summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.htaccess3
-rw-r--r--CHANGELOG68
-rw-r--r--INSTALL2
-rwxr-xr-xbin/package2composer.sh109
-rwxr-xr-xbin/transifexpull.sh38
-rwxr-xr-xbin/updatedb.sh7
-rw-r--r--config/.htaccess2
-rw-r--r--config/defaults.inc.php78
-rw-r--r--index.php9
-rw-r--r--installer/rcube_install.php2
-rw-r--r--logs/.htaccess2
-rw-r--r--main.inc.php.dist900
-rw-r--r--plugins/acl/acl.php56
-rw-r--r--plugins/acl/config.inc.php.dist16
-rw-r--r--plugins/acl/localization/az_AZ.inc2
-rw-r--r--plugins/acl/localization/be_BE.inc90
-rw-r--r--plugins/acl/localization/bg_BG.inc90
-rw-r--r--plugins/acl/localization/el_GR.inc90
-rw-r--r--plugins/acl/localization/en_US.inc4
-rw-r--r--plugins/acl/localization/es_AR.inc89
-rw-r--r--plugins/acl/localization/et_EE.inc6
-rw-r--r--plugins/acl/localization/eu_ES.inc90
-rw-r--r--plugins/acl/localization/fa_IR.inc28
-rw-r--r--plugins/acl/localization/fi_FI.inc28
-rw-r--r--plugins/acl/localization/gl_ES.inc64
-rw-r--r--plugins/acl/localization/he_IL.inc2
-rw-r--r--plugins/acl/localization/lb_LU.inc30
-rw-r--r--plugins/acl/localization/lt_LT.inc2
-rw-r--r--plugins/acl/localization/lv_LV.inc90
-rw-r--r--plugins/acl/localization/pl_PL.inc2
-rw-r--r--plugins/acl/localization/ro_RO.inc24
-rw-r--r--plugins/acl/localization/th_TH.inc50
-rw-r--r--plugins/acl/localization/ti.inc67
-rw-r--r--plugins/acl/localization/tr_TR.inc2
-rw-r--r--plugins/acl/package.xml2
-rw-r--r--plugins/acl/skins/classic/acl.css4
-rw-r--r--plugins/acl/skins/larry/acl.css24
-rw-r--r--plugins/additional_message_headers/additional_message_headers.php4
-rw-r--r--plugins/additional_message_headers/config.inc.php.dist10
-rw-r--r--plugins/archive/archive.js31
-rw-r--r--plugins/archive/archive.php146
-rw-r--r--plugins/archive/localization/ar.inc18
-rw-r--r--plugins/archive/localization/ast.inc31
-rw-r--r--plugins/archive/localization/bn_BD.inc18
-rw-r--r--plugins/archive/localization/en_US.inc11
-rw-r--r--plugins/archive/localization/eu_ES.inc31
-rw-r--r--plugins/archive/localization/fa_AF.inc26
-rw-r--r--plugins/archive/localization/fa_IR.inc6
-rw-r--r--plugins/archive/localization/fi_FI.inc18
-rw-r--r--plugins/archive/localization/fr_FR.inc6
-rw-r--r--plugins/archive/localization/hi_IN.inc18
-rw-r--r--plugins/archive/localization/ia.inc18
-rw-r--r--plugins/archive/localization/lb_LU.inc3
-rw-r--r--plugins/archive/localization/lv_LV.inc22
-rw-r--r--plugins/archive/localization/mn_MN.inc18
-rw-r--r--plugins/archive/localization/ms_MY.inc18
-rw-r--r--plugins/archive/localization/my_MM.inc18
-rw-r--r--plugins/archive/localization/nb_NB.inc21
-rw-r--r--plugins/archive/localization/nb_NO.inc2
-rw-r--r--plugins/archive/localization/nl_BE.inc18
-rw-r--r--plugins/archive/localization/nn_NO.inc2
-rw-r--r--plugins/archive/localization/nqo.inc18
-rw-r--r--plugins/archive/localization/om.inc18
-rw-r--r--plugins/archive/localization/pt_BR.inc18
-rw-r--r--plugins/archive/localization/ro_RO.inc6
-rw-r--r--plugins/archive/localization/te_IN.inc18
-rw-r--r--plugins/archive/localization/th_TH.inc18
-rw-r--r--plugins/archive/localization/ti.inc18
-rw-r--r--plugins/archive/localization/tzm.inc18
-rw-r--r--plugins/archive/localization/ur_PK.inc18
-rw-r--r--plugins/archive/localization/zh_CN.inc20
-rw-r--r--plugins/archive/package.xml42
-rw-r--r--plugins/attachment_reminder/localization/ar.inc20
-rw-r--r--plugins/attachment_reminder/localization/ar_SA.inc20
-rw-r--r--plugins/attachment_reminder/localization/az_AZ.inc20
-rw-r--r--plugins/attachment_reminder/localization/be_BE.inc20
-rw-r--r--plugins/attachment_reminder/localization/bg_BG.inc20
-rw-r--r--plugins/attachment_reminder/localization/bn_BD.inc20
-rw-r--r--plugins/attachment_reminder/localization/bs_BA.inc20
-rw-r--r--plugins/attachment_reminder/localization/ca_ES.inc20
-rw-r--r--plugins/attachment_reminder/localization/cs_CZ.inc20
-rw-r--r--plugins/attachment_reminder/localization/cy_GB.inc20
-rw-r--r--plugins/attachment_reminder/localization/da_DK.inc20
-rw-r--r--plugins/attachment_reminder/localization/de_CH.inc2
-rw-r--r--plugins/attachment_reminder/localization/de_DE.inc18
-rw-r--r--plugins/attachment_reminder/localization/el_GR.inc20
-rw-r--r--plugins/attachment_reminder/localization/eo.inc20
-rw-r--r--plugins/attachment_reminder/localization/es_AR.inc20
-rw-r--r--plugins/attachment_reminder/localization/es_ES.inc18
-rw-r--r--plugins/attachment_reminder/localization/et_EE.inc20
-rw-r--r--plugins/attachment_reminder/localization/eu_ES.inc20
-rw-r--r--plugins/attachment_reminder/localization/fa_AF.inc20
-rw-r--r--plugins/attachment_reminder/localization/fa_IR.inc20
-rw-r--r--plugins/attachment_reminder/localization/fi_FI.inc20
-rw-r--r--plugins/attachment_reminder/localization/fr_FR.inc18
-rw-r--r--plugins/attachment_reminder/localization/gl_ES.inc20
-rw-r--r--plugins/attachment_reminder/localization/he_IL.inc20
-rw-r--r--plugins/attachment_reminder/localization/hi_IN.inc20
-rw-r--r--plugins/attachment_reminder/localization/hu_HU.inc20
-rw-r--r--plugins/attachment_reminder/localization/hy_AM.inc20
-rw-r--r--plugins/attachment_reminder/localization/ia.inc20
-rw-r--r--plugins/attachment_reminder/localization/id_ID.inc20
-rw-r--r--plugins/attachment_reminder/localization/it_IT.inc18
-rw-r--r--plugins/attachment_reminder/localization/ja_JP.inc20
-rw-r--r--plugins/attachment_reminder/localization/ko_KR.inc20
-rw-r--r--plugins/attachment_reminder/localization/lb_LU.inc2
-rw-r--r--plugins/attachment_reminder/localization/lt_LT.inc20
-rw-r--r--plugins/attachment_reminder/localization/lv_LV.inc20
-rw-r--r--plugins/attachment_reminder/localization/ml_IN.inc20
-rw-r--r--plugins/attachment_reminder/localization/mn_MN.inc20
-rw-r--r--plugins/attachment_reminder/localization/ms_MY.inc20
-rw-r--r--plugins/attachment_reminder/localization/my_MM.inc20
-rw-r--r--plugins/attachment_reminder/localization/nb_NO.inc20
-rw-r--r--plugins/attachment_reminder/localization/nl_BE.inc20
-rw-r--r--plugins/attachment_reminder/localization/nl_NL.inc22
-rw-r--r--plugins/attachment_reminder/localization/nn_NO.inc20
-rw-r--r--plugins/attachment_reminder/localization/nqo.inc20
-rw-r--r--plugins/attachment_reminder/localization/om.inc20
-rw-r--r--plugins/attachment_reminder/localization/pl_PL.inc16
-rw-r--r--plugins/attachment_reminder/localization/pt_BR.inc20
-rw-r--r--plugins/attachment_reminder/localization/pt_PT.inc20
-rw-r--r--plugins/attachment_reminder/localization/ro_RO.inc20
-rw-r--r--plugins/attachment_reminder/localization/ru_RU.inc20
-rw-r--r--plugins/attachment_reminder/localization/sk_SK.inc20
-rw-r--r--plugins/attachment_reminder/localization/sl_SI.inc20
-rw-r--r--plugins/attachment_reminder/localization/sr_CS.inc20
-rw-r--r--plugins/attachment_reminder/localization/sv_SE.inc20
-rw-r--r--plugins/attachment_reminder/localization/te_IN.inc20
-rw-r--r--plugins/attachment_reminder/localization/th_TH.inc20
-rw-r--r--plugins/attachment_reminder/localization/ti.inc20
-rw-r--r--plugins/attachment_reminder/localization/tr_TR.inc20
-rw-r--r--plugins/attachment_reminder/localization/tzm.inc20
-rw-r--r--plugins/attachment_reminder/localization/uk_UA.inc20
-rw-r--r--plugins/attachment_reminder/localization/ur_PK.inc20
-rw-r--r--plugins/attachment_reminder/localization/vi_VN.inc20
-rw-r--r--plugins/attachment_reminder/localization/zh_CN.inc22
-rw-r--r--plugins/attachment_reminder/localization/zh_TW.inc18
-rw-r--r--plugins/autologon/autologon.php4
-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/database_attachments/database_attachments.php126
-rw-r--r--plugins/database_attachments/package.xml6
-rw-r--r--plugins/debug_logger/debug_logger.php10
-rw-r--r--plugins/debug_logger/runlog/runlog.php2
-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/README35
-rw-r--r--plugins/enigma/config.inc.php.dist14
-rw-r--r--plugins/enigma/enigma.js206
-rw-r--r--plugins/enigma/enigma.php476
-rw-r--r--plugins/enigma/home/.htaccess2
-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/enigma/lib/enigma_driver.php106
-rw-r--r--plugins/enigma/lib/enigma_driver_gnupg.php305
-rw-r--r--plugins/enigma/lib/enigma_engine.php533
-rw-r--r--plugins/enigma/lib/enigma_error.php62
-rw-r--r--plugins/enigma/lib/enigma_key.php129
-rw-r--r--plugins/enigma/lib/enigma_signature.php34
-rw-r--r--plugins/enigma/lib/enigma_subkey.php57
-rw-r--r--plugins/enigma/lib/enigma_ui.php455
-rw-r--r--plugins/enigma/lib/enigma_userid.php31
-rw-r--r--plugins/enigma/localization/en_US.inc53
-rw-r--r--plugins/enigma/localization/ja_JP.inc55
-rw-r--r--plugins/enigma/localization/ru_RU.inc65
-rw-r--r--plugins/enigma/skins/classic/enigma.css182
-rw-r--r--plugins/enigma/skins/classic/enigma.pngbin1592 -> 0 bytes
-rw-r--r--plugins/enigma/skins/classic/enigma_error.pngbin1960 -> 0 bytes
-rw-r--r--plugins/enigma/skins/classic/key.pngbin1743 -> 0 bytes
-rw-r--r--plugins/enigma/skins/classic/key_add.pngbin1967 -> 0 bytes
-rw-r--r--plugins/enigma/skins/classic/keys_toolbar.pngbin14977 -> 0 bytes
-rw-r--r--plugins/enigma/skins/classic/templates/keyimport.html20
-rw-r--r--plugins/enigma/skins/classic/templates/keyinfo.html17
-rw-r--r--plugins/enigma/skins/classic/templates/keys.html80
-rw-r--r--plugins/enigma/tests/Enigma.php23
-rw-r--r--plugins/fail2ban/fail2ban.php33
-rw-r--r--plugins/filesystem_attachments/filesystem_attachments.php1
-rw-r--r--plugins/filesystem_attachments/package.xml2
-rw-r--r--plugins/help/config.inc.php.dist34
-rw-r--r--plugins/help/content/about.html27
-rw-r--r--plugins/help/content/license.html2
-rw-r--r--plugins/help/help.php69
-rw-r--r--plugins/help/localization/ar.inc18
-rw-r--r--plugins/help/localization/ast.inc21
-rw-r--r--plugins/help/localization/be_BE.inc21
-rw-r--r--plugins/help/localization/bg_BG.inc21
-rw-r--r--plugins/help/localization/bn_BD.inc18
-rw-r--r--plugins/help/localization/el_GR.inc21
-rw-r--r--plugins/help/localization/en_US.inc4
-rw-r--r--plugins/help/localization/es_AR.inc21
-rw-r--r--plugins/help/localization/eu_ES.inc21
-rw-r--r--plugins/help/localization/fa_AF.inc21
-rw-r--r--plugins/help/localization/gl_ES.inc2
-rw-r--r--plugins/help/localization/hi_IN.inc18
-rw-r--r--plugins/help/localization/ia.inc18
-rw-r--r--plugins/help/localization/lb_LU.inc3
-rw-r--r--plugins/help/localization/lv_LV.inc21
-rw-r--r--plugins/help/localization/ml_IN.inc18
-rw-r--r--plugins/help/localization/mn_MN.inc18
-rw-r--r--plugins/help/localization/ms_MY.inc18
-rw-r--r--plugins/help/localization/my_MM.inc18
-rw-r--r--plugins/help/localization/nl_BE.inc18
-rw-r--r--plugins/help/localization/nqo.inc18
-rw-r--r--plugins/help/localization/om.inc18
-rw-r--r--plugins/help/localization/ro_RO.inc21
-rw-r--r--plugins/help/localization/te_IN.inc18
-rw-r--r--plugins/help/localization/th_TH.inc18
-rw-r--r--plugins/help/localization/ti.inc21
-rw-r--r--plugins/help/localization/tzm.inc18
-rw-r--r--plugins/help/localization/uk_UA.inc21
-rw-r--r--plugins/help/localization/ur_PK.inc18
-rw-r--r--plugins/help/package.xml9
-rw-r--r--plugins/help/skins/classic/help.css16
-rw-r--r--plugins/help/skins/classic/templates/help.html17
-rw-r--r--plugins/help/skins/larry/help.css1
-rw-r--r--plugins/help/skins/larry/templates/help.html8
-rw-r--r--plugins/hide_blockquote/hide_blockquote.php4
-rw-r--r--plugins/hide_blockquote/localization/ar.inc18
-rw-r--r--plugins/hide_blockquote/localization/ar_SA.inc20
-rw-r--r--plugins/hide_blockquote/localization/be_BE.inc21
-rw-r--r--plugins/hide_blockquote/localization/bg_BG.inc21
-rw-r--r--plugins/hide_blockquote/localization/bn_BD.inc18
-rw-r--r--plugins/hide_blockquote/localization/el_GR.inc21
-rw-r--r--plugins/hide_blockquote/localization/en_US.inc4
-rw-r--r--plugins/hide_blockquote/localization/es_AR.inc21
-rw-r--r--plugins/hide_blockquote/localization/eu_ES.inc21
-rw-r--r--plugins/hide_blockquote/localization/fa_AF.inc18
-rw-r--r--plugins/hide_blockquote/localization/fi_FI.inc2
-rw-r--r--plugins/hide_blockquote/localization/hi_IN.inc18
-rw-r--r--plugins/hide_blockquote/localization/ia.inc18
-rw-r--r--plugins/hide_blockquote/localization/lb_LU.inc3
-rw-r--r--plugins/hide_blockquote/localization/lv_LV.inc21
-rw-r--r--plugins/hide_blockquote/localization/ml_IN.inc18
-rw-r--r--plugins/hide_blockquote/localization/mn_MN.inc18
-rw-r--r--plugins/hide_blockquote/localization/ms_MY.inc18
-rw-r--r--plugins/hide_blockquote/localization/my_MM.inc18
-rw-r--r--plugins/hide_blockquote/localization/nl_BE.inc18
-rw-r--r--plugins/hide_blockquote/localization/nqo.inc18
-rw-r--r--plugins/hide_blockquote/localization/om.inc18
-rw-r--r--plugins/hide_blockquote/localization/ro_RO.inc21
-rw-r--r--plugins/hide_blockquote/localization/te_IN.inc18
-rw-r--r--plugins/hide_blockquote/localization/th_TH.inc18
-rw-r--r--plugins/hide_blockquote/localization/ti.inc18
-rw-r--r--plugins/hide_blockquote/localization/tzm.inc18
-rw-r--r--plugins/hide_blockquote/localization/uk_UA.inc20
-rw-r--r--plugins/hide_blockquote/localization/ur_PK.inc18
-rw-r--r--plugins/http_authentication/config.inc.php.dist4
-rw-r--r--plugins/http_authentication/http_authentication.php6
-rw-r--r--plugins/jqueryui/config.inc.php.dist4
-rw-r--r--plugins/jqueryui/jqueryui.php1
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery-ui-i18n.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-af.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar-DZ.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-az.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-bg.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-bs.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ca.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-cs.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-cy-GB.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-da.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-de.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-el.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-AU.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-GB.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-NZ.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-eo.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-es.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-et.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-eu.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-fa.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-fi.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-fo.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr-CH.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-gl.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-he.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-hi.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-hr.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-hu.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-hy.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-id.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-is.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-it.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ja.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ka.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-kk.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-km.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ko.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-lb.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-lt.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-lv.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-mk.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ml.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ms.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl-BE.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-no.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-pl.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt-BR.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-rm.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ro.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-sk.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-sl.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-sq.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr-SR.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-sv.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-ta.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-th.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-tj.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-tr.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-uk.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-vi.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-CN.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-HK.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-TW.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/js/jquery-ui-1.9.1.custom.min.js0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_flat_0_aaaaaa_40x100.pngbin180 -> 180 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_flat_75_ffffff_40x100.pngbin178 -> 178 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_flat_90_cc3333_40x100.pngbin212 -> 212 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_glass_95_fef1ec_1x400.pngbin119 -> 119 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_a3a3a3_1x100.pngbin114 -> 114 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_e6e6e7_1x100.pngbin101 -> 101 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_f4f4f4_1x100.pngbin122 -> 122 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-icons_000000_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-icons_333333_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-icons_666666_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-icons_cc3333_256x240.pngbin5355 -> 5355 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/images/ui-icons_dddddd_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/classic/jquery-ui-1.9.1.custom.css0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_55_b0ccd7_1x100.pngbin117 -> 117 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_65_ffffff_1x100.pngbin93 -> 93 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_eaeaea_1x100.pngbin136 -> 136 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_f8f8f8_1x100.pngbin88 -> 88 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_75_fafafa_1x100.pngbin117 -> 117 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_90_e4e4e4_1x100.pngbin111 -> 111 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-icons_004458_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/images/ui-icons_d7211e_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/larry/jquery-ui-1.9.1.custom.css0
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.pngbin180 -> 180 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.pngbin182 -> 182 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.pngbin162 -> 162 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.pngbin123 -> 123 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.pngbin119 -> 119 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.pngbin3457 -> 3457 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.pngbin104 -> 104 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.pngbin88 -> 88 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.pngbin4369 -> 4369 bytes
-rw-r--r--[-rwxr-xr-x]plugins/jqueryui/themes/redmond/jquery-ui-1.9.1.custom.css0
-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/managesieve/Changelog37
-rw-r--r--plugins/managesieve/config.inc.php.dist30
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve.php16
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php151
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_script.php493
-rw-r--r--plugins/managesieve/localization/ar_SA.inc33
-rw-r--r--plugins/managesieve/localization/az_AZ.inc14
-rw-r--r--plugins/managesieve/localization/be_BE.inc2
-rw-r--r--plugins/managesieve/localization/bg_BG.inc8
-rw-r--r--plugins/managesieve/localization/bs_BA.inc2
-rw-r--r--plugins/managesieve/localization/ca_ES.inc8
-rw-r--r--plugins/managesieve/localization/cs_CZ.inc22
-rw-r--r--plugins/managesieve/localization/cy_GB.inc8
-rw-r--r--plugins/managesieve/localization/da_DK.inc8
-rw-r--r--plugins/managesieve/localization/de_CH.inc2
-rw-r--r--plugins/managesieve/localization/de_DE.inc8
-rw-r--r--plugins/managesieve/localization/el_GR.inc216
-rw-r--r--plugins/managesieve/localization/en_GB.inc2
-rw-r--r--plugins/managesieve/localization/en_US.inc51
-rw-r--r--plugins/managesieve/localization/eo.inc2
-rw-r--r--plugins/managesieve/localization/es_AR.inc2
-rw-r--r--plugins/managesieve/localization/es_ES.inc25
-rw-r--r--plugins/managesieve/localization/et_EE.inc29
-rw-r--r--plugins/managesieve/localization/eu_ES.inc181
-rw-r--r--plugins/managesieve/localization/fa_IR.inc7
-rw-r--r--plugins/managesieve/localization/fi_FI.inc24
-rw-r--r--plugins/managesieve/localization/fr_FR.inc26
-rw-r--r--plugins/managesieve/localization/gl_ES.inc148
-rw-r--r--plugins/managesieve/localization/he_IL.inc7
-rw-r--r--plugins/managesieve/localization/hr_HR.inc26
-rw-r--r--plugins/managesieve/localization/hu_HU.inc2
-rw-r--r--plugins/managesieve/localization/hy_AM.inc2
-rw-r--r--plugins/managesieve/localization/ia.inc2
-rw-r--r--plugins/managesieve/localization/id_ID.inc2
-rw-r--r--plugins/managesieve/localization/it_IT.inc26
-rw-r--r--plugins/managesieve/localization/ja_JP.inc2
-rw-r--r--plugins/managesieve/localization/ko_KR.inc2
-rw-r--r--plugins/managesieve/localization/lb_LU.inc147
-rw-r--r--plugins/managesieve/localization/lt_LT.inc10
-rw-r--r--plugins/managesieve/localization/lv_LV.inc163
-rw-r--r--plugins/managesieve/localization/ml_IN.inc1
-rw-r--r--plugins/managesieve/localization/mr_IN.inc2
-rw-r--r--plugins/managesieve/localization/nb_NO.inc2
-rw-r--r--plugins/managesieve/localization/nl_NL.inc2
-rw-r--r--plugins/managesieve/localization/nn_NO.inc13
-rw-r--r--plugins/managesieve/localization/pl_PL.inc25
-rw-r--r--plugins/managesieve/localization/pt_BR.inc21
-rw-r--r--plugins/managesieve/localization/pt_PT.inc2
-rw-r--r--plugins/managesieve/localization/ro_RO.inc8
-rw-r--r--plugins/managesieve/localization/ru_RU.inc21
-rw-r--r--plugins/managesieve/localization/si_LK.inc1
-rw-r--r--plugins/managesieve/localization/sk_SK.inc2
-rw-r--r--plugins/managesieve/localization/sl_SI.inc25
-rw-r--r--plugins/managesieve/localization/sv_SE.inc2
-rw-r--r--plugins/managesieve/localization/th_TH.inc45
-rw-r--r--plugins/managesieve/localization/tr_TR.inc8
-rw-r--r--plugins/managesieve/localization/uk_UA.inc2
-rw-r--r--plugins/managesieve/localization/vi_VN.inc17
-rw-r--r--plugins/managesieve/localization/zh_CN.inc2
-rw-r--r--plugins/managesieve/localization/zh_TW.inc2
-rw-r--r--plugins/managesieve/managesieve.js185
-rw-r--r--plugins/managesieve/managesieve.php1919
-rw-r--r--plugins/managesieve/package.xml18
-rw-r--r--plugins/managesieve/skins/classic/managesieve.css103
-rw-r--r--plugins/managesieve/skins/classic/managesieve_mail.css2
-rw-r--r--plugins/managesieve/skins/classic/templates/managesieve.html6
-rw-r--r--plugins/managesieve/skins/larry/managesieve.css116
-rw-r--r--plugins/managesieve/tests/src/parser.out4
-rw-r--r--plugins/managesieve/tests/src/parser_enotify_b6
-rw-r--r--plugins/managesieve/tests/src/parser_notify_b6
-rw-r--r--plugins/managesieve/tests/src/parser_relational2
-rw-r--r--plugins/managesieve/tests/src/parser_subaddress2
-rw-r--r--plugins/markasjunk/localization/ar.inc20
-rw-r--r--plugins/markasjunk/localization/bg_BG.inc21
-rw-r--r--plugins/markasjunk/localization/en_US.inc4
-rw-r--r--plugins/markasjunk/localization/eu_ES.inc21
-rw-r--r--plugins/markasjunk/localization/lb_LU.inc3
-rw-r--r--plugins/markasjunk/localization/lv_LV.inc6
-rw-r--r--plugins/markasjunk/localization/ro_RO.inc6
-rw-r--r--plugins/markasjunk/localization/ru_RU.inc4
-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/new_user_dialog/localization/ar.inc20
-rw-r--r--plugins/new_user_dialog/localization/ar_SA.inc19
-rw-r--r--plugins/new_user_dialog/localization/ast.inc20
-rw-r--r--plugins/new_user_dialog/localization/en_US.inc4
-rw-r--r--plugins/new_user_dialog/localization/es_AR.inc20
-rw-r--r--plugins/new_user_dialog/localization/eu_ES.inc20
-rw-r--r--plugins/new_user_dialog/localization/fa_AF.inc20
-rw-r--r--plugins/new_user_dialog/localization/lb_LU.inc3
-rw-r--r--plugins/new_user_dialog/localization/lv_LV.inc4
-rw-r--r--plugins/new_user_dialog/localization/ro_RO.inc4
-rw-r--r--plugins/new_user_dialog/new_user_dialog.php69
-rw-r--r--plugins/new_user_dialog/package.xml91
-rw-r--r--plugins/new_user_identity/new_user_identity.php11
-rw-r--r--plugins/new_user_identity/package.xml2
-rw-r--r--plugins/newmail_notifier/config.inc.php.dist6
-rw-r--r--plugins/newmail_notifier/localization/ast.inc28
-rw-r--r--plugins/newmail_notifier/localization/bg_BG.inc28
-rw-r--r--plugins/newmail_notifier/localization/el_GR.inc27
-rw-r--r--plugins/newmail_notifier/localization/en_US.inc2
-rw-r--r--plugins/newmail_notifier/localization/es_AR.inc27
-rw-r--r--plugins/newmail_notifier/localization/eu_ES.inc27
-rw-r--r--plugins/newmail_notifier/localization/lb_LU.inc3
-rw-r--r--plugins/newmail_notifier/localization/lv_LV.inc16
-rw-r--r--plugins/newmail_notifier/localization/ro_RO.inc4
-rw-r--r--plugins/newmail_notifier/localization/ti.inc27
-rw-r--r--plugins/newmail_notifier/newmail_notifier.js110
-rw-r--r--plugins/newmail_notifier/newmail_notifier.php85
-rw-r--r--plugins/newmail_notifier/package.xml8
-rw-r--r--plugins/newmail_notifier/sound.mp3bin0 -> 7488 bytes
-rw-r--r--plugins/password/README116
-rw-r--r--plugins/password/config.inc.php.dist143
-rw-r--r--plugins/password/drivers/chpasswd.php2
-rw-r--r--plugins/password/drivers/cpanel.php110
-rw-r--r--plugins/password/drivers/dbmail.php2
-rw-r--r--plugins/password/drivers/directadmin.php3
-rw-r--r--plugins/password/drivers/expect.php2
-rw-r--r--plugins/password/drivers/hmail.php12
-rw-r--r--plugins/password/drivers/ldap.php2
-rw-r--r--plugins/password/drivers/ldap_simple.php2
-rw-r--r--plugins/password/drivers/pam.php4
-rw-r--r--plugins/password/drivers/pw_usermod.php2
-rw-r--r--plugins/password/drivers/sasl.php2
-rw-r--r--plugins/password/drivers/smb.php14
-rw-r--r--plugins/password/drivers/sql.php19
-rw-r--r--plugins/password/drivers/virtualmin.php13
-rw-r--r--plugins/password/drivers/xmail.php16
-rw-r--r--plugins/password/localization/ar.inc32
-rw-r--r--plugins/password/localization/ar_SA.inc29
-rw-r--r--plugins/password/localization/ast.inc32
-rw-r--r--plugins/password/localization/be_BE.inc32
-rw-r--r--plugins/password/localization/el_GR.inc32
-rw-r--r--plugins/password/localization/en_US.inc2
-rw-r--r--plugins/password/localization/eu_ES.inc32
-rw-r--r--plugins/password/localization/fa_AF.inc32
-rw-r--r--plugins/password/localization/gl_ES.inc2
-rw-r--r--plugins/password/localization/lb_LU.inc5
-rw-r--r--plugins/password/localization/lv_LV.inc16
-rw-r--r--plugins/password/localization/ro_RO.inc10
-rw-r--r--plugins/password/localization/ru_RU.inc4
-rw-r--r--plugins/password/localization/ti.inc32
-rw-r--r--plugins/password/localization/uk_UA.inc32
-rw-r--r--plugins/password/package.xml40
-rw-r--r--plugins/password/password.php82
-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/show_additional_headers/package.xml2
-rw-r--r--plugins/show_additional_headers/show_additional_headers.php6
-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/squirrelmail_usercopy/config.inc.php.dist18
-rw-r--r--plugins/squirrelmail_usercopy/squirrelmail_usercopy.php18
-rw-r--r--plugins/subscriptions_option/localization/az_AZ.inc19
-rw-r--r--plugins/subscriptions_option/localization/be_BE.inc19
-rw-r--r--plugins/subscriptions_option/localization/bg_BG.inc19
-rw-r--r--plugins/subscriptions_option/localization/el_GR.inc19
-rw-r--r--plugins/subscriptions_option/localization/en_US.inc2
-rw-r--r--plugins/subscriptions_option/localization/es_AR.inc19
-rw-r--r--plugins/subscriptions_option/localization/eu_ES.inc19
-rw-r--r--plugins/subscriptions_option/localization/fa_AF.inc19
-rw-r--r--plugins/subscriptions_option/localization/gl_ES.inc2
-rw-r--r--plugins/subscriptions_option/localization/id_ID.inc19
-rw-r--r--plugins/subscriptions_option/localization/lb_LU.inc3
-rw-r--r--plugins/subscriptions_option/localization/lv_LV.inc19
-rw-r--r--plugins/subscriptions_option/localization/nn_NO.inc19
-rw-r--r--plugins/subscriptions_option/localization/ro_RO.inc19
-rw-r--r--plugins/subscriptions_option/localization/ru_RU.inc2
-rw-r--r--plugins/subscriptions_option/package.xml2
-rw-r--r--plugins/subscriptions_option/subscriptions_option.php9
-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--plugins/userinfo/localization/ar.inc21
-rw-r--r--plugins/userinfo/localization/ast.inc22
-rw-r--r--plugins/userinfo/localization/bg_BG.inc22
-rw-r--r--plugins/userinfo/localization/el_GR.inc22
-rw-r--r--plugins/userinfo/localization/en_US.inc2
-rw-r--r--plugins/userinfo/localization/es_AR.inc22
-rw-r--r--plugins/userinfo/localization/eu_ES.inc22
-rw-r--r--plugins/userinfo/localization/fa_AF.inc22
-rw-r--r--[-rwxr-xr-x]plugins/userinfo/localization/fr_FR.inc0
-rw-r--r--plugins/userinfo/localization/lb_LU.inc3
-rw-r--r--[-rwxr-xr-x]plugins/userinfo/localization/ro_RO.inc8
-rw-r--r--plugins/userinfo/localization/ti.inc22
-rw-r--r--plugins/userinfo/userinfo.php24
-rw-r--r--plugins/vcard_attachments/localization/ar.inc20
-rw-r--r--plugins/vcard_attachments/localization/ar_SA.inc20
-rw-r--r--plugins/vcard_attachments/localization/bg_BG.inc20
-rw-r--r--plugins/vcard_attachments/localization/el_GR.inc20
-rw-r--r--plugins/vcard_attachments/localization/en_US.inc2
-rw-r--r--plugins/vcard_attachments/localization/es_AR.inc20
-rw-r--r--plugins/vcard_attachments/localization/eu_ES.inc20
-rw-r--r--plugins/vcard_attachments/localization/gl_ES.inc4
-rw-r--r--plugins/vcard_attachments/localization/lb_LU.inc3
-rw-r--r--plugins/vcard_attachments/vcard_attachments.php15
-rw-r--r--plugins/virtuser_file/virtuser_file.php92
-rw-r--r--plugins/virtuser_query/package.xml8
-rw-r--r--plugins/virtuser_query/virtuser_query.php64
-rw-r--r--plugins/zipdownload/README2
-rw-r--r--plugins/zipdownload/config.inc.php.dist8
-rw-r--r--plugins/zipdownload/localization/ar.inc20
-rw-r--r--plugins/zipdownload/localization/ar_SA.inc20
-rw-r--r--plugins/zipdownload/localization/be_BE.inc20
-rw-r--r--plugins/zipdownload/localization/bg_BG.inc20
-rw-r--r--plugins/zipdownload/localization/el_GR.inc20
-rw-r--r--plugins/zipdownload/localization/en_US.inc2
-rw-r--r--plugins/zipdownload/localization/eo.inc20
-rw-r--r--plugins/zipdownload/localization/eu_ES.inc20
-rw-r--r--plugins/zipdownload/localization/fa_AF.inc20
-rw-r--r--plugins/zipdownload/localization/fi_FI.inc20
-rw-r--r--plugins/zipdownload/localization/id_ID.inc20
-rw-r--r--plugins/zipdownload/localization/ko_KR.inc20
-rw-r--r--plugins/zipdownload/localization/lb_LU.inc3
-rw-r--r--plugins/zipdownload/localization/lv_LV.inc20
-rw-r--r--plugins/zipdownload/localization/ro_RO.inc4
-rw-r--r--plugins/zipdownload/localization/ru_RU.inc2
-rw-r--r--plugins/zipdownload/localization/sl_SI.inc20
-rw-r--r--plugins/zipdownload/localization/uk_UA.inc20
-rw-r--r--plugins/zipdownload/localization/zh_CN.inc20
-rw-r--r--plugins/zipdownload/skins/larry/zipdownload.css4
-rw-r--r--plugins/zipdownload/zipdownload.php27
-rw-r--r--program/include/bc.php16
-rw-r--r--program/include/iniset.php9
-rw-r--r--program/include/rcmail.php393
-rw-r--r--program/include/rcmail_output_html.php145
-rw-r--r--program/js/app.js7016
-rw-r--r--program/js/common.js724
-rw-r--r--program/js/editor.js2
-rw-r--r--program/js/googiespell.js1136
l---------[-rw-r--r--]program/js/jquery.min.js3
-rw-r--r--program/js/jstz.min.js13
-rw-r--r--program/js/list.js1607
-rw-r--r--program/lib/Crypt/GPG.php (renamed from plugins/enigma/lib/Crypt/GPG.php)0
-rw-r--r--program/lib/Crypt/GPG/DecryptStatusHandler.php (renamed from plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php)0
-rw-r--r--program/lib/Crypt/GPG/Engine.php (renamed from plugins/enigma/lib/Crypt/GPG/Engine.php)0
-rw-r--r--program/lib/Crypt/GPG/Exceptions.php (renamed from plugins/enigma/lib/Crypt/GPG/Exceptions.php)0
-rw-r--r--program/lib/Crypt/GPG/Key.php (renamed from plugins/enigma/lib/Crypt/GPG/Key.php)0
-rw-r--r--program/lib/Crypt/GPG/Signature.php (renamed from plugins/enigma/lib/Crypt/GPG/Signature.php)0
-rw-r--r--program/lib/Crypt/GPG/SubKey.php (renamed from plugins/enigma/lib/Crypt/GPG/SubKey.php)0
-rw-r--r--program/lib/Crypt/GPG/UserId.php (renamed from plugins/enigma/lib/Crypt/GPG/UserId.php)0
-rw-r--r--program/lib/Crypt/GPG/VerifyStatusHandler.php (renamed from plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php)0
-rw-r--r--program/lib/Net/Sieve.php1274
-rw-r--r--program/lib/Roundcube/bootstrap.php30
-rw-r--r--program/lib/Roundcube/html.php70
-rw-r--r--program/lib/Roundcube/rcube.php302
-rw-r--r--program/lib/Roundcube/rcube_addressbook.php32
-rw-r--r--program/lib/Roundcube/rcube_base_replacer.php2
-rw-r--r--program/lib/Roundcube/rcube_browser.php2
-rw-r--r--program/lib/Roundcube/rcube_cache.php45
-rw-r--r--program/lib/Roundcube/rcube_config.php251
-rw-r--r--program/lib/Roundcube/rcube_contacts.php4
-rw-r--r--program/lib/Roundcube/rcube_content_filter.php2
-rw-r--r--program/lib/Roundcube/rcube_csv2vcard.php49
-rw-r--r--program/lib/Roundcube/rcube_db.php107
-rw-r--r--program/lib/Roundcube/rcube_db_mssql.php32
-rw-r--r--program/lib/Roundcube/rcube_db_mysql.php23
-rw-r--r--program/lib/Roundcube/rcube_db_pgsql.php47
-rw-r--r--program/lib/Roundcube/rcube_db_sqlite.php47
-rw-r--r--program/lib/Roundcube/rcube_db_sqlsrv.php29
-rw-r--r--program/lib/Roundcube/rcube_enriched.php2
-rw-r--r--program/lib/Roundcube/rcube_image.php99
-rw-r--r--program/lib/Roundcube/rcube_imap.php279
-rw-r--r--program/lib/Roundcube/rcube_imap_cache.php219
-rw-r--r--program/lib/Roundcube/rcube_imap_generic.php282
-rw-r--r--program/lib/Roundcube/rcube_ldap.php1322
-rw-r--r--program/lib/Roundcube/rcube_ldap_generic.php6
-rw-r--r--program/lib/Roundcube/rcube_message.php107
-rw-r--r--program/lib/Roundcube/rcube_mime.php32
-rw-r--r--program/lib/Roundcube/rcube_plugin.php36
-rw-r--r--program/lib/Roundcube/rcube_plugin_api.php122
-rw-r--r--program/lib/Roundcube/rcube_result_set.php47
-rw-r--r--program/lib/Roundcube/rcube_session.php142
-rw-r--r--program/lib/Roundcube/rcube_smtp.php12
-rw-r--r--program/lib/Roundcube/rcube_spellcheck_atd.php204
-rw-r--r--program/lib/Roundcube/rcube_spellcheck_enchant.php182
-rw-r--r--program/lib/Roundcube/rcube_spellcheck_engine.php91
-rw-r--r--program/lib/Roundcube/rcube_spellcheck_googie.php176
-rw-r--r--program/lib/Roundcube/rcube_spellcheck_pspell.php189
-rw-r--r--program/lib/Roundcube/rcube_spellchecker.php163
-rw-r--r--program/lib/Roundcube/rcube_storage.php22
-rw-r--r--program/lib/Roundcube/rcube_string_replacer.php13
-rw-r--r--program/lib/Roundcube/rcube_user.php9
-rw-r--r--program/lib/Roundcube/rcube_utils.php84
-rw-r--r--program/lib/Roundcube/rcube_vcard.php15
-rw-r--r--program/lib/Roundcube/rcube_washtml.php21
-rw-r--r--program/localization/ar_SA/labels.inc5
-rw-r--r--program/localization/ar_SA/messages.inc9
-rw-r--r--program/localization/ast/labels.inc5
-rw-r--r--program/localization/ast/messages.inc9
-rw-r--r--program/localization/az_AZ/labels.inc5
-rw-r--r--program/localization/az_AZ/messages.inc9
-rw-r--r--program/localization/be_BE/labels.inc5
-rw-r--r--program/localization/be_BE/messages.inc9
-rw-r--r--program/localization/bg_BG/labels.inc5
-rw-r--r--program/localization/bg_BG/messages.inc9
-rw-r--r--program/localization/bn_BD/labels.inc5
-rw-r--r--program/localization/bn_BD/messages.inc9
-rw-r--r--program/localization/br/labels.inc5
-rw-r--r--program/localization/br/messages.inc9
-rw-r--r--program/localization/bs_BA/labels.inc7
-rw-r--r--program/localization/bs_BA/messages.inc9
-rw-r--r--program/localization/ca_ES/labels.inc5
-rw-r--r--program/localization/ca_ES/messages.inc9
-rw-r--r--program/localization/cs_CZ/labels.inc7
-rw-r--r--program/localization/cs_CZ/messages.inc6
-rw-r--r--program/localization/cy_GB/labels.inc7
-rw-r--r--program/localization/cy_GB/messages.inc9
-rw-r--r--program/localization/da_DK/labels.inc7
-rw-r--r--program/localization/da_DK/messages.inc9
-rw-r--r--program/localization/de_CH/labels.inc5
-rw-r--r--program/localization/de_CH/messages.inc2
-rw-r--r--program/localization/de_DE/labels.inc7
-rw-r--r--program/localization/de_DE/messages.inc9
-rw-r--r--program/localization/el_GR/labels.inc5
-rw-r--r--program/localization/el_GR/messages.inc9
-rw-r--r--program/localization/en_GB/labels.inc5
-rw-r--r--program/localization/en_GB/messages.inc13
-rw-r--r--program/localization/en_US/csv2vcard.inc19
-rw-r--r--program/localization/en_US/labels.inc20
-rw-r--r--program/localization/en_US/labels.inc.orig537
-rw-r--r--program/localization/en_US/messages.inc19
-rw-r--r--program/localization/eo/labels.inc5
-rw-r--r--program/localization/eo/messages.inc9
-rw-r--r--program/localization/es_AR/labels.inc5
-rw-r--r--program/localization/es_AR/messages.inc9
-rw-r--r--program/localization/es_ES/labels.inc7
-rw-r--r--program/localization/es_ES/messages.inc2
-rw-r--r--program/localization/et_EE/labels.inc5
-rw-r--r--program/localization/et_EE/messages.inc2
-rw-r--r--program/localization/eu_ES/labels.inc5
-rw-r--r--program/localization/eu_ES/messages.inc195
-rw-r--r--program/localization/fa_AF/labels.inc5
-rw-r--r--program/localization/fa_AF/messages.inc55
-rw-r--r--program/localization/fa_IR/labels.inc5
-rw-r--r--program/localization/fa_IR/messages.inc163
-rw-r--r--program/localization/fi_FI/labels.inc3
-rw-r--r--program/localization/fi_FI/messages.inc4
-rw-r--r--program/localization/fr_FR/labels.inc9
-rw-r--r--program/localization/fr_FR/messages.inc210
-rw-r--r--program/localization/fy_NL/labels.inc5
-rw-r--r--program/localization/fy_NL/messages.inc171
-rw-r--r--[-rwxr-xr-x]program/localization/ga_IE/labels.inc5
-rw-r--r--[-rwxr-xr-x]program/localization/ga_IE/messages.inc9
-rw-r--r--program/localization/gl_ES/labels.inc7
-rw-r--r--program/localization/gl_ES/messages.inc2
-rw-r--r--program/localization/he_IL/labels.inc5
-rw-r--r--program/localization/he_IL/messages.inc2
-rw-r--r--program/localization/hi_IN/labels.inc5
-rw-r--r--program/localization/hi_IN/messages.inc9
-rw-r--r--program/localization/hr_HR/labels.inc5
-rw-r--r--program/localization/hr_HR/messages.inc9
-rw-r--r--program/localization/hu_HU/labels.inc5
-rw-r--r--program/localization/hu_HU/messages.inc9
-rw-r--r--program/localization/hy_AM/labels.inc5
-rw-r--r--program/localization/hy_AM/messages.inc9
-rw-r--r--program/localization/ia/labels.inc5
-rw-r--r--program/localization/ia/messages.inc9
-rw-r--r--program/localization/id_ID/labels.inc18
-rw-r--r--program/localization/id_ID/messages.inc11
-rw-r--r--program/localization/index.inc2
-rw-r--r--program/localization/is_IS/labels.inc5
-rw-r--r--program/localization/is_IS/messages.inc9
-rw-r--r--program/localization/it_IT/labels.inc5
-rw-r--r--program/localization/it_IT/messages.inc11
-rw-r--r--program/localization/ja_JP/labels.inc5
-rw-r--r--program/localization/ja_JP/messages.inc9
-rw-r--r--[-rwxr-xr-x]program/localization/ka_GE/labels.inc5
-rw-r--r--[-rwxr-xr-x]program/localization/ka_GE/messages.inc9
-rw-r--r--program/localization/km_KH/labels.inc5
-rw-r--r--program/localization/km_KH/messages.inc9
-rw-r--r--program/localization/ko_KR/labels.inc5
-rw-r--r--program/localization/ko_KR/messages.inc9
-rw-r--r--program/localization/ku/labels.inc5
-rw-r--r--program/localization/ku/messages.inc9
-rw-r--r--program/localization/lb_LU/labels.inc77
-rw-r--r--program/localization/lb_LU/messages.inc7
-rw-r--r--program/localization/lt_LT/labels.inc5
-rw-r--r--program/localization/lt_LT/messages.inc9
-rw-r--r--program/localization/lv_LV/labels.inc323
-rw-r--r--program/localization/lv_LV/messages.inc90
-rw-r--r--[-rwxr-xr-x]program/localization/mk_MK/labels.inc5
-rw-r--r--[-rwxr-xr-x]program/localization/mk_MK/messages.inc9
-rw-r--r--program/localization/ml_IN/labels.inc5
-rw-r--r--program/localization/ml_IN/messages.inc9
-rw-r--r--[-rwxr-xr-x]program/localization/mr_IN/labels.inc5
-rw-r--r--[-rwxr-xr-x]program/localization/mr_IN/messages.inc9
-rw-r--r--program/localization/ms_MY/labels.inc5
-rw-r--r--program/localization/ms_MY/messages.inc9
-rw-r--r--program/localization/nb_NO/labels.inc5
-rw-r--r--program/localization/nb_NO/messages.inc9
-rw-r--r--program/localization/ne_NP/labels.inc5
-rw-r--r--program/localization/ne_NP/messages.inc9
-rw-r--r--program/localization/nl_BE/labels.inc5
-rw-r--r--program/localization/nl_BE/messages.inc9
-rw-r--r--program/localization/nl_NL/labels.inc5
-rw-r--r--program/localization/nl_NL/messages.inc9
-rw-r--r--program/localization/nn_NO/labels.inc5
-rw-r--r--program/localization/nn_NO/messages.inc9
-rw-r--r--program/localization/pl_PL/labels.inc5
-rw-r--r--program/localization/pl_PL/messages.inc2
-rw-r--r--[-rwxr-xr-x]program/localization/ps/labels.inc5
-rw-r--r--[-rwxr-xr-x]program/localization/ps/messages.inc9
-rw-r--r--program/localization/pt_BR/labels.inc9
-rw-r--r--program/localization/pt_BR/messages.inc9
-rw-r--r--program/localization/pt_PT/labels.inc5
-rw-r--r--program/localization/pt_PT/messages.inc9
-rw-r--r--program/localization/ro_RO/labels.inc3
-rw-r--r--program/localization/ro_RO/messages.inc62
-rw-r--r--program/localization/ru_RU/labels.inc20
-rw-r--r--program/localization/ru_RU/messages.inc175
-rw-r--r--program/localization/si_LK/labels.inc5
-rw-r--r--program/localization/si_LK/messages.inc9
-rw-r--r--program/localization/sk_SK/labels.inc5
-rw-r--r--program/localization/sk_SK/messages.inc9
-rw-r--r--program/localization/sl_SI/labels.inc13
-rw-r--r--program/localization/sl_SI/messages.inc2
-rw-r--r--program/localization/sq_AL/labels.inc5
-rw-r--r--program/localization/sq_AL/messages.inc9
-rw-r--r--program/localization/sr_CS/labels.inc5
-rw-r--r--program/localization/sr_CS/messages.inc9
-rw-r--r--program/localization/sv_SE/labels.inc5
-rw-r--r--program/localization/sv_SE/messages.inc63
-rw-r--r--program/localization/ta_IN/labels.inc5
-rw-r--r--program/localization/ta_IN/messages.inc9
-rw-r--r--program/localization/th_TH/labels.inc5
-rw-r--r--program/localization/th_TH/messages.inc9
-rw-r--r--program/localization/tr_TR/labels.inc7
-rw-r--r--program/localization/tr_TR/messages.inc2
-rw-r--r--program/localization/uk_UA/labels.inc533
-rw-r--r--program/localization/uk_UA/messages.inc115
-rw-r--r--program/localization/ur_PK/labels.inc40
-rw-r--r--program/localization/ur_PK/messages.inc18
-rw-r--r--program/localization/vi_VN/labels.inc5
-rw-r--r--program/localization/vi_VN/messages.inc9
-rw-r--r--program/localization/zh_CN/labels.inc5
-rw-r--r--program/localization/zh_CN/messages.inc136
-rw-r--r--program/localization/zh_TW/labels.inc5
-rw-r--r--program/localization/zh_TW/messages.inc9
-rw-r--r--program/steps/addressbook/copy.inc12
-rw-r--r--program/steps/addressbook/delete.inc38
-rw-r--r--program/steps/addressbook/export.inc113
-rw-r--r--program/steps/addressbook/func.inc187
-rw-r--r--program/steps/addressbook/import.inc71
-rw-r--r--program/steps/addressbook/list.inc49
-rw-r--r--program/steps/addressbook/save.inc29
-rw-r--r--program/steps/addressbook/show.inc63
-rw-r--r--program/steps/addressbook/undo.inc25
-rw-r--r--program/steps/mail/attachments.inc5
-rw-r--r--program/steps/mail/check_recent.inc9
-rw-r--r--program/steps/mail/compose.inc103
-rw-r--r--program/steps/mail/func.inc336
-rw-r--r--program/steps/mail/func.inc.orig1964
-rw-r--r--program/steps/mail/get.inc86
-rw-r--r--program/steps/mail/list.inc1
-rw-r--r--program/steps/mail/list_contacts.inc29
-rw-r--r--program/steps/mail/move_del.inc11
-rw-r--r--program/steps/mail/sendmail.inc30
-rw-r--r--program/steps/mail/show.inc61
-rw-r--r--program/steps/mail/show.inc.orig315
-rw-r--r--program/steps/settings/about.inc67
-rw-r--r--program/steps/settings/edit_folder.inc5
-rw-r--r--program/steps/settings/edit_prefs.inc2
-rw-r--r--program/steps/settings/edit_response.inc107
-rw-r--r--program/steps/settings/folders.inc16
-rw-r--r--program/steps/settings/func.inc1961
-rw-r--r--program/steps/settings/responses.inc128
-rw-r--r--program/steps/settings/save_prefs.inc4
-rw-r--r--program/steps/utils/save_pref.inc22
-rw-r--r--program/steps/utils/spell.inc7
-rw-r--r--program/steps/utils/spell_html.inc5
-rw-r--r--skins/classic/addressbook.css79
-rw-r--r--skins/classic/common.css88
-rw-r--r--skins/classic/embed.css2
-rw-r--r--skins/classic/functions.js283
-rw-r--r--skins/classic/ie6hacks.css24
-rw-r--r--skins/classic/iehacks.css6
-rw-r--r--skins/classic/images/favicon.icobin34494 -> 1150 bytes
-rw-r--r--skins/classic/images/mail_toolbar.pngbin40806 -> 36649 bytes
-rw-r--r--skins/classic/includes/messagetoolbar.html2
-rw-r--r--skins/classic/mail.css388
-rw-r--r--skins/classic/settings.css16
-rw-r--r--skins/classic/templates/about.html7
-rw-r--r--skins/classic/templates/addressbook.html28
-rw-r--r--skins/classic/templates/compose.html25
-rw-r--r--skins/classic/templates/contact.html2
-rw-r--r--skins/classic/templates/contactadd.html9
-rw-r--r--skins/classic/templates/contactedit.html9
-rw-r--r--skins/classic/templates/folders.html6
-rw-r--r--skins/classic/templates/login.html2
-rw-r--r--skins/classic/templates/mail.html18
-rw-r--r--skins/classic/templates/message.html28
-rw-r--r--skins/classic/templates/messageerror.html8
-rw-r--r--skins/classic/templates/messagepart.html38
-rw-r--r--skins/classic/templates/messagepreview.html26
-rw-r--r--skins/classic/templates/responseedit.html24
-rw-r--r--skins/classic/templates/responses.html46
-rw-r--r--skins/larry/addressbook.css88
-rw-r--r--skins/larry/embed.css2
-rw-r--r--skins/larry/ie7hacks.css1
-rw-r--r--skins/larry/iehacks.css9
-rw-r--r--skins/larry/images/buttons.gifbin14997 -> 13054 bytes
-rw-r--r--skins/larry/images/buttons.pngbin50162 -> 36693 bytes
-rw-r--r--skins/larry/images/favicon.icobin34494 -> 1150 bytes
-rw-r--r--skins/larry/images/listicons.pngbin26384 -> 25486 bytes
-rw-r--r--skins/larry/includes/footer.html12
-rw-r--r--skins/larry/includes/header.html8
-rw-r--r--skins/larry/mail.css446
-rw-r--r--skins/larry/settings.css12
-rw-r--r--skins/larry/styles.css201
-rw-r--r--skins/larry/svggradients.css7
-rw-r--r--skins/larry/templates/about.html4
-rw-r--r--skins/larry/templates/addressbook.html23
-rw-r--r--skins/larry/templates/compose.html16
-rw-r--r--skins/larry/templates/contact.html2
-rw-r--r--skins/larry/templates/contactedit.html2
-rw-r--r--skins/larry/templates/importcontacts.html9
-rw-r--r--skins/larry/templates/login.html4
-rw-r--r--skins/larry/templates/mail.html17
-rw-r--r--skins/larry/templates/message.html27
-rw-r--r--skins/larry/templates/messageerror.html2
-rw-r--r--skins/larry/templates/messagepart.html34
-rw-r--r--skins/larry/templates/messagepreview.html19
-rw-r--r--skins/larry/templates/responseedit.html22
-rw-r--r--skins/larry/templates/responses.html41
-rw-r--r--skins/larry/ui.js217
-rw-r--r--skins/larry/watermark.html2
-rw-r--r--temp/.htaccess2
-rw-r--r--tests/Framework/Browser.php203
-rw-r--r--tests/Framework/Mime.php4
-rw-r--r--tests/Framework/StringReplacer.php16
-rw-r--r--tests/Framework/Utils.php32
-rw-r--r--tests/MailFunc.php88
-rw-r--r--tests/phpunit.xml1
-rw-r--r--tests/src/media.css22
1215 files changed, 44641 insertions, 24686 deletions
diff --git a/.htaccess b/.htaccess
index dc6e62f38..345d26dba 100644
--- a/.htaccess
+++ b/.htaccess
@@ -21,6 +21,9 @@ php_flag session.auto_start Off
php_value session.gc_maxlifetime 21600
php_value session.gc_divisor 500
php_value session.gc_probability 1
+
+# http://bugs.php.net/bug.php?id=30766
+php_value mbstring.func_overload 0
</IfModule>
<IfModule mod_rewrite.c>
diff --git a/CHANGELOG b/CHANGELOG
index dbc7447ae..32511169a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,14 +1,33 @@
CHANGELOG Roundcube Webmail
===========================
+- Fix date column width to fit the widest possible date format (#1489368)
+- Move certain user preference options to a collapsed "advanced" block (#1488829)
+- Add file type icons for Powerpoint and Open Office presentations (#1489225)
+- Fix operations on folders with trailing spaces in name (#1489419)
+- Improve identity selection based on From: header (#1489378)
+- Fix issue where mails with inline images of the same name contained only the first image multiple times (#1489406)
+- Use left/right arrow keys to collapse/expand thread and spacebar to select a row, change Ctrl key behavior (#1489392)
+- Fix an issue where using arrow keys to go up a list can result in selected message being under headers (#1489403)
+- Fix an issue where Home/End keys don't focus list row properly, don't scrollTo properly (#1489396)
+- Add an option to disable smart Reply-List behaviour - reply_all_mode (#1488734)
+- Fix an issue where pressing minus key on contacts list was hiding list records (#1489393)
+- Fix an issue where shift + arrow-up key wasn't selecting all messages in collapsed thread (#1489397)
+- Added icon for priority column in messages list header (#1489234)
+- New feature "Canned Responses" to save and recall boilerplate text snippets
+- Fix HTML part detection when encapsulated inside multipart/signed (#1489372)
+- Add spellchecker backend for the After the Deadline service
+- Replace markdown-style [1] link indexes in plain text email bodies
+- Improved mailto: link arguments handling (#1489363)
+- Use DOMDocument LIBXML_PARSEHUGE and LIBXML_COMPACT options if possible (#1489302)
+- Support HTTP_HOST, SERVER_NAME and SERVER_ADDR values in include_host_config feature
+- Make default font size for HTML messages configurable (request #118)
+- Fix XSS issue in addressbook group name field [CVE-2013-5646] (#1489333)
- After message is sent refresh messages list of replied message folder (#1489249)
- Add option force specified domain in user login - username_domain_forced (#1489264)
-- Fix expanded thread root message styling after refreshing messages list (#1489327)
-- Fix issue where From address was removed from Cc and Bcc fields when editing a draft (#1489319)
- Add option to import Vcards with group assignments
- Save groups membership in Vcard export (#1488509)
- Workaround broken PHP function timezone_name_from_abbr (#1489261)
-- Fix error_reporting directive check (#1489323)
- Make cached message size limit configurable - messages_cache_threshold (#1489317)
- Log also failed logins to userlogins log
- Add temp_dir_ttl configuration option (#1489304)
@@ -69,6 +88,23 @@ CHANGELOG Roundcube Webmail
- Fix export of selected contacts from search result (#1488905)
- Feature to export only selected contacts from addressbook (by Phil Weir)
+RELEASE 0.9.5
+-------------
+- Fix failing vCard import when email address field contains spaces (#1489386)
+- Fix default spell-check configuration after Google suspended their spell service
+- Fix vulnerability in handling _session argument of utils/save-prefs (#1489382)
+- Fix iframe onload for upload errors handling (#1489379)
+- Fix address matching in Return-Path header on identity selection (#1489374)
+- Fix text wrapping issue with long unwrappable lines (#1489371)
+- Fixed issues where HTML comments inside style tag would hang Internet Explorer
+- Hide Delivery Status Notification option when smtp_server is unset (#1489336)
+- Display full attachment name using title attribute when name is too long to display (#1489320)
+- Fix attachment icon issue when rare font/language is used (#1489326)
+- Fix expanded thread root message styling after refreshing messages list (#1489327)
+- Fix issue where From address was removed from Cc and Bcc fields when editing a draft (#1489319)
+- Fix error_reporting directive check (#1489323)
+- Fix de_DE localization of "About" label in Help plugin (#1489325)
+
RELEASE 0.9.4
-------------
- Make identities matching case insensitive (#1485480)
@@ -95,8 +131,8 @@ RELEASE 0.9.3
- Fix base URL resolving on attribute values with no quotes (#1489275)
- Fix wrong handling of links with '|' character (#1489276)
- Fix colorspace issue on image conversion using ImageMagick (#1489270)
-- Fix XSS vulnerability when editing a message "as new" or draft (#1489251)
-- Fix XSS vulnerability when saving HTML signatures (#1489251)
+- Fix XSS vulnerability when editing a message "as new" or draft [CVE-2013-5645] (#1489251)
+- Fix XSS vulnerability when saving HTML signatures [CVE-2013-5645] (#1489251)
- Fix rewrite rule in .htaccess (#1489240)
- Fix detecting Turkish language in ISO-8859-9 encoding (#1489252)
- Fix identity-selection using Return-Path headers (#1489241)
@@ -316,7 +352,7 @@ RELEASE 0.8.5
- Fix #countcontrols issue in IE<=8 when text is very long (#1488890)
- Fix unwanted horizontal scrollbar in message preview header (#1488866)
- Add workaround for IE<=8 bug where Content-Disposition:inline was ignored (#1488844)
-- Fix XSS vulnerability in vbscript: and data:text links handling (#1488850)
+- Fix XSS vulnerability in vbscript: and data:text links handling [CVE-2012-6121] (#1488850)
- Fix absolute positioning in HTML messages (#1488819)
- Fix cache (in)validation after setting \Deleted flag
- Fix keybord events on messages list in opera browser (#1488823)
@@ -371,8 +407,8 @@ RELEASE 0.8.1
- Fix bug where domain name was converted to lower-case even with login_lc=false (#1488593)
- Fix lower-casing email address on replies (#1488598)
- Fix line separator in exported messages (#1488603)
-- Fix XSS issue where plain signatures wasn't secured in HTML mode (#1488613)
-- Fix XSS issue where href="javascript:" wasn't secured (#1488613)
+- Fix XSS issue where plain signatures wasn't secured in HTML mode [CVE-2012-4668] (#1488613)
+- Fix XSS issue where href="javascript:" wasn't secured [CVE-2012-3508] (#1488613)
- Fix impossible to create message with empty plain text part (#1488610)
- Fix stripped apostrophes when replying in plain text to HTML message (#1488606)
- Fix inactive Save search option after advanced search (#1488607)
@@ -407,7 +443,7 @@ RELEASE 0.8.0
- Fix removing contact photo using LDAP addressbook (#1488420)
- Fix storing X-ANNIVERSARY date in vCard format (#1488527)
- Update to Mail_Mime-1.8.5 (#1488521)
-- Fix XSS vulnerability in message subject handling using Larry skin (#1488519)
+- Fix XSS vulnerability in message subject handling using Larry skin [CVE-2012-3507] (#1488519)
- Fix handling of links with various URI schemes e.g. "skype:" (#1488106)
- Fix handling of links inside PRE elements on html to text conversion
- Fix indexing of links on html to text conversion
@@ -534,7 +570,7 @@ RELEASE 0.7
- Improved handling of some malformed values encoded with quoted-printable (#1488232)
- Add possibility to do LDAP bind before searching for bind DN
- Fix handling of empty <U> tags in HTML messages (#1488225)
-- Add content filter for embedded attachments to protect from XSS on IE (#1487895)
+- Add content filter for embedded attachments to protect from XSS on IE [CVE-2012-1253] (#1487895)
- Use strpos() instead of strstr() when possible (#1488211)
- Fix handling HTML entities when converting HTML to text (#1488212)
- Fix fit_string_to_size() renders browser and ui unresponsive (#1488207)
@@ -702,7 +738,7 @@ RELEASE 0.6-beta
RELEASE 0.5.4
-------------
-- Fix XSS vulnerability in UI messages (#1488030)
+- Fix XSS vulnerability in UI messages [CVE-2011-2937] (#1488030)
RELEASE 0.5.3
-------------
@@ -752,8 +788,8 @@ RELEASE 0.5.1
- Security: add optional referer check to prevent CSRF in GET requests
- Fix email_dns_check setting not used for identities/contacts (#1487740)
- Fix ICANN example addresses doesn't validate (#1487742)
-- Security: protect login form submission from CSRF
-- Security: prevent from relaying malicious requests through modcss.inc
+- Security: protect login form submission from CSRF [CVE-2011-1491]
+- Security: prevent from relaying malicious requests through modcss.inc [CVE-2011-1492]
- Fix handling of non-image attachments in multipart/related messages (#1487750)
- Fix IDNA support when IDN/INTL modules are in use (#1487742)
- Fix handling of invalid HTML comments in messages (#1487759)
@@ -1196,7 +1232,7 @@ RELEASE 0.3-RC1
---------------
- Fix import of vCard entries with params (#1485453)
- Fix HTML messages output with empty block elements (#1485974)
-- Use request tokens to protect POST requests from CSRF
+- Use request tokens to protect POST requests from CSRF [CVE-2009-4076, CVE-2009-4077]
- Added hook when killing a session
- Added hook to write_log function (#1485971)
- Performance improvements by use UID commands (#1485690)
@@ -1323,7 +1359,7 @@ RELEASE 0.2.1
- Fix large search results on server without SORT capability (#1485668)
- Get rid of preg_replace() with eval modifier and create_function usage (#1485686)
- Bring back <base> and <link> tags in HTML messages
-- Fix XSS vulnerability through background attributes as reported by Julien Cayssol
+- Fix XSS vulnerability through background attributes [CVE-2009-0413]
- Fix problems with backslash as IMAP hierarchy delimiter (#1484467)
- Secure vcard export by getting rid of preg's 'e' modifier use (#1485689)
- Fix authentication when submitting form with existing session (#1485679)
@@ -1381,7 +1417,7 @@ RELEASE 0.2-STABLE
- Allow deleting identities when multiple_identities=false (#1485435)
- Added option focus_on_new_message (#1485374)
- Fix html2text class autoloading on Windows (#1485505)
-- Fix html signature formatting when identity save error occured (#1485426)
+- Fix html signature formatting when identity save error occurred (#1485426)
- Add feedback and set busy when moving folder (#1485497)
- Fix 'Empty' link visibility for some languages e.g. Slovak (#1485489)
- Fix messages count bar overlapping (#1485270)
diff --git a/INSTALL b/INSTALL
index 5b1c21dac..834972c9c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -23,6 +23,8 @@ REQUIREMENTS
- Net_SMTP (latest from https://github.com/pear/Net_SMTP/)
- Net_IDNA2 0.1.1 or newer
- Auth_SASL 1.0.6 or newer
+ - Net_Sieve 1.8.2 or newer (for managesieve plugin)
+ - Crypt_GPG 1.2.0 or newer (for enigma plugin)
* php.ini options (see .htaccess file):
- error_reporting E_ALL & ~E_NOTICE (or lower)
- memory_limit > 16MB (increase as suitable to support large attachments)
diff --git a/bin/package2composer.sh b/bin/package2composer.sh
new file mode 100755
index 000000000..c615a177f
--- /dev/null
+++ b/bin/package2composer.sh
@@ -0,0 +1,109 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/package2composer.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, 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: |
+ | Convert a plugin's package.xml file into a composer.json description |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <thomas@roundcube.net> |
+ +-----------------------------------------------------------------------+
+*/
+
+ini_set('error_reporting', E_ALL & ~E_NOTICE);
+
+list(, $filename, $vendor) = $_SERVER['argv'];
+
+if (!$filename || !is_readable($filename)) {
+ die("Invalid input file name!\nUsage: " . $_SERVER['argv'][0] . " XMLFILE VENDOR\n");
+}
+
+if (!$vendor) {
+ $vendor = 'anonymous';
+}
+
+$package = new SimpleXMLElement(file_get_contents($filename));
+
+$data = array(
+ 'name' => $vendor . '/' . strval($package->name),
+ 'type' => 'roundcube-plugin',
+ 'description' => trim(strval($package->description), '- ') ? trim(strval($package->description)) : trim(strval($package->summary)),
+ 'homepage' => strval($package->uri),
+ 'license' => 'GPLv3+',
+ 'version' => strval($package->version->release),
+ 'authors' => array(),
+ 'repositories' => array(
+ array('type' => 'composer', 'url' => 'http://plugins.roundcube.net'),
+ ),
+ 'require' => array(
+ 'php' => '>=5.3.0',
+ 'roundcube/plugin-installer' => '>=0.1.3',
+ ),
+);
+
+if ($package->license) {
+ $data['license'] = strval($package->license);
+}
+
+if ($package->lead) {
+ foreach ($package->lead as $lead) {
+ if (strval($lead->active) == 'no') {
+ continue;
+ }
+ $data['authors'][] = array(
+ 'name' => strval($lead->name),
+ 'email' => strval($lead->email),
+ 'role' => 'Lead',
+ );
+ }
+}
+
+if ($devs = $package->developer) {
+ foreach ($package->developer as $dev) {
+ $data['authors'][] = array(
+ 'name' => strval($dev->name),
+ 'email' => strval($dev->email),
+ 'role' => 'Developer',
+ );
+ }
+}
+
+if ($package->dependencies->required->extension) {
+ foreach ($package->dependencies->required->extension as $ext) {
+ $data['require']['ext-' . strval($ext->name)] = '*';
+ }
+}
+
+// remove empty values
+$data = array_filter($data);
+
+// use the JSON encoder from the Composer package
+if (is_file('composer.phar')) {
+ include 'phar://composer.phar/src/Composer/Json/JsonFile.php';
+ echo \Composer\Json\JsonFile::encode($data);
+}
+// PHP 5.4's json_encode() does the job, too
+else if (defined('JSON_PRETTY_PRINT')) {
+ $flags = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT & JSON_UNESCAPED_SLASHES : 0;
+ echo json_encode($data, $flags);
+}
+else {
+ fputs(STDERR,
+"FAILED! composer.phar not found in current directory.
+
+Please download it from http://getcomposer.org/download/ or with
+ curl -s http://getcomposer.org/installer | php
+");
+}
+
+echo "\n";
+
diff --git a/bin/transifexpull.sh b/bin/transifexpull.sh
new file mode 100755
index 000000000..ba26a07f1
--- /dev/null
+++ b/bin/transifexpull.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# In 'translator' mode files will contain empty translated texts
+# where translation is not available, we'll remove these later
+
+# Note: there's a bug in txclib, so if the command below doesn't
+# work see https://github.com/transifex/transifex-client/commit/a80320735973dd608b48520bf3b89ad53e2b088b
+
+tx --debug pull -a --mode translator
+
+PWD=`dirname "$0"`
+
+do_clean()
+{
+ # do not cleanup en_US files
+ echo "$1" | grep -v en_US > /dev/null || return
+
+ echo "Cleaning $1"
+
+ # remove untranslated/empty texts
+ perl -pi -e "s/^\\\$labels\[[^]]+\]\s+=\s+'';\n//" $1
+ perl -pi -e "s/^\\\$messages\[[^]]+\]\s+=\s+'';\n//" $1
+ # remove variable initialization
+ perl -pi -e "s/^\\\$(labels|messages)\s*=\s*array\(\);\n//" $1
+ # remove (one-line) comments
+ perl -pi -e "s/^\\/\\/.*//" $1
+ # remove empty lines (but not in file header)
+ perl -ne 'print if ($. < 18 || length($_) > 1)' $1 > $1.tmp
+ mv $1.tmp $1
+}
+
+# clean up translation files
+for file in $PWD/../program/localization/*/*.inc; do
+ do_clean $file
+done
+for file in $PWD/../plugins/*/localization/*.inc; do
+ do_clean $file
+done
diff --git a/bin/updatedb.sh b/bin/updatedb.sh
index b4ed8b7ba..1f5e18434 100755
--- a/bin/updatedb.sh
+++ b/bin/updatedb.sh
@@ -72,13 +72,20 @@ if (!$version && $opts['version']) {
'0.2-alpha' => 2008040500,
'0.2-beta' => 2008060900,
'0.2-stable' => 2008092100,
+ '0.2.1' => 2008092100,
+ '0.2.2' => 2008092100,
'0.3-stable' => 2008092100,
'0.3.1' => 2009090400,
'0.4-beta' => 2009103100,
+ '0.4' => 2010042300,
+ '0.4.1' => 2010042300,
'0.4.2' => 2010042300,
'0.5-beta' => 2010100600,
'0.5' => 2010100600,
'0.5.1' => 2010100600,
+ '0.5.2' => 2010100600,
+ '0.5.3' => 2010100600,
+ '0.5.4' => 2010100600,
'0.6-beta' => 2011011200,
'0.6' => 2011011200,
'0.7-beta' => 2011092800,
diff --git a/config/.htaccess b/config/.htaccess
deleted file mode 100644
index 8e6a345dc..000000000
--- a/config/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-Order allow,deny
-Deny from all \ No newline at end of file
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
index bf7c4df2a..fc7e92fd7 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -30,6 +30,9 @@ $config['db_dsnw'] = 'mysql://roundcube:@localhost/roundcubemail';
// useful for database replication
$config['db_dsnr'] = '';
+// Disable the use of already established dsnw connections for subsequent reads
+$config['db_dsnw_noread'] = false;
+
// use persistent db-connections
// beware this will not "always" work as expected
// see: http://www.php.net/manual/en/features.persistent-connections.php
@@ -38,6 +41,16 @@ $config['db_persistent'] = false;
// you can define specific table (and sequence) names prefix
$config['db_prefix'] = '';
+// Mapping of table names and connections to use for ALL operations.
+// This can be used in a setup with replicated databases and a DB master
+// where read/write access to cache tables should not go to master.
+$config['db_table_dsn'] = array(
+// 'cache' => 'r',
+// 'cache_index' => 'r',
+// 'cache_thread' => 'r',
+// 'cache_messages' => 'r',
+);
+
// ----------------------------------
// LOGGING/DEBUGGING
@@ -239,12 +252,18 @@ $config['enable_installer'] = false;
// don't allow these settings to be overriden by the user
$config['dont_override'] = array();
+// define which settings should be listed under the 'advanced' block
+// which is hidden by default
+$config['advanced_prefs'] = array();
+
// provide an URL where a user can get support for this Roundcube installation
// PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!
$config['support_url'] = '';
// replace Roundcube logo with this image
// specify an URL relative to the document root of this Roundcube installation
+// an array can be used to specify different logos for specific template files, '*' for default logo
+// for example array("*" => "/images/roundcube_logo.png", "messageprint" => "/images/roundcube_logo_print.png")
$config['skin_logo'] = null;
// automatically create a new Roundcube user when log-in the first time.
@@ -551,15 +570,20 @@ $config['enable_spellcheck'] = true;
// Setting it to 'shared' will make the dictionary shared by all users.
$config['spellcheck_dictionary'] = false;
-// Set the spell checking engine. 'googie' is the default.
-// 'pspell' and 'enchant' are also available, but they require
-// PHP Pspell or Enchant extensions. When using Nox Spell Server, also set 'googie' here.
+// Set the spell checking engine. Possible values:
+// - 'googie' - the default
+// - 'pspell' - requires the PHP Pspell module and aspell installed
+// - 'enchant' - requires the PHP Enchant module
+// - 'atd' - install your own After the Deadline server or check with the people at http://www.afterthedeadline.com before using their API
+// Since Google shut down their public spell checking service, you need to
+// connect to a Nox Spell Server when using 'googie' here. Therefore specify the 'spellcheck_uri'
$config['spellcheck_engine'] = 'googie';
-// 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
+// For locally installed Nox Spell Server or After the Deadline services,
+// please specify the URI to call it.
+// Get Nox Spell Server from http://orangoo.com/labs/?page_id=72 or
+// the After the Deadline package from http://www.afterthedeadline.com.
+// Leave empty to use the public API of service.afterthedeadline.com
$config['spellcheck_uri'] = '';
// These languages can be selected for spell checking.
@@ -595,6 +619,12 @@ $config['upload_progress'] = false;
// Setting it to 0, disables the feature.
$config['undo_timeout'] = 0;
+// A static list of canned responses which are immutable for the user
+$config['compose_responses_static'] = array(
+// array('name' => 'Canned Response 1', 'text' => 'Static Response One'),
+// array('name' => 'Canned Response 2', 'text' => 'Static Response Two'),
+);
+
// ----------------------------------
// ADDRESSBOOK SETTINGS
// ----------------------------------
@@ -644,6 +674,7 @@ $config['ldap_public']['Verisign'] = array(
'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.
+ // When 'user_specific' is enabled following variables can be used in base_dn/bind_dn config:
// %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 '@'.
@@ -660,6 +691,8 @@ $config['ldap_public']['Verisign'] = array(
// DN and password to bind as before searching for bind DN, if anonymous search is not allowed
'search_bind_dn' => '',
'search_bind_pw' => '',
+ // Optional map of replacement strings => attributes used when binding for an individual address book
+ 'search_bind_attrib' => array(), // e.g. array('%udc' => 'ou')
// Default for %dn variable if search doesn't return DN value
'search_dn_default' => '',
// Optional authentication identifier to be used as SASL authorization proxy
@@ -741,14 +774,19 @@ $config['ldap_public']['Verisign'] = array(
// 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
- 'member_filter' => '(objectclass=*)', // Optional filter to use when querying for group members
- 'vlv' => false, // Use VLV controls to list groups
+ 'base_dn' => '',
+ 'scope' => 'sub', // Search mode: sub|base|list
+ 'filter' => '(objectClass=groupOfNames)',
+ 'object_classes' => array('top', 'groupOfNames'), // Object classes to be assigned to new groups
+ 'member_attr' => 'member', // Name of the default member attribute, e.g. uniqueMember
+ 'name_attr' => 'cn', // Attribute to be used as group name
+ 'email_attr' => 'mail', // Group email address attribute (e.g. for mailing lists)
+ 'member_filter' => '(objectclass=*)', // Optional filter to use when querying for group members
+ 'vlv' => false, // Use VLV controls to list groups
+ 'class_member_attr' => array( // Mapping of group object class to member attribute used in these objects
+ 'groupofnames' => 'member',
+ 'groupofuniquenames' => 'uniquemember'
+ ),
),
// this configuration replaces the regular groups listing in the directory tree with
// a hard-coded list of groups, each listing entries with the configured base DN and filter.
@@ -958,6 +996,7 @@ $config['mdn_requests'] = 0;
$config['mdn_default'] = 0;
// Delivery Status Notification checkbox default state
+// Note: This can be used only if smtp_server is non-empty
$config['dsn_default'] = 0;
// Place replies in the folder of the message being replied to
@@ -982,5 +1021,14 @@ $config['autocomplete_single'] = false;
// Georgia, Helvetica, Impact, Tahoma, Terminal, Times New Roman, Trebuchet MS, Verdana
$config['default_font'] = 'Verdana';
+// Default font size for composed HTML message.
+// Supported sizes: 8pt, 10pt, 12pt, 14pt, 18pt, 24pt, 36pt
+$config['default_font_size'] = '10pt';
+
// Enables display of email address with name instead of a name (and address in title)
$config['message_show_email'] = false;
+
+// Default behavior of Reply-All button:
+// 0 - Reply-All always
+// 1 - Reply-List if mailing list is detected
+$config['reply_all_mode'] = 0;
diff --git a/index.php b/index.php
index 3be71f249..72515203d 100644
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
/*
+-------------------------------------------------------------------------+
| Roundcube Webmail IMAP Client |
- | Version 1.0-git |
+ | Version 0.9.5 |
| |
| Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
@@ -39,7 +39,7 @@
require_once 'program/include/iniset.php';
// init application, start session, init output class, etc.
-$RCMAIL = rcmail::get_instance($GLOBALS['env']);
+$RCMAIL = rcmail::get_instance();
// Make the whole PHP output non-cacheable (#1487797)
$RCMAIL->output->nocacheing_headers();
@@ -138,7 +138,7 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
}
else {
if (!$auth['valid']) {
- $error_code = RCMAIL::ERROR_INVALID_REQUEST;
+ $error_code = RCMAIL::ERROR_INVALID_REQUEST;
}
else {
$error_code = $auth['error'] ? $auth['error'] : $RCMAIL->login_error();
@@ -153,9 +153,6 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
$error_message = $error_labels[$error_code] ? $error_labels[$error_code] : 'loginfailed';
- // log failed login
- $RCMAIL->log_login($auth['user'], true, $error_code);
-
$OUTPUT->show_message($error_message, 'warning');
$RCMAIL->plugins->exec_hook('login_failed', array(
'code' => $error_code, 'host' => $auth['host'], 'user' => $auth['user']));
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
index 9c9794cc2..df05db493 100644
--- a/installer/rcube_install.php
+++ b/installer/rcube_install.php
@@ -406,7 +406,7 @@ class rcube_install
*
* @param rcube_db Database object
*
- * @return boolean True if the schema is up-to-date, false if not or an error occured
+ * @return boolean True if the schema is up-to-date, false if not or an error occurred
*/
function db_schema_check($DB)
{
diff --git a/logs/.htaccess b/logs/.htaccess
deleted file mode 100644
index 8e6a345dc..000000000
--- a/logs/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-Order allow,deny
-Deny from all \ No newline at end of file
diff --git a/main.inc.php.dist b/main.inc.php.dist
new file mode 100644
index 000000000..15512f5dc
--- /dev/null
+++ b/main.inc.php.dist
@@ -0,0 +1,900 @@
+<?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)
+// Note: There's a known issue where using ssl connection with
+// timeout > 0 causes connection errors (https://bugs.php.net/bug.php?id=54511)
+$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 authentication cookie name. Default: 'roundcube_sessauth'
+$rcmail_config['session_auth_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
+// Note: do not use ambiguous formats like m/d/Y
+$rcmail_config['date_formats'] = array('Y-m-d', 'Y/m/d', 'Y.m.d', 'd-m-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
+// Note: This can be used only if smtp_server is non-empty
+$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/acl/acl.php b/plugins/acl/acl.php
index a840bcd58..466185dcc 100644
--- a/plugins/acl/acl.php
+++ b/plugins/acl/acl.php
@@ -9,18 +9,18 @@
*
* Copyright (C) 2011-2012, Kolab Systems AG
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class acl extends rcube_plugin
@@ -55,7 +55,7 @@ class acl extends rcube_plugin
*/
function acl_actions()
{
- $action = trim(rcube_utils::get_input_value('_act', rcube_utils::INPUT_GPC));
+ $action = trim(get_input_value('_act', RCUBE_INPUT_GPC));
// Connect to IMAP
$this->rc->storage_init();
@@ -85,8 +85,8 @@ class acl extends rcube_plugin
{
$this->load_config();
- $search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true);
- $sid = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
+ $search = get_input_value('_search', RCUBE_INPUT_GPC, true);
+ $sid = get_input_value('_id', RCUBE_INPUT_GPC);
$users = array();
if ($this->init_ldap()) {
@@ -148,7 +148,6 @@ class acl extends rcube_plugin
// Load localization and include scripts
$this->load_config();
- $this->specials = $this->rc->config->get('acl_specials', $this->specials);
$this->add_texts('localization/', array('deleteconfirm', 'norights',
'nouser', 'deleting', 'saving'));
$this->include_script('acl.js');
@@ -158,12 +157,12 @@ class acl extends rcube_plugin
// add Info fieldset if it doesn't exist
if (!isset($args['form']['props']['fieldsets']['info']))
$args['form']['props']['fieldsets']['info'] = array(
- 'name' => $this->rc->gettext('info'),
+ 'name' => rcube_label('info'),
'content' => array());
// Display folder rights to 'Info' fieldset
$args['form']['props']['fieldsets']['info']['content']['myrights'] = array(
- 'label' => rcube::Q($this->gettext('myrights')),
+ 'label' => Q($this->gettext('myrights')),
'value' => $this->acl2text($myrights)
);
@@ -187,7 +186,7 @@ class acl extends rcube_plugin
$this->rc->output->add_label('autocompletechars', 'autocompletemore');
$args['form']['sharing'] = array(
- 'name' => rcube::Q($this->gettext('sharing')),
+ 'name' => Q($this->gettext('sharing')),
'content' => $this->rc->output->parse('acl.table', false, false),
);
@@ -385,6 +384,7 @@ class acl extends rcube_plugin
$table->add_header(array('class' => 'acl'.$key, 'title' => $label), $label);
}
+ $i = 1;
$js_table = array();
foreach ($acl as $user => $rights) {
if ($this->rc->storage->conn->user == $user) {
@@ -393,14 +393,14 @@ class acl extends rcube_plugin
// filter out virtual rights (c or d) the server may return
$userrights = array_intersect($rights, $supported);
- $userid = rcube_utils::html_identifier($user);
+ $userid = html_identifier($user);
if (!empty($this->specials) && in_array($user, $this->specials)) {
$user = $this->gettext($user);
}
$table->add_row(array('id' => 'rcmrow'.$userid));
- $table->add('user', rcube::Q($user));
+ $table->add('user', Q($user));
foreach ($items as $key => $right) {
$in = $this->acl_compare($userrights, $right);
@@ -428,10 +428,10 @@ class acl extends rcube_plugin
*/
private function action_save()
{
- $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)); // UTF7-IMAP
- $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_GPC));
- $acl = trim(rcube_utils::get_input_value('_acl', rcube_utils::INPUT_GPC));
- $oldid = trim(rcube_utils::get_input_value('_old', rcube_utils::INPUT_GPC));
+ $mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); // UTF7-IMAP
+ $user = trim(get_input_value('_user', RCUBE_INPUT_GPC));
+ $acl = trim(get_input_value('_acl', RCUBE_INPUT_GPC));
+ $oldid = trim(get_input_value('_old', RCUBE_INPUT_GPC));
$acl = array_intersect(str_split($acl), $this->rights_supported());
$users = $oldid ? array($user) : explode(',', $user);
@@ -445,7 +445,7 @@ class acl extends rcube_plugin
}
else if (!empty($user)) {
if (!strpos($user, '@') && ($realm = $this->get_realm())) {
- $user .= '@' . rcube_utils::idn_to_ascii(preg_replace('/^@/', '', $realm));
+ $user .= '@' . rcube_idn_to_ascii(preg_replace('/^@/', '', $realm));
}
$username = $user;
}
@@ -459,7 +459,7 @@ class acl extends rcube_plugin
if ($user != $_SESSION['username'] && $username != $_SESSION['username']) {
if ($this->rc->storage->set_acl($mbox, $user, $acl)) {
- $ret = array('id' => rcube_utils::html_identifier($user),
+ $ret = array('id' => html_identifier($user),
'username' => $username, 'acl' => implode($acl), 'old' => $oldid);
$this->rc->output->command('acl_update', $ret);
$result++;
@@ -480,15 +480,15 @@ class acl extends rcube_plugin
*/
private function action_delete()
{
- $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)); //UTF7-IMAP
- $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_GPC));
+ $mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); //UTF7-IMAP
+ $user = trim(get_input_value('_user', RCUBE_INPUT_GPC));
$user = explode(',', $user);
foreach ($user as $u) {
$u = trim($u);
if ($this->rc->storage->delete_acl($mbox, $u)) {
- $this->rc->output->command('acl_remove_row', rcube_utils::html_identifier($u));
+ $this->rc->output->command('acl_remove_row', html_identifier($u));
}
else {
$error = true;
@@ -512,8 +512,8 @@ class acl extends rcube_plugin
return;
}
- $this->mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)); // UTF7-IMAP
- $advanced = trim(rcube_utils::get_input_value('_mode', rcube_utils::INPUT_GPC));
+ $this->mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); // UTF7-IMAP
+ $advanced = trim(get_input_value('_mode', RCUBE_INPUT_GPC));
$advanced = $advanced == 'advanced' ? true : false;
// Save state in user preferences
@@ -548,12 +548,12 @@ class acl extends rcube_plugin
foreach ($supported as $right) {
if (in_array($right, $rights)) {
- $list[] = html::tag('li', null, rcube::Q($this->gettext('acl' . $right)));
+ $list[] = html::tag('li', null, Q($this->gettext('acl' . $right)));
}
}
if (count($list) == count($supported))
- return rcube::Q($this->gettext('aclfull'));
+ return Q($this->gettext('aclfull'));
return html::tag('ul', $attrib, implode("\n", $list));
}
diff --git a/plugins/acl/config.inc.php.dist b/plugins/acl/config.inc.php.dist
index 3f0b1efb6..f957a233a 100644
--- a/plugins/acl/config.inc.php.dist
+++ b/plugins/acl/config.inc.php.dist
@@ -3,23 +3,17 @@
// Default look of access rights table
// In advanced mode all access rights are displayed separately
// In simple mode access rights are grouped into four groups: read, write, delete, full
-$config['acl_advanced_mode'] = false;
+$rcmail_config['acl_advanced_mode'] = false;
// LDAP addressbook that would be searched for user names autocomplete.
-// That should be an array refering to the $config['ldap_public'] array key
+// That should be an array refering to the $rcmail_config['ldap_public'] array key
// or complete addressbook configuration array.
-$config['acl_users_source'] = '';
+$rcmail_config['acl_users_source'] = '';
// The LDAP attribute which will be used as ACL user identifier
-$config['acl_users_field'] = 'mail';
+$rcmail_config['acl_users_field'] = 'mail';
// The LDAP search filter will be &'d with search queries
-$config['acl_users_filter'] = '';
-
-// Include the following 'special' access control subjects in the ACL dialog;
-// Defaults to array('anyone', 'anonymous') (not when set to an empty array)
-// Example: array('anyone') to exclude 'anonymous'.
-// Set to an empty array to exclude all special aci subjects.
-$config['acl_specials'] = array('anyone', 'anonymous');
+$rcmail_config['acl_users_filter'] = '';
?>
diff --git a/plugins/acl/localization/az_AZ.inc b/plugins/acl/localization/az_AZ.inc
index 5d875a2b7..d5543ddaa 100644
--- a/plugins/acl/localization/az_AZ.inc
+++ b/plugins/acl/localization/az_AZ.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'Giriş hüququnun saxlanılması...';
$messages['updatesuccess'] = 'Giriş hüququ dəyişdirildi';
$messages['deletesuccess'] = 'Giriş hüququ silindi';
$messages['createsuccess'] = 'Giriş hüququ əlavə edildi';
-$messages['updateerror'] = 'Hüquqları yeniləmək alınmadı';
+$messages['updateerror'] = 'Giriş hüququnu yeniləmək mümkün deyil';
$messages['deleteerror'] = 'Giriş hüququnu silmək mümkün deyil';
$messages['createerror'] = 'Giriş hüququnu əlavə etmək mümkün deyil';
$messages['deleteconfirm'] = 'Seçilmiş istifadəçilərin giriş hüququnu silməkdə əminsiniz?';
diff --git a/plugins/acl/localization/be_BE.inc b/plugins/acl/localization/be_BE.inc
new file mode 100644
index 000000000..bce5915f0
--- /dev/null
+++ b/plugins/acl/localization/be_BE.inc
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'СумеÑны доÑтуп';
+$labels['myrights'] = 'Правы доÑтупа';
+$labels['username'] = 'КарыÑтальнік:';
+$labels['advanced'] = 'ÑкÑпертны Ñ€Ñжым';
+$labels['newuser'] = 'Дадаць запіÑ';
+$labels['actions'] = 'ДзеÑнні з правамі доÑтупа...';
+$labels['anyone'] = 'УÑе карыÑтальнікі (любыÑ)';
+$labels['anonymous'] = 'ГоÑці (ананімныÑ)';
+$labels['identifier'] = 'ІдÑнтыфікатар';
+$labels['acll'] = 'Пошук';
+$labels['aclr'] = 'Прачытаць паведамленні';
+$labels['acls'] = 'Пакінуць Ñтан Бачанае';
+$labels['aclw'] = 'Флагі запіÑваннÑ';
+$labels['acli'] = 'УÑтавіць (капіраваць у)';
+$labels['aclp'] = 'Ðдправіць';
+$labels['aclc'] = 'Стварыць ÑƒÐºÐ»Ð°Ð´Ð·ÐµÐ½Ñ‹Ñ Ð¿Ð°Ð¿ÐºÑ–';
+$labels['aclk'] = 'Стварыць ÑƒÐºÐ»Ð°Ð´Ð·ÐµÐ½Ñ‹Ñ Ð¿Ð°Ð¿ÐºÑ–';
+$labels['acld'] = 'Выдаліць паведамленні';
+$labels['aclt'] = 'Выдаліць паведамленні';
+$labels['acle'] = 'Знішчыць паведамленні';
+$labels['aclx'] = 'Выдаліць папку';
+$labels['acla'] = 'ÐдмініÑтраваць';
+$labels['aclfull'] = 'Поўны доÑтуп';
+$labels['aclother'] = 'Іншае';
+$labels['aclread'] = 'Чытанне';
+$labels['aclwrite'] = 'ЗапіÑ';
+$labels['acldelete'] = 'Выдаленне';
+$labels['shortacll'] = 'Пошук';
+$labels['shortaclr'] = 'Чытанне';
+$labels['shortacls'] = 'Пакінуць';
+$labels['shortaclw'] = 'ЗапіÑванне';
+$labels['shortacli'] = 'Даданне';
+$labels['shortaclp'] = 'Ðдпраўленне';
+$labels['shortaclc'] = 'СтварÑнне';
+$labels['shortaclk'] = 'СтварÑнне';
+$labels['shortacld'] = 'Выдаленне';
+$labels['shortaclt'] = 'Выдаленне';
+$labels['shortacle'] = 'ЗнішчÑнне';
+$labels['shortaclx'] = 'Выдаленне папкі';
+$labels['shortacla'] = 'ÐдмініÑтраванне';
+$labels['shortaclother'] = 'Іншае';
+$labels['shortaclread'] = 'Чытанне';
+$labels['shortaclwrite'] = 'ЗапіÑ';
+$labels['shortacldelete'] = 'Выдаленне';
+$labels['longacll'] = 'Папку можна пабачыць у ÑпіÑах Ñ– падпіÑацца на Ñе';
+$labels['longaclr'] = 'Папку можна адчыніць Ð´Ð»Ñ Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ';
+$labels['longacls'] = 'Ðа паведамленнÑÑ… можна пераключаць флаг Бачанае';
+$labels['longaclw'] = 'Ðа паведамленнÑÑ… можна мÑнÑць ÐºÐ»ÑŽÑ‡Ð°Ð²Ñ‹Ñ Ñловы Ñ– пераключаць флагі, апроч Бачанае Ñ– Выдаленае';
+$labels['longacli'] = 'Паведамленні могуць быць запіÑÐ°Ð½Ñ‹Ñ Ð°Ð»ÑŒÐ±Ð¾ ÑкапіÑÐ²Ð°Ð½Ñ‹Ñ Ñž папку';
+$labels['longaclp'] = 'Паведамленні могуць быць Ð°Ð´Ð¿Ñ€Ð°ÑžÐ»ÐµÐ½Ñ‹Ñ Ñž гÑтую папку';
+$labels['longaclc'] = 'Папкі могуць быць Ñтвораны (альбо перайменаваны) наўпроÑÑ‚ пад гÑтай папкай';
+$labels['longaclk'] = 'Папкі могуць быць Ñтвораны (альбо перайменаваны) наўпроÑÑ‚ пад гÑтай папкай';
+$labels['longacld'] = 'Ðа паведамленнÑÑ… можна пераключаць флаг Выдаленае';
+$labels['longaclt'] = 'Ðа паведамленнÑÑ… можна пераключаць флаг Выдаленае';
+$labels['longacle'] = 'Паведамленні могуць быць знішчаны';
+$labels['longaclx'] = 'Папку можна выдаліць альбо перайменаваць';
+$labels['longacla'] = 'Правы доÑтупу на папку можна змÑнÑць';
+$labels['longaclfull'] = 'Поўны доÑтуп, уключна з адмінÑтраваннем папкі';
+$labels['longaclread'] = 'Папку можна адчыніць Ð´Ð»Ñ Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ';
+$labels['longaclwrite'] = 'Паведамленні могуць быць пазначаныÑ, запіÑÐ°Ð½Ñ‹Ñ Ð°Ð»ÑŒÐ±Ð¾ ÑкапіÑÐ²Ð°Ð½Ñ‹Ñ Ñž папку';
+$labels['longacldelete'] = 'Паведамленні можна выдалÑць';
+$messages['deleting'] = 'Правы доÑтупу выдалÑюцца...';
+$messages['saving'] = 'Правы доÑтупу захоўваюцца...';
+$messages['updatesuccess'] = 'Правы доÑтупу зменены';
+$messages['deletesuccess'] = 'Правы доÑтупу выдалены';
+$messages['createsuccess'] = 'Правы доÑтупу дададзены';
+$messages['updateerror'] = 'Ðе ўдалоÑÑ Ð°Ð±Ð½Ð°Ð²Ñ–Ñ†ÑŒ правы доÑтупу';
+$messages['deleteerror'] = 'Ðе ўдалоÑÑ Ð²Ñ‹Ð´Ð°Ð»Ñ–Ñ†ÑŒ правы доÑтупу';
+$messages['createerror'] = 'Ðе ўдалоÑÑ Ð´Ð°Ð´Ð°Ñ†ÑŒ правы доÑтупу';
+$messages['deleteconfirm'] = 'Ðапраўду выдаліць правы доÑтупу Ð´Ð»Ñ Ð²Ñ‹Ð»ÑƒÑ‡Ð°Ð½Ð°Ð³Ð° карыÑтальніка(Ñž)?';
+$messages['norights'] = 'Жадных правоў не зададзена!';
+$messages['nouser'] = 'Жадных імёнаў карыÑтальнікаў не зададзена!';
+?>
diff --git a/plugins/acl/localization/bg_BG.inc b/plugins/acl/localization/bg_BG.inc
new file mode 100644
index 000000000..2e3c57dcf
--- /dev/null
+++ b/plugins/acl/localization/bg_BG.inc
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'СподелÑне';
+$labels['myrights'] = 'Права за доÑтъп';
+$labels['username'] = 'Потребител:';
+$labels['advanced'] = 'разширен режим';
+$labels['newuser'] = 'ДобавÑне на запиÑ';
+$labels['actions'] = 'ДейÑÑ‚Ð²Ð¸Ñ Ð½Ð° права за доÑтъп...';
+$labels['anyone'] = 'Ð’Ñички потребители (който и да е)';
+$labels['anonymous'] = 'ГоÑти (анонимни)';
+$labels['identifier'] = 'Индентификатор';
+$labels['acll'] = 'ПретърÑване';
+$labels['aclr'] = 'Четене на пиÑма';
+$labels['acls'] = 'Запазване на ВидÑно';
+$labels['aclw'] = 'ЗапиÑване на флагове';
+$labels['acli'] = 'Вмъкване (Копиране в)';
+$labels['aclp'] = 'Изпращане';
+$labels['aclc'] = 'Създаване на подпапки';
+$labels['aclk'] = 'Създаване на подпапки';
+$labels['acld'] = 'Изтриване на пиÑма';
+$labels['aclt'] = 'Изтриване на пиÑмо';
+$labels['acle'] = 'Заличаване';
+$labels['aclx'] = 'Изтриване на папка';
+$labels['acla'] = 'ÐдминиÑтриране';
+$labels['aclfull'] = 'Пълен контрол';
+$labels['aclother'] = 'Други';
+$labels['aclread'] = 'Четене';
+$labels['aclwrite'] = 'ПиÑане';
+$labels['acldelete'] = 'Изтриване';
+$labels['shortacll'] = 'ТърÑене';
+$labels['shortaclr'] = 'Четене';
+$labels['shortacls'] = 'Запазване';
+$labels['shortaclw'] = 'ПиÑане';
+$labels['shortacli'] = 'Вмъкване';
+$labels['shortaclp'] = 'Изпращане';
+$labels['shortaclc'] = 'Създаване';
+$labels['shortaclk'] = 'Създаване';
+$labels['shortacld'] = 'Изтриване';
+$labels['shortaclt'] = 'Изтриване';
+$labels['shortacle'] = 'Заличаване';
+$labels['shortaclx'] = 'Изтриване на папка';
+$labels['shortacla'] = 'ÐдминиÑтриране';
+$labels['shortaclother'] = 'Други';
+$labels['shortaclread'] = 'Четене';
+$labels['shortaclwrite'] = 'ПиÑане';
+$labels['shortacldelete'] = 'Изтриване';
+$labels['longacll'] = 'Папката е видима в ÑпиÑъците и може да Ñе абонирате';
+$labels['longaclr'] = 'Папката може да бъде отворена за четене';
+$labels['longacls'] = 'Флаг ВидÑно може да бъде променен.';
+$labels['longaclw'] = 'Флаговете и кл. думи за пиÑмата могат да бъдат променÑни, без ВидÑно и Изтрито.';
+$labels['longacli'] = 'ПиÑмата могат да бъдат пиÑани или копирани към папката.';
+$labels['longaclp'] = 'ПиÑмата могат да бъдат пиÑани в папката';
+$labels['longaclc'] = 'Папките могат да бъдат Ñъздавани (или преименувани) директно в тази папка';
+$labels['longaclk'] = 'Папките могат да бъдат Ñъздавани (или преименувани) в тази оÑновна папка';
+$labels['longacld'] = 'Флагът Изтрито може да бъде променÑн';
+$labels['longaclt'] = 'Флагът Изтрито може да бъде променÑн';
+$labels['longacle'] = 'ПиÑмата могат да бъдат заличавани';
+$labels['longaclx'] = 'Папката може да бъде изтривана или преименувана';
+$labels['longacla'] = 'Правата за доÑтъп до папката могат да бъдат променÑни';
+$labels['longaclfull'] = 'Пълен контрол, включително и админиÑтриране на папките';
+$labels['longaclread'] = 'Папката може да бъде отворена за четене';
+$labels['longaclwrite'] = 'ПиÑмата могат да бъдат маркирани, запиÑвани или копирани в папката';
+$labels['longacldelete'] = 'ПиÑмата могат да бъдат изтривани';
+$messages['deleting'] = 'Изтриване на права за доÑтъп...';
+$messages['saving'] = 'Запазване на права за доÑтъп...';
+$messages['updatesuccess'] = 'Правата за доÑтъп Ñа променени уÑпешно';
+$messages['deletesuccess'] = 'Правата за доÑтъп Ñа изтрити уÑпешно';
+$messages['createsuccess'] = 'Правата за доÑтъп Ñа добавени уÑпешно';
+$messages['updateerror'] = 'Ðевъзможно модифициране на правата за доÑтъп';
+$messages['deleteerror'] = 'Ðевъзможно изтриване на права за доÑтъп';
+$messages['createerror'] = 'Ðевъзможно добавÑне на права за доÑтъп';
+$messages['deleteconfirm'] = 'Сигурни ли Ñте, че желаете да премахнате правата за доÑтъп от избраните потребители?';
+$messages['norights'] = 'ÐÑма указани права!';
+$messages['nouser'] = 'ÐÑма указано потребителÑко име!';
+?>
diff --git a/plugins/acl/localization/el_GR.inc b/plugins/acl/localization/el_GR.inc
new file mode 100644
index 000000000..56e1081b3
--- /dev/null
+++ b/plugins/acl/localization/el_GR.inc
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'ΜοιÏασμα';
+$labels['myrights'] = 'Δικαιώματα ΠÏόσβασης ';
+$labels['username'] = 'ΧÏηστης:';
+$labels['advanced'] = 'Ï€Ïοηγμένη λειτουÏγία ';
+$labels['newuser'] = 'ΠÏοσθήκη καταχώÏησης ';
+$labels['actions'] = 'ΠÏόσβαση σωστων ενέÏγειων...';
+$labels['anyone'] = 'Όλοι οι χÏήστες (ο καθένας)';
+$labels['anonymous'] = 'Οι επισκέπτες (ανώνυμα) ';
+$labels['identifier'] = 'ΑναγνωÏιστικό';
+$labels['acll'] = 'Αναζήτηση ';
+$labels['aclr'] = 'Διαβάστε τα μηνÏματα ';
+$labels['acls'] = 'ΚÏατήστε Επίσκεψη κατάσταση';
+$labels['aclw'] = 'ΔημιουÏγια σημαιων';
+$labels['acli'] = 'Εισάγωγη (ΑντιγÏαφή σε) ';
+$labels['aclp'] = 'ΚαταχώÏηση';
+$labels['aclc'] = 'ΔημιουÏγια υποφακελων';
+$labels['aclk'] = 'ΔημιουÏγια υποφακελων';
+$labels['acld'] = 'ΔιαγÏαφή μηνυμάτων';
+$labels['aclt'] = 'ΔιαγÏαφή μηνυμάτων';
+$labels['acle'] = 'Απαλειψη';
+$labels['aclx'] = 'ΔιαγÏαφή φακέλου';
+$labels['acla'] = 'ΧοÏηγος';
+$labels['aclfull'] = 'ΠληÏης ελεγχος';
+$labels['aclother'] = 'Άλλα';
+$labels['aclread'] = 'Αναγνωση';
+$labels['aclwrite'] = 'ΔημιουÏγια';
+$labels['acldelete'] = 'ΔιαγÏαφή';
+$labels['shortacll'] = 'Αναζήτηση';
+$labels['shortaclr'] = 'Αναγνωση';
+$labels['shortacls'] = 'ΚÏατηση';
+$labels['shortaclw'] = 'ΔημιουÏγια';
+$labels['shortacli'] = 'ΑντιστÏοφη';
+$labels['shortaclp'] = 'ΚαταχωÏηση';
+$labels['shortaclc'] = 'ΔημιουÏγία';
+$labels['shortaclk'] = 'ΔημιουÏγία';
+$labels['shortacld'] = 'ΔιαγÏαφή';
+$labels['shortaclt'] = 'ΔιαγÏαφή';
+$labels['shortacle'] = 'Απαλειψη';
+$labels['shortaclx'] = 'ΔιαγÏαφη φακελου';
+$labels['shortacla'] = 'ΧοÏηγος';
+$labels['shortaclother'] = 'Άλλα';
+$labels['shortaclread'] = 'Αναγνωση';
+$labels['shortaclwrite'] = 'ΔημιουÏγια';
+$labels['shortacldelete'] = 'ΔιαγÏαφή';
+$labels['longacll'] = 'Ο φάκελος είναι οÏατος στης λιστες και μποÏεί να εγγÏαφεί';
+$labels['longaclr'] = 'Ο φάκελος μποÏεί να ανοίξει για την ανάγνωση ';
+$labels['longacls'] = 'Η σημαια μυνηματων μποÏει να αλλαχθει';
+$labels['longaclw'] = 'ΜηνÏματα σημαίες και λέξεις-κλειδιά που μποÏεί να αλλάξει, εκτός δει και διαγÏάφεται ';
+$labels['longacli'] = 'Τα μηνÏματα μποÏοÏν να γÏαφθουν ή να αντιγÏαφθοÏν στο φάκελο ';
+$labels['longaclp'] = 'Τα μηνÏματα μποÏοÏν να τοποθετηθοÏν σε αυτόν το φάκελο ';
+$labels['longaclc'] = 'ΜποÏοÏν να δημιουÏγηθοÏν φάκελοι (ή να μετονομαστουν ) ακÏιβώς κάτω από αυτόν το φάκελο ';
+$labels['longaclk'] = 'ΜποÏοÏν να δημιουÏγηθοÏν φάκελοι (ή να μετονομαστουν ) ακÏιβώς κάτω από αυτόν το φάκελο ';
+$labels['longacld'] = 'ΔιαγÏαφή μηνυμάτων σημαίας μποÏεί να αλλάξει ';
+$labels['longaclt'] = 'ΔιαγÏαφή μηνυμάτων σημαίας μποÏεί να αλλάξει ';
+$labels['longacle'] = 'Μυνηματα που μποÏουν να απαλειφθουν';
+$labels['longaclx'] = 'Ο φακελος δεν μποÏει να μετονομασθει η να διαγÏαφθει';
+$labels['longacla'] = 'Τα δικαιώματα Ï€Ïόσβασης στο φάκελο και μποÏεί να αλλάξει';
+$labels['longaclfull'] = 'ΠλήÏης έλεγχος συμπεÏιλαμβανομένης της διοίκησης ';
+$labels['longaclread'] = 'Ο φάκελος μποÏεί να ανοίξει για την ανάγνωση ';
+$labels['longaclwrite'] = 'ΜηνÏματα να σημαδεÏονται, γÏαπτή ή αντιγÏάφονται στο φάκελο';
+$labels['longacldelete'] = 'Τα μυνηματα μποÏουν να διαγÏαφθουν';
+$messages['deleting'] = 'ΔιαγÏαφή των δικαιωμάτων Ï€Ïόσβασης...';
+$messages['saving'] = 'Αποθήκευση δικαιώματων Ï€Ïόσβασης...';
+$messages['updatesuccess'] = 'Άλλαξε με επιτυχία τα δικαιώματα Ï€Ïόσβασης ';
+$messages['deletesuccess'] = 'ΔιαγÏάφηκε με επιτυχία τα δικαιώματα Ï€Ïόσβασης ';
+$messages['createsuccess'] = 'ΠÏοστέθηκε με επιτυχία τα δικαιώματα Ï€Ïόσβασης ';
+$messages['updateerror'] = 'Δεν είναι δυνατή η ενημέÏωση δικαιωμάτων Ï€Ïόσβασης';
+$messages['deleteerror'] = 'Δεν είναι δυνατή η διαγÏαφή των δικαιωμάτων Ï€Ïόσβασης ';
+$messages['createerror'] = 'Δεν είναι δυνατή η Ï€Ïοσθήκη δικαιώματα Ï€Ïόσβασης ';
+$messages['deleteconfirm'] = 'Είσαι σίγουÏος, ότι θέλετε να καταÏγήσετε τα δικαιώματα Ï€Ïόσβασης του επιλεγμένου(ων) χÏήστης ';
+$messages['norights'] = 'Κανένα δικαίωμα έχει καθοÏιστεί';
+$messages['nouser'] = 'Το όνομα δεν έχει καθοÏιστεί! ';
+?>
diff --git a/plugins/acl/localization/en_US.inc b/plugins/acl/localization/en_US.inc
index 3c61266be..8eebdc60c 100644
--- a/plugins/acl/localization/en_US.inc
+++ b/plugins/acl/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/acl/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail ACL plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -89,7 +89,7 @@ $messages['saving'] = 'Saving access rights...';
$messages['updatesuccess'] = 'Successfully changed access rights';
$messages['deletesuccess'] = 'Successfully deleted access rights';
$messages['createsuccess'] = 'Successfully added access rights';
-$messages['updateerror'] = 'Unable to update access rights';
+$messages['updateerror'] = 'Ubable to update access rights';
$messages['deleteerror'] = 'Unable to delete access rights';
$messages['createerror'] = 'Unable to add access rights';
$messages['deleteconfirm'] = 'Are you sure, you want to remove access rights of selected user(s)?';
diff --git a/plugins/acl/localization/es_AR.inc b/plugins/acl/localization/es_AR.inc
new file mode 100644
index 000000000..0fa111167
--- /dev/null
+++ b/plugins/acl/localization/es_AR.inc
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'Compartiendo';
+$labels['myrights'] = 'Permisos de acceso';
+$labels['username'] = 'Usuario:';
+$labels['advanced'] = 'modo avanzado';
+$labels['newuser'] = 'Agregar entrada';
+$labels['actions'] = 'Acciones para los permisos de acceso...';
+$labels['anyone'] = 'Todos los usuarios (cualquiera)';
+$labels['anonymous'] = 'Invitado (anonimo)';
+$labels['identifier'] = 'Identificacion';
+$labels['acll'] = 'Buscar';
+$labels['aclr'] = 'Leer mensajes';
+$labels['acls'] = 'Mantener como visualizado';
+$labels['aclw'] = 'Escribir marcadores';
+$labels['acli'] = 'Insertar (Copiar en)';
+$labels['aclp'] = 'Publicar';
+$labels['aclc'] = 'Crear subcarpetas';
+$labels['aclk'] = 'Crear subcarpetas';
+$labels['acld'] = 'Eliminar mensajes';
+$labels['aclt'] = 'Eliminar mensajes';
+$labels['acle'] = 'Descartar';
+$labels['aclx'] = 'Eliminar carpeta';
+$labels['acla'] = 'Administrar';
+$labels['aclfull'] = 'Control total';
+$labels['aclother'] = 'Otro';
+$labels['aclread'] = 'Leer';
+$labels['aclwrite'] = 'Escribir';
+$labels['acldelete'] = 'Eliminar';
+$labels['shortacll'] = 'Buscar';
+$labels['shortaclr'] = 'Leer';
+$labels['shortacls'] = 'Mantener';
+$labels['shortaclw'] = 'Escribir';
+$labels['shortacli'] = 'Insertar';
+$labels['shortaclp'] = 'Publicar';
+$labels['shortaclc'] = 'Crear';
+$labels['shortaclk'] = 'Crear';
+$labels['shortacld'] = 'Eliminar';
+$labels['shortaclt'] = 'Eliminar';
+$labels['shortacle'] = 'Descartar';
+$labels['shortaclx'] = 'Borrado de carpeta';
+$labels['shortacla'] = 'Administrar';
+$labels['shortaclother'] = 'Otro';
+$labels['shortaclread'] = 'Leer';
+$labels['shortaclwrite'] = 'Escribir';
+$labels['shortacldelete'] = 'Eliminar';
+$labels['longacll'] = 'La carpeta es visible en listas y es posible suscribirse a ella';
+$labels['longaclr'] = 'La carpeta se puede abirir para lectura';
+$labels['longacls'] = 'El marcador de Mensajes Vistos puede ser modificado';
+$labels['longaclw'] = 'Los marcadores de mensajes y palabras clave se pueden modificar, excepto Visto y Eliminado';
+$labels['longacli'] = 'En esta carpeta se pueden escribir o copiar mensajes';
+$labels['longaclp'] = 'En esta carpeta se pueden publicar mensajes';
+$labels['longaclc'] = 'Debajo de esta carpeta se puede crear (o renombrar) otras carpetas directamente';
+$labels['longaclk'] = 'Debajo de esta carpeta se puede crear (o renombrar) otras carpetas directamente';
+$labels['longacld'] = 'El marcador de Mensaje Eliminado puede ser modificado';
+$labels['longaclt'] = 'El marcador de Mensaje Eliminado puede ser modificado';
+$labels['longacle'] = 'Los mensajes pueden ser descartados';
+$labels['longaclx'] = 'La carpeta puede ser eliminada o renombrada';
+$labels['longacla'] = 'Los permisos de acceso de esta carpeta pueden ser modificados';
+$labels['longaclfull'] = 'Control total incluyendo la administracion de carpeta';
+$labels['longaclread'] = 'La carpeta se puede abrir para lectura';
+$labels['longaclwrite'] = 'En esta carpeta los mensajes pueden ser marcados, escritos o copiados';
+$labels['longacldelete'] = 'Los mensajes se pueden eliminar';
+$messages['deleting'] = 'Eliminando permisos de acceso...';
+$messages['saving'] = 'Salvando permisos de acceso...';
+$messages['updatesuccess'] = 'Permisos de acceso modificados satisfactoriamente';
+$messages['deletesuccess'] = 'Permisos de acceso eliminados correctamente';
+$messages['createsuccess'] = 'Permisos de acceso agregados satisfactoriamente';
+$messages['deleteerror'] = 'No se pueden eliminar los permisos de acceso';
+$messages['createerror'] = 'No se pueden agregar los permisos de acceso';
+$messages['deleteconfirm'] = 'Estas seguro que queres remover los permisos de acceso a el/los usuario(s) seleccionado/s?';
+$messages['norights'] = 'Ningun permiso ha sido especificado!';
+$messages['nouser'] = 'Ningun nombre de usuario ha sido especificado!';
+?>
diff --git a/plugins/acl/localization/et_EE.inc b/plugins/acl/localization/et_EE.inc
index ceec4cd0c..e41275a7d 100644
--- a/plugins/acl/localization/et_EE.inc
+++ b/plugins/acl/localization/et_EE.inc
@@ -73,8 +73,8 @@ $labels['longacli'] = 'Messages can be written or copied to the folder';
$labels['longaclp'] = 'Messages can be posted to this folder';
$labels['longaclc'] = 'Folders can be created (or renamed) directly under this folder';
$labels['longaclk'] = 'Folders can be created (or renamed) directly under this folder';
-$labels['longacld'] = 'Kirja kustutamis lippu saab muuta';
-$labels['longaclt'] = 'Kirja kustutamis lippu saab muuta';
+$labels['longacld'] = 'Messages Delete flag can be changed';
+$labels['longaclt'] = 'Messages Delete flag can be changed';
$labels['longacle'] = 'Kirju saab eemaldada';
$labels['longaclx'] = 'Seda kausta ei saa kustutada ega ümber nimetada';
$labels['longacla'] = 'Selle kausta ligipääsuõigusi saab muuta';
@@ -89,7 +89,7 @@ $messages['saving'] = 'Ligipääsuõiguste salvestamine...';
$messages['updatesuccess'] = 'Ligipääsuõigused on muudetud';
$messages['deletesuccess'] = 'Ligipääsuõigused on kustutatud';
$messages['createsuccess'] = 'Ligipääsuõigused on lisatud';
-$messages['updateerror'] = 'Ligipääsuõiguste uuendamine nurjus';
+$messages['updateerror'] = 'Unable to update access rights';
$messages['deleteerror'] = 'Ligipääsuõiguste kustutamine nurjus';
$messages['createerror'] = 'Ligipääsuõiguste andmine nurjus';
$messages['deleteconfirm'] = 'Oled sa kindel, et sa soovid valitudkasutaja(te) õiguseid kustutada?';
diff --git a/plugins/acl/localization/eu_ES.inc b/plugins/acl/localization/eu_ES.inc
new file mode 100644
index 000000000..4fa9f3b08
--- /dev/null
+++ b/plugins/acl/localization/eu_ES.inc
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'Partekatzen';
+$labels['myrights'] = 'Sarbide-eskubideak';
+$labels['username'] = 'Erabiltzailea:';
+$labels['advanced'] = 'modu aurreratua';
+$labels['newuser'] = 'Gehitu sarrera';
+$labels['actions'] = 'Sarbide-eskubideen ekintzak...';
+$labels['anyone'] = 'Erabiltzaile guztiak (edozein)';
+$labels['anonymous'] = 'Gonbidatuak (anonimo)';
+$labels['identifier'] = 'Identifikatzailea';
+$labels['acll'] = 'Bilatu';
+$labels['aclr'] = 'Irakurri mezuak';
+$labels['acls'] = 'Mantendu ikusita egoera';
+$labels['aclw'] = 'Idatzi banderak';
+$labels['acli'] = 'Txertatu (kopiatu barnean)';
+$labels['aclp'] = 'Posta';
+$labels['aclc'] = 'Sortu azpikarpetak';
+$labels['aclk'] = 'Sortu azpikarpetak';
+$labels['acld'] = 'Ezabatu mezuak';
+$labels['aclt'] = 'Ezabatu mezuak';
+$labels['acle'] = 'Kendu';
+$labels['aclx'] = 'Ezabatu karpeta';
+$labels['acla'] = 'Administratu';
+$labels['aclfull'] = 'Kontrol osoa';
+$labels['aclother'] = 'Beste';
+$labels['aclread'] = 'Irakurri';
+$labels['aclwrite'] = 'Idatzi';
+$labels['acldelete'] = 'Ezabatu';
+$labels['shortacll'] = 'Bilatu';
+$labels['shortaclr'] = 'Irakurri';
+$labels['shortacls'] = 'Mantendu';
+$labels['shortaclw'] = 'Idatzi';
+$labels['shortacli'] = 'Txertatu';
+$labels['shortaclp'] = 'Bidali';
+$labels['shortaclc'] = 'Sortu';
+$labels['shortaclk'] = 'Sortu';
+$labels['shortacld'] = 'Ezabatu';
+$labels['shortaclt'] = 'Ezabatu';
+$labels['shortacle'] = 'Kendu';
+$labels['shortaclx'] = 'Ezabatu karpeta';
+$labels['shortacla'] = 'Administratu';
+$labels['shortaclother'] = 'Beste';
+$labels['shortaclread'] = 'Irakurri';
+$labels['shortaclwrite'] = 'Idatzi';
+$labels['shortacldelete'] = 'Ezabatu';
+$labels['longacll'] = 'Karpeta hau zerrendan ikusgai dago eta harpidetzen ahal zara';
+$labels['longaclr'] = 'Karpeta ireki daiteke irakurtzeko';
+$labels['longacls'] = 'Mezuen ikusita bandera aldatu daiteke';
+$labels['longaclw'] = 'Mezuen banderak eta gako-hitzak alda daitezke, ikusita eta ezabatuta salbu';
+$labels['longacli'] = 'Mezuak karpetara idatzi edo kopiatu daitezke';
+$labels['longaclp'] = 'Mezuak bidali daitezke karpeta honetara';
+$labels['longaclc'] = 'Karpetak sor daitezke (edo berrizendatu) zuzenean karpeta honetan';
+$labels['longaclk'] = 'Karpetak sor daitezke (edo berrizendatu) karpeta honetan';
+$labels['longacld'] = 'Mezuen ezabatu bandera alda daiteke';
+$labels['longaclt'] = 'Mezuen ezabatu bandera alda daiteke';
+$labels['longacle'] = 'Mezuak betiko ezaba daitezke';
+$labels['longaclx'] = 'Karpeta ezaba edo berrizenda daiteke';
+$labels['longacla'] = 'Karpetaren sarbide eskubideak alda daitezke';
+$labels['longaclfull'] = 'Kontrol osoa, karpetaren administrazioa barne';
+$labels['longaclread'] = 'Karpeta ireki daiteke irakurtzeko';
+$labels['longaclwrite'] = 'Mezuak marka, idatzi edo kopia daitezke karpetara';
+$labels['longacldelete'] = 'Mezuak ezaba daitezke';
+$messages['deleting'] = 'Sarbide-eskubideak ezabatzen...';
+$messages['saving'] = 'Sarbide-eskubideak gordetzen...';
+$messages['updatesuccess'] = 'Sarbide-eskubideak ongi aldatu dira';
+$messages['deletesuccess'] = 'Sarbide-eskubideak ongi ezabatu dira';
+$messages['createsuccess'] = 'Sarbide-eskubideak ongi gehitu dira';
+$messages['updateerror'] = 'Ezin dira eguneratu sarbide-eskubideak';
+$messages['deleteerror'] = 'Ezin dira ezabatu sarbide-eskubideak';
+$messages['createerror'] = 'Ezin dira gehitu sarbide-eskubideak';
+$messages['deleteconfirm'] = 'Seguru zaude hautatutako erabiltzaile(ar)en sarbide-eskubideak ezabatu nahi duzula?';
+$messages['norights'] = 'Eskubideak ez dira zehaztu!';
+$messages['nouser'] = 'Erabiltzaile-izana ez da zehaztu!';
+?>
diff --git a/plugins/acl/localization/fa_IR.inc b/plugins/acl/localization/fa_IR.inc
index 2face4fba..48fb8a225 100644
--- a/plugins/acl/localization/fa_IR.inc
+++ b/plugins/acl/localization/fa_IR.inc
@@ -22,51 +22,51 @@ $labels['username'] = 'کاربر:';
$labels['advanced'] = 'حالت پیشرÙته';
$labels['newuser'] = 'اÙزودن مدخل';
$labels['actions'] = 'Ùعالیت‌های مجوز دسترسی...';
-$labels['anyone'] = 'همه‌ی کاربران (هر کسی)';
-$labels['anonymous'] = 'مهمان‌ها (ناشناس)';
+$labels['anyone'] = 'همه کاربران (هر کسی)';
+$labels['anonymous'] = 'مهمان‌ها (ناشناس‌ها)';
$labels['identifier'] = 'شناساگر';
$labels['acll'] = 'یاÙتن';
-$labels['aclr'] = 'پیغام‌های خوانده شده';
+$labels['aclr'] = 'پیام های خوانده شده';
$labels['acls'] = 'نگه داشتن حالت بازدید';
$labels['aclw'] = 'پرچم‌های نوشتن';
$labels['acli'] = 'وارد کردن (کپی کردن در)';
-$labels['aclp'] = 'ارسال';
+$labels['aclp'] = 'نوشته';
$labels['aclc'] = 'ایجاد زیرپوشه‌ها';
$labels['aclk'] = 'ایجاد زیرپوشه‌ها';
$labels['acld'] = 'پاک کردن پیغام‌ها';
$labels['aclt'] = 'پاک کردن پیغام‌ها';
$labels['acle'] = 'پاک کردن';
$labels['aclx'] = 'حذ٠پوشه';
-$labels['acla'] = 'مدیریت کردن';
+$labels['acla'] = 'مدیر';
$labels['aclfull'] = 'کنترل کامل';
$labels['aclother'] = 'دیگر';
-$labels['aclread'] = 'خواندن';
+$labels['aclread'] = 'خوانده شده';
$labels['aclwrite'] = 'نوشتن';
$labels['acldelete'] = 'حذÙ';
$labels['shortacll'] = 'یاÙتن';
-$labels['shortaclr'] = 'خواندن';
+$labels['shortaclr'] = 'خوانده شده';
$labels['shortacls'] = 'نگه داشتن';
$labels['shortaclw'] = 'نوشتن';
-$labels['shortacli'] = 'اضاÙÙ‡ کردن';
-$labels['shortaclp'] = 'ارسال';
+$labels['shortacli'] = 'جاگذارى';
+$labels['shortaclp'] = 'نوشته';
$labels['shortaclc'] = 'ایجاد';
$labels['shortaclk'] = 'ایجاد';
$labels['shortacld'] = 'حذÙ';
$labels['shortaclt'] = 'حذÙ';
$labels['shortacle'] = 'پاک کردن';
$labels['shortaclx'] = 'حذ٠کردن پوشه';
-$labels['shortacla'] = 'مدیریت کردن';
+$labels['shortacla'] = 'مدیر';
$labels['shortaclother'] = 'دیگر';
-$labels['shortaclread'] = 'خواندن';
+$labels['shortaclread'] = 'خوانده شده';
$labels['shortaclwrite'] = 'نوشتن';
$labels['shortacldelete'] = 'حذÙ';
-$labels['longacll'] = 'پوشه را می‌توان در Ùهرست‌ها دید Ùˆ در آن مشترک شد';
-$labels['longaclr'] = 'پوشه می‌تواند برای خوانده شدن باز شود';
+$labels['longacll'] = 'پوشه در Ùهرست‌ها قابل مشاهده است Ùˆ می‌تواند مشترک به';
+$labels['longaclr'] = 'پوشه می‌تواند برای خواندن باز شود';
$labels['longacls'] = 'پرچم بازدید پیغام‌ها می‌تواند تغییر داده شود';
$labels['longaclw'] = 'پرچم Ùˆ کلیدواژه پیغام‌ها می‌تواند تغییر داده شود، به غیر از بازدید Ùˆ حذÙ';
$labels['longacli'] = 'پیغام‌ها می‌توانند کپی یا نوشته شوند به پوشه';
@@ -89,7 +89,7 @@ $messages['saving'] = 'ذخیره قوانین دسترسی...';
$messages['updatesuccess'] = 'قوانین دسترسی با موÙقیت تغییر کردند';
$messages['deletesuccess'] = 'قوانین دسترسی با موÙقیت حذ٠شدند';
$messages['createsuccess'] = 'قوانین دسترسی با موÙقیت اضاÙÙ‡ شدند';
-$messages['updateerror'] = 'ناتوانی در به روز کردن قوانین دسترسی';
+$messages['updateerror'] = 'ناتوانی در بروزرسانی قوانین دسترسی';
$messages['deleteerror'] = 'ناتوانی در حذ٠قوانین دسترسی';
$messages['createerror'] = 'ناتوانی در اضاÙÙ‡ کردن قوانین دسترسی';
$messages['deleteconfirm'] = 'آیا شما مطمئن هستید که می‌خواهید قوانین دسترسی را برای کاربر(ان) انتخاب شده حذ٠نمایید؟';
diff --git a/plugins/acl/localization/fi_FI.inc b/plugins/acl/localization/fi_FI.inc
index e2b6899fa..1238b0fd3 100644
--- a/plugins/acl/localization/fi_FI.inc
+++ b/plugins/acl/localization/fi_FI.inc
@@ -41,7 +41,7 @@ $labels['aclx'] = 'Delete folder';
$labels['acla'] = 'Administer';
$labels['aclfull'] = 'Full control';
-$labels['aclother'] = 'Other';
+$labels['aclother'] = 'Muu';
$labels['aclread'] = 'Read';
$labels['aclwrite'] = 'Write';
$labels['acldelete'] = 'Delete';
@@ -66,7 +66,7 @@ $labels['shortaclwrite'] = 'Write';
$labels['shortacldelete'] = 'Delete';
$labels['longacll'] = 'The folder is visible on lists and can be subscribed to';
-$labels['longaclr'] = 'The folder can be opened for reading';
+$labels['longaclr'] = 'Kansion voi avata lukua varten';
$labels['longacls'] = 'Messages Seen flag can be changed';
$labels['longaclw'] = 'Messages flags and keywords can be changed, except Seen and Deleted';
$labels['longacli'] = 'Messages can be written or copied to the folder';
@@ -76,24 +76,24 @@ $labels['longaclk'] = 'Folders can be created (or renamed) directly under this f
$labels['longacld'] = 'Messages Delete flag can be changed';
$labels['longaclt'] = 'Messages Delete flag can be changed';
$labels['longacle'] = 'Messages can be expunged';
-$labels['longaclx'] = 'The folder can be deleted or renamed';
-$labels['longacla'] = 'The folder access rights can be changed';
+$labels['longaclx'] = 'Kansio voidaan poistaa tai nimetä uudelleen';
+$labels['longacla'] = 'Kansion käyttöoikeuksia voi muuttaa';
$labels['longaclfull'] = 'Full control including folder administration';
$labels['longaclread'] = 'The folder can be opened for reading';
$labels['longaclwrite'] = 'Messages can be marked, written or copied to the folder';
$labels['longacldelete'] = 'Messages can be deleted';
-$messages['deleting'] = 'Deleting access rights...';
-$messages['saving'] = 'Saving access rights...';
-$messages['updatesuccess'] = 'Successfully changed access rights';
-$messages['deletesuccess'] = 'Successfully deleted access rights';
-$messages['createsuccess'] = 'Successfully added access rights';
-$messages['updateerror'] = 'Ubable to update access rights';
-$messages['deleteerror'] = 'Unable to delete access rights';
-$messages['createerror'] = 'Unable to add access rights';
+$messages['deleting'] = 'Poistetaan käyttöoikeuksia...';
+$messages['saving'] = 'Tallennetaan käyttöoikeuksia...';
+$messages['updatesuccess'] = 'Käyttöoikeuksia muutettiin onnistuneesti';
+$messages['deletesuccess'] = 'Käyttöoikeuksia poistettiin onnistuneesti';
+$messages['createsuccess'] = 'Käyttöoikeuksia lisättiin onnistuneesti';
+$messages['updateerror'] = 'Käyttöoikeuksien päivitys epäonnistui';
+$messages['deleteerror'] = 'Käyttöoikeuksien poistaminen epäonnistui';
+$messages['createerror'] = 'Käyttöoikeuksien lisääminen epäonnistui';
$messages['deleteconfirm'] = 'Are you sure, you want to remove access rights of selected user(s)?';
-$messages['norights'] = 'No rights has been specified!';
-$messages['nouser'] = 'No username has been specified!';
+$messages['norights'] = 'Oikeuksia ei ole määritelty!';
+$messages['nouser'] = 'Käyttäjänimeä ei ole määritelty!';
?>
diff --git a/plugins/acl/localization/gl_ES.inc b/plugins/acl/localization/gl_ES.inc
index 2349975de..bb8837190 100644
--- a/plugins/acl/localization/gl_ES.inc
+++ b/plugins/acl/localization/gl_ES.inc
@@ -28,15 +28,15 @@ $labels['identifier'] = 'Identificador';
$labels['acll'] = 'Bloquear';
$labels['aclr'] = 'Ler mensaxes';
-$labels['acls'] = 'Manter o estado coma visto';
-$labels['aclw'] = 'Marcas de lectura';
-$labels['acli'] = 'Engadir (Copiar en)';
-$labels['aclp'] = 'Envío';
+$labels['acls'] = 'Keep Seen state';
+$labels['aclw'] = 'Write flags';
+$labels['acli'] = 'Insert (Copy into)';
+$labels['aclp'] = 'Post';
$labels['aclc'] = 'Crear subcartafoles';
$labels['aclk'] = 'Crear subcartafoles';
$labels['acld'] = 'Borrar mensaxes';
$labels['aclt'] = 'Borrar mensaxes';
-$labels['acle'] = 'Expurga';
+$labels['acle'] = 'Expunge';
$labels['aclx'] = 'Eliminar carpeta';
$labels['acla'] = 'Administrar';
@@ -51,12 +51,12 @@ $labels['shortaclr'] = 'Ler';
$labels['shortacls'] = 'Manter';
$labels['shortaclw'] = 'Escribir';
$labels['shortacli'] = 'Insertar';
-$labels['shortaclp'] = 'Envío';
+$labels['shortaclp'] = 'Post';
$labels['shortaclc'] = 'Crear';
$labels['shortaclk'] = 'Crear';
$labels['shortacld'] = 'Borrar';
$labels['shortaclt'] = 'Borrar';
-$labels['shortacle'] = 'Expurga';
+$labels['shortacle'] = 'Expunge';
$labels['shortaclx'] = 'Borrar cartafol';
$labels['shortacla'] = 'Administrar';
@@ -66,33 +66,33 @@ $labels['shortaclwrite'] = 'Escritura';
$labels['shortacldelete'] = 'Borrado';
$labels['longacll'] = 'O cartafol é visible e pode ser suscrito';
-$labels['longaclr'] = 'Pódese abrir o cartafol para lectura';
-$labels['longacls'] = 'Pódese mudar o marcador de Mensaxes Enviadas';
-$labels['longaclw'] = 'Pódense mudar marcadores e palabras chave agás Olladas e Borradas';
-$labels['longacli'] = 'Pódense escreber ou copiar as mensaxes a este cartafol';
-$labels['longaclp'] = 'Pódense enviar as mensaxes a este cartafol';
-$labels['longaclc'] = 'Pódense crear (ou renomear) os cartafois directamente baixo deste cartafol';
-$labels['longaclk'] = 'Pódense crear (ou renomear) os cartafois directamente baixo deste cartafol';
-$labels['longacld'] = 'Pódense mudar as mensaxes coa marca de Borrado';
-$labels['longaclt'] = 'Pódense mudar as mensaxes coa marca de Borrado';
-$labels['longacle'] = 'Pódense eliminar as mensaxes';
-$labels['longaclx'] = 'Pódese borrar ou renomear o cartafol';
-$labels['longacla'] = 'Pódense mudar os dereitos de acceso ao cartafol';
+$labels['longaclr'] = 'The folder can be opened for reading';
+$labels['longacls'] = 'Messages Seen flag can be changed';
+$labels['longaclw'] = 'Messages flags and keywords can be changed, except Seen and Deleted';
+$labels['longacli'] = 'Messages can be written or copied to the folder';
+$labels['longaclp'] = 'Messages can be posted to this folder';
+$labels['longaclc'] = 'Folders can be created (or renamed) directly under this folder';
+$labels['longaclk'] = 'Folders can be created (or renamed) directly under this folder';
+$labels['longacld'] = 'Messages Delete flag can be changed';
+$labels['longaclt'] = 'Messages Delete flag can be changed';
+$labels['longacle'] = 'Messages can be expunged';
+$labels['longaclx'] = 'The folder can be deleted or renamed';
+$labels['longacla'] = 'The folder access rights can be changed';
-$labels['longaclfull'] = 'Control total inclúe administración de cartafois';
-$labels['longaclread'] = 'Pódese abrir o cartafol para lectura';
-$labels['longaclwrite'] = 'Pódense marcar, escribir ou copiar as mensaxes no cartafol';
-$labels['longacldelete'] = 'Pódense borrar as mensaxes';
+$labels['longaclfull'] = 'Full control including folder administration';
+$labels['longaclread'] = 'The folder can be opened for reading';
+$labels['longaclwrite'] = 'Messages can be marked, written or copied to the folder';
+$labels['longacldelete'] = 'Messages can be deleted';
-$messages['deleting'] = 'Borrando dereitos de acceso...';
-$messages['saving'] = 'Gardando dereitos de acceso...';
-$messages['updatesuccess'] = 'Mudados con éxito os dereitos de acceso';
-$messages['deletesuccess'] = 'Borrados con éxito os dereitos de acceso';
-$messages['createsuccess'] = 'Engadidos con éxito os dereitos de acceso';
-$messages['updateerror'] = 'Non se poden actualizar os dereitos de acceso';
-$messages['deleteerror'] = 'Non se poden borrar os dereitos de acceso';
-$messages['createerror'] = 'Non se poden engadir dereitos de acceso';
-$messages['deleteconfirm'] = 'De certo quere eliminar os dereitos de acceso do usuario(s) escollido?';
+$messages['deleting'] = 'Deleting access rights...';
+$messages['saving'] = 'Saving access rights...';
+$messages['updatesuccess'] = 'Successfully changed access rights';
+$messages['deletesuccess'] = 'Successfully deleted access rights';
+$messages['createsuccess'] = 'Successfully added access rights';
+$messages['updateerror'] = 'Ubable to update access rights';
+$messages['deleteerror'] = 'Unable to delete access rights';
+$messages['createerror'] = 'Unable to add access rights';
+$messages['deleteconfirm'] = 'Are you sure, you want to remove access rights of selected user(s)?';
$messages['norights'] = 'Non se especificaron permisos!';
$messages['nouser'] = 'Non se especificou o nome de usuario!';
diff --git a/plugins/acl/localization/he_IL.inc b/plugins/acl/localization/he_IL.inc
index 9ca305d32..d7b027a40 100644
--- a/plugins/acl/localization/he_IL.inc
+++ b/plugins/acl/localization/he_IL.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'זכויות גישה נשמרות...';
$messages['updatesuccess'] = 'זכויות גישה שונו בהצלחה';
$messages['deletesuccess'] = 'זכויות גישה נמחקו בהצלחה';
$messages['createsuccess'] = 'זכויות גישה נוספו בהצלחה';
-$messages['updateerror'] = '×œ× × ×™×ª×Ÿ לעדכן הרש×ות גישה';
+$messages['updateerror'] = '×œ× × ×™×ª×Ÿ לעדכן זכויות גישה';
$messages['deleteerror'] = '×œ× × ×™×ª×Ÿ למחוק זכויות גישה';
$messages['createerror'] = '×œ× × ×™×ª×Ÿ להוסיף זכויות גישה';
$messages['deleteconfirm'] = '×”×× ×•×“××™ שברצונך להסיר זכויות גישה של המשתמש(×™×) שנבחרו?';
diff --git a/plugins/acl/localization/lb_LU.inc b/plugins/acl/localization/lb_LU.inc
index b9891931c..be03a7297 100644
--- a/plugins/acl/localization/lb_LU.inc
+++ b/plugins/acl/localization/lb_LU.inc
@@ -15,7 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-acl/
*/
-
$labels['sharing'] = 'Sharing';
$labels['myrights'] = 'Zougrëffsrechter';
$labels['username'] = 'Benotzer:';
@@ -25,27 +24,19 @@ $labels['actions'] = 'Optioune fir d\'Zougrëffsrechter';
$labels['anyone'] = 'All d\'Benotzer (jiddwereen)';
$labels['anonymous'] = 'Gaascht (anonym)';
$labels['identifier'] = 'Identifiant';
-
$labels['acll'] = 'Noschloen';
$labels['aclr'] = 'Messagë liesen';
$labels['acls'] = 'Lies-Status behalen';
-$labels['aclw'] = 'Write flags';
-$labels['acli'] = 'Insert (Copy into)';
-$labels['aclp'] = 'Post';
-$labels['aclc'] = 'Create subfolders';
-$labels['aclk'] = 'Create subfolders';
$labels['acld'] = 'Messagë läschen';
$labels['aclt'] = 'Messagë läschen';
$labels['acle'] = 'Ausläschen';
$labels['aclx'] = 'Dossier läschen';
$labels['acla'] = 'Administréieren';
-
$labels['aclfull'] = 'Voll Kontroll';
$labels['aclother'] = 'Aner';
$labels['aclread'] = 'Liesen';
$labels['aclwrite'] = 'Schreiwen';
$labels['acldelete'] = 'Läschen';
-
$labels['shortacll'] = 'Noschloen';
$labels['shortaclr'] = 'Liesen';
$labels['shortacls'] = 'Halen';
@@ -59,31 +50,11 @@ $labels['shortaclt'] = 'Läschen';
$labels['shortacle'] = 'Ausläschen';
$labels['shortaclx'] = 'Dossier läschen';
$labels['shortacla'] = 'Administréieren';
-
$labels['shortaclother'] = 'Aner';
$labels['shortaclread'] = 'Liesen';
$labels['shortaclwrite'] = 'Schreiwen';
$labels['shortacldelete'] = 'Läschen';
-
-$labels['longacll'] = 'The folder is visible on lists and can be subscribed to';
-$labels['longaclr'] = 'The folder can be opened for reading';
-$labels['longacls'] = 'Messages Seen flag can be changed';
-$labels['longaclw'] = 'Messages flags and keywords can be changed, except Seen and Deleted';
-$labels['longacli'] = 'Messages can be written or copied to the folder';
-$labels['longaclp'] = 'Messages can be posted to this folder';
-$labels['longaclc'] = 'Folders can be created (or renamed) directly under this folder';
-$labels['longaclk'] = 'Folders can be created (or renamed) directly under this folder';
-$labels['longacld'] = 'Messages Delete flag can be changed';
-$labels['longaclt'] = 'Messages Delete flag can be changed';
-$labels['longacle'] = 'Messages can be expunged';
-$labels['longaclx'] = 'The folder can be deleted or renamed';
-$labels['longacla'] = 'The folder access rights can be changed';
-
-$labels['longaclfull'] = 'Full control including folder administration';
-$labels['longaclread'] = 'The folder can be opened for reading';
-$labels['longaclwrite'] = 'Messages can be marked, written or copied to the folder';
$labels['longacldelete'] = 'Messagë kënne geläscht ginn';
-
$messages['deleting'] = 'Zougrëffsrechter gi geläscht...';
$messages['saving'] = 'Zougrëffsrechter gi gespäichert...';
$messages['updatesuccess'] = 'Rechter erfollegräich geännert';
@@ -95,5 +66,4 @@ $messages['createerror'] = 'Zougrëffsrechter kënnen net dobäigesat ginn';
$messages['deleteconfirm'] = 'Bass du dir sécher, dass du d\'Zougrëffsrechter fir déi ausgewielte Benotzer wëlls ewechhuelen?';
$messages['norights'] = 'Et goufe keng Rechter uginn! ';
$messages['nouser'] = 'Et gouf kee Benotzernumm uginn!';
-
?>
diff --git a/plugins/acl/localization/lt_LT.inc b/plugins/acl/localization/lt_LT.inc
index 39a4d1be2..59393012f 100644
--- a/plugins/acl/localization/lt_LT.inc
+++ b/plugins/acl/localization/lt_LT.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'IÅ¡saugomos prieigos teisÄ—s';
$messages['updatesuccess'] = 'Prieigos teisÄ—s sÄ—kmingai pakeistos';
$messages['deletesuccess'] = 'Prieigos teisÄ—s sÄ—kmingai panaikintos';
$messages['createsuccess'] = 'Prieigos teisÄ—s sÄ—kmingai pridÄ—tos';
-$messages['updateerror'] = 'Nepavyko pakeisti prieigos teisių';
+$messages['updateerror'] = 'Neįmanoma atnaujinti prieigos teises';
$messages['deleteerror'] = 'Neįmanoma panaikinti prieigos teises';
$messages['createerror'] = 'Neišeina pridėti prieigos teises';
$messages['deleteconfirm'] = 'Ar jūs esate įsitikinę, jog norite panaikinti prieigos teises pažymėtiems vartotojams(-ui)?';
diff --git a/plugins/acl/localization/lv_LV.inc b/plugins/acl/localization/lv_LV.inc
new file mode 100644
index 000000000..cadb34ae2
--- /dev/null
+++ b/plugins/acl/localization/lv_LV.inc
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'DalÄ«Å¡anÄs';
+$labels['myrights'] = 'Piekļuves tiesības';
+$labels['username'] = 'LietotÄjs:';
+$labels['advanced'] = 'paplaÅ¡inÄtais režīms';
+$labels['newuser'] = 'Pievienot ierakstu';
+$labels['actions'] = 'DarbÄ«bas ar piekļuves tiesÄ«bÄm...';
+$labels['anyone'] = 'Visi lietotÄji (ikviens)';
+$labels['anonymous'] = 'Viesi (anonīmie)';
+$labels['identifier'] = 'Identifikators';
+$labels['acll'] = 'Atrast';
+$labels['aclr'] = 'Lasīt ziņojumus';
+$labels['acls'] = 'PaturÄ“t "RedzÄ“tÄ" statusu';
+$labels['aclw'] = 'SaglabÄt atzÄ«mes';
+$labels['acli'] = 'Ievietot (Iekopēt)';
+$labels['aclp'] = 'Nosūtīt';
+$labels['aclc'] = 'Izveidot apakšmapes';
+$labels['aclk'] = 'Izveidot apakšmapes';
+$labels['acld'] = 'Dzēst ziņojumus';
+$labels['aclt'] = 'Dzēst ziņojumus';
+$labels['acle'] = 'Izdzēst';
+$labels['aclx'] = 'Dzēst mapi';
+$labels['acla'] = 'PÄrvaldÄ«t';
+$labels['aclfull'] = 'Pilna kontrole';
+$labels['aclother'] = 'Cits';
+$labels['aclread'] = 'Lasīt';
+$labels['aclwrite'] = 'Rakstīt';
+$labels['acldelete'] = 'Dzēst';
+$labels['shortacll'] = 'Atrast';
+$labels['shortaclr'] = 'Lasīt';
+$labels['shortacls'] = 'Paturēt';
+$labels['shortaclw'] = 'Rakstīt';
+$labels['shortacli'] = 'Ievietot';
+$labels['shortaclp'] = 'Nosūtīt';
+$labels['shortaclc'] = 'Izveidot';
+$labels['shortaclk'] = 'Izveidot';
+$labels['shortacld'] = 'Dzēst';
+$labels['shortaclt'] = 'Dzēst';
+$labels['shortacle'] = 'Izdzēst';
+$labels['shortaclx'] = 'Mapju dzēšana';
+$labels['shortacla'] = 'PÄrvaldÄ«t';
+$labels['shortaclother'] = 'Cits';
+$labels['shortaclread'] = 'Lasīt';
+$labels['shortaclwrite'] = 'Rakstīt';
+$labels['shortacldelete'] = 'Dzēst';
+$labels['longacll'] = 'Mape ir redzama kopÄ“jÄ mapju sarakstÄ un var tikt abonÄ“ta';
+$labels['longaclr'] = 'Ši mape var tikt atvērta lasīšanai';
+$labels['longacls'] = 'Ziņojumu "Redzēts" atzīme var tik mainīta';
+$labels['longaclw'] = 'Ziņojumu atzÄ«mes, izņemot "RedzÄ“ts" un "DzÄ“sts", un atslÄ“gvÄrdi var tik mainÄ«ti';
+$labels['longacli'] = 'Ziņojumi var tikt ierakstÄ«ti vai pÄrkopÄ“ti uz Å¡o mapi';
+$labels['longaclp'] = 'VÄ“stules var tikt ievietotas Å¡ajÄ mapÄ“';
+$labels['longaclc'] = 'Zem Å¡Ä«s mapes pa tieÅ¡o var tikt izveidotas (vai pÄrsauktas) citas mapes';
+$labels['longaclk'] = 'Zem Å¡Ä«s mapes pa tieÅ¡o var tikt izveidotas (vai pÄrsauktas) citas mapes';
+$labels['longacld'] = 'Ziņojumu "Dzēst" atzīme var tikt mainīta';
+$labels['longaclt'] = 'Ziņojumu "Dzēst" atzīme var tikt mainīta';
+$labels['longacle'] = 'Vēstules var tikt izdzēstas';
+$labels['longaclx'] = 'Mape var tikt gan dzÄ“sta, gan pÄrdÄ“vÄ“ta';
+$labels['longacla'] = 'Mapes pieejas tiesības var tikt izmainītas';
+$labels['longaclfull'] = 'Pilna kontrole, iekļaujot arī mapju administrēšanu';
+$labels['longaclread'] = 'Mape var tikt atvērta lasīšanai';
+$labels['longaclwrite'] = 'Ziņojumi mapÄ“ var tikt gan atzÄ«mÄ“ti, gan ierakstÄ«ti vai arÄ« pÄrkopÄ“ti uz mapi';
+$labels['longacldelete'] = 'Vēstules var tikt izdzēstas';
+$messages['deleting'] = 'Dzēš piekļuves tiesības...';
+$messages['saving'] = 'SaglabÄ piekļuves tiesÄ«bas...';
+$messages['updatesuccess'] = 'Piekļuves tiesības tika veiksmīgi samainītas';
+$messages['deletesuccess'] = 'Piekļuves tiesības tika veiksmīgi izdzēstas';
+$messages['createsuccess'] = 'Piekļuves tiesības tika veiksmīgi pievienotas';
+$messages['updateerror'] = 'Pieejas tiesÄ«bas nomainÄ«t neizdevÄs';
+$messages['deleteerror'] = 'Piekļuves tiesÄ«bas izdzÄ“st neizdevÄs';
+$messages['createerror'] = 'Piekļuves tiesÄ«bas pievienot neizdevÄs';
+$messages['deleteconfirm'] = 'Vai tieÅ¡Äm atzÄ«mÄ“tajiem lietotÄjiem noņemt piekļuves tiesÄ«bas?';
+$messages['norights'] = 'Netika norÄdÄ«tas tiesÄ«bas!';
+$messages['nouser'] = 'Netika norÄdÄ«ts lietotÄjvÄrds!';
+?>
diff --git a/plugins/acl/localization/pl_PL.inc b/plugins/acl/localization/pl_PL.inc
index 69a5e0c05..73c0fc4fb 100644
--- a/plugins/acl/localization/pl_PL.inc
+++ b/plugins/acl/localization/pl_PL.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'Zapisywanie praw dostępu...';
$messages['updatesuccess'] = 'Pomyślnie zmieniono prawa dostępu';
$messages['deletesuccess'] = 'Pomyślnie usunięto prawa dostępu';
$messages['createsuccess'] = 'Pomyślnie dodano prawa dostępu';
-$messages['updateerror'] = 'Nie udało się zaktualizować praw dostępu';
+$messages['updateerror'] = 'Nie udało się zmienić praw dostępu';
$messages['deleteerror'] = 'Nie udało się usunąć praw dostępu';
$messages['createerror'] = 'Nie udało się dodać praw dostępu';
$messages['deleteconfirm'] = 'Czy na pewno chcesz usunąć prawa wybranym użytkownikom?';
diff --git a/plugins/acl/localization/ro_RO.inc b/plugins/acl/localization/ro_RO.inc
index e87524a6c..17124e48b 100644
--- a/plugins/acl/localization/ro_RO.inc
+++ b/plugins/acl/localization/ro_RO.inc
@@ -28,7 +28,7 @@ $labels['identifier'] = 'Identificator';
$labels['acll'] = 'Caută';
$labels['aclr'] = 'Citire mesaje';
-$labels['acls'] = 'Menține starea de Vâzut';
+$labels['acls'] = 'Menține starea citirii';
$labels['aclw'] = 'Indicator scriere';
$labels['acli'] = 'Inserare (copiere în)';
$labels['aclp'] = 'Postează';
@@ -65,7 +65,7 @@ $labels['shortaclread'] = 'CiteÅŸte';
$labels['shortaclwrite'] = 'Scrie';
$labels['shortacldelete'] = 'Șterge';
-$labels['longacll'] = 'Dosarul este vizibil pe liste și se poate înscrie pe el';
+$labels['longacll'] = 'Dosarul este vizibil pe liste și se poate subscrie la acesta';
$labels['longaclr'] = 'Dosarul se poate deschide pentru citire';
$labels['longacls'] = 'Indicatorul de Văzut a fost schimbat';
$labels['longaclw'] = 'Indicatoarele și cuvintele cheie ale mesajelor se pot schimba cu excepția Văzut și Șters';
@@ -73,8 +73,8 @@ $labels['longacli'] = 'Mesajul se poate scrie sau copia într-un dosar';
$labels['longaclp'] = 'Mesajele se pot trimite către acest dosar';
$labels['longaclc'] = 'Dosarele se pot crea (sau redenumi) direct sub acest dosar';
$labels['longaclk'] = 'Dosarele se pot crea (sau redenumi) direct sub acest dosar';
-$labels['longacld'] = 'Indicatorul de Șters al mesajelor se pot modifica';
-$labels['longaclt'] = 'Indicatorul de Șters al mesajelor se pot modifica';
+$labels['longacld'] = 'Indicatorul de Șters al mesajelor se poate modifica';
+$labels['longaclt'] = 'Indicatorul de Șters al mesajelor se poate modifica';
$labels['longacle'] = 'Mesajele se pot elimina';
$labels['longaclx'] = 'Dosarul se poate șterge sau redenumi';
$labels['longacla'] = 'Drepturile de acces la dosar se pot schimba';
@@ -82,18 +82,18 @@ $labels['longacla'] = 'Drepturile de acces la dosar se pot schimba';
$labels['longaclfull'] = 'Control complet include și administrare dosar';
$labels['longaclread'] = 'Dosarul se poate deschide pentru citire';
$labels['longaclwrite'] = 'Mesajul se poate marca, scrie sau copia într-un dosar';
-$labels['longacldelete'] = 'Mesajul se poate șterge';
+$labels['longacldelete'] = 'Mesajele se pot șterge';
-$messages['deleting'] = 'Drepturile de acces la ștergere...';
-$messages['saving'] = 'Drepturile de acces la salvare...';
+$messages['deleting'] = 'Șterg drepturile de access...';
+$messages['saving'] = 'Salvez drepturi accesare...';
$messages['updatesuccess'] = 'Drepturile de acces au fost schimbate cu succes';
$messages['deletesuccess'] = 'Drepturile de acces au fost șterse cu succes';
$messages['createsuccess'] = 'Drepturile de acces au fost adăugate cu succes';
-$messages['updateerror'] = 'Nu sau putut actualiza drepturile de acces';
-$messages['deleteerror'] = 'Nu sau putut șterge drepturile de acces';
-$messages['createerror'] = 'Nu sau putut adăuga drepturi de acces';
-$messages['deleteconfirm'] = 'Sunteți sigur că doriți să ștergeți drepturile de acces la utilizatorul(i) selectați?';
+$messages['updateerror'] = 'Unable to update access rights';
+$messages['deleteerror'] = 'Nu s-au putut șterge drepturile de acces';
+$messages['createerror'] = 'Nu s-au putut adăuga drepturi de acces';
+$messages['deleteconfirm'] = 'Sunteți sigur că doriți să ștergeți drepturile de acces la utilizatorul (ii) selectați?';
$messages['norights'] = 'Nu au fost specificate drepturi!';
-$messages['nouser'] = 'Nu a fost specificat nume de utilizator!';
+$messages['nouser'] = 'Nu a fost specificat niciun utilizator!';
?>
diff --git a/plugins/acl/localization/th_TH.inc b/plugins/acl/localization/th_TH.inc
new file mode 100644
index 000000000..8eb1d279c
--- /dev/null
+++ b/plugins/acl/localization/th_TH.inc
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'à¸à¸²à¸£à¹à¸Šà¸£à¹Œà¸‚้อมูล';
+$labels['myrights'] = 'สิทธิ์à¸à¸²à¸£à¹€à¸‚้าใช้';
+$labels['username'] = 'ผู้ใช้งาน:';
+$labels['advanced'] = 'โหมดขั้นสูง';
+$labels['newuser'] = 'เพิ่มรายà¸à¸²à¸£';
+$labels['anyone'] = 'ผู้ใช้งานทั้งหมด (ใครà¸à¹‡à¹„ด้)';
+$labels['anonymous'] = 'ผู้เยี่ยมชม (คนà¹à¸›à¸¥à¸à¸«à¸™à¹‰à¸²)';
+$labels['aclr'] = 'อ่านข้อความ';
+$labels['acli'] = 'à¹à¸—รภ(คัดลอà¸à¹„ปไว้)';
+$labels['aclp'] = 'โพสต์';
+$labels['aclc'] = 'สร้างโฟลเดอร์ย่อย';
+$labels['aclk'] = 'สร้างโฟลเดอร์ย่อย';
+$labels['acld'] = 'ลบข้อความ';
+$labels['aclt'] = 'ลบข้อความ';
+$labels['aclx'] = 'ลบโฟลเดอร์';
+$labels['aclother'] = 'อื่นๆ';
+$labels['aclread'] = 'อ่าน';
+$labels['aclwrite'] = 'เขียน';
+$labels['acldelete'] = 'ลบ';
+$labels['shortaclr'] = 'อ่าน';
+$labels['shortaclw'] = 'เขียน';
+$labels['shortacli'] = 'à¹à¸—รà¸';
+$labels['shortaclp'] = 'โพสต์';
+$labels['shortaclc'] = 'สร้าง';
+$labels['shortaclk'] = 'สร้าง';
+$labels['shortacld'] = 'ลบ';
+$labels['shortaclt'] = 'ลบ';
+$labels['shortaclx'] = 'ลบโฟลเดอร์';
+$labels['shortaclother'] = 'อื่นๆ';
+$labels['shortaclread'] = 'อ่าน';
+$labels['shortaclwrite'] = 'เขียน';
+$labels['shortacldelete'] = 'ลบ';
+?>
diff --git a/plugins/acl/localization/ti.inc b/plugins/acl/localization/ti.inc
new file mode 100644
index 000000000..751be8736
--- /dev/null
+++ b/plugins/acl/localization/ti.inc
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/acl/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail ACL plugin |
+ | Copyright (C) 2012-2013, 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/plugin-acl/
+*/
+$labels['sharing'] = 'ንኻáˆáŠ¥';
+$labels['myrights'] = 'መሰላት በዓሠዋና';
+$labels['username'] = 'በዓሠዋና';
+$labels['advanced'] = 'á‹áˆ›á‹•á‰ áˆˆ አሰራርሓ';
+$labels['newuser'] = 'እታዎ ክá‹áˆµáŠ½';
+$labels['actions'] = 'ንጥáˆá‰³á‰µ መብት ተጠቃማይáŠá‰µ';
+$labels['anyone'] = 'ኩሉሠበዓáˆá‰² ዋናታት(á‹áŠ¾áŠ ሰብ)';
+$labels['anonymous'] = 'ጋሻ(ሽሠአáˆá‰¦)';
+$labels['identifier'] = 'መለለዪ';
+$labels['acll'] = 'አለሻ';
+$labels['aclr'] = 'á‹á‰°áŠá‰ á‰¡ መáˆáŠ¥áŠ½á‰³á‰µ';
+$labels['acls'] = 'ተራእዩ ብá‹á‰¥áˆ ይጽናሕ';
+$labels['aclw'] = 'áˆáˆáŠ­á‰³á‰µ áˆáŒ½áˆ“á';
+$labels['acli'] = 'ሸጉጥ(አብ..መንጎ አá‰áˆáŒ¥)';
+$labels['aclp'] = 'ጠቅዕ';
+$labels['aclc'] = 'ማህደር áጠር';
+$labels['aclk'] = 'ክáለማህደር áጠር';
+$labels['acld'] = 'መáˆáŠ¥áŠ½á‰³á‰µ አጥáእ';
+$labels['aclt'] = 'መáˆáŠ¥áŠ½á‰³á‰µ አጥáእ';
+$labels['acle'] = 'ንሓዋሩ አጥáእ';
+$labels['aclx'] = 'ማህደር አጥáእ';
+$labels['acla'] = 'ተቖáƒá€áˆ­';
+$labels['aclfull'] = 'áˆáˆ‰áŠ¥ ቑጽá…ር';
+$labels['aclother'] = 'ካሊእ';
+$labels['aclread'] = 'ከንብብ';
+$labels['aclwrite'] = 'ክጽሕá';
+$labels['acldelete'] = 'ይጥáˆáŠ áˆˆá‹­';
+$labels['shortacll'] = 'አለሻ';
+$labels['shortaclr'] = 'á‹á‰°áŠá‰ á‰ ';
+$labels['shortacls'] = 'á‹­á…ናሕ';
+$labels['shortaclw'] = 'ይጽሓá';
+$labels['shortacli'] = 'ይሸጎጥ';
+$labels['shortaclp'] = 'ይጠቃዕ';
+$labels['shortaclc'] = 'á‹­áˆáŒ áˆ­';
+$labels['shortaclk'] = 'á‹­áˆáŒ áˆ­';
+$labels['shortacld'] = 'ይጥá‹áŠ¥';
+$labels['shortaclt'] = 'ይጥá‹áŠ¥';
+$labels['shortacle'] = 'ንሓዋሩ ይጥá‹áŠ¥';
+$labels['shortaclx'] = 'á‹áŒ áእ ማህደር';
+$labels['shortacla'] = 'ክቆáƒá€áˆ­';
+$labels['shortaclother'] = 'ካሊእ';
+$labels['shortaclread'] = 'ከንብብ';
+$labels['shortaclwrite'] = 'ክጽሕá';
+$labels['shortacldelete'] = 'ይጥá‹áŠ¥';
+$labels['longaclr'] = 'ማህደር ተኸáŠá‰± ክንበብ ይኽእáˆ';
+$labels['longacls'] = 'ተራእዩ á‹á‰¥áˆ መáˆáŠ¥áŠ½á‰² ዕላሠክለወጥ ይኽእáˆ';
+$labels['longaclw'] = 'ዕላማትን መáትሕ ቃላትን መáˆáŠ½á‰µá‰³á‰µ ክáˆá‹ˆáŒ¡ ይኽእሉ, ብዘይካ á‹á‰°áˆ¨áŠ£á‹©áŠ• á‹áŒ áኡን';
+$labels['longacli'] = 'መáˆáŠ¥áŠ½á‰² ናብዚ ማህደር ክጽሓá ወይ ክቕዳሕ ይኽእáˆ';
+$labels['longaclp'] = 'መáˆáŠ¥áŠ½á‰² ናብዚ ማህደር ክኣቱ ይኽእáˆ';
+?>
diff --git a/plugins/acl/localization/tr_TR.inc b/plugins/acl/localization/tr_TR.inc
index f3d60324b..1569b5926 100644
--- a/plugins/acl/localization/tr_TR.inc
+++ b/plugins/acl/localization/tr_TR.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'Erişim hakları saklanıyor...';
$messages['updatesuccess'] = 'Erişim hakları başarıyla değiştirildi';
$messages['deletesuccess'] = 'Erişim hakları başarıyla silindi';
$messages['createsuccess'] = 'Erişim hakları başarıyla eklendi';
-$messages['updateerror'] = 'Erişim hakları güncellenemedi';
+$messages['updateerror'] = 'Erişim haklarını güncellenemedi';
$messages['deleteerror'] = 'Erişim haklarını silinemedi';
$messages['createerror'] = 'Erişim hakları eklenemedi';
$messages['deleteconfirm'] = 'Seçilen kullanıcılar için erişim haklarını silmek istediğinizden emin misiniz?';
diff --git a/plugins/acl/package.xml b/plugins/acl/package.xml
index 98460e82f..52e234f37 100644
--- a/plugins/acl/package.xml
+++ b/plugins/acl/package.xml
@@ -22,7 +22,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/acl/skins/classic/acl.css b/plugins/acl/skins/classic/acl.css
index cf3391f49..0764465a0 100644
--- a/plugins/acl/skins/classic/acl.css
+++ b/plugins/acl/skins/classic/acl.css
@@ -47,12 +47,12 @@
#acltable tbody td.partial
{
- background: url(images/partial.png) center no-repeat;
+ background: url(images/partial.png?v=05d7.389) center no-repeat;
}
#acltable tbody td.enabled
{
- background: url(images/enabled.png) center no-repeat;
+ background: url(images/enabled.png?v=9d9a.674) center no-repeat;
}
#acltable tr.selected td
diff --git a/plugins/acl/skins/larry/acl.css b/plugins/acl/skins/larry/acl.css
index e392a269e..67512a619 100644
--- a/plugins/acl/skins/larry/acl.css
+++ b/plugins/acl/skins/larry/acl.css
@@ -65,14 +65,14 @@
#acltable tbody td.partial
{
- background-image: url(images/partial.png);
+ background-image: url(images/partial.png?v=05d7.389);
background-position: center;
background-repeat: no-repeat;
}
#acltable tbody td.enabled
{
- background-image: url(images/enabled.png);
+ background-image: url(images/enabled.png?v=9d9a.674);
background-position: center;
background-repeat: no-repeat;
}
@@ -80,21 +80,21 @@
#acltable tbody tr.selected td.partial
{
background-color: #019bc6;
- background-image: url(images/partial.png), -moz-linear-gradient(top, #019bc6 0%, #017cb4 100%);
- background-image: url(images/partial.png), -webkit-gradient(linear, left top, left bottom, color-stop(0%,#019bc6), color-stop(100%,#017cb4));
- background-image: url(images/partial.png), -o-linear-gradient(top, #019bc6 0%, #017cb4 100%);
- background-image: url(images/partial.png), -ms-linear-gradient(top, #019bc6 0%, #017cb4 100%);
- background-image: url(images/partial.png), linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/partial.png?v=05d7.389), -moz-linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/partial.png?v=05d7.389), -webkit-gradient(linear, left top, left bottom, color-stop(0%,#019bc6), color-stop(100%,#017cb4));
+ background-image: url(images/partial.png?v=05d7.389), -o-linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/partial.png?v=05d7.389), -ms-linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/partial.png?v=05d7.389), linear-gradient(top, #019bc6 0%, #017cb4 100%);
}
#acltable tbody tr.selected td.enabled
{
background-color: #019bc6;
- background-image: url(images/enabled.png), -moz-linear-gradient(top, #019bc6 0%, #017cb4 100%);
- background-image: url(images/enabled.png), -webkit-gradient(linear, left top, left bottom, color-stop(0%,#019bc6), color-stop(100%,#017cb4));
- background-image: url(images/enabled.png), -o-linear-gradient(top, #019bc6 0%, #017cb4 100%);
- background-image: url(images/enabled.png), -ms-linear-gradient(top, #019bc6 0%, #017cb4 100%);
- background-image: url(images/enabled.png), linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/enabled.png?v=9d9a.674), -moz-linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/enabled.png?v=9d9a.674), -webkit-gradient(linear, left top, left bottom, color-stop(0%,#019bc6), color-stop(100%,#017cb4));
+ background-image: url(images/enabled.png?v=9d9a.674), -o-linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/enabled.png?v=9d9a.674), -ms-linear-gradient(top, #019bc6 0%, #017cb4 100%);
+ background-image: url(images/enabled.png?v=9d9a.674), linear-gradient(top, #019bc6 0%, #017cb4 100%);
}
#aclform
diff --git a/plugins/additional_message_headers/additional_message_headers.php b/plugins/additional_message_headers/additional_message_headers.php
index 0d16e605e..43f9d0098 100644
--- a/plugins/additional_message_headers/additional_message_headers.php
+++ b/plugins/additional_message_headers/additional_message_headers.php
@@ -6,8 +6,8 @@
* Very simple plugin which will add additional headers
* to or remove them from outgoing messages.
*
- * Enable the plugin in config.inc.php and add your desired headers:
- * $config['additional_message_headers'] = array('User-Agent' => 'My-Very-Own-Webmail');
+ * Enable the plugin in config/main.inc.php and add your desired headers:
+ * $rcmail_config['additional_message_headers'] = array('User-Agent');
*
* @version @package_version@
* @author Ziba Scott
diff --git a/plugins/additional_message_headers/config.inc.php.dist b/plugins/additional_message_headers/config.inc.php.dist
index 72a4f1cee..83ccd869c 100644
--- a/plugins/additional_message_headers/config.inc.php.dist
+++ b/plugins/additional_message_headers/config.inc.php.dist
@@ -1,14 +1,14 @@
<?php
-// $config['additional_message_headers']['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT'];
-// $config['additional_message_headers']['X-Originating-IP'] = $_SERVER['REMOTE_ADDR'];
-// $config['additional_message_headers']['X-RoundCube-Server'] = $_SERVER['SERVER_ADDR'];
+// $rcmail_config['additional_message_headers']['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT'];
+// $rcmail_config['additional_message_headers']['X-Originating-IP'] = $_SERVER['REMOTE_ADDR'];
+// $rcmail_config['additional_message_headers']['X-RoundCube-Server'] = $_SERVER['SERVER_ADDR'];
// if( isset( $_SERVER['MACHINE_NAME'] )) {
-// $config['additional_message_headers']['X-RoundCube-Server'] .= ' (' . $_SERVER['MACHINE_NAME'] . ')';
+// $rcmail_config['additional_message_headers']['X-RoundCube-Server'] .= ' (' . $_SERVER['MACHINE_NAME'] . ')';
// }
// To remove (e.g. X-Sender) message header use null value
-// $config['additional_message_headers']['X-Sender'] = null;
+// $rcmail_config['additional_message_headers']['X-Sender'] = null;
?>
diff --git a/plugins/archive/archive.js b/plugins/archive/archive.js
index 3500b9fe4..af2b0d26d 100644
--- a/plugins/archive/archive.js
+++ b/plugins/archive/archive.js
@@ -1,47 +1,34 @@
/*
* Archive plugin script
- * @version 2.0
+ * @version @package_version@
*/
function rcmail_archive(prop)
{
if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
return;
-
- if (rcmail.env.mailbox.indexOf(rcmail.env.archive_folder) != 0) {
- if (!rcmail.env.archive_type) {
- // simply move to archive folder (if no partition type is set)
- rcmail.command('move', rcmail.env.archive_folder);
- }
- else {
- // let the server sort the messages to the according subfolders
- var post_data = { _uid: rcmail.message_list.get_selection().join(','), _mbox: rcmail.env.mailbox };
- rcmail.http_post('plugin.move2archive', post_data);
- }
- }
+
+ if (rcmail.env.mailbox != rcmail.env.archive_folder)
+ rcmail.command('moveto', rcmail.env.archive_folder);
}
// callback for app-onload event
if (window.rcmail) {
rcmail.addEventListener('init', function(evt) {
+
// register command (directly enable in message view mode)
rcmail.register_command('plugin.archive', rcmail_archive, (rcmail.env.uid && rcmail.env.mailbox != rcmail.env.archive_folder));
-
+
// add event-listener to message list
if (rcmail.message_list)
- rcmail.message_list.addEventListener('select', function(list) {
+ rcmail.message_list.addEventListener('select', function(list){
rcmail.enable_command('plugin.archive', (list.get_selection().length > 0 && rcmail.env.mailbox != rcmail.env.archive_folder));
});
-
+
// set css style for archive folder
var li;
if (rcmail.env.archive_folder && (li = rcmail.get_folder_li(rcmail.env.archive_folder, '', true)))
$(li).addClass('archive');
-
- // callback for server response
- rcmail.addEventListener('plugin.move2archive_response', function(result) {
- if (result.update)
- rcmail.command('checkmail'); // refresh list
- });
})
}
+
diff --git a/plugins/archive/archive.php b/plugins/archive/archive.php
index 7a81606ab..0a298cbe3 100644
--- a/plugins/archive/archive.php
+++ b/plugins/archive/archive.php
@@ -6,7 +6,7 @@
* Plugin that adds a new button to the mailbox toolbar
* to move messages to a (user selectable) archive folder.
*
- * @version 2.0
+ * @version @package_version@
* @license GNU GPLv3+
* @author Andre Rodier, Thomas Bruederli
*/
@@ -41,23 +41,18 @@ class archive extends rcube_plugin
'domain' => $this->ID,
),
'toolbar');
-
+
// register hook to localize the archive folder
$this->add_hook('render_mailboxlist', array($this, 'render_mailboxlist'));
- // set env variables for client
+ // set env variable for client
$rcmail->output->set_env('archive_folder', $archive_folder);
- $rcmail->output->set_env('archive_type', $rcmail->config->get('archive_type',''));
// add archive folder to the list of default mailboxes
if (($default_folders = $rcmail->config->get('default_folders')) && !in_array($archive_folder, $default_folders)) {
$default_folders[] = $archive_folder;
$rcmail->config->set('default_folders', $default_folders);
- }
- }
- else if ($rcmail->task == 'mail') {
- // handler for ajax request
- $this->register_action('plugin.move2archive', array($this, 'move_messages'));
+ }
}
else if ($rcmail->task == 'settings') {
$dont_override = $rcmail->config->get('dont_override', array());
@@ -67,18 +62,15 @@ class archive extends rcube_plugin
}
}
}
-
- /**
- * Hook to give the archive folder a localized name in the mailbox list
- */
+
function render_mailboxlist($p)
{
$rcmail = rcmail::get_instance();
$archive_folder = $rcmail->config->get('archive_mbox');
- $show_real_name = $rcmail->config->get('show_real_foldernames');
+ $localize_name = $rcmail->config->get('archive_localize_name', true);
// set localized name for the configured archive folder
- if ($archive_folder && !$show_real_name) {
+ if ($archive_folder && $localize_name) {
if (isset($p['list'][$archive_folder]))
$p['list'][$archive_folder]['name'] = $this->gettext('archivefolder');
else // search in subfolders
@@ -88,10 +80,7 @@ class archive extends rcube_plugin
return $p;
}
- /**
- * Helper method to find the archive folder in the mailbox tree
- */
- private function _mod_folder_name(&$list, $folder, $new_name)
+ function _mod_folder_name(&$list, $folder, $new_name)
{
foreach ($list as $idx => $item) {
if ($item['id'] == $folder) {
@@ -104,100 +93,6 @@ class archive extends rcube_plugin
return false;
}
- /**
- * Plugin action to move the submitted list of messages to the archive subfolders
- * according to the user settings and their headers.
- */
- function move_messages()
- {
- $rcmail = rcmail::get_instance();
- $this->add_texts('localization');
-
- $storage = $rcmail->get_storage();
- $storage->set_folder(($current_mbox = rcube_utils::get_input_value('_mbox', RCUBE_INPUT_POST)));
-
- $delimiter = $storage->get_hierarchy_delimiter();
- $archive_folder = $rcmail->config->get('archive_mbox');
- $archive_type = $rcmail->config->get('archive_type', '');
-
- $result = array('reload' => false, 'update' => false, 'errors' => array());
-
- $uids = explode(',', rcube_utils::get_input_value('_uid', RCUBE_INPUT_POST));
- foreach ($uids as $uid) {
- if (!$archive_folder || !($message = $rcmail->storage->get_message($uid))) {
- continue;
- }
-
- $subfolder = null;
- switch ($archive_type) {
- case 'year':
- $subfolder = $rcmail->format_date($message->timestamp, 'Y');
- break;
-
- case 'month':
- $subfolder = $rcmail->format_date($message->timestamp, 'Y') . $delimiter . $rcmail->format_date($message->timestamp, 'm');
- break;
-
- case 'folder':
- $subfolder = $current_mbox;
- break;
-
- case 'sender':
- $from = $message->get('from');
- if (preg_match('/[\b<](.+@.+)[\b>]/i', $from, $m)) {
- $subfolder = $m[1];
- }
- else {
- $subfolder = $this->gettext('unkownsender');
- }
-
- // replace reserved characters in folder name
- $repl = $delimiter == '-' ? '_' : '-';
- $replacements[$delimiter] = $repl;
- $replacements['.'] = $repl; // some IMAP server do not allow . characters
- $subfolder = strtr($subfolder, $replacements);
- break;
-
- default:
- $subfolder = '';
- break;
- }
-
- // compose full folder path
- $folder = $archive_folder . ($subfolder ? $delimiter . $subfolder : '');
-
- // create archive subfolder if it doesn't yet exist
- if (!$storage->folder_exists($folder, false)) {
- if ($storage->create_folder($folder, true))
- $result['reload'] = true;
- }
-
- // move message to target folder
- if ($storage->move_message(array($uid), $folder)) {
- $result['update'] = true;
- }
- else {
- $result['errors'][] = $uid;
- }
- } // end for
-
- // send response
- if ($result['errors']) {
- $rcmail->output->show_message($this->gettext('archiveerror'), 'warning');
- }
- if ($result['reload']) {
- $rcmail->output->show_message($this->gettext('archivedreload'), 'confirmation');
- }
- else if ($result['update']) {
- $rcmail->output->show_message($this->gettext('archived'), 'confirmation');
- }
-
- $rcmail->output->command('plugin.move2archive_response', $result);
- }
-
- /**
- * Hook to inject plugin-specific user settings
- */
function prefs_table($args)
{
global $CURR_SECTION;
@@ -209,7 +104,7 @@ class archive extends rcube_plugin
// load folders list when needed
if ($CURR_SECTION)
- $select = $rcmail->folder_selector(array('noselection' => '---', 'realnames' => true,
+ $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true,
'maxlength' => 30, 'exceptions' => array('INBOX'), 'folder_filter' => 'mail', 'folder_rights' => 'w'));
else
$select = new html_select();
@@ -218,36 +113,15 @@ class archive extends rcube_plugin
'title' => $this->gettext('archivefolder'),
'content' => $select->show($rcmail->config->get('archive_mbox'), array('name' => "_archive_mbox"))
);
-
- // add option for structuring the archive folder
- $archive_type = new html_select(array('name' => '_archive_type', 'id' => 'ff_archive_type'));
- $archive_type->add($this->gettext('none'), '');
- $archive_type->add($this->gettext('archivetypeyear'), 'year');
- $archive_type->add($this->gettext('archivetypemonth'), 'month');
- $archive_type->add($this->gettext('archivetypesender'), 'sender');
- $archive_type->add($this->gettext('archivetypefolder'), 'folder');
-
- $args['blocks']['archive'] = array(
- 'name' => Q(rcube_label('settingstitle', 'archive')),
- 'options' => array('archive_type' => array(
- 'title' => $this->gettext('archivetype'),
- 'content' => $archive_type->show($rcmail->config->get('archive_type'))
- )
- )
- );
}
return $args;
}
- /**
- * Hook to save plugin-specific user settings
- */
function save_prefs($args)
{
if ($args['section'] == 'folders') {
- $args['prefs']['archive_mbox'] = rcube_utils::get_input_value('_archive_mbox', rcube_utils::INPUT_POST);
- $args['prefs']['archive_type'] = rcube_utils::get_input_value('_archive_type', rcube_utils::INPUT_POST);
+ $args['prefs']['archive_mbox'] = get_input_value('_archive_mbox', RCUBE_INPUT_POST);
return $args;
}
}
diff --git a/plugins/archive/localization/ar.inc b/plugins/archive/localization/ar.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/ar.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/ast.inc b/plugins/archive/localization/ast.inc
new file mode 100644
index 000000000..546c33538
--- /dev/null
+++ b/plugins/archive/localization/ast.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+$labels['buttontext'] = 'Archivu';
+$labels['buttontitle'] = 'Archivar esti mensaxe';
+$labels['archived'] = 'Mensaxe archiváu';
+$labels['archivedreload'] = 'Archiváu correchamente. Recarga la páxina pa ver les nueves carpetes d\'archivu.';
+$labels['archiveerror'] = 'Nun pudieron archivase dalgunos mensaxes';
+$labels['archivefolder'] = 'Archivu';
+$labels['settingstitle'] = 'Archivu';
+$labels['archivetype'] = 'Dividir l\'archivu por';
+$labels['archivetypeyear'] = 'Añu (p.ex. Archivu/2012)';
+$labels['archivetypemonth'] = 'Mes (p.ex. Archivu/2012/06)';
+$labels['archivetypefolder'] = 'Bandexa orixinal';
+$labels['archivetypesender'] = 'Corréu-e del remitente';
+$labels['unkownsender'] = 'desconocíu';
+?>
diff --git a/plugins/archive/localization/bn_BD.inc b/plugins/archive/localization/bn_BD.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/bn_BD.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/en_US.inc b/plugins/archive/localization/en_US.inc
index d3714c118..fade70852 100644
--- a/plugins/archive/localization/en_US.inc
+++ b/plugins/archive/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/archive/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Archive plugin |
- | Copyright (C) 2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -20,15 +20,6 @@ $labels = array();
$labels['buttontext'] = 'Archive';
$labels['buttontitle'] = 'Archive this message';
$labels['archived'] = 'Successfully archived';
-$labels['archivedreload'] = 'Successfully archived. Reload the page to see the new archive folders.';
-$labels['archiveerror'] = 'Some messages could not be archived';
$labels['archivefolder'] = 'Archive';
-$labels['settingstitle'] = 'Archive';
-$labels['archivetype'] = 'Divide archive by';
-$labels['archivetypeyear'] = 'Year (e.g. Archive/2012)';
-$labels['archivetypemonth'] = 'Month (e.g. Archive/2012/06)';
-$labels['archivetypefolder'] = 'Original folder';
-$labels['archivetypesender'] = 'Sender email';
-$labels['unkownsender'] = 'unknown';
?>
diff --git a/plugins/archive/localization/eu_ES.inc b/plugins/archive/localization/eu_ES.inc
new file mode 100644
index 000000000..c4f0e7b0e
--- /dev/null
+++ b/plugins/archive/localization/eu_ES.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+$labels['buttontext'] = 'Gorde';
+$labels['buttontitle'] = 'Gorde mezu hau';
+$labels['archived'] = 'Ongi gorde da';
+$labels['archivedreload'] = 'Ongi gorde da. Freskatu orria fitxategi-karpeta berria ikusteko.';
+$labels['archiveerror'] = 'Mezu batzuk ezin dira gorde.';
+$labels['archivefolder'] = 'Gorde';
+$labels['settingstitle'] = 'Gorde';
+$labels['archivetype'] = 'Banatu honen arabera';
+$labels['archivetypeyear'] = 'Urtea (e.b. Archive/2012)';
+$labels['archivetypemonth'] = 'Hilabete (e.b. Archive/2012/06)';
+$labels['archivetypefolder'] = 'Jatorrizko karpeta';
+$labels['archivetypesender'] = 'Bidaltzailearen helbidea';
+$labels['unkownsender'] = 'ezezaguna';
+?>
diff --git a/plugins/archive/localization/fa_AF.inc b/plugins/archive/localization/fa_AF.inc
new file mode 100644
index 000000000..fafccb5b8
--- /dev/null
+++ b/plugins/archive/localization/fa_AF.inc
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+$labels['buttontext'] = 'ارشیو';
+$labels['buttontitle'] = 'ارشیو این پیام';
+$labels['archived'] = 'با موÙقیت ارشیو شد';
+$labels['archivefolder'] = 'ارشیو';
+$labels['settingstitle'] = 'ارشیو';
+$labels['archivetypefolder'] = 'پوشه اصلی';
+$labels['archivetypesender'] = 'ایمیل Ùرستنده';
+$labels['unkownsender'] = 'نا شناس';
+?>
diff --git a/plugins/archive/localization/fa_IR.inc b/plugins/archive/localization/fa_IR.inc
index 03bf6d8bd..9df31ed31 100644
--- a/plugins/archive/localization/fa_IR.inc
+++ b/plugins/archive/localization/fa_IR.inc
@@ -20,11 +20,11 @@ $labels = array();
$labels['buttontext'] = 'بایگانی';
$labels['buttontitle'] = 'بایگانی این پیغام';
$labels['archived'] = 'با موÙقیت بایگانی شد';
-$labels['archivedreload'] = 'با موÙقیت بایگانی شد. برای دیدن پوشه‌های بایگانی جدید صÙحه را مجددا بارگذاری نمایید.';
-$labels['archiveerror'] = 'برخی از پیغام‌ها بایگانی نشدند.';
+$labels['archivedreload'] = 'با موÙقیت بایگانی شد، بارگذاری مجدد صÙحه برای دیدن پوشه‌های بایگانی جدید.';
+$labels['archiveerror'] = 'برخی پیغام‌ها بایگانی نخواهند شد';
$labels['archivefolder'] = 'بایگانی';
$labels['settingstitle'] = 'بایگانی';
-$labels['archivetype'] = 'تقسیم بایگانی با';
+$labels['archivetype'] = 'جدا کردن بایگانی با';
$labels['archivetypeyear'] = 'سال (به عنوان مثال بایگانی/۲۰۱۲)';
$labels['archivetypemonth'] = 'ماه (به عنوان مثال بایگانی/۲۰۱۲/۰۶)';
$labels['archivetypefolder'] = 'پوشه اصلی';
diff --git a/plugins/archive/localization/fi_FI.inc b/plugins/archive/localization/fi_FI.inc
index 261bc19ec..9dda46ec0 100644
--- a/plugins/archive/localization/fi_FI.inc
+++ b/plugins/archive/localization/fi_FI.inc
@@ -20,15 +20,15 @@ $labels = array();
$labels['buttontext'] = 'Arkistoi';
$labels['buttontitle'] = 'Arkistoi viesti';
$labels['archived'] = 'Arkistoitu onnistuneesti';
-$labels['archivedreload'] = 'Successfully archived. Reload the page to see the new archive folders.';
-$labels['archiveerror'] = 'Some messages could not be archived';
+$labels['archivedreload'] = 'Arkistointi onnistui. Päivitä sivu nähdäksesi uudet arkistokansiot.';
+$labels['archiveerror'] = 'Joidenkin viestien arkistointi epäonnistui';
$labels['archivefolder'] = 'Arkistoi';
-$labels['settingstitle'] = 'Archive';
-$labels['archivetype'] = 'Divide archive by';
-$labels['archivetypeyear'] = 'Year (e.g. Archive/2012)';
-$labels['archivetypemonth'] = 'Month (e.g. Archive/2012/06)';
-$labels['archivetypefolder'] = 'Original folder';
-$labels['archivetypesender'] = 'Sender email';
-$labels['unkownsender'] = 'unknown';
+$labels['settingstitle'] = 'Arkistoi';
+$labels['archivetype'] = 'Jaa arkisto';
+$labels['archivetypeyear'] = 'Vuodella (esim. Arkisto/2012)';
+$labels['archivetypemonth'] = 'Kuukaudella (esim. Arkisto/2012/06)';
+$labels['archivetypefolder'] = 'Alkuperäinen kansio';
+$labels['archivetypesender'] = 'Lähettäjän osoite';
+$labels['unkownsender'] = 'tuntematon';
?>
diff --git a/plugins/archive/localization/fr_FR.inc b/plugins/archive/localization/fr_FR.inc
index fbed8725b..638de3a40 100644
--- a/plugins/archive/localization/fr_FR.inc
+++ b/plugins/archive/localization/fr_FR.inc
@@ -19,16 +19,16 @@
$labels = array();
$labels['buttontext'] = 'Archive';
$labels['buttontitle'] = 'Archiver ce message';
-$labels['archived'] = 'Message archivé avec success';
+$labels['archived'] = 'Message archivé avec succès';
$labels['archivedreload'] = 'Archivé avec succès. Rechargez la page pour voir les nouveaux dossiers d\'archivage.';
$labels['archiveerror'] = 'Certains messages n\'ont pas pu être archivés.';
$labels['archivefolder'] = 'Archive';
$labels['settingstitle'] = 'Archive';
-$labels['archivetype'] = 'Diviser l\'archive en';
+$labels['archivetype'] = 'Diviser l\'archive par';
$labels['archivetypeyear'] = 'Année (ex Archives/2012)';
$labels['archivetypemonth'] = 'Mois (ex Archives/2012/06)';
$labels['archivetypefolder'] = 'Dossier original';
-$labels['archivetypesender'] = 'Email de l\'émetteur';
+$labels['archivetypesender'] = 'Courriel de l\'émetteur';
$labels['unkownsender'] = 'inconnu';
?>
diff --git a/plugins/archive/localization/hi_IN.inc b/plugins/archive/localization/hi_IN.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/hi_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/ia.inc b/plugins/archive/localization/ia.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/ia.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/lb_LU.inc b/plugins/archive/localization/lb_LU.inc
index 6e9e6db22..ac16cfea7 100644
--- a/plugins/archive/localization/lb_LU.inc
+++ b/plugins/archive/localization/lb_LU.inc
@@ -15,8 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-archive/
*/
-
-$labels = array();
$labels['buttontext'] = 'Archivéieren';
$labels['buttontitle'] = 'Dëse Message archivéieren';
$labels['archived'] = 'Erfollegräich archivéiert';
@@ -30,5 +28,4 @@ $labels['archivetypemonth'] = 'Mount (z.B. Archiv/2013/06)';
$labels['archivetypefolder'] = 'Original-Dossier';
$labels['archivetypesender'] = 'Sender-E-Mail';
$labels['unkownsender'] = 'onbekannt';
-
?>
diff --git a/plugins/archive/localization/lv_LV.inc b/plugins/archive/localization/lv_LV.inc
index d4c892705..ad2812fba 100644
--- a/plugins/archive/localization/lv_LV.inc
+++ b/plugins/archive/localization/lv_LV.inc
@@ -18,17 +18,17 @@
$labels = array();
$labels['buttontext'] = 'Arhīvs';
-$labels['buttontitle'] = 'Arhivēt šo vēstuli';
-$labels['archived'] = 'Vēstule veiksmīgi arhivēta';
-$labels['archivedreload'] = 'ArhÄ«vs veiksmÄ«gi izveidots. Lai redzÄ“tu jaunÄs arhÄ«va mapes, pÄrlÄdÄ“jiet lapu.';
-$labels['archiveerror'] = 'Dažas vēstules nebija iespējams arhivēt';
+$labels['buttontitle'] = 'Arhivēt vēstuli';
+$labels['archived'] = 'Vēstule sekmīgi arhivēta';
+$labels['archivedreload'] = 'Successfully archived. Reload the page to see the new archive folders.';
+$labels['archiveerror'] = 'Some messages could not be archived';
$labels['archivefolder'] = 'Arhīvs';
-$labels['settingstitle'] = 'Arhīvs';
-$labels['archivetype'] = 'Sadalīt arhīvu pa';
-$labels['archivetypeyear'] = 'Gadiem (piem. Arhīvs/2012)';
-$labels['archivetypemonth'] = 'Mēnešiem (piem. Arhīvs/2012/06)';
-$labels['archivetypefolder'] = 'SÄkotnÄ“jÄ mape';
-$labels['archivetypesender'] = 'SÅ«tÄ«tÄja e-pasts';
-$labels['unkownsender'] = 'nezinÄms';
+$labels['settingstitle'] = 'Archive';
+$labels['archivetype'] = 'Divide archive by';
+$labels['archivetypeyear'] = 'Year (e.g. Archive/2012)';
+$labels['archivetypemonth'] = 'Month (e.g. Archive/2012/06)';
+$labels['archivetypefolder'] = 'Original folder';
+$labels['archivetypesender'] = 'Sender email';
+$labels['unkownsender'] = 'unknown';
?>
diff --git a/plugins/archive/localization/mn_MN.inc b/plugins/archive/localization/mn_MN.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/mn_MN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/ms_MY.inc b/plugins/archive/localization/ms_MY.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/ms_MY.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/my_MM.inc b/plugins/archive/localization/my_MM.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/my_MM.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
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/archive/localization/nb_NO.inc b/plugins/archive/localization/nb_NO.inc
index 62ea381ca..accad4efa 100644
--- a/plugins/archive/localization/nb_NO.inc
+++ b/plugins/archive/localization/nb_NO.inc
@@ -28,7 +28,7 @@ $labels['archivetype'] = 'Del arkiv etter';
$labels['archivetypeyear'] = 'Ã…r (f.eks. Arkiv/2012)';
$labels['archivetypemonth'] = 'MÃ¥ned (f.eks. Arkiv/2012/06)';
$labels['archivetypefolder'] = 'Opprinnelig mappe';
-$labels['archivetypesender'] = 'Sender email';
+$labels['archivetypesender'] = 'Avsender';
$labels['unkownsender'] = 'ukjent';
?>
diff --git a/plugins/archive/localization/nl_BE.inc b/plugins/archive/localization/nl_BE.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/nl_BE.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/nn_NO.inc b/plugins/archive/localization/nn_NO.inc
index 01effaa62..4b2801688 100644
--- a/plugins/archive/localization/nn_NO.inc
+++ b/plugins/archive/localization/nn_NO.inc
@@ -28,7 +28,7 @@ $labels['archivetype'] = 'Del arkiv etter';
$labels['archivetypeyear'] = 'Ã…r (f.eks. Arkiv/2012)';
$labels['archivetypemonth'] = 'MÃ¥nad (f.eks. Arkiv/2012/06)';
$labels['archivetypefolder'] = 'Opprinneleg mappe';
-$labels['archivetypesender'] = 'Sender email';
+$labels['archivetypesender'] = 'Avsendar';
$labels['unkownsender'] = 'ukjent';
?>
diff --git a/plugins/archive/localization/nqo.inc b/plugins/archive/localization/nqo.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/nqo.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/om.inc b/plugins/archive/localization/om.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/om.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/pt_BR.inc b/plugins/archive/localization/pt_BR.inc
index 05508e2e3..3df6cfdad 100644
--- a/plugins/archive/localization/pt_BR.inc
+++ b/plugins/archive/localization/pt_BR.inc
@@ -20,15 +20,15 @@ $labels = array();
$labels['buttontext'] = 'Arquivo';
$labels['buttontitle'] = 'Arquivar esta mensagem';
$labels['archived'] = 'Arquivada com sucesso';
-$labels['archivedreload'] = 'Successfully archived. Reload the page to see the new archive folders.';
-$labels['archiveerror'] = 'Some messages could not be archived';
+$labels['archivedreload'] = 'Arquivado com sucesso. Recarregue a página para ver as novas pastas de arquivo.';
+$labels['archiveerror'] = 'Algumas mensagens não puderam ser arquivadas';
$labels['archivefolder'] = 'Arquivo';
-$labels['settingstitle'] = 'Archive';
-$labels['archivetype'] = 'Divide archive by';
-$labels['archivetypeyear'] = 'Year (e.g. Archive/2012)';
-$labels['archivetypemonth'] = 'Month (e.g. Archive/2012/06)';
-$labels['archivetypefolder'] = 'Original folder';
-$labels['archivetypesender'] = 'Sender email';
-$labels['unkownsender'] = 'unknown';
+$labels['settingstitle'] = 'Arquivo';
+$labels['archivetype'] = 'Dividir arquivo por';
+$labels['archivetypeyear'] = 'Ano (isto é, Arquivo/2012)';
+$labels['archivetypemonth'] = 'Mês (isto é, Arquivo/2012/06)';
+$labels['archivetypefolder'] = 'Pasta original';
+$labels['archivetypesender'] = 'E-mail do remetente';
+$labels['unkownsender'] = 'desconhecido';
?>
diff --git a/plugins/archive/localization/ro_RO.inc b/plugins/archive/localization/ro_RO.inc
index e88e918fa..6fa5cee22 100644
--- a/plugins/archive/localization/ro_RO.inc
+++ b/plugins/archive/localization/ro_RO.inc
@@ -18,13 +18,13 @@
$labels = array();
$labels['buttontext'] = 'Arhivă';
-$labels['buttontitle'] = 'Arhivează acest mesaj.';
+$labels['buttontitle'] = 'Arhivează mesajul.';
$labels['archived'] = 'Arhivare reuşită.';
$labels['archivedreload'] = 'Arhivat cu succes. Reîncărcați pagina pentru a vedea noul dosar de arhivare.';
-$labels['archiveerror'] = 'Câteva mesaje nu au putut fi arhivate';
+$labels['archiveerror'] = 'Unele mesaje nu au putut fi arhivate';
$labels['archivefolder'] = 'Arhivă';
$labels['settingstitle'] = 'Arhivă';
-$labels['archivetype'] = 'Divide arhiva pe';
+$labels['archivetype'] = 'ÃŽmparte arhiva pe';
$labels['archivetypeyear'] = 'Ani (ex. Arhiva/2013)';
$labels['archivetypemonth'] = 'Luni (ex. Arhiva/2013/06)';
$labels['archivetypefolder'] = 'Dosar original';
diff --git a/plugins/archive/localization/te_IN.inc b/plugins/archive/localization/te_IN.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/te_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/th_TH.inc b/plugins/archive/localization/th_TH.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/th_TH.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/ti.inc b/plugins/archive/localization/ti.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/ti.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/tzm.inc b/plugins/archive/localization/tzm.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/tzm.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/ur_PK.inc b/plugins/archive/localization/ur_PK.inc
new file mode 100644
index 000000000..8e95162d5
--- /dev/null
+++ b/plugins/archive/localization/ur_PK.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/archive/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-archive/
+*/
+?>
diff --git a/plugins/archive/localization/zh_CN.inc b/plugins/archive/localization/zh_CN.inc
index 17af54cde..4a13d541a 100644
--- a/plugins/archive/localization/zh_CN.inc
+++ b/plugins/archive/localization/zh_CN.inc
@@ -18,17 +18,17 @@
$labels = array();
$labels['buttontext'] = '存档';
-$labels['buttontitle'] = '将该信æ¯å­˜æ¡£';
+$labels['buttontitle'] = '存档该信æ¯';
$labels['archived'] = '存档æˆåŠŸ';
-$labels['archivedreload'] = 'Successfully archived. Reload the page to see the new archive folders.';
-$labels['archiveerror'] = 'Some messages could not be archived';
+$labels['archivedreload'] = '存档æˆåŠŸã€‚请刷新本页以查看新的存档文件夹。';
+$labels['archiveerror'] = '部分信æ¯æ— æ³•å­˜æ¡£';
$labels['archivefolder'] = '存档';
-$labels['settingstitle'] = 'Archive';
-$labels['archivetype'] = 'Divide archive by';
-$labels['archivetypeyear'] = 'Year (e.g. Archive/2012)';
-$labels['archivetypemonth'] = 'Month (e.g. Archive/2012/06)';
-$labels['archivetypefolder'] = 'Original folder';
-$labels['archivetypesender'] = 'Sender email';
-$labels['unkownsender'] = 'unknown';
+$labels['settingstitle'] = '存档';
+$labels['archivetype'] = '分类存档按';
+$labels['archivetypeyear'] = '年(例如 存档/2012)';
+$labels['archivetypemonth'] = '月(例如 存档/2012/06)';
+$labels['archivetypefolder'] = '原始文件夹';
+$labels['archivetypesender'] = 'å‘件人邮件';
+$labels['unkownsender'] = '未知';
?>
diff --git a/plugins/archive/package.xml b/plugins/archive/package.xml
index 62a009a99..1aeffaf41 100644
--- a/plugins/archive/package.xml
+++ b/plugins/archive/package.xml
@@ -6,17 +6,17 @@
<name>archive</name>
<channel>pear.roundcube.net</channel>
<summary>Archive feature for Roundcube</summary>
- <description>This adds a button to move the selected messages to an archive folder. The folder (and the optional structure of subfolders) can be selected in the settings panel.</description>
+ <description>This adds a button to move the selected messages to an archive folder. The folder can be selected in the settings panel.</description>
<lead>
<name>Thomas Bruederli</name>
<user>thomasb</user>
<email>roundcube@gmail.com</email>
<active>yes</active>
</lead>
- <date>2013-01-20</date>
+ <date>2011-11-23</date>
<version>
- <release>2.0</release>
- <api>2.0</api>
+ <release>1.6</release>
+ <api>1.6</api>
</version>
<stability>
<release>stable</release>
@@ -34,55 +34,21 @@
<tasks:replace from="@name@" to="name" type="package-info"/>
<tasks:replace from="@package_version@" to="version" type="package-info"/>
</file>
- <file name="localization/ar_SA.inc" role="data"></file>
- <file name="localization/az_AZ.inc" role="data"></file>
- <file name="localization/be_BE.inc" role="data"></file>
- <file name="localization/bg_BG.inc" role="data"></file>
- <file name="localization/bs_BA.inc" role="data"></file>
- <file name="localization/ca_ES.inc" role="data"></file>
<file name="localization/cs_CZ.inc" role="data"></file>
- <file name="localization/cy_GB.inc" role="data"></file>
- <file name="localization/da_DK.inc" role="data"></file>
<file name="localization/de_CH.inc" role="data"></file>
<file name="localization/de_DE.inc" role="data"></file>
- <file name="localization/el_GR.inc" role="data"></file>
- <file name="localization/eb_GB.inc" role="data"></file>
<file name="localization/en_US.inc" role="data"></file>
<file name="localization/es_AR.inc" role="data"></file>
<file name="localization/es_ES.inc" role="data"></file>
<file name="localization/et_EE.inc" role="data"></file>
- <file name="localization/fa_IR.inc" role="data"></file>
- <file name="localization/fi_FI.inc" role="data"></file>
<file name="localization/fr_FR.inc" role="data"></file>
<file name="localization/gl_ES.inc" role="data"></file>
- <file name="localization/he_IL.inc" role="data"></file>
- <file name="localization/hr_HR.inc" role="data"></file>
- <file name="localization/hu_HU.inc" role="data"></file>
- <file name="localization/hy_AM.inc" role="data"></file>
- <file name="localization/id_ID.inc" role="data"></file>
- <file name="localization/it_IT.inc" role="data"></file>
<file name="localization/ja_JP.inc" role="data"></file>
- <file name="localization/km_KH.inc" role="data"></file>
- <file name="localization/ko_KR.inc" role="data"></file>
- <file name="localization/lt_LT.inc" role="data"></file>
- <file name="localization/lv_LV.inc" role="data"></file>
- <file name="localization/ml_IN.inc" role="data"></file>
- <file name="localization/nb_NO.inc" role="data"></file>
<file name="localization/nl_NL.inc" role="data"></file>
- <file name="localization/nn_NO.inc" role="data"></file>
<file name="localization/pl_PL.inc" role="data"></file>
<file name="localization/pt_BR.inc" role="data"></file>
- <file name="localization/pt_PT.inc" role="data"></file>
<file name="localization/ru_RU.inc" role="data"></file>
- <file name="localization/si_LK.inc" role="data"></file>
- <file name="localization/sk_SK.inc" role="data"></file>
- <file name="localization/sl_SI.inc" role="data"></file>
- <file name="localization/sr_CS.inc" role="data"></file>
<file name="localization/sv_SE.inc" role="data"></file>
- <file name="localization/tr_TR.inc" role="data"></file>
- <file name="localization/uk_UA.inc" role="data"></file>
- <file name="localization/vi_VN.inc" role="data"></file>
- <file name="localization/zh_CN.inc" role="data"></file>
<file name="localization/zh_TW.inc" role="data"></file>
<file name="skins/classic/archive_act.png" role="data"></file>
<file name="skins/classic/archive_pas.png" role="data"></file>
diff --git a/plugins/attachment_reminder/localization/ar.inc b/plugins/attachment_reminder/localization/ar.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ar.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/ar_SA.inc b/plugins/attachment_reminder/localization/ar_SA.inc
new file mode 100644
index 000000000..bb1ad0449
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ar_SA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "هل نسيت إرÙاق ملÙØŸ";
+$messages['reminderoption'] = "تذكير حول المرÙقات المنسية";
+$messages['keywords'] = "المرÙقات,الملÙ,ارÙاق,مرÙÙ‚,ارÙاق,مضمون,CV,صÙحة المغلÙ";
diff --git a/plugins/attachment_reminder/localization/az_AZ.inc b/plugins/attachment_reminder/localization/az_AZ.inc
new file mode 100644
index 000000000..5340c917e
--- /dev/null
+++ b/plugins/attachment_reminder/localization/az_AZ.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Faylı əlavə etməyi unutdunuz?";
+$messages['reminderoption'] = "Unudulmuş qoşmalardan xəbərdar et";
+$messages['keywords'] = "qoşmalar,fayl,qoşma,qoşulub,qoşulur,qapalı,CV,qoşma məktub";
diff --git a/plugins/attachment_reminder/localization/be_BE.inc b/plugins/attachment_reminder/localization/be_BE.inc
new file mode 100644
index 000000000..a920ccfa6
--- /dev/null
+++ b/plugins/attachment_reminder/localization/be_BE.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "ЗабыліÑÑ Ð´Ð°Ð»ÑƒÑ‡Ñ‹Ñ†ÑŒ файл?";
+$messages['reminderoption'] = "Ðапамінаць пра Ð·Ð°Ð±Ñ‹Ñ‚Ñ‹Ñ Ð´Ð°Ð»ÑƒÑ‡Ñнні";
+$messages['keywords'] = "далучÑнне,файл,далучыць,далучаны,далучаецца,укладзены,CV,cover letter";
diff --git a/plugins/attachment_reminder/localization/bg_BG.inc b/plugins/attachment_reminder/localization/bg_BG.inc
new file mode 100644
index 000000000..a882d6c94
--- /dev/null
+++ b/plugins/attachment_reminder/localization/bg_BG.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Забравихте ли да прикрепите файл към Ñъобщението?";
+$messages['reminderoption'] = "ÐапомнÑне за забравени прикачени файлове";
+$messages['keywords'] = "прикачен,прикрепен,прикачам,прикачвам,прикрепÑм,прикрепвам,файл,attachment,file,attach,attached,attaching,enclosed,CV,cover letter";
diff --git a/plugins/attachment_reminder/localization/bn_BD.inc b/plugins/attachment_reminder/localization/bn_BD.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/bn_BD.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/bs_BA.inc b/plugins/attachment_reminder/localization/bs_BA.inc
new file mode 100644
index 000000000..1ec385dfa
--- /dev/null
+++ b/plugins/attachment_reminder/localization/bs_BA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Da li ste zaboravili da dodate ovu datoteku?";
+$messages['reminderoption'] = "Napomene o zaboravljenim prilozima";
+$messages['keywords'] = "attachment,file,attach,attached,attaching,enclosed,CV,cover letter,prilog,biografija,popratno pismo,prilogu,popratnom pismu,datoteka,fajl";
diff --git a/plugins/attachment_reminder/localization/ca_ES.inc b/plugins/attachment_reminder/localization/ca_ES.inc
new file mode 100644
index 000000000..957548bfb
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ca_ES.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Heu oblidat afegir un fitxer?";
+$messages['reminderoption'] = "Avís de fitxers adjunts oblidats";
+$messages['keywords'] = "adjunt,fitxer,adjuntar,adjuntat,adjuntant,CV,carta";
diff --git a/plugins/attachment_reminder/localization/cs_CZ.inc b/plugins/attachment_reminder/localization/cs_CZ.inc
new file mode 100644
index 000000000..3d2166478
--- /dev/null
+++ b/plugins/attachment_reminder/localization/cs_CZ.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Nezapomněli jste připojit přílohu?";
+$messages['reminderoption'] = "Upozorňovat na zapomenuté přílohy";
+$messages['keywords'] = "příloha,přílohy,příloze,přílohu,přiloženém,připojeném,CV,životopis";
diff --git a/plugins/attachment_reminder/localization/cy_GB.inc b/plugins/attachment_reminder/localization/cy_GB.inc
new file mode 100644
index 000000000..0ce8a9991
--- /dev/null
+++ b/plugins/attachment_reminder/localization/cy_GB.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Wedi anghofio atodi ffeil?";
+$messages['reminderoption'] = "Atgoffa am atodiadau ar goll";
+$messages['keywords'] = "atodiad,atodi,atodaf,atodwyd,atodir,amgaedig,dogfen,llythyr,ffeil,attachment,file,attach,attached,attaching,enclosed,CV,cover letter,";
diff --git a/plugins/attachment_reminder/localization/da_DK.inc b/plugins/attachment_reminder/localization/da_DK.inc
new file mode 100644
index 000000000..e41eafb36
--- /dev/null
+++ b/plugins/attachment_reminder/localization/da_DK.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Glemte du at vedhæfte en fil?";
+$messages['reminderoption'] = "Påmind om glemt vedhæftning af filer";
+$messages['keywords'] = "vedhæftet fil,fil,vedhæft,vedhæftet,vedhæfter,lukket,CV,følgebrev";
diff --git a/plugins/attachment_reminder/localization/de_CH.inc b/plugins/attachment_reminder/localization/de_CH.inc
index ad9f8d4f4..9aca61e68 100644
--- a/plugins/attachment_reminder/localization/de_CH.inc
+++ b/plugins/attachment_reminder/localization/de_CH.inc
@@ -15,8 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-attachment_reminder/
*/
-
-$messages = array();
$messages['forgotattachment'] = "Haben Sie möglicherweise vergessen eine Datei anzuhängen?";
$messages['reminderoption'] = "Vor vergessenen Anhängen warnen";
$messages['keywords'] = "anbei,anhang,angehängt,angefügt,beigefügt,beliegend";
diff --git a/plugins/attachment_reminder/localization/de_DE.inc b/plugins/attachment_reminder/localization/de_DE.inc
index 7de41d1fc..0422e2de2 100644
--- a/plugins/attachment_reminder/localization/de_DE.inc
+++ b/plugins/attachment_reminder/localization/de_DE.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
$messages['forgotattachment'] = "Haben Sie möglicherweise vergessen eine Datei anzuhängen?";
-$messages['reminderoption'] = "Remind about forgotten attachments";
+$messages['reminderoption'] = "Erinnern an vergessene Anhänge ";
$messages['keywords'] = "anbei,im anhang,angehängt,angefügt,beigefügt,beliegend";
diff --git a/plugins/attachment_reminder/localization/el_GR.inc b/plugins/attachment_reminder/localization/el_GR.inc
new file mode 100644
index 000000000..e47995f3a
--- /dev/null
+++ b/plugins/attachment_reminder/localization/el_GR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Μήπως ξεχάσετε να επισυνάψετε ένα αÏχείο; ";
+$messages['reminderoption'] = "ΥπενθÏμιση ξεχάσmena συνημμένα ";
+$messages['keywords'] = "συνημμένο, αÏχείο, συννημενο, επισυναψη, επισυνάπτοντας, κλειστό, βιογÏαφικό σημείωμα, συνοδευτική επιστολή";
diff --git a/plugins/attachment_reminder/localization/eo.inc b/plugins/attachment_reminder/localization/eo.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/eo.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/es_AR.inc b/plugins/attachment_reminder/localization/es_AR.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/es_AR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/es_ES.inc b/plugins/attachment_reminder/localization/es_ES.inc
index 79225d77e..7f6f29e6e 100644
--- a/plugins/attachment_reminder/localization/es_ES.inc
+++ b/plugins/attachment_reminder/localization/es_ES.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
$messages['forgotattachment'] = "¿Olvidó adjuntar un fichero al mensaje?";
-$messages['reminderoption'] = "Remind about forgotten attachments";
+$messages['reminderoption'] = "Recordatorio sobre adjuntos olvidados";
$messages['keywords'] = "adjunto";
diff --git a/plugins/attachment_reminder/localization/et_EE.inc b/plugins/attachment_reminder/localization/et_EE.inc
new file mode 100644
index 000000000..c8be2af6d
--- /dev/null
+++ b/plugins/attachment_reminder/localization/et_EE.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Unustasid faili lisada?";
+$messages['reminderoption'] = "Tuleta mulle meelde kui unustasin manuse lisada";
+$messages['keywords'] = "manus,manuses,lisatud,lisasin,fail,file,failis,attachment,file,attach,attached,attaching,enclosed,CV,cover letter";
diff --git a/plugins/attachment_reminder/localization/eu_ES.inc b/plugins/attachment_reminder/localization/eu_ES.inc
new file mode 100644
index 000000000..f658990e5
--- /dev/null
+++ b/plugins/attachment_reminder/localization/eu_ES.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Ahaztu zaizu fitxategia eranstea?";
+$messages['reminderoption'] = "Ohartarazi ahaztutako erankinez";
+$messages['keywords'] = "eranskin,fitxategia,erantzi,erantzita,eransten,atxikita";
diff --git a/plugins/attachment_reminder/localization/fa_AF.inc b/plugins/attachment_reminder/localization/fa_AF.inc
new file mode 100644
index 000000000..1c47737f1
--- /dev/null
+++ b/plugins/attachment_reminder/localization/fa_AF.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "آیا Ùراموش کردید Ú©Ù‡ Ùایل را الصاق کرده اید؟";
+$messages['reminderoption'] = "یاد آوری درمورد ضمایم Ùراموش شده";
+$messages['keywords'] = "ضمیمه،Ùایل،ضمیمه کردن،ضمیمه شده،در حال ضمیمه کردن، الصاق شده،CVØŒ عنوان نامه";
diff --git a/plugins/attachment_reminder/localization/fa_IR.inc b/plugins/attachment_reminder/localization/fa_IR.inc
new file mode 100644
index 000000000..fd1c40117
--- /dev/null
+++ b/plugins/attachment_reminder/localization/fa_IR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "آیا شما پیوست کردن پرونده را Ùراموش کرده‌اید؟";
+$messages['reminderoption'] = "یادآوری Ùراموشی پیوست‌ها";
+$messages['keywords'] = "پیوست،پرونده،پیوست کردن، پیوست شده، CV";
diff --git a/plugins/attachment_reminder/localization/fi_FI.inc b/plugins/attachment_reminder/localization/fi_FI.inc
new file mode 100644
index 000000000..53d2a9abb
--- /dev/null
+++ b/plugins/attachment_reminder/localization/fi_FI.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Unohditko liittää tiedoston?";
+$messages['reminderoption'] = "Muistuta mahdollisesti unohtuneista liitteistä";
+$messages['keywords'] = "attachment,file,attach,attached,attaching,enclosed,CV,cover letter,liite,tiedosto,liitteenä,liitetiedosto";
diff --git a/plugins/attachment_reminder/localization/fr_FR.inc b/plugins/attachment_reminder/localization/fr_FR.inc
index 78522c2e1..bda3eba90 100644
--- a/plugins/attachment_reminder/localization/fr_FR.inc
+++ b/plugins/attachment_reminder/localization/fr_FR.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
$messages['forgotattachment'] = "Avez vous oublié d'attacher un fichier ?";
-$messages['reminderoption'] = "Remind about forgotten attachments";
+$messages['reminderoption'] = "Rappel à propos des pièces jointes oubliées";
$messages['keywords'] = "joins,joint,attaché,CV";
diff --git a/plugins/attachment_reminder/localization/gl_ES.inc b/plugins/attachment_reminder/localization/gl_ES.inc
new file mode 100644
index 000000000..bd126b2af
--- /dev/null
+++ b/plugins/attachment_reminder/localization/gl_ES.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Esqueceches adxuntar un ficheiro?";
+$messages['reminderoption'] = "Lembrete de adxuntos esquecidos";
+$messages['keywords'] = "adxunto,ficheiro,engádega, engadido,engadindo,anexo,CV,cuberta,carta";
diff --git a/plugins/attachment_reminder/localization/he_IL.inc b/plugins/attachment_reminder/localization/he_IL.inc
new file mode 100644
index 000000000..2c348afb6
--- /dev/null
+++ b/plugins/attachment_reminder/localization/he_IL.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "×”×× ×©×›×—×ª לצרף קובץ?";
+$messages['reminderoption'] = "להזכיר לצרף נספח";
+$messages['keywords'] = "נספח,קובץ,לצרף,מצורף,מצרף,מצרפת,רצ\"ב,קו\"×—,קורות ×—×™×™×";
diff --git a/plugins/attachment_reminder/localization/hi_IN.inc b/plugins/attachment_reminder/localization/hi_IN.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/hi_IN.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/hu_HU.inc b/plugins/attachment_reminder/localization/hu_HU.inc
new file mode 100644
index 000000000..b76a8cf9b
--- /dev/null
+++ b/plugins/attachment_reminder/localization/hu_HU.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Nem felejtetted el a csatolandó file-t?";
+$messages['reminderoption'] = "Emlékeztessen a csatolandó csatolmányra";
+$messages['keywords'] = "csatolmány, file, csatolás, csatolt, csatolni, közrezárt, CV, kisérőlevél";
diff --git a/plugins/attachment_reminder/localization/hy_AM.inc b/plugins/attachment_reminder/localization/hy_AM.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/hy_AM.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/ia.inc b/plugins/attachment_reminder/localization/ia.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ia.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/id_ID.inc b/plugins/attachment_reminder/localization/id_ID.inc
new file mode 100644
index 000000000..1f0b0bb7a
--- /dev/null
+++ b/plugins/attachment_reminder/localization/id_ID.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Apakah anda lupa menambahkan attachment?";
+$messages['reminderoption'] = "Pengingat attachment yang terlupakan";
+$messages['keywords'] = "attachment,file,attach,attached,attaching,enclosed,CV,cover letter";
diff --git a/plugins/attachment_reminder/localization/it_IT.inc b/plugins/attachment_reminder/localization/it_IT.inc
index d326a6065..2a9772dcb 100644
--- a/plugins/attachment_reminder/localization/it_IT.inc
+++ b/plugins/attachment_reminder/localization/it_IT.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
$messages['forgotattachment'] = "Sembra che tu abbia dimenticato di allegare un file!\nPremere Annulla per inviare lo stesso.\nOK per tornare al messaggio senza inviare.";
-$messages['reminderoption'] = "Remind about forgotten attachments";
+$messages['reminderoption'] = "Ricorda per gli allegati dimenticati";
$messages['keywords'] = "allegato,allegati,allegata,allegate,allega,allego,alleghi,attaccato,file,attachment,attach";
diff --git a/plugins/attachment_reminder/localization/ja_JP.inc b/plugins/attachment_reminder/localization/ja_JP.inc
new file mode 100644
index 000000000..5ba55d446
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ja_JP.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "ファイルã®æ·»ä»˜ã‚’忘れã¦ã„ã¾ã›ã‚“ã‹?";
+$messages['reminderoption'] = "添付ファイルã®ä»˜ã‘忘れを確èª";
+$messages['keywords'] = "添付,ファイル,添付ファイル,åŒå°,æ·»ãˆçŠ¶";
diff --git a/plugins/attachment_reminder/localization/ko_KR.inc b/plugins/attachment_reminder/localization/ko_KR.inc
new file mode 100644
index 000000000..c80dcc4c8
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ko_KR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "파ì¼ì„ 첨부하는 ê²ƒì„ ìžŠìœ¼ì…¨ìŠµë‹ˆê¹Œ?";
+$messages['reminderoption'] = "ìžŠì—ˆë˜ ì²¨ë¶€íŒŒì¼ì— 대해 알리기";
+$messages['keywords'] = "attachment,file,attach,attached,attaching,enclosed,CV,cover letter";
diff --git a/plugins/attachment_reminder/localization/lb_LU.inc b/plugins/attachment_reminder/localization/lb_LU.inc
index cdfe031d1..f91f3d129 100644
--- a/plugins/attachment_reminder/localization/lb_LU.inc
+++ b/plugins/attachment_reminder/localization/lb_LU.inc
@@ -15,8 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-attachment_reminder/
*/
-
-$messages = array();
$messages['forgotattachment'] = "Hues du vergiess e Fichier drunzehänken?";
$messages['reminderoption'] = "U vergiessen Unhäng erënneren";
$messages['keywords'] = "Attachment,Fichier,Unhank,Unhang,Unhäng,ugehaangen,unhänken,attachment,file,attach,attached,attaching,enclosed,CV,cover letter,fichier joint";
diff --git a/plugins/attachment_reminder/localization/lt_LT.inc b/plugins/attachment_reminder/localization/lt_LT.inc
new file mode 100644
index 000000000..a8ba0b883
--- /dev/null
+++ b/plugins/attachment_reminder/localization/lt_LT.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Ar nepamiršote prisegti priedo?";
+$messages['reminderoption'] = "Priminti apie neprisegtus priedus";
+$messages['keywords'] = "priedas, byla, prisegti, prisegta, prisegama, uždaras, CV, laiškas";
diff --git a/plugins/attachment_reminder/localization/lv_LV.inc b/plugins/attachment_reminder/localization/lv_LV.inc
new file mode 100644
index 000000000..ee4feeb24
--- /dev/null
+++ b/plugins/attachment_reminder/localization/lv_LV.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Vai JÅ«s nepiemirsÄt pievienot failu?";
+$messages['reminderoption'] = "AtgÄdinÄt par nepievienotajiem pielikumiem";
+$messages['keywords'] = "pielikums,fails,pievienot,pielikt,pievienots,pielikts,ievietot,ievietots,CV";
diff --git a/plugins/attachment_reminder/localization/ml_IN.inc b/plugins/attachment_reminder/localization/ml_IN.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ml_IN.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/mn_MN.inc b/plugins/attachment_reminder/localization/mn_MN.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/mn_MN.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/ms_MY.inc b/plugins/attachment_reminder/localization/ms_MY.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ms_MY.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/my_MM.inc b/plugins/attachment_reminder/localization/my_MM.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/my_MM.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/nb_NO.inc b/plugins/attachment_reminder/localization/nb_NO.inc
new file mode 100644
index 000000000..1462837d5
--- /dev/null
+++ b/plugins/attachment_reminder/localization/nb_NO.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Glemte du å legge ved en fil?";
+$messages['reminderoption'] = "Gi meg en påminnelse om glemte vedlegg";
+$messages['keywords'] = "vedlegg, fil, legg ved, lagt ved, legger ved, lukket, CV, følgebrev";
diff --git a/plugins/attachment_reminder/localization/nl_BE.inc b/plugins/attachment_reminder/localization/nl_BE.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/nl_BE.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/nl_NL.inc b/plugins/attachment_reminder/localization/nl_NL.inc
index d80bfe9a9..293ad174f 100644
--- a/plugins/attachment_reminder/localization/nl_NL.inc
+++ b/plugins/attachment_reminder/localization/nl_NL.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
-$messages['forgotattachment'] = "Ben je vergeten het bestand bij te voegen?";
-$messages['reminderoption'] = "Remind about forgotten attachments";
-$messages['keywords'] = "attachment,bestand,bijgaand,bijgaande,brief,bijgevoegd,bijgesloten,CV";
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Bent u vergeten het bestand bij te voegen?";
+$messages['reminderoption'] = "Herinner mij aan vergeten bijlagen";
+$messages['keywords'] = "attachment,bestand,bijgaand,bijgaande,brief,bijgevoegd,bijgesloten,CV,document,bijgesloten";
diff --git a/plugins/attachment_reminder/localization/nn_NO.inc b/plugins/attachment_reminder/localization/nn_NO.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/nn_NO.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/nqo.inc b/plugins/attachment_reminder/localization/nqo.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/nqo.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/om.inc b/plugins/attachment_reminder/localization/om.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/om.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/pl_PL.inc b/plugins/attachment_reminder/localization/pl_PL.inc
index 96f4f4989..06cede5d9 100644
--- a/plugins/attachment_reminder/localization/pl_PL.inc
+++ b/plugins/attachment_reminder/localization/pl_PL.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
$messages['forgotattachment'] = "Czy nie zapomniałeś załączyć pliku?";
$messages['reminderoption'] = "Włącz przypominanie o brakującym załączniku";
$messages['keywords'] = "załącznik,plik,załącz,CV";
diff --git a/plugins/attachment_reminder/localization/pt_BR.inc b/plugins/attachment_reminder/localization/pt_BR.inc
new file mode 100644
index 000000000..4b61e951c
--- /dev/null
+++ b/plugins/attachment_reminder/localization/pt_BR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Você esqueceu-se de anexar um arquivo?";
+$messages['reminderoption'] = "Alertar sobre o possível esquecimento de anexos";
+$messages['keywords'] = "anexo,arquivo,anexar,anexado,anexando,incluso,CV,currículo";
diff --git a/plugins/attachment_reminder/localization/pt_PT.inc b/plugins/attachment_reminder/localization/pt_PT.inc
new file mode 100644
index 000000000..de2d04efd
--- /dev/null
+++ b/plugins/attachment_reminder/localization/pt_PT.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Você esqueceu-se de anexar um ficheiro?";
+$messages['reminderoption'] = "Lembrar sobre anexos esquecidos";
+$messages['keywords'] = "anexo,ficheiro,anexar,anexado,a anexar,em anexo,currículo,carta de apresentação";
diff --git a/plugins/attachment_reminder/localization/ro_RO.inc b/plugins/attachment_reminder/localization/ro_RO.inc
new file mode 100644
index 000000000..ff1153908
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ro_RO.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Ați uitat să atașati ?";
+$messages['reminderoption'] = "Adu-mi aminte de atașamente";
+$messages['keywords'] = "atașament,atasament,atas,atasat,ataș,attach,fisier,fișier,attach,atach,attache";
diff --git a/plugins/attachment_reminder/localization/ru_RU.inc b/plugins/attachment_reminder/localization/ru_RU.inc
new file mode 100644
index 000000000..d592b1e30
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ru_RU.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Вы не забыли прикрепить файл?";
+$messages['reminderoption'] = "Ðапоминать о забытых вложениÑÑ…";
+$messages['keywords'] = "вложение,файл, вложенный, прикрепленный,резюме,документ";
diff --git a/plugins/attachment_reminder/localization/sk_SK.inc b/plugins/attachment_reminder/localization/sk_SK.inc
new file mode 100644
index 000000000..344d1e6a7
--- /dev/null
+++ b/plugins/attachment_reminder/localization/sk_SK.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Nezabudli ste pridať prílohu?";
+$messages['reminderoption'] = "Pripomenúť zabudnuté prílohy";
+$messages['keywords'] = "príloha,súbor,pripojiť,priložená,priložený,priložené,v prílohe,životopis,sprievodný list";
diff --git a/plugins/attachment_reminder/localization/sl_SI.inc b/plugins/attachment_reminder/localization/sl_SI.inc
new file mode 100644
index 000000000..9531f8ed0
--- /dev/null
+++ b/plugins/attachment_reminder/localization/sl_SI.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Ste pozabili pripeti datoteko?";
+$messages['reminderoption'] = "Opozorilo za dodajanje priponk";
+$messages['keywords'] = "priponka,datoteka,pripeti,pripeta,pripenjati,priložen,priložiti,CV,spremno pismo";
diff --git a/plugins/attachment_reminder/localization/sr_CS.inc b/plugins/attachment_reminder/localization/sr_CS.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/sr_CS.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/sv_SE.inc b/plugins/attachment_reminder/localization/sv_SE.inc
new file mode 100644
index 000000000..744a9618e
--- /dev/null
+++ b/plugins/attachment_reminder/localization/sv_SE.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Glömde du att bifoga en fil?";
+$messages['reminderoption'] = "Påminn om glömda bilagor";
+$messages['keywords'] = "bilaga,fil,bifoga,bifogad,bifogar,infogad,CV,personligt brev";
diff --git a/plugins/attachment_reminder/localization/te_IN.inc b/plugins/attachment_reminder/localization/te_IN.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/te_IN.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/th_TH.inc b/plugins/attachment_reminder/localization/th_TH.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/th_TH.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/ti.inc b/plugins/attachment_reminder/localization/ti.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ti.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/tr_TR.inc b/plugins/attachment_reminder/localization/tr_TR.inc
new file mode 100644
index 000000000..f03587d97
--- /dev/null
+++ b/plugins/attachment_reminder/localization/tr_TR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Bir dosya eklemeyi unuttunuz mu?";
+$messages['reminderoption'] = "Unutulan dosya eklemelerini hatırlat";
+$messages['keywords'] = "ekleme,dosya,ek,eklenildi,ekleniliyor,konuldu,CV,kapak mektubu";
diff --git a/plugins/attachment_reminder/localization/tzm.inc b/plugins/attachment_reminder/localization/tzm.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/tzm.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/uk_UA.inc b/plugins/attachment_reminder/localization/uk_UA.inc
new file mode 100644
index 000000000..122fb2bee
--- /dev/null
+++ b/plugins/attachment_reminder/localization/uk_UA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "Ви забули прикріпити файл?";
+$messages['reminderoption'] = "Ðагадати про забуте вкладеннÑ";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/ur_PK.inc b/plugins/attachment_reminder/localization/ur_PK.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/ur_PK.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/vi_VN.inc b/plugins/attachment_reminder/localization/vi_VN.inc
new file mode 100644
index 000000000..c3b4aaa02
--- /dev/null
+++ b/plugins/attachment_reminder/localization/vi_VN.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "";
+$messages['reminderoption'] = "";
+$messages['keywords'] = "";
diff --git a/plugins/attachment_reminder/localization/zh_CN.inc b/plugins/attachment_reminder/localization/zh_CN.inc
index 367191ffb..6c44fe948 100644
--- a/plugins/attachment_reminder/localization/zh_CN.inc
+++ b/plugins/attachment_reminder/localization/zh_CN.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
-$messages['forgotattachment'] = "您似乎忘記加入附件了,你確定è¦å¯„出?";
-$messages['reminderoption'] = "Remind about forgotten attachments";
-$messages['keywords'] = "附件,附加,附檔,附上,附加檔案";
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
+$messages['forgotattachment'] = "您似乎忘记添加附件了,是å¦ç»§ç»­å‘é€ï¼Ÿ";
+$messages['reminderoption'] = "忘记添加附件æ醒";
+$messages['keywords'] = "attachment,file,attach,attached,attaching,enclosed,CV,cover letter";
diff --git a/plugins/attachment_reminder/localization/zh_TW.inc b/plugins/attachment_reminder/localization/zh_TW.inc
index 367191ffb..aaa91cd24 100644
--- a/plugins/attachment_reminder/localization/zh_TW.inc
+++ b/plugins/attachment_reminder/localization/zh_TW.inc
@@ -1,6 +1,20 @@
<?php
-$messages = array();
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/attachment_reminder/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Archive plugin |
+ | Copyright (C) 2013, 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/plugin-attachment_reminder/
+*/
$messages['forgotattachment'] = "您似乎忘記加入附件了,你確定è¦å¯„出?";
-$messages['reminderoption'] = "Remind about forgotten attachments";
+$messages['reminderoption'] = "æ醒加入附件";
$messages['keywords'] = "附件,附加,附檔,附上,附加檔案";
diff --git a/plugins/autologon/autologon.php b/plugins/autologon/autologon.php
index 9c7d5b6fc..63ffb943e 100644
--- a/plugins/autologon/autologon.php
+++ b/plugins/autologon/autologon.php
@@ -19,6 +19,8 @@ class autologon extends rcube_plugin
function startup($args)
{
+ $rcmail = rcmail::get_instance();
+
// change action to login
if (empty($_SESSION['user_id']) && !empty($_GET['_autologin']) && $this->is_localhost())
$args['action'] = 'login';
@@ -35,7 +37,7 @@ class autologon extends rcube_plugin
$args['cookiecheck'] = false;
$args['valid'] = true;
}
-
+
return $args;
}
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/database_attachments/database_attachments.php b/plugins/database_attachments/database_attachments.php
index 5ec351404..079f4e567 100644
--- a/plugins/database_attachments/database_attachments.php
+++ b/plugins/database_attachments/database_attachments.php
@@ -1,6 +1,6 @@
<?php
/**
- * Database Attachments
+ * Filesystem Attachments
*
* This plugin which provides database backed storage for temporary
* attachment file handling. The primary advantage of this plugin
@@ -13,16 +13,21 @@
* @author Aleksander Machniak <alec@alec.pl>
* @version @package_version@
*/
-
-require_once INSTALL_PATH . 'plugins/filesystem_attachments/filesystem_attachments.php';
-
+require_once('plugins/filesystem_attachments/filesystem_attachments.php');
class database_attachments extends filesystem_attachments
{
- // Cache object
- protected $cache;
// A prefix for the cache key used in the session and in the key field of the cache table
- protected $prefix = "db_attach";
+ private $cache_prefix = "db_attach";
+
+ /**
+ * Helper method to generate a unique key for the given attachment file
+ */
+ private function _key($args)
+ {
+ $uname = $args['path'] ? $args['path'] : $args['name'];
+ return $this->cache_prefix . $args['group'] . md5(mktime() . $uname . $_SESSION['user_id']);
+ }
/**
* Save a newly uploaded attachment
@@ -30,17 +35,23 @@ class database_attachments extends filesystem_attachments
function upload($args)
{
$args['status'] = false;
+ $rcmail = rcmail::get_instance();
+ $key = $this->_key($args);
- $cache = $this->get_cache();
- $key = $this->_key($args);
- $data = file_get_contents($args['path']);
+ $data = file_get_contents($args['path']);
- if ($data === false) {
+ if ($data === false)
return $args;
- }
- $data = base64_encode($data);
- $status = $cache->write($key, $data);
+ $data = base64_encode($data);
+
+ $status = $rcmail->db->query(
+ "INSERT INTO ".get_table_name('cache')
+ ." (created, user_id, cache_key, data)"
+ ." VALUES (".$rcmail->db->now().", ?, ?, ?)",
+ $_SESSION['user_id'],
+ $key,
+ $data);
if ($status) {
$args['id'] = $key;
@@ -57,20 +68,26 @@ class database_attachments extends filesystem_attachments
function save($args)
{
$args['status'] = false;
+ $rcmail = rcmail::get_instance();
- $cache = $this->get_cache();
- $key = $this->_key($args);
+ $key = $this->_key($args);
if ($args['path']) {
$args['data'] = file_get_contents($args['path']);
- if ($args['data'] === false) {
+ if ($args['data'] === false)
return $args;
- }
}
- $data = base64_encode($args['data']);
- $status = $cache->write($key, $data);
+ $data = base64_encode($args['data']);
+
+ $status = $rcmail->db->query(
+ "INSERT INTO ".get_table_name('cache')
+ ." (created, user_id, cache_key, data)"
+ ." VALUES (".$rcmail->db->now().", ?, ?, ?)",
+ $_SESSION['user_id'],
+ $key,
+ $data);
if ($status) {
$args['id'] = $key;
@@ -86,10 +103,18 @@ class database_attachments extends filesystem_attachments
*/
function remove($args)
{
- $cache = $this->get_cache();
- $status = $cache->remove($args['id']);
+ $args['status'] = false;
+ $rcmail = rcmail::get_instance();
+ $status = $rcmail->db->query(
+ "DELETE FROM ".get_table_name('cache')
+ ." WHERE user_id = ?"
+ ." AND cache_key = ?",
+ $_SESSION['user_id'],
+ $args['id']);
- $args['status'] = true;
+ if ($status) {
+ $args['status'] = true;
+ }
return $args;
}
@@ -110,11 +135,18 @@ class database_attachments extends filesystem_attachments
*/
function get($args)
{
- $cache = $this->get_cache();
- $data = $cache->read($args['id']);
-
- if ($data) {
- $args['data'] = base64_decode($data);
+ $rcmail = rcmail::get_instance();
+
+ $sql_result = $rcmail->db->query(
+ "SELECT data"
+ ." FROM ".get_table_name('cache')
+ ." WHERE user_id=?"
+ ." AND cache_key=?",
+ $_SESSION['user_id'],
+ $args['id']);
+
+ if ($sql_arr = $rcmail->db->fetch_assoc($sql_result)) {
+ $args['data'] = base64_decode($sql_arr['data']);
$args['status'] = true;
}
@@ -126,36 +158,12 @@ class database_attachments extends filesystem_attachments
*/
function cleanup($args)
{
- $cache = $this->get_cache();
- $cache->remove($args['group'], true);
- }
-
- /**
- * Helper method to generate a unique key for the given attachment file
- */
- protected function _key($args)
- {
- $uname = $args['path'] ? $args['path'] : $args['name'];
- return $args['group'] . md5(mktime() . $uname . $_SESSION['user_id']);
- }
-
- /**
- * Initialize and return cache object
- */
- protected function get_cache()
- {
- if (!$this->cache) {
- $this->load_config();
-
- $rcmail = rcube::get_instance();
- $ttl = 12 * 60 * 60; // default: 12 hours
- $ttl = $rcmail->config->get('database_attachments_cache_ttl', $ttl);
- $type = $rcmail->config->get('database_attachments_cache', 'db');
-
- // Init SQL cache (disable cache data serialization)
- $this->cache = $rcmail->get_cache($this->prefix, 'db', $ttl, false);
- }
-
- return $this->cache;
+ $prefix = $this->cache_prefix . $args['group'];
+ $rcmail = rcmail::get_instance();
+ $rcmail->db->query(
+ "DELETE FROM ".get_table_name('cache')
+ ." WHERE user_id = ?"
+ ." AND cache_key LIKE '{$prefix}%'",
+ $_SESSION['user_id']);
}
}
diff --git a/plugins/database_attachments/package.xml b/plugins/database_attachments/package.xml
index 44adc219e..40db858a4 100644
--- a/plugins/database_attachments/package.xml
+++ b/plugins/database_attachments/package.xml
@@ -5,7 +5,7 @@
http://pear.php.net/dtd/package-2.0.xsd">
<name>database_attachments</name>
<channel>pear.roundcube.net</channel>
- <summary>Database storage for uploaded attachments</summary>
+ <summary>SQL database storage for uploaded attachments</summary>
<description>
This plugin which provides database backed storage for temporary
attachment file handling. The primary advantage of this plugin
@@ -24,9 +24,9 @@
<email>ziba@umich.edu</email>
<active>yes</active>
</developer>
- <date>2013-06-13</date>
+ <date>2011-11-21</date>
<version>
- <release>1.1</release>
+ <release>1.0</release>
<api>1.0</api>
</version>
<stability>
diff --git a/plugins/debug_logger/debug_logger.php b/plugins/debug_logger/debug_logger.php
index 88237d767..87a163785 100644
--- a/plugins/debug_logger/debug_logger.php
+++ b/plugins/debug_logger/debug_logger.php
@@ -12,7 +12,7 @@
* which can redirect messages to files. The resulting log files
* provide timing and tag quantity results.
*
- * Enable the plugin in config.inc.php and add your desired
+ * Enable the plugin in config/main.inc.php and add your desired
* log types and files.
*
* @version @package_version@
@@ -21,13 +21,13 @@
*
* Example:
*
- * config.inc.php:
+ * config/main.inc.php:
*
- * // $config['debug_logger'][type of logging] = name of file in log_dir
+ * // $rcmail_config['debug_logger'][type of logging] = name of file in log_dir
* // The 'master' log includes timing information
- * $config['debug_logger']['master'] = 'master';
+ * $rcmail_config['debug_logger']['master'] = 'master';
* // If you want sql messages to also go into a separate file
- * $config['debug_logger']['sql'] = 'sql';
+ * $rcmail_config['debug_logger']['sql'] = 'sql';
*
* index.php (just after $RCMAIL->plugins->init()):
*
diff --git a/plugins/debug_logger/runlog/runlog.php b/plugins/debug_logger/runlog/runlog.php
index 0c766a13c..c9f672615 100644
--- a/plugins/debug_logger/runlog/runlog.php
+++ b/plugins/debug_logger/runlog/runlog.php
@@ -194,7 +194,7 @@ class runlog {
public function print_totals(){
$totals = array();
- foreach ($this->run_log as $entry) {
+ foreach ( $this->run_log as $k => $entry ) {
if ( $entry['type'] == 'start' && $entry['ended'] == true) {
$totals[$entry['value']]['duration'] += $entry['duration'];
$totals[$entry['value']]['count'] += 1;
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/README b/plugins/enigma/README
deleted file mode 100644
index 22d6e513a..000000000
--- a/plugins/enigma/README
+++ /dev/null
@@ -1,35 +0,0 @@
-------------------------------------------------------------------
-THIS IS NOT EVEN AN "ALPHA" STATE. USE ONLY FOR DEVELOPMENT!!!!!!!
-------------------------------------------------------------------
-
-WARNING: Don't use with gnupg-2.x!
-
-Enigma Plugin Status:
-
-* DONE:
-
-- PGP signed messages verification
-- Handling of PGP keys files attached to incoming messages
-- PGP encrypted messages decryption (started)
-- PGP keys management UI (started)
-
-* TODO (must have):
-
-- Parsing of decrypted messages into array (see rcube_mime_struct) and then into rcube_message_part structure
- (create core class rcube_mime_parser or take over PEAR::Mail_mimeDecode package and improve it)
-- Sending encrypted/signed messages (probably some changes in core will be needed)
-- Per-Identity settings (including keys/certs)
-- Handling big messages with temp files (including changes in Roundcube core)
-- Performance improvements (some caching, code review)
-- better (and more) icons
-
-* TODO (later):
-
-- Keys generation
-- Certs generation
-- Keys/Certs info in Contacts details page (+ split Contact details page into tabs)
-- Key server support
-- S/MIME signed messages verification
-- S/MIME encrypted messages decryption
-- Handling of S/MIME certs files attached to incoming messages
-- SSL (S/MIME) Certs management
diff --git a/plugins/enigma/config.inc.php.dist b/plugins/enigma/config.inc.php.dist
deleted file mode 100644
index 2adb4d9f6..000000000
--- a/plugins/enigma/config.inc.php.dist
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-// Enigma Plugin options
-// --------------------
-
-// A driver to use for PGP. Default: "gnupg".
-$config['enigma_pgp_driver'] = 'gnupg';
-
-// A driver to use for S/MIME. Default: "phpssl".
-$config['enigma_smime_driver'] = 'phpssl';
-
-// Keys directory for all users. Default 'enigma/home'.
-// Must be writeable by PHP process
-$config['enigma_pgp_homedir'] = null;
diff --git a/plugins/enigma/enigma.js b/plugins/enigma/enigma.js
deleted file mode 100644
index 29c648224..000000000
--- a/plugins/enigma/enigma.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Enigma Plugin */
-
-if (window.rcmail)
-{
- rcmail.addEventListener('init', function(evt)
- {
- if (rcmail.env.task == 'settings') {
- rcmail.register_command('plugin.enigma', function() { rcmail.goto_url('plugin.enigma') }, true);
- rcmail.register_command('plugin.enigma-key-import', function() { rcmail.enigma_key_import() }, true);
- rcmail.register_command('plugin.enigma-key-export', function() { rcmail.enigma_key_export() }, true);
-
- if (rcmail.gui_objects.keyslist)
- {
- var p = rcmail;
- rcmail.keys_list = new rcube_list_widget(rcmail.gui_objects.keyslist,
- {multiselect:false, draggable:false, keyboard:false});
- rcmail.keys_list.addEventListener('select', function(o){ p.enigma_key_select(o); });
- rcmail.keys_list.init();
- rcmail.keys_list.focus();
-
- rcmail.enigma_list();
-
- rcmail.register_command('firstpage', function(props) {return rcmail.enigma_list_page('first'); });
- rcmail.register_command('previouspage', function(props) {return rcmail.enigma_list_page('previous'); });
- rcmail.register_command('nextpage', function(props) {return rcmail.enigma_list_page('next'); });
- rcmail.register_command('lastpage', function(props) {return rcmail.enigma_list_page('last'); });
- }
-
- if (rcmail.env.action == 'edit-prefs') {
- rcmail.register_command('search', function(props) {return rcmail.enigma_search(props); }, true);
- rcmail.register_command('reset-search', function(props) {return rcmail.enigma_search_reset(props); }, true);
- }
- else if (rcmail.env.action == 'plugin.enigma') {
- rcmail.register_command('plugin.enigma-import', function() { rcmail.enigma_import() }, true);
- rcmail.register_command('plugin.enigma-export', function() { rcmail.enigma_export() }, true);
- }
- }
- });
-}
-
-/*********************************************************/
-/********* Enigma Settings/Keys/Certs UI *********/
-/*********************************************************/
-
-// Display key(s) import form
-rcube_webmail.prototype.enigma_key_import = function()
-{
- this.enigma_loadframe(null, '&_a=keyimport');
-};
-
-// Submit key(s) form
-rcube_webmail.prototype.enigma_import = function()
-{
- var form, file;
- if (form = this.gui_objects.importform) {
- file = document.getElementById('rcmimportfile');
- if (file && !file.value) {
- alert(this.get_label('selectimportfile'));
- return;
- }
- form.submit();
- this.set_busy(true, 'importwait');
- this.lock_form(form, true);
- }
-};
-
-// list row selection handler
-rcube_webmail.prototype.enigma_key_select = function(list)
-{
- var id;
- if (id = list.get_single_selection())
- this.enigma_loadframe(id);
-};
-
-// load key frame
-rcube_webmail.prototype.enigma_loadframe = function(id, url)
-{
- var frm, win;
- if (this.env.contentframe && window.frames && (frm = window.frames[this.env.contentframe])) {
- if (!id && !url && (win = window.frames[this.env.contentframe])) {
- if (win.location && win.location.href.indexOf(this.env.blankpage)<0)
- win.location.href = this.env.blankpage;
- return;
- }
- this.set_busy(true);
- if (!url)
- url = '&_a=keyinfo&_id='+id;
- frm.location.href = this.env.comm_path+'&_action=plugin.enigma&_framed=1' + url;
- }
-};
-
-// Search keys/certs
-rcube_webmail.prototype.enigma_search = function(props)
-{
- if (!props && this.gui_objects.qsearchbox)
- props = this.gui_objects.qsearchbox.value;
-
- if (props || this.env.search_request) {
- var params = {'_a': 'keysearch', '_q': urlencode(props)},
- lock = this.set_busy(true, 'searching');
-// if (this.gui_objects.search_filter)
- // addurl += '&_filter=' + this.gui_objects.search_filter.value;
- this.env.current_page = 1;
- this.enigma_loadframe();
- this.enigma_clear_list();
- this.http_post('plugin.enigma', params, lock);
- }
-
- return false;
-}
-
-// Reset search filter and the list
-rcube_webmail.prototype.enigma_search_reset = function(props)
-{
- var s = this.env.search_request;
- this.reset_qsearch();
-
- if (s) {
- this.enigma_loadframe();
- this.enigma_clear_list();
-
- // refresh the list
- this.enigma_list();
- }
-
- return false;
-}
-
-// Keys/certs listing
-rcube_webmail.prototype.enigma_list = function(page)
-{
- var params = {'_a': 'keylist'},
- lock = this.set_busy(true, 'loading');
-
- this.env.current_page = page ? page : 1;
-
- if (this.env.search_request)
- params._q = this.env.search_request;
- if (page)
- params._p = page;
-
- this.enigma_clear_list();
- this.http_post('plugin.enigma', params, lock);
-}
-
-// Change list page
-rcube_webmail.prototype.enigma_list_page = function(page)
-{
- if (page == 'next')
- page = this.env.current_page + 1;
- else if (page == 'last')
- page = this.env.pagecount;
- else if (page == 'prev' && this.env.current_page > 1)
- page = this.env.current_page - 1;
- else if (page == 'first' && this.env.current_page > 1)
- page = 1;
-
- this.enigma_list(page);
-}
-
-// Remove list rows
-rcube_webmail.prototype.enigma_clear_list = function()
-{
- this.enigma_loadframe();
- if (this.keys_list)
- this.keys_list.clear(true);
-}
-
-// Adds a row to the list
-rcube_webmail.prototype.enigma_add_list_row = function(r)
-{
- if (!this.gui_objects.keyslist || !this.keys_list)
- return false;
-
- var list = this.keys_list,
- tbody = this.gui_objects.keyslist.tBodies[0],
- rowcount = tbody.rows.length,
- even = rowcount%2,
- css_class = 'message'
- + (even ? ' even' : ' odd'),
- // for performance use DOM instead of jQuery here
- row = document.createElement('tr'),
- col = document.createElement('td');
-
- row.id = 'rcmrow' + r.id;
- row.className = css_class;
-
- col.innerHTML = r.name;
- row.appendChild(col);
- list.insert_row(row);
-}
-
-/*********************************************************/
-/********* Enigma Message methods *********/
-/*********************************************************/
-
-// Import attached keys/certs file
-rcube_webmail.prototype.enigma_import_attachment = function(mime_id)
-{
- var lock = this.set_busy(true, 'loading');
- this.http_post('plugin.enigmaimport', '_uid='+this.env.uid+'&_mbox='
- +urlencode(this.env.mailbox)+'&_part='+urlencode(mime_id), lock);
-
- return false;
-};
-
diff --git a/plugins/enigma/enigma.php b/plugins/enigma/enigma.php
deleted file mode 100644
index 25520a27d..000000000
--- a/plugins/enigma/enigma.php
+++ /dev/null
@@ -1,476 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Enigma Plugin for Roundcube |
- | Version 0.1 |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-/*
- This class contains only hooks and action handlers.
- Most plugin logic is placed in enigma_engine and enigma_ui classes.
-*/
-
-class enigma extends rcube_plugin
-{
- public $task = 'mail|settings';
- public $rc;
- public $engine;
-
- private $env_loaded;
- private $message;
- private $keys_parts = array();
- private $keys_bodies = array();
-
-
- /**
- * Plugin initialization.
- */
- function init()
- {
- $rcmail = rcmail::get_instance();
- $this->rc = $rcmail;
-
- $section = rcube_utils::get_input_value('_section', rcube_utils::INPUT_GET);
-
- if ($this->rc->task == 'mail') {
- // message parse/display hooks
- $this->add_hook('message_part_structure', array($this, 'parse_structure'));
- $this->add_hook('message_body_prefix', array($this, 'status_message'));
-
- // message displaying
- if ($rcmail->action == 'show' || $rcmail->action == 'preview') {
- $this->add_hook('message_load', array($this, 'message_load'));
- $this->add_hook('template_object_messagebody', array($this, 'message_output'));
- $this->register_action('plugin.enigmaimport', array($this, 'import_file'));
- }
- // message composing
- else if ($rcmail->action == 'compose') {
- $this->load_ui();
- $this->ui->init($section);
- }
- // message sending (and draft storing)
- else if ($rcmail->action == 'sendmail') {
- //$this->add_hook('outgoing_message_body', array($this, 'msg_encode'));
- //$this->add_hook('outgoing_message_body', array($this, 'msg_sign'));
- }
- }
- else if ($this->rc->task == 'settings') {
- // add hooks for Enigma settings
- $this->add_hook('preferences_sections_list', array($this, 'preferences_section'));
- $this->add_hook('preferences_list', array($this, 'preferences_list'));
- $this->add_hook('preferences_save', array($this, 'preferences_save'));
-
- // register handler for keys/certs management
- $this->register_action('plugin.enigma', array($this, 'preferences_ui'));
-
- // grab keys/certs management iframe requests
- if ($this->rc->action == 'edit-prefs' && preg_match('/^enigma(certs|keys)/', $section)) {
- $this->load_ui();
- $this->ui->init($section);
- }
- }
- }
-
- /**
- * Plugin environment initialization.
- */
- function load_env()
- {
- if ($this->env_loaded)
- return;
-
- $this->env_loaded = true;
-
- // Add include path for Enigma classes and drivers
- $include_path = $this->home . '/lib' . PATH_SEPARATOR;
- $include_path .= ini_get('include_path');
- set_include_path($include_path);
-
- // load the Enigma plugin configuration
- $this->load_config();
-
- // include localization (if wasn't included before)
- $this->add_texts('localization/');
- }
-
- /**
- * Plugin UI initialization.
- */
- function load_ui()
- {
- if ($this->ui)
- return;
-
- // load config/localization
- $this->load_env();
-
- // Load UI
- $this->ui = new enigma_ui($this, $this->home);
- }
-
- /**
- * Plugin engine initialization.
- */
- function load_engine()
- {
- if ($this->engine)
- return;
-
- // load config/localization
- $this->load_env();
-
- $this->engine = new enigma_engine($this);
- }
-
- /**
- * Handler for message_part_structure hook.
- * Called for every part of the message.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function parse_structure($p)
- {
-// $struct = $p['structure'];
-
- if ($p['mimetype'] == 'text/plain' || $p['mimetype'] == 'application/pgp') {
- $this->parse_plain($p);
- }
- else if ($p['mimetype'] == 'multipart/signed') {
- $this->parse_signed($p);
- }
- else if ($p['mimetype'] == 'multipart/encrypted') {
- $this->parse_encrypted($p);
- }
- else if ($p['mimetype'] == 'application/pkcs7-mime') {
- $this->parse_encrypted($p);
- }
-
- return $p;
- }
-
- /**
- * Handler for preferences_sections_list hook.
- * Adds Enigma settings sections into preferences sections list.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function preferences_section($p)
- {
- // add labels
- $this->add_texts('localization/');
-
- $p['list']['enigmasettings'] = array(
- 'id' => 'enigmasettings', 'section' => $this->gettext('enigmasettings'),
- );
- $p['list']['enigmacerts'] = array(
- 'id' => 'enigmacerts', 'section' => $this->gettext('enigmacerts'),
- );
- $p['list']['enigmakeys'] = array(
- 'id' => 'enigmakeys', 'section' => $this->gettext('enigmakeys'),
- );
-
- return $p;
- }
-
- /**
- * Handler for preferences_list hook.
- * Adds options blocks into Enigma settings sections in Preferences.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function preferences_list($p)
- {
- if ($p['section'] == 'enigmasettings') {
- // This makes that section is not removed from the list
- $p['blocks']['dummy']['options']['dummy'] = array();
- }
- else if ($p['section'] == 'enigmacerts') {
- // This makes that section is not removed from the list
- $p['blocks']['dummy']['options']['dummy'] = array();
- }
- else if ($p['section'] == 'enigmakeys') {
- // This makes that section is not removed from the list
- $p['blocks']['dummy']['options']['dummy'] = array();
- }
-
- return $p;
- }
-
- /**
- * Handler for preferences_save hook.
- * Executed on Enigma settings form submit.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function preferences_save($p)
- {
- if ($p['section'] == 'enigmasettings') {
- $a['prefs'] = array(
-// 'dummy' => rcube_utils::get_input_value('_dummy', rcube_utils::INPUT_POST),
- );
- }
-
- return $p;
- }
-
- /**
- * Handler for keys/certs management UI template.
- */
- function preferences_ui()
- {
- $this->load_ui();
- $this->ui->init();
- }
-
- /**
- * Handler for message_body_prefix hook.
- * Called for every displayed (content) part of the message.
- * Adds infobox about signature verification and/or decryption
- * status above the body.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function status_message($p)
- {
- $part_id = $p['part']->mime_id;
-
- // skip: not a message part
- if ($p['part'] instanceof rcube_message)
- return $p;
-
- // skip: message has no signed/encoded content
- if (!$this->engine)
- return $p;
-
- // Decryption status
- if (isset($this->engine->decryptions[$part_id])) {
-
- // get decryption status
- $status = $this->engine->decryptions[$part_id];
-
- // Load UI and add css script
- $this->load_ui();
- $this->ui->add_css();
-
- // display status info
- $attrib['id'] = 'enigma-message';
-
- if ($status instanceof enigma_error) {
- $attrib['class'] = 'enigmaerror';
- $code = $status->getCode();
- if ($code == enigma_error::E_KEYNOTFOUND)
- $msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($status->getData('id')),
- $this->gettext('decryptnokey')));
- else if ($code == enigma_error::E_BADPASS)
- $msg = rcube::Q($this->gettext('decryptbadpass'));
- else
- $msg = rcube::Q($this->gettext('decrypterror'));
- }
- else {
- $attrib['class'] = 'enigmanotice';
- $msg = rcube::Q($this->gettext('decryptok'));
- }
-
- $p['prefix'] .= html::div($attrib, $msg);
- }
-
- // Signature verification status
- if (isset($this->engine->signed_parts[$part_id])
- && ($sig = $this->engine->signatures[$this->engine->signed_parts[$part_id]])
- ) {
- // add css script
- $this->load_ui();
- $this->ui->add_css();
-
- // display status info
- $attrib['id'] = 'enigma-message';
-
- if ($sig instanceof enigma_signature) {
- if ($sig->valid) {
- $attrib['class'] = 'enigmanotice';
- $sender = ($sig->name ? $sig->name . ' ' : '') . '<' . $sig->email . '>';
- $msg = rcube::Q(str_replace('$sender', $sender, $this->gettext('sigvalid')));
- }
- else {
- $attrib['class'] = 'enigmawarning';
- $sender = ($sig->name ? $sig->name . ' ' : '') . '<' . $sig->email . '>';
- $msg = rcube::Q(str_replace('$sender', $sender, $this->gettext('siginvalid')));
- }
- }
- else if ($sig->getCode() == enigma_error::E_KEYNOTFOUND) {
- $attrib['class'] = 'enigmawarning';
- $msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($sig->getData('id')),
- $this->gettext('signokey')));
- }
- else {
- $attrib['class'] = 'enigmaerror';
- $msg = rcube::Q($this->gettext('sigerror'));
- }
-/*
- $msg .= '&nbsp;' . html::a(array('href' => "#sigdetails",
- 'onclick' => rcmail_output::JS_OBJECT_NAME.".command('enigma-sig-details')"),
- rcube::Q($this->gettext('showdetails')));
-*/
- // test
-// $msg .= '<br /><pre>'.$sig->body.'</pre>';
-
- $p['prefix'] .= html::div($attrib, $msg);
-
- // Display each signature message only once
- unset($this->engine->signatures[$this->engine->signed_parts[$part_id]]);
- }
-
- return $p;
- }
-
- /**
- * Handler for plain/text message.
- *
- * @param array Reference to hook's parameters (see enigma::parse_structure())
- */
- private function parse_plain(&$p)
- {
- $this->load_engine();
- $this->engine->parse_plain($p);
- }
-
- /**
- * Handler for multipart/signed message.
- * Verifies signature.
- *
- * @param array Reference to hook's parameters (see enigma::parse_structure())
- */
- private function parse_signed(&$p)
- {
- $this->load_engine();
- $this->engine->parse_signed($p);
- }
-
- /**
- * Handler for multipart/encrypted and application/pkcs7-mime message.
- *
- * @param array Reference to hook's parameters (see enigma::parse_structure())
- */
- private function parse_encrypted(&$p)
- {
- $this->load_engine();
- $this->engine->parse_encrypted($p);
- }
-
- /**
- * Handler for message_load hook.
- * Check message bodies and attachments for keys/certs.
- */
- function message_load($p)
- {
- $this->message = $p['object'];
-
- // handle attachments vcard attachments
- foreach ((array)$this->message->attachments as $attachment) {
- if ($this->is_keys_part($attachment)) {
- $this->keys_parts[] = $attachment->mime_id;
- }
- }
- // the same with message bodies
- foreach ((array)$this->message->parts as $part) {
- if ($this->is_keys_part($part)) {
- $this->keys_parts[] = $part->mime_id;
- $this->keys_bodies[] = $part->mime_id;
- }
- }
- // @TODO: inline PGP keys
-
- if ($this->keys_parts) {
- $this->add_texts('localization');
- }
- }
-
- /**
- * Handler for template_object_messagebody hook.
- * This callback function adds a box below the message content
- * if there is a key/cert attachment available
- */
- function message_output($p)
- {
- $attach_script = false;
-
- foreach ($this->keys_parts as $part) {
-
- // remove part's body
- if (in_array($part, $this->keys_bodies))
- $p['content'] = '';
-
- $style = "margin:0 1em; padding:0.2em 0.5em; border:1px solid #999; width: auto"
- ." border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px";
-
- // add box below message body
- $p['content'] .= html::p(array('style' => $style),
- html::a(array(
- 'href' => "#",
- 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".enigma_import_attachment('".rcube::JQ($part)."')",
- 'title' => $this->gettext('keyattimport')),
- html::img(array('src' => $this->url('skins/classic/key_add.png'), 'style' => "vertical-align:middle")))
- . ' ' . html::span(null, $this->gettext('keyattfound')));
-
- $attach_script = true;
- }
-
- if ($attach_script) {
- $this->include_script('enigma.js');
- }
-
- return $p;
- }
-
- /**
- * Handler for attached keys/certs import
- */
- function import_file()
- {
- $this->load_engine();
- $this->engine->import_file();
- }
-
- /**
- * Checks if specified message part is a PGP-key or S/MIME cert data
- *
- * @param rcube_message_part Part object
- *
- * @return boolean True if part is a key/cert
- */
- private function is_keys_part($part)
- {
- // @TODO: S/MIME
- return (
- // Content-Type: application/pgp-keys
- $part->mimetype == 'application/pgp-keys'
- );
- }
-}
diff --git a/plugins/enigma/home/.htaccess b/plugins/enigma/home/.htaccess
deleted file mode 100644
index 8e6a345dc..000000000
--- a/plugins/enigma/home/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-Order allow,deny
-Deny from all \ No newline at end of file
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/enigma/lib/enigma_driver.php b/plugins/enigma/lib/enigma_driver.php
deleted file mode 100644
index a9a3e4715..000000000
--- a/plugins/enigma/lib/enigma_driver.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Abstract driver for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-abstract class enigma_driver
-{
- /**
- * Class constructor.
- *
- * @param string User name (email address)
- */
- abstract function __construct($user);
-
- /**
- * Driver initialization.
- *
- * @return mixed NULL on success, enigma_error on failure
- */
- abstract function init();
-
- /**
- * Encryption.
- */
- abstract function encrypt($text, $keys);
-
- /**
- * Decryption..
- */
- abstract function decrypt($text, $key, $passwd);
-
- /**
- * Signing.
- */
- abstract function sign($text, $key, $passwd);
-
- /**
- * Signature verification.
- *
- * @param string Message body
- * @param string Signature, if message is of type PGP/MIME and body doesn't contain it
- *
- * @return mixed Signature information (enigma_signature) or enigma_error
- */
- abstract function verify($text, $signature);
-
- /**
- * Key/Cert file import.
- *
- * @param string File name or file content
- * @param bollean True if first argument is a filename
- *
- * @return mixed Import status array or enigma_error
- */
- abstract function import($content, $isfile=false);
-
- /**
- * Keys listing.
- *
- * @param string Optional pattern for key ID, user ID or fingerprint
- *
- * @return mixed Array of enigma_key objects or enigma_error
- */
- abstract function list_keys($pattern='');
-
- /**
- * Single key information.
- *
- * @param string Key ID, user ID or fingerprint
- *
- * @return mixed Key (enigma_key) object or enigma_error
- */
- abstract function get_key($keyid);
-
- /**
- * Key pair generation.
- *
- * @param array Key/User data
- *
- * @return mixed Key (enigma_key) object or enigma_error
- */
- abstract function gen_key($data);
-
- /**
- * Key deletion.
- */
- abstract function del_key($keyid);
-}
diff --git a/plugins/enigma/lib/enigma_driver_gnupg.php b/plugins/enigma/lib/enigma_driver_gnupg.php
deleted file mode 100644
index 5aa32217e..000000000
--- a/plugins/enigma/lib/enigma_driver_gnupg.php
+++ /dev/null
@@ -1,305 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | GnuPG (PGP) driver for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-require_once 'Crypt/GPG.php';
-
-class enigma_driver_gnupg extends enigma_driver
-{
- private $rc;
- private $gpg;
- private $homedir;
- private $user;
-
- function __construct($user)
- {
- $rcmail = rcmail::get_instance();
- $this->rc = $rcmail;
- $this->user = $user;
- }
-
- /**
- * Driver initialization and environment checking.
- * Should only return critical errors.
- *
- * @return mixed NULL on success, enigma_error on failure
- */
- function init()
- {
- $homedir = $this->rc->config->get('enigma_pgp_homedir', INSTALL_PATH . '/plugins/enigma/home');
-
- if (!$homedir)
- return new enigma_error(enigma_error::E_INTERNAL,
- "Option 'enigma_pgp_homedir' not specified");
-
- // check if homedir exists (create it if not) and is readable
- if (!file_exists($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Keys directory doesn't exists: $homedir");
- if (!is_writable($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Keys directory isn't writeable: $homedir");
-
- $homedir = $homedir . '/' . $this->user;
-
- // check if user's homedir exists (create it if not) and is readable
- if (!file_exists($homedir))
- mkdir($homedir, 0700);
-
- if (!file_exists($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Unable to create keys directory: $homedir");
- if (!is_writable($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Unable to write to keys directory: $homedir");
-
- $this->homedir = $homedir;
-
- // Create Crypt_GPG object
- try {
- $this->gpg = new Crypt_GPG(array(
- 'homedir' => $this->homedir,
-// 'debug' => true,
- ));
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- function encrypt($text, $keys)
- {
-/*
- foreach ($keys as $key) {
- $this->gpg->addEncryptKey($key);
- }
- $enc = $this->gpg->encrypt($text);
- return $enc;
-*/
- }
-
- function decrypt($text, $key, $passwd)
- {
-// $this->gpg->addDecryptKey($key, $passwd);
- try {
- $dec = $this->gpg->decrypt($text);
- return $dec;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- function sign($text, $key, $passwd)
- {
-/*
- $this->gpg->addSignKey($key, $passwd);
- $signed = $this->gpg->sign($text, Crypt_GPG::SIGN_MODE_DETACHED);
- return $signed;
-*/
- }
-
- function verify($text, $signature)
- {
- try {
- $verified = $this->gpg->verify($text, $signature);
- return $this->parse_signature($verified[0]);
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function import($content, $isfile=false)
- {
- try {
- if ($isfile)
- return $this->gpg->importKeyFile($content);
- else
- return $this->gpg->importKey($content);
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function list_keys($pattern='')
- {
- try {
- $keys = $this->gpg->getKeys($pattern);
- $result = array();
-//print_r($keys);
- foreach ($keys as $idx => $key) {
- $result[] = $this->parse_key($key);
- unset($keys[$idx]);
- }
-//print_r($result);
- return $result;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function get_key($keyid)
- {
- $list = $this->list_keys($keyid);
-
- if (is_array($list))
- return array_shift($list);
-
- // error
- return $list;
- }
-
- public function gen_key($data)
- {
- }
-
- public function del_key($keyid)
- {
-// $this->get_key($keyid);
-
-
- }
-
- public function del_privkey($keyid)
- {
- try {
- $this->gpg->deletePrivateKey($keyid);
- return true;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function del_pubkey($keyid)
- {
- try {
- $this->gpg->deletePublicKey($keyid);
- return true;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- /**
- * Converts Crypt_GPG exception into Enigma's error object
- *
- * @param mixed Exception object
- *
- * @return enigma_error Error object
- */
- private function get_error_from_exception($e)
- {
- $data = array();
-
- if ($e instanceof Crypt_GPG_KeyNotFoundException) {
- $error = enigma_error::E_KEYNOTFOUND;
- $data['id'] = $e->getKeyId();
- }
- else if ($e instanceof Crypt_GPG_BadPassphraseException) {
- $error = enigma_error::E_BADPASS;
- $data['bad'] = $e->getBadPassphrases();
- $data['missing'] = $e->getMissingPassphrases();
- }
- else if ($e instanceof Crypt_GPG_NoDataException)
- $error = enigma_error::E_NODATA;
- else if ($e instanceof Crypt_GPG_DeletePrivateKeyException)
- $error = enigma_error::E_DELKEY;
- else
- $error = enigma_error::E_INTERNAL;
-
- $msg = $e->getMessage();
-
- return new enigma_error($error, $msg, $data);
- }
-
- /**
- * Converts Crypt_GPG_Signature object into Enigma's signature object
- *
- * @param Crypt_GPG_Signature Signature object
- *
- * @return enigma_signature Signature object
- */
- private function parse_signature($sig)
- {
- $user = $sig->getUserId();
-
- $data = new enigma_signature();
- $data->id = $sig->getId();
- $data->valid = $sig->isValid();
- $data->fingerprint = $sig->getKeyFingerprint();
- $data->created = $sig->getCreationDate();
- $data->expires = $sig->getExpirationDate();
- $data->name = $user->getName();
- $data->comment = $user->getComment();
- $data->email = $user->getEmail();
-
- return $data;
- }
-
- /**
- * Converts Crypt_GPG_Key object into Enigma's key object
- *
- * @param Crypt_GPG_Key Key object
- *
- * @return enigma_key Key object
- */
- private function parse_key($key)
- {
- $ekey = new enigma_key();
-
- foreach ($key->getUserIds() as $idx => $user) {
- $id = new enigma_userid();
- $id->name = $user->getName();
- $id->comment = $user->getComment();
- $id->email = $user->getEmail();
- $id->valid = $user->isValid();
- $id->revoked = $user->isRevoked();
-
- $ekey->users[$idx] = $id;
- }
-
- $ekey->name = trim($ekey->users[0]->name . ' <' . $ekey->users[0]->email . '>');
-
- foreach ($key->getSubKeys() as $idx => $subkey) {
- $skey = new enigma_subkey();
- $skey->id = $subkey->getId();
- $skey->revoked = $subkey->isRevoked();
- $skey->created = $subkey->getCreationDate();
- $skey->expires = $subkey->getExpirationDate();
- $skey->fingerprint = $subkey->getFingerprint();
- $skey->has_private = $subkey->hasPrivate();
- $skey->can_sign = $subkey->canSign();
- $skey->can_encrypt = $subkey->canEncrypt();
-
- $ekey->subkeys[$idx] = $skey;
- };
-
- $ekey->id = $ekey->subkeys[0]->id;
-
- return $ekey;
- }
-}
diff --git a/plugins/enigma/lib/enigma_engine.php b/plugins/enigma/lib/enigma_engine.php
deleted file mode 100644
index 8a64c07ff..000000000
--- a/plugins/enigma/lib/enigma_engine.php
+++ /dev/null
@@ -1,533 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Engine of the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-
-*/
-
-/*
- RFC2440: OpenPGP Message Format
- RFC3156: MIME Security with OpenPGP
- RFC3851: S/MIME
-*/
-
-class enigma_engine
-{
- private $rc;
- private $enigma;
- private $pgp_driver;
- private $smime_driver;
-
- public $decryptions = array();
- public $signatures = array();
- public $signed_parts = array();
-
-
- /**
- * Plugin initialization.
- */
- function __construct($enigma)
- {
- $rcmail = rcmail::get_instance();
- $this->rc = $rcmail;
- $this->enigma = $enigma;
- }
-
- /**
- * PGP driver initialization.
- */
- function load_pgp_driver()
- {
- if ($this->pgp_driver)
- return;
-
- $driver = 'enigma_driver_' . $this->rc->config->get('enigma_pgp_driver', 'gnupg');
- $username = $this->rc->user->get_username();
-
- // Load driver
- $this->pgp_driver = new $driver($username);
-
- if (!$this->pgp_driver) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: Unable to load PGP driver: $driver"
- ), true, true);
- }
-
- // Initialise driver
- $result = $this->pgp_driver->init();
-
- if ($result instanceof enigma_error) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: ".$result->getMessage()
- ), true, true);
- }
- }
-
- /**
- * S/MIME driver initialization.
- */
- function load_smime_driver()
- {
- if ($this->smime_driver)
- return;
-
- // NOT IMPLEMENTED!
- return;
-
- $driver = 'enigma_driver_' . $this->rc->config->get('enigma_smime_driver', 'phpssl');
- $username = $this->rc->user->get_username();
-
- // Load driver
- $this->smime_driver = new $driver($username);
-
- if (!$this->smime_driver) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: Unable to load S/MIME driver: $driver"
- ), true, true);
- }
-
- // Initialise driver
- $result = $this->smime_driver->init();
-
- if ($result instanceof enigma_error) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: ".$result->getMessage()
- ), true, true);
- }
- }
-
- /**
- * Handler for plain/text message.
- *
- * @param array Reference to hook's parameters
- */
- function parse_plain(&$p)
- {
- $part = $p['structure'];
-
- // Get message body from IMAP server
- $this->set_part_body($part, $p['object']->uid);
-
- // @TODO: big message body can be a file resource
- // PGP signed message
- if (preg_match('/^-----BEGIN PGP SIGNED MESSAGE-----/', $part->body)) {
- $this->parse_plain_signed($p);
- }
- // PGP encrypted message
- else if (preg_match('/^-----BEGIN PGP MESSAGE-----/', $part->body)) {
- $this->parse_plain_encrypted($p);
- }
- }
-
- /**
- * Handler for multipart/signed message.
- *
- * @param array Reference to hook's parameters
- */
- function parse_signed(&$p)
- {
- $struct = $p['structure'];
-
- // S/MIME
- if ($struct->parts[1] && $struct->parts[1]->mimetype == 'application/pkcs7-signature') {
- $this->parse_smime_signed($p);
- }
- // PGP/MIME:
- // The multipart/signed body MUST consist of exactly two parts.
- // The first part contains the signed data in MIME canonical format,
- // including a set of appropriate content headers describing the data.
- // The second body MUST contain the PGP digital signature. It MUST be
- // labeled with a content type of "application/pgp-signature".
- else if ($struct->parts[1] && $struct->parts[1]->mimetype == 'application/pgp-signature') {
- $this->parse_pgp_signed($p);
- }
- }
-
- /**
- * Handler for multipart/encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- function parse_encrypted(&$p)
- {
- $struct = $p['structure'];
-
- // S/MIME
- if ($struct->mimetype == 'application/pkcs7-mime') {
- $this->parse_smime_encrypted($p);
- }
- // PGP/MIME:
- // The multipart/encrypted MUST consist of exactly two parts. The first
- // MIME body part must have a content type of "application/pgp-encrypted".
- // This body contains the control information.
- // The second MIME body part MUST contain the actual encrypted data. It
- // must be labeled with a content type of "application/octet-stream".
- else if ($struct->parts[0] && $struct->parts[0]->mimetype == 'application/pgp-encrypted' &&
- $struct->parts[1] && $struct->parts[1]->mimetype == 'application/octet-stream'
- ) {
- $this->parse_pgp_encrypted($p);
- }
- }
-
- /**
- * Handler for plain signed message.
- * Excludes message and signature bodies and verifies signature.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_plain_signed(&$p)
- {
- $this->load_pgp_driver();
- $part = $p['structure'];
-
- // Verify signature
- if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
- $sig = $this->pgp_verify($part->body);
- }
-
- // @TODO: Handle big bodies using (temp) files
-
- // In this way we can use fgets on string as on file handle
- $fh = fopen('php://memory', 'br+');
- // @TODO: fopen/fwrite errors handling
- if ($fh) {
- fwrite($fh, $part->body);
- rewind($fh);
- }
- $part->body = null;
-
- // Extract body (and signature?)
- while (!feof($fh)) {
- $line = fgets($fh, 1024);
-
- if ($part->body === null)
- $part->body = '';
- else if (preg_match('/^-----BEGIN PGP SIGNATURE-----/', $line))
- break;
- else
- $part->body .= $line;
- }
-
- // Remove "Hash" Armor Headers
- $part->body = preg_replace('/^.*\r*\n\r*\n/', '', $part->body);
- // de-Dash-Escape (RFC2440)
- $part->body = preg_replace('/(^|\n)- -/', '\\1-', $part->body);
-
- // Store signature data for display
- if (!empty($sig)) {
- $this->signed_parts[$part->mime_id] = $part->mime_id;
- $this->signatures[$part->mime_id] = $sig;
- }
-
- fclose($fh);
- }
-
- /**
- * Handler for PGP/MIME signed message.
- * Verifies signature.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_pgp_signed(&$p)
- {
- $this->load_pgp_driver();
- $struct = $p['structure'];
-
- // Verify signature
- if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
- $msg_part = $struct->parts[0];
- $sig_part = $struct->parts[1];
-
- // Get bodies
- $this->set_part_body($msg_part, $p['object']->uid);
- $this->set_part_body($sig_part, $p['object']->uid);
-
- // Verify
- $sig = $this->pgp_verify($msg_part->body, $sig_part->body);
-
- // Store signature data for display
- $this->signatures[$struct->mime_id] = $sig;
-
- // Message can be multipart (assign signature to each subpart)
- if (!empty($msg_part->parts)) {
- foreach ($msg_part->parts as $part)
- $this->signed_parts[$part->mime_id] = $struct->mime_id;
- }
- else
- $this->signed_parts[$msg_part->mime_id] = $struct->mime_id;
-
- // Remove signature file from attachments list
- unset($struct->parts[1]);
- }
- }
-
- /**
- * Handler for S/MIME signed message.
- * Verifies signature.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_smime_signed(&$p)
- {
- $this->load_smime_driver();
- }
-
- /**
- * Handler for plain encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_plain_encrypted(&$p)
- {
- $this->load_pgp_driver();
- $part = $p['structure'];
-
- // Get body
- $this->set_part_body($part, $p['object']->uid);
-
- // Decrypt
- $result = $this->pgp_decrypt($part->body);
-
- // Store decryption status
- $this->decryptions[$part->mime_id] = $result;
-
- // Parse decrypted message
- if ($result === true) {
- // @TODO
- }
- }
-
- /**
- * Handler for PGP/MIME encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_pgp_encrypted(&$p)
- {
- $this->load_pgp_driver();
- $struct = $p['structure'];
- $part = $struct->parts[1];
-
- // Get body
- $this->set_part_body($part, $p['object']->uid);
-
- // Decrypt
- $result = $this->pgp_decrypt($part->body);
-
- $this->decryptions[$part->mime_id] = $result;
-//print_r($part);
- // Parse decrypted message
- if ($result === true) {
- // @TODO
- }
- else {
- // Make sure decryption status message will be displayed
- $part->type = 'content';
- $p['object']->parts[] = $part;
- }
- }
-
- /**
- * Handler for S/MIME encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_smime_encrypted(&$p)
- {
- $this->load_smime_driver();
- }
-
- /**
- * PGP signature verification.
- *
- * @param mixed Message body
- * @param mixed Signature body (for MIME messages)
- *
- * @return mixed enigma_signature or enigma_error
- */
- private function pgp_verify(&$msg_body, $sig_body=null)
- {
- // @TODO: Handle big bodies using (temp) files
- // @TODO: caching of verification result
- $sig = $this->pgp_driver->verify($msg_body, $sig_body);
-
- if (($sig instanceof enigma_error) && $sig->getCode() != enigma_error::E_KEYNOTFOUND)
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $sig->getMessage()
- ), true, false);
-
- return $sig;
- }
-
- /**
- * PGP message decryption.
- *
- * @param mixed Message body
- *
- * @return mixed True or enigma_error
- */
- private function pgp_decrypt(&$msg_body)
- {
- // @TODO: Handle big bodies using (temp) files
- // @TODO: caching of verification result
- $key = ''; $pass = ''; // @TODO
- $result = $this->pgp_driver->decrypt($msg_body, $key, $pass);
-
- if ($result instanceof enigma_error) {
- $err_code = $result->getCode();
- if (!in_array($err_code, array(enigma_error::E_KEYNOTFOUND, enigma_error::E_BADPASS)))
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- return $result;
- }
-
-// $msg_body = $result;
- return true;
- }
-
- /**
- * PGP keys listing.
- *
- * @param mixed Key ID/Name pattern
- *
- * @return mixed Array of keys or enigma_error
- */
- function list_keys($pattern='')
- {
- $this->load_pgp_driver();
- $result = $this->pgp_driver->list_keys($pattern);
-
- if ($result instanceof enigma_error) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- }
-
- return $result;
- }
-
- /**
- * PGP key details.
- *
- * @param mixed Key ID
- *
- * @return mixed enigma_key or enigma_error
- */
- function get_key($keyid)
- {
- $this->load_pgp_driver();
- $result = $this->pgp_driver->get_key($keyid);
-
- if ($result instanceof enigma_error) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- }
-
- return $result;
- }
-
- /**
- * PGP keys/certs importing.
- *
- * @param mixed Import file name or content
- * @param boolean True if first argument is a filename
- *
- * @return mixed Import status data array or enigma_error
- */
- function import_key($content, $isfile=false)
- {
- $this->load_pgp_driver();
- $result = $this->pgp_driver->import($content, $isfile);
-
- if ($result instanceof enigma_error) {
- rcube::raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- }
- else {
- $result['imported'] = $result['public_imported'] + $result['private_imported'];
- $result['unchanged'] = $result['public_unchanged'] + $result['private_unchanged'];
- }
-
- return $result;
- }
-
- /**
- * Handler for keys/certs import request action
- */
- function import_file()
- {
- $uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
- $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
- $mime_id = rcube_utils::get_input_value('_part', rcube_utils::INPUT_POST);
- $storage = $this->rc->get_storage();
-
- if ($uid && $mime_id) {
- $storage->set_folder($mbox);
- $part = $storage->get_message_part($uid, $mime_id);
- }
-
- if ($part && is_array($result = $this->import_key($part))) {
- $this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
- array('new' => $result['imported'], 'old' => $result['unchanged']));
- }
- else
- $this->rc->output->show_message('enigma.keysimportfailed', 'error');
-
- $this->rc->output->send();
- }
-
- /**
- * Checks if specified message part contains body data.
- * If body is not set it will be fetched from IMAP server.
- *
- * @param rcube_message_part Message part object
- * @param integer Message UID
- */
- private function set_part_body($part, $uid)
- {
- // @TODO: Create such function in core
- // @TODO: Handle big bodies using file handles
- if (!isset($part->body)) {
- $part->body = $this->rc->storage->get_message_part(
- $uid, $part->mime_id, $part);
- }
- }
-}
diff --git a/plugins/enigma/lib/enigma_error.php b/plugins/enigma/lib/enigma_error.php
deleted file mode 100644
index 9f424dc2b..000000000
--- a/plugins/enigma/lib/enigma_error.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Error class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_error
-{
- private $code;
- private $message;
- private $data = array();
-
- // error codes
- const E_OK = 0;
- const E_INTERNAL = 1;
- const E_NODATA = 2;
- const E_KEYNOTFOUND = 3;
- const E_DELKEY = 4;
- const E_BADPASS = 5;
-
- function __construct($code = null, $message = '', $data = array())
- {
- $this->code = $code;
- $this->message = $message;
- $this->data = $data;
- }
-
- function getCode()
- {
- return $this->code;
- }
-
- function getMessage()
- {
- return $this->message;
- }
-
- function getData($name)
- {
- if ($name)
- return $this->data[$name];
- else
- return $this->data;
- }
-}
diff --git a/plugins/enigma/lib/enigma_key.php b/plugins/enigma/lib/enigma_key.php
deleted file mode 100644
index 520c36b0b..000000000
--- a/plugins/enigma/lib/enigma_key.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Key class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_key
-{
- public $id;
- public $name;
- public $users = array();
- public $subkeys = array();
-
- const TYPE_UNKNOWN = 0;
- const TYPE_KEYPAIR = 1;
- const TYPE_PUBLIC = 2;
-
- /**
- * Keys list sorting callback for usort()
- */
- static function cmp($a, $b)
- {
- return strcmp($a->name, $b->name);
- }
-
- /**
- * Returns key type
- */
- function get_type()
- {
- if ($this->subkeys[0]->has_private)
- return enigma_key::TYPE_KEYPAIR;
- else if (!empty($this->subkeys[0]))
- return enigma_key::TYPE_PUBLIC;
-
- return enigma_key::TYPE_UNKNOWN;
- }
-
- /**
- * Returns true if all user IDs are revoked
- */
- function is_revoked()
- {
- foreach ($this->subkeys as $subkey)
- if (!$subkey->revoked)
- return false;
-
- return true;
- }
-
- /**
- * Returns true if any user ID is valid
- */
- function is_valid()
- {
- foreach ($this->users as $user)
- if ($user->valid)
- return true;
-
- return false;
- }
-
- /**
- * Returns true if any of subkeys is not expired
- */
- function is_expired()
- {
- $now = time();
-
- foreach ($this->subkeys as $subkey)
- if (!$subkey->expires || $subkey->expires > $now)
- return true;
-
- return false;
- }
-
- /**
- * Converts long ID or Fingerprint to short ID
- * Crypt_GPG uses internal, but e.g. Thunderbird's Enigmail displays short ID
- *
- * @param string Key ID or fingerprint
- * @return string Key short ID
- */
- static function format_id($id)
- {
- // E.g. 04622F2089E037A5 => 89E037A5
-
- return substr($id, -8);
- }
-
- /**
- * Formats fingerprint string
- *
- * @param string Key fingerprint
- *
- * @return string Formatted fingerprint (with spaces)
- */
- static function format_fingerprint($fingerprint)
- {
- if (!$fingerprint)
- return '';
-
- $result = '';
- for ($i=0; $i<40; $i++) {
- if ($i % 4 == 0)
- $result .= ' ';
- $result .= $fingerprint[$i];
- }
- return $result;
- }
-
-}
diff --git a/plugins/enigma/lib/enigma_signature.php b/plugins/enigma/lib/enigma_signature.php
deleted file mode 100644
index 65990903b..000000000
--- a/plugins/enigma/lib/enigma_signature.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Signature class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_signature
-{
- public $id;
- public $valid;
- public $fingerprint;
- public $created;
- public $expires;
- public $name;
- public $comment;
- public $email;
-}
diff --git a/plugins/enigma/lib/enigma_subkey.php b/plugins/enigma/lib/enigma_subkey.php
deleted file mode 100644
index 1b9fb95ad..000000000
--- a/plugins/enigma/lib/enigma_subkey.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | SubKey class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_subkey
-{
- public $id;
- public $fingerprint;
- public $expires;
- public $created;
- public $revoked;
- public $has_private;
- public $can_sign;
- public $can_encrypt;
-
- /**
- * Converts internal ID to short ID
- * Crypt_GPG uses internal, but e.g. Thunderbird's Enigmail displays short ID
- *
- * @return string Key ID
- */
- function get_short_id()
- {
- // E.g. 04622F2089E037A5 => 89E037A5
- return enigma_key::format_id($this->id);
- }
-
- /**
- * Getter for formatted fingerprint
- *
- * @return string Formatted fingerprint
- */
- function get_fingerprint()
- {
- return enigma_key::format_fingerprint($this->fingerprint);
- }
-
-}
diff --git a/plugins/enigma/lib/enigma_ui.php b/plugins/enigma/lib/enigma_ui.php
deleted file mode 100644
index adb619d0c..000000000
--- a/plugins/enigma/lib/enigma_ui.php
+++ /dev/null
@@ -1,455 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | User Interface for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_ui
-{
- private $rc;
- private $enigma;
- private $home;
- private $css_added;
- private $data;
-
-
- function __construct($enigma_plugin, $home='')
- {
- $this->enigma = $enigma_plugin;
- $this->rc = $enigma_plugin->rc;
- // we cannot use $enigma_plugin->home here
- $this->home = $home;
- }
-
- /**
- * UI initialization and requests handlers.
- *
- * @param string Preferences section
- */
- function init($section='')
- {
- $this->enigma->include_script('enigma.js');
-
- // Enigma actions
- if ($this->rc->action == 'plugin.enigma') {
- $action = rcube_utils::get_input_value('_a', rcube_utils::INPUT_GPC);
-
- switch ($action) {
- case 'keyedit':
- $this->key_edit();
- break;
- case 'keyimport':
- $this->key_import();
- break;
- case 'keysearch':
- case 'keylist':
- $this->key_list();
- break;
- case 'keyinfo':
- default:
- $this->key_info();
- }
- }
- // Message composing UI
- else if ($this->rc->action == 'compose') {
- $this->compose_ui();
- }
- // Preferences UI
- else { // if ($this->rc->action == 'edit-prefs') {
- if ($section == 'enigmacerts') {
- $this->rc->output->add_handlers(array(
- 'keyslist' => array($this, 'tpl_certs_list'),
- 'keyframe' => array($this, 'tpl_cert_frame'),
- 'countdisplay' => array($this, 'tpl_certs_rowcount'),
- 'searchform' => array($this->rc->output, 'search_form'),
- ));
- $this->rc->output->set_pagetitle($this->enigma->gettext('enigmacerts'));
- $this->rc->output->send('enigma.certs');
- }
- else {
- $this->rc->output->add_handlers(array(
- 'keyslist' => array($this, 'tpl_keys_list'),
- 'keyframe' => array($this, 'tpl_key_frame'),
- 'countdisplay' => array($this, 'tpl_keys_rowcount'),
- 'searchform' => array($this->rc->output, 'search_form'),
- ));
- $this->rc->output->set_pagetitle($this->enigma->gettext('enigmakeys'));
- $this->rc->output->send('enigma.keys');
- }
- }
- }
-
- /**
- * Adds CSS style file to the page header.
- */
- function add_css()
- {
- if ($this->css_loaded)
- return;
-
- $skin = $this->rc->config->get('skin');
- if (!file_exists($this->home . "/skins/$skin/enigma.css"))
- $skin = 'default';
-
- $this->enigma->include_stylesheet("skins/$skin/enigma.css");
- $this->css_added = true;
- }
-
- /**
- * Template object for key info/edit frame.
- *
- * @param array Object attributes
- *
- * @return string HTML output
- */
- function tpl_key_frame($attrib)
- {
- if (!$attrib['id']) {
- $attrib['id'] = 'rcmkeysframe';
- }
-
- $attrib['name'] = $attrib['id'];
-
- $this->rc->output->set_env('contentframe', $attrib['name']);
- $this->rc->output->set_env('blankpage', $attrib['src'] ?
- $this->rc->output->abs_url($attrib['src']) : 'program/resources/blank.gif');
-
- return $this->rc->output->frame($attrib);
- }
-
- /**
- * Template object for list of keys.
- *
- * @param array Object attributes
- *
- * @return string HTML content
- */
- function tpl_keys_list($attrib)
- {
- // add id to message list table if not specified
- if (!strlen($attrib['id'])) {
- $attrib['id'] = 'rcmenigmakeyslist';
- }
-
- // define list of cols to be displayed
- $a_show_cols = array('name');
-
- // create XHTML table
- $out = $this->rc->table_output($attrib, array(), $a_show_cols, 'id');
-
- // set client env
- $this->rc->output->add_gui_object('keyslist', $attrib['id']);
- $this->rc->output->include_script('list.js');
-
- // add some labels to client
- $this->rc->output->add_label('enigma.keyconfirmdelete');
-
- return $out;
- }
-
- /**
- * Key listing (and searching) request handler
- */
- private function key_list()
- {
- $this->enigma->load_engine();
-
- $pagesize = $this->rc->config->get('pagesize', 100);
- $page = max(intval(rcube_utils::get_input_value('_p', rcube_utils::INPUT_GPC)), 1);
- $search = rcube_utils::get_input_value('_q', rcube_utils::INPUT_GPC);
-
- // define list of cols to be displayed
-// $a_show_cols = array('name');
-
- // Get the list
- $list = $this->enigma->engine->list_keys($search);
-
- if ($list && ($list instanceof enigma_error))
- $this->rc->output->show_message('enigma.keylisterror', 'error');
- else if (empty($list))
- $this->rc->output->show_message('enigma.nokeysfound', 'notice');
- else {
- if (is_array($list)) {
- // Save the size
- $listsize = count($list);
-
- // Sort the list by key (user) name
- usort($list, array('enigma_key', 'cmp'));
-
- // Slice current page
- $list = array_slice($list, ($page - 1) * $pagesize, $pagesize);
-
- $size = count($list);
-
- // Add rows
- foreach ($list as $key) {
- $this->rc->output->command('enigma_add_list_row',
- array('name' => rcube::Q($key->name), 'id' => $key->id));
- }
- }
- }
-
- $this->rc->output->set_env('search_request', $search);
- $this->rc->output->set_env('pagecount', ceil($listsize/$pagesize));
- $this->rc->output->set_env('current_page', $page);
- $this->rc->output->command('set_rowcount',
- $this->get_rowcount_text($listsize, $size, $page));
-
- $this->rc->output->send();
- }
-
- /**
- * Template object for list records counter.
- *
- * @param array Object attributes
- *
- * @return string HTML output
- */
- function tpl_keys_rowcount($attrib)
- {
- if (!$attrib['id'])
- $attrib['id'] = 'rcmcountdisplay';
-
- $this->rc->output->add_gui_object('countdisplay', $attrib['id']);
-
- return html::span($attrib, $this->get_rowcount_text());
- }
-
- /**
- * Returns text representation of list records counter
- */
- private function get_rowcount_text($all=0, $curr_count=0, $page=1)
- {
- if (!$curr_count)
- $out = $this->enigma->gettext('nokeysfound');
- else {
- $pagesize = $this->rc->config->get('pagesize', 100);
- $first = ($page - 1) * $pagesize;
-
- $out = $this->enigma->gettext(array(
- 'name' => 'keysfromto',
- 'vars' => array(
- 'from' => $first + 1,
- 'to' => $first + $curr_count,
- 'count' => $all)
- ));
- }
-
- return $out;
- }
-
- /**
- * Key information page handler
- */
- private function key_info()
- {
- $id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GET);
-
- $this->enigma->load_engine();
- $res = $this->enigma->engine->get_key($id);
-
- if ($res instanceof enigma_key)
- $this->data = $res;
- else { // error
- $this->rc->output->show_message('enigma.keyopenerror', 'error');
- $this->rc->output->command('parent.enigma_loadframe');
- $this->rc->output->send('iframe');
- }
-
- $this->rc->output->add_handlers(array(
- 'keyname' => array($this, 'tpl_key_name'),
- 'keydata' => array($this, 'tpl_key_data'),
- ));
-
- $this->rc->output->set_pagetitle($this->enigma->gettext('keyinfo'));
- $this->rc->output->send('enigma.keyinfo');
- }
-
- /**
- * Template object for key name
- */
- function tpl_key_name($attrib)
- {
- return rcube::Q($this->data->name);
- }
-
- /**
- * Template object for key information page content
- */
- function tpl_key_data($attrib)
- {
- $out = '';
- $table = new html_table(array('cols' => 2));
-
- // Key user ID
- $table->add('title', $this->enigma->gettext('keyuserid'));
- $table->add(null, rcube::Q($this->data->name));
- // Key ID
- $table->add('title', $this->enigma->gettext('keyid'));
- $table->add(null, $this->data->subkeys[0]->get_short_id());
- // Key type
- $keytype = $this->data->get_type();
- if ($keytype == enigma_key::TYPE_KEYPAIR)
- $type = $this->enigma->gettext('typekeypair');
- else if ($keytype == enigma_key::TYPE_PUBLIC)
- $type = $this->enigma->gettext('typepublickey');
- $table->add('title', $this->enigma->gettext('keytype'));
- $table->add(null, $type);
- // Key fingerprint
- $table->add('title', $this->enigma->gettext('fingerprint'));
- $table->add(null, $this->data->subkeys[0]->get_fingerprint());
-
- $out .= html::tag('fieldset', null,
- html::tag('legend', null,
- $this->enigma->gettext('basicinfo')) . $table->show($attrib));
-
- // Subkeys
- $table = new html_table(array('cols' => 6));
- // Columns: Type, ID, Algorithm, Size, Created, Expires
-
- $out .= html::tag('fieldset', null,
- html::tag('legend', null,
- $this->enigma->gettext('subkeys')) . $table->show($attrib));
-
- // Additional user IDs
- $table = new html_table(array('cols' => 2));
- // Columns: User ID, Validity
-
- $out .= html::tag('fieldset', null,
- html::tag('legend', null,
- $this->enigma->gettext('userids')) . $table->show($attrib));
-
- return $out;
- }
-
- /**
- * Key import page handler
- */
- private function key_import()
- {
- // Import process
- if ($_FILES['_file']['tmp_name'] && is_uploaded_file($_FILES['_file']['tmp_name'])) {
- $this->enigma->load_engine();
- $result = $this->enigma->engine->import_key($_FILES['_file']['tmp_name'], true);
-
- if (is_array($result)) {
- // reload list if any keys has been added
- if ($result['imported']) {
- $this->rc->output->command('parent.enigma_list', 1);
- }
- else
- $this->rc->output->command('parent.enigma_loadframe');
-
- $this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
- array('new' => $result['imported'], 'old' => $result['unchanged']));
-
- $this->rc->output->send('iframe');
- }
- else
- $this->rc->output->show_message('enigma.keysimportfailed', 'error');
- }
- else if ($err = $_FILES['_file']['error']) {
- if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
- $this->rc->output->show_message('filesizeerror', 'error',
- array('size' => $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize')))));
- } else {
- $this->rc->output->show_message('fileuploaderror', 'error');
- }
- }
-
- $this->rc->output->add_handlers(array(
- 'importform' => array($this, 'tpl_key_import_form'),
- ));
-
- $this->rc->output->set_pagetitle($this->enigma->gettext('keyimport'));
- $this->rc->output->send('enigma.keyimport');
- }
-
- /**
- * Template object for key import (upload) form
- */
- function tpl_key_import_form($attrib)
- {
- $attrib += array('id' => 'rcmKeyImportForm');
-
- $upload = new html_inputfield(array('type' => 'file', 'name' => '_file',
- 'id' => 'rcmimportfile', 'size' => 30));
-
- $form = html::p(null,
- rcube::Q($this->enigma->gettext('keyimporttext'), 'show')
- . html::br() . html::br() . $upload->show()
- );
-
- $this->rc->output->add_label('selectimportfile', 'importwait');
- $this->rc->output->add_gui_object('importform', $attrib['id']);
-
- $out = $this->rc->output->form_tag(array(
- 'action' => $this->rc->url(array('action' => 'plugin.enigma', 'a' => 'keyimport')),
- 'method' => 'post',
- 'enctype' => 'multipart/form-data') + $attrib,
- $form);
-
- return $out;
- }
-
- private function compose_ui()
- {
- // Options menu button
- // @TODO: make this work with non-default skins
- $this->enigma->add_button(array(
- 'name' => 'enigmamenu',
- 'imagepas' => 'skins/default/enigma.png',
- 'imageact' => 'skins/default/enigma.png',
- 'onclick' => "rcmail_ui.show_popup('enigmamenu', true); return false",
- 'title' => 'securityoptions',
- 'domain' => 'enigma',
- ), 'toolbar');
-
- // Options menu contents
- $this->enigma->add_hook('render_page', array($this, 'compose_menu'));
- }
-
- function compose_menu($p)
- {
- $menu = new html_table(array('cols' => 2));
- $chbox = new html_checkbox(array('value' => 1));
-
- $menu->add(null, html::label(array('for' => 'enigmadefaultopt'),
- rcube::Q($this->enigma->gettext('identdefault'))));
- $menu->add(null, $chbox->show(1, array('name' => '_enigma_default', 'id' => 'enigmadefaultopt')));
-
- $menu->add(null, html::label(array('for' => 'enigmasignopt'),
- rcube::Q($this->enigma->gettext('signmsg'))));
- $menu->add(null, $chbox->show(1, array('name' => '_enigma_sign', 'id' => 'enigmasignopt')));
-
- $menu->add(null, html::label(array('for' => 'enigmacryptopt'),
- rcube::Q($this->enigma->gettext('encryptmsg'))));
- $menu->add(null, $chbox->show(1, array('name' => '_enigma_crypt', 'id' => 'enigmacryptopt')));
-
- $menu = html::div(array('id' => 'enigmamenu', 'class' => 'popupmenu'),
- $menu->show());
-
- $p['content'] = preg_replace('/(<form name="form"[^>]+>)/i', '\\1'."\n$menu", $p['content']);
-
- return $p;
-
- }
-
-}
diff --git a/plugins/enigma/lib/enigma_userid.php b/plugins/enigma/lib/enigma_userid.php
deleted file mode 100644
index 36185e718..000000000
--- a/plugins/enigma/lib/enigma_userid.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | User ID class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_userid
-{
- public $revoked;
- public $valid;
- public $name;
- public $comment;
- public $email;
-}
diff --git a/plugins/enigma/localization/en_US.inc b/plugins/enigma/localization/en_US.inc
deleted file mode 100644
index e0f03d9a0..000000000
--- a/plugins/enigma/localization/en_US.inc
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-$labels = array();
-$labels['enigmasettings'] = 'Enigma: Settings';
-$labels['enigmacerts'] = 'Enigma: Certificates (S/MIME)';
-$labels['enigmakeys'] = 'Enigma: Keys (PGP)';
-$labels['keysfromto'] = 'Keys $from to $to of $count';
-$labels['keyname'] = 'Name';
-$labels['keyid'] = 'Key ID';
-$labels['keyuserid'] = 'User ID';
-$labels['keytype'] = 'Key type';
-$labels['fingerprint'] = 'Fingerprint';
-$labels['subkeys'] = 'Subkeys';
-$labels['basicinfo'] = 'Basic Information';
-$labels['userids'] = 'Additional User IDs';
-$labels['typepublickey'] = 'public key';
-$labels['typekeypair'] = 'key pair';
-$labels['keyattfound'] = 'This message contains attached PGP key(s).';
-$labels['keyattimport'] = 'Import key(s)';
-
-$labels['createkeys'] = 'Create a new key pair';
-$labels['importkeys'] = 'Import key(s)';
-$labels['exportkeys'] = 'Export key(s)';
-$labels['deletekeys'] = 'Delete key(s)';
-$labels['keyactions'] = 'Key actions...';
-$labels['keydisable'] = 'Disable key';
-$labels['keyrevoke'] = 'Revoke key';
-$labels['keysend'] = 'Send public key in a message';
-$labels['keychpass'] = 'Change password';
-
-$labels['securityoptions'] = 'Message security options...';
-$labels['identdefault'] = 'Use settings of selected identity';
-$labels['encryptmsg'] = 'Encrypt this message';
-$labels['signmsg'] = 'Digitally sign this message';
-
-$messages = array();
-$messages['sigvalid'] = 'Verified signature from $sender.';
-$messages['siginvalid'] = 'Invalid signature from $sender.';
-$messages['signokey'] = 'Unverified signature. Public key not found. Key ID: $keyid.';
-$messages['sigerror'] = 'Unverified signature. Internal error.';
-$messages['decryptok'] = 'Message decrypted.';
-$messages['decrypterror'] = 'Decryption failed.';
-$messages['decryptnokey'] = 'Decryption failed. Private key not found. Key ID: $keyid.';
-$messages['decryptbadpass'] = 'Decryption failed. Bad password.';
-$messages['nokeysfound'] = 'No keys found';
-$messages['keyopenerror'] = 'Unable to get key information! Internal error.';
-$messages['keylisterror'] = 'Unable to list keys! Internal error.';
-$messages['keysimportfailed'] = 'Unable to import key(s)! Internal error.';
-$messages['keysimportsuccess'] = 'Key(s) imported successfully. Imported: $new, unchanged: $old.';
-$messages['keyconfirmdelete'] = 'Are you sure, you want to delete selected key(s)?';
-$messages['keyimporttext'] = 'You can import private and public key(s) or revocation signatures in ASCII-Armor format.';
-
-?>
diff --git a/plugins/enigma/localization/ja_JP.inc b/plugins/enigma/localization/ja_JP.inc
deleted file mode 100644
index 882014440..000000000
--- a/plugins/enigma/localization/ja_JP.inc
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-// EN-Revision: 4203
-
-$labels = array();
-$labels['enigmasettings'] = 'Enigma: 設定';
-$labels['enigmacerts'] = 'Enigma: 証明書 (S/MIME)';
-$labels['enigmakeys'] = 'Enigma: éµ (PGP)';
-$labels['keysfromto'] = 'éµã®ä¸€è¦§ $from ~ $to (åˆè¨ˆ: $count )';
-$labels['keyname'] = 'åå‰';
-$labels['keyid'] = 'éµ ID';
-$labels['keyuserid'] = 'ユーザー ID';
-$labels['keytype'] = 'éµã®ç¨®é¡ž';
-$labels['fingerprint'] = '指紋';
-$labels['subkeys'] = 'Subkeys';
-$labels['basicinfo'] = '基本情報';
-$labels['userids'] = '追加ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ ID';
-$labels['typepublickey'] = '公開éµ';
-$labels['typekeypair'] = 'éµã®ãƒšã‚¢';
-$labels['keyattfound'] = 'ã“ã®ãƒ¡ãƒ¼ãƒ«ã¯ PGP éµã®æ·»ä»˜ãŒã‚ã‚Šã¾ã™ã€‚';
-$labels['keyattimport'] = 'éµã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ';
-
-$labels['createkeys'] = 'æ–°ã—ã„éµã®ãƒšã‚¢ã‚’作æˆã™ã‚‹';
-$labels['importkeys'] = 'éµã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ';
-$labels['exportkeys'] = 'éµã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ';
-$labels['deletekeys'] = 'éµã®å‰Šé™¤';
-$labels['keyactions'] = 'éµã®æ“作...';
-$labels['keydisable'] = 'éµã‚’無効ã«ã™ã‚‹';
-$labels['keyrevoke'] = 'éµã‚’å–り消ã™';
-$labels['keysend'] = 'メッセージã«å…¬é–‹éµã‚’å«ã‚“ã§é€ä¿¡ã™ã‚‹';
-$labels['keychpass'] = 'パスワードã®å¤‰æ›´';
-
-$labels['securityoptions'] = 'メールã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ オプション...';
-$labels['identdefault'] = 'é¸æŠžã—ãŸè­˜åˆ¥å­ã®è¨­å®šã‚’使ã†';
-$labels['encryptmsg'] = 'ã“ã®ãƒ¡ãƒ¼ãƒ«ã®æš—å·åŒ–';
-$labels['signmsg'] = 'ã“ã®ãƒ¡ãƒ¼ãƒ«ã®ãƒ‡ã‚¸ã‚¿ãƒ«ç½²å';
-
-$messages = array();
-$messages['sigvalid'] = '$sender ã‹ã‚‰ã®ç½²åを検証ã—ã¾ã—ãŸã€‚';
-$messages['siginvalid'] = '$sender ã‹ã‚‰ã®ç½²åãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“。';
-$messages['signokey'] = 'ç½²åã¯æœªæ¤œè¨¼ã§ã™ã€‚公開éµãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€‚éµ ID: $keyid';
-$messages['sigerror'] = 'ç½²åã¯æœªæ¤œè¨¼ã§ã™ã€‚内部エラーã§ã™ã€‚';
-$messages['decryptok'] = 'メールを復å·ã—ã¾ã—ãŸã€‚';
-$messages['decrypterror'] = '復å·ã«å¤±æ•—ã—ã¾ã—ãŸã€‚';
-$messages['decryptnokey'] = '復å·ã«å¤±æ•—ã—ã¾ã—ãŸã€‚秘密éµãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€‚éµ ID: $keyid.';
-$messages['decryptbadpass'] = '復å·ã«å¤±æ•—ã—ã¾ã—ãŸã€‚パスワードãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“。';
-$messages['nokeysfound'] = 'éµãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。';
-$messages['keyopenerror'] = 'éµæƒ…å ±ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ! 内部エラーã§ã™ã€‚';
-$messages['keylisterror'] = 'éµæƒ…å ±ã®ãƒªã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ! 内部エラーã§ã™ã€‚';
-$messages['keysimportfailed'] = 'éµã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ! 内部エラーã§ã™ã€‚';
-$messages['keysimportsuccess'] = 'éµã‚’インãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚インãƒãƒ¼ãƒˆ: $new, 未変更: $old';
-$messages['keyconfirmdelete'] = 'é¸æŠžã—ãŸéµã‚’本当ã«å‰Šé™¤ã—ã¾ã™ã‹?';
-$messages['keyimporttext'] = '秘密éµã¨å…¬é–‹éµã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã€ã¾ãŸã¯ ASCII å½¢å¼ã®ç½²åを無効ã«ã§ãã¾ã™ã€‚';
-
-?>
diff --git a/plugins/enigma/localization/ru_RU.inc b/plugins/enigma/localization/ru_RU.inc
deleted file mode 100644
index 3033d002c..000000000
--- a/plugins/enigma/localization/ru_RU.inc
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-/*
-
-+-----------------------------------------------------------------------+
-| plugins/enigma/localization/ru_RU.inc |
-| |
-| Russian translation for roundcube/enigma plugin |
-| Copyright (C) 2010 |
-| Licensed under the GNU GPL |
-| |
-+-----------------------------------------------------------------------+
-| Author: Sergey Dukachev <iam@dukess.ru> |
-| Updates: |
-+-----------------------------------------------------------------------+
-
-@version 2010-12-23
-
-*/
-
-$labels = array();
-$labels['enigmasettings'] = 'Enigma: ÐаÑтройки';
-$labels['enigmacerts'] = 'Enigma: Сертификаты (S/MIME)';
-$labels['enigmakeys'] = 'Enigma: Ключи (PGP)';
-$labels['keysfromto'] = 'Ключи от $from к $to в количеÑтве $count';
-$labels['keyname'] = 'ИмÑ';
-$labels['keyid'] = 'Идентификатор ключа';
-$labels['keyuserid'] = 'Идентификатор пользователÑ';
-$labels['keytype'] = 'Тип ключа';
-$labels['fingerprint'] = 'Отпечаток (Ñ…Ñш) ключа';
-$labels['subkeys'] = 'Подразделы';
-$labels['basicinfo'] = 'ОÑновные ÑведениÑ';
-$labels['userids'] = 'Дополнительные идентификаторы пользователÑ';
-$labels['typepublickey'] = 'Открытый ключ';
-$labels['typekeypair'] = 'пара ключей';
-$labels['keyattfound'] = 'Это Ñообщение Ñодержит один или неÑколько ключей PGP.';
-$labels['keyattimport'] = 'Импортировать ключи';
-
-$labels['createkeys'] = 'Создать новую пару ключей';
-$labels['importkeys'] = 'Импортировать ключ(и)';
-$labels['exportkeys'] = 'ЭкÑпортировать ключ(и)';
-$labels['deletekeys'] = 'Удалить ключ(и)';
-$labels['keyactions'] = 'ДейÑÑ‚Ð²Ð¸Ñ Ñ ÐºÐ»ÑŽÑ‡Ð°Ð¼Ð¸...';
-$labels['keydisable'] = 'Отключить ключ';
-$labels['keyrevoke'] = 'Отозвать ключ';
-$labels['keysend'] = 'Отправить публичный ключ в Ñобщении';
-$labels['keychpass'] = 'Изменить пароль';
-
-$messages = array();
-$messages['sigvalid'] = 'ÐŸÑ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ у $sender.';
-$messages['siginvalid'] = 'ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ у $sender.';
-$messages['signokey'] = 'ÐепроверÑÐµÐ¼Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ. Открытый ключ не найден. Идентификатор ключа: $keyid.';
-$messages['sigerror'] = 'ÐепроверÑÐµÐ¼Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ. ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°.';
-$messages['decryptok'] = 'Сообщение раÑшифровано.';
-$messages['decrypterror'] = 'РаÑшифровка не удалаÑÑŒ.';
-$messages['decryptnokey'] = 'РаÑшифровка не удалаÑÑŒ. Секретный ключ не найден. Идентификатор ключа: $keyid.';
-$messages['decryptbadpass'] = 'РаÑшифровка не удалаÑÑŒ. Ðеправильный пароль.';
-$messages['nokeysfound'] = 'Ключи не найдены';
-$messages['keyopenerror'] = 'Ðевозможно получить информацию о ключе! ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°.';
-$messages['keylisterror'] = 'Ðевозможно Ñделать ÑпиÑок ключей! ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°.';
-$messages['keysimportfailed'] = 'Ðевозможно импортировать ключ(и)! ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°.';
-$messages['keysimportsuccess'] = 'Ключи уÑпешно импортированы. Импортировано: $new, без изменений: $old.';
-$messages['keyconfirmdelete'] = 'Вы точно хотите удалить выбранные ключи?';
-$messages['keyimporttext'] = 'Ð’Ñ‹ можете импортировать открытые и Ñекретные ключи или ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± отзыве ключей в формате ASCII-Armor.';
-
-?>
diff --git a/plugins/enigma/skins/classic/enigma.css b/plugins/enigma/skins/classic/enigma.css
deleted file mode 100644
index b1c656f82..000000000
--- a/plugins/enigma/skins/classic/enigma.css
+++ /dev/null
@@ -1,182 +0,0 @@
-/*** Style for Enigma plugin ***/
-
-/***** Messages displaying *****/
-
-#enigma-message,
-/* fixes border-top */
-#messagebody div #enigma-message
-{
- margin: 0;
- margin-bottom: 5px;
- min-height: 20px;
- padding: 10px 10px 6px 46px;
-}
-
-div.enigmaerror,
-/* fixes border-top */
-#messagebody div.enigmaerror
-{
- background: url(enigma_error.png) 6px 1px no-repeat;
- background-color: #EF9398;
- border: 1px solid #DC5757;
-}
-
-div.enigmanotice,
-/* fixes border-top */
-#messagebody div.enigmanotice
-{
- background: url(enigma.png) 6px 1px no-repeat;
- background-color: #A6EF7B;
- border: 1px solid #76C83F;
-}
-
-div.enigmawarning,
-/* fixes border-top */
-#messagebody div.enigmawarning
-{
- background: url(enigma.png) 6px 1px no-repeat;
- background-color: #F7FDCB;
- border: 1px solid #C2D071;
-}
-
-#enigma-message a
-{
- color: #666666;
- padding-left: 10px;
-}
-
-#enigma-message a:hover
-{
- color: #333333;
-}
-
-/***** Keys/Certs Management *****/
-
-div.enigmascreen
-{
- position: absolute;
- top: 65px;
- right: 10px;
- bottom: 10px;
- left: 10px;
-}
-
-#enigmacontent-box
-{
- position: absolute;
- top: 0px;
- left: 290px;
- right: 0px;
- bottom: 0px;
- border: 1px solid #999999;
- overflow: hidden;
-}
-
-#enigmakeyslist
-{
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- border: 1px solid #999999;
- background-color: #F9F9F9;
- overflow: hidden;
-}
-
-#keylistcountbar
-{
- margin-top: 4px;
- margin-left: 4px;
-}
-
-#keys-table
-{
- width: 100%;
- table-layout: fixed;
-}
-
-#keys-table td
-{
- cursor: default;
- text-overflow: ellipsis;
- -o-text-overflow: ellipsis;
-}
-
-#key-details table td.title
-{
- font-weight: bold;
- text-align: right;
-}
-
-#keystoolbar
-{
- position: absolute;
- top: 30px;
- left: 10px;
- height: 35px;
-}
-
-#keystoolbar a
-{
- padding-right: 10px;
-}
-
-#keystoolbar a.button,
-#keystoolbar a.buttonPas,
-#keystoolbar span.separator {
- display: block;
- float: left;
- width: 32px;
- height: 32px;
- padding: 0;
- margin-right: 10px;
- overflow: hidden;
- background: url(keys_toolbar.png) 0 0 no-repeat transparent;
- opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
-}
-
-#keystoolbar a.buttonPas {
- opacity: 0.35;
-}
-
-#keystoolbar a.createSel {
- background-position: 0 -32px;
-}
-
-#keystoolbar a.create {
- background-position: 0 0;
-}
-
-#keystoolbar a.deleteSel {
- background-position: -32px -32px;
-}
-
-#keystoolbar a.delete {
- background-position: -32px 0;
-}
-
-#keystoolbar a.importSel {
- background-position: -64px -32px;
-}
-
-#keystoolbar a.import {
- background-position: -64px 0;
-}
-
-#keystoolbar a.exportSel {
- background-position: -96px -32px;
-}
-
-#keystoolbar a.export {
- background-position: -96px 0;
-}
-
-#keystoolbar a.keymenu {
- background-position: -128px 0;
- width: 36px;
-}
-
-#keystoolbar span.separator {
- width: 5px;
- background-position: -166px 0;
-}
diff --git a/plugins/enigma/skins/classic/enigma.png b/plugins/enigma/skins/classic/enigma.png
deleted file mode 100644
index 3ef106e2a..000000000
--- a/plugins/enigma/skins/classic/enigma.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/classic/enigma_error.png b/plugins/enigma/skins/classic/enigma_error.png
deleted file mode 100644
index 9bf100efd..000000000
--- a/plugins/enigma/skins/classic/enigma_error.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/classic/key.png b/plugins/enigma/skins/classic/key.png
deleted file mode 100644
index ea1cbd11c..000000000
--- a/plugins/enigma/skins/classic/key.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/classic/key_add.png b/plugins/enigma/skins/classic/key_add.png
deleted file mode 100644
index f22cc870a..000000000
--- a/plugins/enigma/skins/classic/key_add.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/classic/keys_toolbar.png b/plugins/enigma/skins/classic/keys_toolbar.png
deleted file mode 100644
index 7cc258cc8..000000000
--- a/plugins/enigma/skins/classic/keys_toolbar.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/classic/templates/keyimport.html b/plugins/enigma/skins/classic/templates/keyimport.html
deleted file mode 100644
index 4e0b304a5..000000000
--- a/plugins/enigma/skins/classic/templates/keyimport.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!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/enigma.css" />
-</head>
-<body class="iframe">
-
-<div id="keyimport-title" class="boxtitle"><roundcube:label name="enigma.importkeys" /></div>
-
-<div id="import-form" class="boxcontent">
- <roundcube:object name="importform" />
- <p>
- <br /><roundcube:button command="plugin.enigma-import" type="input" class="button mainaction" label="import" />
- </p>
-</div>
-
-</body>
-</html>
diff --git a/plugins/enigma/skins/classic/templates/keyinfo.html b/plugins/enigma/skins/classic/templates/keyinfo.html
deleted file mode 100644
index 2e8ed61db..000000000
--- a/plugins/enigma/skins/classic/templates/keyinfo.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!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/enigma.css" />
-</head>
-<body class="iframe">
-
-<div id="keyinfo-title" class="boxtitle"><roundcube:object name="keyname" part="name" /></div>
-
-<div id="key-details" class="boxcontent">
- <roundcube:object name="keydata" />
-</div>
-
-</body>
-</html>
diff --git a/plugins/enigma/skins/classic/templates/keys.html b/plugins/enigma/skins/classic/templates/keys.html
deleted file mode 100644
index f581c457b..000000000
--- a/plugins/enigma/skins/classic/templates/keys.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!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/enigma.css" />
-<script type="text/javascript" src="/functions.js"></script>
-<script type="text/javascript" src="/splitter.js"></script>
-<style type="text/css">
-#enigmakeyslist { width: <roundcube:exp expression="!empty(cookie:enigmaviewsplitter) ? cookie:enigmaviewsplitter-5 : 210" />px; }
-#enigmacontent-box { left: <roundcube:exp expression="!empty(cookie:enigmaviewsplitter) ? cookie:enigmaviewsplitter+5 : 220" />px;
-<roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:enigmaeviewsplitter) ? cookie:enigmaviewsplitter+5 : 220).')+\\'px\\');') : ''" />
-}
-</style>
-</head>
-<body class="iframe">
-
-<div id="prefs-title" class="boxtitle"><roundcube:label name="enigma.enigmakeys" /></div>
-<div id="prefs-details" class="boxcontent">
-
-<div id="keystoolbar">
- <roundcube:button command="plugin.enigma-key-create" type="link" class="buttonPas create" classAct="button create" classSel="button createSel" title="enigma.createkeys" content=" " />
- <roundcube:button command="plugin.enigma-key-delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="enigma.deletekeys" content=" " />
- <span class="separator">&nbsp;</span>
- <roundcube:button command="plugin.enigma-key-import" type="link" class="buttonPas import" classAct="button import" classSel="button importSel" title="enigma.importkeys" content=" " />
- <roundcube:button command="plugin.enigma-key-export" type="link" class="buttonPas export" classAct="button export" classSel="button exportSel" title="enigma.exportkeys" content=" " />
- <roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button keymenu" title="enigma.keyactions" onclick="rcmail_ui.show_popup('messagemenu');return false" content=" " />
-</div>
-
-<div id="quicksearchbar" style="top: 35px; right: 10px;">
- <roundcube:button name="searchmenulink" id="searchmenulink" image="/images/icons/glass.png" />
- <roundcube:object name="searchform" id="quicksearchbox" />
- <roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
-</div>
-
-<div class="enigmascreen">
-
-<div id="enigmakeyslist">
-<div class="boxtitle"><roundcube:label name="enigma.keyname" /></div>
-<div class="boxlistcontent">
- <roundcube:object name="keyslist" id="keys-table" class="records-table" cellspacing="0" noheader="true" />
-</div>
-<div class="boxfooter">
-<div id="keylistcountbar" class="pagenav">
- <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstpage" content=" " />
- <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previouspage" content=" " />
- <roundcube:object name="countdisplay" style="padding:0 .5em; float:left" />
- <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextpage" content=" " />
- <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastpage" content=" " />
-</div>
-</div>
-</div>
-
-<script type="text/javascript">
- var enigmaviewsplit = new rcube_splitter({id:'enigmaviewsplitter', p1: 'enigmakeyslist', p2: 'enigmacontent-box', orientation: 'v', relative: true, start: 215});
- rcmail.add_onload('enigmaviewsplit.init()');
-</script>
-
-<div id="enigmacontent-box">
- <roundcube:object name="keyframe" id="keyframe" width="100%" height="100%" frameborder="0" src="/watermark.html" />
-</div>
-
-</div>
-</div>
-
-<div id="messagemenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button class="disablelink" command="enigma.key-disable" label="enigma.keydisable" target="_blank" classAct="disablelink active" /></li>
- <li><roundcube:button class="revokelink" command="enigma.key-revoke" label="enigma.keyrevoke" classAct="revokelink active" /></li>
- <li class="separator_below"><roundcube:button class="sendlink" command="enigma.key-send" label="enigma.keysend" classAct="sendlink active" /></li>
- <li><roundcube:button class="chpasslink" command="enigma.key-chpass" label="enigma.keychpass" classAct="chpasslink active" /></li>
- </ul>
-</div>
-
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
-</body>
-</html>
diff --git a/plugins/enigma/tests/Enigma.php b/plugins/enigma/tests/Enigma.php
deleted file mode 100644
index 0d0d8f8ae..000000000
--- a/plugins/enigma/tests/Enigma.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-class Enigma_Plugin extends PHPUnit_Framework_TestCase
-{
-
- function setUp()
- {
- include_once dirname(__FILE__) . '/../enigma.php';
- }
-
- /**
- * Plugin object construction test
- */
- function test_constructor()
- {
- $rcube = rcube::get_instance();
- $plugin = new enigma($rcube->api);
-
- $this->assertInstanceOf('enigma', $plugin);
- $this->assertInstanceOf('rcube_plugin', $plugin);
- }
-}
-
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/filesystem_attachments/filesystem_attachments.php b/plugins/filesystem_attachments/filesystem_attachments.php
index 8d995ca0d..d952e5a75 100644
--- a/plugins/filesystem_attachments/filesystem_attachments.php
+++ b/plugins/filesystem_attachments/filesystem_attachments.php
@@ -13,7 +13,6 @@
* require_once('plugins/filesystem_attachments/filesystem_attachments.php');
* class myCustom_attachments extends filesystem_attachments
*
- * @license GNU GPLv3+
* @author Ziba Scott <ziba@umich.edu>
* @author Thomas Bruederli <roundcube@gmail.com>
*
diff --git a/plugins/filesystem_attachments/package.xml b/plugins/filesystem_attachments/package.xml
index 49ec51934..031a74297 100644
--- a/plugins/filesystem_attachments/package.xml
+++ b/plugins/filesystem_attachments/package.xml
@@ -34,7 +34,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/help/config.inc.php.dist b/plugins/help/config.inc.php.dist
index 7cc8d5f00..d440dbbcc 100644
--- a/plugins/help/config.inc.php.dist
+++ b/plugins/help/config.inc.php.dist
@@ -1,35 +1,5 @@
<?php
// Help content iframe source
-// %l will be replaced by the language code resolved using the 'help_language_map' option
-$config['help_source'] = 'http://roundcube.net/doc/help/0.9/%l/';
-
-// Map task/action combinations to deep-links
-// Use '<task>/<action>' or only '<task>' strings as keys
-// The values will be appended to the 'help_source' URL
-$config['help_index_map'] = array(
- 'login' => 'login.html',
- 'mail' => 'mail/index.html',
- 'mail/compose' => 'mail/compose.html',
- 'addressbook' => 'addressbook/index.html',
- 'settings' => 'settings/index.html',
- 'settings/preferences' => 'settings/preferences.html',
- 'settings/folders' => 'settings/folders.html',
- 'settings/identities' => 'settings/identities.html',
-);
-
-// Map to translate Roundcube language codes into help document languages
-// The '*' entry will be used as default
-$config['help_language_map'] = array('*' => 'en_US');
-
-// Enter an absolute URL to a page displaying information about this webmail
-// Alternatively, create a HTML file under <this-plugin-dir>/content/about.html
-$config['help_about_url'] = null;
-
-// Enter an absolute URL to a page displaying information about this webmail
-// Alternatively, put your license text to <this-plugin-dir>/content/license.html
-$config['help_license_url'] = null;
-
-// Determine whether to open the help in a new window
-$config['help_open_extwin'] = false;
-
+// $rcmail_config['help_source'] = 'http://trac.roundcube.net/wiki';
+$rcmail_config['help_source'] = '';
diff --git a/plugins/help/content/about.html b/plugins/help/content/about.html
new file mode 100644
index 000000000..6e9632bec
--- /dev/null
+++ b/plugins/help/content/about.html
@@ -0,0 +1,27 @@
+<div id="helpabout" class="readtext">
+<h2 align="center">Copyright &copy; 2005-2012, The Roundcube Dev Team</h2>
+
+<p>
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License (with exceptions
+for skins &amp; plugins) as published by the Free Software Foundation,
+either version 3 of the License, or (at your option) any later version.
+</p>
+<p>
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+</p>
+<p>
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">www.gnu.org/licenses</a>.
+</p>
+
+<p>
+For more details about licensing and the expections for skins and plugins
+see <a href="http://roundcube.net/license">roundcube.net/license</a>.
+</p>
+
+<p><br/>Website: <a href="http://roundcube.net">roundcube.net</a></p>
+</div>
diff --git a/plugins/help/content/license.html b/plugins/help/content/license.html
index 9034d46f8..371dbffe1 100644
--- a/plugins/help/content/license.html
+++ b/plugins/help/content/license.html
@@ -655,7 +655,7 @@ the &ldquo;copyright&rdquo; line and a pointer to where the full notice is found
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
+ along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
</pre>
<p>Also add information on how to contact you by electronic and paper mail.</p>
diff --git a/plugins/help/help.php b/plugins/help/help.php
index 37fd908a3..4b11dceb3 100644
--- a/plugins/help/help.php
+++ b/plugins/help/help.php
@@ -1,10 +1,9 @@
<?php
/**
- * Roundcube Help Plugin
+ * Help Plugin
*
* @author Aleksander 'A.L.E.C' Machniak
- * @author Thomas Bruederli <thomas@roundcube.net>
* @license GNU GPLv3+
*
* Configuration (see config.inc.php.dist)
@@ -22,7 +21,8 @@ class help extends rcube_plugin
function init()
{
- $this->load_config();
+ $rcmail = rcmail::get_instance();
+
$this->add_texts('localization/', false);
// register task
@@ -33,8 +33,6 @@ class help extends rcube_plugin
$this->register_action('about', array($this, 'action'));
$this->register_action('license', array($this, 'action'));
- $rcmail = rcmail::get_instance();
-
// add taskbar button
$this->add_button(array(
'command' => 'help',
@@ -44,9 +42,6 @@ class help extends rcube_plugin
'label' => 'help.help',
), 'taskbar');
- $this->include_script('help.js');
- $rcmail->output->set_env('help_open_extwin', $rcmail->config->get('help_open_extwin', false), true);
-
// add style for taskbar button (must be here) and Help UI
$skin_path = $this->local_skin_path();
if (is_file($this->home . "/$skin_path/help.css")) {
@@ -58,10 +53,11 @@ class help extends rcube_plugin
{
$rcmail = rcmail::get_instance();
+ $this->load_config();
+
// register UI objects
$rcmail->output->add_handlers(array(
'helpcontent' => array($this, 'content'),
- 'tablink' => array($this, 'tablink'),
));
if ($rcmail->action == 'about')
@@ -74,52 +70,20 @@ class help extends rcube_plugin
$rcmail->output->send('help.help');
}
- function tablink($attrib)
- {
- $rcmail = rcmail::get_instance();
- $attrib['name'] = 'helplink' . $attrib['action'];
- $attrib['href'] = $rcmail->url(array('_action' => $attrib['action'], '_extwin' => !empty($_REQUEST['_extwin']) ? 1 : null));
- return $rcmail->output->button($attrib);
- }
-
function content($attrib)
{
$rcmail = rcmail::get_instance();
- switch ($rcmail->action) {
- case 'about':
- if (is_readable($this->home . '/content/about.html')) {
- return @file_get_contents($this->home . '/content/about.html');
- }
- $default = $rcmail->url(array('_task' => 'settings', '_action' => 'about', '_framed' => 1));
- $src = $rcmail->config->get('help_about_url', $default);
- break;
-
- case 'license':
- if (is_readable($this->home . '/content/license.html')) {
- return @file_get_contents($this->home . '/content/license.html');
- }
- $src = $rcmail->config->get('help_license_url', 'http://www.gnu.org/licenses/gpl-3.0-standalone.html');
- break;
-
- default:
- $src = $rcmail->config->get('help_source');
-
- // resolve task/action for depp linking
- $index_map = $rcmail->config->get('help_index_map', array());
- $rel = $_REQUEST['_rel'];
- list($task,$action) = explode('/', $rel);
- if ($add = $index_map[$rel])
- $src .= $add;
- else if ($add = $index_map[$task])
- $src .= $add;
- break;
+ if ($rcmail->action == 'about') {
+ return @file_get_contents($this->home.'/content/about.html');
+ }
+ else if ($rcmail->action == 'license') {
+ return @file_get_contents($this->home.'/content/license.html');
}
// default content: iframe
- if (!empty($src)) {
- $attrib['src'] = $this->resolve_language($src);
- }
+ if ($src = $rcmail->config->get('help_source'))
+ $attrib['src'] = $src;
if (empty($attrib['id']))
$attrib['id'] = 'rcmailhelpcontent';
@@ -129,13 +93,4 @@ class help extends rcube_plugin
return $rcmail->output->frame($attrib);
}
-
- private function resolve_language($path)
- {
- // resolve language placeholder
- $rcmail = rcmail::get_instance();
- $langmap = $rcmail->config->get('help_language_map', array('*' => 'en_US'));
- $lang = !empty($langmap[$_SESSION['language']]) ? $langmap[$_SESSION['language']] : $langmap['*'];
- return str_replace('%l', $lang, $path);
- }
}
diff --git a/plugins/help/localization/ar.inc b/plugins/help/localization/ar.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/ar.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/ast.inc b/plugins/help/localization/ast.inc
new file mode 100644
index 000000000..7e5e2874a
--- /dev/null
+++ b/plugins/help/localization/ast.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Ayuda';
+$labels['about'] = 'Tocante a';
+$labels['license'] = 'Llicencia';
+?>
diff --git a/plugins/help/localization/be_BE.inc b/plugins/help/localization/be_BE.inc
new file mode 100644
index 000000000..3bbb1db32
--- /dev/null
+++ b/plugins/help/localization/be_BE.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Дапамога';
+$labels['about'] = 'ÐпіÑанне';
+$labels['license'] = 'ЛіцÑнзіÑ';
+?>
diff --git a/plugins/help/localization/bg_BG.inc b/plugins/help/localization/bg_BG.inc
new file mode 100644
index 000000000..05a0aafab
--- /dev/null
+++ b/plugins/help/localization/bg_BG.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Помощ';
+$labels['about'] = 'ОтноÑно';
+$labels['license'] = 'Лиценз';
+?>
diff --git a/plugins/help/localization/bn_BD.inc b/plugins/help/localization/bn_BD.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/bn_BD.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/el_GR.inc b/plugins/help/localization/el_GR.inc
new file mode 100644
index 000000000..74be22bf1
--- /dev/null
+++ b/plugins/help/localization/el_GR.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Βοηθεια';
+$labels['about'] = 'Σχετικά';
+$labels['license'] = 'Άδεια χÏήσης';
+?>
diff --git a/plugins/help/localization/en_US.inc b/plugins/help/localization/en_US.inc
index b81f02fb9..cf6c0aaaf 100644
--- a/plugins/help/localization/en_US.inc
+++ b/plugins/help/localization/en_US.inc
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | plugins/help/localization/<lang>.inc |
+ | plugins/help/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Help plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/help/localization/es_AR.inc b/plugins/help/localization/es_AR.inc
new file mode 100644
index 000000000..5425367f4
--- /dev/null
+++ b/plugins/help/localization/es_AR.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Ayuda';
+$labels['about'] = 'Acerca de';
+$labels['license'] = 'Licencia';
+?>
diff --git a/plugins/help/localization/eu_ES.inc b/plugins/help/localization/eu_ES.inc
new file mode 100644
index 000000000..d6547c7da
--- /dev/null
+++ b/plugins/help/localization/eu_ES.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Laguntza';
+$labels['about'] = 'Honi buruz';
+$labels['license'] = 'Lizentzia';
+?>
diff --git a/plugins/help/localization/fa_AF.inc b/plugins/help/localization/fa_AF.inc
new file mode 100644
index 000000000..e9fac20c1
--- /dev/null
+++ b/plugins/help/localization/fa_AF.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'راهنما';
+$labels['about'] = 'درباره نرم اÙزار';
+$labels['license'] = 'حق نشر';
+?>
diff --git a/plugins/help/localization/gl_ES.inc b/plugins/help/localization/gl_ES.inc
index e3e9e36ca..432623751 100644
--- a/plugins/help/localization/gl_ES.inc
+++ b/plugins/help/localization/gl_ES.inc
@@ -19,6 +19,6 @@
$labels = array();
$labels['help'] = 'Axuda';
$labels['about'] = 'Acerca de';
-$labels['license'] = 'Licenza';
+$labels['license'] = 'Licencia';
?>
diff --git a/plugins/help/localization/hi_IN.inc b/plugins/help/localization/hi_IN.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/hi_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/ia.inc b/plugins/help/localization/ia.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/ia.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/lb_LU.inc b/plugins/help/localization/lb_LU.inc
index 0a7ec6eef..63d6aebdc 100644
--- a/plugins/help/localization/lb_LU.inc
+++ b/plugins/help/localization/lb_LU.inc
@@ -15,10 +15,7 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-help/
*/
-
-$labels = array();
$labels['help'] = 'Hëllef';
$labels['about'] = 'Iwwert';
$labels['license'] = 'Lizenz';
-
?>
diff --git a/plugins/help/localization/lv_LV.inc b/plugins/help/localization/lv_LV.inc
new file mode 100644
index 000000000..c3b15f0bc
--- /dev/null
+++ b/plugins/help/localization/lv_LV.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Palīdzība';
+$labels['about'] = 'Par';
+$labels['license'] = 'Licence';
+?>
diff --git a/plugins/help/localization/ml_IN.inc b/plugins/help/localization/ml_IN.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/ml_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/mn_MN.inc b/plugins/help/localization/mn_MN.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/mn_MN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/ms_MY.inc b/plugins/help/localization/ms_MY.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/ms_MY.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/my_MM.inc b/plugins/help/localization/my_MM.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/my_MM.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/nl_BE.inc b/plugins/help/localization/nl_BE.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/nl_BE.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/nqo.inc b/plugins/help/localization/nqo.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/nqo.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/om.inc b/plugins/help/localization/om.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/om.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/ro_RO.inc b/plugins/help/localization/ro_RO.inc
new file mode 100644
index 000000000..1706d0cea
--- /dev/null
+++ b/plugins/help/localization/ro_RO.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Ajutor';
+$labels['about'] = 'Despre';
+$labels['license'] = 'Licența';
+?>
diff --git a/plugins/help/localization/te_IN.inc b/plugins/help/localization/te_IN.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/te_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/th_TH.inc b/plugins/help/localization/th_TH.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/th_TH.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/ti.inc b/plugins/help/localization/ti.inc
new file mode 100644
index 000000000..5eccd5075
--- /dev/null
+++ b/plugins/help/localization/ti.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'መáˆáˆƒáˆª';
+$labels['about'] = 'ብዛዕባ';
+$labels['license'] = 'áቓድ';
+?>
diff --git a/plugins/help/localization/tzm.inc b/plugins/help/localization/tzm.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/tzm.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/localization/uk_UA.inc b/plugins/help/localization/uk_UA.inc
new file mode 100644
index 000000000..8d2f76c3c
--- /dev/null
+++ b/plugins/help/localization/uk_UA.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+$labels['help'] = 'Допомога';
+$labels['about'] = 'Про програму';
+$labels['license'] = 'ЛіцензіÑ';
+?>
diff --git a/plugins/help/localization/ur_PK.inc b/plugins/help/localization/ur_PK.inc
new file mode 100644
index 000000000..46160477e
--- /dev/null
+++ b/plugins/help/localization/ur_PK.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/help/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Help plugin |
+ | Copyright (C) 2012-2013, 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/plugin-help/
+*/
+?>
diff --git a/plugins/help/package.xml b/plugins/help/package.xml
index d39143ba1..889efd17d 100644
--- a/plugins/help/package.xml
+++ b/plugins/help/package.xml
@@ -5,7 +5,7 @@
http://pear.php.net/dtd/package-2.0.xsd">
<name>help</name>
<channel>pear.roundcube.net</channel>
- <summary>Online Help for Roundcube</summary>
+ <summary>Help for Roundcube</summary>
<description>Plugin adds a new item (Help) in taskbar.</description>
<lead>
<name>Aleksander Machniak</name>
@@ -13,10 +13,10 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
- <date>2013-07-03</date>
+ <date>2012-11-11</date>
<version>
- <release>1.4</release>
- <api>1.4</api>
+ <release>1.3</release>
+ <api>1.2</api>
</version>
<stability>
<release>stable</release>
@@ -31,6 +31,7 @@
<tasks:replace from="@package_version@" to="version" type="package-info"/>
</file>
<file name="config.inc.php.dist" role="data"></file>
+ <file name="content/about.html" role="data"></file>
<file name="content/license.html" role="data"></file>
<file name="localization/bs_BA.inc" role="data"></file>
<file name="localization/ca_ES.inc" role="data"></file>
diff --git a/plugins/help/skins/classic/help.css b/plugins/help/skins/classic/help.css
index c45b8f0b0..8f67f111e 100644
--- a/plugins/help/skins/classic/help.css
+++ b/plugins/help/skins/classic/help.css
@@ -5,23 +5,9 @@
background-image: url('help.gif');
}
-.extwin #tabsbar
-{
- top: 21px;
- left: 20px;
- right: 100px;
- border-bottom: 0;
-}
-
-.closelink {
- position: absolute;
- top: 20px;
- right: 20px;
-}
-
.help-box
{
- overflow: auto;
+ overflow: auto;
background-color: #F2F2F2;
}
diff --git a/plugins/help/skins/classic/templates/help.html b/plugins/help/skins/classic/templates/help.html
index 3d5b22869..2e430ecf3 100644
--- a/plugins/help/skins/classic/templates/help.html
+++ b/plugins/help/skins/classic/templates/help.html
@@ -7,28 +7,23 @@
<script type="text/javascript">
function help_init_settings_tabs()
{
- var action, tab = '#helptabindex';
+ var action, tab = '#helptabdefault';
if (window.rcmail && (action = rcmail.env.action)) {
- tab = '#helptab' + (action ? action : 'index');
+ tab = '#helptab' + (action ? action : 'default');
}
$(tab).addClass('tablink-selected');
}
</script>
</head>
-<roundcube:if condition="env:extwin" />
-<body class="extwin">
-<roundcube:object name="message" id="message" />
-<roundcube:button name="close" type="link" label="close" class="closelink" onclick="self.close()" />
-<roundcube:else />
<body>
+
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
-<roundcube:endif />
<div id="tabsbar">
-<span id="helptabindex" class="tablink"><roundcube:object name="tablink" action="index" type="link" label="help.help" title="help.help" /></span>
-<span id="helptababout" class="tablink"><roundcube:object name="tablink" action="about" type="link" label="help.about" title="help.about" class="tablink" /></span>
-<span id="helptablicense" class="tablink"><roundcube:object name="tablink" action="license" type="link" label="help.license" title="help.license" class="tablink" /></span>
+<span id="helptabdefault" class="tablink"><roundcube:button name="helpdefault" href="?_task=help" type="link" label="help.help" title="help.help" /></span>
+<span id="helptababout" class="tablink"><roundcube:button name="helpabout" href="?_task=help&_action=about" type="link" label="help.about" title="help.about" class="tablink" /></span>
+<span id="helptablicense" class="tablink"><roundcube:button name="helplicense" href="?_task=help&_action=license" type="link" label="help.license" title="help.license" class="tablink" /></span>
<roundcube:container name="helptabs" id="helptabsbar" />
<script type="text/javascript"> if (window.rcmail) rcmail.add_onload(help_init_settings_tabs);</script>
</div>
diff --git a/plugins/help/skins/larry/help.css b/plugins/help/skins/larry/help.css
index d9af6e15e..c2e369af6 100644
--- a/plugins/help/skins/larry/help.css
+++ b/plugins/help/skins/larry/help.css
@@ -39,6 +39,7 @@
background: url(help.png) center -130px no-repeat;
}
+.iframebox.help_about,
.iframebox.help_license {
overflow: auto;
}
diff --git a/plugins/help/skins/larry/templates/help.html b/plugins/help/skins/larry/templates/help.html
index bfd3f1141..39caaa62f 100644
--- a/plugins/help/skins/larry/templates/help.html
+++ b/plugins/help/skins/larry/templates/help.html
@@ -4,16 +4,16 @@
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
</head>
-<roundcube:if condition="env:extwin" /><body class="extwin"><roundcube:else /><body><roundcube:endif />
+<body>
<roundcube:include file="/includes/header.html" />
<div id="mainscreen">
<div id="helptoolbar" class="toolbar">
-<roundcube:object name="tablink" action="index" type="link" label="help.help" title="help.help" class="button help" />
-<roundcube:object name="tablink" action="about" type="link" label="help.about" title="help.about" class="button about" />
-<roundcube:object name="tablink" action="license" type="link" label="help.license" title="help.license" class="button license" />
+<roundcube:button name="helpdefault" href="?_task=help" type="link" label="help.help" title="help.help" class="button help" />
+<roundcube:button name="helpabout" href="?_task=help&amp;_action=about" type="link" label="help.about" title="help.about" class="button about" />
+<roundcube:button name="helplicense" href="?_task=help&amp;_action=license" type="link" label="help.license" title="help.license" class="button license" />
<roundcube:container name="helptabs" id="helptabsbar" />
</div>
diff --git a/plugins/hide_blockquote/hide_blockquote.php b/plugins/hide_blockquote/hide_blockquote.php
index 2ad5dd8ac..7af163dcd 100644
--- a/plugins/hide_blockquote/hide_blockquote.php
+++ b/plugins/hide_blockquote/hide_blockquote.php
@@ -8,7 +8,7 @@
* Configuration:
* // Minimum number of citation lines. Longer citation blocks will be hidden.
* // 0 - no limit (no hidding).
- * $config['hide_blockquote_limit'] = 0;
+ * $rcmail_config['hide_blockquote_limit'] = 0;
*
* @version @package_version@
* @license GNU GPLv3+
@@ -69,7 +69,7 @@ class hide_blockquote extends rcube_plugin
function save_prefs($args)
{
if ($args['section'] == 'mailview') {
- $args['prefs']['hide_blockquote_limit'] = (int) rcube_utils::get_input_value('_hide_blockquote_limit', rcube_utils::INPUT_POST);
+ $args['prefs']['hide_blockquote_limit'] = (int) get_input_value('_hide_blockquote_limit', RCUBE_INPUT_POST);
}
return $args;
diff --git a/plugins/hide_blockquote/localization/ar.inc b/plugins/hide_blockquote/localization/ar.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ar.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/ar_SA.inc b/plugins/hide_blockquote/localization/ar_SA.inc
new file mode 100644
index 000000000..30ade1397
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ar_SA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'إخÙاء';
+$labels['show'] = 'إظهار';
+?>
diff --git a/plugins/hide_blockquote/localization/be_BE.inc b/plugins/hide_blockquote/localization/be_BE.inc
new file mode 100644
index 000000000..28248adf0
--- /dev/null
+++ b/plugins/hide_blockquote/localization/be_BE.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Схаваць';
+$labels['show'] = 'Паказаць';
+$labels['quotelimit'] = 'Хаваць цытаванне, калі колькаÑць радкоў пераўзыходзіць';
+?>
diff --git a/plugins/hide_blockquote/localization/bg_BG.inc b/plugins/hide_blockquote/localization/bg_BG.inc
new file mode 100644
index 000000000..ec64513a8
--- /dev/null
+++ b/plugins/hide_blockquote/localization/bg_BG.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Скрий';
+$labels['show'] = 'Покажи';
+$labels['quotelimit'] = 'Скрива цитатите когато Ð±Ñ€Ð¾Ñ Ñ€ÐµÐ´Ð¾Ð²Ðµ е по-голÑм от';
+?>
diff --git a/plugins/hide_blockquote/localization/bn_BD.inc b/plugins/hide_blockquote/localization/bn_BD.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/bn_BD.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/el_GR.inc b/plugins/hide_blockquote/localization/el_GR.inc
new file mode 100644
index 000000000..a5572957a
--- /dev/null
+++ b/plugins/hide_blockquote/localization/el_GR.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'ΑποκÏυψη';
+$labels['show'] = 'Εμφάνιση';
+$labels['quotelimit'] = 'ΑπόκÏυψη παÏαπομπων όταν οι γÏαμμές μέτÏησης είναι μεγαλÏτεÏες από';
+?>
diff --git a/plugins/hide_blockquote/localization/en_US.inc b/plugins/hide_blockquote/localization/en_US.inc
index 90dd28955..c3a5ca019 100644
--- a/plugins/hide_blockquote/localization/en_US.inc
+++ b/plugins/hide_blockquote/localization/en_US.inc
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | plugins/hide_blockquote/localization/<lang>.inc |
+ | plugins/hide_blockquote/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Hide-Blockquote plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/hide_blockquote/localization/es_AR.inc b/plugins/hide_blockquote/localization/es_AR.inc
new file mode 100644
index 000000000..5046eaf69
--- /dev/null
+++ b/plugins/hide_blockquote/localization/es_AR.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Ocultar';
+$labels['show'] = 'Mostrar';
+$labels['quotelimit'] = 'Ocultar el mail citado cuando el número de líneas sea mayor que';
+?>
diff --git a/plugins/hide_blockquote/localization/eu_ES.inc b/plugins/hide_blockquote/localization/eu_ES.inc
new file mode 100644
index 000000000..f7adf6e00
--- /dev/null
+++ b/plugins/hide_blockquote/localization/eu_ES.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Ezkutatu';
+$labels['show'] = 'Erakutsi';
+$labels['quotelimit'] = 'Ezkutatu aipamena lerroen kopurua hau baino handiagoa denean';
+?>
diff --git a/plugins/hide_blockquote/localization/fa_AF.inc b/plugins/hide_blockquote/localization/fa_AF.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/fa_AF.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/fi_FI.inc b/plugins/hide_blockquote/localization/fi_FI.inc
index cb7c8aaa4..952149858 100644
--- a/plugins/hide_blockquote/localization/fi_FI.inc
+++ b/plugins/hide_blockquote/localization/fi_FI.inc
@@ -19,6 +19,6 @@
$labels = array();
$labels['hide'] = 'Piilota';
$labels['show'] = 'Näytä';
-$labels['quotelimit'] = 'Hide citation when lines count is greater than';
+$labels['quotelimit'] = 'Piilota lainaus rivejä ollessa enemmän kuin';
?>
diff --git a/plugins/hide_blockquote/localization/hi_IN.inc b/plugins/hide_blockquote/localization/hi_IN.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/hi_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/ia.inc b/plugins/hide_blockquote/localization/ia.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ia.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/lb_LU.inc b/plugins/hide_blockquote/localization/lb_LU.inc
index 98e0f6936..8f5a07df9 100644
--- a/plugins/hide_blockquote/localization/lb_LU.inc
+++ b/plugins/hide_blockquote/localization/lb_LU.inc
@@ -15,10 +15,7 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-hide_blockquote/
*/
-
-$labels = array();
$labels['hide'] = 'Verstoppen';
$labels['show'] = 'Weisen';
$labels['quotelimit'] = 'Zitat verstoppe wann d\'Zeilenunzuel méi grouss ass ewéi';
-
?>
diff --git a/plugins/hide_blockquote/localization/lv_LV.inc b/plugins/hide_blockquote/localization/lv_LV.inc
new file mode 100644
index 000000000..162deda8b
--- /dev/null
+++ b/plugins/hide_blockquote/localization/lv_LV.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Slēpt';
+$labels['show'] = 'RÄdÄ«t';
+$labels['quotelimit'] = 'SlÄ“pt citÄtu kad lÄ«niju skaits ir lielÄks kÄ';
+?>
diff --git a/plugins/hide_blockquote/localization/ml_IN.inc b/plugins/hide_blockquote/localization/ml_IN.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ml_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/mn_MN.inc b/plugins/hide_blockquote/localization/mn_MN.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/mn_MN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/ms_MY.inc b/plugins/hide_blockquote/localization/ms_MY.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ms_MY.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/my_MM.inc b/plugins/hide_blockquote/localization/my_MM.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/my_MM.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/nl_BE.inc b/plugins/hide_blockquote/localization/nl_BE.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/nl_BE.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/nqo.inc b/plugins/hide_blockquote/localization/nqo.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/nqo.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/om.inc b/plugins/hide_blockquote/localization/om.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/om.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/ro_RO.inc b/plugins/hide_blockquote/localization/ro_RO.inc
new file mode 100644
index 000000000..978b84a90
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ro_RO.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Ascunde';
+$labels['show'] = 'Afișează';
+$labels['quotelimit'] = 'Ascunde citațiile dacă numărul de linii este mai mare ca';
+?>
diff --git a/plugins/hide_blockquote/localization/te_IN.inc b/plugins/hide_blockquote/localization/te_IN.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/te_IN.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/th_TH.inc b/plugins/hide_blockquote/localization/th_TH.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/th_TH.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/ti.inc b/plugins/hide_blockquote/localization/ti.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ti.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/tzm.inc b/plugins/hide_blockquote/localization/tzm.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/tzm.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/hide_blockquote/localization/uk_UA.inc b/plugins/hide_blockquote/localization/uk_UA.inc
new file mode 100644
index 000000000..a8dd54144
--- /dev/null
+++ b/plugins/hide_blockquote/localization/uk_UA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+$labels['hide'] = 'Приховати';
+$labels['show'] = 'Показати';
+?>
diff --git a/plugins/hide_blockquote/localization/ur_PK.inc b/plugins/hide_blockquote/localization/ur_PK.inc
new file mode 100644
index 000000000..83c0e3cb6
--- /dev/null
+++ b/plugins/hide_blockquote/localization/ur_PK.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/hide_blockquote/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Hide-Blockquote plugin |
+ | Copyright (C) 2012-2013, 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/plugin-hide_blockquote/
+*/
+?>
diff --git a/plugins/http_authentication/config.inc.php.dist b/plugins/http_authentication/config.inc.php.dist
index 0940dee1f..0d798a586 100644
--- a/plugins/http_authentication/config.inc.php.dist
+++ b/plugins/http_authentication/config.inc.php.dist
@@ -5,5 +5,5 @@
// Default mail host to log-in using user/password from HTTP Authentication.
// This is useful if the users are free to choose arbitrary mail hosts (or
// from a list), but have one host they usually want to log into.
-// Unlike $config['default_host'] this must be a string!
-$config['http_authentication_host'] = '';
+// Unlike $rcmail_config['default_host'] this must be a string!
+$rcmail_config['http_authentication_host'] = '';
diff --git a/plugins/http_authentication/http_authentication.php b/plugins/http_authentication/http_authentication.php
index d86e1791c..a94b6121a 100644
--- a/plugins/http_authentication/http_authentication.php
+++ b/plugins/http_authentication/http_authentication.php
@@ -7,7 +7,7 @@
*
* Configuration:
* // redirect the client to this URL after logout. This page is then responsible to clear HTTP auth
- * $config['logout_url'] = 'http://server.tld/logout.html';
+ * $rcmail_config['logout_url'] = 'http://server.tld/logout.html';
*
* See logout.html (in this directory) for an example how HTTP auth can be cleared.
*
@@ -52,8 +52,8 @@ class http_authentication extends rcube_plugin
$this->load_config();
$host = rcmail::get_instance()->config->get('http_authentication_host');
- if (is_string($host) && trim($host) !== '' && empty($args['host']))
- $args['host'] = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
+ if (is_string($host) && trim($host) !== '')
+ $args['host'] = rcube_idn_to_ascii(rcube_parse_host($host));
// Allow entering other user data in login form,
// e.g. after log out (#1487953)
diff --git a/plugins/jqueryui/config.inc.php.dist b/plugins/jqueryui/config.inc.php.dist
index 8e111e0e1..a3c3f75a0 100644
--- a/plugins/jqueryui/config.inc.php.dist
+++ b/plugins/jqueryui/config.inc.php.dist
@@ -1,10 +1,10 @@
<?php
// if you want to load localization strings for specific sub-libraries of jquery-ui, configure them here
-$config['jquery_ui_i18n'] = array('datepicker');
+$rcmail_config['jquery_ui_i18n'] = array('datepicker');
// map Roundcube skins with jquery-ui themes here
-$config['jquery_ui_skin_map'] = array(
+$rcmail_config['jquery_ui_skin_map'] = array(
'larry' => 'larry',
'default' => 'larry',
'groupvice4' => 'redmond',
diff --git a/plugins/jqueryui/jqueryui.php b/plugins/jqueryui/jqueryui.php
index e9b3c215e..db640d1aa 100644
--- a/plugins/jqueryui/jqueryui.php
+++ b/plugins/jqueryui/jqueryui.php
@@ -8,7 +8,6 @@
* @version 1.9.1
* @author Cor Bosman <roundcube@wa.ter.net>
* @author Thomas Bruederli <roundcube@gmail.com>
- * @license GNU GPLv3+
*/
class jqueryui extends rcube_plugin
{
diff --git a/plugins/jqueryui/js/i18n/jquery-ui-i18n.js b/plugins/jqueryui/js/i18n/jquery-ui-i18n.js
index e8acb16ea..e8acb16ea 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery-ui-i18n.js
+++ b/plugins/jqueryui/js/i18n/jquery-ui-i18n.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-af.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-af.js
index 0922ef7a1..0922ef7a1 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-af.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-af.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar-DZ.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar-DZ.js
index 7b175af40..7b175af40 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar-DZ.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar-DZ.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar.js
index cef0f08fd..cef0f08fd 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-az.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-az.js
index a133a9eb2..a133a9eb2 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-az.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-az.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bg.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bg.js
index 86ab88582..86ab88582 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bg.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bg.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bs.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bs.js
index f08870ffe..f08870ffe 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bs.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-bs.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ca.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ca.js
index a10b549c2..a10b549c2 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ca.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ca.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cs.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cs.js
index b96b1a51c..b96b1a51c 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cs.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cs.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cy-GB.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cy-GB.js
index cf3a38e6c..cf3a38e6c 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cy-GB.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-cy-GB.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-da.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-da.js
index 7e42948b3..7e42948b3 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-da.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-da.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-de.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-de.js
index cfe91759b..cfe91759b 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-de.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-de.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-el.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-el.js
index 1ac47561a..1ac47561a 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-el.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-el.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-AU.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-AU.js
index c1a1020a1..c1a1020a1 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-AU.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-AU.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-GB.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-GB.js
index 16a096e75..16a096e75 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-GB.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-GB.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-NZ.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-NZ.js
index 7819df052..7819df052 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-NZ.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-NZ.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eo.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eo.js
index 39e44fc57..39e44fc57 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eo.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eo.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-es.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-es.js
index 97a2d6ead..97a2d6ead 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-es.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-es.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-et.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-et.js
index 62cbea8fa..62cbea8fa 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-et.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-et.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eu.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eu.js
index a71db2c72..a71db2c72 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eu.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-eu.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fa.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fa.js
index bb957f6d8..bb957f6d8 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fa.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fa.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fi.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fi.js
index bd6d99498..bd6d99498 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fi.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fi.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fo.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fo.js
index 9c848a04b..9c848a04b 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fo.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fo.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr-CH.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr-CH.js
index e574537b0..e574537b0 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr-CH.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr-CH.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr.js
index 934afd1d0..934afd1d0 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-gl.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-gl.js
index 59b989a6d..59b989a6d 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-gl.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-gl.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-he.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-he.js
index b9e8deec5..b9e8deec5 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-he.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-he.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hi.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hi.js
index 6c563b997..6c563b997 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hi.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hi.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hr.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hr.js
index 2fe37b64b..2fe37b64b 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hr.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hr.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hu.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hu.js
index b28c268c1..b28c268c1 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hu.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hu.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hy.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hy.js
index 6d4eca555..6d4eca555 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hy.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-hy.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-id.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-id.js
index 6327fa60c..6327fa60c 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-id.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-id.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-is.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-is.js
index 925341a7a..925341a7a 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-is.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-is.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-it.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-it.js
index a01f043f8..a01f043f8 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-it.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-it.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ja.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ja.js
index 4d0b63c77..4d0b63c77 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ja.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ja.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ka.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ka.js
index c10658d79..c10658d79 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ka.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ka.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-kk.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-kk.js
index dcd6a65df..dcd6a65df 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-kk.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-kk.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-km.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-km.js
index f9c4e3a02..f9c4e3a02 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-km.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-km.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ko.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ko.js
index af36f3d6b..af36f3d6b 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ko.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ko.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lb.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lb.js
index 87c79d594..87c79d594 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lb.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lb.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lt.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lt.js
index 1afaaac5d..1afaaac5d 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lt.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lt.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lv.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lv.js
index 28cc102fc..28cc102fc 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lv.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-lv.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-mk.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-mk.js
index 028532551..028532551 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-mk.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-mk.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ml.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ml.js
index 9b8f460db..9b8f460db 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ml.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ml.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ms.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ms.js
index e70de7299..e70de7299 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ms.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ms.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl-BE.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl-BE.js
index 7b3cdf425..7b3cdf425 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl-BE.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl-BE.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl.js
index 203f16069..203f16069 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-no.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-no.js
index d36e430be..d36e430be 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-no.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-no.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pl.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pl.js
index 0ffc515b9..0ffc515b9 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pl.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pl.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt-BR.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt-BR.js
index 521967ec3..521967ec3 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt-BR.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt-BR.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt.js
index 999f20e3e..999f20e3e 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-rm.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-rm.js
index 22ed21685..22ed21685 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-rm.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-rm.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ro.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ro.js
index a988270d7..a988270d7 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ro.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ro.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js
index a51971405..a51971405 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sk.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sk.js
index 83ae8e811..83ae8e811 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sk.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sk.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sl.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sl.js
index 048a47af7..048a47af7 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sl.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sl.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sq.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sq.js
index d6086a789..d6086a789 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sq.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sq.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr-SR.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr-SR.js
index 6d5d04211..6d5d04211 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr-SR.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr-SR.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr.js
index d4e1d9af0..d4e1d9af0 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sv.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sv.js
index cbb5ad135..cbb5ad135 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sv.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-sv.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ta.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ta.js
index 40431ed8e..40431ed8e 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ta.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ta.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-th.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-th.js
index aecfd27cc..aecfd27cc 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-th.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-th.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tj.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tj.js
index 9a20e4d37..9a20e4d37 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tj.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tj.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tr.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tr.js
index 75b583a77..75b583a77 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tr.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-tr.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-uk.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-uk.js
index 2bdc82ff7..2bdc82ff7 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-uk.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-uk.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-vi.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-vi.js
index b49e7eb13..b49e7eb13 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-vi.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-vi.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-CN.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-CN.js
index d337e4a99..d337e4a99 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-CN.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-CN.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-HK.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-HK.js
index ef6f4e715..ef6f4e715 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-HK.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-HK.js
diff --git a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-TW.js b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-TW.js
index b9105ea50..b9105ea50 100755..100644
--- a/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-TW.js
+++ b/plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-TW.js
diff --git a/plugins/jqueryui/js/jquery-ui-1.9.1.custom.min.js b/plugins/jqueryui/js/jquery-ui-1.9.1.custom.min.js
index aa7a923e7..aa7a923e7 100755..100644
--- a/plugins/jqueryui/js/jquery-ui-1.9.1.custom.min.js
+++ b/plugins/jqueryui/js/jquery-ui-1.9.1.custom.min.js
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_flat_0_aaaaaa_40x100.png b/plugins/jqueryui/themes/classic/images/ui-bg_flat_0_aaaaaa_40x100.png
index 5b5dab2ab..5b5dab2ab 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_flat_0_aaaaaa_40x100.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_flat_75_ffffff_40x100.png b/plugins/jqueryui/themes/classic/images/ui-bg_flat_75_ffffff_40x100.png
index ac8b229af..ac8b229af 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_flat_75_ffffff_40x100.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_flat_90_cc3333_40x100.png b/plugins/jqueryui/themes/classic/images/ui-bg_flat_90_cc3333_40x100.png
index 6a5d37d65..6a5d37d65 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_flat_90_cc3333_40x100.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_flat_90_cc3333_40x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_glass_95_fef1ec_1x400.png b/plugins/jqueryui/themes/classic/images/ui-bg_glass_95_fef1ec_1x400.png
index 4443fdc1a..4443fdc1a 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_glass_95_fef1ec_1x400.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_a3a3a3_1x100.png b/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_a3a3a3_1x100.png
index b3533aafe..b3533aafe 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_a3a3a3_1x100.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_a3a3a3_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_e6e6e7_1x100.png b/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_e6e6e7_1x100.png
index d0a127f4d..d0a127f4d 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_e6e6e7_1x100.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_e6e6e7_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_f4f4f4_1x100.png b/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_f4f4f4_1x100.png
index ecc0ac16a..ecc0ac16a 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_f4f4f4_1x100.png
+++ b/plugins/jqueryui/themes/classic/images/ui-bg_highlight-hard_90_f4f4f4_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-icons_000000_256x240.png b/plugins/jqueryui/themes/classic/images/ui-icons_000000_256x240.png
index 7c211aa08..7c211aa08 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-icons_000000_256x240.png
+++ b/plugins/jqueryui/themes/classic/images/ui-icons_000000_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-icons_333333_256x240.png b/plugins/jqueryui/themes/classic/images/ui-icons_333333_256x240.png
index fe079a595..fe079a595 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-icons_333333_256x240.png
+++ b/plugins/jqueryui/themes/classic/images/ui-icons_333333_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-icons_666666_256x240.png b/plugins/jqueryui/themes/classic/images/ui-icons_666666_256x240.png
index f87de1ca1..f87de1ca1 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-icons_666666_256x240.png
+++ b/plugins/jqueryui/themes/classic/images/ui-icons_666666_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-icons_cc3333_256x240.png b/plugins/jqueryui/themes/classic/images/ui-icons_cc3333_256x240.png
index b2fe02927..b2fe02927 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-icons_cc3333_256x240.png
+++ b/plugins/jqueryui/themes/classic/images/ui-icons_cc3333_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/images/ui-icons_dddddd_256x240.png b/plugins/jqueryui/themes/classic/images/ui-icons_dddddd_256x240.png
index 91aada0ab..91aada0ab 100755..100644
--- a/plugins/jqueryui/themes/classic/images/ui-icons_dddddd_256x240.png
+++ b/plugins/jqueryui/themes/classic/images/ui-icons_dddddd_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/classic/jquery-ui-1.9.1.custom.css b/plugins/jqueryui/themes/classic/jquery-ui-1.9.1.custom.css
index 1002a95fe..1002a95fe 100755..100644
--- a/plugins/jqueryui/themes/classic/jquery-ui-1.9.1.custom.css
+++ b/plugins/jqueryui/themes/classic/jquery-ui-1.9.1.custom.css
diff --git a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_55_b0ccd7_1x100.png b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_55_b0ccd7_1x100.png
index 04f19af52..04f19af52 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_55_b0ccd7_1x100.png
+++ b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_55_b0ccd7_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_65_ffffff_1x100.png b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_65_ffffff_1x100.png
index eaa8cfa3c..eaa8cfa3c 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_65_ffffff_1x100.png
+++ b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_65_ffffff_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_eaeaea_1x100.png b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_eaeaea_1x100.png
index 3231591bd..3231591bd 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_eaeaea_1x100.png
+++ b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_eaeaea_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_f8f8f8_1x100.png b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_f8f8f8_1x100.png
index e2286450a..e2286450a 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_f8f8f8_1x100.png
+++ b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-hard_75_f8f8f8_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_75_fafafa_1x100.png b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_75_fafafa_1x100.png
index a13a9720f..a13a9720f 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_75_fafafa_1x100.png
+++ b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_75_fafafa_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_90_e4e4e4_1x100.png b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_90_e4e4e4_1x100.png
index 675c05118..675c05118 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_90_e4e4e4_1x100.png
+++ b/plugins/jqueryui/themes/larry/images/ui-bg_highlight-soft_90_e4e4e4_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-icons_004458_256x240.png b/plugins/jqueryui/themes/larry/images/ui-icons_004458_256x240.png
index 083a564f0..083a564f0 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-icons_004458_256x240.png
+++ b/plugins/jqueryui/themes/larry/images/ui-icons_004458_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/images/ui-icons_d7211e_256x240.png b/plugins/jqueryui/themes/larry/images/ui-icons_d7211e_256x240.png
index fdc2c494f..fdc2c494f 100755..100644
--- a/plugins/jqueryui/themes/larry/images/ui-icons_d7211e_256x240.png
+++ b/plugins/jqueryui/themes/larry/images/ui-icons_d7211e_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/larry/jquery-ui-1.9.1.custom.css b/plugins/jqueryui/themes/larry/jquery-ui-1.9.1.custom.css
index 01afcac0d..01afcac0d 100755..100644
--- a/plugins/jqueryui/themes/larry/jquery-ui-1.9.1.custom.css
+++ b/plugins/jqueryui/themes/larry/jquery-ui-1.9.1.custom.css
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png b/plugins/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
index 5b5dab2ab..5b5dab2ab 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.png b/plugins/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.png
index 47acaadd7..47acaadd7 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png b/plugins/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
index 9d149b1c6..9d149b1c6 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.png b/plugins/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.png
index 014951529..014951529 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.png b/plugins/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.png
index 4443fdc1a..4443fdc1a 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/plugins/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
index 81ecc362d..81ecc362d 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png b/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
index 4f3faf8aa..4f3faf8aa 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
index 38c38335d..38c38335d 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.png
index 6f4bd87c0..6f4bd87c0 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.png
index 09d1cdc85..09d1cdc85 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.png
index bd2cf079a..bd2cf079a 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.png
index 9f3eafaab..9f3eafaab 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.png
index 2ab019b73..2ab019b73 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.png
index ad2dc6f9d..ad2dc6f9d 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.png b/plugins/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.png
index 78625024d..78625024d 100755..100644
--- a/plugins/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.png
+++ b/plugins/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.png
Binary files differ
diff --git a/plugins/jqueryui/themes/redmond/jquery-ui-1.9.1.custom.css b/plugins/jqueryui/themes/redmond/jquery-ui-1.9.1.custom.css
index 614420add..614420add 100755..100644
--- a/plugins/jqueryui/themes/redmond/jquery-ui-1.9.1.custom.css
+++ b/plugins/jqueryui/themes/redmond/jquery-ui-1.9.1.custom.css
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/managesieve/Changelog b/plugins/managesieve/Changelog
index e660ee1ee..159cc3ef9 100644
--- a/plugins/managesieve/Changelog
+++ b/plugins/managesieve/Changelog
@@ -1,13 +1,4 @@
-* version 7.0 [2013-09-09]
------------------------------------------------------------
-- Add vacation-seconds extension support (RFC 6131)
-- Several script parser code improvements
-- Support string list arguments in filter form (#1489018)
-- Support date, currendate and index tests - RFC5260 (#1488120)
-- Split plugin file into two files
- Fix handling of &, <, > characters in scripts/filter names (#1489208)
-- Support 'keep' action (#1489226)
-- Add common headers to header selector (#1489271)
* version 6.2 [2013-02-17]
-----------------------------------------------------------
@@ -214,18 +205,18 @@
- Added it_IT localization
* version 1.1 [2009-05-27]
------------------------------------------------------------
+-----------------------------------------------------------
- Added new icons
- Added support for headers lists (coma-separated) in rules
- Added de_CH localization
* version 1.0 [2009-05-21]
------------------------------------------------------------
+-----------------------------------------------------------
- Rewritten using plugin API
- Added hu_HU localization (Tamas Tevesz)
* version beta7 (svn-r2300) [2009-03-01]
------------------------------------------------------------
+-----------------------------------------------------------
- Added SquirrelMail script auto-import (Jonathan Ernst)
- Added 'vacation' support (Jonathan Ernst & alec)
- Added 'stop' support (Jonathan Ernst)
@@ -234,47 +225,47 @@
- Small style fixes
* version 0.2-stable1 (svn-r2205) [2009-01-03]
------------------------------------------------------------
+-----------------------------------------------------------
- Fix moving down filter row
- Fixes for compressed js files in stable release package
- Created patch for svn version r2205
* version 0.2-stable [2008-12-31]
------------------------------------------------------------
+-----------------------------------------------------------
- Added ru_RU, fr_FR, zh_CN translation
- Fixes for Roundcube 0.2-stable
-* version 0.2-beta [2008-09-21]
------------------------------------------------------------
+* version rc0.2beta [2008-09-21]
+-----------------------------------------------------------
- Small css fixes for IE
- Fixes for Roundcube 0.2-beta
* version beta6 [2008-08-08]
------------------------------------------------------------
+-----------------------------------------------------------
- Added de_DE translation
- Fix for Roundcube r1634
* version beta5 [2008-06-10]
------------------------------------------------------------
+-----------------------------------------------------------
- Fixed 'exists' operators
- Fixed 'not*' operators for custom headers
- Fixed filters deleting
* version beta4 [2008-06-09]
------------------------------------------------------------
+-----------------------------------------------------------
- Fix for Roundcube r1490
* version beta3 [2008-05-22]
------------------------------------------------------------
+-----------------------------------------------------------
- Fixed textarea error class setting
- Added pagetitle setting
- Added option 'managesieve_replace_delimiter'
- Fixed errors on IE (still need some css fixes)
-
+
* version beta2 [2008-05-20]
------------------------------------------------------------
+-----------------------------------------------------------
- Use 'if' only for first filter and 'elsif' for the rest
* version beta1 [2008-05-15]
------------------------------------------------------------
+-----------------------------------------------------------
- Initial version for Roundcube r1388.
diff --git a/plugins/managesieve/config.inc.php.dist b/plugins/managesieve/config.inc.php.dist
index cb56a0efd..65dbcfc4e 100644
--- a/plugins/managesieve/config.inc.php.dist
+++ b/plugins/managesieve/config.inc.php.dist
@@ -2,7 +2,7 @@
// managesieve server port. When empty the port will be determined automatically
// using getservbyname() function, with 4190 as a fallback.
-$config['managesieve_port'] = null;
+$rcmail_config['managesieve_port'] = null;
// managesieve server address, default is localhost.
// Replacement variables supported in host name:
@@ -10,58 +10,58 @@ $config['managesieve_port'] = null;
// %n - http hostname ($_SERVER['SERVER_NAME'])
// %d - domain (http hostname without the first part)
// For example %n = mail.domain.tld, %d = domain.tld
-$config['managesieve_host'] = 'localhost';
+$rcmail_config['managesieve_host'] = 'localhost';
// authentication method. Can be CRAM-MD5, DIGEST-MD5, PLAIN, LOGIN, EXTERNAL
// or none. Optional, defaults to best method supported by server.
-$config['managesieve_auth_type'] = null;
+$rcmail_config['managesieve_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.
-$config['managesieve_auth_cid'] = null;
+$rcmail_config['managesieve_auth_cid'] = null;
// Optional managesieve authentication password to be used for imap_auth_cid
-$config['managesieve_auth_pw'] = null;
+$rcmail_config['managesieve_auth_pw'] = null;
// use or not TLS for managesieve server connection
// Note: tls:// prefix in managesieve_host is also supported
-$config['managesieve_usetls'] = false;
+$rcmail_config['managesieve_usetls'] = false;
// default contents of filters script (eg. default spam filter)
-$config['managesieve_default'] = '/etc/dovecot/sieve/global';
+$rcmail_config['managesieve_default'] = '/etc/dovecot/sieve/global';
// The name of the script which will be used when there's no user script
-$config['managesieve_script_name'] = 'managesieve';
+$rcmail_config['managesieve_script_name'] = 'managesieve';
// Sieve RFC says that we should use UTF-8 endcoding for mailbox names,
// but some implementations does not covert UTF-8 to modified UTF-7.
// Defaults to UTF7-IMAP
-$config['managesieve_mbox_encoding'] = 'UTF-8';
+$rcmail_config['managesieve_mbox_encoding'] = 'UTF-8';
// I need this because my dovecot (with listescape plugin) uses
// ':' delimiter, but creates folders with dot delimiter
-$config['managesieve_replace_delimiter'] = '';
+$rcmail_config['managesieve_replace_delimiter'] = '';
// disabled sieve extensions (body, copy, date, editheader, encoded-character,
// envelope, environment, ereject, fileinto, ihave, imap4flags, index,
// mailbox, mboxmetadata, regex, reject, relational, servermetadata,
// spamtest, spamtestplus, subaddress, vacation, variables, virustest, etc.
// Note: not all extensions are implemented
-$config['managesieve_disabled_extensions'] = array();
+$rcmail_config['managesieve_disabled_extensions'] = array();
// Enables debugging of conversation with sieve server. Logs it into <log_dir>/sieve
-$config['managesieve_debug'] = false;
+$rcmail_config['managesieve_debug'] = false;
// Enables features described in http://wiki.kolab.org/KEP:14
-$config['managesieve_kolab_master'] = false;
+$rcmail_config['managesieve_kolab_master'] = false;
// Script name extension used for scripts including. Dovecot uses '.sieve',
// Cyrus uses '.siv'. Doesn't matter if you have managesieve_kolab_master disabled.
-$config['managesieve_filename_extension'] = '.sieve';
+$rcmail_config['managesieve_filename_extension'] = '.sieve';
// List of reserved script names (without extension).
// Scripts listed here will be not presented to the user.
-$config['managesieve_filename_exceptions'] = array();
+$rcmail_config['managesieve_filename_exceptions'] = array();
?>
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve.php b/plugins/managesieve/lib/Roundcube/rcube_sieve.php
index 3bd2978da..4f66bf029 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve.php
@@ -6,18 +6,18 @@
* Copyright (C) 2008-2011, The Roundcube Dev Team
* Copyright (C) 2011, Kolab Systems AG
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// Managesieve Protocol: RFC5804
@@ -84,7 +84,7 @@ class rcube_sieve
return $this->_set_error(SIEVE_ERROR_LOGIN);
}
- $this->exts = $this->get_extensions();
+ $this->exts = $this->get_extensions();
// disable features by config
if (!empty($disabled)) {
@@ -379,6 +379,6 @@ class rcube_sieve
*/
public function debug_handler(&$sieve, $message)
{
- rcube::write_log('sieve', preg_replace('/\r\n$/', '', $message));
+ write_log('sieve', preg_replace('/\r\n$/', '', $message));
}
}
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
index e4efef5b3..6c9f8048a 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -535,6 +535,7 @@ class rcube_sieve_engine
$act_types = rcube_utils::get_input_value('_action_type', rcube_utils::INPUT_POST, true);
$mailboxes = rcube_utils::get_input_value('_action_mailbox', rcube_utils::INPUT_POST, true);
$act_targets = rcube_utils::get_input_value('_action_target', rcube_utils::INPUT_POST, true);
+ $domain_targets = rcube_utils::get_input_value('_action_target_domain', rcube_utils::INPUT_POST);
$area_targets = rcube_utils::get_input_value('_action_target_area', rcube_utils::INPUT_POST, true);
$reasons = rcube_utils::get_input_value('_action_reason', rcube_utils::INPUT_POST, true);
$addresses = rcube_utils::get_input_value('_action_addresses', rcube_utils::INPUT_POST, true);
@@ -622,7 +623,21 @@ class rcube_sieve_engine
if (!count($target)) {
$this->errors['tests'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
}
- else if ($type != 'regex' && $type != 'matches') {
+ else if (strpos($type, 'count-') === 0) {
+ foreach ($target as $arg) {
+ if (preg_match('/[^0-9]/', $arg)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('forbiddenchars');
+ }
+ }
+ }
+ else if (strpos($type, 'value-') === 0) {
+ // Some date/time formats do not support i;ascii-numeric comparator
+ if ($comparator == 'i;ascii-numeric' && in_array($datepart, array('date', 'time', 'iso8601', 'std11'))) {
+ $comparator = '';
+ }
+ }
+
+ if (!preg_match('/^(regex|matches|count-)/', $type) && count($target)) {
foreach ($target as $arg) {
if (!$this->validate_date_part($datepart, $arg)) {
$this->errors['tests'][$i]['target'] = $this->plugin->gettext('invaliddateformat');
@@ -668,7 +683,21 @@ class rcube_sieve_engine
if (!count($target)) {
$this->errors['tests'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
}
- else if ($type != 'regex' && $type != 'matches') {
+ else if (strpos($type, 'count-') === 0) {
+ foreach ($target as $arg) {
+ if (preg_match('/[^0-9]/', $arg)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('forbiddenchars');
+ }
+ }
+ }
+ else if (strpos($type, 'value-') === 0) {
+ // Some date/time formats do not support i;ascii-numeric comparator
+ if ($comparator == 'i;ascii-numeric' && in_array($datepart, array('date', 'time', 'iso8601', 'std11'))) {
+ $comparator = '';
+ }
+ }
+
+ if (count($target) && !preg_match('/^(regex|matches|count-)/', $type)) {
foreach ($target as $arg) {
if (!$this->validate_date_part($datepart, $arg)) {
$this->errors['tests'][$i]['target'] = $this->plugin->gettext('invaliddateformat');
@@ -699,7 +728,7 @@ class rcube_sieve_engine
}
else if (preg_match('/^(value|count)-/', $type)) {
foreach ($target as $target_value) {
- if (!preg_match('/[0-9]+/', $target_value)) {
+ if (preg_match('/[^0-9]/', $target_value)) {
$this->errors['tests'][$i]['target'] = $this->plugin->gettext('forbiddenchars');
}
}
@@ -781,7 +810,7 @@ class rcube_sieve_engine
}
else if (preg_match('/^(value|count)-/', $type)) {
foreach ($target as $target_value) {
- if (!preg_match('/[0-9]+/', $target_value)) {
+ if (preg_match('/[^0-9]/', $target_value)) {
$this->errors['tests'][$i]['target'] = $this->plugin->gettext('forbiddenchars');
}
}
@@ -794,9 +823,6 @@ class rcube_sieve_engine
}
if ($header != 'size' && $comparator) {
- if (preg_match('/^(value|count)/', $this->form['tests'][$i]['type']))
- $comparator = 'i;ascii-numeric';
-
$this->form['tests'][$i]['comparator'] = $comparator;
}
@@ -806,16 +832,15 @@ class rcube_sieve_engine
$i = 0;
// actions
- foreach($act_types as $idx => $type) {
- $type = $this->strip_value($type);
- $target = $this->strip_value($act_targets[$idx]);
+ foreach ($act_types as $idx => $type) {
+ $type = $this->strip_value($type);
switch ($type) {
-
case 'fileinto':
case 'fileinto_copy':
$mailbox = $this->strip_value($mailboxes[$idx], false, false);
$this->form['actions'][$i]['target'] = $this->mod_mailbox($mailbox, 'in');
+
if ($type == 'fileinto_copy') {
$type = 'fileinto';
$this->form['actions'][$i]['copy'] = true;
@@ -833,17 +858,31 @@ class rcube_sieve_engine
case 'redirect':
case 'redirect_copy':
+ $target = $this->strip_value($act_targets[$idx]);
+ $domain = $this->strip_value($domain_targets[$idx]);
+
+ // force one of the configured domains
+ $domains = (array) $this->rc->config->get('managesieve_domains');
+ if (!empty($domains) && !empty($target)) {
+ if (!$domain || !in_array($domain, $domains)) {
+ $domain = $domains[0];
+ }
+
+ $target .= '@' . $domain;
+ }
+
$this->form['actions'][$i]['target'] = $target;
- if ($this->form['actions'][$i]['target'] == '')
+ if ($target == '')
$this->errors['actions'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
- else if (!rcube_utils::check_email($this->form['actions'][$i]['target']))
- $this->errors['actions'][$i]['target'] = $this->plugin->gettext('noemailwarning');
+ else if (!rcube_utils::check_email($target))
+ $this->errors['actions'][$i]['target'] = $this->plugin->gettext(!empty($domains) ? 'forbiddenchars' : 'noemailwarning');
if ($type == 'redirect_copy') {
$type = 'redirect';
$this->form['actions'][$i]['copy'] = true;
}
+
break;
case 'addflag':
@@ -864,6 +903,7 @@ class rcube_sieve_engine
case 'vacation':
$reason = $this->strip_value($reasons[$idx]);
$interval_type = $interval_types[$idx] == 'seconds' ? 'seconds' : 'days';
+
$this->form['actions'][$i]['reason'] = str_replace("\r\n", "\n", $reason);
$this->form['actions'][$i]['subject'] = $subject[$idx];
$this->form['actions'][$i]['addresses'] = array_shift($addresses);
@@ -871,7 +911,12 @@ class rcube_sieve_engine
// @TODO: vacation :mime, :from, :handle
foreach ((array)$this->form['actions'][$i]['addresses'] as $aidx => $address) {
- if (!rcube_utils::check_email($address)) {
+ $this->form['actions'][$i]['addresses'][$aidx] = $address = trim($address);
+
+ if (empty($address)) {
+ unset($this->form['actions'][$i]['addresses'][$aidx]);
+ }
+ else if (!rcube_utils::check_email($address)) {
$this->errors['actions'][$i]['addresses'] = $this->plugin->gettext('noemailwarning');
break;
}
@@ -1354,22 +1399,6 @@ class rcube_sieve_engine
$select_op->add(rcube::Q($this->plugin->gettext('valuenotequals')), 'value-ne');
}
- // (current)date part select
- if (in_array('date', $this->exts) || in_array('currentdate', $this->exts)) {
- $date_parts = array('date', 'iso8601', 'std11', 'julian', 'time',
- 'year', 'month', 'day', 'hour', 'minute', 'second', 'weekday', 'zone');
- $select_dp = new html_select(array('name' => "_rule_date_part[]", 'id' => 'rule_date_part'.$id,
- 'style' => $rule['test'] == 'currentdate' || $rule['test'] == 'date' ? '' : 'display:none',
- 'class' => 'datepart_selector',
- ));
-
- foreach ($date_parts as $part) {
- $select_dp->add(rcube::Q($this->plugin->gettext($part)), $part);
- }
-
- $tout .= $select_dp->show($rule['test'] == 'currentdate' || $rule['test'] == 'date' ? $rule['part'] : '');
- }
-
// target(s) input
if (in_array($rule['test'], array('header', 'address', 'envelope'))) {
$test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
@@ -1396,6 +1425,22 @@ class rcube_sieve_engine
$target = '';
}
+ // (current)date part select
+ if (in_array('date', $this->exts) || in_array('currentdate', $this->exts)) {
+ $date_parts = array('date', 'iso8601', 'std11', 'julian', 'time',
+ 'year', 'month', 'day', 'hour', 'minute', 'second', 'weekday', 'zone');
+ $select_dp = new html_select(array('name' => "_rule_date_part[]", 'id' => 'rule_date_part'.$id,
+ 'style' => in_array($rule['test'], array('currentdate', 'date')) && !preg_match('/^(notcount|count)-/', $test) ? '' : 'display:none',
+ 'class' => 'datepart_selector',
+ ));
+
+ foreach ($date_parts as $part) {
+ $select_dp->add(rcube::Q($this->plugin->gettext($part)), $part);
+ }
+
+ $tout .= $select_dp->show($rule['test'] == 'currentdate' || $rule['test'] == 'date' ? $rule['part'] : '');
+ }
+
$tout .= $select_op->show($test);
$tout .= $this->list_input($id, 'rule_target', $target,
$rule['test'] != 'size' && $rule['test'] != 'exists',
@@ -1436,7 +1481,7 @@ class rcube_sieve_engine
$select_type->add(rcube::Q($this->plugin->gettext('detail')), 'detail');
}
- $need_mod = $rule['test'] != 'size' && $rule['test'] != 'body';
+ $need_mod = !in_array($rule['test'], array('size', 'body', 'date', 'currentdate'));
$mout = '<div id="rule_mod' .$id. '" class="adv"' . (!$need_mod ? ' style="display:none"' : '') . '>';
$mout .= ' <span class="label">' . rcube::Q($this->plugin->gettext('modifier')) . ' </span>';
$mout .= $select_mod->show($rule['test']);
@@ -1578,11 +1623,34 @@ class rcube_sieve_engine
// actions target inputs
$out .= '<td class="rowtargets">';
- // shared targets
- $out .= '<input type="text" name="_action_target['.$id.']" id="action_target' .$id. '" '
- .'value="' .($action['type']=='redirect' ? rcube::Q($action['target'], 'strict', false) : ''). '" size="35" '
- .'style="display:' .($action['type']=='redirect' ? 'inline' : 'none') .'" '
- . $this->error_class($id, 'action', 'target', 'action_target') .' />';
+
+ // force domain selection in redirect email input
+ $domains = (array) $this->rc->config->get('managesieve_domains');
+ if (!empty($domains)) {
+ sort($domains);
+
+ $domain_select = new html_select(array('name' => "_action_target_domain[$id]", 'id' => 'action_target_domain'.$id));
+ $domain_select->add(array_combine($domains, $domains));
+
+ $parts = explode('@', $action['target']);
+
+ if (!empty($parts)) {
+ $action['domain'] = array_pop($parts);
+ $action['target'] = implode('@', $parts);
+ }
+ }
+
+ // redirect target
+ $out .= '<span id="redirect_target' . $id . '" style="white-space:nowrap;'
+ . ' display:' . ($action['type'] == 'redirect' ? 'inline' : 'none') . '">'
+ . '<input type="text" name="_action_target['.$id.']" id="action_target' .$id. '"'
+ . ' value="' .($action['type'] == 'redirect' ? rcube::Q($action['target'], 'strict', false) : '') . '"'
+ . (!empty($domains) ? ' size="20"' : ' size="35"')
+ . $this->error_class($id, 'action', 'target', 'action_target') .' />'
+ . (!empty($domains) ? ' @ ' . $domain_select->show($action['domain']) : '')
+ . '</span>';
+
+ // (e)reject target
$out .= '<textarea name="_action_target_area['.$id.']" id="action_target_area' .$id. '" '
.'rows="3" cols="35" '. $this->error_class($id, 'action', 'targetarea', 'action_target_area')
.'style="display:' .(in_array($action['type'], array('reject', 'ereject')) ? 'inline' : 'none') .'">'
@@ -2147,7 +2215,8 @@ class rcube_sieve_engine
return;
}
- $headers = array();
+ $headers = array();
+ $exceptions = array('date', 'currentdate', 'size', 'body');
// find common headers used in script, will be added to the list
// of available (predefined) headers (#1489271)
@@ -2156,6 +2225,12 @@ class rcube_sieve_engine
if ($test['test'] == 'header') {
foreach ((array) $test['arg1'] as $header) {
$lc_header = strtolower($header);
+
+ // skip special names to not confuse UI
+ if (in_array($lc_header, $exceptions)) {
+ continue;
+ }
+
if (!isset($this->headers[$lc_header]) && !isset($headers[$lc_header])) {
$headers[$lc_header] = $header;
}
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
index 371b45d84..36eb1bcf8 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
@@ -6,18 +6,18 @@
* Copyright (C) 2008-2011, The Roundcube Dev Team
* Copyright (C) 2011, Kolab Systems AG
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class rcube_sieve_script
@@ -27,26 +27,23 @@ class rcube_sieve_script
private $vars = array(); // "global" variables
private $prefix = ''; // script header (comments)
private $supported = array( // Sieve extensions supported by class
- 'body', // RFC5173
- 'copy', // RFC3894
- 'date', // RFC5260
- 'enotify', // RFC5435
+ 'fileinto', // RFC5228
'envelope', // RFC5228
+ 'reject', // RFC5429
'ereject', // RFC5429
- 'fileinto', // RFC5228
+ 'copy', // RFC3894
+ 'vacation', // RFC5230
+ 'relational', // RFC3431
+ 'regex', // draft-ietf-sieve-regex-01
'imapflags', // draft-melnikov-sieve-imapflags-06
'imap4flags', // RFC5232
'include', // draft-ietf-sieve-include-12
- 'index', // RFC5260
- 'notify', // draft-ietf-sieve-notify-00
- 'regex', // draft-ietf-sieve-regex-01
- 'reject', // RFC5429
- 'relational', // RFC3431
- 'subaddress', // RFC5233
- 'vacation', // RFC5230
- 'vacation-seconds', // RFC6131
'variables', // RFC5229
- // @TODO: spamtest+virustest, mailbox
+ 'body', // RFC5173
+ 'subaddress', // RFC5233
+ 'enotify', // RFC5435
+ 'notify', // draft-ietf-sieve-notify-00
+ // @TODO: spamtest+virustest, mailbox, date
);
/**
@@ -208,6 +205,7 @@ class rcube_sieve_script
// rules
foreach ($this->content as $rule) {
+ $extension = '';
$script = '';
$tests = array();
$i = 0;
@@ -240,8 +238,24 @@ class rcube_sieve_script
$tests[$i] .= ($test['not'] ? 'not ' : '');
$tests[$i] .= 'header';
- $this->add_index($test, $tests[$i], $exts);
- $this->add_operator($test, $tests[$i], $exts);
+ if (!empty($test['type'])) {
+ // relational operator + comparator
+ if (preg_match('/^(value|count)-([gteqnl]{2})/', $test['type'], $m)) {
+ array_push($exts, 'relational');
+ array_push($exts, 'comparator-i;ascii-numeric');
+
+ $tests[$i] .= ' :' . $m[1] . ' "' . $m[2] . '" :comparator "i;ascii-numeric"';
+ }
+ else {
+ $this->add_comparator($test, $tests[$i], $exts);
+
+ if ($test['type'] == 'regex') {
+ array_push($exts, 'regex');
+ }
+
+ $tests[$i] .= ' :' . $test['type'];
+ }
+ }
$tests[$i] .= ' ' . self::escape_string($test['arg1']);
$tests[$i] .= ' ' . self::escape_string($test['arg2']);
@@ -256,19 +270,21 @@ class rcube_sieve_script
$tests[$i] .= ($test['not'] ? 'not ' : '');
$tests[$i] .= $test['test'];
- if ($test['test'] != 'envelope') {
- $this->add_index($test, $tests[$i], $exts);
- }
-
- // :all address-part is optional, skip it
- if (!empty($test['part']) && $test['part'] != 'all') {
+ if (!empty($test['part'])) {
$tests[$i] .= ' :' . $test['part'];
if ($test['part'] == 'user' || $test['part'] == 'detail') {
array_push($exts, 'subaddress');
}
}
- $this->add_operator($test, $tests[$i], $exts);
+ $this->add_comparator($test, $tests[$i], $exts);
+
+ if (!empty($test['type'])) {
+ if ($test['type'] == 'regex') {
+ array_push($exts, 'regex');
+ }
+ $tests[$i] .= ' :' . $test['type'];
+ }
$tests[$i] .= ' ' . self::escape_string($test['arg1']);
$tests[$i] .= ' ' . self::escape_string($test['arg2']);
@@ -279,6 +295,8 @@ class rcube_sieve_script
$tests[$i] .= ($test['not'] ? 'not ' : '') . 'body';
+ $this->add_comparator($test, $tests[$i], $exts);
+
if (!empty($test['part'])) {
$tests[$i] .= ' :' . $test['part'];
@@ -287,35 +305,14 @@ class rcube_sieve_script
}
}
- $this->add_operator($test, $tests[$i], $exts);
-
- $tests[$i] .= ' ' . self::escape_string($test['arg']);
- break;
-
- case 'date':
- case 'currentdate':
- array_push($exts, 'date');
-
- $tests[$i] .= ($test['not'] ? 'not ' : '') . $test['test'];
-
- $this->add_index($test, $tests[$i], $exts);
-
- if (!empty($test['originalzone']) && $test['test'] == 'date') {
- $tests[$i] .= ' :originalzone';
- }
- else if (!empty($test['zone'])) {
- $tests[$i] .= ' :zone ' . self::escape_string($test['zone']);
- }
-
- $this->add_operator($test, $tests[$i], $exts);
-
- if ($test['test'] == 'date') {
- $tests[$i] .= ' ' . self::escape_string($test['header']);
+ if (!empty($test['type'])) {
+ if ($test['type'] == 'regex') {
+ array_push($exts, 'regex');
+ }
+ $tests[$i] .= ' :' . $test['type'];
}
- $tests[$i] .= ' ' . self::escape_string($test['part']);
$tests[$i] .= ' ' . self::escape_string($test['arg']);
-
break;
}
$i++;
@@ -450,13 +447,8 @@ class rcube_sieve_script
case 'vacation':
array_push($exts, 'vacation');
$action_script .= 'vacation';
- if (isset($action['seconds'])) {
- array_push($exts, 'vacation-seconds');
- $action_script .= " :seconds " . intval($action['seconds']);
- }
- else if (!empty($action['days'])) {
- $action_script .= " :days " . intval($action['days']);
- }
+ if (!empty($action['days']))
+ $action_script .= " :days " . $action['days'];
if (!empty($action['addresses']))
$action_script .= " :addresses " . self::escape_string($action['addresses']);
if (!empty($action['subject']))
@@ -485,17 +477,8 @@ class rcube_sieve_script
}
// requires
- if (!empty($exts)) {
- $exts = array_unique($exts);
-
- if (in_array('vacation-seconds', $exts) && ($key = array_search('vacation', $exts)) !== false) {
- unset($exts[$key]);
- }
-
- sort($exts); // for convenience use always the same order
-
- $output = 'require ["' . implode('","', $exts) . "\"];\n" . $output;
- }
+ if (!empty($exts))
+ $output = 'require ["' . implode('","', array_unique($exts)) . "\"];\n" . $output;
if (!empty($this->prefix)) {
$output = $this->prefix . "\n\n" . $output;
@@ -657,85 +640,86 @@ class rcube_sieve_script
break;
case 'size':
- $test = array('test' => 'size', 'not' => $not);
-
- $test['arg'] = array_pop($tokens);
-
+ $size = array('test' => 'size', 'not' => $not);
for ($i=0, $len=count($tokens); $i<$len; $i++) {
if (!is_array($tokens[$i])
&& preg_match('/^:(under|over)$/i', $tokens[$i])
) {
- $test['type'] = strtolower(substr($tokens[$i], 1));
+ $size['type'] = strtolower(substr($tokens[$i], 1));
+ }
+ else {
+ $size['arg'] = $tokens[$i];
}
}
- $tests[] = $test;
+ $tests[] = $size;
break;
case 'header':
- case 'address':
- case 'envelope':
- $test = array('test' => $token, 'not' => $not);
-
- $test['arg2'] = array_pop($tokens);
- $test['arg1'] = array_pop($tokens);
-
- $test += $this->test_tokens($tokens);
-
- if ($token != 'header' && !empty($tokens)) {
- for ($i=0, $len=count($tokens); $i<$len; $i++) {
- if (!is_array($tokens[$i]) && preg_match('/^:(localpart|domain|all|user|detail)$/i', $tokens[$i])) {
- $test['part'] = strtolower(substr($tokens[$i], 1));
- }
+ $header = array('test' => 'header', 'not' => $not, 'arg1' => '', 'arg2' => '');
+ for ($i=0, $len=count($tokens); $i<$len; $i++) {
+ if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) {
+ $header['comparator'] = $tokens[++$i];
+ }
+ else if (!is_array($tokens[$i]) && preg_match('/^:(count|value)$/i', $tokens[$i])) {
+ $header['type'] = strtolower(substr($tokens[$i], 1)) . '-' . $tokens[++$i];
+ }
+ else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches|regex)$/i', $tokens[$i])) {
+ $header['type'] = strtolower(substr($tokens[$i], 1));
+ }
+ else {
+ $header['arg1'] = $header['arg2'];
+ $header['arg2'] = $tokens[$i];
}
}
- $tests[] = $test;
+ $tests[] = $header;
break;
- case 'body':
- $test = array('test' => 'body', 'not' => $not);
-
- $test['arg'] = array_pop($tokens);
-
- $test += $this->test_tokens($tokens);
-
+ case 'address':
+ case 'envelope':
+ $header = array('test' => $token, 'not' => $not, 'arg1' => '', 'arg2' => '');
for ($i=0, $len=count($tokens); $i<$len; $i++) {
- if (!is_array($tokens[$i]) && preg_match('/^:(raw|content|text)$/i', $tokens[$i])) {
- $test['part'] = strtolower(substr($tokens[$i], 1));
-
- if ($test['part'] == 'content') {
- $test['content'] = $tokens[++$i];
- }
+ if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) {
+ $header['comparator'] = $tokens[++$i];
+ }
+ else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches|regex)$/i', $tokens[$i])) {
+ $header['type'] = strtolower(substr($tokens[$i], 1));
+ }
+ else if (!is_array($tokens[$i]) && preg_match('/^:(localpart|domain|all|user|detail)$/i', $tokens[$i])) {
+ $header['part'] = strtolower(substr($tokens[$i], 1));
+ }
+ else {
+ $header['arg1'] = $header['arg2'];
+ $header['arg2'] = $tokens[$i];
}
}
- $tests[] = $test;
+ $tests[] = $header;
break;
- case 'date':
- case 'currentdate':
- $test = array('test' => $token, 'not' => $not);
-
- $test['arg'] = array_pop($tokens);
- $test['part'] = array_pop($tokens);
-
- if ($token == 'date') {
- $test['header'] = array_pop($tokens);
- }
-
- $test += $this->test_tokens($tokens);
-
+ case 'body':
+ $header = array('test' => 'body', 'not' => $not, 'arg' => '');
for ($i=0, $len=count($tokens); $i<$len; $i++) {
- if (!is_array($tokens[$i]) && preg_match('/^:zone$/i', $tokens[$i])) {
- $test['zone'] = $tokens[++$i];
+ if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) {
+ $header['comparator'] = $tokens[++$i];
+ }
+ else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches|regex)$/i', $tokens[$i])) {
+ $header['type'] = strtolower(substr($tokens[$i], 1));
}
- else if (!is_array($tokens[$i]) && preg_match('/^:originalzone$/i', $tokens[$i])) {
- $test['originalzone'] = true;
+ else if (!is_array($tokens[$i]) && preg_match('/^:(raw|content|text)$/i', $tokens[$i])) {
+ $header['part'] = strtolower(substr($tokens[$i], 1));
+
+ if ($header['part'] == 'content') {
+ $header['content'] = $tokens[++$i];
+ }
+ }
+ else {
+ $header['arg'] = $tokens[$i];
}
}
- $tests[] = $test;
+ $tests[] = $header;
break;
case 'exists':
@@ -787,9 +771,15 @@ class rcube_sieve_script
$result = null;
while (strlen($content)) {
- $tokens = self::tokenize($content, true);
+ $tokens = self::tokenize($content, true);
$separator = array_pop($tokens);
- $token = !empty($tokens) ? array_shift($tokens) : $separator;
+
+ if (!empty($tokens)) {
+ $token = array_shift($tokens);
+ }
+ else {
+ $token = $separator;
+ }
switch ($token) {
case 'discard':
@@ -800,78 +790,125 @@ class rcube_sieve_script
case 'fileinto':
case 'redirect':
- $action = array('type' => $token, 'target' => array_pop($tokens));
- $args = array('copy');
- $action += $this->action_arguments($tokens, $args);
+ $copy = false;
+ $target = '';
- $result[] = $action;
+ for ($i=0, $len=count($tokens); $i<$len; $i++) {
+ if (strtolower($tokens[$i]) == ':copy') {
+ $copy = true;
+ }
+ else {
+ $target = $tokens[$i];
+ }
+ }
+
+ $result[] = array('type' => $token, 'copy' => $copy,
+ 'target' => $target);
+ break;
+
+ case 'reject':
+ case 'ereject':
+ $result[] = array('type' => $token, 'target' => array_pop($tokens));
break;
case 'vacation':
- $action = array('type' => 'vacation', 'reason' => array_pop($tokens));
- $args = array('mime');
- $vargs = array('seconds', 'days', 'addresses', 'subject', 'handle', 'from');
- $action += $this->action_arguments($tokens, $args, $vargs);
+ $vacation = array('type' => 'vacation', 'reason' => array_pop($tokens));
- $result[] = $action;
+ for ($i=0, $len=count($tokens); $i<$len; $i++) {
+ $tok = strtolower($tokens[$i]);
+ if ($tok == ':days') {
+ $vacation['days'] = $tokens[++$i];
+ }
+ else if ($tok == ':subject') {
+ $vacation['subject'] = $tokens[++$i];
+ }
+ else if ($tok == ':addresses') {
+ $vacation['addresses'] = $tokens[++$i];
+ }
+ else if ($tok == ':handle') {
+ $vacation['handle'] = $tokens[++$i];
+ }
+ else if ($tok == ':from') {
+ $vacation['from'] = $tokens[++$i];
+ }
+ else if ($tok == ':mime') {
+ $vacation['mime'] = true;
+ }
+ }
+
+ $result[] = $vacation;
break;
- case 'reject':
- case 'ereject':
case 'setflag':
case 'addflag':
case 'removeflag':
- $result[] = array('type' => $token, 'target' => array_pop($tokens));
+ $result[] = array('type' => $token,
+ // Flags list: last token (skip optional variable)
+ 'target' => $tokens[count($tokens)-1]
+ );
break;
case 'include':
- $action = array('type' => 'include', 'target' => array_pop($tokens));
- $args = array('once', 'optional', 'global', 'personal');
- $action += $this->action_arguments($tokens, $args);
+ $include = array('type' => 'include', 'target' => array_pop($tokens));
- $result[] = $action;
+ // Parameters: :once, :optional, :global, :personal
+ for ($i=0, $len=count($tokens); $i<$len; $i++) {
+ $tok = strtolower($tokens[$i]);
+ if ($tok[0] == ':') {
+ $include[substr($tok, 1)] = true;
+ }
+ }
+
+ $result[] = $include;
break;
case 'set':
- $action = array('type' => 'set', 'value' => array_pop($tokens), 'name' => array_pop($tokens));
- $args = array('lower', 'upper', 'lowerfirst', 'upperfirst', 'quotewildcard', 'length');
- $action += $this->action_arguments($tokens, $args);
+ $set = array('type' => 'set', 'value' => array_pop($tokens), 'name' => array_pop($tokens));
+
+ // Parameters: :lower :upper :lowerfirst :upperfirst :quotewildcard :length
+ for ($i=0, $len=count($tokens); $i<$len; $i++) {
+ $tok = strtolower($tokens[$i]);
+ if ($tok[0] == ':') {
+ $set[substr($tok, 1)] = true;
+ }
+ }
- $result[] = $action;
+ $result[] = $set;
break;
case 'require':
// skip, will be build according to used commands
- // $result[] = array('type' => 'require', 'target' => array_pop($tokens));
+ // $result[] = array('type' => 'require', 'target' => $tokens);
break;
case 'notify':
- $action = array('type' => 'notify');
- $priorities = array('high' => 1, 'normal' => 2, 'low' => 3);
- $vargs = array('from', 'importance', 'options', 'message', 'method');
- $args = array_keys($priorities);
- $action += $this->action_arguments($tokens, $args, $vargs);
-
- // Here we support only 00 version of notify draft, there
- // were a couple regressions in 00 to 04 changelog, we use
- // the version used by Cyrus
- if (!isset($action['importance'])) {
- foreach ($priorities as $key => $val) {
- if (isset($action[$key])) {
- $action['importance'] = $val;
- unset($action[$key]);
+ $notify = array('type' => 'notify');
+ $priorities = array(':high' => 1, ':normal' => 2, ':low' => 3);
+
+ // Parameters: :from, :importance, :options, :message
+ // additional (optional) :method parameter for notify extension
+ for ($i=0, $len=count($tokens); $i<$len; $i++) {
+ $tok = strtolower($tokens[$i]);
+ if ($tok[0] == ':') {
+ // Here we support only 00 version of notify draft, there
+ // were a couple regressions in 00 to 04 changelog, we use
+ // the version used by Cyrus
+ if (isset($priorities[$tok])) {
+ $notify['importance'] = $priorities[$tok];
+ }
+ else {
+ $notify[substr($tok, 1)] = $tokens[++$i];
}
}
+ else {
+ // unnamed parameter is a :method in enotify extension
+ $notify['method'] = $tokens[$i];
+ }
}
- // unnamed parameter is a :method in enotify extension
- if (!isset($action['method'])) {
- $action['method'] = array_pop($tokens);
- }
-
- $method_components = parse_url($action['method']);
+ $method_components = parse_url($notify['method']);
if ($method_components['scheme'] == 'mailto') {
- $action['address'] = $method_components['path'];
+ $notify['address'] = $method_components['path'];
$method_params = array();
if (array_key_exists('query', $method_components)) {
parse_str($method_components['query'], $method_params);
@@ -881,10 +918,10 @@ class rcube_sieve_script
if (ini_get('magic_quotes_gpc') || ini_get('magic_quotes_sybase')) {
array_map('stripslashes', $method_params);
}
- $action['body'] = (array_key_exists('body', $method_params)) ? $method_params['body'] : '';
+ $notify['body'] = (array_key_exists('body', $method_params)) ? $method_params['body'] : '';
}
- $result[] = $action;
+ $result[] = $notify;
break;
}
@@ -897,7 +934,7 @@ class rcube_sieve_script
}
/**
- * Add comparator to the test
+ *
*/
private function add_comparator($test, &$out, &$exts)
{
@@ -920,111 +957,6 @@ class rcube_sieve_script
}
/**
- * Add index argument to the test
- */
- private function add_index($test, &$out, &$exts)
- {
- if (!empty($test['index'])) {
- array_push($exts, 'index');
- $out .= ' :index ' . intval($test['index']) . ($test['last'] ? ' :last' : '');
- }
- }
-
- /**
- * Add operators to the test
- */
- private function add_operator($test, &$out, &$exts)
- {
- if (empty($test['type'])) {
- return;
- }
-
- // relational operator + comparator
- if (preg_match('/^(value|count)-([gteqnl]{2})/', $test['type'], $m)) {
- array_push($exts, 'relational');
- array_push($exts, 'comparator-i;ascii-numeric');
-
- $out .= ' :' . $m[1] . ' "' . $m[2] . '" :comparator "i;ascii-numeric"';
- }
- else {
- $this->add_comparator($test, $out, $exts);
-
- if ($test['type'] == 'regex') {
- array_push($exts, 'regex');
- }
-
- $out .= ' :' . $test['type'];
- }
- }
-
- /**
- * Extract test tokens
- */
- private function test_tokens(&$tokens)
- {
- $test = array();
- $result = array();
-
- for ($i=0, $len=count($tokens); $i<$len; $i++) {
- if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) {
- $test['comparator'] = $tokens[++$i];
- }
- else if (!is_array($tokens[$i]) && preg_match('/^:(count|value)$/i', $tokens[$i])) {
- $test['type'] = strtolower(substr($tokens[$i], 1)) . '-' . $tokens[++$i];
- }
- else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches|regex)$/i', $tokens[$i])) {
- $test['type'] = strtolower(substr($tokens[$i], 1));
- }
- else if (!is_array($tokens[$i]) && preg_match('/^:index$/i', $tokens[$i])) {
- $test['index'] = intval($tokens[++$i]);
- if ($tokens[$i+1] && preg_match('/^:last$/i', $tokens[$i+1])) {
- $test['last'] = true;
- $i++;
- }
- }
- else {
- $result[] = $tokens[$i];
- }
- }
-
- $tokens = $result;
-
- return $test;
- }
-
- /**
- * Extract action arguments
- */
- private function action_arguments(&$tokens, $bool_args, $val_args = array())
- {
- $action = array();
- $result = array();
-
- for ($i=0, $len=count($tokens); $i<$len; $i++) {
- $tok = $tokens[$i];
- if (!is_array($tok) && $tok[0] == ':') {
- $tok = strtolower(substr($tok, 1));
- if (in_array($tok, $bool_args)) {
- $action[$tok] = true;
- }
- else if (in_array($tok, $val_args)) {
- $action[$tok] = $tokens[++$i];
- }
- else {
- $result[] = $tok;
- }
- }
- else {
- $result[] = $tok;
- }
- }
-
- $tokens = $result;
-
- return $action;
- }
-
- /**
* Escape special chars into quoted string value or multi-line string
* or list of strings
*
@@ -1082,10 +1014,11 @@ class rcube_sieve_script
* @param mixed $num Number of tokens to return, 0 for all
* or True for all tokens until separator is found.
* Separator will be returned as last token.
+ * @param int $in_list Enable to call recursively inside a list
*
* @return mixed Tokens array or string if $num=1
*/
- static function tokenize(&$str, $num=0)
+ static function tokenize(&$str, $num=0, $in_list=false)
{
$result = array();
@@ -1120,7 +1053,7 @@ class rcube_sieve_script
// Parenthesized list
case '[':
$str = substr($str, 1);
- $result[] = self::tokenize($str, 0);
+ $result[] = self::tokenize($str, 0, true);
break;
case ']':
$str = substr($str, 1);
diff --git a/plugins/managesieve/localization/ar_SA.inc b/plugins/managesieve/localization/ar_SA.inc
new file mode 100644
index 000000000..8e6d8414a
--- /dev/null
+++ b/plugins/managesieve/localization/ar_SA.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/managesieve/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Managesieve plugin |
+ | Copyright (C) 2012-2013, 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/plugin-managesieve/
+*/
+$labels['messagedelete'] = 'حذ٠الرسالة';
+$labels['add'] = 'إضاÙØ©';
+$labels['del'] = 'حذÙ';
+$labels['recipient'] = 'مستلم';
+$labels['active'] = 'نشط';
+$labels['flagdeleted'] = 'محذوÙ';
+$labels['flagflagged'] = 'موسوم';
+$labels['flagdraft'] = 'مسودة';
+$labels['notifyimportancelow'] = 'منخÙض';
+$labels['notifyimportancenormal'] = 'عادي';
+$labels['notifyimportancehigh'] = 'مرتÙع';
+$labels['advancedopts'] = 'خيارات متقدّمة';
+$labels['address'] = 'العنوان';
+$labels['allparts'] = 'الكل';
+$labels['domain'] = 'المجال';
+?>
diff --git a/plugins/managesieve/localization/az_AZ.inc b/plugins/managesieve/localization/az_AZ.inc
index 670162552..f272df7b0 100644
--- a/plugins/managesieve/localization/az_AZ.inc
+++ b/plugins/managesieve/localization/az_AZ.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'ÆlavÉ™ et';
$labels['del'] = 'Sil';
$labels['sender'] = 'Göndərən';
$labels['recipient'] = 'Qəbul edən';
-$labels['vacationaddr'] = 'ÆlavÉ™ ünvanlarım üçün siyahı:';
+$labels['vacationaddresses'] = 'ÆlavÉ™ ünvanlarım üçün siyahı (vergüllÉ™r ilÉ™ ayrılmış):';
$labels['vacationdays'] = 'Məktub neçə müddətdən bir göndərilsin (gündə):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Məktublar nə qədər sıx göndərilsin:';
+$labels['days'] = 'günlər';
+$labels['seconds'] = 'saniyələr';
$labels['vacationreason'] = 'Məktubun mətni (səbəb yoxdur):';
$labels['vacationsubject'] = 'Məktubun mövzusu:';
$labels['rulestop'] = 'Yerinə yetirməyi dayandır';
@@ -98,9 +98,9 @@ $labels['flagdeleted'] = 'Silindi';
$labels['flaganswered'] = 'Cavab verilmiÅŸ';
$labels['flagflagged'] = 'İşarəlilər';
$labels['flagdraft'] = 'Qaralama';
-$labels['setvariable'] = 'Set variable';
-$labels['setvarname'] = 'Variable name:';
-$labels['setvarvalue'] = 'Variable value:';
+$labels['setvariable'] = 'Dəyişəni təyin et';
+$labels['setvarname'] = 'Dəyişənin adı:';
+$labels['setvarvalue'] = 'Dəyişənin dəyəri:';
$labels['setvarmodifiers'] = 'Modifikatorlar';
$labels['varlower'] = 'aşağı registr';
$labels['varupper'] = 'yuxarı registr';
diff --git a/plugins/managesieve/localization/be_BE.inc b/plugins/managesieve/localization/be_BE.inc
index ff54c0546..64f81599e 100644
--- a/plugins/managesieve/localization/be_BE.inc
+++ b/plugins/managesieve/localization/be_BE.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Дадаць';
$labels['del'] = 'Выдаліць';
$labels['sender'] = 'Ðд каго';
$labels['recipient'] = 'Каму';
-$labels['vacationaddr'] = 'Дадатковы ÑÐ¿Ñ–Ñ Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ð»ÑŒÐ½Ñ–ÐºÐ°Ñž:';
+$labels['vacationaddresses'] = 'Дадатковы ÑÐ¿Ñ–Ñ Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ð»ÑŒÐ½Ñ–ÐºÐ°Ñž (праз коÑку):';
$labels['vacationdays'] = 'Як чаÑта даÑылаць паведамленні (Ñž днÑÑ…):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/bg_BG.inc b/plugins/managesieve/localization/bg_BG.inc
index e22290cff..28f2ddb99 100644
--- a/plugins/managesieve/localization/bg_BG.inc
+++ b/plugins/managesieve/localization/bg_BG.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'ДобавÑне';
$labels['del'] = 'Изтриване';
$labels['sender'] = 'Подател';
$labels['recipient'] = 'Получател';
-$labels['vacationaddr'] = 'Допълнителни e-mail адреÑи:';
+$labels['vacationaddresses'] = 'Допълнителни e-mail адреÑи (разделени ÑÑŠÑ Ð·Ð°Ð¿ÐµÑ‚Ð°Ñ):';
$labels['vacationdays'] = 'Колко чеÑто пращате ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (в дни):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Колко чеÑто да праща ÑъобщениÑ:';
+$labels['days'] = 'дни';
+$labels['seconds'] = 'Ñекунди';
$labels['vacationreason'] = 'ТекÑÑ‚ на Ñъобщението (причина за ваканциÑта)';
$labels['vacationsubject'] = 'Тема на Ñъобщението';
$labels['rulestop'] = 'Правила за Ñпиране';
diff --git a/plugins/managesieve/localization/bs_BA.inc b/plugins/managesieve/localization/bs_BA.inc
index df9083129..7d21dbd9f 100644
--- a/plugins/managesieve/localization/bs_BA.inc
+++ b/plugins/managesieve/localization/bs_BA.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Dodaj';
$labels['del'] = 'Obriši';
$labels['sender'] = 'Pošiljaoc';
$labels['recipient'] = 'Primaoc';
-$labels['vacationaddr'] = 'Moje dodatne email adrese:';
+$labels['vacationaddresses'] = 'Moje dodatne email adrese (odvojite zarezima):';
$labels['vacationdays'] = 'Frekvencija slanja poruka (u danima):';
$labels['vacationinterval'] = 'Frekvencija slanja poruka:';
$labels['days'] = 'dana';
diff --git a/plugins/managesieve/localization/ca_ES.inc b/plugins/managesieve/localization/ca_ES.inc
index 7ebd2c049..e721fcce3 100644
--- a/plugins/managesieve/localization/ca_ES.inc
+++ b/plugins/managesieve/localization/ca_ES.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Afegeix';
$labels['del'] = 'Suprimeix';
$labels['sender'] = 'Remitent';
$labels['recipient'] = 'Destinatari/a';
-$labels['vacationaddr'] = 'Altres adreces electròniques meves:';
+$labels['vacationaddresses'] = 'Altres adreces electròniques meves (separades per coma)';
$labels['vacationdays'] = 'Cada quan enviar un missatge (en dies):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Amb quina freqüència enviar missatges:';
+$labels['days'] = 'dies';
+$labels['seconds'] = 'segons';
$labels['vacationreason'] = 'Cos del missatge (raó de les vacances):';
$labels['vacationsubject'] = 'Assumpte del missatge:';
$labels['rulestop'] = 'Deixa d\'avaluar regles';
diff --git a/plugins/managesieve/localization/cs_CZ.inc b/plugins/managesieve/localization/cs_CZ.inc
index 758316b3f..26baeff2b 100644
--- a/plugins/managesieve/localization/cs_CZ.inc
+++ b/plugins/managesieve/localization/cs_CZ.inc
@@ -49,14 +49,13 @@ $labels['messagesendcopy'] = 'Odeslat kopii zprávy na';
$labels['messagereply'] = 'Odpovědět se zprávou';
$labels['messagedelete'] = 'Smazat zprávu';
$labels['messagediscard'] = 'Smazat se zprávou';
-$labels['messagekeep'] = 'Ponechat zprávu v doruÄené poÅ¡tÄ›';
$labels['messagesrules'] = 'Pravidla pro příchozí zprávu:';
$labels['messagesactions'] = '...vykonej následující akce:';
$labels['add'] = 'Přidej';
$labels['del'] = 'Smaž';
$labels['sender'] = 'Odesílatel';
$labels['recipient'] = 'Příjemce';
-$labels['vacationaddr'] = 'Moje další e-mailová adresa(y):';
+$labels['vacationaddresses'] = 'Moje další e-mailové adresy (aliasy) spojené s tímto úÄtem (oddÄ›lené Äárkou):';
$labels['vacationdays'] = 'PoÄet dnů mezi automatickými odpovÄ›Ämi:';
$labels['vacationinterval'] = 'Prodleva mezi automatickými odpovÄ›Ämi:';
$labels['days'] = 'dnů';
@@ -122,22 +121,6 @@ $labels['filtercreate'] = 'Vytvořit filtr';
$labels['usedata'] = 'Použít následující údaje ve filtru:';
$labels['nextstep'] = 'Další krok';
$labels['...'] = '...';
-$labels['currdate'] = 'Aktuální datum';
-$labels['datetest'] = 'Datum';
-$labels['dateheader'] = 'hlaviÄka:';
-$labels['year'] = 'rok';
-$labels['month'] = 'měsíc';
-$labels['day'] = 'den';
-$labels['date'] = 'datum (rrrr-mm-dd)';
-$labels['julian'] = 'datum (juliánské)';
-$labels['hour'] = 'hodina';
-$labels['minute'] = 'minuta';
-$labels['second'] = 'sekunda';
-$labels['time'] = 'Äas (hh:mm:ss)';
-$labels['iso8601'] = 'datum (ISO8601)';
-$labels['std11'] = 'datum (RFC2822)';
-$labels['zone'] = 'Äasová zóna';
-$labels['weekday'] = 'všední den (0-6)';
$labels['advancedopts'] = 'PokroÄilá nastavení';
$labels['body'] = 'Tělo';
$labels['address'] = 'adresa';
@@ -157,8 +140,6 @@ $labels['default'] = 'výchozí';
$labels['octet'] = 'striktní (oktet)';
$labels['asciicasemap'] = 'necitlivé na velikost písmen (ascii-casemap)';
$labels['asciinumeric'] = 'Äíslené (ascii-numeric)';
-$labels['index'] = 'index:';
-$labels['indexlast'] = 'pozpátku';
$messages = array();
$messages['filterunknownerror'] = 'Neznámá chyba serveru';
@@ -192,6 +173,5 @@ $messages['nametoolong'] = 'Příliš dlouhý název.';
$messages['namereserved'] = 'Vyhrazený název.';
$messages['setexist'] = 'Sada již existuje.';
$messages['nodata'] = 'Musí být vybrána minimálně jedna pozice!';
-$messages['invaliddateformat'] = 'Neplatné datum nebo Äást data';
?>
diff --git a/plugins/managesieve/localization/cy_GB.inc b/plugins/managesieve/localization/cy_GB.inc
index 63d2e7100..52fafe770 100644
--- a/plugins/managesieve/localization/cy_GB.inc
+++ b/plugins/managesieve/localization/cy_GB.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Ychwanegu';
$labels['del'] = 'Dileu';
$labels['sender'] = 'Anfonwr';
$labels['recipient'] = 'Derbynnwr';
-$labels['vacationaddr'] = 'Fy chyfeiriadau ebost ychwanegol:';
+$labels['vacationaddresses'] = 'Fy chyfeiriadau ebost ychwanegol (gwahanir gyda coma):';
$labels['vacationdays'] = 'Pa mor aml i ddanfon negeseuon (mewn dyddiau):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Pa mor aml i ddanfon negeseuon:';
+$labels['days'] = 'dyddiau';
+$labels['seconds'] = 'eiliadau';
$labels['vacationreason'] = 'Corff neges (rheswm ar wyliau):';
$labels['vacationsubject'] = 'Pwnc neges:';
$labels['rulestop'] = 'Stopio gwerthuso rheolau';
diff --git a/plugins/managesieve/localization/da_DK.inc b/plugins/managesieve/localization/da_DK.inc
index 058481031..cd3deaf40 100644
--- a/plugins/managesieve/localization/da_DK.inc
+++ b/plugins/managesieve/localization/da_DK.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Tilføje';
$labels['del'] = 'Fjern';
$labels['sender'] = 'Afsender';
$labels['recipient'] = 'Modtager';
-$labels['vacationaddr'] = 'Mine alternative e-mailadresser:';
+$labels['vacationaddresses'] = 'Mine alternative e-mailadresser (kommasepareret):';
$labels['vacationdays'] = 'Hvor tit skal besked sendes (i dage):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Hvor tit skal besked sendes:';
+$labels['days'] = 'dage';
+$labels['seconds'] = 'sekunder';
$labels['vacationreason'] = 'Besked (ved ferie):';
$labels['vacationsubject'] = 'Besked emne:';
$labels['rulestop'] = 'Stop behandling af regler';
diff --git a/plugins/managesieve/localization/de_CH.inc b/plugins/managesieve/localization/de_CH.inc
index 19a9b9de3..b30625fe9 100644
--- a/plugins/managesieve/localization/de_CH.inc
+++ b/plugins/managesieve/localization/de_CH.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Hinzufügen';
$labels['del'] = 'Löschen';
$labels['sender'] = 'Absender';
$labels['recipient'] = 'Empfänger';
-$labels['vacationaddr'] = 'Zusätzliche Liste von Empfängern:';
+$labels['vacationaddresses'] = 'Zusätzliche Liste von Empfängern (Komma getrennt):';
$labels['vacationdays'] = 'Antwort wird erneut gesendet nach (in Tagen):';
$labels['vacationinterval'] = 'Wie oft senden:';
$labels['days'] = 'Tage';
diff --git a/plugins/managesieve/localization/de_DE.inc b/plugins/managesieve/localization/de_DE.inc
index 4894904d6..d0cba28db 100644
--- a/plugins/managesieve/localization/de_DE.inc
+++ b/plugins/managesieve/localization/de_DE.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Hinzufügen';
$labels['del'] = 'Löschen';
$labels['sender'] = 'Absender';
$labels['recipient'] = 'Empfänger';
-$labels['vacationaddr'] = 'Zusätzliche Liste von E-Mail Empfängern:';
+$labels['vacationaddresses'] = 'Zusätzliche Liste von E-Mail Empfängern (Komma getrennt):';
$labels['vacationdays'] = 'Wie oft sollen Nachrichten gesendet werden (in Tagen):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Wie oft sollen Nachrichten gesendet werden:';
+$labels['days'] = 'Tage';
+$labels['seconds'] = 'Sekunden';
$labels['vacationreason'] = 'Nachrichteninhalt (Abwesenheitsgrund):';
$labels['vacationsubject'] = 'Nachrichtenbetreff';
$labels['rulestop'] = 'Regelauswertung anhalten';
diff --git a/plugins/managesieve/localization/el_GR.inc b/plugins/managesieve/localization/el_GR.inc
index e5a1b792d..5ef9916ad 100644
--- a/plugins/managesieve/localization/el_GR.inc
+++ b/plugins/managesieve/localization/el_GR.inc
@@ -34,18 +34,18 @@ $labels['filteris'] = 'είναι ίσο με';
$labels['filterisnot'] = 'δεν είναι ίσο με';
$labels['filterexists'] = 'υπάÏχει';
$labels['filternotexists'] = 'δεν υπάÏχει';
-$labels['filtermatches'] = 'matches expression';
-$labels['filternotmatches'] = 'not matches expression';
-$labels['filterregex'] = 'matches regular expression';
-$labels['filternotregex'] = 'not matches regular expression';
+$labels['filtermatches'] = 'ταιÏιάζει με την έκφÏαση ';
+$labels['filternotmatches'] = 'Δεν ταιÏιάζει με την έκφÏαση';
+$labels['filterregex'] = 'ταιÏιάζει με κανονική έκφÏαση';
+$labels['filternotregex'] = 'δεν ταιÏιάζει με κανονική έκφÏαση';
$labels['filterunder'] = 'κάτω';
$labels['filterover'] = 'πάνω';
$labels['addrule'] = 'ΠÏοσθήκη κανόνα';
$labels['delrule'] = 'ΔιαγÏαφή κανόνα';
$labels['messagemoveto'] = 'Μετακίνηση μηνÏματος στο';
$labels['messageredirect'] = 'ΠÏοώθηση μηνÏματος στο';
-$labels['messagecopyto'] = 'Copy message to';
-$labels['messagesendcopy'] = 'Send message copy to';
+$labels['messagecopyto'] = 'ΑντιγÏαφη μυνηματος σε';
+$labels['messagesendcopy'] = 'Αποστολη της αντιγÏαφης μυνηματος σε';
$labels['messagereply'] = 'Απάντηση με μήνυμα';
$labels['messagedelete'] = 'ΔιαγÏαφή μηνÏματος';
$labels['messagediscard'] = 'ΑπόÏÏιψη με μήνυμα';
@@ -55,91 +55,91 @@ $labels['add'] = 'ΠÏοσθήκη';
$labels['del'] = 'ΔιαγÏαφή';
$labels['sender'] = 'Αποστολέας';
$labels['recipient'] = 'ΠαÏαλήπτης';
-$labels['vacationaddr'] = 'ΠÏόσθετη λίστα email παÏαληπτών:';
+$labels['vacationaddresses'] = 'ΠÏόσθετη λίστα email παÏαληπτών (διαχωÏισμένη με κόμματα):';
$labels['vacationdays'] = 'Συχνότητα αποστολής μηνυμάτων (σε ημέÏες):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Συχνότητα αποστολής μηνυμάτων:';
+$labels['days'] = 'ημεÏες';
+$labels['seconds'] = 'δευτεÏόλεπτα';
$labels['vacationreason'] = 'Σώμα μηνÏματος (λόγος απουσίας):';
-$labels['vacationsubject'] = 'Message subject:';
+$labels['vacationsubject'] = 'Θέμα μηνÏματος: ';
$labels['rulestop'] = 'ΠαÏση επαλήθευσης κανόνων';
-$labels['enable'] = 'Enable/Disable';
-$labels['filterset'] = 'Filters set';
-$labels['filtersets'] = 'Filter sets';
-$labels['filtersetadd'] = 'Add filters set';
-$labels['filtersetdel'] = 'Delete current filters set';
-$labels['filtersetact'] = 'Activate current filters set';
-$labels['filtersetdeact'] = 'Deactivate current filters set';
-$labels['filterdef'] = 'Filter definition';
-$labels['filtersetname'] = 'Filters set name';
-$labels['newfilterset'] = 'New filters set';
-$labels['active'] = 'active';
-$labels['none'] = 'none';
-$labels['fromset'] = 'from set';
-$labels['fromfile'] = 'from file';
-$labels['filterdisabled'] = 'Filter disabled';
-$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['setflags'] = 'Set flags to the message';
-$labels['addflags'] = 'Add flags to the message';
-$labels['removeflags'] = 'Remove flags from the message';
-$labels['flagread'] = 'Read';
-$labels['flagdeleted'] = 'Deleted';
-$labels['flaganswered'] = 'Answered';
-$labels['flagflagged'] = 'Flagged';
-$labels['flagdraft'] = 'Draft';
-$labels['setvariable'] = 'Set variable';
-$labels['setvarname'] = 'Variable name:';
-$labels['setvarvalue'] = 'Variable value:';
-$labels['setvarmodifiers'] = 'Modifiers:';
-$labels['varlower'] = 'lower-case';
-$labels['varupper'] = 'upper-case';
-$labels['varlowerfirst'] = 'first character lower-case';
-$labels['varupperfirst'] = 'first character upper-case';
-$labels['varquotewildcard'] = 'quote special characters';
-$labels['varlength'] = 'length';
-$labels['notify'] = 'Send notification';
-$labels['notifyaddress'] = 'To e-mail address:';
-$labels['notifybody'] = 'Notification body:';
-$labels['notifysubject'] = 'Notification subject:';
-$labels['notifyfrom'] = 'Notification sender:';
-$labels['notifyimportance'] = 'Importance:';
-$labels['notifyimportancelow'] = 'low';
-$labels['notifyimportancenormal'] = 'normal';
-$labels['notifyimportancehigh'] = 'high';
-$labels['filtercreate'] = 'Create filter';
-$labels['usedata'] = 'Use following data in the filter:';
-$labels['nextstep'] = 'Next Step';
+$labels['enable'] = 'ΕνεÏγοποιηση/ΑπενεÏγοποιηση';
+$labels['filterset'] = 'ΦίλτÏα';
+$labels['filtersets'] = 'ΦίλτÏο';
+$labels['filtersetadd'] = 'ΠÏοσθήκη φίλτÏων';
+$labels['filtersetdel'] = 'ΔιαγÏαφή φίλτÏων';
+$labels['filtersetact'] = 'ΕνεÏγοποιηση φιλτÏων';
+$labels['filtersetdeact'] = 'ΑπενεÏγοποιηση φιλτÏων';
+$labels['filterdef'] = 'ΟÏισμος φιλτÏου';
+$labels['filtersetname'] = 'Ονομασία φίλτÏων';
+$labels['newfilterset'] = 'Îεα φιλτÏα';
+$labels['active'] = 'ενεÏγο';
+$labels['none'] = 'κανένα';
+$labels['fromset'] = 'από το σÏνολο ';
+$labels['fromfile'] = 'απο αÏχειο';
+$labels['filterdisabled'] = 'ΑπενεÏγοποιημενο φιλτÏο';
+$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['setflags'] = 'ΟÏισμός σημαίων στο μήνυμα';
+$labels['addflags'] = 'ΠÏοσθήκη σημαίων στο μήνυμα';
+$labels['removeflags'] = 'ΑφαιÏέση σημαίων από το μήνυμα';
+$labels['flagread'] = 'Αναγνωση';
+$labels['flagdeleted'] = 'ΔιεγÏαμμένο';
+$labels['flaganswered'] = 'Απαντήθηκε ';
+$labels['flagflagged'] = 'Σημειωμένο';
+$labels['flagdraft'] = 'ΠÏόχειÏα';
+$labels['setvariable'] = 'ΟÏισμός μεταβλητής';
+$labels['setvarname'] = 'Όνομα μεταβλητης:';
+$labels['setvarvalue'] = 'Τιμη μεταβλητης:';
+$labels['setvarmodifiers'] = 'ΤÏοποποιητές: ';
+$labels['varlower'] = 'ΜικÏογÏάμματη γÏαφή';
+$labels['varupper'] = 'κεφαλαία γÏάμματα ';
+$labels['varlowerfirst'] = 'Ï€Ïώτος χαÏακτήÏας πεζός ';
+$labels['varupperfirst'] = 'Ï€Ïώτος χαÏακτήÏας κεφαλαία γÏάμματα';
+$labels['varquotewildcard'] = 'παÏαθέση ειδικων χαÏακτήÏων';
+$labels['varlength'] = 'Μήκος';
+$labels['notify'] = 'Αποστολή ειδοποίησης ';
+$labels['notifyaddress'] = 'Σε διεÏθυνση email:';
+$labels['notifybody'] = 'ΟÏγανισμός ειδοποιησης:';
+$labels['notifysubject'] = 'Θεμα ειδοποιησης:';
+$labels['notifyfrom'] = 'Αποστολεας ειδοποιησης:';
+$labels['notifyimportance'] = 'Σημασία: ';
+$labels['notifyimportancelow'] = 'Χαμηλή';
+$labels['notifyimportancenormal'] = 'Κανονική';
+$labels['notifyimportancehigh'] = 'Υψηλή';
+$labels['filtercreate'] = 'ΔημιουÏγία φίλτÏου';
+$labels['usedata'] = 'ΧÏησιμοποιηση ακολουθων δεδομενων στο φιλτÏο:';
+$labels['nextstep'] = 'Επομενο βημα';
$labels['...'] = '...';
-$labels['advancedopts'] = 'Advanced options';
-$labels['body'] = 'Body';
-$labels['address'] = 'address';
-$labels['envelope'] = 'envelope';
-$labels['modifier'] = 'modifier:';
-$labels['text'] = 'text';
-$labels['undecoded'] = 'undecoded (raw)';
-$labels['contenttype'] = 'content type';
-$labels['modtype'] = 'type:';
-$labels['allparts'] = 'all';
-$labels['domain'] = 'domain';
-$labels['localpart'] = 'local part';
-$labels['user'] = 'user';
-$labels['detail'] = 'detail';
-$labels['comparator'] = 'comparator:';
-$labels['default'] = 'default';
-$labels['octet'] = 'strict (octet)';
-$labels['asciicasemap'] = 'case insensitive (ascii-casemap)';
-$labels['asciinumeric'] = 'numeric (ascii-numeric)';
+$labels['advancedopts'] = 'ΠÏοχωÏημένες Ïυθμίσεις';
+$labels['body'] = 'Σώμα';
+$labels['address'] = 'ΔιεÏθυνση';
+$labels['envelope'] = 'φάκελος';
+$labels['modifier'] = 'ΤÏοποποιηση: ';
+$labels['text'] = 'κειμενο';
+$labels['undecoded'] = 'αποκωδικοποιημένο (raw)';
+$labels['contenttype'] = 'ΤÏπος πεÏιεχομένου ';
+$labels['modtype'] = 'τυπος:';
+$labels['allparts'] = 'Όλα';
+$labels['domain'] = 'τομέας';
+$labels['localpart'] = 'τοπικό τμήμα ';
+$labels['user'] = 'χÏηστης';
+$labels['detail'] = 'λεπτομεÏειες';
+$labels['comparator'] = 'σÏγκÏιση:';
+$labels['default'] = 'Ï€Ïοεπιλογή';
+$labels['octet'] = 'αυστηÏή (οκτάδα) ';
+$labels['asciicasemap'] = 'πεζά ή κεφαλαία (ascii-casemap)';
+$labels['asciinumeric'] = 'αÏιθμητικό (ascii-αÏιθμητικο)';
$messages = array();
$messages['filterunknownerror'] = 'Άγνωστο σφάλμα διακομιστή';
@@ -148,30 +148,30 @@ $messages['filterdeleteerror'] = 'Αδυναμία διαγÏαφής φίλτÏ
$messages['filterdeleted'] = 'Το φίλτÏο διαγÏάφηκε επιτυχώς';
$messages['filtersaved'] = 'Το φίλτÏο αποθηκεÏτηκε επιτυχώς';
$messages['filtersaveerror'] = 'Αδυναμία αποθήκευσης φίλτÏου. ΠÏοέκυψε σφάλμα στον διακομιστή';
-$messages['filterdeleteconfirm'] = 'Do you really want to delete selected filter?';
+$messages['filterdeleteconfirm'] = 'Είστε σίγουÏοι ότι θέλετε να διαγÏάψετε το επιλεγμένο φίλτÏο? ';
$messages['ruledeleteconfirm'] = 'Θέλετε όντως να διαγÏάψετε τον επιλεγμένο κανόνα;';
$messages['actiondeleteconfirm'] = 'Θέλετε όντως να διαγÏάψετε την επιλεγμένη ενέÏγεια;';
$messages['forbiddenchars'] = 'Μη επιτÏεπτοί χαÏακτήÏες στο πεδίο';
$messages['cannotbeempty'] = 'Το πεδίο δεν μποÏεί να είναι κενό';
-$messages['ruleexist'] = 'Filter with specified name already exists.';
-$messages['setactivateerror'] = 'Unable to activate selected filters set. Server error occured.';
-$messages['setdeactivateerror'] = 'Unable to deactivate selected filters set. Server error occured.';
-$messages['setdeleteerror'] = 'Unable to delete selected filters set. Server error occured.';
-$messages['setactivated'] = 'Filters set activated successfully.';
-$messages['setdeactivated'] = 'Filters set deactivated successfully.';
-$messages['setdeleted'] = 'Filters set deleted successfully.';
-$messages['setdeleteconfirm'] = 'Are you sure, you want to delete selected filters set?';
-$messages['setcreateerror'] = 'Unable to create filters set. Server error occured.';
-$messages['setcreated'] = 'Filters set created successfully.';
-$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occured.';
-$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occured.';
-$messages['deactivated'] = 'Filter(s) disabled successfully.';
-$messages['activated'] = 'Filter(s) enabled successfully.';
-$messages['moved'] = 'Filter moved successfully.';
-$messages['moveerror'] = 'Unable to move selected filter. Server error occured.';
-$messages['nametoolong'] = 'Name too long.';
-$messages['namereserved'] = 'Reserved name.';
-$messages['setexist'] = 'Set already exists.';
-$messages['nodata'] = 'At least one position must be selected!';
+$messages['ruleexist'] = 'ΦιλτÏο με αυτο το όνομα υπάÏχει ήδη. ';
+$messages['setactivateerror'] = 'Αδυναμία ενεÏγοποιησης επιλεγμενων φιλτÏων. ΠÏοέκυψε σφάλμα στον διακομιστή.';
+$messages['setdeactivateerror'] = 'Αδυναμία απενεÏγοποιησης επιλεγμενων φιλτÏων. ΠÏοέκυψε σφάλμα στον διακομιστή.';
+$messages['setdeleteerror'] = 'Αδυναμία διαγÏαφής φίλτÏων. ΠÏοέκυψε σφάλμα στον διακομιστή';
+$messages['setactivated'] = 'ΦίλτÏα ενεÏγοποιήθηκαν με επιτυχία.';
+$messages['setdeactivated'] = 'ΦίλτÏα απενεÏγοποιήθηκαν με επιτυχία.';
+$messages['setdeleted'] = 'Τα φίλτÏα διαγÏάφηκαν επιτυχώς.';
+$messages['setdeleteconfirm'] = 'Θέλετε όντως να διαγÏάψετε τα επιλεγμένα φιλτÏα?';
+$messages['setcreateerror'] = 'Αδυναμία δημιουÏγιας φιλτÏων. ΠÏοέκυψε σφάλμα στον διακομιστή.';
+$messages['setcreated'] = 'Τα φιλτÏα δημιουÏγηθηκαν επιτυχως.';
+$messages['activateerror'] = 'Αδυναμία ενεÏγοποιησης επιλεγμενου φίλτÏου(ων). ΠÏοέκυψε σφάλμα στον διακομιστή.';
+$messages['deactivateerror'] = 'Αδυναμία απενεÏγοποιησης επιλεγμενου φίλτÏου(ων). ΠÏοέκυψε σφάλμα στον διακομιστή.';
+$messages['deactivated'] = 'Το φιλτÏο(α) απενεÏγοποιηθηκαν επιτυχως.';
+$messages['activated'] = 'Το φίλτÏο(α) ενεÏγοποιηθηκαν επιτυχώς.';
+$messages['moved'] = 'Το φίλτÏο μετακινηθηκε επιτυχώς.';
+$messages['moveerror'] = 'Αδυναμία μετακινησης επιλεγμενου φίλτÏου. ΠÏοέκυψε σφάλμα στον διακομιστή.';
+$messages['nametoolong'] = 'Το όνομα είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿.';
+$messages['namereserved'] = 'Δεσμευμένο όνομα. ';
+$messages['setexist'] = 'Set υπάÏχει ήδη. ';
+$messages['nodata'] = 'Τουλάχιστον μία θέση Ï€Ïέπει να επιλεγεί!';
?>
diff --git a/plugins/managesieve/localization/en_GB.inc b/plugins/managesieve/localization/en_GB.inc
index ff4965ca0..4dd4f7d8b 100644
--- a/plugins/managesieve/localization/en_GB.inc
+++ b/plugins/managesieve/localization/en_GB.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Add';
$labels['del'] = 'Delete';
$labels['sender'] = 'Sender';
$labels['recipient'] = 'Recipient';
-$labels['vacationaddr'] = 'Additional list of recipient e-mails:';
+$labels['vacationaddresses'] = 'Additional list of recipient e-mails (comma separated):';
$labels['vacationdays'] = 'How often send messages (in days):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc
index a37ea7db9..eea764c48 100644
--- a/plugins/managesieve/localization/en_US.inc
+++ b/plugins/managesieve/localization/en_US.inc
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | plugins/managesieve/localization/<lang>.inc |
+ | plugins/managesieve/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Managesieve plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -49,18 +49,14 @@ $labels['messagesendcopy'] = 'Send message copy to';
$labels['messagereply'] = 'Reply with message';
$labels['messagedelete'] = 'Delete message';
$labels['messagediscard'] = 'Discard with message';
-$labels['messagekeep'] = 'Keep message in Inbox';
$labels['messagesrules'] = 'For incoming mail:';
$labels['messagesactions'] = '...execute the following actions:';
$labels['add'] = 'Add';
$labels['del'] = 'Delete';
$labels['sender'] = 'Sender';
$labels['recipient'] = 'Recipient';
-$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
+$labels['vacationaddresses'] = 'My additional e-mail addresse(s) (comma-separated):';
$labels['vacationdays'] = 'How often send messages (in days):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
$labels['vacationreason'] = 'Message body (vacation reason):';
$labels['vacationsubject'] = 'Message subject:';
$labels['rulestop'] = 'Stop evaluating rules';
@@ -84,13 +80,13 @@ $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 is not 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 is not equal to';
+$labels['valuenotequals'] = 'value does not equal';
$labels['setflags'] = 'Set flags to the message';
$labels['addflags'] = 'Add flags to the message';
$labels['removeflags'] = 'Remove flags from the message';
@@ -122,22 +118,6 @@ $labels['filtercreate'] = 'Create filter';
$labels['usedata'] = 'Use following data in the filter:';
$labels['nextstep'] = 'Next Step';
$labels['...'] = '...';
-$labels['currdate'] = 'Current date';
-$labels['datetest'] = 'Date';
-$labels['dateheader'] = 'header:';
-$labels['year'] = 'year';
-$labels['month'] = 'month';
-$labels['day'] = 'day';
-$labels['date'] = 'date (yyyy-mm-dd)';
-$labels['julian'] = 'date (julian)';
-$labels['hour'] = 'hour';
-$labels['minute'] = 'minute';
-$labels['second'] = 'second';
-$labels['time'] = 'time (hh:mm:ss)';
-$labels['iso8601'] = 'date (ISO8601)';
-$labels['std11'] = 'date (RFC2822)';
-$labels['zone'] = 'time-zone';
-$labels['weekday'] = 'weekday (0-6)';
$labels['advancedopts'] = 'Advanced options';
$labels['body'] = 'Body';
$labels['address'] = 'address';
@@ -157,41 +137,38 @@ $labels['default'] = 'default';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'case insensitive (ascii-casemap)';
$labels['asciinumeric'] = 'numeric (ascii-numeric)';
-$labels['index'] = 'index:';
-$labels['indexlast'] = 'backwards';
$messages = array();
$messages['filterunknownerror'] = 'Unknown server error.';
$messages['filterconnerror'] = 'Unable to connect to server.';
-$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured.';
+$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 occured.';
+$messages['filtersaveerror'] = 'Unable to save filter. Server error occurred.';
$messages['filterdeleteconfirm'] = 'Do you really want to delete selected filter?';
$messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?';
$messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?';
$messages['forbiddenchars'] = 'Forbidden characters in field.';
$messages['cannotbeempty'] = 'Field cannot be empty.';
$messages['ruleexist'] = 'Filter with specified name already exists.';
-$messages['setactivateerror'] = 'Unable to activate selected filters set. Server error occured.';
-$messages['setdeactivateerror'] = 'Unable to deactivate selected filters set. Server error occured.';
-$messages['setdeleteerror'] = 'Unable to delete selected filters set. Server error occured.';
+$messages['setactivateerror'] = 'Unable to activate selected filters set. Server error occurred.';
+$messages['setdeactivateerror'] = 'Unable to deactivate selected filters set. Server error occurred.';
+$messages['setdeleteerror'] = 'Unable to delete selected filters set. Server error occurred.';
$messages['setactivated'] = 'Filters set activated successfully.';
$messages['setdeactivated'] = 'Filters set deactivated successfully.';
$messages['setdeleted'] = 'Filters set deleted successfully.';
$messages['setdeleteconfirm'] = 'Are you sure, you want to delete selected filters set?';
-$messages['setcreateerror'] = 'Unable to create filters set. Server error occured.';
+$messages['setcreateerror'] = 'Unable to create filters set. Server error occurred.';
$messages['setcreated'] = 'Filters set created successfully.';
-$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occured.';
-$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occured.';
+$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occurred.';
+$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occurred.';
$messages['deactivated'] = 'Filter(s) disabled successfully.';
$messages['activated'] = 'Filter(s) enabled successfully.';
$messages['moved'] = 'Filter moved successfully.';
-$messages['moveerror'] = 'Unable to move selected filter. Server error occured.';
+$messages['moveerror'] = 'Unable to move selected filter. Server error occurred.';
$messages['nametoolong'] = 'Name too long.';
$messages['namereserved'] = 'Reserved name.';
$messages['setexist'] = 'Set already exists.';
$messages['nodata'] = 'At least one position must be selected!';
-$messages['invaliddateformat'] = 'Invalid date or date part format';
?>
diff --git a/plugins/managesieve/localization/eo.inc b/plugins/managesieve/localization/eo.inc
index 3f54e2391..3ce49ddb2 100644
--- a/plugins/managesieve/localization/eo.inc
+++ b/plugins/managesieve/localization/eo.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Aldoni';
$labels['del'] = 'Forigi';
$labels['sender'] = 'Sendanto';
$labels['recipient'] = 'Ricevanto';
-$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
+$labels['vacationaddresses'] = 'My additional e-mail addresse(s) (comma-separated):';
$labels['vacationdays'] = 'How often send messages (in days):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/es_AR.inc b/plugins/managesieve/localization/es_AR.inc
index e8d90efcf..c9c6e70f8 100644
--- a/plugins/managesieve/localization/es_AR.inc
+++ b/plugins/managesieve/localization/es_AR.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Agregar';
$labels['del'] = 'Eliminar';
$labels['sender'] = 'Remitente';
$labels['recipient'] = 'Destinatario';
-$labels['vacationaddr'] = 'Lista de direcciones de correo de destinatarios adicionales:';
+$labels['vacationaddresses'] = 'Lista de direcciones de correo de destinatarios adicionales (separados por comas):';
$labels['vacationdays'] = 'Cada cuanto enviar mensajes (en días):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/es_ES.inc b/plugins/managesieve/localization/es_ES.inc
index 65ed461c4..69ad9ce8a 100644
--- a/plugins/managesieve/localization/es_ES.inc
+++ b/plugins/managesieve/localization/es_ES.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Agregar';
$labels['del'] = 'Eliminar';
$labels['sender'] = 'Remitente';
$labels['recipient'] = 'Destinatario';
-$labels['vacationaddr'] = 'Mis direcciones de correo electrónico adicionales:';
+$labels['vacationaddresses'] = 'Lista de direcciones de correo de destinatarios adicionales (separados por comas):';
$labels['vacationdays'] = 'Cada cuánto enviar mensajes (en días):';
$labels['vacationinterval'] = 'Cada cuánto enviar mensajes:';
$labels['days'] = 'días';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'contiene más o igual que';
$labels['countislessthan'] = 'contiene menos que';
$labels['countislessthanequal'] = 'contiene menos o igual que';
$labels['countequals'] = 'contiene igual que';
-$labels['countnotequals'] = 'la cuenta no es igual a';
+$labels['countnotequals'] = 'contiene distinto que';
$labels['valueisgreaterthan'] = 'el valor es mayor que';
$labels['valueisgreaterthanequal'] = 'el valor es mayor o igual que';
$labels['valueislessthan'] = 'el valor es menor que';
$labels['valueislessthanequal'] = 'el valor es menor o igual que';
$labels['valueequals'] = 'el valor es igual que';
-$labels['valuenotequals'] = 'el valor no es igual a';
+$labels['valuenotequals'] = 'el valor es distinto que';
$labels['setflags'] = 'Etiquetar el mensaje';
$labels['addflags'] = 'Agregar etiquetas al mensaje';
$labels['removeflags'] = 'Eliminar etiquetas al mensaje';
@@ -121,22 +121,6 @@ $labels['filtercreate'] = 'Crear Filtro';
$labels['usedata'] = 'Usar los siguientes datos en el filtro:';
$labels['nextstep'] = 'Siguiente paso';
$labels['...'] = '...';
-$labels['currdate'] = 'Fecha actual';
-$labels['datetest'] = 'Fecha';
-$labels['dateheader'] = 'cabecera:';
-$labels['year'] = 'año';
-$labels['month'] = 'mes';
-$labels['day'] = 'día';
-$labels['date'] = 'fecha (aaaa-mm-dd)';
-$labels['julian'] = 'fecha (juliano)';
-$labels['hour'] = 'hora';
-$labels['minute'] = 'minuto';
-$labels['second'] = 'segundo';
-$labels['time'] = 'hora (hh:mm:ss)';
-$labels['iso8601'] = 'fecha (ISO8601)';
-$labels['std11'] = 'fecha (RFC2822)';
-$labels['zone'] = 'zona horaria';
-$labels['weekday'] = 'día de la semana (0-6)';
$labels['advancedopts'] = 'Opciones avanzadas';
$labels['body'] = 'Cuerpo del mensaje';
$labels['address'] = 'dirección';
@@ -156,8 +140,6 @@ $labels['default'] = 'predeterminado';
$labels['octet'] = 'estricto (octeto)';
$labels['asciicasemap'] = 'no sensible a mayúsculas (ascii-casemap)';
$labels['asciinumeric'] = 'numerico (ascii-numeric)';
-$labels['index'] = 'índice:';
-$labels['indexlast'] = 'hacia atrás';
$messages = array();
$messages['filterunknownerror'] = 'Error desconocido de servidor.';
@@ -191,6 +173,5 @@ $messages['nametoolong'] = 'Imposible crear el conjunto de filtros. Nombre demas
$messages['namereserved'] = 'Nombre reservado.';
$messages['setexist'] = 'El conjunto ya existe.';
$messages['nodata'] = '¡Al menos una posición debe ser seleccionada!';
-$messages['invaliddateformat'] = 'Fecha o formato de parte de la fecha no válido';
?>
diff --git a/plugins/managesieve/localization/et_EE.inc b/plugins/managesieve/localization/et_EE.inc
index dff15dfb4..5688e08e1 100644
--- a/plugins/managesieve/localization/et_EE.inc
+++ b/plugins/managesieve/localization/et_EE.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Lisa';
$labels['del'] = 'Kustuta';
$labels['sender'] = 'Saatja';
$labels['recipient'] = 'Saaja';
-$labels['vacationaddr'] = 'Minu teised e-posti aadress(id):';
+$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
$labels['vacationdays'] = 'Kui tihti kirju saata (päevades):';
-$labels['vacationinterval'] = 'Kui tihti kirju saata:';
-$labels['days'] = 'päeva';
-$labels['seconds'] = 'sekundit';
+$labels['vacationinterval'] = 'How often send messages:';
+$labels['days'] = 'days';
+$labels['seconds'] = 'seconds';
$labels['vacationreason'] = 'Kirja sisu (puhkuse põhjus):';
$labels['vacationsubject'] = 'Kirja teema:';
$labels['rulestop'] = 'Peata reeglite otsimine';
@@ -83,7 +83,7 @@ $labels['countisgreaterthanequal'] = 'koguarv on suurem kui või võrdne';
$labels['countislessthan'] = 'koguarv on väiksem';
$labels['countislessthanequal'] = 'koguarv on väiksem kui või võrdne';
$labels['countequals'] = 'koguarv on võrdne';
-$labels['countnotequals'] = 'summa ei ole võrdne';
+$labels['countnotequals'] = 'koguarv ei ole võrdne';
$labels['valueisgreaterthan'] = 'väärtus on suurem kui';
$labels['valueisgreaterthanequal'] = 'väärtus on suurem kui või võrdne';
$labels['valueislessthan'] = 'väärtus on väiksem kui';
@@ -121,22 +121,6 @@ $labels['filtercreate'] = 'Loo filter';
$labels['usedata'] = 'Kasuta filtris järgmisi andmeid:';
$labels['nextstep'] = 'Järgmine samm';
$labels['...'] = '…';
-$labels['currdate'] = 'Praegune kuupäev';
-$labels['datetest'] = 'Kuupäev';
-$labels['dateheader'] = 'päis:';
-$labels['year'] = 'aasta';
-$labels['month'] = 'kuu';
-$labels['day'] = 'päev';
-$labels['date'] = 'kuupäev (aaaa-kk-pp)';
-$labels['julian'] = 'kuupäev (Juliuse)';
-$labels['hour'] = 'tund';
-$labels['minute'] = 'minut';
-$labels['second'] = 'sekund';
-$labels['time'] = 'aeg (tt:mm:ss)';
-$labels['iso8601'] = 'kuupäev (ISO8601)';
-$labels['std11'] = 'kuupäev (RCF2822)';
-$labels['zone'] = 'ajatsoon';
-$labels['weekday'] = 'nädalapäev (0-6)';
$labels['advancedopts'] = 'Lisaseadistused';
$labels['body'] = 'Põhitekst';
$labels['address'] = 'aadress';
@@ -156,8 +140,6 @@ $labels['default'] = 'vaikimisi';
$labels['octet'] = 'range (octet)';
$labels['asciicasemap'] = 'tõstutundetu (ascii-casemap)';
$labels['asciinumeric'] = 'numbriline (ascii-numeric)';
-$labels['index'] = 'indeks:';
-$labels['indexlast'] = 'tagasisuunas';
$messages = array();
$messages['filterunknownerror'] = 'Tundmatu serveri tõrge';
@@ -191,6 +173,5 @@ $messages['nametoolong'] = 'Nimi on liiga pikk.';
$messages['namereserved'] = 'Nimi on reserveeritud.';
$messages['setexist'] = 'Kogum on juba olemas.';
$messages['nodata'] = 'Valitud peab olema vähemalt üks asukoht!';
-$messages['invaliddateformat'] = 'Vigane kuupäev või kuupäeva formaat';
?>
diff --git a/plugins/managesieve/localization/eu_ES.inc b/plugins/managesieve/localization/eu_ES.inc
new file mode 100644
index 000000000..fde8f919d
--- /dev/null
+++ b/plugins/managesieve/localization/eu_ES.inc
@@ -0,0 +1,181 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/managesieve/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Managesieve plugin |
+ | Copyright (C) 2012-2013, 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/plugin-managesieve/
+*/
+$labels['filters'] = 'Iragazkiak';
+$labels['managefilters'] = 'Administratu postaren sarrera-iragazkiak';
+$labels['filtername'] = 'Iragazkiaren izena';
+$labels['newfilter'] = 'Iragazki berria';
+$labels['filteradd'] = 'Gehitu iragazkia';
+$labels['filterdel'] = 'Ezabatu iragazkia';
+$labels['moveup'] = 'Mugitu gora';
+$labels['movedown'] = 'Mugitu behera';
+$labels['filterallof'] = 'alderatu datozen arau guztiak';
+$labels['filteranyof'] = 'alderatu datozen arauetako batzuk';
+$labels['filterany'] = 'mezu guztiak';
+$labels['filtercontains'] = 'badu';
+$labels['filternotcontains'] = 'ez du';
+$labels['filteris'] = 'honen berdina da';
+$labels['filterisnot'] = 'ez da honen berdina';
+$labels['filterexists'] = 'badago';
+$labels['filternotexists'] = 'ez dago';
+$labels['filtermatches'] = 'bat datozen adierazpenak';
+$labels['filternotmatches'] = 'bat ez datozen adierazpenak';
+$labels['filterregex'] = 'bat datozen adierazpen erregularrak';
+$labels['filternotregex'] = 'bat ez datozen adierazpen erregularrak';
+$labels['filterunder'] = 'azpian';
+$labels['filterover'] = 'gainean';
+$labels['addrule'] = 'Gehitu araua';
+$labels['delrule'] = 'Ezabatu araua';
+$labels['messagemoveto'] = 'Mugitu mezua hona';
+$labels['messageredirect'] = 'Birbideratu mezua hona ';
+$labels['messagecopyto'] = 'Kopiatu mezua hona';
+$labels['messagesendcopy'] = 'Bidali mezuaren kopia hona';
+$labels['messagereply'] = 'Erantzun mezuarekin';
+$labels['messagedelete'] = 'Ezabatu mezua';
+$labels['messagediscard'] = 'Baztertu mezuarekin';
+$labels['messagesrules'] = 'Sarrerako postarako:';
+$labels['messagesactions'] = '...exekutatu datozen ekintzak:';
+$labels['add'] = 'Gehitu';
+$labels['del'] = 'Ezabatu';
+$labels['sender'] = 'Bidaltzailea';
+$labels['recipient'] = 'Hartzailea';
+$labels['vacationdays'] = 'Zer maiztasunarekin bidaltzen ditu mezuak (egunak)';
+$labels['vacationinterval'] = 'Zenbatero bidali mezuak:';
+$labels['days'] = 'egun';
+$labels['seconds'] = 'segundo';
+$labels['vacationreason'] = 'Mezuaren gorputza (oporrak direla medio):';
+$labels['vacationsubject'] = 'Mezuaren izenburua:';
+$labels['rulestop'] = 'Gelditu arauak ebaluatzen';
+$labels['enable'] = 'Gaitu/Ezgaitu';
+$labels['filterset'] = 'Iragazki-paketea';
+$labels['filtersets'] = 'Iragazki paketeak';
+$labels['filtersetadd'] = 'Gehitu iragazki-paketea';
+$labels['filtersetdel'] = 'Ezabatu uneko iragazki-paketea';
+$labels['filtersetact'] = 'Gaitu uneko iragazki-paketea';
+$labels['filtersetdeact'] = 'Ezgaitu uneko iragazki-paketea';
+$labels['filterdef'] = 'Iragazkiaren definizioa';
+$labels['filtersetname'] = 'Iragazki-paketearen izena';
+$labels['newfilterset'] = 'Iragazki-pakete berria';
+$labels['active'] = 'gaitua';
+$labels['none'] = 'Bat ere ez';
+$labels['fromset'] = 'paketetik';
+$labels['fromfile'] = 'fitxategitik';
+$labels['filterdisabled'] = 'Iragazki ezgaitua';
+$labels['countisgreaterthan'] = 'kopurua handiagoa da hau baino';
+$labels['countisgreaterthanequal'] = 'kopurua hau baino handiagoa edo berdina da';
+$labels['countislessthan'] = 'kopurua hau baino txikiagoa da';
+$labels['countislessthanequal'] = 'kopurua hau baino txikiagoa edo berdina da';
+$labels['countequals'] = 'kopurua honen berdina da';
+$labels['countnotequals'] = 'kopurua ez da honen berdina';
+$labels['valueisgreaterthan'] = 'balioa hau baino handiagoa da';
+$labels['valueisgreaterthanequal'] = 'balioa hau baino handiagoa edo berdina da';
+$labels['valueislessthan'] = 'balioa hau baino txikiagoa da';
+$labels['valueislessthanequal'] = 'balioa hau baino txikiagoa edo berdina da';
+$labels['valueequals'] = 'balioa honen berdina da';
+$labels['valuenotequals'] = 'balioa ez da honen berdina';
+$labels['setflags'] = 'Jarri banderak mezuarik';
+$labels['addflags'] = 'Gehitu banderak mezuari';
+$labels['removeflags'] = 'Ezabatu banderak mezutik';
+$labels['flagread'] = 'Irakurri';
+$labels['flagdeleted'] = 'Ezabatuta';
+$labels['flaganswered'] = 'Erantzunda';
+$labels['flagflagged'] = 'Bandera jarrita';
+$labels['flagdraft'] = 'Ziriborroa';
+$labels['setvariable'] = 'Ezarri aldagaia';
+$labels['setvarname'] = 'Aldagaiaren izena:';
+$labels['setvarvalue'] = 'Aldagaiaren balioa:';
+$labels['setvarmodifiers'] = 'Modifikatzaileak:';
+$labels['varlower'] = 'minuskulan';
+$labels['varupper'] = 'maiuskulan';
+$labels['varlowerfirst'] = 'lehenengo karakterea minuskulan';
+$labels['varupperfirst'] = 'lehenengo karakterea maiuskulan';
+$labels['varquotewildcard'] = 'aipatu karaktere bereziak';
+$labels['varlength'] = 'luzera';
+$labels['notify'] = 'Bidali jakinarazpena';
+$labels['notifyaddress'] = 'e-posta helbidera:';
+$labels['notifybody'] = 'Jakinarazpenaren gorputza:';
+$labels['notifysubject'] = 'Jakinarazpenaren subjektua:';
+$labels['notifyfrom'] = 'Jakinarazpenaren bidaltzailea:';
+$labels['notifyimportance'] = 'Garrantzia:';
+$labels['notifyimportancelow'] = 'baxua';
+$labels['notifyimportancenormal'] = 'normala';
+$labels['notifyimportancehigh'] = 'altua';
+$labels['filtercreate'] = 'Sortu iragazkia';
+$labels['usedata'] = 'Erabili datorren data iragazkian:';
+$labels['nextstep'] = 'Hurrengo urratsa';
+$labels['...'] = '...';
+$labels['currdate'] = 'Uneko data';
+$labels['datetest'] = 'Data';
+$labels['dateheader'] = 'goiburua:';
+$labels['year'] = 'urte';
+$labels['month'] = 'hilabete';
+$labels['day'] = 'egun';
+$labels['date'] = 'data (yyyy-mm-dd)';
+$labels['julian'] = 'data (juliarra)';
+$labels['hour'] = 'ordu';
+$labels['minute'] = 'minutu';
+$labels['second'] = 'segundo';
+$labels['time'] = 'ordua (hh:mm:ss)';
+$labels['iso8601'] = 'data (ISO8601)';
+$labels['std11'] = 'data (RFC2822)';
+$labels['zone'] = 'ordu-zona';
+$labels['weekday'] = 'asteguna (0-6)';
+$labels['advancedopts'] = 'Aukera aurreratuak';
+$labels['body'] = 'Gorputza';
+$labels['address'] = 'helbidea';
+$labels['envelope'] = 'gutun-azala';
+$labels['modifier'] = 'modifikatzailea:';
+$labels['text'] = 'testua';
+$labels['undecoded'] = 'kodetu gabe (gordina)';
+$labels['contenttype'] = 'eduki mota';
+$labels['modtype'] = 'mota:';
+$labels['allparts'] = 'denak';
+$labels['domain'] = 'domeinua';
+$labels['localpart'] = 'zati lokala';
+$labels['user'] = 'erabiltzailea';
+$labels['detail'] = 'xehetasuna';
+$labels['comparator'] = 'alderatzailea:';
+$labels['default'] = 'lehenetsia';
+$labels['octet'] = 'zorrotza (zortzikotea)';
+$labels['asciicasemap'] = 'minuskulak eta maiuskulak (ascii-casemap)';
+$labels['asciinumeric'] = 'numerikoa (ascii-numeric)';
+$labels['index'] = 'indexatu:';
+$labels['indexlast'] = 'atzeraka';
+$messages['filterunknownerror'] = 'Zerbitzari ezezaguna errorea';
+$messages['filterconnerror'] = 'Ezin da konektatu zerbitzariarekin.';
+$messages['filterdeleted'] = 'Iragazkia ongi ezabatu da.';
+$messages['filtersaved'] = 'Iragazkia ongi ezabatu da.';
+$messages['filterdeleteconfirm'] = 'Seguru zaude hautatutako iragazkiak ezabatu nahi dituzula?';
+$messages['ruledeleteconfirm'] = 'Seguru zaude hautatutako arauak ezabatu nahi dituzula?';
+$messages['actiondeleteconfirm'] = 'Seguru zaude hautatutako ekintzak ezabatu nahi dituzula?';
+$messages['forbiddenchars'] = 'Debekatutako karaktereak eremuan.';
+$messages['cannotbeempty'] = 'Eremua ezin da hutsik egon.';
+$messages['ruleexist'] = 'Lehendik badago izen hori duen iragazki bat.';
+$messages['setactivated'] = 'Iragazki paketea ongi aktibatu da.';
+$messages['setdeactivated'] = 'Iragazki paketea ongi desaktibatu da.';
+$messages['setdeleted'] = 'Iragazki paketea ongi ezabatu da.';
+$messages['setdeleteconfirm'] = 'Seguru zaude hautatutako iragazki paketea ezabatu nahi duzula?';
+$messages['setcreated'] = 'Iragazki paketea ongi sortu da.';
+$messages['deactivated'] = 'Iragazkia(k) ongi ezgaitu da.';
+$messages['activated'] = 'Iragazkia(k) ongi gaitu da.';
+$messages['moved'] = 'Iragazkia ongi mugitu da.';
+$messages['nametoolong'] = 'Izen luzeegia.';
+$messages['namereserved'] = 'Izen erreserbatua.';
+$messages['setexist'] = 'Lehendik badago pakete hori.';
+$messages['nodata'] = 'Gutxienez posizio bat hautatu behar da!';
+$messages['invaliddateformat'] = 'Dataren edo dataren zati baten formatua ez da baliozkoa ';
+?>
diff --git a/plugins/managesieve/localization/fa_IR.inc b/plugins/managesieve/localization/fa_IR.inc
index 1c8eace27..ebdc4531d 100644
--- a/plugins/managesieve/localization/fa_IR.inc
+++ b/plugins/managesieve/localization/fa_IR.inc
@@ -55,10 +55,11 @@ $labels['add'] = 'اÙزودن';
$labels['del'] = 'حذÙ';
$labels['sender'] = 'Ùرستنده';
$labels['recipient'] = 'گیرنده';
+$labels['vacationaddresses'] = 'آدرس‌های ایمیل دیگر من (جدا شده با ویرگول):';
$labels['vacationdays'] = 'پیغام ها در Ú†Ù‡ مواقعی Ùرستاده شدند (در روزهای):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'مواقعی که پیغام‌ها ارسال می‌شوند:';
+$labels['days'] = 'روزها';
+$labels['seconds'] = 'ثانیه‌ها';
$labels['vacationreason'] = 'بدنه پیغام (علت مساÙرت):';
$labels['vacationsubject'] = 'موضوع پیغام:';
$labels['rulestop'] = 'توق٠قوانین ارزیابی';
diff --git a/plugins/managesieve/localization/fi_FI.inc b/plugins/managesieve/localization/fi_FI.inc
index 67c819106..f006f6d23 100644
--- a/plugins/managesieve/localization/fi_FI.inc
+++ b/plugins/managesieve/localization/fi_FI.inc
@@ -49,7 +49,6 @@ $labels['messagesendcopy'] = 'Send message copy to';
$labels['messagereply'] = 'Reply with message';
$labels['messagedelete'] = 'Delete message';
$labels['messagediscard'] = 'Discard with message';
-$labels['messagekeep'] = 'Keep message in Inbox';
$labels['messagesrules'] = 'For incoming mail:';
$labels['messagesactions'] = '...execute the following actions:';
$labels['add'] = 'Lisää';
@@ -84,13 +83,13 @@ $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 is not 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 is not equal to';
+$labels['valuenotequals'] = 'value does not equal';
$labels['setflags'] = 'Aseta liput viestiin';
$labels['addflags'] = 'Lisää liput viestiin';
$labels['removeflags'] = 'Poista liput viestistä';
@@ -122,22 +121,6 @@ $labels['filtercreate'] = 'Luo suodatin';
$labels['usedata'] = 'Use following data in the filter:';
$labels['nextstep'] = 'Next Step';
$labels['...'] = '...';
-$labels['currdate'] = 'Current date';
-$labels['datetest'] = 'Date';
-$labels['dateheader'] = 'header:';
-$labels['year'] = 'year';
-$labels['month'] = 'month';
-$labels['day'] = 'day';
-$labels['date'] = 'date (yyyy-mm-dd)';
-$labels['julian'] = 'date (julian)';
-$labels['hour'] = 'hour';
-$labels['minute'] = 'minute';
-$labels['second'] = 'second';
-$labels['time'] = 'time (hh:mm:ss)';
-$labels['iso8601'] = 'date (ISO8601)';
-$labels['std11'] = 'date (RFC2822)';
-$labels['zone'] = 'time-zone';
-$labels['weekday'] = 'weekday (0-6)';
$labels['advancedopts'] = 'Lisävalinnat';
$labels['body'] = 'Body';
$labels['address'] = 'address';
@@ -157,8 +140,6 @@ $labels['default'] = 'oletus';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'case insensitive (ascii-casemap)';
$labels['asciinumeric'] = 'numeric (ascii-numeric)';
-$labels['index'] = 'index:';
-$labels['indexlast'] = 'backwards';
$messages = array();
$messages['filterunknownerror'] = 'Tuntematon palvelinvirhe.';
@@ -192,6 +173,5 @@ $messages['nametoolong'] = 'Nimi on liian pitkä.';
$messages['namereserved'] = 'Reserved name.';
$messages['setexist'] = 'Set already exists.';
$messages['nodata'] = 'At least one position must be selected!';
-$messages['invaliddateformat'] = 'Invalid date or date part format';
?>
diff --git a/plugins/managesieve/localization/fr_FR.inc b/plugins/managesieve/localization/fr_FR.inc
index 3defe9f12..b3f9ec9df 100644
--- a/plugins/managesieve/localization/fr_FR.inc
+++ b/plugins/managesieve/localization/fr_FR.inc
@@ -49,14 +49,13 @@ $labels['messagesendcopy'] = 'Envoyer une copie du message à';
$labels['messagereply'] = 'Répondre avec le message';
$labels['messagedelete'] = 'Supprimer le message';
$labels['messagediscard'] = 'Rejeter avec le message';
-$labels['messagekeep'] = 'Conserver le message dans la boîte de réception';
$labels['messagesrules'] = 'Pour les courriels entrants :';
$labels['messagesactions'] = '...exécuter les actions suivantes:';
$labels['add'] = 'Ajouter';
$labels['del'] = 'Supprimer';
$labels['sender'] = 'Expéditeur';
$labels['recipient'] = 'Destinataire';
-$labels['vacationaddr'] = 'Mon/Mes adresse(s) de courriel additionnelle(s):';
+$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
$labels['vacationdays'] = 'Ne pas renvoyer un message avant (jours) :';
$labels['vacationinterval'] = 'Comment envoyer les messages :';
$labels['days'] = 'jours';
@@ -84,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'total supérieur ou égal à';
$labels['countislessthan'] = 'total inférieur à';
$labels['countislessthanequal'] = 'total inférieur à';
$labels['countequals'] = 'total égal à';
-$labels['countnotequals'] = 'le comptage n\'est pas égal à';
+$labels['countnotequals'] = 'total différent de';
$labels['valueisgreaterthan'] = 'valeur supérieure à';
$labels['valueisgreaterthanequal'] = 'valeur supérieure ou égale à';
$labels['valueislessthan'] = 'valeur inférieure à';
$labels['valueislessthanequal'] = 'valeur inférieure ou égale à';
$labels['valueequals'] = 'valeur égale à';
-$labels['valuenotequals'] = 'la valeur n\'est pas égale à';
+$labels['valuenotequals'] = 'valeur différente de';
$labels['setflags'] = 'Mettre les marqueurs au message';
$labels['addflags'] = 'Ajouter les marqueurs au message';
$labels['removeflags'] = 'Supprimer les marqueurs du message';
@@ -122,22 +121,6 @@ $labels['filtercreate'] = 'Créer un filtre';
$labels['usedata'] = 'Utiliser les informations suivantes dans le filtre';
$labels['nextstep'] = 'Étape suivante';
$labels['...'] = '...';
-$labels['currdate'] = 'Date actuelle';
-$labels['datetest'] = 'Date';
-$labels['dateheader'] = 'header:';
-$labels['year'] = 'année';
-$labels['month'] = 'mois';
-$labels['day'] = 'jour';
-$labels['date'] = 'date (yyyy-mm-dd)';
-$labels['julian'] = 'date (julien)';
-$labels['hour'] = 'heure';
-$labels['minute'] = 'minute';
-$labels['second'] = 'seconde';
-$labels['time'] = 'heure (hh:mm:ss)';
-$labels['iso8601'] = 'date (ISO8601)';
-$labels['std11'] = 'date (RFC2822)';
-$labels['zone'] = 'fuseau horaire';
-$labels['weekday'] = 'jour de la semaine (0-6)';
$labels['advancedopts'] = 'Options avancées';
$labels['body'] = 'Corps du message';
$labels['address'] = 'adresse';
@@ -157,8 +140,6 @@ $labels['default'] = 'par défaut';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'insensible à la casse (ascii-casemap)';
$labels['asciinumeric'] = 'numérique (ascii-numeric)';
-$labels['index'] = 'index:';
-$labels['indexlast'] = 'retour arrière';
$messages = array();
$messages['filterunknownerror'] = 'Erreur du serveur inconnue';
@@ -192,6 +173,5 @@ $messages['nametoolong'] = 'Nom trop long.';
$messages['namereserved'] = 'Nom réservé.';
$messages['setexist'] = 'Ce groupe existe déjà.';
$messages['nodata'] = 'Au moins un élément doit être selectionné !';
-$messages['invaliddateformat'] = 'Date non valide ou format d\'une partie de la date';
?>
diff --git a/plugins/managesieve/localization/gl_ES.inc b/plugins/managesieve/localization/gl_ES.inc
index 185490a94..fef5ed718 100644
--- a/plugins/managesieve/localization/gl_ES.inc
+++ b/plugins/managesieve/localization/gl_ES.inc
@@ -34,10 +34,10 @@ $labels['filteris'] = 'é igual a';
$labels['filterisnot'] = 'non é igual a';
$labels['filterexists'] = 'existe';
$labels['filternotexists'] = 'non existe';
-$labels['filtermatches'] = 'matches expression';
-$labels['filternotmatches'] = 'not matches expression';
-$labels['filterregex'] = 'matches regular expression';
-$labels['filternotregex'] = 'not matches regular expression';
+$labels['filtermatches'] = 'casa coa expresión';
+$labels['filternotmatches'] = 'non casa coa expresión';
+$labels['filterregex'] = 'casa coa expresión regular';
+$labels['filternotregex'] = 'non casa coa expresión regular';
$labels['filterunder'] = 'baixo';
$labels['filterover'] = 'sobre';
$labels['addrule'] = 'Engadir regra';
@@ -55,17 +55,17 @@ $labels['add'] = 'Engadir';
$labels['del'] = 'Eliminar';
$labels['sender'] = 'Remitente';
$labels['recipient'] = 'Destinatario';
-$labels['vacationaddr'] = 'Lista de enderezos de correo de destinatarios adicionais:';
+$labels['vacationaddresses'] = 'Lista de enderezos de correo de destinatarios adicionais (separados por comas):';
$labels['vacationdays'] = 'Cada canto enviar mensaxes (en días):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Con qué frecuencia vanse enviar mensaxes:';
+$labels['days'] = 'días';
+$labels['seconds'] = 'segundos';
$labels['vacationreason'] = 'Corpo da mensaxe (razón de vacacións):';
-$labels['vacationsubject'] = 'Message subject:';
+$labels['vacationsubject'] = 'Asunto da mensaxe:';
$labels['rulestop'] = 'Parar de avaliar regras';
$labels['enable'] = 'Activar/Desactivar';
$labels['filterset'] = 'Conxunto de filtros';
-$labels['filtersets'] = 'Filter sets';
+$labels['filtersets'] = 'Conxunto de filtros';
$labels['filtersetadd'] = 'Engadir un conxunto de filtros';
$labels['filtersetdel'] = 'Eliminar o conxunto de filtros actual';
$labels['filtersetact'] = 'Activar o conxunto de filtros actual';
@@ -78,68 +78,68 @@ $labels['none'] = 'ningún';
$labels['fromset'] = 'de conxunto';
$labels['fromfile'] = 'de arquivo';
$labels['filterdisabled'] = 'Filtro desactivado';
-$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['countisgreaterthan'] = 'a conta é meirande que';
+$labels['countisgreaterthanequal'] = 'a conta é meirande ou igual a';
+$labels['countislessthan'] = 'a conta é menor que';
+$labels['countislessthanequal'] = 'a conta é menor ou igual a';
+$labels['countequals'] = 'a conta é igual a';
+$labels['countnotequals'] = 'a conta non é igual a';
+$labels['valueisgreaterthan'] = 'o valor é meirande que ';
+$labels['valueisgreaterthanequal'] = 'o valor é meirande ou igual a';
+$labels['valueislessthan'] = 'o valor é menor que';
+$labels['valueislessthanequal'] = 'o valor é menor ou igual a';
+$labels['valueequals'] = 'o valor é igual a';
+$labels['valuenotequals'] = 'o valor non é igual a';
$labels['setflags'] = 'Set flags to the message';
$labels['addflags'] = 'Add flags to the message';
$labels['removeflags'] = 'Remove flags from the message';
-$labels['flagread'] = 'Read';
-$labels['flagdeleted'] = 'Deleted';
-$labels['flaganswered'] = 'Answered';
-$labels['flagflagged'] = 'Flagged';
-$labels['flagdraft'] = 'Draft';
-$labels['setvariable'] = 'Set variable';
-$labels['setvarname'] = 'Variable name:';
-$labels['setvarvalue'] = 'Variable value:';
-$labels['setvarmodifiers'] = 'Modifiers:';
-$labels['varlower'] = 'lower-case';
-$labels['varupper'] = 'upper-case';
-$labels['varlowerfirst'] = 'first character lower-case';
-$labels['varupperfirst'] = 'first character upper-case';
+$labels['flagread'] = 'Lidas';
+$labels['flagdeleted'] = 'Eliminadas';
+$labels['flaganswered'] = 'Respostadas';
+$labels['flagflagged'] = 'Marcadas';
+$labels['flagdraft'] = 'Borrador';
+$labels['setvariable'] = 'Establecer variable';
+$labels['setvarname'] = 'Nome da variable:';
+$labels['setvarvalue'] = 'Valor da variable:';
+$labels['setvarmodifiers'] = 'Modificadores:';
+$labels['varlower'] = 'minúscula';
+$labels['varupper'] = 'maiúscula';
+$labels['varlowerfirst'] = 'primeira letra minúscula';
+$labels['varupperfirst'] = 'primeira letra maiúscula';
$labels['varquotewildcard'] = 'quote special characters';
-$labels['varlength'] = 'length';
-$labels['notify'] = 'Send notification';
-$labels['notifyaddress'] = 'To e-mail address:';
-$labels['notifybody'] = 'Notification body:';
-$labels['notifysubject'] = 'Notification subject:';
-$labels['notifyfrom'] = 'Notification sender:';
-$labels['notifyimportance'] = 'Importance:';
-$labels['notifyimportancelow'] = 'low';
+$labels['varlength'] = 'lonxitude';
+$labels['notify'] = 'Enviar notificación';
+$labels['notifyaddress'] = 'Destinatario:';
+$labels['notifybody'] = 'Corpo da notificación:';
+$labels['notifysubject'] = 'Asunto da notificación:';
+$labels['notifyfrom'] = 'Remitente da notificación:';
+$labels['notifyimportance'] = 'Importancia:';
+$labels['notifyimportancelow'] = 'baixa';
$labels['notifyimportancenormal'] = 'normal';
-$labels['notifyimportancehigh'] = 'high';
-$labels['filtercreate'] = 'Create filter';
-$labels['usedata'] = 'Use following data in the filter:';
-$labels['nextstep'] = 'Next Step';
+$labels['notifyimportancehigh'] = 'alta';
+$labels['filtercreate'] = 'Crear filtro';
+$labels['usedata'] = 'Usar os seguintes datos no filtro:';
+$labels['nextstep'] = 'Seguinte paso';
$labels['...'] = '...';
-$labels['advancedopts'] = 'Advanced options';
-$labels['body'] = 'Body';
-$labels['address'] = 'address';
+$labels['advancedopts'] = 'Opcións avanzadas';
+$labels['body'] = 'Corpo';
+$labels['address'] = 'enderezo';
$labels['envelope'] = 'envelope';
-$labels['modifier'] = 'modifier:';
-$labels['text'] = 'text';
-$labels['undecoded'] = 'undecoded (raw)';
-$labels['contenttype'] = 'content type';
-$labels['modtype'] = 'type:';
-$labels['allparts'] = 'all';
-$labels['domain'] = 'domain';
-$labels['localpart'] = 'local part';
-$labels['user'] = 'user';
-$labels['detail'] = 'detail';
-$labels['comparator'] = 'comparator:';
-$labels['default'] = 'default';
-$labels['octet'] = 'strict (octet)';
-$labels['asciicasemap'] = 'case insensitive (ascii-casemap)';
-$labels['asciinumeric'] = 'numeric (ascii-numeric)';
+$labels['modifier'] = 'modificador:';
+$labels['text'] = 'texto';
+$labels['undecoded'] = 'sen codificar (en bruto)';
+$labels['contenttype'] = 'tipo de contido';
+$labels['modtype'] = 'tipo:';
+$labels['allparts'] = 'todos';
+$labels['domain'] = 'dominio';
+$labels['localpart'] = 'parte local';
+$labels['user'] = 'usuario';
+$labels['detail'] = 'detalle';
+$labels['comparator'] = 'comparador';
+$labels['default'] = 'defecto';
+$labels['octet'] = 'estricto (octeto)';
+$labels['asciicasemap'] = 'non sensible a maiúsculas/minúsculas (ascii-casemap)';
+$labels['asciinumeric'] = 'numérico (ascii-numerico)';
$messages = array();
$messages['filterunknownerror'] = 'Erro descoñecido servidor';
@@ -153,7 +153,7 @@ $messages['ruledeleteconfirm'] = 'Está seguro de que desexa eliminar a regra se
$messages['actiondeleteconfirm'] = 'Está seguro de que desexa eliminar a acción seleccionada?';
$messages['forbiddenchars'] = 'Caracteres non permitidos no campo';
$messages['cannotbeempty'] = 'O campo non pode estar baleiro';
-$messages['ruleexist'] = 'Filter with specified name already exists.';
+$messages['ruleexist'] = 'Xa existe un filtro con nome especificado.';
$messages['setactivateerror'] = 'Imposible activar o conxunto de filtros seleccionado. Ocurriu un erro no servidor';
$messages['setdeactivateerror'] = 'Imposible desactivar o conxunto de filtros seleccionado. Ocurriu un error no servidor';
$messages['setdeleteerror'] = 'Imposible eliminar o conxunto de filtros seleccionado. Ocurriu un error no servidor';
@@ -163,15 +163,15 @@ $messages['setdeleted'] = 'O Conxunto de filtros borrouse con éxito';
$messages['setdeleteconfirm'] = 'Está seguro de que desexa eliminar o conxunto de filtros seleccionado?';
$messages['setcreateerror'] = 'Imposible crear o conxunto de filtros. Ocurriu un error no servidor';
$messages['setcreated'] = 'Conxunto de filtros creado con éxito';
-$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occured.';
-$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occured.';
-$messages['deactivated'] = 'Filter(s) disabled successfully.';
-$messages['activated'] = 'Filter(s) enabled successfully.';
-$messages['moved'] = 'Filter moved successfully.';
-$messages['moveerror'] = 'Unable to move selected filter. Server error occured.';
+$messages['activateerror'] = 'Non foi posible activar o(s) filtro(s) seleccionado(s). Ocurriu un erro no servidor.';
+$messages['deactivateerror'] = 'Non foi posible desactivar o(s) filtro(s) seleccionado(s). Ocurriu un erro no servidor.';
+$messages['deactivated'] = 'Desactiváronse os filtros correctamente.';
+$messages['activated'] = 'Activáronse os filtros correctamente';
+$messages['moved'] = 'Moveuse correctamente o filtro.';
+$messages['moveerror'] = 'Non foi posible mover o(s) filtro(s) seleccionado(s). Ocurriu un erro no servidor.';
$messages['nametoolong'] = 'Imposible crear o conxunto de filtros. O nome é longo de máis';
-$messages['namereserved'] = 'Reserved name.';
+$messages['namereserved'] = 'Nome reservado';
$messages['setexist'] = 'Set already exists.';
-$messages['nodata'] = 'At least one position must be selected!';
+$messages['nodata'] = 'É preciso seleccionar polo menos unha posición!';
?>
diff --git a/plugins/managesieve/localization/he_IL.inc b/plugins/managesieve/localization/he_IL.inc
index 932d4e5d6..aa736ac87 100644
--- a/plugins/managesieve/localization/he_IL.inc
+++ b/plugins/managesieve/localization/he_IL.inc
@@ -55,10 +55,11 @@ $labels['add'] = 'הוספה';
$labels['del'] = 'מחיקה';
$labels['sender'] = 'השולח';
$labels['recipient'] = 'הנמען';
+$labels['vacationaddresses'] = 'כתובות דו×"ל נוספות שלי (מופרדות ×¢"×™ פסיקי×)';
$labels['vacationdays'] = 'ב×יזו תדירות ( ×‘×™×ž×™× ) לשלוח הודעות:';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'ב×יזו תדירות לשלוח ההודעה';
+$labels['days'] = 'ימי×';
+$labels['seconds'] = 'שניות';
$labels['vacationreason'] = 'גוף ההודעה (סיבת החופשה):';
$labels['vacationsubject'] = '× ×•×©× ×”×”×•×“×¢×”:';
$labels['rulestop'] = 'עצירה של בחינת הכללי×';
diff --git a/plugins/managesieve/localization/hr_HR.inc b/plugins/managesieve/localization/hr_HR.inc
index 77b664b5f..64b9bef62 100644
--- a/plugins/managesieve/localization/hr_HR.inc
+++ b/plugins/managesieve/localization/hr_HR.inc
@@ -49,14 +49,13 @@ $labels['messagesendcopy'] = 'Pošalji kopiju poruke na';
$labels['messagereply'] = 'Odgovori sa porukom';
$labels['messagedelete'] = 'Obriši poruku';
$labels['messagediscard'] = 'Otkaži sa porukom';
-$labels['messagekeep'] = 'Keep message in Inbox';
$labels['messagesrules'] = 'Za pristigle poruke:';
$labels['messagesactions'] = '...primijeni sljedeće akcije:';
$labels['add'] = 'Dodaj';
$labels['del'] = 'Obriši';
$labels['sender'] = 'Pošiljatelj';
$labels['recipient'] = 'Primatelj';
-$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
+$labels['vacationaddresses'] = 'Dodatna lista primatelja (odvojenih zarezom):';
$labels['vacationdays'] = 'Koliko Äesto slati poruku (u danima):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
@@ -84,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'brojaÄ je veći ili jednak od';
$labels['countislessthan'] = 'brojaÄ je manji od';
$labels['countislessthanequal'] = 'brojaÄ je manji ili jednak od';
$labels['countequals'] = 'brojaÄ je jednak';
-$labels['countnotequals'] = 'count is not equal to';
+$labels['countnotequals'] = 'brojaÄ nije jednak';
$labels['valueisgreaterthan'] = 'vrijednost je veća od';
$labels['valueisgreaterthanequal'] = 'vrijednost je veća ili jednaka od';
$labels['valueislessthan'] = 'vrijednost je manja od';
$labels['valueislessthanequal'] = 'vrijednost je manja ili jednaka od';
$labels['valueequals'] = 'vrijednost je jednaka';
-$labels['valuenotequals'] = 'value is not equal to';
+$labels['valuenotequals'] = 'vrijednost nije jednaka';
$labels['setflags'] = 'Postavi oznake na poruku';
$labels['addflags'] = 'Dodaj oznake na poruku';
$labels['removeflags'] = 'Ukloni oznake sa poruke';
@@ -122,22 +121,6 @@ $labels['filtercreate'] = 'Stvori filter';
$labels['usedata'] = 'Koristi podatke za filter:';
$labels['nextstep'] = 'Idući korak';
$labels['...'] = '…';
-$labels['currdate'] = 'Current date';
-$labels['datetest'] = 'Date';
-$labels['dateheader'] = 'header:';
-$labels['year'] = 'year';
-$labels['month'] = 'month';
-$labels['day'] = 'day';
-$labels['date'] = 'date (yyyy-mm-dd)';
-$labels['julian'] = 'date (julian)';
-$labels['hour'] = 'hour';
-$labels['minute'] = 'minute';
-$labels['second'] = 'second';
-$labels['time'] = 'time (hh:mm:ss)';
-$labels['iso8601'] = 'date (ISO8601)';
-$labels['std11'] = 'date (RFC2822)';
-$labels['zone'] = 'time-zone';
-$labels['weekday'] = 'weekday (0-6)';
$labels['advancedopts'] = 'Napredne postavke';
$labels['body'] = 'Tijelo poruke';
$labels['address'] = 'adresa';
@@ -157,8 +140,6 @@ $labels['default'] = 'preddefinirano';
$labels['octet'] = 'strogo (oktet)';
$labels['asciicasemap'] = 'neosjetljivo na veliÄinu slova (ascii-casemap)';
$labels['asciinumeric'] = 'numeriÄki (ascii-numeric)';
-$labels['index'] = 'index:';
-$labels['indexlast'] = 'backwards';
$messages = array();
$messages['filterunknownerror'] = 'Nepoznata greška na poslužitelju';
@@ -192,6 +173,5 @@ $messages['nametoolong'] = 'Nemoguće napraviti grupu filtera. Naziv je predugaÄ
$messages['namereserved'] = 'Rezervirano ime.';
$messages['setexist'] = 'Skup već postoji.';
$messages['nodata'] = 'Barem jedan pozicija mora biti odabrana!';
-$messages['invaliddateformat'] = 'Invalid date or date part format';
?>
diff --git a/plugins/managesieve/localization/hu_HU.inc b/plugins/managesieve/localization/hu_HU.inc
index ea59fa717..9d39ffac3 100644
--- a/plugins/managesieve/localization/hu_HU.inc
+++ b/plugins/managesieve/localization/hu_HU.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Hozzáadás';
$labels['del'] = 'Törlés';
$labels['sender'] = 'Feladó';
$labels['recipient'] = 'Címzett';
-$labels['vacationaddr'] = 'További címzettek:';
+$labels['vacationaddresses'] = 'További címzettek (vesszővel elválasztva):';
$labels['vacationdays'] = 'Válaszüzenet küldése ennyi naponként:';
$labels['vacationinterval'] = 'Milyen gyakran küld üzeneteket:';
$labels['days'] = 'napok';
diff --git a/plugins/managesieve/localization/hy_AM.inc b/plugins/managesieve/localization/hy_AM.inc
index 68837b065..908175f1d 100644
--- a/plugins/managesieve/localization/hy_AM.inc
+++ b/plugins/managesieve/localization/hy_AM.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Ô±Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬';
$labels['del'] = 'Õ‹Õ¶Õ»Õ¥Õ¬';
$labels['sender'] = 'ÕˆÖ‚Õ²Õ¡Ö€Õ¯Õ¸Õ²';
$labels['recipient'] = 'ÕÕ¿Õ¡ÖÕ¸Õ²';
-$labels['vacationaddr'] = 'Ô»Õ´ Õ°Õ¡Õ¾Õ¥Õ¬ÕµÕ¡Õ¬ Õ§Õ¬ÖƒÕ¸Õ½Õ¿Õ« Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€.';
+$labels['vacationaddresses'] = 'Ô»Õ´ Õ°Õ¡Õ¾Õ¥Õ¬ÕµÕ¡Õ¬ Õ§Õ¬ÖƒÕ¸Õ½Õ¿Õ« Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€ (Õ¢Õ¡ÕªÕ¡Õ¶Õ¾Õ¡Õ® Õ½Õ¿Õ¸Ö€Õ¡Õ¯Õ¥Õ¿Õ¶Õ¥Ö€Õ¸Õ¾).';
$labels['vacationdays'] = 'Ô»Õ¶Õ¹ Õ°Õ¡Õ³Õ¡Õ­Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¸Ö‚Õ²Õ¡Ö€Õ¯Õ¥Õ¬ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ (Ö…Ö€Õ¥Ö€)`';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/ia.inc b/plugins/managesieve/localization/ia.inc
index 945de27d8..45f6e5263 100644
--- a/plugins/managesieve/localization/ia.inc
+++ b/plugins/managesieve/localization/ia.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Add';
$labels['del'] = 'Delete';
$labels['sender'] = 'Sender';
$labels['recipient'] = 'Recipient';
-$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
+$labels['vacationaddresses'] = 'My additional e-mail addresse(s) (comma-separated):';
$labels['vacationdays'] = 'How often send messages (in days):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/id_ID.inc b/plugins/managesieve/localization/id_ID.inc
index d98a326c1..a30c2a0b0 100644
--- a/plugins/managesieve/localization/id_ID.inc
+++ b/plugins/managesieve/localization/id_ID.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Tambah';
$labels['del'] = 'Hapus';
$labels['sender'] = 'Pengirim';
$labels['recipient'] = 'Penerima';
-$labels['vacationaddr'] = 'Alamat email tambahan saya:';
+$labels['vacationaddresses'] = 'Alamat email tambahan saya (dipisahkan koma):';
$labels['vacationdays'] = 'Seberapa sering mengirim pesan (dalam hari):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/it_IT.inc b/plugins/managesieve/localization/it_IT.inc
index 9fc7dc570..0ac4f293a 100644
--- a/plugins/managesieve/localization/it_IT.inc
+++ b/plugins/managesieve/localization/it_IT.inc
@@ -49,14 +49,13 @@ $labels['messagesendcopy'] = 'Invia copia a';
$labels['messagereply'] = 'Rispondi con il messaggio';
$labels['messagedelete'] = 'Elimina il messaggio';
$labels['messagediscard'] = 'Rifiuta con messaggio';
-$labels['messagekeep'] = 'Mantieni il messaggio in Posta ricevuta';
$labels['messagesrules'] = 'Per la posta in arrivo';
$labels['messagesactions'] = '...esegui le seguenti azioni:';
$labels['add'] = 'Aggiungi';
$labels['del'] = 'Elimina';
$labels['sender'] = 'Mittente';
$labels['recipient'] = 'Destinatario';
-$labels['vacationaddr'] = 'Account email aggiuntivo(i):';
+$labels['vacationaddresses'] = 'Lista di indirizzi e-mail di destinatari addizionali (separati da virgola):';
$labels['vacationdays'] = 'Ogni quanti giorni ribadire il messaggio allo stesso mittente';
$labels['vacationinterval'] = 'Ogni quanto tempo inviare i messaggi:';
$labels['days'] = 'giorni';
@@ -84,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'somma maggiore uguale a';
$labels['countislessthan'] = 'somma minore di';
$labels['countislessthanequal'] = 'somma minore o uguale a';
$labels['countequals'] = 'somma uguale a';
-$labels['countnotequals'] = 'il conteggio non è uguale a';
+$labels['countnotequals'] = 'somma diversa da';
$labels['valueisgreaterthan'] = 'valore maggiore di';
$labels['valueisgreaterthanequal'] = 'valore maggiore uguale a';
$labels['valueislessthan'] = 'valore minore di';
$labels['valueislessthanequal'] = 'valore minore uguale di';
$labels['valueequals'] = 'valore uguale a';
-$labels['valuenotequals'] = 'il valore non è uguale a';
+$labels['valuenotequals'] = 'valore diverso da';
$labels['setflags'] = 'Contrassegna il messaggio';
$labels['addflags'] = 'aggiungi flag al messaggio';
$labels['removeflags'] = 'togli flag dal messaggio';
@@ -122,22 +121,6 @@ $labels['filtercreate'] = 'Crea filtro';
$labels['usedata'] = 'utilizza i seguenti dati nel filtro';
$labels['nextstep'] = 'passo successivo';
$labels['...'] = '...';
-$labels['currdate'] = 'Data attuale';
-$labels['datetest'] = 'Data';
-$labels['dateheader'] = 'intestazione:';
-$labels['year'] = 'anno';
-$labels['month'] = 'mese';
-$labels['day'] = 'giorno';
-$labels['date'] = 'data (aaaa-mm-gg)';
-$labels['julian'] = 'data (Giuliana)';
-$labels['hour'] = 'ora';
-$labels['minute'] = 'minuto';
-$labels['second'] = 'secondo';
-$labels['time'] = 'tempo (hh:mm:ss)';
-$labels['iso8601'] = 'data (ISO8601)';
-$labels['std11'] = 'data (RFC2822)';
-$labels['zone'] = 'fuso orario';
-$labels['weekday'] = 'giorno della settimana (0-6)';
$labels['advancedopts'] = 'Opzioni avanzate';
$labels['body'] = 'Corpo';
$labels['address'] = 'indirizzo';
@@ -157,8 +140,6 @@ $labels['default'] = 'predefinito';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'non differenziare maiuscole/minuscole (ascii-casemap)';
$labels['asciinumeric'] = 'numerico';
-$labels['index'] = 'indice:';
-$labels['indexlast'] = 'indietro';
$messages = array();
$messages['filterunknownerror'] = 'Errore sconosciuto del server';
@@ -192,6 +173,5 @@ $messages['nametoolong'] = 'Impossibile creare il gruppo: Nome troppo lungo';
$messages['namereserved'] = 'nome riservato';
$messages['setexist'] = 'Il gruppo esiste già';
$messages['nodata'] = 'selezionare almeno una posizione';
-$messages['invaliddateformat'] = 'Formato della data non valido';
?>
diff --git a/plugins/managesieve/localization/ja_JP.inc b/plugins/managesieve/localization/ja_JP.inc
index c8927d3f2..0cd4f44b9 100644
--- a/plugins/managesieve/localization/ja_JP.inc
+++ b/plugins/managesieve/localization/ja_JP.inc
@@ -55,7 +55,7 @@ $labels['add'] = '追加';
$labels['del'] = '削除';
$labels['sender'] = 'é€ä¿¡è€…';
$labels['recipient'] = '宛先';
-$labels['vacationaddr'] = 'é›»å­ãƒ¡ãƒ¼ãƒ«ã®å®›å…ˆã®è¿½åŠ ã®ãƒªã‚¹ãƒˆ:';
+$labels['vacationaddresses'] = 'é›»å­ãƒ¡ãƒ¼ãƒ«ã®å®›å…ˆã®(コンマ区切ã£ãŸ)追加ã®ãƒªã‚¹ãƒˆ:';
$labels['vacationdays'] = 'メッセージを(1æ—¥ã«)é€ä¿¡ã™ã‚‹é »åº¦:';
$labels['vacationinterval'] = 'メッセージをé€ä¿¡ã™ã‚‹é »åº¦:';
$labels['days'] = 'æ—¥';
diff --git a/plugins/managesieve/localization/ko_KR.inc b/plugins/managesieve/localization/ko_KR.inc
index 1085f624d..5ab4fc220 100644
--- a/plugins/managesieve/localization/ko_KR.inc
+++ b/plugins/managesieve/localization/ko_KR.inc
@@ -55,7 +55,7 @@ $labels['add'] = '추가';
$labels['del'] = '삭제';
$labels['sender'] = '발신ì¸';
$labels['recipient'] = '수신ì¸';
-$labels['vacationaddr'] = 'ë‚˜ì˜ ì¶”ê°€ ì´ë©”ì¼ ì£¼ì†Œ:';
+$labels['vacationaddresses'] = 'ë‚˜ì˜ ì¶”ê°€ ì´ë©”ì¼ ì£¼ì†Œ (쉼표로 구분ë¨):';
$labels['vacationdays'] = '메시지 발신 주기 (ì¼):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/lb_LU.inc b/plugins/managesieve/localization/lb_LU.inc
index 7494c0eb5..621fff831 100644
--- a/plugins/managesieve/localization/lb_LU.inc
+++ b/plugins/managesieve/localization/lb_LU.inc
@@ -15,8 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-managesieve/
*/
-
-
$labels['filters'] = 'Filteren';
$labels['managefilters'] = 'Filtere geréieren fir Mailen déi erakommen';
$labels['filtername'] = 'Numm vum Filter';
@@ -34,10 +32,6 @@ $labels['filteris'] = 'ass gläich';
$labels['filterisnot'] = 'ass net gläich';
$labels['filterexists'] = 'existéiert';
$labels['filternotexists'] = 'existéiert net';
-$labels['filtermatches'] = 'matches expression';
-$labels['filternotmatches'] = 'not matches expression';
-$labels['filterregex'] = 'matches regular expression';
-$labels['filternotregex'] = 'not matches regular expression';
$labels['filterunder'] = 'ënner';
$labels['filterover'] = 'iwwer';
$labels['addrule'] = 'Reegel dobäisetzen';
@@ -48,149 +42,8 @@ $labels['messagecopyto'] = 'Message kopéieren an';
$labels['messagesendcopy'] = 'Kopie vum Message schécken un';
$labels['messagereply'] = 'Mat dësem Message äntweren';
$labels['messagedelete'] = 'Message läschen';
-$labels['messagediscard'] = 'Discard with message';
-$labels['messagesrules'] = 'For incoming mail:';
-$labels['messagesactions'] = '...execute the following actions:';
$labels['add'] = 'Dobäisetzen';
$labels['del'] = 'Läschen';
$labels['sender'] = 'Ofsender';
$labels['recipient'] = 'Empfänger';
-$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
-$labels['vacationdays'] = 'How often send messages (in days):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
-$labels['vacationreason'] = 'Message body (vacation reason):';
-$labels['vacationsubject'] = 'Message subject:';
-$labels['rulestop'] = 'Stop evaluating rules';
-$labels['enable'] = 'Enable/Disable';
-$labels['filterset'] = 'Filters set';
-$labels['filtersets'] = 'Filter sets';
-$labels['filtersetadd'] = 'Add filters set';
-$labels['filtersetdel'] = 'Delete current filters set';
-$labels['filtersetact'] = 'Activate current filters set';
-$labels['filtersetdeact'] = 'Deactivate current filters set';
-$labels['filterdef'] = 'Filter definition';
-$labels['filtersetname'] = 'Filters set name';
-$labels['newfilterset'] = 'New filters set';
-$labels['active'] = 'active';
-$labels['none'] = 'none';
-$labels['fromset'] = 'from set';
-$labels['fromfile'] = 'from file';
-$labels['filterdisabled'] = 'Filter disabled';
-$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 is not equal to';
-$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 is not equal to';
-$labels['setflags'] = 'Set flags to the message';
-$labels['addflags'] = 'Add flags to the message';
-$labels['removeflags'] = 'Remove flags from the message';
-$labels['flagread'] = 'Read';
-$labels['flagdeleted'] = 'Deleted';
-$labels['flaganswered'] = 'Answered';
-$labels['flagflagged'] = 'Flagged';
-$labels['flagdraft'] = 'Draft';
-$labels['setvariable'] = 'Set variable';
-$labels['setvarname'] = 'Variable name:';
-$labels['setvarvalue'] = 'Variable value:';
-$labels['setvarmodifiers'] = 'Modifiers:';
-$labels['varlower'] = 'lower-case';
-$labels['varupper'] = 'upper-case';
-$labels['varlowerfirst'] = 'first character lower-case';
-$labels['varupperfirst'] = 'first character upper-case';
-$labels['varquotewildcard'] = 'quote special characters';
-$labels['varlength'] = 'length';
-$labels['notify'] = 'Send notification';
-$labels['notifyaddress'] = 'To e-mail address:';
-$labels['notifybody'] = 'Notification body:';
-$labels['notifysubject'] = 'Notification subject:';
-$labels['notifyfrom'] = 'Notification sender:';
-$labels['notifyimportance'] = 'Importance:';
-$labels['notifyimportancelow'] = 'low';
-$labels['notifyimportancenormal'] = 'normal';
-$labels['notifyimportancehigh'] = 'high';
-$labels['filtercreate'] = 'Create filter';
-$labels['usedata'] = 'Use following data in the filter:';
-$labels['nextstep'] = 'Next Step';
-$labels['...'] = '...';
-$labels['currdate'] = 'Current date';
-$labels['datetest'] = 'Date';
-$labels['dateheader'] = 'header:';
-$labels['year'] = 'year';
-$labels['month'] = 'month';
-$labels['day'] = 'day';
-$labels['date'] = 'date (yyyy-mm-dd)';
-$labels['julian'] = 'date (julian)';
-$labels['hour'] = 'hour';
-$labels['minute'] = 'minute';
-$labels['second'] = 'second';
-$labels['time'] = 'time (hh:mm:ss)';
-$labels['iso8601'] = 'date (ISO8601)';
-$labels['std11'] = 'date (RFC2822)';
-$labels['zone'] = 'time-zone';
-$labels['weekday'] = 'weekday (0-6)';
-$labels['advancedopts'] = 'Advanced options';
-$labels['body'] = 'Body';
-$labels['address'] = 'address';
-$labels['envelope'] = 'envelope';
-$labels['modifier'] = 'modifier:';
-$labels['text'] = 'text';
-$labels['undecoded'] = 'undecoded (raw)';
-$labels['contenttype'] = 'content type';
-$labels['modtype'] = 'type:';
-$labels['allparts'] = 'all';
-$labels['domain'] = 'domain';
-$labels['localpart'] = 'local part';
-$labels['user'] = 'user';
-$labels['detail'] = 'detail';
-$labels['comparator'] = 'comparator:';
-$labels['default'] = 'default';
-$labels['octet'] = 'strict (octet)';
-$labels['asciicasemap'] = 'case insensitive (ascii-casemap)';
-$labels['asciinumeric'] = 'numeric (ascii-numeric)';
-$labels['index'] = 'index:';
-$labels['indexlast'] = 'backwards';
-
-$messages = array();
-$messages['filterunknownerror'] = 'Unknown server error.';
-$messages['filterconnerror'] = 'Unable to connect to server.';
-$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured.';
-$messages['filterdeleted'] = 'Filter deleted successfully.';
-$messages['filtersaved'] = 'Filter saved successfully.';
-$messages['filtersaveerror'] = 'Unable to save filter. Server error occured.';
-$messages['filterdeleteconfirm'] = 'Do you really want to delete selected filter?';
-$messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?';
-$messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?';
-$messages['forbiddenchars'] = 'Forbidden characters in field.';
-$messages['cannotbeempty'] = 'Field cannot be empty.';
-$messages['ruleexist'] = 'Filter with specified name already exists.';
-$messages['setactivateerror'] = 'Unable to activate selected filters set. Server error occured.';
-$messages['setdeactivateerror'] = 'Unable to deactivate selected filters set. Server error occured.';
-$messages['setdeleteerror'] = 'Unable to delete selected filters set. Server error occured.';
-$messages['setactivated'] = 'Filters set activated successfully.';
-$messages['setdeactivated'] = 'Filters set deactivated successfully.';
-$messages['setdeleted'] = 'Filters set deleted successfully.';
-$messages['setdeleteconfirm'] = 'Are you sure, you want to delete selected filters set?';
-$messages['setcreateerror'] = 'Unable to create filters set. Server error occured.';
-$messages['setcreated'] = 'Filters set created successfully.';
-$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occured.';
-$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occured.';
-$messages['deactivated'] = 'Filter(s) disabled successfully.';
-$messages['activated'] = 'Filter(s) enabled successfully.';
-$messages['moved'] = 'Filter moved successfully.';
-$messages['moveerror'] = 'Unable to move selected filter. Server error occured.';
-$messages['nametoolong'] = 'Name too long.';
-$messages['namereserved'] = 'Reserved name.';
-$messages['setexist'] = 'Set already exists.';
-$messages['nodata'] = 'At least one position must be selected!';
-$messages['invaliddateformat'] = 'Invalid date or date part format';
-
?>
diff --git a/plugins/managesieve/localization/lt_LT.inc b/plugins/managesieve/localization/lt_LT.inc
index 3b6f4eec4..8fafb6d8d 100644
--- a/plugins/managesieve/localization/lt_LT.inc
+++ b/plugins/managesieve/localization/lt_LT.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'PridÄ—ti';
$labels['del'] = 'Pašalinti';
$labels['sender'] = 'SiuntÄ—jas';
$labels['recipient'] = 'GavÄ—jas';
-$labels['vacationaddr'] = 'Papildomas gavėjų adresų sąrašas:';
+$labels['vacationaddresses'] = 'Papildomas gavėjų adresų sąrašas (skirti kableliais):';
$labels['vacationdays'] = 'Kaip dažnai išsiųsti laiškus (dienomis):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Kaip dažnai siųsti laiškus:';
+$labels['days'] = 'd.';
+$labels['seconds'] = 'sek.';
$labels['vacationreason'] = 'Laiško tekstas';
$labels['vacationsubject'] = 'Laiško tema:';
$labels['rulestop'] = 'Nutraukti taisyklių vykdymą';
@@ -172,6 +172,6 @@ $messages['moveerror'] = 'Pasirinkto filtro perkelti neįmanoma. Įvyko serverio
$messages['nametoolong'] = 'Vardas per ilgas.';
$messages['namereserved'] = 'Rezervuotas vardas.';
$messages['setexist'] = 'Rinkinys jau yra sukurtas.';
-$messages['nodata'] = 'At least one position must be selected!';
+$messages['nodata'] = 'BÅ«tina pasirinkti bent vienÄ… pozicijÄ…!';
?>
diff --git a/plugins/managesieve/localization/lv_LV.inc b/plugins/managesieve/localization/lv_LV.inc
index 02b4eeffa..f1f85c2e0 100644
--- a/plugins/managesieve/localization/lv_LV.inc
+++ b/plugins/managesieve/localization/lv_LV.inc
@@ -30,7 +30,7 @@ $labels['filteranyof'] = 'jÄatbilst jebkuram no sekojoÅ¡ajiem nosacÄ«jumiem';
$labels['filterany'] = 'visÄm vÄ“stulÄ“m';
$labels['filtercontains'] = 'satur';
$labels['filternotcontains'] = 'nesatur';
-$labels['filteris'] = 'ir vienÄds ar';
+$labels['filteris'] = 'vienÄds ar';
$labels['filterisnot'] = 'nav vienÄds ar';
$labels['filterexists'] = 'eksistē';
$labels['filternotexists'] = 'neeksistē';
@@ -46,20 +46,20 @@ $labels['messagemoveto'] = 'PÄrvietot vÄ“stuli uz';
$labels['messageredirect'] = 'PÄradresÄ“t vÄ“stuli uz';
$labels['messagecopyto'] = 'Kopēt vēstuli uz';
$labels['messagesendcopy'] = 'PÄrsÅ«tÄ«t vÄ“stules kopiju uz';
-$labels['messagereply'] = 'Atbildēt ar vēstuli';
+$labels['messagereply'] = 'Atbildēt ar';
$labels['messagedelete'] = 'Dzēst vēstuli';
$labels['messagediscard'] = 'Dzēst vēstuli un atbildēt';
$labels['messagesrules'] = 'IenÄkoÅ¡ajÄm vÄ“stulÄ“m:';
-$labels['messagesactions'] = '...izpildÄ«t sekojoÅ¡Äs darbÄ«bas:';
+$labels['messagesactions'] = 'IzpildÄ«t sekojoÅ¡Äs darbÄ«bas:';
$labels['add'] = 'Pievienot';
$labels['del'] = 'Dzēst';
$labels['sender'] = 'SÅ«tÄ«tÄjs';
$labels['recipient'] = 'Saņēmējs';
-$labels['vacationaddr'] = 'Mana(s) papildus e-pasta adrese(s):';
+$labels['vacationaddresses'] = 'Ievadiet vienu vai vairÄkus e-pastu(s), atdalot tos komatu:';
$labels['vacationdays'] = 'Cik dienu laikÄ vienam un tam paÅ¡am sÅ«tÄ«tÄjam neatbildÄ“t atkÄrtoti (piem., 7):';
-$labels['vacationinterval'] = 'Cik bieži sūtīt vēstules:';
-$labels['days'] = 'dienas';
-$labels['seconds'] = 'sekundes';
+$labels['vacationinterval'] = 'How often send messages:';
+$labels['days'] = 'days';
+$labels['seconds'] = 'seconds';
$labels['vacationreason'] = 'AtvaļinÄjuma paziņojuma teksts:';
$labels['vacationsubject'] = 'Vēstules tēma:';
$labels['rulestop'] = 'ApturÄ“t nosacÄ«jumu pÄrbaudi';
@@ -78,16 +78,16 @@ $labels['none'] = 'nav';
$labels['fromset'] = 'no kopas';
$labels['fromfile'] = 'no faila';
$labels['filterdisabled'] = 'Filtrs atslēgts';
-$labels['countisgreaterthan'] = 'skaits ir lielÄks kÄ';
-$labels['countisgreaterthanequal'] = 'skaits ir vienÄds vai lielÄks kÄ';
-$labels['countislessthan'] = 'skaits ir mazÄks kÄ';
-$labels['countislessthanequal'] = 'skaits ir vienÄds vai mazÄks kÄ';
+$labels['countisgreaterthan'] = 'skaits ir lielÄks nekÄ';
+$labels['countisgreaterthanequal'] = 'skaits ir vienÄds vai lielÄks nekÄ';
+$labels['countislessthan'] = 'skaits ir mazÄks nekÄ';
+$labels['countislessthanequal'] = 'skaits ir vienÄds vai mazÄks nekÄ';
$labels['countequals'] = 'skaits ir vienÄds ar';
$labels['countnotequals'] = 'skaits nav vienÄds ar';
-$labels['valueisgreaterthan'] = 'vÄ“rtÄ«ba ir lielÄka kÄ';
-$labels['valueisgreaterthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai lielÄka kÄ';
-$labels['valueislessthan'] = 'vÄ“rtÄ«ba ir mazÄka kÄ';
-$labels['valueislessthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai mazÄka kÄ';
+$labels['valueisgreaterthan'] = 'vÄ“rtÄ«ba ir lielÄka nekÄ';
+$labels['valueisgreaterthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai lielÄka nekÄ';
+$labels['valueislessthan'] = 'vÄ“rtÄ«ba ir mazÄka nekÄ';
+$labels['valueislessthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai mazÄka nekÄ';
$labels['valueequals'] = 'vÄ“rtÄ«ba ir vienÄda ar';
$labels['valuenotequals'] = 'vÄ“rtÄ«ba nav vienÄda ar';
$labels['setflags'] = 'Marķēt vēstuli';
@@ -96,101 +96,82 @@ $labels['removeflags'] = 'Noņemt vēstulei marķierus';
$labels['flagread'] = 'Lasītas';
$labels['flagdeleted'] = 'Dzēstas';
$labels['flaganswered'] = 'Atbildētas';
-$labels['flagflagged'] = 'MarÄ·Ä“tas';
+$labels['flagflagged'] = 'IezÄ«mÄ“tÄs';
$labels['flagdraft'] = 'Melnraksts';
-$labels['setvariable'] = 'Iestatīt mainīgo';
-$labels['setvarname'] = 'MainÄ«gÄ nosaukums:';
-$labels['setvarvalue'] = 'MainÄ«gÄ vÄ“rtÄ«ba:';
-$labels['setvarmodifiers'] = 'Modifikatori:';
-$labels['varlower'] = 'mazie burti';
-$labels['varupper'] = 'lielie burti';
-$labels['varlowerfirst'] = 'pirmais burts kÄ mazais burts';
-$labels['varupperfirst'] = 'pirmais burts kÄ lielais burts';
-$labels['varquotewildcard'] = '"citÄ“t" speciÄlÄs rakstzÄ«mes';
-$labels['varlength'] = 'garums';
-$labels['notify'] = 'Sūtīt paziņojumus';
-$labels['notifyaddress'] = 'Uz e-pasta adresi:';
-$labels['notifybody'] = 'Paziņojuma teksts:';
-$labels['notifysubject'] = 'Paziņojuma tēma:';
-$labels['notifyfrom'] = 'Paziņojuma sÅ«tÄ«tÄjs:';
-$labels['notifyimportance'] = 'Svarīgums:';
-$labels['notifyimportancelow'] = 'zems';
-$labels['notifyimportancenormal'] = 'parasts';
-$labels['notifyimportancehigh'] = 'augsts';
+$labels['setvariable'] = 'Set variable';
+$labels['setvarname'] = 'Variable name:';
+$labels['setvarvalue'] = 'Variable value:';
+$labels['setvarmodifiers'] = 'Modifiers:';
+$labels['varlower'] = 'lower-case';
+$labels['varupper'] = 'upper-case';
+$labels['varlowerfirst'] = 'first character lower-case';
+$labels['varupperfirst'] = 'first character upper-case';
+$labels['varquotewildcard'] = 'quote special characters';
+$labels['varlength'] = 'length';
+$labels['notify'] = 'Send notification';
+$labels['notifyaddress'] = 'To e-mail address:';
+$labels['notifybody'] = 'Notification body:';
+$labels['notifysubject'] = 'Notification subject:';
+$labels['notifyfrom'] = 'Notification sender:';
+$labels['notifyimportance'] = 'Importance:';
+$labels['notifyimportancelow'] = 'low';
+$labels['notifyimportancenormal'] = 'normal';
+$labels['notifyimportancehigh'] = 'high';
$labels['filtercreate'] = 'Izveidot filtru';
$labels['usedata'] = 'FiltrÄ izmantot sekojoÅ¡us datus';
$labels['nextstep'] = 'NÄkamais solis';
$labels['...'] = '...';
-$labels['currdate'] = 'Pašreizējais datums';
-$labels['datetest'] = 'Datums';
-$labels['dateheader'] = 'galvene:';
-$labels['year'] = 'gads';
-$labels['month'] = 'mēnesis';
-$labels['day'] = 'diena';
-$labels['date'] = 'datums (gggg-mm-dd)';
-$labels['julian'] = 'datums (JÅ«lija kalendÄrs)';
-$labels['hour'] = 'stunda';
-$labels['minute'] = 'minūte';
-$labels['second'] = 'sekunde';
-$labels['time'] = 'laiks (hh:mm:ss)';
-$labels['iso8601'] = 'datums (ISO8601)';
-$labels['std11'] = 'datums (RFC2822)';
-$labels['zone'] = 'laikajosla';
-$labels['weekday'] = 'nedēļas diena (0-6)';
-$labels['advancedopts'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
+$labels['advancedopts'] = 'PaplaÅ¡inÄti iestatÄ«jumi';
$labels['body'] = 'Pamatteksts';
$labels['address'] = 'adresÄts';
$labels['envelope'] = 'aploksne';
$labels['modifier'] = 'modifikators:';
$labels['text'] = 'teksts';
-$labels['undecoded'] = 'neatkodÄ“ts (neapstrÄdÄti dati)';
+$labels['undecoded'] = 'neatkodēts (jēldati)';
$labels['contenttype'] = 'satura tips';
$labels['modtype'] = 'tips:';
$labels['allparts'] = 'viss';
$labels['domain'] = 'domēns';
-$labels['localpart'] = 'lokÄlÄ daļa';
+$labels['localpart'] = 'vietÄ“jÄ daļa';
$labels['user'] = 'lietotÄjs';
$labels['detail'] = 'detaļas';
-$labels['comparator'] = 'salÄ«dzinÄtÄjs';
-$labels['default'] = 'noklusÄ“tÄ vÄ“rtÄ«ba';
-$labels['octet'] = 'precīzs (oktets)';
+$labels['comparator'] = 'komparators';
+$labels['default'] = 'noklusējums';
+$labels['octet'] = 'strikti (oktets)';
$labels['asciicasemap'] = 'reģistrnejutīgs (ascii tabula)';
$labels['asciinumeric'] = 'skaitļu (ascii skaitļu)';
-$labels['index'] = 'indekss:';
-$labels['indexlast'] = '"backwards"';
$messages = array();
-$messages['filterunknownerror'] = 'NezinÄma servera kļūda.';
-$messages['filterconnerror'] = 'NeizdevÄs pieslÄ“gties ManageSieve serverim.';
-$messages['filterdeleteerror'] = 'NeizdevÄs izdzÄ“st filtru - servera kļūda.';
-$messages['filterdeleted'] = 'Filtrs veiksmīgi izdzēsts.';
-$messages['filtersaved'] = 'Filtrs veiksmÄ«gi saglabÄts.';
-$messages['filtersaveerror'] = 'NeizdevÄs saglabÄt filtru - servera kļūda.';
-$messages['filterdeleteconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to filtru?';
-$messages['ruledeleteconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to nosacÄ«jumu?';
-$messages['actiondeleteconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to darbÄ«bu?';
-$messages['forbiddenchars'] = 'Lauks satur aizliegtus simbolus.';
-$messages['cannotbeempty'] = 'Lauks nedrīkst būt tukšs.';
-$messages['ruleexist'] = 'Filtrs ar tÄdu nosaukumu jau pastÄv.';
-$messages['setactivateerror'] = 'NeizdevÄs aktivizÄ“t atzÄ«mÄ“to filtru kopu - servera kļūda.';
-$messages['setdeactivateerror'] = 'NeizdevÄs deaktivizÄ“t atzÄ«mÄ“to filtru kopu - servera kļūda.';
-$messages['setdeleteerror'] = 'NeizdevÄs izdzÄ“st atzÄ«mÄ“to filtru kopu - servera kļūda.';
-$messages['setactivated'] = 'Filtru kopa veiksmīgi aktivizēta.';
-$messages['setdeactivated'] = 'Filtru kopa veiksmīgi deaktivizēta.';
-$messages['setdeleted'] = 'Filtru kopa veiksmīgi izdzēsta.';
-$messages['setdeleteconfirm'] = 'Vai tieÅ¡Äm JÅ«s vÄ“laties dzÄ“st atzÄ«mÄ“to filtru kopu?';
-$messages['setcreateerror'] = 'NeizdevÄs izveidot filtru kopu - servera kļūda.';
-$messages['setcreated'] = 'Filtru kopa veiksmīgi izveidota.';
-$messages['activateerror'] = 'Nav iespējams ieslēgt izvēlēto(s) filtru(s) - servera kļūda.';
-$messages['deactivateerror'] = 'Nav iespējams atslēgt izvēlēto(s) filtru(s) - servera kļūda.';
-$messages['deactivated'] = 'Filtrs(i) veiksmīgi atslēgts(i).';
-$messages['activated'] = 'Filtrs(i) veiksmīgi ieslēgts(i).';
-$messages['moved'] = 'Filtrs veiksmÄ«gi pÄrvietots.';
-$messages['moveerror'] = 'Nav iespÄ“jams pÄrvietot izvÄ“lÄ“to filtru - servera kļūda.';
-$messages['nametoolong'] = 'NeizdevÄs izveidot filtru kopu. PÄrÄk garÅ¡ kopas nosaukums.';
-$messages['namereserved'] = 'Rezervētais nosaukums.';
-$messages['setexist'] = 'Kopa jau eksistē.';
-$messages['nodata'] = 'Ir jÄbÅ«t atzÄ«mÄ“tai vismaz vienai pozÄ«cijai!';
-$messages['invaliddateformat'] = 'NederÄ«gs datums vai datuma formÄts';
+$messages['filterunknownerror'] = 'NezinÄma servera kļūda';
+$messages['filterconnerror'] = 'NeizdevÄs pieslÄ“gties ManageSieve serverim';
+$messages['filterdeleteerror'] = 'NeizdevÄs dzÄ“st filtru. Servera iekÅ¡Ä“jÄ kļūda';
+$messages['filterdeleted'] = 'Filtrs veiksmīgi izdzēsts';
+$messages['filtersaved'] = 'Filtrs veiksmÄ«gi saglabÄts';
+$messages['filtersaveerror'] = 'NeizdevÄs saglabÄt filtru. Servera iekÅ¡Ä“jÄ kļūda';
+$messages['filterdeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to filtru?';
+$messages['ruledeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to nosacÄ«jumu?';
+$messages['actiondeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to darbÄ«bu?';
+$messages['forbiddenchars'] = 'Lauks satur aizliegtus simbolus';
+$messages['cannotbeempty'] = 'Lauks nedrīkst būt tukšs';
+$messages['ruleexist'] = 'Filter with specified name already exists.';
+$messages['setactivateerror'] = 'NeizdevÄs aktivizÄ“t atzÄ«mÄ“to filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
+$messages['setdeactivateerror'] = 'NeizdevÄs deaktivizÄ“t atzÄ«mÄ“to filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
+$messages['setdeleteerror'] = 'NeizdevÄs izdzÄ“st atzÄ«mÄ“to filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
+$messages['setactivated'] = 'Filtru kopa veiksmīgi aktivizēta';
+$messages['setdeactivated'] = 'Filtru kopa veiksmīgi deaktivizēta';
+$messages['setdeleted'] = 'Filtru kopa veiksmīgi izdzēsta';
+$messages['setdeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to filtru kopu?';
+$messages['setcreateerror'] = 'NeizdevÄs izveidot filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
+$messages['setcreated'] = 'Filtru kopa veiksmīgi izveidota';
+$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occured.';
+$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occured.';
+$messages['deactivated'] = 'Filter(s) disabled successfully.';
+$messages['activated'] = 'Filter(s) enabled successfully.';
+$messages['moved'] = 'Filter moved successfully.';
+$messages['moveerror'] = 'Unable to move selected filter. Server error occured.';
+$messages['nametoolong'] = 'NeizdevÄs izveidot filtru kopu. PÄrÄk garÅ¡ kopas nosaukums';
+$messages['namereserved'] = 'Reserved name.';
+$messages['setexist'] = 'Set already exists.';
+$messages['nodata'] = 'At least one position must be selected!';
?>
diff --git a/plugins/managesieve/localization/ml_IN.inc b/plugins/managesieve/localization/ml_IN.inc
index 761b4305b..67cd6829f 100644
--- a/plugins/managesieve/localization/ml_IN.inc
+++ b/plugins/managesieve/localization/ml_IN.inc
@@ -55,6 +55,7 @@ $labels['add'] = 'ചേരàµâ€à´•àµà´•àµ';
$labels['del'] = 'നീകàµà´•à´‚ ചെയàµà´¯àµà´•';
$labels['sender'] = 'അയചയാളàµâ€';
$labels['recipient'] = 'à´¸àµà´µàµ€à´•à´°àµâ€à´¤àµà´¤à´¾à´µàµ';
+$labels['vacationaddresses'] = 'à´¸àµà´µàµ€à´•à´°àµâ€à´¤àµà´¤à´¾à´µà´¿à´¨àµà´±àµ† ഇമെയിലàµâ€ വിലാസങàµà´™à´³àµà´Ÿàµ† അധികമàµà´³àµà´³ പടàµà´Ÿà´¿à´• (കോമയിടàµà´Ÿàµ തിരിചàµà´š)';
$labels['vacationdays'] = 'à´Žà´¤àµà´° ഭിവസം കൂടàµà´®àµà´ªàµ‹à´³àµâ€ സനàµà´¦àµ‡à´¶à´‚ അയകàµà´•à´£à´‚:';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/mr_IN.inc b/plugins/managesieve/localization/mr_IN.inc
index 082ea9bc6..3339737e0 100644
--- a/plugins/managesieve/localization/mr_IN.inc
+++ b/plugins/managesieve/localization/mr_IN.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'समावेश करा';
$labels['del'] = 'नषà¥à¤Ÿ करा';
$labels['sender'] = 'पà¥à¤°à¥‡à¤·à¤•';
$labels['recipient'] = 'Recipient';
-$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
+$labels['vacationaddresses'] = 'My additional e-mail addresse(s) (comma-separated):';
$labels['vacationdays'] = 'How often send messages (in days):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/nb_NO.inc b/plugins/managesieve/localization/nb_NO.inc
index c3bf98f8b..c2c17b23c 100644
--- a/plugins/managesieve/localization/nb_NO.inc
+++ b/plugins/managesieve/localization/nb_NO.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Legg til';
$labels['del'] = 'Slett';
$labels['sender'] = 'Avsender';
$labels['recipient'] = 'Mottaker';
-$labels['vacationaddr'] = 'Liste med mottakeradresser:';
+$labels['vacationaddresses'] = 'Liste med mottakeradresser (adskilt med komma):';
$labels['vacationdays'] = 'Periode mellom meldinger (i dager):';
$labels['vacationinterval'] = 'Periode mellom meldinger:';
$labels['days'] = 'dager';
diff --git a/plugins/managesieve/localization/nl_NL.inc b/plugins/managesieve/localization/nl_NL.inc
index 80c2274b1..1fd6eee4e 100644
--- a/plugins/managesieve/localization/nl_NL.inc
+++ b/plugins/managesieve/localization/nl_NL.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Toevoegen';
$labels['del'] = 'Verwijderen';
$labels['sender'] = 'Afzender';
$labels['recipient'] = 'Ontvanger';
-$labels['vacationaddr'] = 'Aanvullende lijst van geadresseerden:';
+$labels['vacationaddresses'] = 'Aanvullende lijst van geadresseerden (gescheiden met komma\'s):';
$labels['vacationdays'] = 'Hoe vaak moet een bericht verstuurd worden (in dagen):';
$labels['vacationinterval'] = 'Hoe vaak moet een bericht verstuurd worden:';
$labels['days'] = 'dagen';
diff --git a/plugins/managesieve/localization/nn_NO.inc b/plugins/managesieve/localization/nn_NO.inc
index 03563a72b..18bf8b987 100644
--- a/plugins/managesieve/localization/nn_NO.inc
+++ b/plugins/managesieve/localization/nn_NO.inc
@@ -55,8 +55,11 @@ $labels['add'] = 'Legg til';
$labels['del'] = 'Slett';
$labels['sender'] = 'Avsendar';
$labels['recipient'] = 'Mottakar';
-$labels['vacationaddr'] = 'Liste med mottakaradresser:';
+$labels['vacationaddresses'] = 'Liste med mottakaradresser (komma-separert):';
$labels['vacationdays'] = 'Periode mellom meldingar (i dagar):';
+$labels['vacationinterval'] = 'How often send messages:';
+$labels['days'] = 'days';
+$labels['seconds'] = 'seconds';
$labels['vacationreason'] = 'Innhald (grunngjeving for fråvær)';
$labels['vacationsubject'] = 'Meldingsemne:';
$labels['rulestop'] = 'Stopp evaluering av regler';
@@ -98,7 +101,7 @@ $labels['flagdraft'] = 'Skisse';
$labels['setvariable'] = 'Sett variabel:';
$labels['setvarname'] = 'Variabelnamn:';
$labels['setvarvalue'] = 'Variabelverdi:';
-$labels['setvarmodifiers'] = 'Modifiers:';
+$labels['setvarmodifiers'] = 'Modifikator:';
$labels['varlower'] = 'med små bokstavar';
$labels['varupper'] = 'med store bokstavar';
$labels['varlowerfirst'] = 'med liten forbokstav';
@@ -107,9 +110,9 @@ $labels['varquotewildcard'] = 'quote special characters';
$labels['varlength'] = 'lengde';
$labels['notify'] = 'Send varsel';
$labels['notifyaddress'] = 'Til e-postadresse:';
-$labels['notifybody'] = 'Notification body:';
-$labels['notifysubject'] = 'Notification subject:';
-$labels['notifyfrom'] = 'Notification sender:';
+$labels['notifybody'] = 'Varseltekst:';
+$labels['notifysubject'] = 'Varselemne:';
+$labels['notifyfrom'] = 'Varselavsendar:';
$labels['notifyimportance'] = 'Betyding:';
$labels['notifyimportancelow'] = 'låg';
$labels['notifyimportancenormal'] = 'normal';
diff --git a/plugins/managesieve/localization/pl_PL.inc b/plugins/managesieve/localization/pl_PL.inc
index 799f0fb54..9a6b70d8a 100644
--- a/plugins/managesieve/localization/pl_PL.inc
+++ b/plugins/managesieve/localization/pl_PL.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Dodaj';
$labels['del'] = 'Usuń';
$labels['sender'] = 'Nadawca';
$labels['recipient'] = 'Odbiorca';
-$labels['vacationaddr'] = 'Dodatkowy/e adres(y) e-mail:';
+$labels['vacationaddresses'] = 'Lista dodatkowych adresów odbiorców (oddzielonych przecinkami):';
$labels['vacationdays'] = 'Częstotliwość wysyłania wiadomości (w dniach):';
$labels['vacationinterval'] = 'Jak często wysyłać wiadomości:';
$labels['days'] = 'dni';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'ilość jest równa lub większa od';
$labels['countislessthan'] = 'ilość jest mniejsza od';
$labels['countislessthanequal'] = 'ilość jest równa lub mniejsza od';
$labels['countequals'] = 'ilość jest równa';
-$labels['countnotequals'] = 'ilość nie jest równa';
+$labels['countnotequals'] = 'ilość jest różna od';
$labels['valueisgreaterthan'] = 'wartość jest większa od';
$labels['valueisgreaterthanequal'] = 'wartość jest równa lub większa od';
$labels['valueislessthan'] = 'wartość jest mniejsza od';
$labels['valueislessthanequal'] = 'wartość jest równa lub mniejsza od';
$labels['valueequals'] = 'wartość jest równa';
-$labels['valuenotequals'] = 'wartość nie jest równa';
+$labels['valuenotequals'] = 'wartość jest różna od';
$labels['setflags'] = 'Ustaw flagi wiadomości';
$labels['addflags'] = 'Dodaj flagi do wiadomości';
$labels['removeflags'] = 'Usuń flagi wiadomości';
@@ -121,22 +121,6 @@ $labels['filtercreate'] = 'Utwórz filtr';
$labels['usedata'] = 'Użyj następujących danych do utworzenia filtra:';
$labels['nextstep'] = 'Następny krok';
$labels['...'] = '...';
-$labels['currdate'] = 'Bieżąca data';
-$labels['datetest'] = 'Data';
-$labels['dateheader'] = 'nagłówek:';
-$labels['year'] = 'rok';
-$labels['month'] = 'miesiÄ…c';
-$labels['day'] = 'dzień';
-$labels['date'] = 'data (rrrr-mm-dd)';
-$labels['julian'] = 'data (kalendarz juliański)';
-$labels['hour'] = 'godzina';
-$labels['minute'] = 'minuta';
-$labels['second'] = 'sekunda';
-$labels['time'] = 'czas (gg:mm:ss)';
-$labels['iso8601'] = 'data (ISO8601)';
-$labels['std11'] = 'data (RFC2822)';
-$labels['zone'] = 'Strefa czasowa';
-$labels['weekday'] = 'dzień tygodnia (0-6)';
$labels['advancedopts'] = 'Zaawansowane opcje';
$labels['body'] = 'Treść';
$labels['address'] = 'adres';
@@ -156,8 +140,6 @@ $labels['default'] = 'domyślny';
$labels['octet'] = 'dokładny (octet)';
$labels['asciicasemap'] = 'nierozróżniający wielkości liter (ascii-casemap)';
$labels['asciinumeric'] = 'numeryczny (ascii-numeric)';
-$labels['index'] = 'indeks:';
-$labels['indexlast'] = 'wstecz';
$messages = array();
$messages['filterunknownerror'] = 'Nieznany błąd serwera.';
@@ -191,6 +173,5 @@ $messages['nametoolong'] = 'Zbyt długa nazwa.';
$messages['namereserved'] = 'Nazwa zarezerwowana.';
$messages['setexist'] = 'Zbiór już istnieje.';
$messages['nodata'] = 'Należy wybrać co najmniej jedną pozycję!';
-$messages['invaliddateformat'] = 'Nieprawidłowy format daty lub fragmentu daty';
?>
diff --git a/plugins/managesieve/localization/pt_BR.inc b/plugins/managesieve/localization/pt_BR.inc
index cd96c49ca..941119335 100644
--- a/plugins/managesieve/localization/pt_BR.inc
+++ b/plugins/managesieve/localization/pt_BR.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Adicionar';
$labels['del'] = 'Excluir';
$labels['sender'] = 'Remetente';
$labels['recipient'] = 'Destinatário';
-$labels['vacationaddr'] = 'Meus endereços de e-mail adicionais:';
+$labels['vacationaddresses'] = 'Lista adicional de e-mails destinatários (separado por vírgula):';
$labels['vacationdays'] = 'Enviar mensagens com que frequência (em dias):';
$labels['vacationinterval'] = 'Como geralmente enviam mensagens:';
$labels['days'] = 'dias';
@@ -121,22 +121,6 @@ $labels['filtercreate'] = 'Criar filtro';
$labels['usedata'] = 'Usar os seguintes dados no filtro:';
$labels['nextstep'] = 'Próximo Passo';
$labels['...'] = '...';
-$labels['currdate'] = 'Data atual';
-$labels['datetest'] = 'Data';
-$labels['dateheader'] = 'cabeçalho:';
-$labels['year'] = 'ano';
-$labels['month'] = 'mês';
-$labels['day'] = 'dia';
-$labels['date'] = 'data (aaaa-mm-dd)';
-$labels['julian'] = 'data (calendário juliano)';
-$labels['hour'] = 'hora';
-$labels['minute'] = 'minuto';
-$labels['second'] = 'segundo';
-$labels['time'] = 'hora (hh:mm:ss)';
-$labels['iso8601'] = 'data (ISO8601)';
-$labels['std11'] = 'data (RFC2822)';
-$labels['zone'] = 'fuso horário';
-$labels['weekday'] = 'dia da semana (0-6)';
$labels['advancedopts'] = 'Opções avançadas';
$labels['body'] = 'Corpo';
$labels['address'] = 'endereço';
@@ -156,8 +140,6 @@ $labels['default'] = 'padrão';
$labels['octet'] = 'estrito (octeto)';
$labels['asciicasemap'] = 'caso insensível (mapa de caracteres ascii)';
$labels['asciinumeric'] = 'numérico (ascii-numeric)';
-$labels['index'] = 'índice:';
-$labels['indexlast'] = 'retroceder';
$messages = array();
$messages['filterunknownerror'] = 'Erro desconhecido de servidor';
@@ -191,6 +173,5 @@ $messages['nametoolong'] = 'Nome muito longo.';
$messages['namereserved'] = 'Nome reservado.';
$messages['setexist'] = 'Conjunto já existe.';
$messages['nodata'] = 'Pelo menos uma posição precisa ser selecionada!';
-$messages['invaliddateformat'] = 'Data inválida';
?>
diff --git a/plugins/managesieve/localization/pt_PT.inc b/plugins/managesieve/localization/pt_PT.inc
index f51e8bf5e..bfb3f296a 100644
--- a/plugins/managesieve/localization/pt_PT.inc
+++ b/plugins/managesieve/localization/pt_PT.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Adicionar';
$labels['del'] = 'Eliminar';
$labels['sender'] = 'Remetente';
$labels['recipient'] = 'Destinatário';
-$labels['vacationaddr'] = 'Lista adicional de destinatários de e-mails:';
+$labels['vacationaddresses'] = 'Lista adicional de destinatários de e-mails (separados por vírgula):';
$labels['vacationdays'] = 'Enviar mensagens com que frequência (em dias):';
$labels['vacationinterval'] = 'Com que frequência envia mensagens:';
$labels['days'] = 'dias';
diff --git a/plugins/managesieve/localization/ro_RO.inc b/plugins/managesieve/localization/ro_RO.inc
index 8d6e9c96f..5eb7186dd 100644
--- a/plugins/managesieve/localization/ro_RO.inc
+++ b/plugins/managesieve/localization/ro_RO.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Adaugă';
$labels['del'] = 'Șterge';
$labels['sender'] = 'Expeditor';
$labels['recipient'] = 'Destinatar';
-$labels['vacationaddr'] = 'Adresele mele de e-mail adiționale:';
+$labels['vacationaddr'] = 'My additional e-mail addresse(s):';
$labels['vacationdays'] = 'Cât de des să trimit mesajele (în zile):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Cât de des să trimit mesaje:';
+$labels['days'] = 'zile';
+$labels['seconds'] = 'secunde';
$labels['vacationreason'] = 'Corpul mesajului (motivul vacanţei):';
$labels['vacationsubject'] = 'Subiectul mesajului:';
$labels['rulestop'] = 'Nu mai evalua reguli';
diff --git a/plugins/managesieve/localization/ru_RU.inc b/plugins/managesieve/localization/ru_RU.inc
index f922bcf22..fb3f113c3 100644
--- a/plugins/managesieve/localization/ru_RU.inc
+++ b/plugins/managesieve/localization/ru_RU.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Добавить';
$labels['del'] = 'Удалить';
$labels['sender'] = 'Отправитель';
$labels['recipient'] = 'Получатель';
-$labels['vacationaddr'] = 'Мои дополнительные адреÑа:';
+$labels['vacationaddresses'] = 'СпиÑок моих дополнительных адреÑов (разделённых запÑтыми):';
$labels['vacationdays'] = 'Как чаÑто отправлÑÑ‚ÑŒ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (в днÑÑ…):';
$labels['vacationinterval'] = 'Как чаÑто отправлÑÑ‚ÑŒ ÑообщениÑ:';
$labels['days'] = 'дней';
@@ -121,22 +121,6 @@ $labels['filtercreate'] = 'Создать фильтр';
$labels['usedata'] = 'ИÑпользовать Ñледующие данные в фильтре:';
$labels['nextstep'] = 'Далее';
$labels['...'] = '...';
-$labels['currdate'] = 'Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð´Ð°Ñ‚Ð°';
-$labels['datetest'] = 'Дата';
-$labels['dateheader'] = 'заголовок:';
-$labels['year'] = 'год';
-$labels['month'] = 'меÑÑц';
-$labels['day'] = 'день';
-$labels['date'] = 'дата (гггг-мм-дд)';
-$labels['julian'] = 'дата (юлианÑкаÑ)';
-$labels['hour'] = 'чаÑ';
-$labels['minute'] = 'минута';
-$labels['second'] = 'Ñекунда';
-$labels['time'] = 'Ð²Ñ€ÐµÐ¼Ñ (чч:мм:ÑÑ)';
-$labels['iso8601'] = 'дата (ISO8601)';
-$labels['std11'] = 'дата (RFC2822)';
-$labels['zone'] = 'чаÑовой поÑÑ';
-$labels['weekday'] = 'день недели (0-6)';
$labels['advancedopts'] = 'Дополнительные параметры';
$labels['body'] = 'Тело пиÑьма';
$labels['address'] = 'адреÑ';
@@ -156,8 +140,6 @@ $labels['default'] = 'по умолчанию';
$labels['octet'] = 'Строгий (octet)';
$labels['asciicasemap'] = 'РегиÑтронезавиÑимый (ascii-casemap)';
$labels['asciinumeric'] = 'ЧиÑловой (ascii-numeric)';
-$labels['index'] = 'индекÑ:';
-$labels['indexlast'] = 'наоборот';
$messages = array();
$messages['filterunknownerror'] = 'ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñервера';
@@ -191,6 +173,5 @@ $messages['nametoolong'] = 'Ðевозможно Ñоздать набор фиÐ
$messages['namereserved'] = 'Зарезервированное имÑ.';
$messages['setexist'] = 'Ðабор уже ÑущеÑтвует.';
$messages['nodata'] = 'Ðужно выбрать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одну позицию!';
-$messages['invaliddateformat'] = 'ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð°Ñ‚Ð° или формат чаÑти даты';
?>
diff --git a/plugins/managesieve/localization/si_LK.inc b/plugins/managesieve/localization/si_LK.inc
index 378fcf15d..afc2e3851 100644
--- a/plugins/managesieve/localization/si_LK.inc
+++ b/plugins/managesieve/localization/si_LK.inc
@@ -55,6 +55,7 @@ $labels['add'] = 'එක් කරන්න';
$labels['del'] = 'මකන්න';
$labels['sender'] = 'යවන්නà·';
$labels['recipient'] = 'ලබන්නà·';
+$labels['vacationaddresses'] = 'My additional e-mail addresse(s) (comma-separated):';
$labels['vacationdays'] = 'How often send messages (in days):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/sk_SK.inc b/plugins/managesieve/localization/sk_SK.inc
index 9bfb2ef8f..f336cf2c5 100644
--- a/plugins/managesieve/localization/sk_SK.inc
+++ b/plugins/managesieve/localization/sk_SK.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Pridaj';
$labels['del'] = 'Zmaž';
$labels['sender'] = 'Odosielateľ';
$labels['recipient'] = 'Adresát';
-$labels['vacationaddr'] = 'DodatoÄní príjemcovia správy:';
+$labels['vacationaddresses'] = 'DodatoÄní príjemcovia správy (oddelení Äiarkami):';
$labels['vacationdays'] = 'PoÄet dní medzi odoslaním správy:';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/sl_SI.inc b/plugins/managesieve/localization/sl_SI.inc
index aa82078f1..d9da8ab60 100644
--- a/plugins/managesieve/localization/sl_SI.inc
+++ b/plugins/managesieve/localization/sl_SI.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Dodaj';
$labels['del'] = 'Izbriši';
$labels['sender'] = 'Pošiljatelj';
$labels['recipient'] = 'Prejemnik';
-$labels['vacationaddr'] = 'Moji dodatni e-naslovi';
+$labels['vacationaddresses'] = 'Dodaten seznam naslovov prejemnikov (loÄenih z vejico):';
$labels['vacationdays'] = 'Kako pogosto naj bodo sporoÄila poslana (v dnevih):';
$labels['vacationinterval'] = 'SporoÄila poÅ¡lji na:';
$labels['days'] = 'dni';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'seÅ¡tevek je veÄji ali enak';
$labels['countislessthan'] = 'seštevek je manjši od';
$labels['countislessthanequal'] = 'seštevel je manjši ali enak';
$labels['countequals'] = 'seštevek je enak';
-$labels['countnotequals'] = 'vsota ne ustreza';
+$labels['countnotequals'] = 'seštevek ni enak';
$labels['valueisgreaterthan'] = 'vrednost je veÄja od';
$labels['valueisgreaterthanequal'] = 'vrednost je veÄja ali enaka';
$labels['valueislessthan'] = 'vrednost je manjša od';
$labels['valueislessthanequal'] = 'vrednost je manjša ali enaka';
$labels['valueequals'] = 'vrednost je enaka';
-$labels['valuenotequals'] = 'vrednost ni enaka';
+$labels['valuenotequals'] = 'vrednost je neenaka';
$labels['setflags'] = 'OznaÄi sporoÄilo';
$labels['addflags'] = 'OznaÄi sporoÄilo';
$labels['removeflags'] = 'Odstrani zaznamke s sporoÄil';
@@ -121,22 +121,6 @@ $labels['filtercreate'] = 'Ustvari filter';
$labels['usedata'] = 'Pri stvarjanju filtra uporabi naslednje podatke';
$labels['nextstep'] = 'Naslednji korak';
$labels['...'] = '...';
-$labels['currdate'] = 'Današnji datum';
-$labels['datetest'] = 'Datum';
-$labels['dateheader'] = 'glava:';
-$labels['year'] = 'leto';
-$labels['month'] = 'mesec';
-$labels['day'] = 'dan';
-$labels['date'] = 'datum(yyyy-mm-dd)';
-$labels['julian'] = 'datum (julijanski)';
-$labels['hour'] = 'ura';
-$labels['minute'] = 'minuta';
-$labels['second'] = 'sekunda';
-$labels['time'] = 'Äas';
-$labels['iso8601'] = 'datum (ISO8601)';
-$labels['std11'] = 'datum (RFC2822)';
-$labels['zone'] = 'Äasovni pas';
-$labels['weekday'] = 'dan v tednu (0-6)';
$labels['advancedopts'] = 'Dodatne možnosti';
$labels['body'] = 'Vsebina';
$labels['address'] = 'naslov';
@@ -156,8 +140,6 @@ $labels['default'] = 'privzeto';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'ni obÄutljiv na velike/male Ärke (ascii-casemap)';
$labels['asciinumeric'] = 'numeriÄno (ascii-numeric)';
-$labels['index'] = 'indeks:';
-$labels['indexlast'] = 'obraten vrstni red';
$messages = array();
$messages['filterunknownerror'] = 'Prišlo je do neznane napake.';
@@ -191,6 +173,5 @@ $messages['nametoolong'] = 'Ime je predolgo.';
$messages['namereserved'] = 'Rezervirano ime.';
$messages['setexist'] = 'Nastavitev filtra že obstaja.';
$messages['nodata'] = 'Izbrana mora biti vsaj ena nastavitev!';
-$messages['invaliddateformat'] = 'Neveljaven datum ali oblika zapisa datuma';
?>
diff --git a/plugins/managesieve/localization/sv_SE.inc b/plugins/managesieve/localization/sv_SE.inc
index f2aeddd9f..49d5b1222 100644
--- a/plugins/managesieve/localization/sv_SE.inc
+++ b/plugins/managesieve/localization/sv_SE.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Lägg till';
$labels['del'] = 'Ta bort';
$labels['sender'] = 'Avsändare';
$labels['recipient'] = 'Mottagare';
-$labels['vacationaddr'] = 'Ytterligare mottagaradresser:';
+$labels['vacationaddresses'] = 'Ytterligare mottagaradresser (avdelade med kommatecken)';
$labels['vacationdays'] = 'Antal dagar mellan auto-svar:';
$labels['vacationinterval'] = 'Tid mellan auto-svar:';
$labels['days'] = 'Dagar';
diff --git a/plugins/managesieve/localization/th_TH.inc b/plugins/managesieve/localization/th_TH.inc
new file mode 100644
index 000000000..c2d041cfe
--- /dev/null
+++ b/plugins/managesieve/localization/th_TH.inc
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/managesieve/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Managesieve plugin |
+ | Copyright (C) 2012-2013, 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/plugin-managesieve/
+*/
+$labels['filters'] = 'ตัวà¸à¸£à¸­à¸‡à¸‚้อมูล';
+$labels['filtername'] = 'ชื่อตัวà¸à¸£à¸­à¸‡à¸‚้อมูล';
+$labels['newfilter'] = 'สร้างตัวà¸à¸£à¸­à¸‡à¸‚้อมูลใหม่';
+$labels['filteradd'] = 'เพิ่มตัวà¸à¸£à¸­à¸‡à¸‚้อมูล';
+$labels['filterdel'] = 'ลบตัวà¸à¸£à¸­à¸‡à¸‚้อมูล';
+$labels['moveup'] = 'เลื่อนขึ้น';
+$labels['movedown'] = 'เลื่อนลง';
+$labels['filterany'] = 'ข้อความทั้งหมด';
+$labels['filtercontains'] = 'ที่มีคำว่า';
+$labels['filternotcontains'] = 'ไม่มีคำว่า';
+$labels['filteris'] = 'ที่มีค่าเท่าà¸à¸±à¸š';
+$labels['filterisnot'] = 'ที่มีค่าไม่เท่าà¸à¸±à¸š';
+$labels['addrule'] = 'เพิ่มà¸à¸';
+$labels['delrule'] = 'ลบà¸à¸';
+$labels['messagemoveto'] = 'ย้ายข้อความไปที่';
+$labels['messageredirect'] = 'เปลียนเส้นทางข้อความไปที่';
+$labels['messagecopyto'] = 'คัดลอà¸à¸‚้อความไปที่';
+$labels['messagesendcopy'] = 'ส่งข้อความคัดลอà¸à¹„ปที่';
+$labels['messagedelete'] = 'ลบข้อความ';
+$labels['messagediscard'] = 'ยà¸à¹€à¸¥à¸´à¸à¸‚้อความ';
+$labels['messagesrules'] = 'สำหรับอีเมลขาเข้า:';
+$labels['add'] = 'เพิ่ม';
+$labels['del'] = 'ลบ';
+$labels['sender'] = 'ผู้ส่ง';
+$labels['recipient'] = 'ผู้รับ';
+$labels['vacationsubject'] = 'หัวเรื่องข้อความ:';
+$labels['enable'] = 'เปิดใช้งาน/ปิดใช้งาน';
+?>
diff --git a/plugins/managesieve/localization/tr_TR.inc b/plugins/managesieve/localization/tr_TR.inc
index 19bbb2e8e..c36869d29 100644
--- a/plugins/managesieve/localization/tr_TR.inc
+++ b/plugins/managesieve/localization/tr_TR.inc
@@ -55,8 +55,8 @@ $labels['add'] = 'Ekle';
$labels['del'] = 'Sil';
$labels['sender'] = 'Gönderici';
$labels['recipient'] = 'Alıcı';
-$labels['vacationaddr'] = 'Ä°lave e-posta adreslerim:';
-$labels['vacationdays'] = 'Ne sıklıkla mesajlar gönderilir(gün):';
+$labels['vacationaddresses'] = 'İlave e-posta adreslerim(virgül ile ayrılmış)';
+$labels['vacationdays'] = 'Ne sıklıkla mesajlar gönderilir(gün)';
$labels['vacationinterval'] = 'Ne kadar sıklıkla mesaj gönderirsiniz:';
$labels['days'] = 'günler';
$labels['seconds'] = 'saniyeler';
@@ -165,8 +165,8 @@ $messages['setcreateerror'] = 'Filtre setleri oluşturulamadı. Sunucuda hata ol
$messages['setcreated'] = 'Filtre setleri başarıyla oluşturuldu.';
$messages['activateerror'] = 'Seçilen filtre(ler) etkinleştirilemedi. Sunucuda hata oluştu.';
$messages['deactivateerror'] = 'Seçilen filtre(ler) pasifleştirilemedi. Sunucuda hata oluştu.';
-$messages['deactivated'] = 'Filtre(ler) başarıyla iptal edildi.';
-$messages['activated'] = 'Filtre(ler) başarıyla etkinleştirildi.';
+$messages['deactivated'] = 'Filtre(ler) başarıyla etkinleştirildi.';
+$messages['activated'] = 'Filtre(ler) başarıyla iptal edildi.';
$messages['moved'] = 'Filtre başarıyla taşındı.';
$messages['moveerror'] = 'Seçilen filtre(ler) taşınamadı. Sunucuda hata oluştu.';
$messages['nametoolong'] = 'İsim çok uzun.';
diff --git a/plugins/managesieve/localization/uk_UA.inc b/plugins/managesieve/localization/uk_UA.inc
index 57cab9ea5..41623df35 100644
--- a/plugins/managesieve/localization/uk_UA.inc
+++ b/plugins/managesieve/localization/uk_UA.inc
@@ -55,7 +55,7 @@ $labels['add'] = 'Додати';
$labels['del'] = 'Видалити';
$labels['sender'] = 'Відправник';
$labels['recipient'] = 'Отримувач';
-$labels['vacationaddr'] = 'Додатковий ÑпиÑок Ð°Ð´Ñ€ÐµÑ Ð¾Ñ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‡Ñ–Ð²:';
+$labels['vacationaddresses'] = 'Додатковий ÑпиÑок Ð°Ð´Ñ€ÐµÑ Ð¾Ñ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‡Ñ–Ð² (розділених комою)';
$labels['vacationdays'] = 'Як чаÑто повторювати (у днÑÑ…):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/vi_VN.inc b/plugins/managesieve/localization/vi_VN.inc
index 6e65cccf5..0a4ce6e82 100644
--- a/plugins/managesieve/localization/vi_VN.inc
+++ b/plugins/managesieve/localization/vi_VN.inc
@@ -55,8 +55,11 @@ $labels['add'] = 'Thêm';
$labels['del'] = 'Xoá';
$labels['sender'] = 'NgÆ°á»i gá»­i';
$labels['recipient'] = 'NgÆ°á»i nhận';
-$labels['vacationaddr'] = 'Äịa chỉ email bổ sung của tôi';
+$labels['vacationaddresses'] = 'Äịa chỉ email bổ sung của tôi ( phân cách bằng dấu phẩy)';
$labels['vacationdays'] = 'Số lần gửi thư (trong ngày)';
+$labels['vacationinterval'] = 'How often send messages:';
+$labels['days'] = 'days';
+$labels['seconds'] = 'seconds';
$labels['vacationreason'] = 'Nội dung chính';
$labels['vacationsubject'] = 'Tiêu đỠthư';
$labels['rulestop'] = 'Ngừng đánh giá qui luật';
@@ -95,17 +98,17 @@ $labels['flagdeleted'] = 'Äã được xóa';
$labels['flaganswered'] = 'Äã trả lá»i';
$labels['flagflagged'] = 'Äã đánh dấu';
$labels['flagdraft'] = 'Nháp';
-$labels['setvariable'] = 'Set variable';
-$labels['setvarname'] = 'Variable name:';
-$labels['setvarvalue'] = 'Variable value:';
-$labels['setvarmodifiers'] = 'Modifiers:';
+$labels['setvariable'] = 'Äặt biến';
+$labels['setvarname'] = 'Tên biến:';
+$labels['setvarvalue'] = 'Giá trị biến:';
+$labels['setvarmodifiers'] = 'Bá»™ chia:';
$labels['varlower'] = 'viết thÆ°á»ng';
$labels['varupper'] = 'viết hoa';
$labels['varlowerfirst'] = 'chữ cái đầu viết thÆ°á»ng';
$labels['varupperfirst'] = 'chữ cái đầu viết hoa';
-$labels['varquotewildcard'] = 'quote special characters';
+$labels['varquotewildcard'] = 'trích dẫn ký tự đặc biệt';
$labels['varlength'] = 'độ dài';
-$labels['notify'] = 'Send notification';
+$labels['notify'] = 'Gửi thông báo';
$labels['notifyaddress'] = 'Gửi đến địa chỉ email:';
$labels['notifybody'] = 'Notification body:';
$labels['notifysubject'] = 'Notification subject:';
diff --git a/plugins/managesieve/localization/zh_CN.inc b/plugins/managesieve/localization/zh_CN.inc
index 106fb40fc..79b705c54 100644
--- a/plugins/managesieve/localization/zh_CN.inc
+++ b/plugins/managesieve/localization/zh_CN.inc
@@ -55,7 +55,7 @@ $labels['add'] = '添加';
$labels['del'] = '删除';
$labels['sender'] = 'å‘件人';
$labels['recipient'] = '收件人';
-$labels['vacationaddr'] = '收件人地å€çš„附加åå•';
+$labels['vacationaddresses'] = '收件人地å€çš„附加åå•ï¼ˆä»¥åŠè§’逗å·åˆ†éš”)';
$labels['vacationdays'] = 'å‘é€é‚®ä»¶é¢‘率(å•ä½ï¼šå¤©):';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/localization/zh_TW.inc b/plugins/managesieve/localization/zh_TW.inc
index 047ebcccc..3f3fc1313 100644
--- a/plugins/managesieve/localization/zh_TW.inc
+++ b/plugins/managesieve/localization/zh_TW.inc
@@ -55,7 +55,7 @@ $labels['add'] = '新增';
$labels['del'] = '刪除';
$labels['sender'] = '寄件者';
$labels['recipient'] = '收件者';
-$labels['vacationaddr'] = '其他收件者:';
+$labels['vacationaddresses'] = '其他收件者(用åŠå½¢é€—號隔開):';
$labels['vacationdays'] = '多久回覆一次(單ä½ï¼šå¤©ï¼‰ï¼š';
$labels['vacationinterval'] = 'How often send messages:';
$labels['days'] = 'days';
diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js
index 156bce6f0..035ed7bec 100644
--- a/plugins/managesieve/managesieve.js
+++ b/plugins/managesieve/managesieve.js
@@ -55,11 +55,6 @@ if (window.rcmail) {
}
$('input[type="text"]:first', rcmail.gui_objects.sieveform).focus();
-
- // initialize smart list inputs
- $('textarea[data-type="list"]', rcmail.gui_objects.sieveform).each(function() {
- smart_field_init(this);
- });
}
else {
rcmail.enable_command('plugin.managesieve-add', 'plugin.managesieve-setadd', !rcmail.env.sieveconnerror);
@@ -474,11 +469,6 @@ rcube_webmail.prototype.managesieve_rulefill = function(content, id, after)
row.className = 'rulerow';
row.innerHTML = content;
- // initialize smart list inputs
- $('textarea[data-type="list"]', row).each(function() {
- smart_field_init(this);
- });
-
this.managesieve_formbuttons(div);
}
};
@@ -575,45 +565,40 @@ function rule_header_select(id)
var obj = document.getElementById('header' + id),
size = document.getElementById('rule_size' + id),
op = document.getElementById('rule_op' + id),
- header = document.getElementById('custom_header' + id + '_list'),
+ target = document.getElementById('rule_target' + id),
+ header = document.getElementById('custom_header' + id),
mod = document.getElementById('rule_mod' + id),
trans = document.getElementById('rule_trans' + id),
- comp = document.getElementById('rule_comp' + id),
- datepart = document.getElementById('rule_date_part' + id),
- dateheader = document.getElementById('rule_date_header_div' + id),
- h = obj.value;
+ comp = document.getElementById('rule_comp' + id);
- if (h == 'size') {
+ if (obj.value == 'size') {
size.style.display = 'inline';
- $.each([op, header, mod, trans, comp], function() { this.style.display = 'none'; });
+ op.style.display = 'none';
+ target.style.display = 'none';
+ header.style.display = 'none';
+ mod.style.display = 'none';
+ trans.style.display = 'none';
+ comp.style.display = 'none';
}
else {
- header.style.display = h != '...' ? 'none' : 'inline-block';
+ header.style.display = obj.value != '...' ? 'none' : 'inline';
size.style.display = 'none';
op.style.display = 'inline';
comp.style.display = '';
- mod.style.display = h == 'body' || h == 'currentdate' || h == 'date' ? 'none' : 'block';
- trans.style.display = h == 'body' ? 'block' : 'none';
+ rule_op_select(id);
+ mod.style.display = obj.value == 'body' ? 'none' : 'block';
+ trans.style.display = obj.value == 'body' ? 'block' : 'none';
}
- if (datepart)
- datepart.style.display = h == 'currentdate' || h == 'date' ? 'inline' : 'none';
- if (dateheader)
- dateheader.style.display = h == 'date' ? '' : 'none';
-
- rule_op_select(op, id, h);
- rule_mod_select(id, h);
- obj.style.width = h == '...' ? '40px' : '';
+ obj.style.width = obj.value == '...' ? '40px' : '';
};
-function rule_op_select(obj, id, header)
+function rule_op_select(id)
{
- var target = document.getElementById('rule_target' + id + '_list');
+ var obj = document.getElementById('rule_op' + id),
+ target = document.getElementById('rule_target' + id);
- if (!header)
- header = document.getElementById('header' + id).value;
-
- target.style.display = obj.value == 'exists' || obj.value == 'notexists' || header == 'size' ? 'none' : 'inline-block';
+ target.style.display = obj.value == 'exists' || obj.value == 'notexists' ? 'none' : 'inline';
};
function rule_trans_select(id)
@@ -624,19 +609,12 @@ function rule_trans_select(id)
target.style.display = obj.value != 'content' ? 'none' : 'inline';
};
-function rule_mod_select(id, header)
+function rule_mod_select(id)
{
var obj = document.getElementById('rule_mod_op' + id),
- target = document.getElementById('rule_mod_type' + id),
- index = document.getElementById('rule_index_div' + id);
-
- if (!header)
- header = document.getElementById('header' + id).value;
+ target = document.getElementById('rule_mod_type' + id);
target.style.display = obj.value != 'address' && obj.value != 'envelope' ? 'none' : 'inline';
-
- if (index)
- index.style.display = header != 'body' && header != 'currentdate' && header != 'size' && obj.value != 'envelope' ? '' : 'none';
};
function rule_join_radio(value)
@@ -661,7 +639,7 @@ function rule_adv_switch(id, elem)
function action_type_select(id)
{
var obj = document.getElementById('action_type' + id),
- v = obj.value, enabled = {},
+ enabled = {},
elems = {
mailbox: document.getElementById('action_mailbox' + id),
target: document.getElementById('action_target' + id),
@@ -672,25 +650,25 @@ function action_type_select(id)
notify: document.getElementById('action_notify' + id)
};
- if (v == 'fileinto' || v == 'fileinto_copy') {
+ if (obj.value == 'fileinto' || obj.value == 'fileinto_copy') {
enabled.mailbox = 1;
}
- else if (v == 'redirect' || v == 'redirect_copy') {
+ else if (obj.value == 'redirect' || obj.value == 'redirect_copy') {
enabled.target = 1;
}
- else if (v.match(/^reject|ereject$/)) {
+ else if (obj.value.match(/^reject|ereject$/)) {
enabled.target_area = 1;
}
- else if (v.match(/^(add|set|remove)flag$/)) {
+ else if (obj.value.match(/^(add|set|remove)flag$/)) {
enabled.flags = 1;
}
- else if (v == 'vacation') {
+ else if (obj.value == 'vacation') {
enabled.vacation = 1;
}
- else if (v == 'set') {
+ else if (obj.value == 'set') {
enabled.set = 1;
}
- else if (v == 'notify') {
+ else if (obj.value == 'notify') {
enabled.notify = 1;
}
@@ -699,72 +677,6 @@ function action_type_select(id)
}
};
-// Inititalizes smart list input
-function smart_field_init(field)
-{
- var id = field.id + '_list',
- area = $('<span class="listarea"></span>'),
- list = field.value ? field.value.split("\n") : [''];
-
- if ($('#'+id).length)
- return;
-
- // add input rows
- $.each(list, function(i, v) {
- area.append(smart_field_row(v, field.name, i, $(field).data('size')));
- });
-
- area.attr('id', id);
- field = $(field);
-
- if (field.attr('disabled'))
- area.hide();
-
- field.after(area);
-
- if (field.hasClass('error')) {
- area.addClass('error');
- rcmail.managesieve_tip_register([[id, field.data('tip')]]);
- }
-};
-
-function smart_field_row(value, name, idx, size)
-{
- // build row element content
- var input, content = '<span class="listelement">'
- + '<span class="reset"></span><input type="text"></span>',
- elem = $(content),
- attrs = {value: value, name: name + '[]'};
-
- if (size)
- attrs.size = size;
-
- input = $('input', elem).attr(attrs).keydown(function(e) {
- var input = $(this);
- // element creation event (on Enter)
- if (e.which == 13) {
- var name = input.attr('name').replace(/\[\]$/, ''),
- dt = (new Date()).getTime(),
- elem = smart_field_row('', name, dt, size);
-
- input.parent().after(elem);
- $('input', elem).focus();
- }
- });
-
- // element deletion event
- $('span[class="reset"]', elem).click(function() {
- var span = $(this.parentNode);
-
- if (span.parent().children().length > 1)
- span.remove();
- else
- $('input', span).val('').focus();
- });
-
- return elem;
-}
-
// Register onmouse(leave/enter) events for tips on specified form element
rcube_webmail.prototype.managesieve_tip_register = function(tips)
{
@@ -773,26 +685,25 @@ rcube_webmail.prototype.managesieve_tip_register = function(tips)
for (var n in tips) {
$('#'+tips[n][0])
- .data('tip', tips[n][1])
- .bind('mouseenter', function(e) {
- var elem = $(this),
- offset = elem.offset(),
- left = offset.left,
- top = offset.top - 12,
- minwidth = elem.width();
-
- if (framed) {
- offset = $((rcmail.env.task == 'mail' ? '#sievefilterform > iframe' : '#filter-box'), parent.document).offset();
- top += offset.top;
- left += offset.left;
- }
-
- tip.html(elem.data('tip'));
- top -= tip.height();
-
- tip.css({left: left, top: top, minWidth: (minwidth-2) + 'px'}).show();
- })
- .bind('mouseleave', function(e) { tip.hide(); });
+ .bind('mouseenter', {str: tips[n][1]},
+ function(e) {
+ var offset = $(this).offset(),
+ left = offset.left,
+ top = offset.top - 12,
+ minwidth = $(this).width();
+
+ if (framed) {
+ offset = $((rcmail.env.task == 'mail' ? '#sievefilterform > iframe' : '#filter-box'), parent.document).offset();
+ top += offset.top;
+ left += offset.left;
+ }
+
+ tip.html(e.data.str)
+ top -= tip.height();
+
+ tip.css({left: left, top: top, minWidth: (minwidth-2) + 'px'}).show();
+ })
+ .bind('mouseleave', function(e) { tip.hide(); });
}
};
diff --git a/plugins/managesieve/managesieve.php b/plugins/managesieve/managesieve.php
index 6970193c2..80face70a 100644
--- a/plugins/managesieve/managesieve.php
+++ b/plugins/managesieve/managesieve.php
@@ -12,28 +12,60 @@
*
* Configuration (see config.inc.php.dist)
*
- * Copyright (C) 2008-2013, The Roundcube Dev Team
- * Copyright (C) 2011-2013, Kolab Systems AG
+ * Copyright (C) 2008-2012, The Roundcube Dev Team
+ * Copyright (C) 2011-2012, Kolab Systems AG
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class managesieve extends rcube_plugin
{
public $task = 'mail|settings';
+
private $rc;
- private $engine;
+ private $sieve;
+ private $errors;
+ private $form;
+ private $tips = array();
+ private $script = array();
+ private $exts = array();
+ private $list;
+ private $active = array();
+ private $headers = array(
+ 'subject' => 'Subject',
+ 'from' => 'From',
+ 'to' => 'To',
+ );
+ private $addr_headers = array(
+ // Required
+ "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to",
+ // Additional (RFC 822 / RFC 2822)
+ "reply-to", "resent-reply-to", "resent-sender", "resent-cc", "resent-bcc",
+ // Non-standard (RFC 2076, draft-palme-mailext-headers-08.txt)
+ "for-approval", "for-handling", "for-comment", "apparently-to", "errors-to",
+ "delivered-to", "return-receipt-to", "x-admin", "read-receipt-to",
+ "x-confirm-reading-to", "return-receipt-requested",
+ "registered-mail-reply-requested-by", "mail-followup-to", "mail-reply-to",
+ "abuse-reports-to", "x-complaints-to", "x-report-abuse-to",
+ // Undocumented
+ "x-beenthere",
+ );
+
+ const VERSION = '6.2';
+ const PROGNAME = 'Roundcube (Managesieve)';
+ const PORT = 4190;
+
function init()
{
@@ -60,11 +92,10 @@ class managesieve extends rcube_plugin
/**
* Initializes plugin's UI (localization, js script)
*/
- function init_ui()
+ private function init_ui()
{
- if ($this->ui_initialized) {
+ if ($this->ui_initialized)
return;
- }
// load localization
$this->add_texts('localization/', array('filters','managefilters'));
@@ -78,11 +109,6 @@ class managesieve extends rcube_plugin
*/
function mail_task_handler()
{
- // make sure we're not in ajax request
- if ($this->rc->output->type != 'html') {
- return;
- }
-
// use jQuery for popup window
$this->require_plugin('jqueryui');
@@ -154,18 +180,352 @@ class managesieve extends rcube_plugin
}
/**
- * Plugin action handler
+ * Loads configuration, initializes plugin (including sieve connection)
*/
+ function managesieve_start()
+ {
+ $this->load_config();
+
+ // register UI objects
+ $this->rc->output->add_handlers(array(
+ 'filterslist' => array($this, 'filters_list'),
+ 'filtersetslist' => array($this, 'filtersets_list'),
+ 'filterframe' => array($this, 'filter_frame'),
+ 'filterform' => array($this, 'filter_form'),
+ 'filtersetform' => array($this, 'filterset_form'),
+ ));
+
+ // Add include path for internal classes
+ $include_path = $this->home . '/lib' . PATH_SEPARATOR;
+ $include_path .= ini_get('include_path');
+ set_include_path($include_path);
+
+ // Get connection parameters
+ $host = $this->rc->config->get('managesieve_host', 'localhost');
+ $port = $this->rc->config->get('managesieve_port');
+ $tls = $this->rc->config->get('managesieve_usetls', false);
+
+ $host = rcube_parse_host($host);
+ $host = rcube_idn_to_ascii($host);
+
+ // remove tls:// prefix, set TLS flag
+ if (($host = preg_replace('|^tls://|i', '', $host, 1, $cnt)) && $cnt) {
+ $tls = true;
+ }
+
+ if (empty($port)) {
+ $port = getservbyname('sieve', 'tcp');
+ if (empty($port)) {
+ $port = self::PORT;
+ }
+ }
+
+ $plugin = $this->rc->plugins->exec_hook('managesieve_connect', array(
+ 'user' => $_SESSION['username'],
+ 'password' => $this->rc->decrypt($_SESSION['password']),
+ 'host' => $host,
+ 'port' => $port,
+ 'usetls' => $tls,
+ 'auth_type' => $this->rc->config->get('managesieve_auth_type'),
+ 'disabled' => $this->rc->config->get('managesieve_disabled_extensions'),
+ 'debug' => $this->rc->config->get('managesieve_debug', false),
+ 'auth_cid' => $this->rc->config->get('managesieve_auth_cid'),
+ 'auth_pw' => $this->rc->config->get('managesieve_auth_pw'),
+ ));
+
+ // try to connect to managesieve server and to fetch the script
+ $this->sieve = new rcube_sieve(
+ $plugin['user'],
+ $plugin['password'],
+ $plugin['host'],
+ $plugin['port'],
+ $plugin['auth_type'],
+ $plugin['usetls'],
+ $plugin['disabled'],
+ $plugin['debug'],
+ $plugin['auth_cid'],
+ $plugin['auth_pw']
+ );
+
+ if (!($error = $this->sieve->error())) {
+ // Get list of scripts
+ $list = $this->list_scripts();
+
+ if (!empty($_GET['_set']) || !empty($_POST['_set'])) {
+ $script_name = get_input_value('_set', RCUBE_INPUT_GPC, true);
+ }
+ else if (!empty($_SESSION['managesieve_current'])) {
+ $script_name = $_SESSION['managesieve_current'];
+ }
+ else {
+ // get (first) active script
+ if (!empty($this->active[0])) {
+ $script_name = $this->active[0];
+ }
+ else if ($list) {
+ $script_name = $list[0];
+ }
+ // create a new (initial) script
+ else {
+ // if script not exists build default script contents
+ $script_file = $this->rc->config->get('managesieve_default');
+ $script_name = $this->rc->config->get('managesieve_script_name');
+
+ if (empty($script_name))
+ $script_name = 'roundcube';
+
+ if ($script_file && is_readable($script_file))
+ $content = file_get_contents($script_file);
+
+ // add script and set it active
+ if ($this->sieve->save_script($script_name, $content)) {
+ $this->activate_script($script_name);
+ $this->list[] = $script_name;
+ }
+ }
+ }
+
+ if ($script_name) {
+ $this->sieve->load($script_name);
+ }
+
+ $error = $this->sieve->error();
+ }
+
+ // finally set script objects
+ if ($error) {
+ switch ($error) {
+ case SIEVE_ERROR_CONNECTION:
+ case SIEVE_ERROR_LOGIN:
+ $this->rc->output->show_message('managesieve.filterconnerror', 'error');
+ break;
+ default:
+ $this->rc->output->show_message('managesieve.filterunknownerror', 'error');
+ break;
+ }
+
+ raise_error(array('code' => 403, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Unable to connect to managesieve on $host:$port"), true, false);
+
+ // to disable 'Add filter' button set env variable
+ $this->rc->output->set_env('filterconnerror', true);
+ $this->script = array();
+ }
+ else {
+ $this->exts = $this->sieve->get_extensions();
+ $this->script = $this->sieve->script->as_array();
+ $this->rc->output->set_env('currentset', $this->sieve->current);
+ $_SESSION['managesieve_current'] = $this->sieve->current;
+ }
+
+ return $error;
+ }
+
function managesieve_actions()
{
$this->init_ui();
- $engine = $this->get_engine();
- $engine->actions();
+
+ $error = $this->managesieve_start();
+
+ // Handle user requests
+ if ($action = get_input_value('_act', RCUBE_INPUT_GPC)) {
+ $fid = (int) get_input_value('_fid', RCUBE_INPUT_POST);
+
+ if ($action == 'delete' && !$error) {
+ if (isset($this->script[$fid])) {
+ if ($this->sieve->script->delete_rule($fid))
+ $result = $this->save_script();
+
+ if ($result === true) {
+ $this->rc->output->show_message('managesieve.filterdeleted', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'del', array('id' => $fid));
+ } else {
+ $this->rc->output->show_message('managesieve.filterdeleteerror', 'error');
+ }
+ }
+ }
+ else if ($action == 'move' && !$error) {
+ if (isset($this->script[$fid])) {
+ $to = (int) get_input_value('_to', RCUBE_INPUT_POST);
+ $rule = $this->script[$fid];
+
+ // remove rule
+ unset($this->script[$fid]);
+ $this->script = array_values($this->script);
+
+ // add at target position
+ if ($to >= count($this->script)) {
+ $this->script[] = $rule;
+ }
+ else {
+ $script = array();
+ foreach ($this->script as $idx => $r) {
+ if ($idx == $to)
+ $script[] = $rule;
+ $script[] = $r;
+ }
+ $this->script = $script;
+ }
+
+ $this->sieve->script->content = $this->script;
+ $result = $this->save_script();
+
+ if ($result === true) {
+ $result = $this->list_rules();
+
+ $this->rc->output->show_message('managesieve.moved', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'list',
+ array('list' => $result, 'clear' => true, 'set' => $to));
+ } else {
+ $this->rc->output->show_message('managesieve.moveerror', 'error');
+ }
+ }
+ }
+ else if ($action == 'act' && !$error) {
+ if (isset($this->script[$fid])) {
+ $rule = $this->script[$fid];
+ $disabled = $rule['disabled'] ? true : false;
+ $rule['disabled'] = !$disabled;
+ $result = $this->sieve->script->update_rule($fid, $rule);
+
+ if ($result !== false)
+ $result = $this->save_script();
+
+ if ($result === true) {
+ if ($rule['disabled'])
+ $this->rc->output->show_message('managesieve.deactivated', 'confirmation');
+ else
+ $this->rc->output->show_message('managesieve.activated', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'update',
+ array('id' => $fid, 'disabled' => $rule['disabled']));
+ } else {
+ if ($rule['disabled'])
+ $this->rc->output->show_message('managesieve.deactivateerror', 'error');
+ else
+ $this->rc->output->show_message('managesieve.activateerror', 'error');
+ }
+ }
+ }
+ else if ($action == 'setact' && !$error) {
+ $script_name = get_input_value('_set', RCUBE_INPUT_GPC, true);
+ $result = $this->activate_script($script_name);
+ $kep14 = $this->rc->config->get('managesieve_kolab_master');
+
+ if ($result === true) {
+ $this->rc->output->set_env('active_sets', $this->active);
+ $this->rc->output->show_message('managesieve.setactivated', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'setact',
+ array('name' => $script_name, 'active' => true, 'all' => !$kep14));
+ } else {
+ $this->rc->output->show_message('managesieve.setactivateerror', 'error');
+ }
+ }
+ else if ($action == 'deact' && !$error) {
+ $script_name = get_input_value('_set', RCUBE_INPUT_GPC, true);
+ $result = $this->deactivate_script($script_name);
+
+ if ($result === true) {
+ $this->rc->output->set_env('active_sets', $this->active);
+ $this->rc->output->show_message('managesieve.setdeactivated', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'setact',
+ array('name' => $script_name, 'active' => false));
+ } else {
+ $this->rc->output->show_message('managesieve.setdeactivateerror', 'error');
+ }
+ }
+ else if ($action == 'setdel' && !$error) {
+ $script_name = get_input_value('_set', RCUBE_INPUT_GPC, true);
+ $result = $this->remove_script($script_name);
+
+ if ($result === true) {
+ $this->rc->output->show_message('managesieve.setdeleted', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'setdel',
+ array('name' => $script_name));
+ $this->rc->session->remove('managesieve_current');
+ } else {
+ $this->rc->output->show_message('managesieve.setdeleteerror', 'error');
+ }
+ }
+ else if ($action == 'setget') {
+ $script_name = get_input_value('_set', RCUBE_INPUT_GPC, true);
+ $script = $this->sieve->get_script($script_name);
+
+ if (PEAR::isError($script))
+ exit;
+
+ $browser = new rcube_browser;
+
+ // send download headers
+ header("Content-Type: application/octet-stream");
+ header("Content-Length: ".strlen($script));
+
+ if ($browser->ie)
+ header("Content-Type: application/force-download");
+ if ($browser->ie && $browser->ver < 7)
+ $filename = rawurlencode(abbreviate_string($script_name, 55));
+ else if ($browser->ie)
+ $filename = rawurlencode($script_name);
+ else
+ $filename = addcslashes($script_name, '\\"');
+
+ header("Content-Disposition: attachment; filename=\"$filename.txt\"");
+ echo $script;
+ exit;
+ }
+ else if ($action == 'list') {
+ $result = $this->list_rules();
+
+ $this->rc->output->command('managesieve_updatelist', 'list', array('list' => $result));
+ }
+ else if ($action == 'ruleadd') {
+ $rid = get_input_value('_rid', RCUBE_INPUT_GPC);
+ $id = $this->genid();
+ $content = $this->rule_div($fid, $id, false);
+
+ $this->rc->output->command('managesieve_rulefill', $content, $id, $rid);
+ }
+ else if ($action == 'actionadd') {
+ $aid = get_input_value('_aid', RCUBE_INPUT_GPC);
+ $id = $this->genid();
+ $content = $this->action_div($fid, $id, false);
+
+ $this->rc->output->command('managesieve_actionfill', $content, $id, $aid);
+ }
+
+ $this->rc->output->send();
+ }
+ else if ($this->rc->task == 'mail') {
+ // Initialize the form
+ $rules = get_input_value('r', RCUBE_INPUT_GET);
+ if (!empty($rules)) {
+ $i = 0;
+ foreach ($rules as $rule) {
+ list($header, $value) = explode(':', $rule, 2);
+ $tests[$i] = array(
+ 'type' => 'contains',
+ 'test' => 'header',
+ 'arg1' => $header,
+ 'arg2' => $value,
+ );
+ $i++;
+ }
+
+ $this->form = array(
+ 'join' => count($tests) > 1 ? 'allof' : 'anyof',
+ 'name' => '',
+ 'tests' => $tests,
+ 'actions' => array(
+ 0 => array('type' => 'fileinto'),
+ 1 => array('type' => 'stop'),
+ ),
+ );
+ }
+ }
+
+ $this->managesieve_send();
}
- /**
- * Forms save action handler
- */
function managesieve_save()
{
// load localization
@@ -176,26 +536,1515 @@ class managesieve extends rcube_plugin
$this->include_script('managesieve.js');
}
- $engine = $this->get_engine();
- $engine->save();
+ // Init plugin and handle managesieve connection
+ $error = $this->managesieve_start();
+
+ // get request size limits (#1488648)
+ $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' => "Request size limit exceeded (one of max_input_vars/suhosin.request.max_vars/suhosin.post.max_vars)"
+ ), true, false);
+ $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+ }
+ // check request depth limits
+ else if ($max_depth && count($_POST['_header']) > $max_depth) {
+ rcube::raise_error(array(
+ 'code' => 500, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Request size limit exceeded (one of suhosin.request.max_array_depth/suhosin.post.max_array_depth)"
+ ), true, false);
+ $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+ }
+ // filters set add action
+ else if (!empty($_POST['_newset'])) {
+ $name = get_input_value('_name', RCUBE_INPUT_POST, true);
+ $copy = get_input_value('_copy', RCUBE_INPUT_POST, true);
+ $from = get_input_value('_from', RCUBE_INPUT_POST);
+ $exceptions = $this->rc->config->get('managesieve_filename_exceptions');
+ $kolab = $this->rc->config->get('managesieve_kolab_master');
+ $name_uc = mb_strtolower($name);
+ $list = $this->list_scripts();
+
+ if (!$name) {
+ $this->errors['name'] = $this->gettext('cannotbeempty');
+ }
+ else if (mb_strlen($name) > 128) {
+ $this->errors['name'] = $this->gettext('nametoolong');
+ }
+ else if (!empty($exceptions) && in_array($name, (array)$exceptions)) {
+ $this->errors['name'] = $this->gettext('namereserved');
+ }
+ else if (!empty($kolab) && in_array($name_uc, array('MASTER', 'USER', 'MANAGEMENT'))) {
+ $this->errors['name'] = $this->gettext('namereserved');
+ }
+ else if (in_array($name, $list)) {
+ $this->errors['name'] = $this->gettext('setexist');
+ }
+ else if ($from == 'file') {
+ // from file
+ if (is_uploaded_file($_FILES['_file']['tmp_name'])) {
+ $file = file_get_contents($_FILES['_file']['tmp_name']);
+ $file = preg_replace('/\r/', '', $file);
+ // for security don't save script directly
+ // check syntax before, like this...
+ $this->sieve->load_script($file);
+ if (!$this->save_script($name)) {
+ $this->errors['file'] = $this->gettext('setcreateerror');
+ }
+ }
+ else { // upload failed
+ $err = $_FILES['_file']['error'];
+
+ if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
+ $msg = rcube_label(array('name' => 'filesizeerror',
+ 'vars' => array('size' =>
+ show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
+ }
+ else {
+ $this->errors['file'] = $this->gettext('fileuploaderror');
+ }
+ }
+ }
+ else if (!$this->sieve->copy($name, $from == 'set' ? $copy : '')) {
+ $error = 'managesieve.setcreateerror';
+ }
+
+ if (!$error && empty($this->errors)) {
+ // Find position of the new script on the list
+ $list[] = $name;
+ asort($list, SORT_LOCALE_STRING);
+ $list = array_values($list);
+ $index = array_search($name, $list);
+
+ $this->rc->output->show_message('managesieve.setcreated', 'confirmation');
+ $this->rc->output->command('parent.managesieve_updatelist', 'setadd',
+ array('name' => $name, 'index' => $index));
+ } else if ($msg) {
+ $this->rc->output->command('display_message', $msg, 'error');
+ } else if ($error) {
+ $this->rc->output->show_message($error, 'error');
+ }
+ }
+ // filter add/edit action
+ else if (isset($_POST['_name'])) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST, true));
+ $fid = trim(get_input_value('_fid', RCUBE_INPUT_POST));
+ $join = trim(get_input_value('_join', RCUBE_INPUT_POST));
+
+ // and arrays
+ $headers = get_input_value('_header', RCUBE_INPUT_POST);
+ $cust_headers = get_input_value('_custom_header', RCUBE_INPUT_POST);
+ $ops = get_input_value('_rule_op', RCUBE_INPUT_POST);
+ $sizeops = get_input_value('_rule_size_op', RCUBE_INPUT_POST);
+ $sizeitems = get_input_value('_rule_size_item', RCUBE_INPUT_POST);
+ $sizetargets = get_input_value('_rule_size_target', RCUBE_INPUT_POST);
+ $targets = get_input_value('_rule_target', RCUBE_INPUT_POST, true);
+ $mods = get_input_value('_rule_mod', RCUBE_INPUT_POST);
+ $mod_types = get_input_value('_rule_mod_type', RCUBE_INPUT_POST);
+ $body_trans = get_input_value('_rule_trans', RCUBE_INPUT_POST);
+ $body_types = get_input_value('_rule_trans_type', RCUBE_INPUT_POST, true);
+ $comparators = get_input_value('_rule_comp', RCUBE_INPUT_POST);
+ $act_types = get_input_value('_action_type', RCUBE_INPUT_POST, true);
+ $mailboxes = get_input_value('_action_mailbox', RCUBE_INPUT_POST, true);
+ $act_targets = get_input_value('_action_target', RCUBE_INPUT_POST, true);
+ $area_targets = get_input_value('_action_target_area', RCUBE_INPUT_POST, true);
+ $reasons = get_input_value('_action_reason', RCUBE_INPUT_POST, true);
+ $addresses = get_input_value('_action_addresses', RCUBE_INPUT_POST, true);
+ $days = get_input_value('_action_days', RCUBE_INPUT_POST);
+ $subject = get_input_value('_action_subject', RCUBE_INPUT_POST, true);
+ $flags = get_input_value('_action_flags', RCUBE_INPUT_POST);
+ $varnames = get_input_value('_action_varname', RCUBE_INPUT_POST);
+ $varvalues = get_input_value('_action_varvalue', RCUBE_INPUT_POST);
+ $varmods = get_input_value('_action_varmods', RCUBE_INPUT_POST);
+ $notifyaddrs = get_input_value('_action_notifyaddress', RCUBE_INPUT_POST);
+ $notifybodies = get_input_value('_action_notifybody', RCUBE_INPUT_POST);
+ $notifymessages = get_input_value('_action_notifymessage', RCUBE_INPUT_POST);
+ $notifyfrom = get_input_value('_action_notifyfrom', RCUBE_INPUT_POST);
+ $notifyimp = get_input_value('_action_notifyimportance', RCUBE_INPUT_POST);
+
+ // we need a "hack" for radiobuttons
+ foreach ($sizeitems as $item)
+ $items[] = $item;
+
+ $this->form['disabled'] = $_POST['_disabled'] ? true : false;
+ $this->form['join'] = $join=='allof' ? true : false;
+ $this->form['name'] = $name;
+ $this->form['tests'] = array();
+ $this->form['actions'] = array();
+
+ if ($name == '')
+ $this->errors['name'] = $this->gettext('cannotbeempty');
+ else {
+ foreach($this->script as $idx => $rule)
+ if($rule['name'] == $name && $idx != $fid) {
+ $this->errors['name'] = $this->gettext('ruleexist');
+ break;
+ }
+ }
+
+ $i = 0;
+ // rules
+ if ($join == 'any') {
+ $this->form['tests'][0]['test'] = 'true';
+ }
+ else {
+ foreach ($headers as $idx => $header) {
+ $header = $this->strip_value($header);
+ $target = $this->strip_value($targets[$idx], true);
+ $operator = $this->strip_value($ops[$idx]);
+ $comparator = $this->strip_value($comparators[$idx]);
+
+ if ($header == 'size') {
+ $sizeop = $this->strip_value($sizeops[$idx]);
+ $sizeitem = $this->strip_value($items[$idx]);
+ $sizetarget = $this->strip_value($sizetargets[$idx]);
+
+ $this->form['tests'][$i]['test'] = 'size';
+ $this->form['tests'][$i]['type'] = $sizeop;
+ $this->form['tests'][$i]['arg'] = $sizetarget;
+
+ if ($sizetarget == '')
+ $this->errors['tests'][$i]['sizetarget'] = $this->gettext('cannotbeempty');
+ else if (!preg_match('/^[0-9]+(K|M|G)?$/i', $sizetarget.$sizeitem, $m)) {
+ $this->errors['tests'][$i]['sizetarget'] = $this->gettext('forbiddenchars');
+ $this->form['tests'][$i]['item'] = $sizeitem;
+ }
+ else
+ $this->form['tests'][$i]['arg'] .= $m[1];
+ }
+ else if ($header == 'body') {
+ $trans = $this->strip_value($body_trans[$idx]);
+ $trans_type = $this->strip_value($body_types[$idx], true);
+
+ if (preg_match('/^not/', $operator))
+ $this->form['tests'][$i]['not'] = true;
+ $type = preg_replace('/^not/', '', $operator);
+
+ if ($type == 'exists') {
+ $this->errors['tests'][$i]['op'] = true;
+ }
+
+ $this->form['tests'][$i]['test'] = 'body';
+ $this->form['tests'][$i]['type'] = $type;
+ $this->form['tests'][$i]['arg'] = $target;
+
+ if ($target == '' && $type != 'exists')
+ $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty');
+ else if (preg_match('/^(value|count)-/', $type) && !preg_match('/[0-9]+/', $target))
+ $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars');
+
+ $this->form['tests'][$i]['part'] = $trans;
+ if ($trans == 'content') {
+ $this->form['tests'][$i]['content'] = $trans_type;
+ }
+ }
+ else {
+ $cust_header = $headers = $this->strip_value($cust_headers[$idx]);
+ $mod = $this->strip_value($mods[$idx]);
+ $mod_type = $this->strip_value($mod_types[$idx]);
+
+ if (preg_match('/^not/', $operator))
+ $this->form['tests'][$i]['not'] = true;
+ $type = preg_replace('/^not/', '', $operator);
+
+ if ($header == '...') {
+ $headers = preg_split('/[\s,]+/', $cust_header, -1, PREG_SPLIT_NO_EMPTY);
+
+ if (!count($headers))
+ $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty');
+ else {
+ foreach ($headers as $hr) {
+ // RFC2822: printable ASCII except colon
+ if (!preg_match('/^[\x21-\x39\x41-\x7E]+$/i', $hr)) {
+ $this->errors['tests'][$i]['header'] = $this->gettext('forbiddenchars');
+ }
+ }
+ }
+
+ if (empty($this->errors['tests'][$i]['header']))
+ $cust_header = (is_array($headers) && count($headers) == 1) ? $headers[0] : $headers;
+ }
+
+ if ($type == 'exists') {
+ $this->form['tests'][$i]['test'] = 'exists';
+ $this->form['tests'][$i]['arg'] = $header == '...' ? $cust_header : $header;
+ }
+ else {
+ $test = 'header';
+ $header = $header == '...' ? $cust_header : $header;
+
+ if ($mod == 'address' || $mod == 'envelope') {
+ $found = false;
+ if (empty($this->errors['tests'][$i]['header'])) {
+ foreach ((array)$header as $hdr) {
+ if (!in_array(strtolower(trim($hdr)), $this->addr_headers))
+ $found = true;
+ }
+ }
+ if (!$found)
+ $test = $mod;
+ }
+
+ $this->form['tests'][$i]['type'] = $type;
+ $this->form['tests'][$i]['test'] = $test;
+ $this->form['tests'][$i]['arg1'] = $header;
+ $this->form['tests'][$i]['arg2'] = $target;
+
+ if ($target == '')
+ $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty');
+ else if (preg_match('/^(value|count)-/', $type) && !preg_match('/[0-9]+/', $target))
+ $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars');
+
+ if ($mod) {
+ $this->form['tests'][$i]['part'] = $mod_type;
+ }
+ }
+ }
+
+ if ($header != 'size' && $comparator) {
+ if (preg_match('/^(value|count)/', $this->form['tests'][$i]['type']))
+ $comparator = 'i;ascii-numeric';
+
+ $this->form['tests'][$i]['comparator'] = $comparator;
+ }
+
+ $i++;
+ }
+ }
+
+ $i = 0;
+ // actions
+ foreach($act_types as $idx => $type) {
+ $type = $this->strip_value($type);
+ $target = $this->strip_value($act_targets[$idx]);
+
+ switch ($type) {
+
+ case 'fileinto':
+ case 'fileinto_copy':
+ $mailbox = $this->strip_value($mailboxes[$idx], false, false);
+ $this->form['actions'][$i]['target'] = $this->mod_mailbox($mailbox, 'in');
+ if ($type == 'fileinto_copy') {
+ $type = 'fileinto';
+ $this->form['actions'][$i]['copy'] = true;
+ }
+ break;
+
+ case 'reject':
+ case 'ereject':
+ $target = $this->strip_value($area_targets[$idx]);
+ $this->form['actions'][$i]['target'] = str_replace("\r\n", "\n", $target);
+
+ // if ($target == '')
+// $this->errors['actions'][$i]['targetarea'] = $this->gettext('cannotbeempty');
+ break;
+
+ case 'redirect':
+ case 'redirect_copy':
+ $this->form['actions'][$i]['target'] = $target;
+
+ if ($this->form['actions'][$i]['target'] == '')
+ $this->errors['actions'][$i]['target'] = $this->gettext('cannotbeempty');
+ else if (!check_email($this->form['actions'][$i]['target']))
+ $this->errors['actions'][$i]['target'] = $this->gettext('noemailwarning');
+
+ if ($type == 'redirect_copy') {
+ $type = 'redirect';
+ $this->form['actions'][$i]['copy'] = true;
+ }
+ break;
+
+ case 'addflag':
+ case 'setflag':
+ case 'removeflag':
+ $_target = array();
+ if (empty($flags[$idx])) {
+ $this->errors['actions'][$i]['target'] = $this->gettext('noflagset');
+ }
+ else {
+ foreach ($flags[$idx] as $flag) {
+ $_target[] = $this->strip_value($flag);
+ }
+ }
+ $this->form['actions'][$i]['target'] = $_target;
+ break;
+
+ case 'vacation':
+ $reason = $this->strip_value($reasons[$idx]);
+ $this->form['actions'][$i]['reason'] = str_replace("\r\n", "\n", $reason);
+ $this->form['actions'][$i]['days'] = $days[$idx];
+ $this->form['actions'][$i]['subject'] = $subject[$idx];
+ $this->form['actions'][$i]['addresses'] = explode(',', $addresses[$idx]);
+// @TODO: vacation :mime, :from, :handle
+
+ if ($this->form['actions'][$i]['addresses']) {
+ foreach($this->form['actions'][$i]['addresses'] as $aidx => $address) {
+ $address = trim($address);
+ if (!$address)
+ unset($this->form['actions'][$i]['addresses'][$aidx]);
+ else if(!check_email($address)) {
+ $this->errors['actions'][$i]['addresses'] = $this->gettext('noemailwarning');
+ break;
+ } else
+ $this->form['actions'][$i]['addresses'][$aidx] = $address;
+ }
+ }
+
+ if ($this->form['actions'][$i]['reason'] == '')
+ $this->errors['actions'][$i]['reason'] = $this->gettext('cannotbeempty');
+ if ($this->form['actions'][$i]['days'] && !preg_match('/^[0-9]+$/', $this->form['actions'][$i]['days']))
+ $this->errors['actions'][$i]['days'] = $this->gettext('forbiddenchars');
+ break;
+
+ case 'set':
+ $this->form['actions'][$i]['name'] = $varnames[$idx];
+ $this->form['actions'][$i]['value'] = $varvalues[$idx];
+ foreach ((array)$varmods[$idx] as $v_m) {
+ $this->form['actions'][$i][$v_m] = true;
+ }
+
+ if (empty($varnames[$idx])) {
+ $this->errors['actions'][$i]['name'] = $this->gettext('cannotbeempty');
+ }
+ else if (!preg_match('/^[0-9a-z_]+$/i', $varnames[$idx])) {
+ $this->errors['actions'][$i]['name'] = $this->gettext('forbiddenchars');
+ }
+
+ if (!isset($varvalues[$idx]) || $varvalues[$idx] === '') {
+ $this->errors['actions'][$i]['value'] = $this->gettext('cannotbeempty');
+ }
+ break;
+
+ case 'notify':
+ if (empty($notifyaddrs[$idx])) {
+ $this->errors['actions'][$i]['address'] = $this->gettext('cannotbeempty');
+ }
+ else if (!check_email($notifyaddrs[$idx])) {
+ $this->errors['actions'][$i]['address'] = $this->gettext('noemailwarning');
+ }
+ if (!empty($notifyfrom[$idx]) && !check_email($notifyfrom[$idx])) {
+ $this->errors['actions'][$i]['from'] = $this->gettext('noemailwarning');
+ }
+ $this->form['actions'][$i]['address'] = $notifyaddrs[$idx];
+ $this->form['actions'][$i]['body'] = $notifybodies[$idx];
+ $this->form['actions'][$i]['message'] = $notifymessages[$idx];
+ $this->form['actions'][$i]['from'] = $notifyfrom[$idx];
+ $this->form['actions'][$i]['importance'] = $notifyimp[$idx];
+ break;
+ }
+
+ $this->form['actions'][$i]['type'] = $type;
+ $i++;
+ }
+
+ if (!$this->errors && !$error) {
+ // zapis skryptu
+ if (!isset($this->script[$fid])) {
+ $fid = $this->sieve->script->add_rule($this->form);
+ $new = true;
+ } else
+ $fid = $this->sieve->script->update_rule($fid, $this->form);
+
+ if ($fid !== false)
+ $save = $this->save_script();
+
+ if ($save && $fid !== false) {
+ $this->rc->output->show_message('managesieve.filtersaved', 'confirmation');
+ if ($this->rc->task != 'mail') {
+ $this->rc->output->command('parent.managesieve_updatelist',
+ isset($new) ? 'add' : 'update',
+ array(
+ 'name' => $this->form['name'],
+ 'id' => $fid,
+ 'disabled' => $this->form['disabled']
+ ));
+ }
+ else {
+ $this->rc->output->command('managesieve_dialog_close');
+ $this->rc->output->send('iframe');
+ }
+ }
+ else {
+ $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+// $this->rc->output->send();
+ }
+ }
+ }
+
+ $this->managesieve_send();
+ }
+
+ private function managesieve_send()
+ {
+ // Handle form action
+ if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
+ if (isset($_GET['_newset']) || isset($_POST['_newset'])) {
+ $this->rc->output->send('managesieve.setedit');
+ }
+ else {
+ $this->rc->output->send('managesieve.filteredit');
+ }
+ } else {
+ $this->rc->output->set_pagetitle($this->gettext('filters'));
+ $this->rc->output->send('managesieve.managesieve');
+ }
+ }
+
+ // return the filters list as HTML table
+ function filters_list($attrib)
+ {
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmfilterslist';
+
+ // define list of cols to be displayed
+ $a_show_cols = array('name');
+
+ $result = $this->list_rules();
+
+ // create XHTML table
+ $out = rcube_table_output($attrib, $result, $a_show_cols, 'id');
+
+ // set client env
+ $this->rc->output->add_gui_object('filterslist', $attrib['id']);
+ $this->rc->output->include_script('list.js');
+
+ // add some labels to client
+ $this->rc->output->add_label('managesieve.filterdeleteconfirm');
+
+ return $out;
+ }
+
+ // return the filters list as <SELECT>
+ function filtersets_list($attrib, $no_env = false)
+ {
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmfiltersetslist';
+
+ $list = $this->list_scripts();
+
+ if ($list) {
+ asort($list, SORT_LOCALE_STRING);
+ }
+
+ if (!empty($attrib['type']) && $attrib['type'] == 'list') {
+ // define list of cols to be displayed
+ $a_show_cols = array('name');
+
+ if ($list) {
+ foreach ($list as $idx => $set) {
+ $scripts['S'.$idx] = $set;
+ $result[] = array(
+ 'name' => $set,
+ 'id' => 'S'.$idx,
+ 'class' => !in_array($set, $this->active) ? 'disabled' : '',
+ );
+ }
+ }
+
+ // create XHTML table
+ $out = rcube_table_output($attrib, $result, $a_show_cols, 'id');
+
+ $this->rc->output->set_env('filtersets', $scripts);
+ $this->rc->output->include_script('list.js');
+ }
+ else {
+ $select = new html_select(array('name' => '_set', 'id' => $attrib['id'],
+ 'onchange' => $this->rc->task != 'mail' ? 'rcmail.managesieve_set()' : ''));
+
+ if ($list) {
+ foreach ($list as $set)
+ $select->add($set, $set);
+ }
+
+ $out = $select->show($this->sieve->current);
+ }
+
+ // set client env
+ if (!$no_env) {
+ $this->rc->output->add_gui_object('filtersetslist', $attrib['id']);
+ $this->rc->output->add_label('managesieve.setdeleteconfirm');
+ }
+
+ return $out;
+ }
+
+ function filter_frame($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfilterframe';
+
+ $attrib['name'] = $attrib['id'];
+
+ $this->rc->output->set_env('contentframe', $attrib['name']);
+ $this->rc->output->set_env('blankpage', $attrib['src'] ?
+ $this->rc->output->abs_url($attrib['src']) : 'program/resources/blank.gif');
+
+ return $this->rc->output->frame($attrib);
+ }
+
+ function filterset_form($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfiltersetform';
+
+ $out = '<form name="filtersetform" action="./" method="post" enctype="multipart/form-data">'."\n";
+
+ $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
+ $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
+ $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
+ $hiddenfields->add(array('name' => '_newset', 'value' => 1));
+
+ $out .= $hiddenfields->show();
+
+ $name = get_input_value('_name', RCUBE_INPUT_POST);
+ $copy = get_input_value('_copy', RCUBE_INPUT_POST);
+ $selected = get_input_value('_from', RCUBE_INPUT_POST);
+
+ // filter set name input
+ $input_name = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30,
+ 'class' => ($this->errors['name'] ? 'error' : '')));
+
+ $out .= sprintf('<label for="%s"><b>%s:</b></label> %s<br /><br />',
+ '_name', Q($this->gettext('filtersetname')), $input_name->show($name));
+
+ $out .="\n<fieldset class=\"itemlist\"><legend>" . $this->gettext('filters') . ":</legend>\n";
+ $out .= '<input type="radio" id="from_none" name="_from" value="none"'
+ .(!$selected || $selected=='none' ? ' checked="checked"' : '').'></input>';
+ $out .= sprintf('<label for="%s">%s</label> ', 'from_none', Q($this->gettext('none')));
+
+ // filters set list
+ $list = $this->list_scripts();
+ $select = new html_select(array('name' => '_copy', 'id' => '_copy'));
+
+ if (is_array($list)) {
+ asort($list, SORT_LOCALE_STRING);
+
+ if (!$copy)
+ $copy = $_SESSION['managesieve_current'];
+
+ foreach ($list as $set) {
+ $select->add($set, $set);
+ }
+
+ $out .= '<br /><input type="radio" id="from_set" name="_from" value="set"'
+ .($selected=='set' ? ' checked="checked"' : '').'></input>';
+ $out .= sprintf('<label for="%s">%s:</label> ', 'from_set', Q($this->gettext('fromset')));
+ $out .= $select->show($copy);
+ }
+
+ // script upload box
+ $upload = new html_inputfield(array('name' => '_file', 'id' => '_file', 'size' => 30,
+ 'type' => 'file', 'class' => ($this->errors['file'] ? 'error' : '')));
+
+ $out .= '<br /><input type="radio" id="from_file" name="_from" value="file"'
+ .($selected=='file' ? ' checked="checked"' : '').'></input>';
+ $out .= sprintf('<label for="%s">%s:</label> ', 'from_file', Q($this->gettext('fromfile')));
+ $out .= $upload->show();
+ $out .= '</fieldset>';
+
+ $this->rc->output->add_gui_object('sieveform', 'filtersetform');
+
+ if ($this->errors['name'])
+ $this->add_tip('_name', $this->errors['name'], true);
+ if ($this->errors['file'])
+ $this->add_tip('_file', $this->errors['file'], true);
+
+ $this->print_tips();
+
+ return $out;
+ }
+
+
+ function filter_form($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfilterform';
+
+ $fid = get_input_value('_fid', RCUBE_INPUT_GPC);
+ $scr = isset($this->form) ? $this->form : $this->script[$fid];
+
+ $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
+ $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
+ $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
+ $hiddenfields->add(array('name' => '_fid', 'value' => $fid));
+
+ $out = '<form name="filterform" action="./" method="post">'."\n";
+ $out .= $hiddenfields->show();
+
+ // 'any' flag
+ if (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not'])
+ $any = true;
+
+ // filter name input
+ $field_id = '_name';
+ $input_name = new html_inputfield(array('name' => '_name', 'id' => $field_id, 'size' => 30,
+ 'class' => ($this->errors['name'] ? 'error' : '')));
+
+ if ($this->errors['name'])
+ $this->add_tip($field_id, $this->errors['name'], true);
+
+ if (isset($scr))
+ $input_name = $input_name->show($scr['name']);
+ else
+ $input_name = $input_name->show();
+
+ $out .= sprintf("\n<label for=\"%s\"><b>%s:</b></label> %s\n",
+ $field_id, Q($this->gettext('filtername')), $input_name);
+
+ // filter set selector
+ if ($this->rc->task == 'mail') {
+ $out .= sprintf("\n&nbsp;<label for=\"%s\"><b>%s:</b></label> %s\n",
+ $field_id, Q($this->gettext('filterset')),
+ $this->filtersets_list(array('id' => 'sievescriptname'), true));
+ }
+
+ $out .= '<br /><br /><fieldset><legend>' . Q($this->gettext('messagesrules')) . "</legend>\n";
+
+ // any, allof, anyof radio buttons
+ $field_id = '_allof';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'allof',
+ 'onclick' => 'rule_join_radio(\'allof\')', 'class' => 'radio'));
+
+ if (isset($scr) && !$any)
+ $input_join = $input_join->show($scr['join'] ? 'allof' : '');
+ else
+ $input_join = $input_join->show();
+
+ $out .= sprintf("%s<label for=\"%s\">%s</label>&nbsp;\n",
+ $input_join, $field_id, Q($this->gettext('filterallof')));
+
+ $field_id = '_anyof';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'anyof',
+ 'onclick' => 'rule_join_radio(\'anyof\')', 'class' => 'radio'));
+
+ if (isset($scr) && !$any)
+ $input_join = $input_join->show($scr['join'] ? '' : 'anyof');
+ else
+ $input_join = $input_join->show('anyof'); // default
+
+ $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
+ $input_join, $field_id, Q($this->gettext('filteranyof')));
+
+ $field_id = '_any';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'any',
+ 'onclick' => 'rule_join_radio(\'any\')', 'class' => 'radio'));
+
+ $input_join = $input_join->show($any ? 'any' : '');
+
+ $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
+ $input_join, $field_id, Q($this->gettext('filterany')));
+
+ $rows_num = isset($scr) ? sizeof($scr['tests']) : 1;
+
+ $out .= '<div id="rules"'.($any ? ' style="display: none"' : '').'>';
+ for ($x=0; $x<$rows_num; $x++)
+ $out .= $this->rule_div($fid, $x);
+ $out .= "</div>\n";
+
+ $out .= "</fieldset>\n";
+
+ // actions
+ $out .= '<fieldset><legend>' . Q($this->gettext('messagesactions')) . "</legend>\n";
+
+ $rows_num = isset($scr) ? sizeof($scr['actions']) : 1;
+
+ $out .= '<div id="actions">';
+ for ($x=0; $x<$rows_num; $x++)
+ $out .= $this->action_div($fid, $x);
+ $out .= "</div>\n";
+
+ $out .= "</fieldset>\n";
+
+ $this->print_tips();
+
+ if ($scr['disabled']) {
+ $this->rc->output->set_env('rule_disabled', true);
+ }
+ $this->rc->output->add_label(
+ 'managesieve.ruledeleteconfirm',
+ 'managesieve.actiondeleteconfirm'
+ );
+ $this->rc->output->add_gui_object('sieveform', 'filterform');
+
+ return $out;
+ }
+
+ function rule_div($fid, $id, $div=true)
+ {
+ $rule = isset($this->form) ? $this->form['tests'][$id] : $this->script[$fid]['tests'][$id];
+ $rows_num = isset($this->form) ? sizeof($this->form['tests']) : sizeof($this->script[$fid]['tests']);
+
+ // headers select
+ $select_header = new html_select(array('name' => "_header[]", 'id' => 'header'.$id,
+ 'onchange' => 'rule_header_select(' .$id .')'));
+ foreach($this->headers as $name => $val)
+ $select_header->add(Q($this->gettext($name)), Q($val));
+ if (in_array('body', $this->exts))
+ $select_header->add(Q($this->gettext('body')), 'body');
+ $select_header->add(Q($this->gettext('size')), 'size');
+ $select_header->add(Q($this->gettext('...')), '...');
+
+ // TODO: list arguments
+ $aout = '';
+
+ if ((isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope')))
+ && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers)
+ ) {
+ $aout .= $select_header->show($rule['arg1']);
+ }
+ else if ((isset($rule['test']) && $rule['test'] == 'exists')
+ && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers)
+ ) {
+ $aout .= $select_header->show($rule['arg']);
+ }
+ else if (isset($rule['test']) && $rule['test'] == 'size')
+ $aout .= $select_header->show('size');
+ else if (isset($rule['test']) && $rule['test'] == 'body')
+ $aout .= $select_header->show('body');
+ else if (isset($rule['test']) && $rule['test'] != 'true')
+ $aout .= $select_header->show('...');
+ else
+ $aout .= $select_header->show();
+
+ if (isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) {
+ if (is_array($rule['arg1']))
+ $custom = implode(', ', $rule['arg1']);
+ else if (!in_array($rule['arg1'], $this->headers))
+ $custom = $rule['arg1'];
+ }
+ else if (isset($rule['test']) && $rule['test'] == 'exists') {
+ if (is_array($rule['arg']))
+ $custom = implode(', ', $rule['arg']);
+ else if (!in_array($rule['arg'], $this->headers))
+ $custom = $rule['arg'];
+ }
+
+ $tout = '<div id="custom_header' .$id. '" style="display:' .(isset($custom) ? 'inline' : 'none'). '">
+ <input type="text" name="_custom_header[]" id="custom_header_i'.$id.'" '
+ . $this->error_class($id, 'test', 'header', 'custom_header_i')
+ .' value="' .Q($custom). '" size="15" />&nbsp;</div>' . "\n";
+
+ // matching type select (operator)
+ $select_op = new html_select(array('name' => "_rule_op[]", 'id' => 'rule_op'.$id,
+ 'style' => 'display:' .($rule['test']!='size' ? 'inline' : 'none'),
+ 'class' => 'operator_selector',
+ 'onchange' => 'rule_op_select('.$id.')'));
+ $select_op->add(Q($this->gettext('filtercontains')), 'contains');
+ $select_op->add(Q($this->gettext('filternotcontains')), 'notcontains');
+ $select_op->add(Q($this->gettext('filteris')), 'is');
+ $select_op->add(Q($this->gettext('filterisnot')), 'notis');
+ $select_op->add(Q($this->gettext('filterexists')), 'exists');
+ $select_op->add(Q($this->gettext('filternotexists')), 'notexists');
+ $select_op->add(Q($this->gettext('filtermatches')), 'matches');
+ $select_op->add(Q($this->gettext('filternotmatches')), 'notmatches');
+ if (in_array('regex', $this->exts)) {
+ $select_op->add(Q($this->gettext('filterregex')), 'regex');
+ $select_op->add(Q($this->gettext('filternotregex')), 'notregex');
+ }
+ if (in_array('relational', $this->exts)) {
+ $select_op->add(Q($this->gettext('countisgreaterthan')), 'count-gt');
+ $select_op->add(Q($this->gettext('countisgreaterthanequal')), 'count-ge');
+ $select_op->add(Q($this->gettext('countislessthan')), 'count-lt');
+ $select_op->add(Q($this->gettext('countislessthanequal')), 'count-le');
+ $select_op->add(Q($this->gettext('countequals')), 'count-eq');
+ $select_op->add(Q($this->gettext('countnotequals')), 'count-ne');
+ $select_op->add(Q($this->gettext('valueisgreaterthan')), 'value-gt');
+ $select_op->add(Q($this->gettext('valueisgreaterthanequal')), 'value-ge');
+ $select_op->add(Q($this->gettext('valueislessthan')), 'value-lt');
+ $select_op->add(Q($this->gettext('valueislessthanequal')), 'value-le');
+ $select_op->add(Q($this->gettext('valueequals')), 'value-eq');
+ $select_op->add(Q($this->gettext('valuenotequals')), 'value-ne');
+ }
+
+ // target input (TODO: lists)
+
+ if (in_array($rule['test'], array('header', 'address', 'envelope'))) {
+ $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
+ $target = $rule['arg2'];
+ }
+ else if ($rule['test'] == 'body') {
+ $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
+ $target = $rule['arg'];
+ }
+ else if ($rule['test'] == 'size') {
+ $test = '';
+ $target = '';
+ if (preg_match('/^([0-9]+)(K|M|G)?$/', $rule['arg'], $matches)) {
+ $sizetarget = $matches[1];
+ $sizeitem = $matches[2];
+ }
+ else {
+ $sizetarget = $rule['arg'];
+ $sizeitem = $rule['item'];
+ }
+ }
+ else {
+ $test = ($rule['not'] ? 'not' : '').$rule['test'];
+ $target = '';
+ }
+
+ $tout .= $select_op->show($test);
+ $tout .= '<input type="text" name="_rule_target[]" id="rule_target' .$id. '"
+ value="' .Q($target). '" size="20" ' . $this->error_class($id, 'test', 'target', 'rule_target')
+ . ' style="display:' . ($rule['test']!='size' && $rule['test'] != 'exists' ? 'inline' : 'none') . '" />'."\n";
+
+ $select_size_op = new html_select(array('name' => "_rule_size_op[]", 'id' => 'rule_size_op'.$id));
+ $select_size_op->add(Q($this->gettext('filterover')), 'over');
+ $select_size_op->add(Q($this->gettext('filterunder')), 'under');
+
+ $tout .= '<div id="rule_size' .$id. '" style="display:' . ($rule['test']=='size' ? 'inline' : 'none') .'">';
+ $tout .= $select_size_op->show($rule['test']=='size' ? $rule['type'] : '');
+ $tout .= '<input type="text" name="_rule_size_target[]" id="rule_size_i'.$id.'" value="'.$sizetarget.'" size="10" '
+ . $this->error_class($id, 'test', 'sizetarget', 'rule_size_i') .' />
+ <input type="radio" name="_rule_size_item['.$id.']" value=""'
+ . (!$sizeitem ? ' checked="checked"' : '') .' class="radio" />'.rcube_label('B').'
+ <input type="radio" name="_rule_size_item['.$id.']" value="K"'
+ . ($sizeitem=='K' ? ' checked="checked"' : '') .' class="radio" />'.rcube_label('KB').'
+ <input type="radio" name="_rule_size_item['.$id.']" value="M"'
+ . ($sizeitem=='M' ? ' checked="checked"' : '') .' class="radio" />'.rcube_label('MB').'
+ <input type="radio" name="_rule_size_item['.$id.']" value="G"'
+ . ($sizeitem=='G' ? ' checked="checked"' : '') .' class="radio" />'.rcube_label('GB');
+ $tout .= '</div>';
+
+ // Advanced modifiers (address, envelope)
+ $select_mod = new html_select(array('name' => "_rule_mod[]", 'id' => 'rule_mod_op'.$id,
+ 'onchange' => 'rule_mod_select(' .$id .')'));
+ $select_mod->add(Q($this->gettext('none')), '');
+ $select_mod->add(Q($this->gettext('address')), 'address');
+ if (in_array('envelope', $this->exts))
+ $select_mod->add(Q($this->gettext('envelope')), 'envelope');
+
+ $select_type = new html_select(array('name' => "_rule_mod_type[]", 'id' => 'rule_mod_type'.$id));
+ $select_type->add(Q($this->gettext('allparts')), 'all');
+ $select_type->add(Q($this->gettext('domain')), 'domain');
+ $select_type->add(Q($this->gettext('localpart')), 'localpart');
+ if (in_array('subaddress', $this->exts)) {
+ $select_type->add(Q($this->gettext('user')), 'user');
+ $select_type->add(Q($this->gettext('detail')), 'detail');
+ }
+
+ $need_mod = $rule['test'] != 'size' && $rule['test'] != 'body';
+ $mout = '<div id="rule_mod' .$id. '" class="adv" style="display:' . ($need_mod ? 'block' : 'none') .'">';
+ $mout .= ' <span>';
+ $mout .= Q($this->gettext('modifier')) . ' ';
+ $mout .= $select_mod->show($rule['test']);
+ $mout .= '</span>';
+ $mout .= ' <span id="rule_mod_type' . $id . '"';
+ $mout .= ' style="display:' . (in_array($rule['test'], array('address', 'envelope')) ? 'inline' : 'none') .'">';
+ $mout .= Q($this->gettext('modtype')) . ' ';
+ $mout .= $select_type->show($rule['part']);
+ $mout .= '</span>';
+ $mout .= '</div>';
+
+ // Advanced modifiers (body transformations)
+ $select_mod = new html_select(array('name' => "_rule_trans[]", 'id' => 'rule_trans_op'.$id,
+ 'onchange' => 'rule_trans_select(' .$id .')'));
+ $select_mod->add(Q($this->gettext('text')), 'text');
+ $select_mod->add(Q($this->gettext('undecoded')), 'raw');
+ $select_mod->add(Q($this->gettext('contenttype')), 'content');
+
+ $mout .= '<div id="rule_trans' .$id. '" class="adv" style="display:' . ($rule['test'] == 'body' ? 'block' : 'none') .'">';
+ $mout .= ' <span>';
+ $mout .= Q($this->gettext('modifier')) . ' ';
+ $mout .= $select_mod->show($rule['part']);
+ $mout .= '<input type="text" name="_rule_trans_type[]" id="rule_trans_type'.$id
+ . '" value="'.(is_array($rule['content']) ? implode(',', $rule['content']) : $rule['content'])
+ .'" size="20" style="display:' . ($rule['part'] == 'content' ? 'inline' : 'none') .'"'
+ . $this->error_class($id, 'test', 'part', 'rule_trans_type') .' />';
+ $mout .= '</span>';
+ $mout .= '</div>';
+
+ // Advanced modifiers (body transformations)
+ $select_comp = new html_select(array('name' => "_rule_comp[]", 'id' => 'rule_comp_op'.$id));
+ $select_comp->add(Q($this->gettext('default')), '');
+ $select_comp->add(Q($this->gettext('octet')), 'i;octet');
+ $select_comp->add(Q($this->gettext('asciicasemap')), 'i;ascii-casemap');
+ if (in_array('comparator-i;ascii-numeric', $this->exts)) {
+ $select_comp->add(Q($this->gettext('asciinumeric')), 'i;ascii-numeric');
+ }
+
+ $mout .= '<div id="rule_comp' .$id. '" class="adv" style="display:' . ($rule['test'] != 'size' ? 'block' : 'none') .'">';
+ $mout .= ' <span>';
+ $mout .= Q($this->gettext('comparator')) . ' ';
+ $mout .= $select_comp->show($rule['comparator']);
+ $mout .= '</span>';
+ $mout .= '</div>';
+
+ // Build output table
+ $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : '';
+ $out .= '<table><tr>';
+ $out .= '<td class="advbutton">';
+ $out .= '<a href="#" id="ruleadv' . $id .'" title="'. Q($this->gettext('advancedopts')). '"
+ onclick="rule_adv_switch(' . $id .', this)" class="show">&nbsp;&nbsp;</a>';
+ $out .= '</td>';
+ $out .= '<td class="rowactions">' . $aout . '</td>';
+ $out .= '<td class="rowtargets">' . $tout . "\n";
+ $out .= '<div id="rule_advanced' .$id. '" style="display:none">' . $mout . '</div>';
+ $out .= '</td>';
+
+ // add/del buttons
+ $out .= '<td class="rowbuttons">';
+ $out .= '<a href="#" id="ruleadd' . $id .'" title="'. Q($this->gettext('add')). '"
+ onclick="rcmail.managesieve_ruleadd(' . $id .')" class="button add"></a>';
+ $out .= '<a href="#" id="ruledel' . $id .'" title="'. Q($this->gettext('del')). '"
+ onclick="rcmail.managesieve_ruledel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>';
+ $out .= '</td>';
+ $out .= '</tr></table>';
+
+ $out .= $div ? "</div>\n" : '';
+
+ return $out;
+ }
+
+ function action_div($fid, $id, $div=true)
+ {
+ $action = isset($this->form) ? $this->form['actions'][$id] : $this->script[$fid]['actions'][$id];
+ $rows_num = isset($this->form) ? sizeof($this->form['actions']) : sizeof($this->script[$fid]['actions']);
+
+ $out = $div ? '<div class="actionrow" id="actionrow' .$id .'">'."\n" : '';
+
+ $out .= '<table><tr><td class="rowactions">';
+
+ // action select
+ $select_action = new html_select(array('name' => "_action_type[$id]", 'id' => 'action_type'.$id,
+ 'onchange' => 'action_type_select(' .$id .')'));
+ if (in_array('fileinto', $this->exts))
+ $select_action->add(Q($this->gettext('messagemoveto')), 'fileinto');
+ if (in_array('fileinto', $this->exts) && in_array('copy', $this->exts))
+ $select_action->add(Q($this->gettext('messagecopyto')), 'fileinto_copy');
+ $select_action->add(Q($this->gettext('messageredirect')), 'redirect');
+ if (in_array('copy', $this->exts))
+ $select_action->add(Q($this->gettext('messagesendcopy')), 'redirect_copy');
+ if (in_array('reject', $this->exts))
+ $select_action->add(Q($this->gettext('messagediscard')), 'reject');
+ else if (in_array('ereject', $this->exts))
+ $select_action->add(Q($this->gettext('messagediscard')), 'ereject');
+ if (in_array('vacation', $this->exts))
+ $select_action->add(Q($this->gettext('messagereply')), 'vacation');
+ $select_action->add(Q($this->gettext('messagedelete')), 'discard');
+ if (in_array('imapflags', $this->exts) || in_array('imap4flags', $this->exts)) {
+ $select_action->add(Q($this->gettext('setflags')), 'setflag');
+ $select_action->add(Q($this->gettext('addflags')), 'addflag');
+ $select_action->add(Q($this->gettext('removeflags')), 'removeflag');
+ }
+ if (in_array('variables', $this->exts)) {
+ $select_action->add(Q($this->gettext('setvariable')), 'set');
+ }
+ if (in_array('enotify', $this->exts) || in_array('notify', $this->exts)) {
+ $select_action->add(Q($this->gettext('notify')), 'notify');
+ }
+ $select_action->add(Q($this->gettext('rulestop')), 'stop');
+
+ $select_type = $action['type'];
+ if (in_array($action['type'], array('fileinto', 'redirect')) && $action['copy']) {
+ $select_type .= '_copy';
+ }
+
+ $out .= $select_action->show($select_type);
+ $out .= '</td>';
+
+ // actions target inputs
+ $out .= '<td class="rowtargets">';
+ // shared targets
+ $out .= '<input type="text" name="_action_target['.$id.']" id="action_target' .$id. '" '
+ .'value="' .($action['type']=='redirect' ? Q($action['target'], 'strict', false) : ''). '" size="35" '
+ .'style="display:' .($action['type']=='redirect' ? 'inline' : 'none') .'" '
+ . $this->error_class($id, 'action', 'target', 'action_target') .' />';
+ $out .= '<textarea name="_action_target_area['.$id.']" id="action_target_area' .$id. '" '
+ .'rows="3" cols="35" '. $this->error_class($id, 'action', 'targetarea', 'action_target_area')
+ .'style="display:' .(in_array($action['type'], array('reject', 'ereject')) ? 'inline' : 'none') .'">'
+ . (in_array($action['type'], array('reject', 'ereject')) ? Q($action['target'], 'strict', false) : '')
+ . "</textarea>\n";
+
+ // vacation
+ $out .= '<div id="action_vacation' .$id.'" style="display:' .($action['type']=='vacation' ? 'inline' : 'none') .'">';
+ $out .= '<span class="label">'. Q($this->gettext('vacationreason')) .'</span><br />'
+ .'<textarea name="_action_reason['.$id.']" id="action_reason' .$id. '" '
+ .'rows="3" cols="35" '. $this->error_class($id, 'action', 'reason', 'action_reason') . '>'
+ . Q($action['reason'], 'strict', false) . "</textarea>\n";
+ $out .= '<br /><span class="label">' .Q($this->gettext('vacationsubject')) . '</span><br />'
+ .'<input type="text" name="_action_subject['.$id.']" id="action_subject'.$id.'" '
+ .'value="' . (is_array($action['subject']) ? Q(implode(', ', $action['subject']), 'strict', false) : $action['subject']) . '" size="35" '
+ . $this->error_class($id, 'action', 'subject', 'action_subject') .' />';
+ $out .= '<br /><span class="label">' .Q($this->gettext('vacationaddresses')) . '</span><br />'
+ .'<input type="text" name="_action_addresses['.$id.']" id="action_addr'.$id.'" '
+ .'value="' . (is_array($action['addresses']) ? Q(implode(', ', $action['addresses']), 'strict', false) : $action['addresses']) . '" size="35" '
+ . $this->error_class($id, 'action', 'addresses', 'action_addr') .' />';
+ $out .= '<br /><span class="label">' . Q($this->gettext('vacationdays')) . '</span><br />'
+ .'<input type="text" name="_action_days['.$id.']" id="action_days'.$id.'" '
+ .'value="' .Q($action['days'], 'strict', false) . '" size="2" '
+ . $this->error_class($id, 'action', 'days', 'action_days') .' />';
+ $out .= '</div>';
+
+ // flags
+ $flags = array(
+ 'read' => '\\Seen',
+ 'answered' => '\\Answered',
+ 'flagged' => '\\Flagged',
+ 'deleted' => '\\Deleted',
+ 'draft' => '\\Draft',
+ );
+ $flags_target = (array)$action['target'];
+
+ $out .= '<div id="action_flags' .$id.'" style="display:'
+ . (preg_match('/^(set|add|remove)flag$/', $action['type']) ? 'inline' : 'none') . '"'
+ . $this->error_class($id, 'action', 'flags', 'action_flags') . '>';
+ foreach ($flags as $fidx => $flag) {
+ $out .= '<input type="checkbox" name="_action_flags[' .$id .'][]" value="' . $flag . '"'
+ . (in_array_nocase($flag, $flags_target) ? 'checked="checked"' : '') . ' />'
+ . Q($this->gettext('flag'.$fidx)) .'<br>';
+ }
+ $out .= '</div>';
+
+ // set variable
+ $set_modifiers = array(
+ 'lower',
+ 'upper',
+ 'lowerfirst',
+ 'upperfirst',
+ 'quotewildcard',
+ 'length'
+ );
+
+ $out .= '<div id="action_set' .$id.'" style="display:' .($action['type']=='set' ? 'inline' : 'none') .'">';
+ $out .= '<span class="label">' .Q($this->gettext('setvarname')) . '</span><br />'
+ .'<input type="text" name="_action_varname['.$id.']" id="action_varname'.$id.'" '
+ .'value="' . Q($action['name']) . '" size="35" '
+ . $this->error_class($id, 'action', 'name', 'action_varname') .' />';
+ $out .= '<br /><span class="label">' .Q($this->gettext('setvarvalue')) . '</span><br />'
+ .'<input type="text" name="_action_varvalue['.$id.']" id="action_varvalue'.$id.'" '
+ .'value="' . Q($action['value']) . '" size="35" '
+ . $this->error_class($id, 'action', 'value', 'action_varvalue') .' />';
+ $out .= '<br /><span class="label">' .Q($this->gettext('setvarmodifiers')) . '</span><br />';
+ foreach ($set_modifiers as $j => $s_m) {
+ $s_m_id = 'action_varmods' . $id . $s_m;
+ $out .= sprintf('<input type="checkbox" name="_action_varmods[%s][]" value="%s" id="%s"%s />%s<br>',
+ $id, $s_m, $s_m_id,
+ (array_key_exists($s_m, (array)$action) && $action[$s_m] ? ' checked="checked"' : ''),
+ Q($this->gettext('var' . $s_m)));
+ }
+ $out .= '</div>';
+
+ // notify
+ // skip :options tag - not used by the mailto method
+ $out .= '<div id="action_notify' .$id.'" style="display:' .($action['type']=='notify' ? 'inline' : 'none') .'">';
+ $out .= '<span class="label">' .Q($this->gettext('notifyaddress')) . '</span><br />'
+ .'<input type="text" name="_action_notifyaddress['.$id.']" id="action_notifyaddress'.$id.'" '
+ .'value="' . Q($action['address']) . '" size="35" '
+ . $this->error_class($id, 'action', 'address', 'action_notifyaddress') .' />';
+ $out .= '<br /><span class="label">'. Q($this->gettext('notifybody')) .'</span><br />'
+ .'<textarea name="_action_notifybody['.$id.']" id="action_notifybody' .$id. '" '
+ .'rows="3" cols="35" '. $this->error_class($id, 'action', 'method', 'action_notifybody') . '>'
+ . Q($action['body'], 'strict', false) . "</textarea>\n";
+ $out .= '<br /><span class="label">' .Q($this->gettext('notifysubject')) . '</span><br />'
+ .'<input type="text" name="_action_notifymessage['.$id.']" id="action_notifymessage'.$id.'" '
+ .'value="' . Q($action['message']) . '" size="35" '
+ . $this->error_class($id, 'action', 'message', 'action_notifymessage') .' />';
+ $out .= '<br /><span class="label">' .Q($this->gettext('notifyfrom')) . '</span><br />'
+ .'<input type="text" name="_action_notifyfrom['.$id.']" id="action_notifyfrom'.$id.'" '
+ .'value="' . Q($action['from']) . '" size="35" '
+ . $this->error_class($id, 'action', 'from', 'action_notifyfrom') .' />';
+ $importance_options = array(
+ 3 => 'notifyimportancelow',
+ 2 => 'notifyimportancenormal',
+ 1 => 'notifyimportancehigh'
+ );
+ $select_importance = new html_select(array(
+ 'name' => '_action_notifyimportance[' . $id . ']',
+ 'id' => '_action_notifyimportance' . $id,
+ 'class' => $this->error_class($id, 'action', 'importance', 'action_notifyimportance')));
+ foreach ($importance_options as $io_v => $io_n) {
+ $select_importance->add(Q($this->gettext($io_n)), $io_v);
+ }
+ $out .= '<br /><span class="label">' . Q($this->gettext('notifyimportance')) . '</span><br />';
+ $out .= $select_importance->show($action['importance'] ? $action['importance'] : 2);
+ $out .= '</div>';
+
+ // mailbox select
+ if ($action['type'] == 'fileinto')
+ $mailbox = $this->mod_mailbox($action['target'], 'out');
+ else
+ $mailbox = '';
+
+ $select = rcmail_mailbox_select(array(
+ 'realnames' => false,
+ 'maxlength' => 100,
+ 'id' => 'action_mailbox' . $id,
+ 'name' => "_action_mailbox[$id]",
+ 'style' => 'display:'.(!isset($action) || $action['type']=='fileinto' ? 'inline' : 'none')
+ ));
+ $out .= $select->show($mailbox);
+ $out .= '</td>';
+
+ // add/del buttons
+ $out .= '<td class="rowbuttons">';
+ $out .= '<a href="#" id="actionadd' . $id .'" title="'. Q($this->gettext('add')). '"
+ onclick="rcmail.managesieve_actionadd(' . $id .')" class="button add"></a>';
+ $out .= '<a href="#" id="actiondel' . $id .'" title="'. Q($this->gettext('del')). '"
+ onclick="rcmail.managesieve_actiondel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>';
+ $out .= '</td>';
+
+ $out .= '</tr></table>';
+
+ $out .= $div ? "</div>\n" : '';
+
+ return $out;
+ }
+
+ private function genid()
+ {
+ return preg_replace('/[^0-9]/', '', microtime(true));
+ }
+
+ private function strip_value($str, $allow_html = false, $trim = true)
+ {
+ if (!$allow_html) {
+ $str = strip_tags($str);
+ }
+
+ return $trim ? trim($str) : $str;
+ }
+
+ private function error_class($id, $type, $target, $elem_prefix='')
+ {
+ // TODO: tooltips
+ if (($type == 'test' && ($str = $this->errors['tests'][$id][$target])) ||
+ ($type == 'action' && ($str = $this->errors['actions'][$id][$target]))
+ ) {
+ $this->add_tip($elem_prefix.$id, $str, true);
+ return ' class="error"';
+ }
+
+ return '';
+ }
+
+ private function add_tip($id, $str, $error=false)
+ {
+ if ($error)
+ $str = html::span('sieve error', $str);
+
+ $this->tips[] = array($id, $str);
+ }
+
+ private function print_tips()
+ {
+ if (empty($this->tips))
+ return;
+
+ $script = JS_OBJECT_NAME.'.managesieve_tip_register('.json_encode($this->tips).');';
+ $this->rc->output->add_script($script, 'foot');
}
/**
- * Initializes engine object
+ * Converts mailbox name from/to UTF7-IMAP from/to internal Sieve encoding
+ * with delimiter replacement.
+ *
+ * @param string $mailbox Mailbox name
+ * @param string $mode Conversion direction ('in'|'out')
+ *
+ * @return string Mailbox name
*/
- private function get_engine()
+ private function mod_mailbox($mailbox, $mode = 'out')
{
- if (!$this->engine) {
- $this->load_config();
+ $delimiter = $_SESSION['imap_delimiter'];
+ $replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter');
+ $mbox_encoding = $this->rc->config->get('managesieve_mbox_encoding', 'UTF7-IMAP');
+
+ if ($mode == 'out') {
+ $mailbox = rcube_charset_convert($mailbox, $mbox_encoding, 'UTF7-IMAP');
+ if ($replace_delimiter && $replace_delimiter != $delimiter)
+ $mailbox = str_replace($replace_delimiter, $delimiter, $mailbox);
+ }
+ else {
+ $mailbox = rcube_charset_convert($mailbox, 'UTF7-IMAP', $mbox_encoding);
+ if ($replace_delimiter && $replace_delimiter != $delimiter)
+ $mailbox = str_replace($delimiter, $replace_delimiter, $mailbox);
+ }
+
+ return $mailbox;
+ }
+
+ /**
+ * List sieve scripts
+ *
+ * @return array Scripts list
+ */
+ public function list_scripts()
+ {
+ if ($this->list !== null) {
+ return $this->list;
+ }
+
+ $this->list = $this->sieve->get_scripts();
+
+ // Handle active script(s) and list of scripts according to Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
- // Add include path for internal classes
- $include_path = $this->home . '/lib' . PATH_SEPARATOR;
- $include_path .= ini_get('include_path');
- set_include_path($include_path);
+ // Skip protected names
+ foreach ((array)$this->list as $idx => $name) {
+ $_name = strtoupper($name);
+ if ($_name == 'MASTER')
+ $master_script = $name;
+ else if ($_name == 'MANAGEMENT')
+ $management_script = $name;
+ else if($_name == 'USER')
+ $user_script = $name;
+ else
+ continue;
- $this->engine = new rcube_sieve_engine($this);
+ unset($this->list[$idx]);
+ }
+
+ // get active script(s), read USER script
+ if ($user_script) {
+ $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
+ $filename_regex = '/'.preg_quote($extension, '/').'$/';
+ $_SESSION['managesieve_user_script'] = $user_script;
+
+ $this->sieve->load($user_script);
+
+ foreach ($this->sieve->script->as_array() as $rules) {
+ foreach ($rules['actions'] as $action) {
+ if ($action['type'] == 'include' && empty($action['global'])) {
+ $name = preg_replace($filename_regex, '', $action['target']);
+ $this->active[] = $name;
+ }
+ }
+ }
+ }
+ // create USER script if it doesn't exist
+ else {
+ $content = "# USER Management Script\n"
+ ."#\n"
+ ."# This script includes the various active sieve scripts\n"
+ ."# it is AUTOMATICALLY GENERATED. DO NOT EDIT MANUALLY!\n"
+ ."#\n"
+ ."# For more information, see http://wiki.kolab.org/KEP:14#USER\n"
+ ."#\n";
+ if ($this->sieve->save_script('USER', $content)) {
+ $_SESSION['managesieve_user_script'] = 'USER';
+ if (empty($this->master_file))
+ $this->sieve->activate('USER');
+ }
+ }
+ }
+ else if (!empty($this->list)) {
+ // Get active script name
+ if ($active = $this->sieve->get_active()) {
+ $this->active = array($active);
+ }
+
+ // Hide scripts from config
+ $exceptions = $this->rc->config->get('managesieve_filename_exceptions');
+ if (!empty($exceptions)) {
+ $this->list = array_diff($this->list, (array)$exceptions);
+ }
+ }
+
+ return $this->list;
+ }
+
+ /**
+ * Removes sieve script
+ *
+ * @param string $name Script name
+ *
+ * @return bool True on success, False on failure
+ */
+ public function remove_script($name)
+ {
+ $result = $this->sieve->remove($name);
+
+ // Kolab's KEP:14
+ if ($result && $this->rc->config->get('managesieve_kolab_master')) {
+ $this->deactivate_script($name);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Activates sieve script
+ *
+ * @param string $name Script name
+ *
+ * @return bool True on success, False on failure
+ */
+ public function activate_script($name)
+ {
+ // Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+ $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
+ $user_script = $_SESSION['managesieve_user_script'];
+
+ // if the script is not active...
+ if ($user_script && ($key = array_search($name, $this->active)) === false) {
+ // ...rewrite USER file adding appropriate include command
+ if ($this->sieve->load($user_script)) {
+ $script = $this->sieve->script->as_array();
+ $list = array();
+ $regexp = '/' . preg_quote($extension, '/') . '$/';
+
+ // Create new include entry
+ $rule = array(
+ 'actions' => array(
+ 0 => array(
+ 'target' => $name.$extension,
+ 'type' => 'include',
+ 'personal' => true,
+ )));
+
+ // get all active scripts for sorting
+ foreach ($script as $rid => $rules) {
+ foreach ($rules['actions'] as $aid => $action) {
+ if ($action['type'] == 'include' && empty($action['global'])) {
+ $target = $extension ? preg_replace($regexp, '', $action['target']) : $action['target'];
+ $list[] = $target;
+ }
+ }
+ }
+ $list[] = $name;
+
+ // Sort and find current script position
+ asort($list, SORT_LOCALE_STRING);
+ $list = array_values($list);
+ $index = array_search($name, $list);
+
+ // add rule at the end of the script
+ if ($index === false || $index == count($list)-1) {
+ $this->sieve->script->add_rule($rule);
+ }
+ // add rule at index position
+ else {
+ $script2 = array();
+ foreach ($script as $rid => $rules) {
+ if ($rid == $index) {
+ $script2[] = $rule;
+ }
+ $script2[] = $rules;
+ }
+ $this->sieve->script->content = $script2;
+ }
+
+ $result = $this->sieve->save();
+ if ($result) {
+ $this->active[] = $name;
+ }
+ }
+ }
+ }
+ else {
+ $result = $this->sieve->activate($name);
+ if ($result)
+ $this->active = array($name);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Deactivates sieve script
+ *
+ * @param string $name Script name
+ *
+ * @return bool True on success, False on failure
+ */
+ public function deactivate_script($name)
+ {
+ // Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+ $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
+ $user_script = $_SESSION['managesieve_user_script'];
+
+ // if the script is active...
+ if ($user_script && ($key = array_search($name, $this->active)) !== false) {
+ // ...rewrite USER file removing appropriate include command
+ if ($this->sieve->load($user_script)) {
+ $script = $this->sieve->script->as_array();
+ $name = $name.$extension;
+
+ foreach ($script as $rid => $rules) {
+ foreach ($rules['actions'] as $aid => $action) {
+ if ($action['type'] == 'include' && empty($action['global'])
+ && $action['target'] == $name
+ ) {
+ break 2;
+ }
+ }
+ }
+
+ // Entry found
+ if ($rid < count($script)) {
+ $this->sieve->script->delete_rule($rid);
+ $result = $this->sieve->save();
+ if ($result) {
+ unset($this->active[$key]);
+ }
+ }
+ }
+ }
+ }
+ else {
+ $result = $this->sieve->deactivate();
+ if ($result)
+ $this->active = array();
+ }
+
+ return $result;
+ }
+
+ /**
+ * Saves current script (adding some variables)
+ */
+ public function save_script($name = null)
+ {
+ // Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+ $this->sieve->script->set_var('EDITOR', self::PROGNAME);
+ $this->sieve->script->set_var('EDITOR_VERSION', self::VERSION);
+ }
+
+ return $this->sieve->save($name);
+ }
+
+ /**
+ * Returns list of rules from the current script
+ *
+ * @return array List of rules
+ */
+ public function list_rules()
+ {
+ $result = array();
+ $i = 1;
+
+ foreach ($this->script as $idx => $filter) {
+ if ($filter['type'] != 'if') {
+ continue;
+ }
+ $fname = $filter['name'] ? $filter['name'] : "#$i";
+ $result[] = array(
+ 'id' => $idx,
+ 'name' => $fname,
+ 'class' => $filter['disabled'] ? 'disabled' : '',
+ );
+ $i++;
}
- return $this->engine;
+ return $result;
}
}
diff --git a/plugins/managesieve/package.xml b/plugins/managesieve/package.xml
index 6ae53c250..a0c38b82d 100644
--- a/plugins/managesieve/package.xml
+++ b/plugins/managesieve/package.xml
@@ -17,16 +17,16 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
- <date>2013-09-09</date>
+ <date>2013-02-17</date>
<version>
- <release>7.0</release>
- <api>7.0</api>
+ <release>6.2</release>
+ <api>6.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
@@ -38,10 +38,6 @@
<tasks:replace from="@name@" to="name" type="package-info"/>
<tasks:replace from="@package_version@" to="version" type="package-info"/>
</file>
- <file name="lib/Roundcube/rcube_sieve.php" role="php"></file>
- <file name="lib/Roundcube/rcube_sieve_engine.php" role="php"></file>
- <file name="lib/Roundcube/rcube_sieve_script.php" role="php"></file>
- <file name="lib/Net/Sieve.php" role="php"></file>
<file name="localization/be_BE.inc" role="data"></file>
<file name="localization/bg_BG.inc" role="data"></file>
<file name="localization/bs_BA.inc" role="data"></file>
@@ -97,7 +93,6 @@
<file name="skins/classic/images/add.png" role="data"></file>
<file name="skins/classic/images/del.png" role="data"></file>
<file name="skins/classic/images/down_small.gif" role="data"></file>
- <file name="skins/classic/images/erase.png" role="data"></file>
<file name="skins/classic/images/filter.png" role="data"></file>
<file name="skins/classic/images/up_small.gif" role="data"></file>
<file name="skins/larry/managesieve.css" role="data"></file>
@@ -108,8 +103,11 @@
<file name="skins/larry/images/add.png" role="data"></file>
<file name="skins/larry/images/del.png" role="data"></file>
<file name="skins/larry/images/down_small.gif" role="data"></file>
- <file name="skins/larry/images/erase.png" role="data"></file>
<file name="skins/larry/images/up_small.gif" role="data"></file>
+ <file name="managesieve.php" role="php"></file>
+ <file name="lib/rcube_sieve.php" role="php"></file>
+ <file name="lib/rcube_sieve_script.php" role="php"></file>
+ <file name="lib/Net/Sieve.php" role="php"></file>
<file name="config.inc.php.dist" role="data"></file>
</dir>
<!-- / -->
diff --git a/plugins/managesieve/skins/classic/managesieve.css b/plugins/managesieve/skins/classic/managesieve.css
index 59d88cb46..b7c6f5d06 100644
--- a/plugins/managesieve/skins/classic/managesieve.css
+++ b/plugins/managesieve/skins/classic/managesieve.css
@@ -171,12 +171,12 @@ td.advbutton a
td.advbutton a.show
{
- background: url(images/down_small.gif) center no-repeat;
+ background: url(images/down_small.gif?v=8629.106) center no-repeat;
}
td.advbutton a.hide
{
- background: url(images/up_small.gif) center no-repeat;
+ background: url(images/up_small.gif?v=c56c.106) center no-repeat;
}
td.rowbuttons
@@ -201,30 +201,11 @@ td.rowtargets
padding-top: 2px;
}
-td.rowtargets > div
-{
- vertical-align: top;
- margin-top: 2px;
-}
-
td.rowtargets div.adv
{
padding-top: 3px;
}
-td.rowtargets div.adv span.label
-{
- display: inline-block;
- padding-right: 10px;
- min-width: 65px;
-}
-
-html.mozilla #filter-form select
-{
- padding-top: 3px;
- padding-bottom: 3px;
-}
-
input.disabled, input.disabled:hover
{
color: #999999;
@@ -245,7 +226,6 @@ input.radio
select.operator_selector
{
width: 200px;
- vertical-align: top;
}
td.rowtargets span,
@@ -256,11 +236,6 @@ span.label
white-space: nowrap;
}
-td.rowtargets label
-{
- color: black;
-}
-
#footer
{
padding-top: 5px;
@@ -299,7 +274,7 @@ span.sieve.error
a.button.add
{
- background: url(images/add.png) no-repeat;
+ background: url(images/add.png?v=a165.280) no-repeat;
width: 30px;
height: 20px;
margin-right: 4px;
@@ -308,7 +283,7 @@ a.button.add
a.button.del
{
- background: url(images/del.png) no-repeat;
+ background: url(images/del.png?v=3c27.247) no-repeat;
width: 30px;
height: 20px;
display: inline-block;
@@ -326,78 +301,8 @@ a.button.disabled
#filter-form textarea
{
font-size: 11px;
- vertical-align: middle;
}
-/* smart multi-row input field */
-.listarea
-{
- border: 1px solid #666;
- margin: 0;
- padding: 1px;
- display: inline-block;
- max-height: 67px;
- overflow-y: auto;
-}
-
-td.rowtargets > span.listarea
-{
- vertical-align: top;
- margin-top: 2px;
-}
-
-.listelement
-{
- display: block;
- white-space: nowrap;
- background-color: #fff;
- border-top: 1px solid #e2e2e2;
- height: 16px;
- padding: 0;
- margin: 0;
- overflow: hidden;
- line-height: 16px;
-}
-
-.listarea.error .listelement
-{
- background-color: #FFFFC4;
-}
-
-.listelement:first-child
-{
- border-top: none;
-}
-
-#filter-form .listelement input
-{
- border: none;
- border-radius: 0;
- box-shadow: none;
- outline: none;
- vertical-align: top;
- height: 16px;
- padding-top: 0;
- padding-bottom: 0;
- line-height: 16px;
- background-color: transparent;
-}
-
-.listelement input:focus
-{
- box-shadow: none;
-}
-
-.listelement .reset
-{
- display: inline-block;
- width: 16px;
- height: 16px;
- background: url(images/erase.png) -1px 0 no-repeat #eee;
- cursor: pointer;
-}
-
-
/* fixes for popup window */
body.iframe.mail
diff --git a/plugins/managesieve/skins/classic/managesieve_mail.css b/plugins/managesieve/skins/classic/managesieve_mail.css
index 87a11cc92..73cc47ba2 100644
--- a/plugins/managesieve/skins/classic/managesieve_mail.css
+++ b/plugins/managesieve/skins/classic/managesieve_mail.css
@@ -1,5 +1,5 @@
#messagemenu li a.filterlink {
- background-image: url(images/filter.png);
+ background-image: url(images/filter.png?v=b0fe.547);
background-position: 7px 0;
}
diff --git a/plugins/managesieve/skins/classic/templates/managesieve.html b/plugins/managesieve/skins/classic/templates/managesieve.html
index 869e3ac36..71eebe105 100644
--- a/plugins/managesieve/skins/classic/templates/managesieve.html
+++ b/plugins/managesieve/skins/classic/templates/managesieve.html
@@ -19,7 +19,7 @@
</style>
</head>
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -83,9 +83,5 @@
</ul>
</div>
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/plugins/managesieve/skins/larry/managesieve.css b/plugins/managesieve/skins/larry/managesieve.css
index 2144fe13f..bf5910edc 100644
--- a/plugins/managesieve/skins/larry/managesieve.css
+++ b/plugins/managesieve/skins/larry/managesieve.css
@@ -43,7 +43,7 @@
#filtersetslist
{
width: 100%;
- table-layout: fixed;
+ table-layout: fixed;
}
#filterslist tbody td,
@@ -145,12 +145,12 @@ td.advbutton a
td.advbutton a.show
{
- background: url(images/down_small.gif) center no-repeat;
+ background: url(images/down_small.gif?v=8629.106) center no-repeat;
}
td.advbutton a.hide
{
- background: url(images/up_small.gif) center no-repeat;
+ background: url(images/up_small.gif?v=c56c.106) center no-repeat;
}
td.rowbuttons
@@ -175,23 +175,9 @@ td.rowtargets
padding-top: 2px;
}
-td.rowtargets > div
-{
- vertical-align: top;
- margin-top: 2px;
-}
-
td.rowtargets div.adv
{
padding-top: 3px;
- font-size: 10px;
-}
-
-td.rowtargets div.adv span.label
-{
- display: inline-block;
- padding-right: 5px;
- min-width: 70px;
}
input.disabled, input.disabled:hover
@@ -211,15 +197,9 @@ input.radio
margin-top: 0;
}
-input.radio
-{
- vertical-align: middle;
-}
-
select.operator_selector
{
width: 200px;
- vertical-align: top;
}
td.rowtargets span,
@@ -230,11 +210,6 @@ span.label
white-space: nowrap;
}
-td.rowtargets label
-{
- color: black;
-}
-
#footer
{
padding-top: 5px;
@@ -277,7 +252,7 @@ a.button
a.button.add
{
- background: url(images/add.png) no-repeat;
+ background: url(images/add.png?v=a165.280) no-repeat;
width: 30px;
height: 20px;
margin-right: 4px;
@@ -286,7 +261,7 @@ a.button.add
a.button.del
{
- background: url(images/del.png) no-repeat;
+ background: url(images/del.png?v=3c27.247) no-repeat;
width: 30px;
height: 20px;
display: inline-block;
@@ -305,13 +280,6 @@ a.button.disabled
{
font-size: 11px;
padding: 1px;
- vertical-align: middle;
-}
-
-html.mozilla #filter-form select
-{
- padding-top: 3px;
- padding-bottom: 3px;
}
/* revert larry style button */
@@ -328,80 +296,6 @@ fieldset
border-radius: 4px;
}
-/* smart multi-row input field */
-.listarea
-{
- border: 1px solid #B2B2B2;
- border-radius: 4px;
- box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
- -moz-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
- -webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
- -o-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
- margin: 0;
- padding: 2px;
- display: inline-block;
- max-height: 59px;
- overflow-y: auto;
-}
-
-td.rowtargets > span.listarea
-{
- vertical-align: top;
- margin-top: 2px;
-}
-
-.listelement
-{
- display: block;
- white-space: nowrap;
- background-color: #fff;
- border-top: 1px solid #e2e2e2;
- height: 14px;
- padding: 0;
- margin: 0;
- overflow: hidden;
- line-height: 14px;
-}
-
-.listarea.error .listelement
-{
- background-color: #FFFFC4;
-}
-
-.listelement:first-child
-{
- border-top: none;
-}
-
-#filter-form .listelement input
-{
- border: none;
- border-radius: 0;
- box-shadow: none;
- outline: none;
- vertical-align: top;
- height: 14px;
- padding-top: 0;
- padding-bottom: 0;
- line-height: 14px;
- background-color: transparent;
-}
-
-.listelement input:focus
-{
- box-shadow: none;
-}
-
-.listelement .reset
-{
- display: inline-block;
- width: 16px;
- height: 16px;
- background: url(images/erase.png) -1px -1px no-repeat #eee;
- cursor: pointer;
-}
-
-
/* fixes for popup window */
body.iframe.mail
diff --git a/plugins/managesieve/tests/src/parser.out b/plugins/managesieve/tests/src/parser.out
index cb0bad5e7..385c8890d 100644
--- a/plugins/managesieve/tests/src/parser.out
+++ b/plugins/managesieve/tests/src/parser.out
@@ -1,4 +1,4 @@
-require ["envelope","fileinto","reject"];
+require ["fileinto","reject","envelope"];
# rule:[spam]
if header :contains "X-DSPAM-Result" "Spam"
{
@@ -39,7 +39,7 @@ if true
}
fileinto "Test";
# rule:[address test]
-if address :is "From" "nagios@domain.tld"
+if address :all :is "From" "nagios@domain.tld"
{
fileinto "domain.tld";
stop;
diff --git a/plugins/managesieve/tests/src/parser_enotify_b b/plugins/managesieve/tests/src/parser_enotify_b
index a3011bac2..8854658f4 100644
--- a/plugins/managesieve/tests/src/parser_enotify_b
+++ b/plugins/managesieve/tests/src/parser_enotify_b
@@ -1,6 +1,6 @@
-require ["enotify","envelope","variables"];
+require ["envelope","variables","enotify"];
# rule:[from]
-if envelope :matches "from" "*"
+if envelope :all :matches "from" "*"
{
set "env_from" " [really: ${1}]";
}
@@ -10,7 +10,7 @@ if header :matches "Subject" "*"
set "subject" "${1}";
}
# rule:[from notify]
-if address :matches "from" "*"
+if address :all :matches "from" "*"
{
set "from_addr" "${1}";
notify :message "${from_addr}${env_from}: ${subject}" "mailto:alm@example.com";
diff --git a/plugins/managesieve/tests/src/parser_notify_b b/plugins/managesieve/tests/src/parser_notify_b
index ab90ed48c..cf80a9701 100644
--- a/plugins/managesieve/tests/src/parser_notify_b
+++ b/plugins/managesieve/tests/src/parser_notify_b
@@ -1,6 +1,6 @@
-require ["envelope","notify","variables"];
+require ["envelope","variables","notify"];
# rule:[from]
-if envelope :matches "from" "*"
+if envelope :all :matches "from" "*"
{
set "env_from" " [really: ${1}]";
}
@@ -10,7 +10,7 @@ if header :matches "Subject" "*"
set "subject" "${1}";
}
# rule:[from notify]
-if address :matches "from" "*"
+if address :all :matches "from" "*"
{
set "from_addr" "${1}";
notify :message "${from_addr}${env_from}: ${subject}" :method "sms:1234567890";
diff --git a/plugins/managesieve/tests/src/parser_relational b/plugins/managesieve/tests/src/parser_relational
index 92c5e1a8e..0a92fde54 100644
--- a/plugins/managesieve/tests/src/parser_relational
+++ b/plugins/managesieve/tests/src/parser_relational
@@ -1,4 +1,4 @@
-require ["comparator-i;ascii-numeric","relational"];
+require ["relational","comparator-i;ascii-numeric"];
# rule:[redirect]
if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-score" "14"
{
diff --git a/plugins/managesieve/tests/src/parser_subaddress b/plugins/managesieve/tests/src/parser_subaddress
index e44555096..f106b796e 100644
--- a/plugins/managesieve/tests/src/parser_subaddress
+++ b/plugins/managesieve/tests/src/parser_subaddress
@@ -1,4 +1,4 @@
-require ["envelope","fileinto","subaddress"];
+require ["envelope","subaddress","fileinto"];
if envelope :user "To" "postmaster"
{
fileinto "postmaster";
diff --git a/plugins/markasjunk/localization/ar.inc b/plugins/markasjunk/localization/ar.inc
new file mode 100644
index 000000000..1915e97fb
--- /dev/null
+++ b/plugins/markasjunk/localization/ar.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/markasjunk/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Mark-As-Junk plugin |
+ | Copyright (C) 2012-2013, 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/plugin-markasjunk/
+*/
+$labels['buttontext'] = 'غير المرغوب';
+$labels['buttontitle'] = 'حدد كغير مرغوب';
+?> \ No newline at end of file
diff --git a/plugins/markasjunk/localization/bg_BG.inc b/plugins/markasjunk/localization/bg_BG.inc
new file mode 100644
index 000000000..c49bafaab
--- /dev/null
+++ b/plugins/markasjunk/localization/bg_BG.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/markasjunk/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Mark-As-Junk plugin |
+ | Copyright (C) 2012-2013, 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/plugin-markasjunk/
+*/
+$labels['buttontext'] = 'Спам';
+$labels['buttontitle'] = 'Маркирай като Ñпам';
+$labels['reportedasjunk'] = 'ПиÑмото е маркирано като Ñпам уÑпешно';
+?> \ No newline at end of file
diff --git a/plugins/markasjunk/localization/en_US.inc b/plugins/markasjunk/localization/en_US.inc
index aaa3c91ac..0cc212f22 100644
--- a/plugins/markasjunk/localization/en_US.inc
+++ b/plugins/markasjunk/localization/en_US.inc
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | plugins/markasjunk/localization/<lang>.inc |
+ | plugins/markasjunk/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Mark-As-Junk plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/markasjunk/localization/eu_ES.inc b/plugins/markasjunk/localization/eu_ES.inc
new file mode 100644
index 000000000..ade169b70
--- /dev/null
+++ b/plugins/markasjunk/localization/eu_ES.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/markasjunk/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Mark-As-Junk plugin |
+ | Copyright (C) 2012-2013, 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/plugin-markasjunk/
+*/
+$labels['buttontext'] = 'Zabor-mezua';
+$labels['buttontitle'] = 'Markatu zabor-mezu bezala';
+$labels['reportedasjunk'] = 'Zabor bezala markatu da';
+?> \ No newline at end of file
diff --git a/plugins/markasjunk/localization/lb_LU.inc b/plugins/markasjunk/localization/lb_LU.inc
index eb211d66c..c6f1081e2 100644
--- a/plugins/markasjunk/localization/lb_LU.inc
+++ b/plugins/markasjunk/localization/lb_LU.inc
@@ -15,10 +15,7 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-markasjunk/
*/
-
-$labels = array();
$labels['buttontext'] = 'Spam';
$labels['buttontitle'] = 'Als Spam markéieren';
$labels['reportedasjunk'] = 'Erfollegräich als Spam gemellt';
-
?> \ No newline at end of file
diff --git a/plugins/markasjunk/localization/lv_LV.inc b/plugins/markasjunk/localization/lv_LV.inc
index 5389ae399..f0ea921ba 100644
--- a/plugins/markasjunk/localization/lv_LV.inc
+++ b/plugins/markasjunk/localization/lv_LV.inc
@@ -17,8 +17,8 @@
*/
$labels = array();
-$labels['buttontext'] = 'MÄ“stules';
-$labels['buttontitle'] = 'AtzÄ«mÄ“t kÄ mÄ“stuli';
-$labels['reportedasjunk'] = 'SekmÄ«gi iatzÄ«mÄ“ta kÄ mÄ“stule';
+$labels['buttontext'] = 'Junk';
+$labels['buttontitle'] = 'IezÄ«mÄ“t kÄ mÄ“stuli';
+$labels['reportedasjunk'] = 'SekmÄ«gi iezÄ«mÄ“ta kÄ mÄ“stule';
?> \ No newline at end of file
diff --git a/plugins/markasjunk/localization/ro_RO.inc b/plugins/markasjunk/localization/ro_RO.inc
index 03e5824c2..1186aab73 100644
--- a/plugins/markasjunk/localization/ro_RO.inc
+++ b/plugins/markasjunk/localization/ro_RO.inc
@@ -17,8 +17,8 @@
*/
$labels = array();
-$labels['buttontext'] = 'Vechituri';
-$labels['buttontitle'] = 'Marchează ca SPAM';
-$labels['reportedasjunk'] = 'Raportat cu succes ca SPAM';
+$labels['buttontext'] = 'Spam';
+$labels['buttontitle'] = 'Marchează ca Spam';
+$labels['reportedasjunk'] = 'Raportat cu succes ca Spam';
?> \ No newline at end of file
diff --git a/plugins/markasjunk/localization/ru_RU.inc b/plugins/markasjunk/localization/ru_RU.inc
index d2b6abd40..cbf99d253 100644
--- a/plugins/markasjunk/localization/ru_RU.inc
+++ b/plugins/markasjunk/localization/ru_RU.inc
@@ -18,7 +18,7 @@
$labels = array();
$labels['buttontext'] = 'СПÐÐœ';
-$labels['buttontitle'] = 'ПеремеÑтить в СПÐÐœ';
-$labels['reportedasjunk'] = 'Перемещено в СПÐÐœ';
+$labels['buttontitle'] = 'ПеремеÑтить в "СПÐÐœ';
+$labels['reportedasjunk'] = 'Перемещено в "СПÐÐœ';
?> \ No newline at end of file
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..3d18b3b54
--- /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..f6b0c58ec
--- /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.color = 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/new_user_dialog/localization/ar.inc b/plugins/new_user_dialog/localization/ar.inc
new file mode 100644
index 000000000..110b6c429
--- /dev/null
+++ b/plugins/new_user_dialog/localization/ar.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/new_user_dialog/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New User Dialog plugin |
+ | Copyright (C) 2012-2013, 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/plugin-new_user_dialog/
+*/
+$labels['identitydialogtitle'] = 'يرجى إكمال هوية المرسل';
+$labels['identitydialoghint'] = 'يظهر هذا المربع مرة واحدة Ùقط عند تسجيل الدخول أول مرة .';
+?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/ar_SA.inc b/plugins/new_user_dialog/localization/ar_SA.inc
new file mode 100644
index 000000000..ea65a059c
--- /dev/null
+++ b/plugins/new_user_dialog/localization/ar_SA.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/new_user_dialog/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New User Dialog plugin |
+ | Copyright (C) 2012-2013, 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/plugin-new_user_dialog/
+*/
+$labels['identitydialoghint'] = 'يظهر هذا المربع مرة واحدة Ùقط عند أول الدخول';
+?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/ast.inc b/plugins/new_user_dialog/localization/ast.inc
new file mode 100644
index 000000000..0ec826dee
--- /dev/null
+++ b/plugins/new_user_dialog/localization/ast.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/new_user_dialog/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New User Dialog plugin |
+ | Copyright (C) 2012-2013, 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/plugin-new_user_dialog/
+*/
+$labels['identitydialogtitle'] = 'Por favor, completa los tos datos personales';
+$labels['identitydialoghint'] = 'Esti diálogu namái va apaecer la primer vegada que te coneutes al corréu.';
+?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/en_US.inc b/plugins/new_user_dialog/localization/en_US.inc
index d508cfc9c..a9e66bd23 100644
--- a/plugins/new_user_dialog/localization/en_US.inc
+++ b/plugins/new_user_dialog/localization/en_US.inc
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | plugins/new_user_dialog/localization/<lang>.inc |
+ | plugins/new_user_dialog/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail New User Dialog plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/new_user_dialog/localization/es_AR.inc b/plugins/new_user_dialog/localization/es_AR.inc
new file mode 100644
index 000000000..bda1c7477
--- /dev/null
+++ b/plugins/new_user_dialog/localization/es_AR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/new_user_dialog/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New User Dialog plugin |
+ | Copyright (C) 2012-2013, 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/plugin-new_user_dialog/
+*/
+$labels['identitydialogtitle'] = 'Por favor, seleccione una identidad para los mensajes salientes';
+$labels['identitydialoghint'] = 'Este diálogo aparecerá sólo una vez durante el primer ingreso';
+?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/eu_ES.inc b/plugins/new_user_dialog/localization/eu_ES.inc
new file mode 100644
index 000000000..1276ea70c
--- /dev/null
+++ b/plugins/new_user_dialog/localization/eu_ES.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/new_user_dialog/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New User Dialog plugin |
+ | Copyright (C) 2012-2013, 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/plugin-new_user_dialog/
+*/
+$labels['identitydialogtitle'] = 'Osatu zure bidaltzaile-identitatea';
+$labels['identitydialoghint'] = 'Kutxa hau behin bakarri agertzen da lehenengoz sartzean.';
+?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/fa_AF.inc b/plugins/new_user_dialog/localization/fa_AF.inc
new file mode 100644
index 000000000..d66d4cbcf
--- /dev/null
+++ b/plugins/new_user_dialog/localization/fa_AF.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/new_user_dialog/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New User Dialog plugin |
+ | Copyright (C) 2012-2013, 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/plugin-new_user_dialog/
+*/
+$labels['identitydialogtitle'] = 'لطÙا مشخصات Ùرستنده را کامل کنید';
+$labels['identitydialoghint'] = 'این متن تنها هنگام اولین ورود نمایش داده خواهد شد';
+?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/lb_LU.inc b/plugins/new_user_dialog/localization/lb_LU.inc
index 36da96e5e..4fe55546a 100644
--- a/plugins/new_user_dialog/localization/lb_LU.inc
+++ b/plugins/new_user_dialog/localization/lb_LU.inc
@@ -15,9 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-new_user_dialog/
*/
-
-$labels = array();
$labels['identitydialogtitle'] = 'Vervollstänneg w.e.gl deng Sender-Identitéit';
$labels['identitydialoghint'] = 'Dës Këscht erschéngt just beim éischte Login.';
-
?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/lv_LV.inc b/plugins/new_user_dialog/localization/lv_LV.inc
index 0447d995a..2e3642330 100644
--- a/plugins/new_user_dialog/localization/lv_LV.inc
+++ b/plugins/new_user_dialog/localization/lv_LV.inc
@@ -17,7 +17,7 @@
*/
$labels = array();
-$labels['identitydialogtitle'] = 'LÅ«dzu aizpildiet JÅ«su, kÄ sÅ«tÄ«tÄja, identitÄtes informÄciju';
-$labels['identitydialoghint'] = 'Å is logs parÄdÄ«sies tikai pirmajÄ autorizÄcijas reizÄ“.';
+$labels['identitydialogtitle'] = 'LÅ«dzu, aizpildiet nosÅ«tÄ«tÄja identifikÄcijas informÄciju';
+$labels['identitydialoghint'] = 'Å is logs parÄdÄ«sies tikai pirmajÄ pieteikÅ¡anÄs reizÄ“';
?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/ro_RO.inc b/plugins/new_user_dialog/localization/ro_RO.inc
index caa8f3257..9d16daee5 100644
--- a/plugins/new_user_dialog/localization/ro_RO.inc
+++ b/plugins/new_user_dialog/localization/ro_RO.inc
@@ -17,7 +17,7 @@
*/
$labels = array();
-$labels['identitydialogtitle'] = 'Te rog completează identitatea de expeditor.';
-$labels['identitydialoghint'] = 'Această căsuţă apare o data la prima autentificare.';
+$labels['identitydialogtitle'] = 'Te rog completează identitatea expeditorului.';
+$labels['identitydialoghint'] = 'Această căsuţă apare doar la prima autentificare.';
?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/new_user_dialog.php b/plugins/new_user_dialog/new_user_dialog.php
index 39a707638..9c9dcce1c 100644
--- a/plugins/new_user_dialog/new_user_dialog.php
+++ b/plugins/new_user_dialog/new_user_dialog.php
@@ -10,12 +10,10 @@
* @version @package_version@
* @license GNU GPLv3+
* @author Thomas Bruederli
- * @author Aleksander Machniak
*/
class new_user_dialog extends rcube_plugin
{
public $task = 'login|mail';
- public $noframe = true;
function init()
{
@@ -34,9 +32,8 @@ class new_user_dialog extends rcube_plugin
function create_identity($p)
{
// set session flag when a new user was created and the default identity seems to be incomplete
- if ($p['login'] && !$p['complete']) {
+ if ($p['login'] && !$p['complete'])
$_SESSION['plugin.newuserdialog'] = true;
- }
}
/**
@@ -66,7 +63,7 @@ class new_user_dialog extends rcube_plugin
$table->add(null, html::tag('input', array(
'type' => 'text',
'name' => '_email',
- 'value' => rcube_utils::idn_to_utf8($identity['email']),
+ 'value' => rcube_idn_to_utf8($identity['email']),
'disabled' => ($identities_level == 1 || $identities_level == 3)
)));
@@ -89,30 +86,20 @@ class new_user_dialog extends rcube_plugin
'id' => 'newuserdialog',
'action' => $rcmail->url('plugin.newusersave'),
'method' => 'post'),
- html::p('hint', rcube::Q($this->gettext('identitydialoghint'))) .
+ html::tag('h3', null, Q($this->gettext('identitydialogtitle'))) .
+ html::p('hint', Q($this->gettext('identitydialoghint'))) .
$table->show() .
html::p(array('class' => 'formbuttons'),
html::tag('input', array('type' => 'submit',
'class' => 'button mainaction', 'value' => $this->gettext('save'))))
));
- $title = rcube::JQ($this->gettext('identitydialogtitle'));
-
// disable keyboard events for messages list (#1486726)
- $rcmail->output->add_script("
- $('#newuserdialog').show()
- .dialog({modal:true, resizable:false, closeOnEscape:false, width:450, title:'$title'})
- .submit(function() {
- var i, request = {}, form = $(this).serializeArray();
-
- for (i in form)
- request[form[i].name] = form[i].value;
-
- rcmail.http_post('plugin.newusersave', request, true);
- return false;
- });
- $('input[name=_name]').focus();
- rcube_webmail.prototype.new_user_dialog_close = function() { $('#newuserdialog').dialog('close'); }
+ $rcmail->output->add_script(
+ "rcmail.message_list.key_press = function(){};
+ rcmail.message_list.key_down = function(){};
+ $('#newuserdialog').show().dialog({ modal:true, resizable:false, closeOnEscape:false, width:420 });
+ $('input[name=_name]').focus();
", 'docready');
$this->include_stylesheet('newuserdialog.css');
@@ -120,45 +107,39 @@ class new_user_dialog extends rcube_plugin
}
/**
- * Handler for submitted form (ajax request)
+ * Handler for submitted form
*
* Check fields and save to default identity if valid.
* Afterwards the session flag is removed and we're done.
*/
function save_data()
{
- $rcmail = rcmail::get_instance();
- $identity = $rcmail->user->get_identity();
- $ident_level = intval($rcmail->config->get('identities_level', 0));
+ $rcmail = rcmail::get_instance();
+ $identity = $rcmail->user->get_identity();
+ $identities_level = intval($rcmail->config->get('identities_level', 0));
$save_data = array(
- 'name' => rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST),
- 'email' => rcube_utils::get_input_value('_email', rcube_utils::INPUT_POST),
- 'organization' => rcube_utils::get_input_value('_organization', rcube_utils::INPUT_POST),
- 'signature' => rcube_utils::get_input_value('_signature', rcube_utils::INPUT_POST),
+ 'name' => get_input_value('_name', RCUBE_INPUT_POST),
+ 'email' => get_input_value('_email', RCUBE_INPUT_POST),
+ 'organization' => get_input_value('_organization', RCUBE_INPUT_POST),
+ 'signature' => get_input_value('_signature', RCUBE_INPUT_POST),
);
// don't let the user alter the e-mail address if disabled by config
- if (in_array($ident_level, array(1,3,4))) {
+ if ($identities_level == 1 || $identities_level == 3)
$save_data['email'] = $identity['email'];
- }
+ else
+ $save_data['email'] = rcube_idn_to_ascii($save_data['email']);
- if (empty($save_data['name']) || empty($save_data['email'])) {
- $rcmail->output->show_message('formincomplete', 'error');
- }
- else if (!rcube_utils::check_email($save_data['email'] = rcube_utils::idn_to_ascii($save_data['email']))) {
- $rcmail->output->show_message('emailformaterror', 'error', array('email' => $save_data['email']));
- }
- else {
- // save data
+ // save data if not empty
+ if (!empty($save_data['name']) && !empty($save_data['email'])) {
$rcmail->user->update_identity($identity['identity_id'], $save_data);
$rcmail->session->remove('plugin.newuserdialog');
- // hide dialog
- $rcmail->output->command('new_user_dialog_close');
- $rcmail->output->show_message('successfullysaved', 'confirmation');
}
- $rcmail->output->send();
+ $rcmail->output->redirect('');
}
}
+
+?>
diff --git a/plugins/new_user_dialog/package.xml b/plugins/new_user_dialog/package.xml
index 68a929931..0bca1d9d4 100644
--- a/plugins/new_user_dialog/package.xml
+++ b/plugins/new_user_dialog/package.xml
@@ -13,16 +13,21 @@
<email>roundcube@gmail.com</email>
<active>yes</active>
</lead>
- <date>2013-05-09</date>
+ <date>2012-01-16</date>
+ <time>17:00</time>
<version>
- <release>2.0</release>
- <api>2.0</api>
+ <release>1.5</release>
+ <api>1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>
+- Use jquery UI to render the dialog
+- Fixed IDNA encoding/decoding of e-mail addresses (#1487909)
+ </notes>
<contents>
<dir baseinstalldir="/" name="/">
<file name="new_user_dialog.php" role="php">
@@ -66,4 +71,84 @@
</required>
</dependencies>
<phprelease/>
+ <changelog>
+ <release>
+ <date>2010-03-29</date>
+ <time>13:20:00</time>
+ <version>
+ <release>1.0</release>
+ <api>1.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <notes></notes>
+ </release>
+ <release>
+ <date>2010-05-13</date>
+ <time>19:35:00</time>
+ <version>
+ <release>1.1</release>
+ <api>1.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <notes>
+- Fix space bar and backspace buttons not working (#1486726)
+ </notes>
+ </release>
+ <release>
+ <date>2010-05-27</date>
+ <time>12:00:00</time>
+ <version>
+ <release>1.2</release>
+ <api>1.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <notes>
+- Add overlay box only to mail task main template
+- Fix possible error on form submission (#1486103)
+ </notes>
+ </release>
+ <release>
+ <date>2010-12-02</date>
+ <time>12:00:00</time>
+ <version>
+ <release>1.3</release>
+ <api>1.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <notes>
+- Added setting of focus on name input
+- Added gl_ES translation
+ </notes>
+ </release>
+ <release>
+ <date>2012-01-16</date>
+ <time>17:00:00</time>
+ <version>
+ <release>1.5</release>
+ <api>1.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <notes>- Use jquery UI to render the dialog</notes>
+ </release>
+ </changelog>
</package>
diff --git a/plugins/new_user_identity/new_user_identity.php b/plugins/new_user_identity/new_user_identity.php
index 3943134b2..200d9accd 100644
--- a/plugins/new_user_identity/new_user_identity.php
+++ b/plugins/new_user_identity/new_user_identity.php
@@ -8,18 +8,17 @@
*
* @version @package_version@
* @author Kris Steinhoff
- * @license GNU GPLv3+
*
* Example configuration:
*
* // The id of the address book to use to automatically set a new
* // user's full name in their new identity. (This should be an
- * // string, which refers to the $config['ldap_public'] array.)
- * $config['new_user_identity_addressbook'] = 'People';
+ * // string, which refers to the $rcmail_config['ldap_public'] array.)
+ * $rcmail_config['new_user_identity_addressbook'] = 'People';
*
* // When automatically setting a new users's full name in their
* // new identity, match the user's login name against this field.
- * $config['new_user_identity_match'] = 'uid';
+ * $rcmail_config['new_user_identity_match'] = 'uid';
*/
class new_user_identity extends rcube_plugin
{
@@ -34,6 +33,8 @@ class new_user_identity extends rcube_plugin
function lookup_user_name($args)
{
+ $rcmail = rcmail::get_instance();
+
if ($this->init_ldap($args['host'])) {
$results = $this->ldap->search('*', $args['user'], true);
if (count($results->records) == 1) {
@@ -42,7 +43,7 @@ class new_user_identity extends rcube_plugin
$args['user_name'] = $user_name;
if (!$args['user_email'] && strpos($user_email, '@')) {
- $args['user_email'] = rcube_utils::idn_to_ascii($user_email);
+ $args['user_email'] = rcube_idn_to_ascii($user_email);
}
}
}
diff --git a/plugins/new_user_identity/package.xml b/plugins/new_user_identity/package.xml
index 45a3c4c8d..e50cd9255 100644
--- a/plugins/new_user_identity/package.xml
+++ b/plugins/new_user_identity/package.xml
@@ -24,7 +24,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/newmail_notifier/config.inc.php.dist b/plugins/newmail_notifier/config.inc.php.dist
index cdb563c40..067fe19f1 100644
--- a/plugins/newmail_notifier/config.inc.php.dist
+++ b/plugins/newmail_notifier/config.inc.php.dist
@@ -1,12 +1,12 @@
<?php
// Enables basic notification
-$config['newmail_notifier_basic'] = false;
+$rcmail_config['newmail_notifier_basic'] = false;
// Enables sound notification
-$config['newmail_notifier_sound'] = false;
+$rcmail_config['newmail_notifier_sound'] = false;
// Enables desktop notification
-$config['newmail_notifier_desktop'] = false;
+$rcmail_config['newmail_notifier_desktop'] = false;
?>
diff --git a/plugins/newmail_notifier/localization/ast.inc b/plugins/newmail_notifier/localization/ast.inc
new file mode 100644
index 000000000..3c5c192e0
--- /dev/null
+++ b/plugins/newmail_notifier/localization/ast.inc
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/newmail_notifier/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New Mail Notifier plugin |
+ | Copyright (C) 2012-2013, 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/plugin-newmail_notifier/
+*/
+$labels['basic'] = 'Amosar notificaciones del navegador cuando aporte un mensaxe nuevu';
+$labels['desktop'] = 'Amosar notificaciones del escritoriu cuando aporte un mensaxe nuevu';
+$labels['sound'] = 'Reproducir soníu cuando aporte un mensaxe nuevu';
+$labels['test'] = 'Prueba';
+$labels['title'] = '¡Mensaxe nuevu!';
+$labels['body'] = 'Recibisti un mensaxe nuevu';
+$labels['testbody'] = 'Esta ye una notificación de pruebes';
+$labels['desktopdisabled'] = 'Les notificaciones d\'escritoriu tán deshabilitaes nel to navegador.';
+$labels['desktopunsupported'] = 'El to navegador nun sofita notificaciones d\'escritoriu.';
+$labels['desktoptimeout'] = 'Zarrar notificación d\'escritoriu';
+?>
diff --git a/plugins/newmail_notifier/localization/bg_BG.inc b/plugins/newmail_notifier/localization/bg_BG.inc
new file mode 100644
index 000000000..15791dd93
--- /dev/null
+++ b/plugins/newmail_notifier/localization/bg_BG.inc
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/newmail_notifier/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New Mail Notifier plugin |
+ | Copyright (C) 2012-2013, 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/plugin-newmail_notifier/
+*/
+$labels['basic'] = 'Показва извеÑÑ‚Ð¸Ñ Ð² браузъра при ново пиÑмо';
+$labels['desktop'] = 'Показва извеÑÑ‚Ð¸Ñ Ð½Ð° Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚ при ново пиÑмо';
+$labels['sound'] = 'Възпроизведи звук при ново пиÑмо';
+$labels['test'] = 'ТеÑÑ‚';
+$labels['title'] = 'Ðово пиÑмо!';
+$labels['body'] = 'Получихте ново пиÑмо.';
+$labels['testbody'] = 'Това е теÑтово извеÑтие.';
+$labels['desktopdisabled'] = 'ИзвеÑтиÑта на Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚ Ñа изключени за Ð’Ð°ÑˆÐ¸Ñ Ð±Ñ€Ð°ÑƒÐ·ÑŠÑ€.';
+$labels['desktopunsupported'] = 'ВашиÑÑ‚ браузър не поддържа извеÑÑ‚Ð¸Ñ Ð½Ð° Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚.';
+$labels['desktoptimeout'] = 'ЗатварÑне на извеÑтие на Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚';
+?>
diff --git a/plugins/newmail_notifier/localization/el_GR.inc b/plugins/newmail_notifier/localization/el_GR.inc
new file mode 100644
index 000000000..5f41bc974
--- /dev/null
+++ b/plugins/newmail_notifier/localization/el_GR.inc
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/newmail_notifier/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New Mail Notifier plugin |
+ | Copyright (C) 2012-2013, 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/plugin-newmail_notifier/
+*/
+$labels['basic'] = 'Εμφανίση ειδοποιήσεων Ï€ÏόγÏαμματος πεÏιήγησης στο νέο μήνυμα';
+$labels['desktop'] = 'Εμφάνιση ειδοποιήσεων στην επιφάνεια εÏγασίας για νέο μήνυμα ';
+$labels['sound'] = 'Ηχητική ειδοποίηση κατά την λήψη νέων μηνυμάτων';
+$labels['test'] = 'Δοκιμη';
+$labels['title'] = 'Nεο Email!';
+$labels['body'] = 'Έχετε λάβει ένα νέο μήνυμα.';
+$labels['testbody'] = 'Αυτή είναι μια δοκιμή ειδοποίησης.';
+$labels['desktopdisabled'] = 'Οι κοινοποιήσεις Desktop ειναι απενεÏγοποιημένη στον πεÏιηγητή σας.';
+$labels['desktopunsupported'] = 'Ο πεÏιηγητής σας δεν υποστηÏίζει ειδοποιήσεις στην επιφάνεια εÏγασίας.';
+?>
diff --git a/plugins/newmail_notifier/localization/en_US.inc b/plugins/newmail_notifier/localization/en_US.inc
index 7c1c5cf3f..da8340b80 100644
--- a/plugins/newmail_notifier/localization/en_US.inc
+++ b/plugins/newmail_notifier/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/newmail_notifier/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail New Mail Notifier plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/newmail_notifier/localization/es_AR.inc b/plugins/newmail_notifier/localization/es_AR.inc
new file mode 100644
index 000000000..682d79ef4
--- /dev/null
+++ b/plugins/newmail_notifier/localization/es_AR.inc
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/newmail_notifier/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New Mail Notifier plugin |
+ | Copyright (C) 2012-2013, 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/plugin-newmail_notifier/
+*/
+$labels['basic'] = 'Mostrar notificación cuando haya nuevos mensajes';
+$labels['desktop'] = 'Mostrar notificación en escritorio cuando haya nuevos mensajes';
+$labels['sound'] = 'Reproducir sonido cuando haya nuevos mensajes';
+$labels['test'] = 'Prueba';
+$labels['title'] = 'Correo nuevo!';
+$labels['body'] = 'Has recibido correo nuevo';
+$labels['testbody'] = 'Esta es una notificación de prueba';
+$labels['desktopdisabled'] = 'Las notificaciones en escritorio están deshabilitadas en tu navegador';
+$labels['desktopunsupported'] = 'Tu navegador no soporta notificaciones en escritorio';
+?>
diff --git a/plugins/newmail_notifier/localization/eu_ES.inc b/plugins/newmail_notifier/localization/eu_ES.inc
new file mode 100644
index 000000000..7d7d90408
--- /dev/null
+++ b/plugins/newmail_notifier/localization/eu_ES.inc
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/newmail_notifier/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New Mail Notifier plugin |
+ | Copyright (C) 2012-2013, 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/plugin-newmail_notifier/
+*/
+$labels['basic'] = 'Bistaratu nabigatzailearen jakinarazpenak mezu berrian';
+$labels['desktop'] = 'Bistaratu sistemaren jakinarazpenak mezu berrian';
+$labels['sound'] = 'Jo soinu bat mezu berriarekin';
+$labels['test'] = 'Testa';
+$labels['title'] = 'ePosta berria';
+$labels['body'] = 'Mezu berria jaso duzu';
+$labels['testbody'] = 'Hau jakinarazpen proba bat da';
+$labels['desktopdisabled'] = 'Sistemaren jakinarazpenak ezgaituak daude zure nabigatzailean';
+$labels['desktopunsupported'] = 'Zure nabigatzaileak ez ditu sistemaren jakinarazpenak onartzen.';
+?>
diff --git a/plugins/newmail_notifier/localization/lb_LU.inc b/plugins/newmail_notifier/localization/lb_LU.inc
index c4b014819..8e6f5f603 100644
--- a/plugins/newmail_notifier/localization/lb_LU.inc
+++ b/plugins/newmail_notifier/localization/lb_LU.inc
@@ -15,7 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/
*/
-
$labels['basic'] = 'Browser-Notifikatioun bei neiem Message uweisen';
$labels['desktop'] = 'Desktop-Notifikatioun bei neiem Message uweisen';
$labels['sound'] = 'Dësen Toun bei neiem Message spillen';
@@ -25,5 +24,5 @@ $labels['body'] = 'Du hues en neie Message kritt.';
$labels['testbody'] = 'Dëst ass eng Test-Benoorichtegung.';
$labels['desktopdisabled'] = 'Desktop-Notifikatioune sinn an dengem Browser ausgeschalt.';
$labels['desktopunsupported'] = 'Däi Browser ënnerstëtzt keng Desktop-Notifikatiounen.';
-
+$labels['desktoptimeout'] = 'Browser-Notifikatioun zoumaachen';
?>
diff --git a/plugins/newmail_notifier/localization/lv_LV.inc b/plugins/newmail_notifier/localization/lv_LV.inc
index da9603cd5..9df738b25 100644
--- a/plugins/newmail_notifier/localization/lv_LV.inc
+++ b/plugins/newmail_notifier/localization/lv_LV.inc
@@ -16,14 +16,14 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/
*/
-$labels['basic'] = 'Saņemot jaunu vÄ“stuli, parÄdÄ«t paziņojumu';
-$labels['desktop'] = 'Saņemot jaunu vÄ“stuli, parÄdÄ«t darbavirsmas paziņojumu';
-$labels['sound'] = 'Saņemot jaunu vÄ“stuli, atskaņot skaņas signÄlu';
-$labels['test'] = 'PÄrbaudÄ«t';
-$labels['title'] = 'Jauns e-pasts!';
-$labels['body'] = 'Jūs esat saņēmis jaunu vēstuli.';
+$labels['basic'] = 'Attēlot paziņojumu pie jaunas vēstules saņemšanas';
+$labels['desktop'] = 'Attēlot darbvirsmas paziņojumu pie jaunas vēstules saņemšanas';
+$labels['sound'] = 'Atskaņot skaņas signÄlu pie jaunas vÄ“stules saņemÅ¡anas';
+$labels['test'] = 'Test';
+$labels['title'] = 'Jauns E-pasts!';
+$labels['body'] = 'Jūs esat saņēmis jaunu e-pastu.';
$labels['testbody'] = 'Šis ir testa paziņojums.';
-$labels['desktopdisabled'] = 'Darbavirsmas paziņojumi JÅ«su pÄrlÅ«kprogrammÄ ir atslÄ“gti.';
-$labels['desktopunsupported'] = 'JÅ«su pÄrlÅ«kprogramma neatbalsta darbavirsmas paziņojumus.';
+$labels['desktopdisabled'] = 'Darbvirsmas paziņojumi ir atslÄ“gti JÅ«su pÄrlÅ«kprogrammÄ.';
+$labels['desktopunsupported'] = 'JÅ«su pÄrlÅ«kprogramma neatbalsta darbvirsmas paziņojumus.';
?>
diff --git a/plugins/newmail_notifier/localization/ro_RO.inc b/plugins/newmail_notifier/localization/ro_RO.inc
index c78c7e081..b27e506ab 100644
--- a/plugins/newmail_notifier/localization/ro_RO.inc
+++ b/plugins/newmail_notifier/localization/ro_RO.inc
@@ -19,11 +19,11 @@
$labels['basic'] = 'Afişează notificări în browser la mesaj nou.';
$labels['desktop'] = 'Afişează notificări desktop la mesaj nou.';
$labels['sound'] = 'Redă un sunet la mesaj nou.';
-$labels['test'] = 'Test';
+$labels['test'] = 'Testează';
$labels['title'] = 'E-mail nou!';
$labels['body'] = 'Ai primit un mesaj nou.';
$labels['testbody'] = 'Aceasta este o notificare de test.';
$labels['desktopdisabled'] = 'Notificările desktop sunt dezactivate în browser.';
-$labels['desktopunsupported'] = 'Browser-ul nu suportă notificări desktop.';
+$labels['desktopunsupported'] = 'Browser-ul dumneavoastră nu suportă notificări desktop.';
?>
diff --git a/plugins/newmail_notifier/localization/ti.inc b/plugins/newmail_notifier/localization/ti.inc
new file mode 100644
index 000000000..17b8e7361
--- /dev/null
+++ b/plugins/newmail_notifier/localization/ti.inc
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/newmail_notifier/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail New Mail Notifier plugin |
+ | Copyright (C) 2012-2013, 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/plugin-newmail_notifier/
+*/
+$labels['basic'] = 'ሓዱሽ መሠእኽቲ ጠቆáˆá‰² አብ ጎስጓሲ ይርአ';
+$labels['desktop'] = 'ሓዱሽ መሠእኽቲ ጠቆáˆá‰² ኣብ ደስክቶᕠይርአ';
+$labels['sound'] = 'ሓዱሽ መሠእኽቲ áˆáˆµá‹áˆ˜áŒ½áŠ¥ ድáˆáŒº ይሰማዕ';
+$labels['test'] = 'áˆá‰°áŠ';
+$labels['title'] = 'ሓድሽ ኢደብዳበ!';
+$labels['body'] = 'ሓድሽ ኢደብዳበ በጺሑ አሎ::';
+$labels['testbody'] = 'እዚ ጥቆማ ንáˆá‰°áŠ• á‹á‰°áŒˆá‰¥áˆ¨ እዩ::';
+$labels['desktopdisabled'] = 'ናይ ደስክቶᕠጠቆáˆá‰² ተኸáˆáŠªáˆŽáˆ› አለዉ::';
+$labels['desktopunsupported'] = 'እዚ ጎስጓሲ ናይ ደስክቶᕠጠቆáˆá‰² ኣይተገጠመሉን::';
+?>
diff --git a/plugins/newmail_notifier/newmail_notifier.js b/plugins/newmail_notifier/newmail_notifier.js
index b00f33d10..45238eb56 100644
--- a/plugins/newmail_notifier/newmail_notifier.js
+++ b/plugins/newmail_notifier/newmail_notifier.js
@@ -34,13 +34,6 @@ function newmail_notifier_stop(prop)
$('<link rel="shortcut icon" href="'+rcmail.env.favicon_href+'"/>').replaceAll('link[rel="shortcut icon"]');
rcmail.env.favicon_changed = 0;
}
-
- // Remove IE icon overlay if we're pinned to Taskbar
- try {
- if(window.external.msIsSiteMode()) {
- window.external.msSiteModeClearIconOverlay();
- }
- } catch(e) {}
}
// Basic notification: window.focus and favicon change
@@ -59,13 +52,6 @@ function newmail_notifier_basic()
rcmail.env.favicon_changed = 1;
link.replaceAll(oldlink);
-
- // Add IE icon overlay if we're pinned to Taskbar
- try {
- if (window.external.msIsSiteMode()) {
- window.external.msSiteModeSetIconOverlay('plugins/newmail_notifier/overlay.ico', rcmail.gettext('title', 'newmail_notifier'));
- }
- } catch(e) {}
}
// Sound notification
@@ -86,79 +72,44 @@ function newmail_notifier_sound()
}
}
-// Desktop notification
-// - Require Chrome or Firefox latest version (22+) / 21.0 or older with a plugin
+// Desktop notification (need Chrome or Firefox with a plugin)
function newmail_notifier_desktop(body)
{
-
-/**
- * Fix: As of 17 June 2013, Chrome/Chromium does not implement Notification.permission correctly that
- * it gives 'undefined' until an object has been created:
- * https://code.google.com/p/chromium/issues/detail?id=163226
- *
- */
- try {
- if (Notification.permission == 'granted' || Notification.permission == undefined) {
- var popup = new Notification(rcmail.gettext('title', 'newmail_notifier'), {
- dir: "auto",
- lang: "",
- body: body,
- tag: "newmail_notifier",
- icon: "plugins/newmail_notifier/mail.png",
- });
- popup.onclick = function() {
- this.close();
- }
- setTimeout(function() { popup.close(); }, 10000); // close after 10 seconds
- if (popup.permission == 'granted') return true;
- }
- }
- catch (e) {
- var dn = window.webkitNotifications;
-
- if (dn && !dn.checkPermission()) {
- if (rcmail.newmail_popup)
- rcmail.newmail_popup.cancel();
- var popup = window.webkitNotifications.createNotification('plugins/newmail_notifier/mail.png',
- rcmail.gettext('title', 'newmail_notifier'), body);
- popup.onclick = function() {
- this.cancel();
- }
- popup.show();
- setTimeout(function() { popup.cancel(); }, 10000); // close after 10 seconds
- rcmail.newmail_popup = popup;
- return true;
+ var dn = window.webkitNotifications;
+
+ if (dn && !dn.checkPermission()) {
+ if (rcmail.newmail_popup)
+ rcmail.newmail_popup.cancel();
+ var popup = window.webkitNotifications.createNotification('plugins/newmail_notifier/mail.png',
+ rcmail.gettext('title', 'newmail_notifier'), body);
+ popup.onclick = function() {
+ this.cancel();
}
+ popup.show();
+ setTimeout(function() { popup.cancel(); }, 10000); // close after 10 seconds
+ rcmail.newmail_popup = popup;
+ return true;
}
+
return false;
}
function newmail_notifier_test_desktop()
{
- var txt = rcmail.gettext('testbody', 'newmail_notifier');
+ var dn = window.webkitNotifications,
+ txt = rcmail.gettext('testbody', 'newmail_notifier');
- // W3C draft implementation (with fix for Chrome/Chromium)
- try {
- var testNotification = new window.Notification(txt, {tag: "newmail_notifier"}); // Try to show a test message
- if (Notification.permission !== 'granted' || (testNotification.permission && testNotification.permission !== 'granted'))
- newmail_notifier_desktop_authorize();
- }
- // webkit implementation
- catch (e) {
- var dn = window.webkitNotifications;
- if (dn) {
- if (!dn.checkPermission())
- newmail_notifier_desktop(txt);
- else
- dn.requestPermission(function() {
- if (!newmail_notifier_desktop(txt))
- rcmail.display_message(rcmail.gettext('desktopdisabled', 'newmail_notifier'), 'error');
- });
- }
+ if (dn) {
+ if (!dn.checkPermission())
+ newmail_notifier_desktop(txt);
else
- // Everything fails, means the browser has no support
- rcmail.display_message(rcmail.gettext('desktopunsupported', 'newmail_notifier'), 'error');
+ dn.requestPermission(function() {
+ if (!newmail_notifier_desktop(txt))
+ rcmail.display_message(rcmail.gettext('desktopdisabled', 'newmail_notifier'), 'error');
+ });
}
+ else
+ rcmail.display_message(rcmail.gettext('desktopunsupported', 'newmail_notifier'), 'error');
}
function newmail_notifier_test_basic()
@@ -170,12 +121,3 @@ function newmail_notifier_test_sound()
{
newmail_notifier_sound();
}
-
-function newmail_notifier_desktop_authorize() {
- Notification.requestPermission(function(perm) {
- if (perm == 'denied')
- rcmail.display_message(rcmail.gettext('desktopdisabled', 'newmail_notifier'), 'error');
- if (perm == 'granted')
- newmail_notifier_test_desktop(); // Test again, which should show test message
- });
-}
diff --git a/plugins/newmail_notifier/newmail_notifier.php b/plugins/newmail_notifier/newmail_notifier.php
index ca1c2ff67..2c7ba949d 100644
--- a/plugins/newmail_notifier/newmail_notifier.php
+++ b/plugins/newmail_notifier/newmail_notifier.php
@@ -15,18 +15,18 @@
*
* Copyright (C) 2011, Kolab Systems AG
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class newmail_notifier extends rcube_plugin
@@ -35,9 +35,6 @@ class newmail_notifier extends rcube_plugin
private $rc;
private $notified;
- private $opt = array();
- private $exceptions = array();
-
/**
* Plugin initialization
@@ -52,34 +49,13 @@ class newmail_notifier extends rcube_plugin
$this->add_hook('preferences_save', array($this, 'prefs_save'));
}
else { // if ($this->rc->task == 'mail') {
+ $this->add_hook('new_messages', array($this, 'notify'));
// add script when not in ajax and not in frame
if ($this->rc->output->type == 'html' && empty($_REQUEST['_framed'])) {
$this->add_texts('localization/');
$this->rc->output->add_label('newmail_notifier.title', 'newmail_notifier.body');
$this->include_script('newmail_notifier.js');
}
-
- if ($this->rc->action == 'refresh') {
- // Load configuration
- $this->load_config();
-
- $this->opt['basic'] = $this->rc->config->get('newmail_notifier_basic');
- $this->opt['sound'] = $this->rc->config->get('newmail_notifier_sound');
- $this->opt['desktop'] = $this->rc->config->get('newmail_notifier_desktop');
-
- if (!empty($this->opt)) {
- // Get folders to skip checking for
- $exceptions = array('drafts_mbox', 'sent_mbox', 'trash_mbox');
- foreach ($exceptions as $folder) {
- $folder = $this->rc->config->get($folder);
- if (strlen($folder) && $folder != 'INBOX') {
- $this->exceptions[] = $folder;
- }
- }
-
- $this->add_hook('new_messages', array($this, 'notify'));
- }
- }
}
}
@@ -117,7 +93,7 @@ class newmail_notifier extends rcube_plugin
$this->gettext('test'));
$args['blocks']['new_message']['options'][$key] = array(
- 'title' => html::label($field_id, rcube::Q($this->gettext($type))),
+ 'title' => html::label($field_id, Q($this->gettext($type))),
'content' => $content
);
}
@@ -144,7 +120,7 @@ class newmail_notifier extends rcube_plugin
foreach (array('basic', 'desktop', 'sound') as $type) {
$key = 'newmail_notifier_' . $type;
if (!in_array($key, $dont_override)) {
- $args['prefs'][$key] = rcube_utils::get_input_value('_'.$key, rcube_utils::INPUT_POST) ? true : false;
+ $args['prefs'][$key] = get_input_value('_'.$key, RCUBE_INPUT_POST) ? true : false;
}
}
@@ -156,36 +132,45 @@ class newmail_notifier extends rcube_plugin
*/
function notify($args)
{
- // Already notified or unexpected input
- if ($this->notified || empty($args['diff']['new'])) {
+ // Already notified or non-automatic check
+ if ($this->notified || !empty($_GET['_refresh'])) {
return $args;
}
- $mbox = $args['mailbox'];
- $storage = $this->rc->get_storage();
- $delimiter = $storage->get_hierarchy_delimiter();
+ // Get folders to skip checking for
+ if (empty($this->exceptions)) {
+ $this->delimiter = $this->rc->storage->get_hierarchy_delimiter();
+
+ $exceptions = array('drafts_mbox', 'sent_mbox', 'trash_mbox');
+ foreach ($exceptions as $folder) {
+ $folder = $this->rc->config->get($folder);
+ if (strlen($folder) && $folder != 'INBOX') {
+ $this->exceptions[] = $folder;
+ }
+ }
+ }
+
+ $mbox = $args['mailbox'];
// Skip exception (sent/drafts) folders (and their subfolders)
foreach ($this->exceptions as $folder) {
- if (strpos($mbox.$delimiter, $folder.$delimiter) === 0) {
+ if (strpos($mbox.$this->delimiter, $folder.$this->delimiter) === 0) {
return $args;
}
}
- // Check if any of new messages is UNSEEN
- $deleted = $this->rc->config->get('skip_deleted') ? 'UNDELETED ' : '';
- $search = $deleted . 'UNSEEN UID ' . $args['diff']['new'];
- $unseen = $storage->search_once($mbox, $search);
+ $this->notified = true;
+
+ // Load configuration
+ $this->load_config();
- if ($unseen->count()) {
- $this->notified = true;
+ $basic = $this->rc->config->get('newmail_notifier_basic');
+ $sound = $this->rc->config->get('newmail_notifier_sound');
+ $desktop = $this->rc->config->get('newmail_notifier_desktop');
+ if ($basic || $sound || $desktop) {
$this->rc->output->command('plugin.newmail_notifier',
- array(
- 'basic' => $this->opt['basic'],
- 'sound' => $this->opt['sound'],
- 'desktop' => $this->opt['desktop'],
- ));
+ array('basic' => $basic, 'sound' => $sound, 'desktop' => $desktop));
}
return $args;
diff --git a/plugins/newmail_notifier/package.xml b/plugins/newmail_notifier/package.xml
index b8ef34933..d3de25fb3 100644
--- a/plugins/newmail_notifier/package.xml
+++ b/plugins/newmail_notifier/package.xml
@@ -19,16 +19,16 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
- <date>2013-03-16</date>
+ <date>2012-02-07</date>
<version>
- <release>0.5</release>
- <api>0.5</api>
+ <release>0.4</release>
+ <api>0.3</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/newmail_notifier/sound.mp3 b/plugins/newmail_notifier/sound.mp3
new file mode 100644
index 000000000..3b494a94d
--- /dev/null
+++ b/plugins/newmail_notifier/sound.mp3
Binary files differ
diff --git a/plugins/password/README b/plugins/password/README
index 262ebfd86..ef6f5b428 100644
--- a/plugins/password/README
+++ b/plugins/password/README
@@ -1,29 +1,31 @@
-----------------------------------------------------------------------
Password Plugin for Roundcube
-----------------------------------------------------------------------
+
Plugin that adds a possibility to change user password using many
methods (drivers) via Settings/Password tab.
+
-----------------------------------------------------------------------
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see http://www.gnu.org/licenses/.
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@version @package_version@
- @author Aleksander Machniak <alec@alec.pl>
+ @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
@author <see driver files for driver authors>
-----------------------------------------------------------------------
- 1. Configuration
- 2. Drivers
+ 1. Configuration
+ 2. Drivers
2.1. Database (sql)
2.2. Cyrus/SASL (sasl)
2.3. Poppassd/Courierpassd (poppassd)
@@ -42,8 +44,7 @@
2.16. DBMail (dbmail)
2.17. Expect (expect)
2.18. Samba (smb)
- 2.19. Vpopmail daemon (vpopmaild)
- 3. Driver API
+ 3. Driver API
1. Configuration
@@ -64,40 +65,40 @@
-------------------
You can specify which database to connect by 'password_db_dsn' option and
- what SQL query to execute by 'password_query'. See config.inc.php.dist file for
+ what SQL query to execute by 'password_query'. See main.inc.php.dist file for
more info.
Example implementations of an update_passwd function:
- This is for use with LMS (http://lms.org.pl) database and postgres:
- CREATE OR REPLACE FUNCTION update_passwd(hash text, account text) RETURNS integer AS $$
- DECLARE
- res integer;
- BEGIN
- UPDATE passwd SET password = hash
- WHERE login = split_part(account, '@', 1)
- AND domainid = (SELECT id FROM domains WHERE name = split_part(account, '@', 2))
- RETURNING id INTO res;
- RETURN res;
- END;
- $$ LANGUAGE plpgsql SECURITY DEFINER;
+ CREATE OR REPLACE FUNCTION update_passwd(hash text, account text) RETURNS integer AS $$
+ DECLARE
+ res integer;
+ BEGIN
+ UPDATE passwd SET password = hash
+ WHERE login = split_part(account, '@', 1)
+ AND domainid = (SELECT id FROM domains WHERE name = split_part(account, '@', 2))
+ RETURNING id INTO res;
+ RETURN res;
+ END;
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
- This is for use with a SELECT update_passwd(%o,%c,%u) query
- Updates the password only when the old password matches the MD5 password
- in the database
-
- CREATE FUNCTION update_password (oldpass text, cryptpass text, user text) RETURNS text
- MODIFIES SQL DATA
- BEGIN
- DECLARE currentsalt varchar(20);
- DECLARE error text;
- SET error = 'incorrect current password';
- SELECT substring_index(substr(user.password,4),_latin1'$',1) INTO currentsalt FROM users WHERE username=user;
- SELECT '' INTO error FROM users WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
- UPDATE users SET password=cryptpass WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
- RETURN error;
- END
+ Updates the password only when the old password matches the MD5 password
+ in the database
+
+ CREATE FUNCTION update_password (oldpass text, cryptpass text, user text) RETURNS text
+ MODIFIES SQL DATA
+ BEGIN
+ DECLARE currentsalt varchar(20);
+ DECLARE error text;
+ SET error = 'incorrect current password';
+ SELECT substring_index(substr(user.password,4),_latin1'$',1) INTO currentsalt FROM users WHERE username=user;
+ SELECT '' INTO error FROM users WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+ UPDATE users SET password=cryptpass WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+ RETURN error;
+ END
Example SQL UPDATEs:
@@ -137,11 +138,12 @@
Installation:
- Change into the helpers directory. Edit the chgsaslpasswd.c file as is
+ Change into the helpers directory. Copy and edit
+ /usr/share/roundcube-plugins/examples/chgsaslpasswd.c as is
documented within it.
Compile the wrapper program:
- gcc -o chgsaslpasswd chgsaslpasswd.c
+ gcc -o chgsaslpasswd chgsaslpasswd.c
Chown the compiled chgsaslpasswd binary to the cyrus user and group
that your browser runs as, then chmod them to 4550.
@@ -149,13 +151,13 @@
For example, if your cyrus user is 'cyrus' and the apache server group is
'nobody' (I've been told Redhat runs Apache as user 'apache'):
- chown cyrus:nobody chgsaslpasswd
- chmod 4550 chgsaslpasswd
+ chown cyrus:nobody chgsaslpasswd
+ chmod 4550 chgsaslpasswd
Stephen Carr has suggested users should try to run the scripts on a test
account as the cyrus user eg;
- su cyrus -c "./chgsaslpasswd -p test_account"
+ su cyrus -c "./chgsaslpasswd -p test_account"
This will allow you to make sure that the script will work for your setup.
Should the script not work, make sure that:
@@ -191,12 +193,8 @@
2.6. cPanel (cpanel)
--------------------
- Install cPanel XMLAPI Client Class into Roundcube program/lib directory
- or any other place in PHP include path. You can get the class from
- https://raw.github.com/CpanelInc/xmlapi-php/master/xmlapi.php
-
- You can configure parameters for connection to cPanel's API interface.
- See config.inc.php.dist file for more info.
+ You can specify parameters for HTTP connection to cPanel's admin
+ interface. See config.inc.php.dist file for more info.
2.7. XIMSS/Communigate (ximms)
@@ -210,7 +208,8 @@
----------------------------
As in sasl driver this one allows to change password using shell
- utility called "virtualmin". See helpers/chgvirtualminpasswd.c for
+ utility called "virtualmin". See
+ /usr/share/doc/roundcube-plugins/examples/chgvirtualminpasswd.c for
installation instructions. See also config.inc.php.dist file.
@@ -235,8 +234,9 @@
Driver that adds functionality to change the systems user password via
the 'chpasswd' command. See config.inc.php.dist file.
- Attached wrapper script (helpers/chpass-wrapper.py) restricts password changes
- to uids >= 1000 and can deny requests based on a blacklist.
+ Attached wrapper script
+ (/usr/share/doc/roundcube-plugins/examples/chpass-wrapper.py) restricts
+ password changes to uids >= 1000 and can deny requests based on a blacklist.
2.12. LDAP - no PEAR (ldap_simple)
@@ -247,7 +247,7 @@
This driver is fully compatible with the ldap driver, but
does not require (or uses) the
- $config['password_ldap_force_replace'] variable.
+ $rcmail_config['password_ldap_force_replace'] variable.
Other advantages:
* Connects only once with the LDAP server when using the search user.
* Does not read the DN, but only replaces the password within (that is
@@ -300,16 +300,6 @@
Driver to change Samba user password via the 'smbpasswd' command.
See config.inc.php.dist file for configuration description.
- 2.19. Vpopmail daemon (vpopmaild)
- -----------------------------------
-
- Driver for the daemon of vpopmail. Vpopmail is used with qmail to
- enable virtual users that are saved in a database and not in /etc/passwd.
-
- Set $config['password_vpopmaild_host'] to the host where vpopmaild runs.
-
- Set $config['password_vpopmaild_port'] to the port of vpopmaild.
-
3. Driver API
-------------
diff --git a/plugins/password/config.inc.php.dist b/plugins/password/config.inc.php.dist
index 82f6617e5..a40e2a93f 100644
--- a/plugins/password/config.inc.php.dist
+++ b/plugins/password/config.inc.php.dist
@@ -4,43 +4,39 @@
// -----------------------
// A driver to use for password change. Default: "sql".
// See README file for list of supported driver names.
-$config['password_driver'] = 'sql';
+$rcmail_config['password_driver'] = 'sql';
// Determine whether current password is required to change password.
// Default: false.
-$config['password_confirm_current'] = true;
+$rcmail_config['password_confirm_current'] = true;
// Require the new password to be a certain length.
// set to blank to allow passwords of any length
-$config['password_minimum_length'] = 0;
+$rcmail_config['password_minimum_length'] = 0;
// Require the new password to contain a letter and punctuation character
// Change to false to remove this check.
-$config['password_require_nonalpha'] = false;
+$rcmail_config['password_require_nonalpha'] = false;
// Enables logging of password changes into logs/password
-$config['password_log'] = false;
+$rcmail_config['password_log'] = false;
// Comma-separated list of login exceptions for which password change
// will be not available (no Password tab in Settings)
-$config['password_login_exceptions'] = null;
+$rcmail_config['password_login_exceptions'] = null;
// Array of hosts that support password changing. Default is NULL.
// Listed hosts will feature a Password option in Settings; others will not.
// Example:
-//$config['password_hosts'] = array('mail.example.com', 'mail2.example.org');
-$config['password_hosts'] = null;
-
-// Enables saving the new password even if it matches the old password. Useful
-// for upgrading the stored passwords after the encryption scheme has changed.
-$config['password_force_save'] = false;
+//$rcmail_config['password_hosts'] = array('mail.example.com', 'mail2.example.org');
+$rcmail_config['password_hosts'] = null;
// SQL Driver options
// ------------------
// PEAR database DSN for performing the query. By default
// Roundcube DB settings are used.
-$config['password_db_dsn'] = '';
+$rcmail_config['password_db_dsn'] = '';
// The SQL query used to change the password.
// The query can contain the following macros that will be expanded as follows:
@@ -60,52 +56,52 @@ $config['password_db_dsn'] = '';
// (in case the username is an email address)
// Escaping of macros is handled by this module.
// Default: "SELECT update_passwd(%c, %u)"
-$config['password_query'] = 'SELECT update_passwd(%c, %u)';
+$rcmail_config['password_query'] = 'SELECT update_passwd(%c, %u)';
// By default the crypt() function which is used to create the '%c'
// parameter uses the md5 algorithm. To use different algorithms
// you can choose between: des, md5, blowfish, sha256, sha512.
// Before using other hash functions than des or md5 please make sure
// your operating system supports the other hash functions.
-$config['password_crypt_hash'] = 'md5';
+$rcmail_config['password_crypt_hash'] = 'md5';
// By default domains in variables are using unicode.
// Enable this option to use punycoded names
-$config['password_idn_ascii'] = false;
+$rcmail_config['password_idn_ascii'] = false;
// Path for dovecotpw (if not in $PATH)
-// $config['password_dovecotpw'] = '/usr/local/sbin/dovecotpw';
+// $rcmail_config['password_dovecotpw'] = '/usr/local/sbin/dovecotpw';
// Dovecot method (dovecotpw -s 'method')
-$config['password_dovecotpw_method'] = 'CRAM-MD5';
+$rcmail_config['password_dovecotpw_method'] = 'CRAM-MD5';
// Enables use of password with crypt method prefix in %D, e.g. {MD5}$1$LUiMYWqx$fEkg/ggr/L6Mb2X7be4i1/
-$config['password_dovecotpw_with_method'] = false;
+$rcmail_config['password_dovecotpw_with_method'] = false;
// Using a password hash for %n and %q variables.
// Determine which hashing algorithm should be used to generate
// the hashed new and current password for using them within the
// SQL query. Requires PHP's 'hash' extension.
-$config['password_hash_algorithm'] = 'sha1';
+$rcmail_config['password_hash_algorithm'] = 'sha1';
// You can also decide whether the hash should be provided
// as hex string or in base64 encoded format.
-$config['password_hash_base64'] = false;
+$rcmail_config['password_hash_base64'] = false;
// Poppassd Driver options
// -----------------------
// The host which changes the password
-$config['password_pop_host'] = 'localhost';
+$rcmail_config['password_pop_host'] = 'localhost';
// TCP port used for poppassd connections
-$config['password_pop_port'] = 106;
+$rcmail_config['password_pop_port'] = 106;
// SASL Driver options
// -------------------
// Additional arguments for the saslpasswd2 call
-$config['password_saslpasswd_args'] = '';
+$rcmail_config['password_saslpasswd_args'] = '';
// LDAP and LDAP_SIMPLE Driver options
@@ -114,41 +110,41 @@ $config['password_saslpasswd_args'] = '';
// You can provide one or several hosts in an array in which case the hosts are tried from left to right.
// Exemple: array('ldap1.exemple.com', 'ldap2.exemple.com');
// Default: 'localhost'
-$config['password_ldap_host'] = 'localhost';
+$rcmail_config['password_ldap_host'] = 'localhost';
// LDAP server port to connect to
// Default: '389'
-$config['password_ldap_port'] = '389';
+$rcmail_config['password_ldap_port'] = '389';
// TLS is started after connecting
// Using TLS for password modification is recommanded.
// Default: false
-$config['password_ldap_starttls'] = false;
+$rcmail_config['password_ldap_starttls'] = false;
// LDAP version
// Default: '3'
-$config['password_ldap_version'] = '3';
+$rcmail_config['password_ldap_version'] = '3';
// LDAP base name (root directory)
// Exemple: 'dc=exemple,dc=com'
-$config['password_ldap_basedn'] = 'dc=exemple,dc=com';
+$rcmail_config['password_ldap_basedn'] = 'dc=exemple,dc=com';
// LDAP connection method
// There is two connection method for changing a user's LDAP password.
// 'user': use user credential (recommanded, require password_confirm_current=true)
// 'admin': use admin credential (this mode require password_ldap_adminDN and password_ldap_adminPW)
// Default: 'user'
-$config['password_ldap_method'] = 'user';
+$rcmail_config['password_ldap_method'] = 'user';
// LDAP Admin DN
// Used only in admin connection mode
// Default: null
-$config['password_ldap_adminDN'] = null;
+$rcmail_config['password_ldap_adminDN'] = null;
// LDAP Admin Password
// Used only in admin connection mode
// Default: null
-$config['password_ldap_adminPW'] = null;
+$rcmail_config['password_ldap_adminPW'] = null;
// LDAP user DN mask
// The user's DN is mandatory and as we only have his login,
@@ -158,7 +154,7 @@ $config['password_ldap_adminPW'] = null;
// '%domain' will be replaced by the current roundcube user's domain part
// '%dc' will be replaced by domain name hierarchal string e.g. "dc=test,dc=domain,dc=com"
// Exemple: 'uid=%login,ou=people,dc=exemple,dc=com'
-$config['password_ldap_userDN_mask'] = 'uid=%login,ou=people,dc=exemple,dc=com';
+$rcmail_config['password_ldap_userDN_mask'] = 'uid=%login,ou=people,dc=exemple,dc=com';
// LDAP search DN
// The DN roundcube should bind with to find out user's DN
@@ -169,7 +165,7 @@ $config['password_ldap_userDN_mask'] = 'uid=%login,ou=people,dc=exemple,dc=com';
// users login to find his DN instead. A common reason might be that
// your users are placed under different ou's like engineering or
// sales which cannot be derived from their login only.
-$config['password_ldap_searchDN'] = 'cn=roundcube,ou=services,dc=example,dc=com';
+$rcmail_config['password_ldap_searchDN'] = 'cn=roundcube,ou=services,dc=example,dc=com';
// LDAP search password
// If password_ldap_searchDN is set, the password to use for
@@ -179,13 +175,13 @@ $config['password_ldap_searchDN'] = 'cn=roundcube,ou=services,dc=example,dc=com'
// is only accesible to roundcube and don't forget to restrict roundcube's access to
// your directory as much as possible using ACLs. Should this password be compromised
// you want to minimize the damage.
-$config['password_ldap_searchPW'] = 'secret';
+$rcmail_config['password_ldap_searchPW'] = 'secret';
// LDAP search base
// If password_ldap_searchDN is set, the base to search in using the filter below.
// Note that you should comment out the default password_ldap_userDN_mask setting
// for this to take effect.
-$config['password_ldap_search_base'] = 'ou=people,dc=example,dc=com';
+$rcmail_config['password_ldap_search_base'] = 'ou=people,dc=example,dc=com';
// LDAP search filter
// If password_ldap_searchDN is set, the filter to use when
@@ -197,7 +193,7 @@ $config['password_ldap_search_base'] = 'ou=people,dc=example,dc=com';
// '%dc' will be replaced by domain name hierarchal string e.g. "dc=test,dc=domain,dc=com"
// Example: '(uid=%login)'
// Example: '(&(objectClass=posixAccount)(uid=%login))'
-$config['password_ldap_search_filter'] = '(uid=%login)';
+$rcmail_config['password_ldap_search_filter'] = '(uid=%login)';
// LDAP password hash type
// Standard LDAP encryption type which must be one of: crypt,
@@ -205,34 +201,34 @@ $config['password_ldap_search_filter'] = '(uid=%login)';
// Please note that most encodage types require external libraries
// to be included in your PHP installation, see function hashPassword in drivers/ldap.php for more info.
// Default: 'crypt'
-$config['password_ldap_encodage'] = 'crypt';
+$rcmail_config['password_ldap_encodage'] = 'crypt';
// LDAP password attribute
// Name of the ldap's attribute used for storing user password
// Default: 'userPassword'
-$config['password_ldap_pwattr'] = 'userPassword';
+$rcmail_config['password_ldap_pwattr'] = 'userPassword';
// LDAP password force replace
// Force LDAP replace in cases where ACL allows only replace not read
// See http://pear.php.net/package/Net_LDAP2/docs/latest/Net_LDAP2/Net_LDAP2_Entry.html#methodreplace
// Default: true
-$config['password_ldap_force_replace'] = true;
+$rcmail_config['password_ldap_force_replace'] = true;
// LDAP Password Last Change Date
// Some places use an attribute to store the date of the last password change
// The date is meassured in "days since epoch" (an integer value)
// Whenever the password is changed, the attribute will be updated if set (e.g. shadowLastChange)
-$config['password_ldap_lchattr'] = '';
+$rcmail_config['password_ldap_lchattr'] = '';
// LDAP Samba password attribute, e.g. sambaNTPassword
// Name of the LDAP's Samba attribute used for storing user password
-$config['password_ldap_samba_pwattr'] = '';
+$rcmail_config['password_ldap_samba_pwattr'] = '';
// LDAP Samba Password Last Change Date attribute, e.g. sambaPwdLastSet
// Some places use an attribute to store the date of the last password change
// The date is meassured in "seconds since epoch" (an integer value)
// Whenever the password is changed, the attribute will be updated if set
-$config['password_ldap_samba_lchattr'] = '';
+$rcmail_config['password_ldap_samba_lchattr'] = '';
// DirectAdmin Driver options
@@ -242,57 +238,63 @@ $config['password_ldap_samba_lchattr'] = '';
// The host can contain the following macros that will be expanded as follows:
// %h is replaced with the imap host (from the session info)
// %d is replaced with the domain part of the username (if the username is an email)
-$config['password_directadmin_host'] = 'tcp://localhost';
+$rcmail_config['password_directadmin_host'] = 'tcp://localhost';
// TCP port used for DirectAdmin connections
-$config['password_directadmin_port'] = 2222;
+$rcmail_config['password_directadmin_port'] = 2222;
// vpopmaild Driver options
// -----------------------
// The host which changes the password
-$config['password_vpopmaild_host'] = 'localhost';
+$rcmail_config['password_vpopmaild_host'] = 'localhost';
// TCP port used for vpopmaild connections
-$config['password_vpopmaild_port'] = 89;
+$rcmail_config['password_vpopmaild_port'] = 89;
// cPanel Driver options
// --------------------------
// The cPanel Host name
-$config['password_cpanel_host'] = 'host.domain.com';
+$rcmail_config['password_cpanel_host'] = 'host.domain.com';
// The cPanel admin username
-$config['password_cpanel_username'] = 'username';
+$rcmail_config['password_cpanel_username'] = 'username';
// The cPanel admin password
-$config['password_cpanel_password'] = 'password';
+$rcmail_config['password_cpanel_password'] = 'password';
// The cPanel port to use
-$config['password_cpanel_port'] = 2087;
+$rcmail_config['password_cpanel_port'] = 2082;
+
+// Using ssl for cPanel connections?
+$rcmail_config['password_cpanel_ssl'] = true;
+
+// The cPanel theme in use
+$rcmail_config['password_cpanel_theme'] = 'x';
// XIMSS (Communigate server) Driver options
// -----------------------------------------
// Host name of the Communigate server
-$config['password_ximss_host'] = 'mail.example.com';
+$rcmail_config['password_ximss_host'] = 'mail.example.com';
// XIMSS port on Communigate server
-$config['password_ximss_port'] = 11024;
+$rcmail_config['password_ximss_port'] = 11024;
// chpasswd Driver options
// ---------------------
// Command to use
-$config['password_chpasswd_cmd'] = 'sudo /usr/sbin/chpasswd 2> /dev/null';
+$rcmail_config['password_chpasswd_cmd'] = 'sudo /usr/sbin/chpasswd 2> /dev/null';
// XMail Driver options
// ---------------------
-$config['xmail_host'] = 'localhost';
-$config['xmail_user'] = 'YourXmailControlUser';
-$config['xmail_pass'] = 'YourXmailControlPass';
-$config['xmail_port'] = 6017;
+$rcmail_config['xmail_host'] = 'localhost';
+$rcmail_config['xmail_user'] = 'YourXmailControlUser';
+$rcmail_config['xmail_pass'] = 'YourXmailControlPass';
+$rcmail_config['xmail_port'] = 6017;
// hMail Driver options
@@ -300,9 +302,9 @@ $config['xmail_port'] = 6017;
// Remote hMailServer configuration
// true: HMailserver is on a remote box (php.ini: com.allow_dcom = true)
// false: Hmailserver is on same box as PHP
-$config['hmailserver_remote_dcom'] = false;
+$rcmail_config['hmailserver_remote_dcom'] = false;
// Windows credentials
-$config['hmailserver_server'] = array(
+$rcmail_config['hmailserver_server'] = array(
'Server' => 'localhost', // hostname or ip address
'Username' => 'administrator', // windows username
'Password' => 'password' // windows user password
@@ -320,8 +322,7 @@ $config['hmailserver_server'] = array(
// 5: domain-username
// 6: username_domain
// 7: domain_username
-// 8: username@domain; mbox.username
-$config['password_virtualmin_format'] = 8;
+$config['password_virtualmin_format'] = 0;
// pw_usermod Driver options
@@ -329,36 +330,32 @@ $config['password_virtualmin_format'] = 8;
// Use comma delimited exlist to disable password change for users
// Add the following line to visudo to tighten security:
// www ALL=NOPASSWORD: /usr/sbin/pw
-$config['password_pw_usermod_cmd'] = 'sudo /usr/sbin/pw usermod -h 0 -n';
+$rcmail_config['password_pw_usermod_cmd'] = 'sudo /usr/sbin/pw usermod -h 0 -n';
// DBMail Driver options
// -------------------
// Additional arguments for the dbmail-users call
-$config['password_dbmail_args'] = '-p sha512';
+$rcmail_config['password_dbmail_args'] = '-p sha512';
// Expect Driver options
// ---------------------
// Location of expect binary
-$config['password_expect_bin'] = '/usr/bin/expect';
+$rcmail_config['password_expect_bin'] = '/usr/bin/expect';
// Location of expect script (see helpers/passwd-expect)
-$config['password_expect_script'] = '';
+$rcmail_config['password_expect_script'] = '';
// Arguments for the expect script. See the helpers/passwd-expect file for details.
// This is probably a good starting default:
// -telent -host localhost -output /tmp/passwd.log -log /tmp/passwd.log
-$config['password_expect_params'] = '';
+$rcmail_config['password_expect_params'] = '';
// smb Driver options
// ---------------------
// Samba host (default: localhost)
-// 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)
-$config['password_smb_host'] = 'localhost';
+$rcmail_config['password_smb_host'] = 'localhost';
// Location of smbpasswd binary
-$config['password_smb_cmd'] = '/usr/bin/smbpasswd';
+$rcmail_config['password_smb_cmd'] = '/usr/bin/smbpasswd';
diff --git a/plugins/password/drivers/chpasswd.php b/plugins/password/drivers/chpasswd.php
index 137275e69..3ea10159c 100644
--- a/plugins/password/drivers/chpasswd.php
+++ b/plugins/password/drivers/chpasswd.php
@@ -26,7 +26,7 @@ class rcube_chpasswd_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/cpanel.php b/plugins/password/drivers/cpanel.php
index b71c33ec1..79887109b 100644
--- a/plugins/password/drivers/cpanel.php
+++ b/plugins/password/drivers/cpanel.php
@@ -4,43 +4,95 @@
* cPanel Password Driver
*
* Driver that adds functionality to change the users cPanel password.
- * Originally written by Fulvio Venturelli <fulvio@venturelli.org>
+ * The cPanel PHP API code has been taken from: http://www.phpclasses.org/browse/package/3534.html
*
- * Completely rewritten using the cPanel API2 call Email::passwdpop
- * as opposed to the original coding against the UI, which is a fragile method that
- * makes the driver to always return a failure message for any language other than English
- * see http://trac.roundcube.net/ticket/1487015
+ * This driver has been tested with Hostmonster hosting and seems to work fine.
*
- * This driver has been tested with o2switch hosting and seems to work fine.
- *
- * @version 3.0
- * @author Christian Chech <christian@chech.fr>
+ * @version 2.0
+ * @author Fulvio Venturelli <fulvio@venturelli.org>
*/
class rcube_cpanel_password
{
public function save($curpas, $newpass)
{
- require_once 'xmlapi.php';
-
$rcmail = rcmail::get_instance();
- $this->cuser = $rcmail->config->get('password_cpanel_username');
-
- // Setup the xmlapi connection
- $this->xmlapi = new xmlapi($rcmail->config->get('password_cpanel_host'));
- $this->xmlapi->set_port($rcmail->config->get('password_cpanel_port'));
- $this->xmlapi->password_auth($this->cuser, $rcmail->config->get('password_cpanel_password'));
- $this->xmlapi->set_output('json');
- $this->xmlapi->set_debug(0);
+ // Create a cPanel email object
+ $cPanel = new emailAccount($rcmail->config->get('password_cpanel_host'),
+ $rcmail->config->get('password_cpanel_username'),
+ $rcmail->config->get('password_cpanel_password'),
+ $rcmail->config->get('password_cpanel_port'),
+ $rcmail->config->get('password_cpanel_ssl'),
+ $rcmail->config->get('password_cpanel_theme'),
+ $_SESSION['username'] );
- if ($this->setPassword($_SESSION['username'], $newpass)) {
+ if ($cPanel->setPassword($newpass)) {
return PASSWORD_SUCCESS;
}
else {
return PASSWORD_ERROR;
}
}
+}
+
+
+class HTTP
+{
+ function HTTP($host, $username, $password, $port, $ssl, $theme)
+ {
+ $this->ssl = $ssl ? 'ssl://' : '';
+ $this->username = $username;
+ $this->password = $password;
+ $this->theme = $theme;
+ $this->auth = base64_encode($username . ':' . $password);
+ $this->port = $port;
+ $this->host = $host;
+ $this->path = '/frontend/' . $theme . '/';
+ }
+
+ function getData($url, $data = '')
+ {
+ $url = $this->path . $url;
+ if (is_array($data)) {
+ $url = $url . '?';
+ foreach ($data as $key => $value) {
+ $url .= urlencode($key) . '=' . urlencode($value) . '&';
+ }
+ $url = substr($url, 0, -1);
+ }
+
+ $response = '';
+ $fp = fsockopen($this->ssl . $this->host, $this->port);
+ if (!$fp) {
+ return false;
+ }
+
+ $out = 'GET ' . $url . ' HTTP/1.0' . "\r\n";
+ $out .= 'Authorization: Basic ' . $this->auth . "\r\n";
+ $out .= 'Connection: Close' . "\r\n\r\n";
+ fwrite($fp, $out);
+ while (!feof($fp)) {
+ $response .= @fgets($fp);
+ }
+ fclose($fp);
+ return $response;
+ }
+}
+
+
+class emailAccount
+{
+ function emailAccount($host, $username, $password, $port, $ssl, $theme, $address)
+ {
+ $this->HTTP = new HTTP($host, $username, $password, $port, $ssl, $theme);
+ if (strpos($address, '@')) {
+ list($this->email, $this->domain) = explode('@', $address);
+ }
+ else {
+ list($this->email, $this->domain) = array($address, '');
+ }
+ }
/**
* Change email account password
@@ -49,24 +101,16 @@ class rcube_cpanel_password
* @param string $password email account password
* @return bool
*/
- function setPassword($address, $password)
+ function setPassword($password)
{
- if (strpos($address, '@')) {
- list($data['email'], $data['domain']) = explode('@', $address);
- }
- else {
- list($data['email'], $data['domain']) = array($address, '');
- }
-
+ $data['email'] = $this->email;
+ $data['domain'] = $this->domain;
$data['password'] = $password;
+ $response = $this->HTTP->getData('mail/dopasswdpop.html', $data);
- $query = $this->xmlapi->api2_query($this->cuser, 'Email', 'passwdpop', $data);
- $query = json_decode($query, true);
-
- if ($query['cpanelresult']['data'][0]['result'] == 1) {
+ if (strpos($response, 'success') && !strpos($response, 'failure')) {
return true;
}
-
return false;
}
}
diff --git a/plugins/password/drivers/dbmail.php b/plugins/password/drivers/dbmail.php
index 529027b8d..e4c0d52e3 100644
--- a/plugins/password/drivers/dbmail.php
+++ b/plugins/password/drivers/dbmail.php
@@ -29,7 +29,7 @@ class rcube_dbmail_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/directadmin.php b/plugins/password/drivers/directadmin.php
index 44ecea406..fb156cea9 100644
--- a/plugins/password/drivers/directadmin.php
+++ b/plugins/password/drivers/directadmin.php
@@ -43,7 +43,7 @@ class rcube_directadmin_password
$response = $Socket->fetch_parsed_body();
//DEBUG
- //rcube::console("Password Plugin: [USER: $da_user] [HOST: $da_host] - Response: [SOCKET: ".$Socket->result_status_code."] [DA ERROR: ".strip_tags($response['error'])."] [TEXT: ".$response[text]."]");
+ //console("Password Plugin: [USER: $da_user] [HOST: $da_host] - Response: [SOCKET: ".$Socket->result_status_code."] [DA ERROR: ".strip_tags($response['error'])."] [TEXT: ".$response[text]."]");
if($Socket->result_status_code != 200)
return array('code' => PASSWORD_CONNECT_ERROR, 'message' => $Socket->error[0]);
@@ -297,6 +297,7 @@ class HTTPSocket {
$status = socket_get_status($socket);
$startTime = time();
$length = 0;
+ $prevSecond = 0;
while ( !feof($socket) && !$status['timed_out'] )
{
$chunk = fgets($socket,1024);
diff --git a/plugins/password/drivers/expect.php b/plugins/password/drivers/expect.php
index 1f68924df..7a191e254 100644
--- a/plugins/password/drivers/expect.php
+++ b/plugins/password/drivers/expect.php
@@ -45,7 +45,7 @@ class rcube_expect_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/hmail.php b/plugins/password/drivers/hmail.php
index 650434617..104c851ae 100644
--- a/plugins/password/drivers/hmail.php
+++ b/plugins/password/drivers/hmail.php
@@ -5,6 +5,7 @@
*
* @version 2.0
* @author Roland 'rosali' Liebl <myroundcube@mail4us.net>
+ *
*/
class rcube_hmail_password
@@ -25,8 +26,8 @@ class rcube_hmail_password
$obApp = new COM("hMailServer.Application");
}
catch (Exception $e) {
- rcube::write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage())));
- rcube::write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set.");
+ write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage())));
+ write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set.");
return PASSWORD_ERROR;
}
@@ -38,7 +39,8 @@ class rcube_hmail_password
else {
$domain = $rcmail->config->get('username_domain',false);
if (!$domain) {
- rcube::write_log('errors','Plugin password (hmail driver): $config[\'username_domain\'] is not defined.');
+ write_log('errors','Plugin password (hmail driver): $rcmail_config[\'username_domain\'] is not defined.');
+ write_log('errors','Plugin password (hmail driver): Hint: Use hmail_login plugin (http://myroundcube.googlecode.com');
return PASSWORD_ERROR;
}
$username = $username . "@" . $domain;
@@ -53,8 +55,8 @@ class rcube_hmail_password
return PASSWORD_SUCCESS;
}
catch (Exception $e) {
- rcube::write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage())));
- rcube::write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set.");
+ write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage())));
+ write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set.");
return PASSWORD_ERROR;
}
}
diff --git a/plugins/password/drivers/ldap.php b/plugins/password/drivers/ldap.php
index 548d327e1..f773335ac 100644
--- a/plugins/password/drivers/ldap.php
+++ b/plugins/password/drivers/ldap.php
@@ -271,7 +271,7 @@ class rcube_ldap_password
case 'samba':
if (function_exists('hash')) {
- $cryptedPassword = hash('md4', rcube_charset::convert($passwordClear, RCUBE_CHARSET, 'UTF-16LE'));
+ $cryptedPassword = hash('md4', rcube_charset_convert($passwordClear, RCMAIL_CHARSET, 'UTF-16LE'));
$cryptedPassword = strtoupper($cryptedPassword);
} else {
/* Your PHP install does not have the hash() function */
diff --git a/plugins/password/drivers/ldap_simple.php b/plugins/password/drivers/ldap_simple.php
index d47e14492..01385f2d0 100644
--- a/plugins/password/drivers/ldap_simple.php
+++ b/plugins/password/drivers/ldap_simple.php
@@ -240,7 +240,7 @@ class rcube_ldap_simple_password
break;
case 'samba':
if (function_exists('hash')) {
- $crypted_password = hash('md4', rcube_charset::convert($password_clear, RCUBE_CHARSET, 'UTF-16LE'));
+ $crypted_password = hash('md4', rcube_charset_convert($password_clear, RCMAIL_CHARSET, 'UTF-16LE'));
$crypted_password = strtoupper($crypted_password);
} else {
/* Your PHP install does not have the hash() function */
diff --git a/plugins/password/drivers/pam.php b/plugins/password/drivers/pam.php
index 4d0ba1656..15a802c74 100644
--- a/plugins/password/drivers/pam.php
+++ b/plugins/password/drivers/pam.php
@@ -21,7 +21,7 @@ class rcube_pam_password
}
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@@ -30,7 +30,7 @@ class rcube_pam_password
}
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/pw_usermod.php b/plugins/password/drivers/pw_usermod.php
index 237e275a7..5b92fcbfb 100644
--- a/plugins/password/drivers/pw_usermod.php
+++ b/plugins/password/drivers/pw_usermod.php
@@ -28,7 +28,7 @@ class rcube_pw_usermod_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/sasl.php b/plugins/password/drivers/sasl.php
index 8776eff2e..9380cf838 100644
--- a/plugins/password/drivers/sasl.php
+++ b/plugins/password/drivers/sasl.php
@@ -32,7 +32,7 @@ class rcube_sasl_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/smb.php b/plugins/password/drivers/smb.php
index 9f2b96afa..88021156f 100644
--- a/plugins/password/drivers/smb.php
+++ b/plugins/password/drivers/smb.php
@@ -26,15 +26,13 @@ class rcube_smb_password
public function save($currpass, $newpass)
{
- $host = rcmail::get_instance()->config->get('password_smb_host','localhost');
- $bin = rcmail::get_instance()->config->get('password_smb_cmd','/usr/bin/smbpasswd');
+ $host = rcmail::get_instance()->config->get('password_smb_host','localhost');
+ $bin = rcmail::get_instance()->config->get('password_smb_cmd','/usr/bin/smbpasswd');
$username = $_SESSION['username'];
- $host = rcube_utils::parse_host($host);
- $tmpfile = tempnam(sys_get_temp_dir(),'smb');
- $cmd = $bin . ' -r ' . $host . ' -s -U "' . $username . '" > ' . $tmpfile . ' 2>&1';
- $handle = @popen($cmd, 'w');
-
+ $tmpfile = tempnam(sys_get_temp_dir(),'smb');
+ $cmd = $bin . ' -r ' . $host . ' -s -U "' . $username . '" > ' . $tmpfile . ' 2>&1';
+ $handle = @popen($cmd, 'w');
fputs($handle, $currpass."\n");
fputs($handle, $newpass."\n");
fputs($handle, $newpass."\n");
@@ -46,7 +44,7 @@ class rcube_smb_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/sql.php b/plugins/password/drivers/sql.php
index 7a51dfe44..8c8dc87b5 100644
--- a/plugins/password/drivers/sql.php
+++ b/plugins/password/drivers/sql.php
@@ -34,9 +34,8 @@ class rcube_sql_password
$db = $rcmail->get_dbh();
}
- if ($db->is_error()) {
+ if ($err = $db->is_error())
return PASSWORD_ERROR;
- }
// crypted password
if (strpos($sql, '%c') !== FALSE) {
@@ -118,7 +117,7 @@ class rcube_sql_password
// hashed passwords
if (preg_match('/%[n|q]/', $sql)) {
if (!extension_loaded('hash')) {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@@ -165,14 +164,14 @@ class rcube_sql_password
// convert domains to/from punnycode
if ($rcmail->config->get('password_idn_ascii')) {
- $domain_part = rcube_utils::idn_to_ascii($domain_part);
- $username = rcube_utils::idn_to_ascii($username);
- $host = rcube_utils::idn_to_ascii($host);
+ $domain_part = rcube_idn_to_ascii($domain_part);
+ $username = rcube_idn_to_ascii($username);
+ $host = rcube_idn_to_ascii($host);
}
else {
- $domain_part = rcube_utils::idn_to_utf8($domain_part);
- $username = rcube_utils::idn_to_utf8($username);
- $host = rcube_utils::idn_to_utf8($host);
+ $domain_part = rcube_idn_to_utf8($domain_part);
+ $username = rcube_idn_to_utf8($username);
+ $host = rcube_idn_to_utf8($host);
}
// at least we should always have the local part
@@ -185,7 +184,7 @@ class rcube_sql_password
if (!$db->is_error()) {
if (strtolower(substr(trim($sql),0,6)) == 'select') {
- if ($db->fetch_array($res))
+ if ($result = $db->fetch_array($res))
return PASSWORD_SUCCESS;
} else {
// This is the good case: 1 row updated
diff --git a/plugins/password/drivers/virtualmin.php b/plugins/password/drivers/virtualmin.php
index 2c7aee617..40f5c2529 100644
--- a/plugins/password/drivers/virtualmin.php
+++ b/plugins/password/drivers/virtualmin.php
@@ -18,8 +18,7 @@ class rcube_virtualmin_password
{
function save($currpass, $newpass)
{
- $rcmail = rcmail::get_instance();
-
+ $rcmail = rcmail::get_instance();
$format = $rcmail->config->get('password_virtualmin_format', 0);
$username = $_SESSION['username'];
@@ -48,14 +47,14 @@ class rcube_virtualmin_password
$pieces = explode("_", $username);
$domain = $pieces[0];
break;
- case 8: // domain taken from alias, username left as it was
- $email = $rcmail->user->data['alias'];
- $domain = substr(strrchr($email, "@"), 1);
- break;
default: // username@domain
$domain = substr(strrchr($username, "@"), 1);
}
+ if (!$domain) {
+ $domain = $rcmail->user->get_username('domain');
+ }
+
$username = escapeshellcmd($username);
$domain = escapeshellcmd($domain);
$newpass = escapeshellcmd($newpass);
@@ -67,7 +66,7 @@ class rcube_virtualmin_password
return PASSWORD_SUCCESS;
}
else {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
diff --git a/plugins/password/drivers/xmail.php b/plugins/password/drivers/xmail.php
index 47beb2178..33a49ffe3 100644
--- a/plugins/password/drivers/xmail.php
+++ b/plugins/password/drivers/xmail.php
@@ -10,10 +10,10 @@
* Setup xmail_host, xmail_user, xmail_pass and xmail_port into
* config.inc.php of password plugin as follows:
*
- * $config['xmail_host'] = 'localhost';
- * $config['xmail_user'] = 'YourXmailControlUser';
- * $config['xmail_pass'] = 'YourXmailControlPass';
- * $config['xmail_port'] = 6017;
+ * $rcmail_config['xmail_host'] = 'localhost';
+ * $rcmail_config['xmail_user'] = 'YourXmailControlUser';
+ * $rcmail_config['xmail_pass'] = 'YourXmailControlPass';
+ * $rcmail_config['xmail_port'] = 6017;
*
*/
@@ -32,7 +32,7 @@ class rcube_xmail_password
$xmail->port = $rcmail->config->get('xmail_port');
if (!$xmail->connect()) {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@@ -42,7 +42,7 @@ class rcube_xmail_password
}
else if (!$xmail->send("userpasswd\t".$domain."\t".$user."\t".$newpass."\n")) {
$xmail->close();
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@@ -67,7 +67,7 @@ class XMail {
function send($msg)
{
socket_write($this->socket,$msg);
- if (substr(socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") {
+ if (substr($in = socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") {
return false;
}
return true;
@@ -85,7 +85,7 @@ class XMail {
return false;
}
- if (substr(socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") {
+ if (substr($in = socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") {
socket_close($this->socket);
return false;
}
diff --git a/plugins/password/localization/ar.inc b/plugins/password/localization/ar.inc
new file mode 100644
index 000000000..521127a8f
--- /dev/null
+++ b/plugins/password/localization/ar.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'تغيير كلمة المرور';
+$labels['curpasswd'] = 'كلمة المرور الحالية:';
+$labels['newpasswd'] = 'كلمة المرور الجديدة:';
+$labels['confpasswd'] = 'تأكيد كلمة المرور الجديدة:';
+$messages['nopassword'] = 'من Ùضلك أدخل كلمة المرور الجديدة.';
+$messages['nocurpassword'] = 'من Ùضلك أدخل كلمة المرور الحالية.';
+$messages['passwordincorrect'] = 'كلمة المرور الحالية غير صحيحة.';
+$messages['passwordinconsistency'] = 'كلمة المرور غير مطابقة حاول مجددا';
+$messages['crypterror'] = 'تعذر Ø­Ùظ كلمة المرور الجديدة. وظيÙØ© التشÙير Ù…Ùقودة.';
+$messages['connecterror'] = 'تعذر Ø­Ùظ كلمة المرور الجديدة. خطأ بالإتصال.';
+$messages['internalerror'] = 'تعذر Ø­Ùظ كلمة المرور الجديدة.';
+$messages['passwordshort'] = 'كلمة المرور يجب على الأقل $length أحرÙ';
+$messages['passwordweak'] = ' كلمة المرور يجب أن تتضمن رقم واحد على الأقل وحر٠ترقيم واحد.';
+$messages['passwordforbidden'] = 'كلمة المرور تحتوى على أحر٠ممنوعة';
+?>
diff --git a/plugins/password/localization/ar_SA.inc b/plugins/password/localization/ar_SA.inc
new file mode 100644
index 000000000..990505bac
--- /dev/null
+++ b/plugins/password/localization/ar_SA.inc
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'تغيير كلمة المرور';
+$labels['curpasswd'] = 'كلمة المرور الحالية';
+$labels['newpasswd'] = 'كلمة المرور الجديدة';
+$labels['confpasswd'] = 'تأكيد كلمة المرور الجديدة';
+$messages['nopassword'] = 'من Ùضلك أدخل كلمة مرور جديدة';
+$messages['nocurpassword'] = 'من Ùضلك أدخل كلمة المرور الحالية';
+$messages['passwordincorrect'] = 'كلمة المرور الحالية غير صحيحة';
+$messages['passwordinconsistency'] = 'كلمة المرور غير مطابقة, أعد المحاولة';
+$messages['connecterror'] = 'تعذر Ø­Ùظ كلمة المرور الجديدة. خطأ ÙÙŠ الإتصال';
+$messages['internalerror'] = 'تعذر Ø­Ùظ كلمة المرور الجديدة';
+$messages['passwordforbidden'] = 'كلمة المرور تحتوي حروÙاً ممنوعة';
+?>
diff --git a/plugins/password/localization/ast.inc b/plugins/password/localization/ast.inc
new file mode 100644
index 000000000..99b283ec5
--- /dev/null
+++ b/plugins/password/localization/ast.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'Camudar contraseña';
+$labels['curpasswd'] = 'Contraseña actual:';
+$labels['newpasswd'] = 'Contraseña nueva:';
+$labels['confpasswd'] = 'Confirmar contraseña:';
+$messages['nopassword'] = 'Por favor, introduz una contraseña nueva.';
+$messages['nocurpassword'] = 'Por favor, introduz la contraseña actual.';
+$messages['passwordincorrect'] = 'La contraseña actual ye incorreuta.';
+$messages['passwordinconsistency'] = 'Les contraseñes nun concasen. Por favor, inténtalo otra vegada.';
+$messages['crypterror'] = 'Nun pudo guardase la contraseña nueva. Falta la función de cifráu.';
+$messages['connecterror'] = 'Nun pudo guardase la contraseña nueva. Fallu de conexón.';
+$messages['internalerror'] = 'Nun pudo guardase la contraseña nueva. ';
+$messages['passwordshort'] = 'La contraseña tien de tener polo menos $length caráuteres.';
+$messages['passwordweak'] = 'La contraseña tien de tener polo menos un númberu y un signu de puntuación.';
+$messages['passwordforbidden'] = 'La contraseña que s\'introduxo contién caráuteres non permitíos.';
+?>
diff --git a/plugins/password/localization/be_BE.inc b/plugins/password/localization/be_BE.inc
new file mode 100644
index 000000000..457e67e9e
--- /dev/null
+++ b/plugins/password/localization/be_BE.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'ЗмÑніць пароль';
+$labels['curpasswd'] = 'БÑгучы пароль:';
+$labels['newpasswd'] = 'Ðовы пароль:';
+$labels['confpasswd'] = 'Паўтарыце новы пароль:';
+$messages['nopassword'] = 'УвÑдзіце новы пароль.';
+$messages['nocurpassword'] = 'УвÑдзіце бÑгучы пароль.';
+$messages['passwordincorrect'] = 'ÐÑÑлушны бÑгучы пароль.';
+$messages['passwordinconsistency'] = 'Паролі не Ñупадаюць. ПаÑпрабуйце ÑÑˆÑ‡Ñ Ñ€Ð°Ð·.';
+$messages['crypterror'] = 'Ðе ўдалоÑÑ Ð·Ð°Ñ…Ð°Ð²Ð°Ñ†ÑŒ новы пароль. Бракуе функцыі шыфраваннÑ.';
+$messages['connecterror'] = 'Ðе ўдалоÑÑ Ð·Ð°Ñ…Ð°Ð²Ð°Ñ†ÑŒ новы пароль. Памылка злучÑннÑ.';
+$messages['internalerror'] = 'Ðе ўдалоÑÑ Ð·Ð°Ñ…Ð°Ð²Ð°Ñ†ÑŒ новы пароль.';
+$messages['passwordshort'] = 'Пароль муÑіць быць мінімум $length знакаў.';
+$messages['passwordweak'] = 'Пароль муÑіць утрымліваць мінімум адну лічбу Ñ– адзін знак пунктуацыі.';
+$messages['passwordforbidden'] = 'Пароль утрымлівае Ð·Ð°Ð±Ð°Ñ€Ð¾Ð½ÐµÐ½Ñ‹Ñ Ð·Ð½Ð°ÐºÑ–.';
+?>
diff --git a/plugins/password/localization/el_GR.inc b/plugins/password/localization/el_GR.inc
new file mode 100644
index 000000000..b1c72ab69
--- /dev/null
+++ b/plugins/password/localization/el_GR.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'Αλλαγη κωδικου Ï€Ïοσβασης';
+$labels['curpasswd'] = 'ΤÏεχων κωδικος Ï€Ïοσβασης:';
+$labels['newpasswd'] = 'Îεος κωδικος Ï€Ïοσβασης:';
+$labels['confpasswd'] = 'Επιβεβαιωση κωδικου Ï€Ïοσβασης:';
+$messages['nopassword'] = 'Εισαγετε εναν νεο κωδικο.';
+$messages['nocurpassword'] = 'Εισαγετε τον Ï„Ïεχων κωδικο.';
+$messages['passwordincorrect'] = 'Ο Ï„Ïεχων κωδικος ειναι λαθος.';
+$messages['passwordinconsistency'] = 'Οι κωδικοί Ï€Ïόσβασης δεν ταιÏιάζουν, Ï€Ïοσπαθήστε ξανά.';
+$messages['crypterror'] = 'Δεν μποÏεσε να αποθηκεÏθει ο νέος κωδικός Ï€Ïόσβασης. Η λειτουÏγία κÏυπτογÏάφησης λείπει.';
+$messages['connecterror'] = 'Δεν μποÏεσε να αποθηκεÏθει ο νέος κωδικός Ï€Ïόσβασης. Σφάλμα σÏνδεσης.';
+$messages['internalerror'] = 'Δεν μποÏεσε να αποθηκεÏθει ο νέος κωδικός Ï€Ïόσβασης. ';
+$messages['passwordshort'] = 'Ο κωδικός Ï€Ïόσβασης Ï€Ïέπει να είναι τουλάχιστον $μήκος χαÏακτήÏων.';
+$messages['passwordweak'] = 'Ο κωδικός Ï€Ïόσβασης Ï€Ïέπει να πεÏιλαμβάνει τουλάχιστον έναν αÏιθμό και ένα σημείο στίξης. ';
+$messages['passwordforbidden'] = 'Ο κωδικός Ï€Ïόσβασης πεÏιέχει μη επιτÏεπτοÏÏ‚ χαÏακτήÏες. ';
+?>
diff --git a/plugins/password/localization/en_US.inc b/plugins/password/localization/en_US.inc
index a4c077fe5..dd57c1318 100644
--- a/plugins/password/localization/en_US.inc
+++ b/plugins/password/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/password/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Password plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/password/localization/eu_ES.inc b/plugins/password/localization/eu_ES.inc
new file mode 100644
index 000000000..b814d2983
--- /dev/null
+++ b/plugins/password/localization/eu_ES.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'Pasahitza aldatu';
+$labels['curpasswd'] = 'Oraingo pasahitza:';
+$labels['newpasswd'] = 'Pasahitz berria:';
+$labels['confpasswd'] = 'Konfirmatu pasahitz berria:';
+$messages['nopassword'] = 'Sartu pasahitz berria.';
+$messages['nocurpassword'] = 'Sartu oraingo pasahitza.';
+$messages['passwordincorrect'] = 'Oraingo pasahitza ez da zuzena.';
+$messages['passwordinconsistency'] = 'Pasahitz berria ez datoz bat, saiatu berriz.';
+$messages['crypterror'] = 'Ezin izan da pasahitz berria gorde. Ez da enkriptazio funtziorik aurkitu.';
+$messages['connecterror'] = 'Ezin izan da pasahitz berria gorde. Konexio arazoak egon dira.';
+$messages['internalerror'] = 'Ezin izan da pasahitz berria gorde.';
+$messages['passwordshort'] = 'Gutxienez $length karakteretakoa izan behar du pasahitzak.';
+$messages['passwordweak'] = 'Gutxienez zenbaki bat eta puntuazio karaktere bat izan behar du pasahitzak.';
+$messages['passwordforbidden'] = 'Galarazitako karaktereak daude pasahitzean.';
+?>
diff --git a/plugins/password/localization/fa_AF.inc b/plugins/password/localization/fa_AF.inc
new file mode 100644
index 000000000..5bf7c3a8f
--- /dev/null
+++ b/plugins/password/localization/fa_AF.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'تغییر رمز عبور';
+$labels['curpasswd'] = 'رمز عبور کنونی';
+$labels['newpasswd'] = 'رمز عبور جدید';
+$labels['confpasswd'] = 'تایید رمز عبور جدید';
+$messages['nopassword'] = 'لطÙا رمز عبور جدیدی وارد کنید';
+$messages['nocurpassword'] = 'لطÙا رمز عبور کنونی را وارد کنید';
+$messages['passwordincorrect'] = 'رمز عبور کنونی اشتباه است';
+$messages['passwordinconsistency'] = 'رمزهای عبور با هم مطابقت ندارند، لطÙا دوباره سعی کنید';
+$messages['crypterror'] = 'امکان ذخیره رمز عبور جدید وجود ندارد. تابع رمزگذاری یاÙت نشد';
+$messages['connecterror'] = 'امکان ذخیره رمز عبور جدید وجود ندارد. لطÙا دوباره سعی کنید';
+$messages['internalerror'] = 'امکان ذخیره رمز عبور جدید وجود ندارد';
+$messages['passwordshort'] = 'طول رمز عبور می بایست حداقل به طول $length کاراکتر باشد';
+$messages['passwordweak'] = 'رمز عبور می بایست دارای حداقل یک عدد و یک کاراکتر علامت گذاری باشد';
+$messages['passwordforbidden'] = 'رمز عبور شامل کاراکترهای غیر مجاز است';
+?>
diff --git a/plugins/password/localization/gl_ES.inc b/plugins/password/localization/gl_ES.inc
index 93c505a6a..245d1c634 100644
--- a/plugins/password/localization/gl_ES.inc
+++ b/plugins/password/localization/gl_ES.inc
@@ -26,7 +26,7 @@ $messages = array();
$messages['nopassword'] = 'Por favor, introduza un contrasinal novo.';
$messages['nocurpassword'] = 'Por favor, introduza o contrasinal actual.';
$messages['passwordincorrect'] = 'O contrasinal actual é incorrecto.';
-$messages['passwordinconsistency'] = 'Os contrasinais non cadran. Por favor, inténteo outra vez.';
+$messages['passwordinconsistency'] = 'Os contrasinals non coinciden. Por favor, inténteo de novo.';
$messages['crypterror'] = 'Non foi posible gardar o contrasinal novo. Falta a función de cifrado.';
$messages['connecterror'] = 'Non foi posible gardar o contrasinal novo. Erro de conexión';
$messages['internalerror'] = 'Non foi posible gardar o contrasinal novo.';
diff --git a/plugins/password/localization/lb_LU.inc b/plugins/password/localization/lb_LU.inc
index 9962aed28..08026f242 100644
--- a/plugins/password/localization/lb_LU.inc
+++ b/plugins/password/localization/lb_LU.inc
@@ -15,14 +15,10 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
*/
-
-$labels = array();
$labels['changepasswd'] = 'Passwuert änneren';
$labels['curpasswd'] = 'Aktuellt Passwuert:';
$labels['newpasswd'] = 'Neit Passwuert:';
$labels['confpasswd'] = 'Neit Passwuert bestätegen:';
-
-$messages = array();
$messages['nopassword'] = 'Gëff wann ech gelift en neit Passwuert an.';
$messages['nocurpassword'] = 'Gëff wann ech gelift dat aktuellt Passwuert an.';
$messages['passwordincorrect'] = 'Aktuellt Passwuert net korrekt.';
@@ -33,5 +29,4 @@ $messages['internalerror'] = 'Neit Passwuert konnt net gespäichert ginn.';
$messages['passwordshort'] = 'D\'Passwuert muss mindestens $length Zeeche laang sinn.';
$messages['passwordweak'] = 'D\'Passwuert muss mindestens eng Zuel an ee Sazzeechen enthalen.';
$messages['passwordforbidden'] = 'D\'Passwuert enthält verbueden Zeechen.';
-
?>
diff --git a/plugins/password/localization/lv_LV.inc b/plugins/password/localization/lv_LV.inc
index ac0e5da79..650d31b2c 100644
--- a/plugins/password/localization/lv_LV.inc
+++ b/plugins/password/localization/lv_LV.inc
@@ -20,18 +20,18 @@ $labels = array();
$labels['changepasswd'] = 'Nomainīt paroli';
$labels['curpasswd'] = 'PaÅ¡reizÄ“jÄ parole:';
$labels['newpasswd'] = 'JaunÄ parole:';
-$labels['confpasswd'] = 'ApstiprinÄt jauno paroli:';
+$labels['confpasswd'] = 'VÄ“lreiz jauno paroli:';
$messages = array();
-$messages['nopassword'] = 'LÅ«dzu ievadiet jauno paroli.';
-$messages['nocurpassword'] = 'Lūdzu ievadiet pašreizējo paroli.';
-$messages['passwordincorrect'] = 'PaÅ¡reizÄ“jÄ parole nav pareiza.';
+$messages['nopassword'] = 'LÅ«dzu, ievadiet jauno paroli.';
+$messages['nocurpassword'] = 'Lūdzu, ievadiet pašreizējo paroli.';
+$messages['passwordincorrect'] = 'PaÅ¡reizÄ“jÄ parole nepareiza.';
$messages['passwordinconsistency'] = 'Paroles nesakrīt. Lūdzu, ievadiet vēlreiz.';
-$messages['crypterror'] = 'NevarÄ“ja saglabÄt jauno paroli. TrÅ«kst kriptÄ“Å¡anas funkcijas.';
+$messages['crypterror'] = 'NevarÄ“ja saglabÄt jauno paroli. TrÅ«kst kriptÄ“Å¡anas funkcija.';
$messages['connecterror'] = 'NevarÄ“ja saglabÄt jauno paroli. Savienojuma kļūda.';
$messages['internalerror'] = 'NevarÄ“ja saglabÄt jauno paroli.';
-$messages['passwordshort'] = 'Jaunajai parolei jÄbÅ«t vismaz $length simbolu garai.';
-$messages['passwordweak'] = 'Jaunajai parolei jÄsatur vismaz viens cipars un speciÄlais simbols.';
-$messages['passwordforbidden'] = 'Parole satur neatļautus simbolus.';
+$messages['passwordshort'] = 'Jaunajai parolei jÄbÅ«t vismaz $length simbola garai.';
+$messages['passwordweak'] = 'Jaunajai parolei jÄsatur vismaz viens cipars un punktuÄcijas simbols.';
+$messages['passwordforbidden'] = 'Password contains forbidden characters.';
?>
diff --git a/plugins/password/localization/ro_RO.inc b/plugins/password/localization/ro_RO.inc
index 7406efb9a..17ec31c6b 100644
--- a/plugins/password/localization/ro_RO.inc
+++ b/plugins/password/localization/ro_RO.inc
@@ -20,18 +20,18 @@ $labels = array();
$labels['changepasswd'] = 'Schimbați parola';
$labels['curpasswd'] = 'Parola curentă:';
$labels['newpasswd'] = 'Parola nouă:';
-$labels['confpasswd'] = 'Confirmați parola nouă:';
+$labels['confpasswd'] = 'Confirmare parola nouă:';
$messages = array();
$messages['nopassword'] = 'Te rog să introduci noua parolă.';
$messages['nocurpassword'] = 'Te rog să introduci parola curentă';
$messages['passwordincorrect'] = 'Parola curentă este incorectă.';
-$messages['passwordinconsistency'] = 'Parolele nu se potrivesc, vă rugăm să mai încercați';
-$messages['crypterror'] = 'Nu am reușit să salvez noua parolă. Lipsa funcției de criptare.';
+$messages['passwordinconsistency'] = 'Parolele nu se potrivesc, te rog să mai încerci';
+$messages['crypterror'] = 'Nu am reușit să salvez noua parolă. Funcția de criptare lipsește.';
$messages['connecterror'] = 'Nu am reușit să salvez noua parolă. Eroare connexiune.';
$messages['internalerror'] = 'Nu am reușit să salvez noua parolă.';
-$messages['passwordshort'] = 'Parola trebuie să aibă $length caractere.';
-$messages['passwordweak'] = 'Parola trebuie să conțina cel puțin un număr si un semn de punctuație';
+$messages['passwordshort'] = 'Parola trebuie să aibă minim $length caractere.';
+$messages['passwordweak'] = 'Parola trebuie să conțina cel puțin un număr si un semn de punctuație.';
$messages['passwordforbidden'] = 'Parola conține caractere nepermise.';
?>
diff --git a/plugins/password/localization/ru_RU.inc b/plugins/password/localization/ru_RU.inc
index 2517f922b..79fbfedf6 100644
--- a/plugins/password/localization/ru_RU.inc
+++ b/plugins/password/localization/ru_RU.inc
@@ -26,11 +26,11 @@ $messages = array();
$messages['nopassword'] = 'ПожалуйÑта, введите новый пароль.';
$messages['nocurpassword'] = 'ПожалуйÑта, введите текущий пароль.';
$messages['passwordincorrect'] = 'Текущий пароль неверен.';
-$messages['passwordinconsistency'] = 'Пароли не Ñовпадают, попробуйте ещё раз, пожалуйÑта.';
+$messages['passwordinconsistency'] = 'Пароли не Ñовпадают, попробуйте, пожалуйÑта, ещё.';
$messages['crypterror'] = 'Ðе могу Ñохранить новый пароль. ОтÑутÑтвует криптографичеÑÐºÐ°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ.';
$messages['connecterror'] = 'Ðе могу Ñохранить новый пароль. Ошибка ÑоединениÑ.';
$messages['internalerror'] = 'Ðе могу Ñохранить новый пароль.';
-$messages['passwordshort'] = 'Длина Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть как минимум $length Ñимволов.';
+$messages['passwordshort'] = 'Пароль должен быть длиной как минимум $length Ñимволов.';
$messages['passwordweak'] = 'Пароль должен включать в ÑÐµÐ±Ñ ÐºÐ°Ðº минимум одну цифру и один знак пунктуации.';
$messages['passwordforbidden'] = 'Пароль Ñодержит недопуÑтимые Ñимволы.';
diff --git a/plugins/password/localization/ti.inc b/plugins/password/localization/ti.inc
new file mode 100644
index 000000000..9453318f0
--- /dev/null
+++ b/plugins/password/localization/ti.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'መሕለአቃሠይለወጥ';
+$labels['curpasswd'] = 'ህáˆá‹ መሕለአቃáˆ:';
+$labels['newpasswd'] = 'ሓዱሽ መሕለአቃáˆ:';
+$labels['confpasswd'] = 'መረጋገႠሓዱሽ መሕለአቃሠ:';
+$messages['nopassword'] = 'ሓዱሽ መሕለአቃሠአብዚ ይእቶ::';
+$messages['nocurpassword'] = 'ህáˆá‹ መሕለአቃሠኣብዚ ይእቶ::';
+$messages['passwordincorrect'] = 'ህáˆá‹ መሕለአቃሠከáˆáŠ¡ ኣይኮáŠáŠ•::';
+$messages['passwordinconsistency'] = 'መሕለáቲ ቃላት ሓድ ኣይኮኑን ::ተá‹áˆ³áŠº áˆá‰°áŠ የድሊ::';
+$messages['crypterror'] = 'መመስጥሪ á‹áŠ•áŠ­áˆ½áŠ• ስለá‹áˆ³áŠ¥áŠ እቲ መሕለአቃሠኣይተá‰áˆ˜áŒ áŠ•::';
+$messages['connecterror'] = 'ናይ ርክብ ጸገሠስለዘሎ እቲ መሕለአቃሠኣይተá‰áˆ˜áŒ áŠ•::';
+$messages['internalerror'] = 'እቲ መሕለአቃሠኣይተá‰áˆ˜áŒ áŠ•::';
+$messages['passwordshort'] = 'ንá‹áˆ“ት መሕለአቃሠ$length áŠá‹³áˆ‹á‰µ ክኾን አለዎ::';
+$messages['passwordweak'] = 'መሕለአቃሠእንተá‹áˆ“á‹° ሓደ ኣሃá‹áŠ• ሓደ ስርዓተ áŠáŒ¥á‰¥áŠ• ከጠቓáˆáˆ አለዎ::';
+$messages['passwordforbidden'] = 'እቲ መሕለአቃሠá‹áŒ‰á‹³á‰µ áŠá‹³áˆ‹á‰µ አለá‹á‹Ž::';
+?>
diff --git a/plugins/password/localization/uk_UA.inc b/plugins/password/localization/uk_UA.inc
new file mode 100644
index 000000000..0d102e528
--- /dev/null
+++ b/plugins/password/localization/uk_UA.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, 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/plugin-password/
+*/
+$labels['changepasswd'] = 'Змінити пароль';
+$labels['curpasswd'] = 'Поточний пароль:';
+$labels['newpasswd'] = 'Ðовий пароль:';
+$labels['confpasswd'] = 'Підтвердіть новий пароль:';
+$messages['nopassword'] = 'Будь лаÑка, введіть новий пароль.';
+$messages['nocurpassword'] = 'Будь лаÑка, введіть поточний пароль.';
+$messages['passwordincorrect'] = 'Поточний пароль неправильний.';
+$messages['passwordinconsistency'] = 'Паролі не збігаютьÑÑ, Ñпробуйте ще раз.';
+$messages['crypterror'] = 'Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ новий пароль. Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ÑутнÑ.';
+$messages['connecterror'] = 'Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ новий пароль. Помилка з\'єднаннÑ.';
+$messages['internalerror'] = 'Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ новий пароль.';
+$messages['passwordshort'] = 'Пароль повинен бути не менше $length Ñимволів.';
+$messages['passwordweak'] = 'Пароль повинен міÑтити Ñк мінімум одну цифру Ñ– один розділовий знак.';
+$messages['passwordforbidden'] = 'Пароль міÑтить заборонені Ñимволи.';
+?>
diff --git a/plugins/password/package.xml b/plugins/password/package.xml
index 16eda1ad0..9a056dec6 100644
--- a/plugins/password/package.xml
+++ b/plugins/password/package.xml
@@ -15,18 +15,19 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
- <date>2013-04-28</date>
+ <date>2012-11-15</date>
<version>
- <release>3.4</release>
+ <release>3.2</release>
<api>2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>
-Added password_force_save option
+- Fix wrong (non-specific) error message on crypt or connection error (#1488808)
+- Added option to define IMAP hosts that support password changes - password_hosts
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@@ -346,36 +347,5 @@ Added password_force_save option
- Added Samba password (#1488364)
</notes>
</release>
- <release>
- <date>2012-11-15</date>
- <version>
- <release>3.2</release>
- <api>2.0</api>
- </version>
- <stability>
- <release>stable</release>
- <api>stable</api>
- </stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
- <notes>
-- Fix wrong (non-specific) error message on crypt or connection error (#1488808)
-- Added option to define IMAP hosts that support password changes - password_hosts
- </notes>
- </release>
- <release>
- <date>2013-03-30</date>
- <version>
- <release>3.3</release>
- <api>2.0</api>
- </version>
- <stability>
- <release>stable</release>
- <api>stable</api>
- </stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
- <notes>
-Added new cPanel driver - fixes localization related issues (#1487015)
- </notes>
- </release>
</changelog>
</package>
diff --git a/plugins/password/password.php b/plugins/password/password.php
index f1a3e17b9..806db0586 100644
--- a/plugins/password/password.php
+++ b/plugins/password/password.php
@@ -1,26 +1,32 @@
<?php
-/**
- * Password Plugin for Roundcube
- *
- * @version @package_version@
- * @author Aleksander Machniak <alec@alec.pl>
- *
- * Copyright (C) 2005-2013, The Roundcube Dev Team
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
+/*
+ +-------------------------------------------------------------------------+
+ | Password Plugin for Roundcube |
+ | @version @package_version@ |
+ | |
+ | Copyright (C) 2009-2010, Roundcube Dev. |
+ | |
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License version 2 |
+ | as published by the Free Software Foundation. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License along |
+ | with this program; if not, write to the Free Software Foundation, Inc., |
+ | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
+ | |
+ +-------------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-------------------------------------------------------------------------+
+
+ $Id: index.php 2645 2009-06-15 07:01:36Z alec $
+
+*/
define('PASSWORD_CRYPT_ERROR', 1);
define('PASSWORD_ERROR', 2);
@@ -106,22 +112,22 @@ class password extends rcube_plugin
$rc_charset = strtoupper($rcmail->output->get_charset());
$sespwd = $rcmail->decrypt($_SESSION['password']);
- $curpwd = $confirm ? rcube_utils::get_input_value('_curpasswd', rcube_utils::INPUT_POST, true, $charset) : $sespwd;
- $newpwd = rcube_utils::get_input_value('_newpasswd', rcube_utils::INPUT_POST, true);
- $conpwd = rcube_utils::get_input_value('_confpasswd', rcube_utils::INPUT_POST, true);
+ $curpwd = $confirm ? get_input_value('_curpasswd', RCUBE_INPUT_POST, true, $charset) : $sespwd;
+ $newpwd = get_input_value('_newpasswd', RCUBE_INPUT_POST, true);
+ $conpwd = get_input_value('_confpasswd', RCUBE_INPUT_POST, true);
// check allowed characters according to the configured 'password_charset' option
// by converting the password entered by the user to this charset and back to UTF-8
$orig_pwd = $newpwd;
- $chk_pwd = rcube_charset::convert($orig_pwd, $rc_charset, $charset);
- $chk_pwd = rcube_charset::convert($chk_pwd, $charset, $rc_charset);
+ $chk_pwd = rcube_charset_convert($orig_pwd, $rc_charset, $charset);
+ $chk_pwd = rcube_charset_convert($chk_pwd, $charset, $rc_charset);
// WARNING: Default password_charset is ISO-8859-1, so conversion will
// change national characters. This may disable possibility of using
// the same password in other MUA's.
// We're doing this for consistence with Roundcube core
- $newpwd = rcube_charset::convert($newpwd, $rc_charset, $charset);
- $conpwd = rcube_charset::convert($conpwd, $rc_charset, $charset);
+ $newpwd = rcube_charset_convert($newpwd, $rc_charset, $charset);
+ $conpwd = rcube_charset_convert($conpwd, $rc_charset, $charset);
if ($chk_pwd != $orig_pwd) {
$rcmail->output->command('display_message', $this->gettext('passwordforbidden'), 'error');
@@ -135,13 +141,13 @@ class password extends rcube_plugin
}
else if ($required_length && strlen($newpwd) < $required_length) {
$rcmail->output->command('display_message', $this->gettext(
- array('name' => 'passwordshort', 'vars' => array('length' => $required_length))), 'error');
+ array('name' => 'passwordshort', 'vars' => array('length' => $required_length))), 'error');
}
else if ($check_strength && (!preg_match("/[0-9]/", $newpwd) || !preg_match("/[^A-Za-z0-9]/", $newpwd))) {
$rcmail->output->command('display_message', $this->gettext('passwordweak'), 'error');
}
// password is the same as the old one, do nothing, return success
- else if ($sespwd == $newpwd && !$rcmail->config->get('password_force_save')) {
+ else if ($sespwd == $newpwd) {
$rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
}
// try to save the password
@@ -157,8 +163,8 @@ class password extends rcube_plugin
// Log password change
if ($rcmail->config->get('password_log')) {
- rcube::write_log('password', sprintf('Password changed for user %s (ID: %d) from %s',
- $rcmail->get_user_name(), $rcmail->user->ID, rcube_utils::remote_ip()));
+ write_log('password', sprintf('Password changed for user %s (ID: %d) from %s',
+ $rcmail->get_user_name(), $rcmail->user->ID, rcmail_remote_ip()));
}
}
else {
@@ -166,7 +172,7 @@ class password extends rcube_plugin
}
}
- $rcmail->overwrite_action('plugin.password');
+ rcmail_overwrite_action('plugin.password');
$rcmail->output->send('plugin');
}
@@ -191,7 +197,7 @@ class password extends rcube_plugin
$input_curpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id,
'size' => 20, 'autocomplete' => 'off'));
- $table->add('title', html::label($field_id, rcube::Q($this->gettext('curpasswd'))));
+ $table->add('title', html::label($field_id, Q($this->gettext('curpasswd'))));
$table->add(null, $input_curpasswd->show());
}
@@ -200,7 +206,7 @@ class password extends rcube_plugin
$input_newpasswd = new html_passwordfield(array('name' => '_newpasswd', 'id' => $field_id,
'size' => 20, 'autocomplete' => 'off'));
- $table->add('title', html::label($field_id, rcube::Q($this->gettext('newpasswd'))));
+ $table->add('title', html::label($field_id, Q($this->gettext('newpasswd'))));
$table->add(null, $input_newpasswd->show());
// show confirm password selection
@@ -208,7 +214,7 @@ class password extends rcube_plugin
$input_confpasswd = new html_passwordfield(array('name' => '_confpasswd', 'id' => $field_id,
'size' => 20, 'autocomplete' => 'off'));
- $table->add('title', html::label($field_id, rcube::Q($this->gettext('confpasswd'))));
+ $table->add('title', html::label($field_id, Q($this->gettext('confpasswd'))));
$table->add(null, $input_confpasswd->show());
$out = html::div(array('class' => 'box'),
@@ -240,7 +246,7 @@ class password extends rcube_plugin
$file = $this->home . "/drivers/$driver.php";
if (!file_exists($file)) {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@@ -252,7 +258,7 @@ class password extends rcube_plugin
include_once $file;
if (!class_exists($class, false) || !method_exists($class, 'save')) {
- rcube::raise_error(array(
+ raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
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/show_additional_headers/package.xml b/plugins/show_additional_headers/package.xml
index 9ca60baa9..7297916c3 100644
--- a/plugins/show_additional_headers/package.xml
+++ b/plugins/show_additional_headers/package.xml
@@ -24,7 +24,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/show_additional_headers/show_additional_headers.php b/plugins/show_additional_headers/show_additional_headers.php
index b7f01104c..1375348c2 100644
--- a/plugins/show_additional_headers/show_additional_headers.php
+++ b/plugins/show_additional_headers/show_additional_headers.php
@@ -6,12 +6,12 @@
* Proof-of-concept plugin which will fetch additional headers
* and display them in the message view.
*
- * Enable the plugin in config.inc.php and add your desired headers:
- * $config['show_additional_headers'] = array('User-Agent');
+ * Enable the plugin in config/main.inc.php and add your desired headers:
+ * $rcmail_config['show_additional_headers'] = array('User-Agent');
*
* @version @package_version@
* @author Thomas Bruederli
- * @license GNU GPLv3+
+ * @website http://roundcube.net
*/
class show_additional_headers extends rcube_plugin
{
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/squirrelmail_usercopy/config.inc.php.dist b/plugins/squirrelmail_usercopy/config.inc.php.dist
index 03ec1cb86..cb62b1b86 100644
--- a/plugins/squirrelmail_usercopy/config.inc.php.dist
+++ b/plugins/squirrelmail_usercopy/config.inc.php.dist
@@ -1,25 +1,25 @@
<?php
// Driver - 'file' or 'sql'
-$config['squirrelmail_driver'] = 'sql';
+$rcmail_config['squirrelmail_driver'] = 'sql';
// full path to the squirrelmail data directory
-$config['squirrelmail_data_dir'] = '';
-$config['squirrelmail_data_dir_hash_level'] = 0;
+$rcmail_config['squirrelmail_data_dir'] = '';
+$rcmail_config['squirrelmail_data_dir_hash_level'] = 0;
// 'mysql://dbuser:dbpass@localhost/database'
-$config['squirrelmail_dsn'] = 'mysql://user:password@localhost/webmail';
-$config['squirrelmail_db_charset'] = 'iso-8859-1';
+$rcmail_config['squirrelmail_dsn'] = 'mysql://user:password@localhost/webmail';
+$rcmail_config['squirrelmail_db_charset'] = 'iso-8859-1';
-$config['squirrelmail_address_table'] = 'address';
-$config['squirrelmail_userprefs_table'] = 'userprefs';
+$rcmail_config['squirrelmail_address_table'] = 'address';
+$rcmail_config['squirrelmail_userprefs_table'] = 'userprefs';
// identities_level option value for squirrelmail plugin
// With this you can bypass/change identities_level checks
// for operations inside this plugin. See #1486773
-$config['squirrelmail_identities_level'] = null;
+$rcmail_config['squirrelmail_identities_level'] = null;
// Set to false if you don't want the email address of the default identity
// (squirrelmail preference "email_address") to be saved as alias.
// Recommended: set to false if your squirrelmail config setting $edit_identity has been true.
-$config['squirrelmail_set_alias'] = true; \ No newline at end of file
+$rcmail_config['squirrelmail_set_alias'] = true; \ No newline at end of file
diff --git a/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php b/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
index e882a2f37..7849f915e 100644
--- a/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
+++ b/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
@@ -63,7 +63,7 @@ class squirrelmail_usercopy extends rcube_plugin
if ($this->prefs['___sig'.$i.'___'])
$ident_data['signature'] = $this->prefs['___sig'.$i.'___'];
// insert identity
- $rcmail->user->insert_identity($ident_data);
+ $identid = $rcmail->user->insert_identity($ident_data);
}
}
@@ -73,8 +73,8 @@ class squirrelmail_usercopy extends rcube_plugin
foreach ($this->abook as $rec) {
// #1487096 handle multi-address and/or too long items
$rec['email'] = array_shift(explode(';', $rec['email']));
- if (rcube_utils::check_email(rcube_utils::idn_to_ascii($rec['email']))) {
- $rec['email'] = rcube_utils::idn_to_utf8($rec['email']);
+ if (check_email(rcube_idn_to_ascii($rec['email']))) {
+ $rec['email'] = rcube_idn_to_utf8($rec['email']);
$contacts->insert($rec, true);
}
}
@@ -167,7 +167,7 @@ class squirrelmail_usercopy extends rcube_plugin
$sql_result = $db->query('SELECT * FROM '.$userprefs_table.' WHERE user=?', $uname); // ? is replaced with emailaddress
while ($sql_array = $db->fetch_assoc($sql_result) ) { // fetch one row from result
- $this->prefs[$sql_array['prefkey']] = rcube_charset::convert(rtrim($sql_array['prefval']), $db_charset);
+ $this->prefs[$sql_array['prefkey']] = rcube_charset_convert(rtrim($sql_array['prefval']), $db_charset);
}
/* retrieve address table data */
@@ -175,11 +175,11 @@ class squirrelmail_usercopy extends rcube_plugin
// parse addres book
while ($sql_array = $db->fetch_assoc($sql_result) ) { // fetch one row from result
- $rec['name'] = rcube_charset::convert(rtrim($sql_array['nickname']), $db_charset);
- $rec['firstname'] = rcube_charset::convert(rtrim($sql_array['firstname']), $db_charset);
- $rec['surname'] = rcube_charset::convert(rtrim($sql_array['lastname']), $db_charset);
- $rec['email'] = rcube_charset::convert(rtrim($sql_array['email']), $db_charset);
- $rec['notes'] = rcube_charset::convert(rtrim($sql_array['label']), $db_charset);
+ $rec['name'] = rcube_charset_convert(rtrim($sql_array['nickname']), $db_charset);
+ $rec['firstname'] = rcube_charset_convert(rtrim($sql_array['firstname']), $db_charset);
+ $rec['surname'] = rcube_charset_convert(rtrim($sql_array['lastname']), $db_charset);
+ $rec['email'] = rcube_charset_convert(rtrim($sql_array['email']), $db_charset);
+ $rec['notes'] = rcube_charset_convert(rtrim($sql_array['label']), $db_charset);
if ($rec['name'] && $rec['email'])
$this->abook[] = $rec;
diff --git a/plugins/subscriptions_option/localization/az_AZ.inc b/plugins/subscriptions_option/localization/az_AZ.inc
new file mode 100644
index 000000000..27ee6a54e
--- /dev/null
+++ b/plugins/subscriptions_option/localization/az_AZ.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'IMAP göndərişi istifadə et';
+?>
diff --git a/plugins/subscriptions_option/localization/be_BE.inc b/plugins/subscriptions_option/localization/be_BE.inc
new file mode 100644
index 000000000..470336838
--- /dev/null
+++ b/plugins/subscriptions_option/localization/be_BE.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'ВыкарыÑтоўваць IMAP-падпіÑкі';
+?>
diff --git a/plugins/subscriptions_option/localization/bg_BG.inc b/plugins/subscriptions_option/localization/bg_BG.inc
new file mode 100644
index 000000000..fd025e7dc
--- /dev/null
+++ b/plugins/subscriptions_option/localization/bg_BG.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Използвай IMAP абонаменти';
+?>
diff --git a/plugins/subscriptions_option/localization/el_GR.inc b/plugins/subscriptions_option/localization/el_GR.inc
new file mode 100644
index 000000000..aae45c2a6
--- /dev/null
+++ b/plugins/subscriptions_option/localization/el_GR.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'ΧÏησιμοποιήστε IMAP ΣυνδÏομές';
+?>
diff --git a/plugins/subscriptions_option/localization/en_US.inc b/plugins/subscriptions_option/localization/en_US.inc
index 3eb18fc1d..19e1b26c7 100644
--- a/plugins/subscriptions_option/localization/en_US.inc
+++ b/plugins/subscriptions_option/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/subscriptions_option/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Subscriptions plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/subscriptions_option/localization/es_AR.inc b/plugins/subscriptions_option/localization/es_AR.inc
new file mode 100644
index 000000000..d062f1934
--- /dev/null
+++ b/plugins/subscriptions_option/localization/es_AR.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Usar suscripción a carpetas IMAP';
+?>
diff --git a/plugins/subscriptions_option/localization/eu_ES.inc b/plugins/subscriptions_option/localization/eu_ES.inc
new file mode 100644
index 000000000..a6d349e11
--- /dev/null
+++ b/plugins/subscriptions_option/localization/eu_ES.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Erabili IMAP harpidetzak';
+?>
diff --git a/plugins/subscriptions_option/localization/fa_AF.inc b/plugins/subscriptions_option/localization/fa_AF.inc
new file mode 100644
index 000000000..696fbdc0b
--- /dev/null
+++ b/plugins/subscriptions_option/localization/fa_AF.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'از ثبت نام های IMAP استÙاده کنید';
+?>
diff --git a/plugins/subscriptions_option/localization/gl_ES.inc b/plugins/subscriptions_option/localization/gl_ES.inc
index a273777da..bbff10c3b 100644
--- a/plugins/subscriptions_option/localization/gl_ES.inc
+++ b/plugins/subscriptions_option/localization/gl_ES.inc
@@ -17,6 +17,6 @@
*/
$labels = array();
-$labels['useimapsubscriptions'] = 'Usar subscricións IMAP';
+$labels['useimapsubscriptions'] = 'Usar suscripcións IMAP';
?>
diff --git a/plugins/subscriptions_option/localization/id_ID.inc b/plugins/subscriptions_option/localization/id_ID.inc
new file mode 100644
index 000000000..4232379c2
--- /dev/null
+++ b/plugins/subscriptions_option/localization/id_ID.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Gunakan Langganan IMAP';
+?>
diff --git a/plugins/subscriptions_option/localization/lb_LU.inc b/plugins/subscriptions_option/localization/lb_LU.inc
index d9432634b..8c1114e85 100644
--- a/plugins/subscriptions_option/localization/lb_LU.inc
+++ b/plugins/subscriptions_option/localization/lb_LU.inc
@@ -15,8 +15,5 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-subscriptions_option/
*/
-
-$labels = array();
$labels['useimapsubscriptions'] = 'IMAP-Abonnementer benotzen';
-
?>
diff --git a/plugins/subscriptions_option/localization/lv_LV.inc b/plugins/subscriptions_option/localization/lv_LV.inc
new file mode 100644
index 000000000..1b22bd148
--- /dev/null
+++ b/plugins/subscriptions_option/localization/lv_LV.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Izmantot IMAP abonēšanas iestatījumus';
+?>
diff --git a/plugins/subscriptions_option/localization/nn_NO.inc b/plugins/subscriptions_option/localization/nn_NO.inc
new file mode 100644
index 000000000..c679eac90
--- /dev/null
+++ b/plugins/subscriptions_option/localization/nn_NO.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Bruk IMAP-abonnement';
+?>
diff --git a/plugins/subscriptions_option/localization/ro_RO.inc b/plugins/subscriptions_option/localization/ro_RO.inc
new file mode 100644
index 000000000..82053c1a3
--- /dev/null
+++ b/plugins/subscriptions_option/localization/ro_RO.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/subscriptions_option/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Subscriptions plugin |
+ | Copyright (C) 2012-2013, 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/plugin-subscriptions_option/
+*/
+$labels['useimapsubscriptions'] = 'Utilizare abonări IMAP';
+?>
diff --git a/plugins/subscriptions_option/localization/ru_RU.inc b/plugins/subscriptions_option/localization/ru_RU.inc
index b332e24ba..2b25783f3 100644
--- a/plugins/subscriptions_option/localization/ru_RU.inc
+++ b/plugins/subscriptions_option/localization/ru_RU.inc
@@ -17,6 +17,6 @@
*/
$labels = array();
-$labels['useimapsubscriptions'] = 'ИÑпользовать IMAP подпиÑки';
+$labels['useimapsubscriptions'] = 'ИÑпользовать IMAP подпиÑку';
?>
diff --git a/plugins/subscriptions_option/package.xml b/plugins/subscriptions_option/package.xml
index 04f2c1b3c..79d44f8c2 100644
--- a/plugins/subscriptions_option/package.xml
+++ b/plugins/subscriptions_option/package.xml
@@ -32,7 +32,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/subscriptions_option/subscriptions_option.php b/plugins/subscriptions_option/subscriptions_option.php
index 130f16a8b..b81a5ac8a 100644
--- a/plugins/subscriptions_option/subscriptions_option.php
+++ b/plugins/subscriptions_option/subscriptions_option.php
@@ -7,12 +7,12 @@
* It includes a toggle on the settings page under "Server Settings".
* The preference can also be locked
*
- * Add it to the plugins list in config.inc.php to enable the user option
+ * Add it to the plugins list in config/main.inc.php to enable the user option
* The user option can be hidden and set globally by adding 'use_subscriptions'
* to the 'dont_override' configure line:
- * $config['dont_override'] = array('use_subscriptions');
+ * $rcmail_config['dont_override'] = array('use_subscriptions');
* and then set the global preference
- * $config['use_subscriptions'] = true; // or false
+ * $rcmail_config['use_subscriptions'] = true; // or false
*
* Roundcube caches folder lists. When a user changes this option or visits
* their folder list, this cache is refreshed. If the option is on the
@@ -21,7 +21,6 @@
*
* @version @package_version@
* @author Ziba Scott
- * @license GNU GPLv3+
*/
class subscriptions_option extends rcube_plugin
{
@@ -47,7 +46,7 @@ class subscriptions_option extends rcube_plugin
$checkbox = new html_checkbox(array('name' => '_use_subscriptions', 'id' => $field_id, 'value' => 1));
$args['blocks']['main']['options']['use_subscriptions'] = array(
- 'title' => html::label($field_id, rcube::Q($this->gettext('useimapsubscriptions'))),
+ 'title' => html::label($field_id, Q($this->gettext('useimapsubscriptions'))),
'content' => $checkbox->show($use_subscriptions?1:0),
);
}
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/plugins/userinfo/localization/ar.inc b/plugins/userinfo/localization/ar.inc
new file mode 100644
index 000000000..92d5194ee
--- /dev/null
+++ b/plugins/userinfo/localization/ar.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'معلومات المستخدم';
+$labels['lastlogin'] = 'أخر تسجيل دخول';
+$labels['defaultidentity'] = 'الهوية الاÙتراضية';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/ast.inc b/plugins/userinfo/localization/ast.inc
new file mode 100644
index 000000000..179c5ba29
--- /dev/null
+++ b/plugins/userinfo/localization/ast.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'Información d\'usuariu';
+$labels['created'] = 'Creáu';
+$labels['lastlogin'] = 'Cabera conexón';
+$labels['defaultidentity'] = 'Identidá predeterminada';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/bg_BG.inc b/plugins/userinfo/localization/bg_BG.inc
new file mode 100644
index 000000000..078c89e4a
--- /dev/null
+++ b/plugins/userinfo/localization/bg_BG.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'ПотребителÑка информациÑ';
+$labels['created'] = 'Създаден';
+$labels['lastlogin'] = 'ПоÑледен вход';
+$labels['defaultidentity'] = 'СамоличноÑÑ‚ по подразбиране';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/el_GR.inc b/plugins/userinfo/localization/el_GR.inc
new file mode 100644
index 000000000..61fa25aa3
--- /dev/null
+++ b/plugins/userinfo/localization/el_GR.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'ΠληÏοφοÏίες χÏήστη ';
+$labels['created'] = 'ΔημιουÏγηθηκε';
+$labels['lastlogin'] = 'Τελευταια συνδεση';
+$labels['defaultidentity'] = 'ΠÏοκαθοÏισμένη ταυτότητα';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/en_US.inc b/plugins/userinfo/localization/en_US.inc
index 01230de85..b269dd560 100644
--- a/plugins/userinfo/localization/en_US.inc
+++ b/plugins/userinfo/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/userinfo/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Userinfo plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/userinfo/localization/es_AR.inc b/plugins/userinfo/localization/es_AR.inc
new file mode 100644
index 000000000..fefbecef1
--- /dev/null
+++ b/plugins/userinfo/localization/es_AR.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'Información de usuario';
+$labels['created'] = 'Creado';
+$labels['lastlogin'] = 'Ultimo ingreso';
+$labels['defaultidentity'] = 'Identidad por defecto';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/eu_ES.inc b/plugins/userinfo/localization/eu_ES.inc
new file mode 100644
index 000000000..38cce04bd
--- /dev/null
+++ b/plugins/userinfo/localization/eu_ES.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'Erabiltzailearen informazioa';
+$labels['created'] = 'Sortua';
+$labels['lastlogin'] = 'Azken saioa';
+$labels['defaultidentity'] = 'Lehenetsitako identitatea';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/fa_AF.inc b/plugins/userinfo/localization/fa_AF.inc
new file mode 100644
index 000000000..8308a7f3c
--- /dev/null
+++ b/plugins/userinfo/localization/fa_AF.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'اطلاعات کاربر';
+$labels['created'] = 'ایجاد شد';
+$labels['lastlogin'] = 'آخرین ورود';
+$labels['defaultidentity'] = 'هویت پیش Ùرض';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/fr_FR.inc b/plugins/userinfo/localization/fr_FR.inc
index c830c587d..c830c587d 100755..100644
--- a/plugins/userinfo/localization/fr_FR.inc
+++ b/plugins/userinfo/localization/fr_FR.inc
diff --git a/plugins/userinfo/localization/lb_LU.inc b/plugins/userinfo/localization/lb_LU.inc
index d8394f6d8..db2e0c8c7 100644
--- a/plugins/userinfo/localization/lb_LU.inc
+++ b/plugins/userinfo/localization/lb_LU.inc
@@ -15,11 +15,8 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-userinfo/
*/
-
-$labels = array();
$labels['userinfo'] = 'Benotzer-Info';
$labels['created'] = 'Erstallt';
$labels['lastlogin'] = 'Leschte Login';
$labels['defaultidentity'] = 'Standard-Identitéit';
-
?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/ro_RO.inc b/plugins/userinfo/localization/ro_RO.inc
index 25c4d1059..2f96f849b 100755..100644
--- a/plugins/userinfo/localization/ro_RO.inc
+++ b/plugins/userinfo/localization/ro_RO.inc
@@ -17,9 +17,9 @@
*/
$labels = array();
-$labels['userinfo'] = 'Informatii utilisator';
-$labels['created'] = 'Data creatiei';
-$labels['lastlogin'] = 'Ultima conectare';
-$labels['defaultidentity'] = 'Identitate principala';
+$labels['userinfo'] = 'Informații utilizator';
+$labels['created'] = 'Data creării';
+$labels['lastlogin'] = 'Ultima autentificare';
+$labels['defaultidentity'] = 'Identitate principală';
?> \ No newline at end of file
diff --git a/plugins/userinfo/localization/ti.inc b/plugins/userinfo/localization/ti.inc
new file mode 100644
index 000000000..3799f66e4
--- /dev/null
+++ b/plugins/userinfo/localization/ti.inc
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/userinfo/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Userinfo plugin |
+ | Copyright (C) 2012-2013, 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/plugin-userinfo/
+*/
+$labels['userinfo'] = 'ሓብሬታ በዓሠዋና ';
+$labels['created'] = 'እዋን áጥረት';
+$labels['lastlogin'] = 'እዋን እታá‹';
+$labels['defaultidentity'] = 'ዘይተለወጠ መለለይ መንáŠá‰µ';
+?> \ No newline at end of file
diff --git a/plugins/userinfo/userinfo.php b/plugins/userinfo/userinfo.php
index a175563ef..efb65f51d 100644
--- a/plugins/userinfo/userinfo.php
+++ b/plugins/userinfo/userinfo.php
@@ -31,25 +31,25 @@ class userinfo extends rcube_plugin
$table = new html_table(array('cols' => 2, 'cellpadding' => 3));
$table->add('title', 'ID');
- $table->add('', rcube::Q($user->ID));
+ $table->add('', Q($user->ID));
- $table->add('title', rcube::Q($this->gettext('username')));
- $table->add('', rcube::Q($user->data['username']));
+ $table->add('title', Q($this->gettext('username')));
+ $table->add('', Q($user->data['username']));
- $table->add('title', rcube::Q($this->gettext('server')));
- $table->add('', rcube::Q($user->data['mail_host']));
+ $table->add('title', Q($this->gettext('server')));
+ $table->add('', Q($user->data['mail_host']));
- $table->add('title', rcube::Q($this->gettext('created')));
- $table->add('', rcube::Q($user->data['created']));
+ $table->add('title', Q($this->gettext('created')));
+ $table->add('', Q($user->data['created']));
- $table->add('title', rcube::Q($this->gettext('lastlogin')));
- $table->add('', rcube::Q($user->data['last_login']));
+ $table->add('title', Q($this->gettext('lastlogin')));
+ $table->add('', Q($user->data['last_login']));
$identity = $user->get_identity();
- $table->add('title', rcube::Q($this->gettext('defaultidentity')));
- $table->add('', rcube::Q($identity['name'] . ' <' . $identity['email'] . '>'));
+ $table->add('title', Q($this->gettext('defaultidentity')));
+ $table->add('', Q($identity['name'] . ' <' . $identity['email'] . '>'));
- return html::tag('h4', null, rcube::Q('Infos for ' . $user->get_username())) . $table->show();
+ return html::tag('h4', null, Q('Infos for ' . $user->get_username())) . $table->show();
}
}
diff --git a/plugins/vcard_attachments/localization/ar.inc b/plugins/vcard_attachments/localization/ar.inc
new file mode 100644
index 000000000..2d40d9bba
--- /dev/null
+++ b/plugins/vcard_attachments/localization/ar.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/vcard_attachments/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Vcard Attachments plugin |
+ | Copyright (C) 2012-2013, 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/plugin-vcard_attachments/
+*/
+$labels['addvcardmsg'] = 'إضاÙØ© vCard إلى دÙتر العناوين';
+$labels['vcardsavefailed'] = 'غير قادر على Ø­Ùظ بصيغة vCard';
+?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/ar_SA.inc b/plugins/vcard_attachments/localization/ar_SA.inc
new file mode 100644
index 000000000..47461898d
--- /dev/null
+++ b/plugins/vcard_attachments/localization/ar_SA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/vcard_attachments/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Vcard Attachments plugin |
+ | Copyright (C) 2012-2013, 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/plugin-vcard_attachments/
+*/
+$labels['addvcardmsg'] = 'إضاÙØ© صيغة vCard إلى دÙتر العناوين';
+$labels['vcardsavefailed'] = 'غير قادر على الحÙظ بصيغة vCard';
+?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/bg_BG.inc b/plugins/vcard_attachments/localization/bg_BG.inc
new file mode 100644
index 000000000..7e0b174e9
--- /dev/null
+++ b/plugins/vcard_attachments/localization/bg_BG.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/vcard_attachments/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Vcard Attachments plugin |
+ | Copyright (C) 2012-2013, 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/plugin-vcard_attachments/
+*/
+$labels['addvcardmsg'] = 'ДобавÑне на vCard към адреÑната книга';
+$labels['vcardsavefailed'] = 'Ðевъзможен Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° vCard';
+?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/el_GR.inc b/plugins/vcard_attachments/localization/el_GR.inc
new file mode 100644
index 000000000..a59f6f556
--- /dev/null
+++ b/plugins/vcard_attachments/localization/el_GR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/vcard_attachments/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Vcard Attachments plugin |
+ | Copyright (C) 2012-2013, 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/plugin-vcard_attachments/
+*/
+$labels['addvcardmsg'] = 'ΠÏοσθήκη vCard στο βιβλίο διευθÏνσεων';
+$labels['vcardsavefailed'] = 'Δεν είναι δυνατή η αποθήκευση του vCard';
+?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/en_US.inc b/plugins/vcard_attachments/localization/en_US.inc
index a52a93228..02eed29ea 100644
--- a/plugins/vcard_attachments/localization/en_US.inc
+++ b/plugins/vcard_attachments/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/vcard_attachments/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Vcard Attachments plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/vcard_attachments/localization/es_AR.inc b/plugins/vcard_attachments/localization/es_AR.inc
new file mode 100644
index 000000000..ee2f0c84b
--- /dev/null
+++ b/plugins/vcard_attachments/localization/es_AR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/vcard_attachments/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Vcard Attachments plugin |
+ | Copyright (C) 2012-2013, 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/plugin-vcard_attachments/
+*/
+$labels['addvcardmsg'] = 'Agregar vCard a la libreta de direcciones';
+$labels['vcardsavefailed'] = 'Imposible guardar vCard';
+?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/eu_ES.inc b/plugins/vcard_attachments/localization/eu_ES.inc
new file mode 100644
index 000000000..f60ac6efa
--- /dev/null
+++ b/plugins/vcard_attachments/localization/eu_ES.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/vcard_attachments/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Vcard Attachments plugin |
+ | Copyright (C) 2012-2013, 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/plugin-vcard_attachments/
+*/
+$labels['addvcardmsg'] = 'Gehitu vCard helbide-liburura';
+$labels['vcardsavefailed'] = 'Ezin da vCard gorde';
+?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/gl_ES.inc b/plugins/vcard_attachments/localization/gl_ES.inc
index 806f6bb7d..b502c85c7 100644
--- a/plugins/vcard_attachments/localization/gl_ES.inc
+++ b/plugins/vcard_attachments/localization/gl_ES.inc
@@ -17,7 +17,7 @@
*/
$labels = array();
-$labels['addvcardmsg'] = 'Engadir vCard ao caderno de enderezos';
-$labels['vcardsavefailed'] = 'Non foi posible gardar a vCard';
+$labels['addvcardmsg'] = 'Engadir a tarxeta ao caderno de enderezos';
+$labels['vcardsavefailed'] = 'Non foi posible gardar a tarxeta';
?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/lb_LU.inc b/plugins/vcard_attachments/localization/lb_LU.inc
index b9d23eaa5..005650fd7 100644
--- a/plugins/vcard_attachments/localization/lb_LU.inc
+++ b/plugins/vcard_attachments/localization/lb_LU.inc
@@ -15,9 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-vcard_attachments/
*/
-
-$labels = array();
$labels['addvcardmsg'] = 'vCard an d\'Adressbuch setzen';
$labels['vcardsavefailed'] = 'vCard kann net gespäichert ginn';
-
?> \ No newline at end of file
diff --git a/plugins/vcard_attachments/vcard_attachments.php b/plugins/vcard_attachments/vcard_attachments.php
index cf7e22d3a..e7f7d5f1f 100644
--- a/plugins/vcard_attachments/vcard_attachments.php
+++ b/plugins/vcard_attachments/vcard_attachments.php
@@ -45,7 +45,7 @@ class vcard_attachments extends rcube_plugin
}
}
// the same with message bodies
- foreach ((array)$this->message->parts as $part) {
+ foreach ((array)$this->message->parts as $idx => $part) {
if ($this->is_vcard($part)) {
$this->vcard_parts[] = $part->mime_id;
$this->vcard_bodies[] = $part->mime_id;
@@ -63,6 +63,7 @@ class vcard_attachments extends rcube_plugin
function html_output($p)
{
$attach_script = false;
+ $icon = 'plugins/vcard_attachments/' .$this->local_skin_path(). '/vcard_add_contact.png';
foreach ($this->vcard_parts as $part) {
$vcards = rcube_vcard::import($this->message->get_part_content($part, null, true));
@@ -89,10 +90,10 @@ class vcard_attachments extends rcube_plugin
$p['content'] .= html::p(array('class' => 'vcardattachment'),
html::a(array(
'href' => "#",
- 'onclick' => "return plugin_vcard_save_contact('" . rcube::JQ($part.':'.$idx) . "')",
+ 'onclick' => "return plugin_vcard_save_contact('" . JQ($part.':'.$idx) . "')",
'title' => $this->gettext('addvcardmsg'),
),
- html::span(null, rcube::Q($display)))
+ html::span(null, Q($display)))
);
}
@@ -114,9 +115,9 @@ class vcard_attachments extends rcube_plugin
{
$this->add_texts('localization', true);
- $uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
- $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
- $mime_id = rcube_utils::get_input_value('_part', rcube_utils::INPUT_POST);
+ $uid = get_input_value('_uid', RCUBE_INPUT_POST);
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
+ $mime_id = get_input_value('_part', RCUBE_INPUT_POST);
$rcmail = rcmail::get_instance();
$storage = $rcmail->get_storage();
@@ -143,7 +144,7 @@ class vcard_attachments extends rcube_plugin
}
else {
// We're using UTF8 internally
- $email = rcube_utils::idn_to_utf8($email);
+ $email = rcube_idn_to_utf8($email);
// compare e-mail address
$existing = $CONTACTS->search('email', $email, 1, false);
diff --git a/plugins/virtuser_file/virtuser_file.php b/plugins/virtuser_file/virtuser_file.php
index f2b357aaf..01032616c 100644
--- a/plugins/virtuser_file/virtuser_file.php
+++ b/plugins/virtuser_file/virtuser_file.php
@@ -3,10 +3,10 @@
/**
* File based User-to-Email and Email-to-User lookup
*
- * Add it to the plugins list in config.inc.php and set
+ * Add it to the plugins list in config/main.inc.php and set
* path to a virtuser table file to resolve user names and e-mail
* addresses
- * $rcmail['virtuser_file'] = '';
+ * $rcmail_config['virtuser_file'] = '';
*
* @version @package_version@
* @license GNU GPLv3+
@@ -19,13 +19,13 @@ class virtuser_file extends rcube_plugin
function init()
{
- $this->app = rcmail::get_instance();
- $this->file = $this->app->config->get('virtuser_file');
+ $this->app = rcmail::get_instance();
+ $this->file = $this->app->config->get('virtuser_file');
- if ($this->file) {
- $this->add_hook('user2email', array($this, 'user2email'));
- $this->add_hook('email2user', array($this, 'email2user'));
- }
+ if ($this->file) {
+ $this->add_hook('user2email', array($this, 'user2email'));
+ $this->add_hook('email2user', array($this, 'email2user'));
+ }
}
/**
@@ -34,24 +34,25 @@ class virtuser_file extends rcube_plugin
function user2email($p)
{
$r = $this->findinvirtual('/\s' . preg_quote($p['user'], '/') . '\s*$/');
- $result = array();
+ $result = array();
- for ($i=0; $i<count($r); $i++) {
- $arr = preg_split('/\s+/', $r[$i]);
+ for ($i=0; $i<count($r); $i++)
+ {
+ $arr = preg_split('/\s+/', $r[$i]);
- if (count($arr) > 0 && strpos($arr[0], '@')) {
- $result[] = rcube_utils::idn_to_ascii(trim(str_replace('\\@', '@', $arr[0])));
+ if (count($arr) > 0 && strpos($arr[0], '@')) {
+ $result[] = rcube_idn_to_ascii(trim(str_replace('\\@', '@', $arr[0])));
- if ($p['first']) {
- $p['email'] = $result[0];
- break;
- }
- }
- }
+ if ($p['first']) {
+ $p['email'] = $result[0];
+ break;
+ }
+ }
+ }
- $p['email'] = empty($result) ? NULL : $result;
+ $p['email'] = empty($result) ? NULL : $result;
- return $p;
+ return $p;
}
/**
@@ -59,18 +60,18 @@ class virtuser_file extends rcube_plugin
*/
function email2user($p)
{
- $r = $this->findinvirtual('/^' . preg_quote($p['email'], '/') . '\s/');
+ $r = $this->findinvirtual('/^' . preg_quote($p['email'], '/') . '\s/');
- for ($i=0; $i<count($r); $i++) {
- $arr = preg_split('/\s+/', trim($r[$i]));
+ for ($i=0; $i<count($r); $i++) {
+ $arr = preg_split('/\s+/', trim($r[$i]));
- if (count($arr) > 0) {
- $p['user'] = trim($arr[count($arr)-1]);
- break;
- }
- }
+ if (count($arr) > 0) {
+ $p['user'] = trim($arr[count($arr)-1]);
+ break;
+ }
+ }
- return $p;
+ return $p;
}
/**
@@ -81,25 +82,26 @@ class virtuser_file extends rcube_plugin
*/
private function findinvirtual($pattern)
{
- $result = array();
- $virtual = null;
+ $result = array();
+ $virtual = null;
- if ($this->file)
- $virtual = file($this->file);
+ if ($this->file)
+ $virtual = file($this->file);
- if (empty($virtual))
- return $result;
+ if (empty($virtual))
+ return $result;
- // check each line for matches
- foreach ($virtual as $line) {
- $line = trim($line);
- if (empty($line) || $line[0]=='#')
- continue;
+ // check each line for matches
+ foreach ($virtual as $line) {
+ $line = trim($line);
+ if (empty($line) || $line[0]=='#')
+ continue;
- if (preg_match($pattern, $line))
- $result[] = $line;
- }
+ if (preg_match($pattern, $line))
+ $result[] = $line;
+ }
- return $result;
+ return $result;
}
+
}
diff --git a/plugins/virtuser_query/package.xml b/plugins/virtuser_query/package.xml
index 9430bf69d..58f697019 100644
--- a/plugins/virtuser_query/package.xml
+++ b/plugins/virtuser_query/package.xml
@@ -13,16 +13,16 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
- <date>2012-02-17</date>
+ <date>2011-11-21</date>
<version>
- <release>2.0</release>
- <api>2.0</api>
+ <release>1.1</release>
+ <api>1.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/virtuser_query/virtuser_query.php b/plugins/virtuser_query/virtuser_query.php
index a0b748288..a4c83265e 100644
--- a/plugins/virtuser_query/virtuser_query.php
+++ b/plugins/virtuser_query/virtuser_query.php
@@ -3,7 +3,7 @@
/**
* DB based User-to-Email and Email-to-User lookup
*
- * Add it to the plugins list in config.inc.php and set
+ * Add it to the plugins list in config/main.inc.php and set
* SQL queries to resolve usernames, e-mail addresses and hostnames from the database
* %u will be replaced with the current username for login.
* %m will be replaced with the current e-mail address for login.
@@ -12,29 +12,23 @@
* The email query could optionally select identity data columns in specified order:
* name, organization, reply-to, bcc, signature, html_signature
*
- * $config['virtuser_query'] = array('email' => '', 'user' => '', 'host' => '', 'alias' => '');
+ * $rcmail_config['virtuser_query'] = array('email' => '', 'user' => '', 'host' => '');
*
* The email query can return more than one record to create more identities.
* This requires identities_level option to be set to value less than 2.
*
- * By default Roundcube database is used. To use different database (or host)
- * you can specify DSN string in $config['virtuser_query_dsn'] option.
- *
* @version @package_version@
* @author Aleksander Machniak <alec@alec.pl>
* @author Steffen Vogel
- * @author Tim Gerundt
- * @license GNU GPLv3+
*/
class virtuser_query extends rcube_plugin
{
private $config;
private $app;
- private $db;
function init()
{
- $this->app = rcmail::get_instance();
+ $this->app = rcmail::get_instance();
$this->config = $this->app->config->get('virtuser_query');
if (!empty($this->config)) {
@@ -51,9 +45,6 @@ class virtuser_query extends rcube_plugin
if ($this->config['host']) {
$this->add_hook('authenticate', array($this, 'user2host'));
}
- if ($this->config['alias']) {
- $this->add_hook('authenticate', array($this, 'alias2user'));
- }
}
}
@@ -62,7 +53,7 @@ class virtuser_query extends rcube_plugin
*/
function user2email($p)
{
- $dbh = $this->get_dbh();
+ $dbh = $this->app->get_dbh();
$sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['email']));
@@ -70,11 +61,11 @@ class virtuser_query extends rcube_plugin
if (strpos($sql_arr[0], '@')) {
if ($p['extended'] && count($sql_arr) > 1) {
$result[] = array(
- 'email' => rcube_utils::idn_to_ascii($sql_arr[0]),
+ 'email' => rcube_idn_to_ascii($sql_arr[0]),
'name' => $sql_arr[1],
'organization' => $sql_arr[2],
- 'reply-to' => rcube_utils::idn_to_ascii($sql_arr[3]),
- 'bcc' => rcube_utils::idn_to_ascii($sql_arr[4]),
+ 'reply-to' => rcube_idn_to_ascii($sql_arr[3]),
+ 'bcc' => rcube_idn_to_ascii($sql_arr[4]),
'signature' => $sql_arr[5],
'html_signature' => (int)$sql_arr[6],
);
@@ -99,7 +90,7 @@ class virtuser_query extends rcube_plugin
*/
function email2user($p)
{
- $dbh = $this->get_dbh();
+ $dbh = $this->app->get_dbh();
$sql_result = $dbh->query(preg_replace('/%m/', $dbh->escape($p['email']), $this->config['user']));
@@ -115,7 +106,7 @@ class virtuser_query extends rcube_plugin
*/
function user2host($p)
{
- $dbh = $this->get_dbh();
+ $dbh = $this->app->get_dbh();
$sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['host']));
@@ -126,40 +117,5 @@ class virtuser_query extends rcube_plugin
return $p;
}
- /**
- * Alias > User
- */
- function alias2user($p)
- {
- $dbh = $this->get_dbh();
-
- $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['alias']));
-
- if ($sql_arr = $dbh->fetch_array($sql_result)) {
- $p['user'] = $sql_arr[0];
- }
-
- return $p;
- }
-
- /**
- * Initialize database handler
- */
- function get_dbh()
- {
- if (!$this->db) {
- if ($dsn = $this->app->config->get('virtuser_query_dsn')) {
- // connect to the virtuser database
- $this->db = rcube_db::factory($dsn);
- $this->db->set_debug((bool)$this->app->config->get('sql_debug'));
- $this->db->db_connect('r'); // connect in read mode
- }
- else {
- $this->db = $this->app->get_dbh();
- }
- }
-
- return $this->db;
- }
-
}
+
diff --git a/plugins/zipdownload/README b/plugins/zipdownload/README
index f253d63ee..4fa3c17b6 100644
--- a/plugins/zipdownload/README
+++ b/plugins/zipdownload/README
@@ -23,7 +23,7 @@ folder for details on the skin license.
Install
=======
* Place this plugin folder into plugins directory of Roundcube
-* Add zipdownload to $config['plugins'] in your Roundcube config
+* Add zipdownload to $rcmail_config['plugins'] in your Roundcube config
NB: When downloading the plugin from GitHub you will need to create a
directory called zipdownload and place the files in there, ignoring the
diff --git a/plugins/zipdownload/config.inc.php.dist b/plugins/zipdownload/config.inc.php.dist
index 0b2d14b60..5c7489a15 100644
--- a/plugins/zipdownload/config.inc.php.dist
+++ b/plugins/zipdownload/config.inc.php.dist
@@ -7,15 +7,15 @@
// Zip attachments
// Only show the link when there are more than this many attachments
// -1 to prevent downloading of attachments as zip
-$config['zipdownload_attachments'] = 1;
+$rcmail_config['zipdownload_attachments'] = 1;
// Zip entire folders
-$config['zipdownload_folder'] = false;
+$rcmail_config['zipdownload_folder'] = false;
// Zip selection of messages
-$config['zipdownload_selection'] = false;
+$rcmail_config['zipdownload_selection'] = false;
// Charset to use for filenames inside the zip
-$config['zipdownload_charset'] = 'ISO-8859-1';
+$rcmail_config['zipdownload_charset'] = 'ISO-8859-1';
?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/ar.inc b/plugins/zipdownload/localization/ar.inc
new file mode 100644
index 000000000..c5857c96c
--- /dev/null
+++ b/plugins/zipdownload/localization/ar.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'تنزيل كل المرÙقات';
+$labels['downloadfolder'] = 'تنزيل المجلد';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/ar_SA.inc b/plugins/zipdownload/localization/ar_SA.inc
new file mode 100644
index 000000000..dd5f5f349
--- /dev/null
+++ b/plugins/zipdownload/localization/ar_SA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'تحميل جميع المرÙقات';
+$labels['downloadfolder'] = 'تحميل المجلد';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/be_BE.inc b/plugins/zipdownload/localization/be_BE.inc
new file mode 100644
index 000000000..7c6fb3876
--- /dev/null
+++ b/plugins/zipdownload/localization/be_BE.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Спампаваць уÑе далучÑнні';
+$labels['downloadfolder'] = 'Спампаваць папку';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/bg_BG.inc b/plugins/zipdownload/localization/bg_BG.inc
new file mode 100644
index 000000000..69f91f6f2
--- /dev/null
+++ b/plugins/zipdownload/localization/bg_BG.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'ИзтеглÑне на вÑички прикачени файлове';
+$labels['downloadfolder'] = 'ИзтеглÑне на папка';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/el_GR.inc b/plugins/zipdownload/localization/el_GR.inc
new file mode 100644
index 000000000..2a12b5da0
--- /dev/null
+++ b/plugins/zipdownload/localization/el_GR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Λυψη ολων των συννημενων';
+$labels['downloadfolder'] = 'Λυψη φακελου';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/en_US.inc b/plugins/zipdownload/localization/en_US.inc
index aee8a5e15..8823d3b8d 100644
--- a/plugins/zipdownload/localization/en_US.inc
+++ b/plugins/zipdownload/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/zipdownload/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Zipdownload plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
diff --git a/plugins/zipdownload/localization/eo.inc b/plugins/zipdownload/localization/eo.inc
new file mode 100644
index 000000000..bc6ef9d69
--- /dev/null
+++ b/plugins/zipdownload/localization/eo.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'ElÅuti ĉiujn kunsendaĵojn';
+$labels['downloadfolder'] = 'ElÅuti dosierujon';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/eu_ES.inc b/plugins/zipdownload/localization/eu_ES.inc
new file mode 100644
index 000000000..0be09c8b2
--- /dev/null
+++ b/plugins/zipdownload/localization/eu_ES.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Deskargatu eranskin guztiak';
+$labels['downloadfolder'] = 'Deskargatu karpeta';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/fa_AF.inc b/plugins/zipdownload/localization/fa_AF.inc
new file mode 100644
index 000000000..57bb55ea4
--- /dev/null
+++ b/plugins/zipdownload/localization/fa_AF.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'بارگزاری همه ضمیمه ها';
+$labels['downloadfolder'] = 'بارگزاری پوشه';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/fi_FI.inc b/plugins/zipdownload/localization/fi_FI.inc
new file mode 100644
index 000000000..7e2c3137d
--- /dev/null
+++ b/plugins/zipdownload/localization/fi_FI.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Lataa kaikki liitteet';
+$labels['downloadfolder'] = 'Lataa kansio';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/id_ID.inc b/plugins/zipdownload/localization/id_ID.inc
new file mode 100644
index 000000000..2ff3c87df
--- /dev/null
+++ b/plugins/zipdownload/localization/id_ID.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Unduh semua lampiran';
+$labels['downloadfolder'] = 'Folder download';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/ko_KR.inc b/plugins/zipdownload/localization/ko_KR.inc
new file mode 100644
index 000000000..cae831353
--- /dev/null
+++ b/plugins/zipdownload/localization/ko_KR.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = '모든 첨부파ì¼ì„ 다운로드';
+$labels['downloadfolder'] = '다운로드 í´ë”';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/lb_LU.inc b/plugins/zipdownload/localization/lb_LU.inc
index 6721c51cb..434b064dd 100644
--- a/plugins/zipdownload/localization/lb_LU.inc
+++ b/plugins/zipdownload/localization/lb_LU.inc
@@ -15,9 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-zipdownload/
*/
-
-$labels = array();
$labels['downloadall'] = 'All d\'Unhäng eroflueden';
$labels['downloadfolder'] = 'Dossier eroflueden';
-
?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/lv_LV.inc b/plugins/zipdownload/localization/lv_LV.inc
new file mode 100644
index 000000000..b23417abc
--- /dev/null
+++ b/plugins/zipdownload/localization/lv_LV.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'LejupielÄdÄ“t visus pielikumus';
+$labels['downloadfolder'] = 'LejupielÄdÄ“t mapi';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/ro_RO.inc b/plugins/zipdownload/localization/ro_RO.inc
index 7cba54d32..ac4a983d6 100644
--- a/plugins/zipdownload/localization/ro_RO.inc
+++ b/plugins/zipdownload/localization/ro_RO.inc
@@ -17,7 +17,7 @@
*/
$labels = array();
-$labels['downloadall'] = 'Descarca toate atasamentele.';
-$labels['downloadfolder'] = 'Dosar de descărcare';
+$labels['downloadall'] = 'Descarcă toate atașamentele';
+$labels['downloadfolder'] = 'Descarcă dosar';
?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/ru_RU.inc b/plugins/zipdownload/localization/ru_RU.inc
index 0b58fa7fa..014b2001e 100644
--- a/plugins/zipdownload/localization/ru_RU.inc
+++ b/plugins/zipdownload/localization/ru_RU.inc
@@ -18,6 +18,6 @@
$labels = array();
$labels['downloadall'] = 'Загрузить вÑе вложениÑ';
-$labels['downloadfolder'] = 'Загрузить папку';
+$labels['downloadfolder'] = 'Загрузить каталог';
?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/sl_SI.inc b/plugins/zipdownload/localization/sl_SI.inc
new file mode 100644
index 000000000..07caeacbc
--- /dev/null
+++ b/plugins/zipdownload/localization/sl_SI.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Prenesi vse priponke';
+$labels['downloadfolder'] = 'Prenesi mapo';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/uk_UA.inc b/plugins/zipdownload/localization/uk_UA.inc
new file mode 100644
index 000000000..6232e9a2c
--- /dev/null
+++ b/plugins/zipdownload/localization/uk_UA.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = 'Завантажити вÑÑ– вкладеннÑ';
+$labels['downloadfolder'] = 'Завантажити теку';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/localization/zh_CN.inc b/plugins/zipdownload/localization/zh_CN.inc
new file mode 100644
index 000000000..dfa8db34a
--- /dev/null
+++ b/plugins/zipdownload/localization/zh_CN.inc
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/zipdownload/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Zipdownload plugin |
+ | Copyright (C) 2012-2013, 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/plugin-zipdownload/
+*/
+$labels['downloadall'] = '下载全部附件';
+$labels['downloadfolder'] = '下载文件夹';
+?> \ No newline at end of file
diff --git a/plugins/zipdownload/skins/larry/zipdownload.css b/plugins/zipdownload/skins/larry/zipdownload.css
index bb92631b1..d719ac677 100644
--- a/plugins/zipdownload/skins/larry/zipdownload.css
+++ b/plugins/zipdownload/skins/larry/zipdownload.css
@@ -2,6 +2,6 @@
a.zipdownload {
display: inline-block;
- margin-top: .5em;
+ margin-top: 1.5em;
padding: 3px 5px 4px 5px;
-}
+} \ No newline at end of file
diff --git a/plugins/zipdownload/zipdownload.php b/plugins/zipdownload/zipdownload.php
index 59431267d..443fef728 100644
--- a/plugins/zipdownload/zipdownload.php
+++ b/plugins/zipdownload/zipdownload.php
@@ -62,14 +62,11 @@ class zipdownload extends rcube_plugin
// only show the link if there is more than the configured number of attachments
if (substr_count($p['content'], '<li') > $rcmail->config->get('zipdownload_attachments', 1)) {
- $href = $rcmail->url(array(
- '_action' => 'plugin.zipdownload.zip_attachments',
- '_mbox' => $rcmail->output->env['mailbox'],
- '_uid' => $rcmail->output->env['uid'],
- ));
-
- $link = html::a(array('href' => $href, 'class' => 'button zipdownload'),
- rcube::Q($this->gettext('downloadall'))
+ $link = html::a(array(
+ 'href' => rcmail_url('plugin.zipdownload.zip_attachments', array('_mbox' => $rcmail->output->env['mailbox'], '_uid' => $rcmail->output->env['uid'])),
+ 'class' => 'button zipdownload',
+ ),
+ Q($this->gettext('downloadall'))
);
// append link to attachments list, slightly different in some skins
@@ -99,7 +96,7 @@ class zipdownload extends rcube_plugin
$temp_dir = $rcmail->config->get('temp_dir');
$tmpfname = tempnam($temp_dir, 'zipdownload');
$tempfiles = array($tmpfname);
- $message = new rcube_message(rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET));
+ $message = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET));
// open zip file
$zip = new ZipArchive();
@@ -143,7 +140,7 @@ class zipdownload extends rcube_plugin
public function download_selection()
{
if (isset($_REQUEST['_uid'])) {
- $uids = explode(",", rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GPC));
+ $uids = explode(",", get_input_value('_uid', RCUBE_INPUT_GPC));
if (sizeof($uids) > 0)
$this->_download_messages($uids);
@@ -160,7 +157,7 @@ class zipdownload extends rcube_plugin
// initialize searching result if search_filter is used
if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') {
- $imap->search($mbox_name, $_SESSION['search_filter'], RCUBE_CHARSET);
+ $imap->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET);
}
// fetch message headers for all pages
@@ -169,7 +166,7 @@ class zipdownload extends rcube_plugin
for ($i = 0; ($i * $imap->get_pagesize()) <= $count; $i++) {
$a_headers = $imap->list_messages($mbox_name, ($i + 1));
- foreach ($a_headers as $header) {
+ foreach ($a_headers as $n => $header) {
if (empty($header))
continue;
@@ -199,7 +196,7 @@ class zipdownload extends rcube_plugin
$zip = new ZipArchive();
$zip->open($tmpfname, ZIPARCHIVE::OVERWRITE);
- foreach ($uids as $uid){
+ foreach ($uids as $key => $uid){
$headers = $imap->get_message_headers($uid);
$subject = rcube_mime::decode_mime_string((string)$headers->subject);
$subject = $this->_convert_filename($subject);
@@ -237,9 +234,7 @@ class zipdownload extends rcube_plugin
private function _deliver_zipfile($tmpfname, $filename)
{
$browser = new rcube_browser;
- $rcmail = rcmail::get_instance();
-
- $rcmail->output->nocacheing_headers();
+ send_nocacheing_headers();
if ($browser->ie && $browser->ver < 7)
$filename = rawurlencode(abbreviate_string($filename, 55));
diff --git a/program/include/bc.php b/program/include/bc.php
index a7d7b5ac1..af2e51210 100644
--- a/program/include/bc.php
+++ b/program/include/bc.php
@@ -62,7 +62,7 @@ function rcmail_url($action, $p=array(), $task=null)
function rcmail_temp_gc()
{
- rcmail::get_instance()->gc_temp();
+ $rcmail = rcmail::get_instance()->temp_gc();
}
function rcube_charset_convert($str, $from, $to=NULL)
@@ -205,9 +205,9 @@ function rcmail_quota_content($attrib = null)
return rcmail::get_instance()->quota_content($attrib);
}
-function rcmail_display_server_error($fallback=null, $fallback_args=null, $suffix='')
+function rcmail_display_server_error($fallback=null, $fallback_args=null)
{
- rcmail::get_instance()->display_server_error($fallback, $fallback_args, $suffix);
+ rcmail::get_instance()->display_server_error($fallback, $fallback_args);
}
function rcmail_filetype2classname($mimetype, $filename)
@@ -405,16 +405,6 @@ function enriched_to_html($data)
return rcube_enriched::to_html($data);
}
-function strip_quotes($str)
-{
- return str_replace(array("'", '"'), '', $str);
-}
-
-function strip_newlines($str)
-{
- return preg_replace('/[\r\n]/', '', $str);
-}
-
class rcube_html_page extends rcmail_html_page
{
}
diff --git a/program/include/iniset.php b/program/include/iniset.php
index 919cc7682..e4fa956ef 100644
--- a/program/include/iniset.php
+++ b/program/include/iniset.php
@@ -21,11 +21,11 @@
*/
// application constants
-define('RCMAIL_VERSION', '1.0-git');
+define('RCMAIL_VERSION', '0.9.5');
define('RCMAIL_START', microtime(true));
if (!defined('INSTALL_PATH')) {
- define('INSTALL_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/');
+ define('INSTALL_PATH', '/var/lib/roundcube/');
}
if (!defined('RCMAIL_CONFIG_DIR')) {
@@ -60,11 +60,6 @@ require_once 'Roundcube/bootstrap.php';
// register autoloader for rcmail app classes
spl_autoload_register('rcmail_autoload');
-// include composer autoloader (if available)
-if (file_exists('vendor/autoload.php')) {
- require 'vendor/autoload.php';
-}
-
// backward compatybility (to be removed)
require_once INSTALL_PATH . 'program/include/bc.php';
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 0483f0e18..c9350bdd9 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -51,7 +51,6 @@ class rcmail extends rcube
*/
public $action = '';
public $comm_path = './';
- public $filename = '';
private $address_books = array();
private $action_map = array();
@@ -66,13 +65,12 @@ class rcmail extends rcube
/**
* This implements the 'singleton' design pattern
*
- * @param string Environment name to run (e.g. live, dev, test)
* @return rcmail The one and only instance
*/
- static function get_instance($env = '')
+ static function get_instance()
{
if (!self::$instance || !is_a(self::$instance, 'rcmail')) {
- self::$instance = new rcmail($env);
+ self::$instance = new rcmail();
self::$instance->startup(); // init AFTER object was linked with self::$instance
}
@@ -88,10 +86,6 @@ class rcmail extends rcube
{
$this->init(self::INIT_WITH_DB | self::INIT_WITH_PLUGINS);
- // set filename if not index.php
- if (($basename = basename($_SERVER['SCRIPT_FILENAME'])) && $basename != 'index.php')
- $this->filename = $basename;
-
// start session
$this->session_init();
@@ -132,7 +126,7 @@ class rcmail extends rcube
*/
public function set_task($task)
{
- $task = asciiwords($task, true);
+ $task = asciiwords($task);
if ($this->user && $this->user->ID)
$task = !$task ? 'mail' : $task;
@@ -168,7 +162,7 @@ class rcmail extends rcube
setlocale(LC_ALL, $lang . '.utf8', $lang . '.UTF-8', 'en_US.utf8', 'en_US.UTF-8');
// workaround for http://bugs.php.net/bug.php?id=18556
- if (version_compare(PHP_VERSION, '5.5.0', '<') && in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
+ if (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8');
}
}
@@ -289,13 +283,13 @@ class rcmail extends rcube
*/
public function get_address_sources($writeable = false, $skip_hidden = false)
{
- $abook_type = (string) $this->config->get('address_book_type');
- $ldap_config = (array) $this->config->get('ldap_public');
+ $abook_type = strtolower($this->config->get('address_book_type'));
+ $ldap_config = $this->config->get('ldap_public');
$autocomplete = (array) $this->config->get('autocomplete_addressbooks');
- $list = array();
+ $list = array();
// We are using the DB address book or a plugin address book
- if (!empty($abook_type) && strtolower($abook_type) != 'ldap') {
+ if ($abook_type != 'ldap' && $abook_type != '') {
if (!isset($this->address_books['0']))
$this->address_books['0'] = new rcube_contacts($this->db, $this->get_user_id());
$list['0'] = array(
@@ -308,7 +302,8 @@ class rcmail extends rcube
);
}
- if (!empty($ldap_config)) {
+ if ($ldap_config) {
+ $ldap_config = (array) $ldap_config;
foreach ($ldap_config as $id => $prop) {
// handle misconfiguration
if (empty($prop) || !is_array($prop)) {
@@ -317,7 +312,7 @@ class rcmail extends rcube
$list[$id] = array(
'id' => $id,
'name' => html::quote($prop['name']),
- 'groups' => !empty($prop['groups']) || !empty($prop['group_filters']),
+ 'groups' => is_array($prop['groups']),
'readonly' => !$prop['writable'],
'hidden' => $prop['hidden'],
'autocomplete' => in_array($id, $autocomplete)
@@ -481,22 +476,15 @@ class rcmail extends rcube
$port = $config['default_port'];
}
- // Check if we need to add/force domain to username
- if (!empty($config['username_domain'])) {
- $domain = is_array($config['username_domain']) ? $config['username_domain'][$host] : $config['username_domain'];
-
- if ($domain = rcube_utils::parse_host((string)$domain, $host)) {
- $pos = strpos($username, '@');
-
- // force configured domains
- if (!empty($config['username_domain_forced']) && $pos !== false) {
- $username = substr($username, 0, $pos) . '@' . $domain;
- }
- // just add domain if not specified
- else if ($pos === false) {
- $username .= '@' . $domain;
- }
- }
+ /* Modify username with domain if required
+ Inspired by Marco <P0L0_notspam_binware.org>
+ */
+ // Check if we need to add domain
+ if (!empty($config['username_domain']) && strpos($username, '@') === false) {
+ if (is_array($config['username_domain']) && isset($config['username_domain'][$host]))
+ $username .= '@'.rcube_utils::parse_host($config['username_domain'][$host], $host);
+ else if (is_string($config['username_domain']))
+ $username .= '@'.rcube_utils::parse_host($config['username_domain'], $host);
}
if (!isset($config['login_lc'])) {
@@ -631,7 +619,7 @@ class rcmail extends rcube
$post_host = rcube_utils::get_input_value('_host', rcube_utils::INPUT_POST);
$post_user = rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST);
- list(, $domain) = explode('@', $post_user);
+ list($user, $domain) = explode('@', $post_user);
// direct match in default_host array
if ($default_host[$post_host] || in_array($post_host, array_values($default_host))) {
@@ -735,6 +723,28 @@ class rcmail extends rcube
/**
+ * Create unique authorization hash
+ *
+ * @param string Session ID
+ * @param int Timestamp
+ * @return string The generated auth hash
+ */
+ private function get_auth_hash($sess_id, $ts)
+ {
+ $auth_string = sprintf('rcmail*sess%sR%s*Chk:%s;%s',
+ $sess_id,
+ $ts,
+ $this->config->get('ip_check') ? $_SERVER['REMOTE_ADDR'] : '***.***.***.***',
+ $_SERVER['HTTP_USER_AGENT']);
+
+ if (function_exists('sha1'))
+ return sha1($auth_string);
+ else
+ return md5($auth_string);
+ }
+
+
+ /**
* Build a valid URL to this instance of Roundcube
*
* @param mixed Either a string with the action or url parameters as key-value pairs
@@ -754,7 +764,7 @@ class rcmail extends rcube
$p['_task'] = $task;
unset($p['task']);
- $url = './' . $this->filename;
+ $url = './';
$delm = '?';
foreach (array_reverse($p) as $key => $val) {
if ($val !== '' && $val !== null) {
@@ -779,6 +789,11 @@ class rcmail extends rcube
$book->close();
}
+ // before closing the database connection, write session data
+ if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
+ session_write_close();
+ }
+
// write performance stats to logs/console
if ($this->config->get('devel_mode')) {
if (function_exists('memory_get_usage'))
@@ -939,6 +954,193 @@ class rcmail extends rcube
/**
+ * Send the given message using the configured method.
+ *
+ * @param object $message Reference to Mail_MIME object
+ * @param string $from Sender address string
+ * @param array $mailto Array of recipient address strings
+ * @param array $error SMTP error array (reference)
+ * @param string $body_file Location of file with saved message body (reference),
+ * used when delay_file_io is enabled
+ * @param array $options SMTP options (e.g. DSN request)
+ *
+ * @return boolean Send status.
+ */
+ public function deliver_message(&$message, $from, $mailto, &$error, &$body_file = null, $options = null)
+ {
+ $plugin = $this->plugins->exec_hook('message_before_send', array(
+ 'message' => $message,
+ 'from' => $from,
+ 'mailto' => $mailto,
+ 'options' => $options,
+ ));
+
+ if ($plugin['abort']) {
+ return isset($plugin['result']) ? $plugin['result'] : false;
+ }
+
+ $from = $plugin['from'];
+ $mailto = $plugin['mailto'];
+ $options = $plugin['options'];
+ $message = $plugin['message'];
+ $headers = $message->headers();
+
+ // send thru SMTP server using custom SMTP library
+ if ($this->config->get('smtp_server')) {
+ // generate list of recipients
+ $a_recipients = array($mailto);
+
+ if (strlen($headers['Cc']))
+ $a_recipients[] = $headers['Cc'];
+ if (strlen($headers['Bcc']))
+ $a_recipients[] = $headers['Bcc'];
+
+ // clean Bcc from header for recipients
+ $send_headers = $headers;
+ unset($send_headers['Bcc']);
+ // here too, it because txtHeaders() below use $message->_headers not only $send_headers
+ unset($message->_headers['Bcc']);
+
+ $smtp_headers = $message->txtHeaders($send_headers, true);
+
+ if ($message->getParam('delay_file_io')) {
+ // use common temp dir
+ $temp_dir = $this->config->get('temp_dir');
+ $body_file = tempnam($temp_dir, 'rcmMsg');
+ if (PEAR::isError($mime_result = $message->saveMessageBody($body_file))) {
+ self::raise_error(array('code' => 650, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Could not create message: ".$mime_result->getMessage()),
+ TRUE, FALSE);
+ return false;
+ }
+ $msg_body = fopen($body_file, 'r');
+ }
+ else {
+ $msg_body = $message->get();
+ }
+
+ // send message
+ if (!is_object($this->smtp)) {
+ $this->smtp_init(true);
+ }
+
+ $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $options);
+ $response = $this->smtp->get_response();
+ $error = $this->smtp->get_error();
+
+ // log error
+ if (!$sent) {
+ self::raise_error(array('code' => 800, 'type' => 'smtp',
+ 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => "SMTP error: ".join("\n", $response)), TRUE, FALSE);
+ }
+ }
+ // send mail using PHP's mail() function
+ else {
+ // unset some headers because they will be added by the mail() function
+ $headers_enc = $message->headers($headers);
+ $headers_php = $message->_headers;
+ unset($headers_php['To'], $headers_php['Subject']);
+
+ // reset stored headers and overwrite
+ $message->_headers = array();
+ $header_str = $message->txtHeaders($headers_php);
+
+ // #1485779
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) {
+ $headers_enc['To'] = implode(', ', $m[1]);
+ }
+ }
+
+ $msg_body = $message->get();
+
+ if (PEAR::isError($msg_body)) {
+ self::raise_error(array('code' => 650, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Could not create message: ".$msg_body->getMessage()),
+ TRUE, FALSE);
+ }
+ else {
+ $delim = $this->config->header_delimiter();
+ $to = $headers_enc['To'];
+ $subject = $headers_enc['Subject'];
+ $header_str = rtrim($header_str);
+
+ if ($delim != "\r\n") {
+ $header_str = str_replace("\r\n", $delim, $header_str);
+ $msg_body = str_replace("\r\n", $delim, $msg_body);
+ $to = str_replace("\r\n", $delim, $to);
+ $subject = str_replace("\r\n", $delim, $subject);
+ }
+
+ if (filter_var(ini_get('safe_mode'), FILTER_VALIDATE_BOOLEAN))
+ $sent = mail($to, $subject, $msg_body, $header_str);
+ else
+ $sent = mail($to, $subject, $msg_body, $header_str, "-f$from");
+ }
+ }
+
+ if ($sent) {
+ $this->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body));
+
+ // remove MDN headers after sending
+ unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']);
+
+ // get all recipients
+ if ($headers['Cc'])
+ $mailto .= $headers['Cc'];
+ if ($headers['Bcc'])
+ $mailto .= $headers['Bcc'];
+ if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m))
+ $mailto = implode(', ', array_unique($m[1]));
+
+ if ($this->config->get('smtp_log')) {
+ self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s",
+ $this->user->get_username(),
+ $_SERVER['REMOTE_ADDR'],
+ $mailto,
+ !empty($response) ? join('; ', $response) : ''));
+ }
+ }
+
+ if (is_resource($msg_body)) {
+ fclose($msg_body);
+ }
+
+ $message->_headers = array();
+ $message->headers($headers);
+
+ return $sent;
+ }
+
+
+ /**
+ * Unique Message-ID generator.
+ *
+ * @return string Message-ID
+ */
+ public function gen_message_id()
+ {
+ $local_part = md5(uniqid('rcmail'.mt_rand(),true));
+ $domain_part = $this->user->get_username('domain');
+
+ // Try to find FQDN, some spamfilters doesn't like 'localhost' (#1486924)
+ if (!preg_match('/\.[a-z]+$/i', $domain_part)) {
+ foreach (array($_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME']) as $host) {
+ $host = preg_replace('/:[0-9]+$/', '', $host);
+ if ($host && preg_match('/\.[a-z]+$/i', $host)) {
+ $domain_part = $host;
+ }
+ }
+ }
+
+ return sprintf('<%s@%s>', $local_part, $domain_part);
+ }
+
+
+ /**
* Returns RFC2822 formatted current date in user's timezone
*
* @return string Date
@@ -961,32 +1163,22 @@ class rcmail extends rcube
/**
* Write login data (name, ID, IP address) to the 'userlogins' log file.
*/
- public function log_login($user = null, $failed_login = false, $error_code = 0)
+ public function log_login()
{
if (!$this->config->get('log_logins')) {
return;
}
- // failed login
- if ($failed_login) {
- $message = sprintf('Failed login for %s from %s in session %s (error: %d)',
- $user, rcube_utils::remote_ip(), session_id(), $error_code);
- }
- // successful login
- else {
- $user_name = $this->get_user_name();
- $user_id = $this->get_user_id();
+ $user_name = $this->get_user_name();
+ $user_id = $this->get_user_id();
- if (!$user_id) {
- return;
- }
-
- $message = sprintf('Successful login for %s (ID: %d) from %s in session %s',
- $user_name, $user_id, rcube_utils::remote_ip(), session_id());
+ if (!$user_id) {
+ return;
}
- // log login
- self::write_log('userlogins', $message);
+ self::write_log('userlogins',
+ sprintf('Successful login for %s (ID: %d) from %s in session %s',
+ $user_name, $user_id, rcube_utils::remote_ip(), session_id()));
}
@@ -1002,7 +1194,7 @@ class rcmail extends rcube
*/
public function table_output($attrib, $table_data, $a_show_cols, $id_col)
{
- $table = new html_table($attrib);
+ $table = new html_table(/*array('cols' => count($a_show_cols))*/);
// add table header
if (!$attrib['noheader']) {
@@ -1243,7 +1435,6 @@ class rcmail extends rcube
$js_mailboxlist = array();
$out = html::tag('ul', $attrib, $rcmail->render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
- $rcmail->output->include_script('treelist.js');
$rcmail->output->add_gui_object('mailboxlist', $attrib['id']);
$rcmail->output->set_env('mailboxes', $js_mailboxlist);
$rcmail->output->set_env('unreadwrap', $attrib['unreadwrap']);
@@ -1365,10 +1556,9 @@ class rcmail extends rcube
$realnames = (bool)$attrib['realnames'];
$msgcounts = $this->storage->get_cache('messagecount');
$collapsed = $this->config->get('collapsed_folders');
- $realnames = $this->config->get('show_real_foldernames');
$out = '';
- foreach ($arrFolders as $folder) {
+ foreach ($arrFolders as $key => $folder) {
$title = null;
$folder_class = $this->folder_classname($folder['id']);
$is_collapsed = strpos($collapsed, '&'.rawurlencode($folder['id']).'&') !== false;
@@ -1423,13 +1613,14 @@ class rcmail extends rcube
'id' => "rcmli".$folder_id,
'class' => join(' ', $classes),
'noclose' => true),
- html::a($link_attrib, $html_name));
-
- if (!empty($folder['folders'])) {
- $out .= html::div('treetoggle ' . ($is_collapsed ? 'collapsed' : 'expanded'), '&nbsp;');
- }
-
- $jslist[$folder['id']] = array(
+ html::a($link_attrib, $html_name) .
+ (!empty($folder['folders']) ? html::div(array(
+ 'class' => ($is_collapsed ? 'collapsed' : 'expanded'),
+ 'style' => "position:absolute",
+ 'onclick' => sprintf("%s.command('collapse-folder', '%s')", rcmail_output::JS_OBJECT_NAME, $js_name)
+ ), '&nbsp;') : ''));
+
+ $jslist[$folder_id] = array(
'id' => $folder['id'],
'name' => $foldername,
'virtual' => $folder['virtual']
@@ -1454,7 +1645,7 @@ class rcmail extends rcube
{
$out = '';
- foreach ($arrFolders as $folder) {
+ foreach ($arrFolders as $key => $folder) {
// skip exceptions (and its subfolders)
if (!empty($opts['exceptions']) && in_array($folder['id'], $opts['exceptions'])) {
continue;
@@ -1515,38 +1706,18 @@ class rcmail extends rcube
* Try to localize the given IMAP folder name.
* UTF-7 decode it in case no localized text was found
*
- * @param string $name Folder name
- * @param bool $with_path Enable path localization
+ * @param string $name Folder name
*
* @return string Localized folder name in UTF-8 encoding
*/
- public function localize_foldername($name, $with_path = true)
+ public function localize_foldername($name)
{
- $realnames = $this->config->get('show_real_foldernames');
-
- // try to localize path of the folder
- if ($with_path && !$realnames) {
- $storage = $this->get_storage();
- $delimiter = $storage->get_hierarchy_delimiter();
- $path = explode($delimiter, $name);
- $count = count($path);
-
- if ($count > 1) {
- for ($i = 0; $i < $count; $i++) {
- $folder = implode($delimiter, array_slice($path, 0, -$i));
- if ($folder_class = $this->folder_classname($folder)) {
- $name = implode($delimiter, array_slice($path, $count - $i));
- return $this->gettext($folder_class) . $delimiter . rcube_charset::convert($name, 'UTF7-IMAP');
- }
- }
- }
- }
-
- if (!$realnames && ($folder_class = $this->folder_classname($name))) {
+ if ($folder_class = $this->folder_classname($name)) {
return $this->gettext($folder_class);
}
-
- return rcube_charset::convert($name, 'UTF7-IMAP');
+ else {
+ return rcube_charset::convert($name, 'UTF7-IMAP');
+ }
}
@@ -1601,7 +1772,11 @@ class rcmail extends rcube
$quota_result = (array) $quota;
$quota_result['type'] = isset($_SESSION['quota_display']) ? $_SESSION['quota_display'] : '';
- if ($quota['total'] > 0) {
+ if (!$quota['total'] && $this->config->get('quota_zero_as_unlimited')) {
+ $quota_result['title'] = $this->gettext('unlimited');
+ $quota_result['percent'] = 0;
+ }
+ else if ($quota['total']) {
if (!isset($quota['percent'])) {
$quota_result['percent'] = min(100, round(($quota['used']/max(1,$quota['total']))*100));
}
@@ -1620,8 +1795,7 @@ class rcmail extends rcube
}
}
else {
- $unlimited = $this->config->get('quota_zero_as_unlimited');
- $quota_result['title'] = $this->gettext($unlimited ? 'unlimited' : 'unknown');
+ $quota_result['title'] = $this->gettext('unknown');
$quota_result['percent'] = 0;
}
@@ -1634,51 +1808,32 @@ class rcmail extends rcube
*
* @param string $fallback Fallback message label
* @param array $fallback_args Fallback message label arguments
- * @param string $suffix Message label suffix
*/
- public function display_server_error($fallback = null, $fallback_args = null, $suffix = '')
+ public function display_server_error($fallback = null, $fallback_args = null)
{
$err_code = $this->storage->get_error_code();
$res_code = $this->storage->get_response_code();
- $args = array();
if ($res_code == rcube_storage::NOPERM) {
- $error = 'errornoperm';
+ $this->output->show_message('errornoperm', 'error');
}
else if ($res_code == rcube_storage::READONLY) {
- $error = 'errorreadonly';
- }
- else if ($res_code == rcube_storage::OVERQUOTA) {
- $error = 'errorroverquota';
+ $this->output->show_message('errorreadonly', 'error');
}
else if ($err_code && ($err_str = $this->storage->get_error_str())) {
// try to detect access rights problem and display appropriate message
if (stripos($err_str, 'Permission denied') !== false) {
- $error = 'errornoperm';
- }
- // try to detect full mailbox problem and display appropriate message
- // there can be e.g. "Quota exceeded" or "quotum would exceed"
- else if (stripos($err_str, 'quot') !== false && stripos($err_str, 'exceed') !== false) {
- $error = 'erroroverquota';
+ $this->output->show_message('errornoperm', 'error');
}
else {
- $error = 'servererrormsg';
- $args = array('msg' => $err_str);
+ $this->output->show_message('servererrormsg', 'error', array('msg' => $err_str));
}
}
else if ($err_code < 0) {
- $error = 'storageerror';
+ $this->output->show_message('storageerror', 'error');
}
else if ($fallback) {
- $error = $fallback;
- $args = $fallback_args;
- }
-
- if ($error) {
- if ($suffix && $this->text_exists($error . $suffix)) {
- $error .= $suffix;
- }
- $this->output->show_message($error, 'error', $args);
+ $this->output->show_message($fallback, 'error', $fallback_args);
}
}
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php
index a2ec29ca3..465d92f83 100644
--- a/program/include/rcmail_output_html.php
+++ b/program/include/rcmail_output_html.php
@@ -67,7 +67,6 @@ class rcmail_output_html extends rcmail_output
//$this->framed = $framed;
$this->set_env('task', $task);
$this->set_env('x_frame_options', $this->config->get('x_frame_options', 'sameorigin'));
- $this->set_env('standard_windows', (bool) $this->config->get('standard_windows'));
// add cookie info
$this->set_env('cookie_domain', ini_get('session.cookie_domain'));
@@ -106,6 +105,7 @@ class rcmail_output_html extends rcmail_output
));
}
+
/**
* Set environment variable
*
@@ -121,6 +121,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Getter for the current page title
*
@@ -144,17 +145,17 @@ class rcmail_output_html extends rcmail_output
return $title;
}
+
/**
* Set skin
*/
public function set_skin($skin)
{
$valid = false;
- $path = RCUBE_INSTALL_PATH . 'skins/';
- if (!empty($skin) && is_dir($path . $skin) && is_readable($path . $skin)) {
- $skin_path = 'skins/' . $skin;
- $valid = true;
+ if (!empty($skin) && is_dir('skins/'.$skin) && is_readable('skins/'.$skin)) {
+ $skin_path = 'skins/'.$skin;
+ $valid = true;
}
else {
$skin_path = $this->config->get('skin_path');
@@ -182,16 +183,13 @@ class rcmail_output_html extends rcmail_output
$this->skin_paths[] = $skin_path;
// read meta file and check for dependecies
- $meta = @file_get_contents(RCUBE_INSTALL_PATH . $skin_path . '/meta.json');
- $meta = @json_decode($meta, true);
- if ($meta['extends']) {
- $path = RCUBE_INSTALL_PATH . 'skins/';
- if (is_dir($path . $meta['extends']) && is_readable($path . $meta['extends'])) {
- $this->load_skin('skins/' . $meta['extends']);
- }
+ $meta = @json_decode(@file_get_contents($skin_path.'/meta.json'), true);
+ if ($meta['extends'] && is_dir('skins/' . $meta['extends'])) {
+ $this->load_skin('skins/' . $meta['extends']);
}
}
+
/**
* Check if a specific template exists
*
@@ -200,18 +198,17 @@ class rcmail_output_html extends rcmail_output
*/
public function template_exists($name)
{
+ $found = false;
foreach ($this->skin_paths as $skin_path) {
- $filename = RCUBE_INSTALL_PATH . $skin_path . '/templates/' . $name . '.html';
- if ((is_file($filename) && is_readable($filename))
- || ($this->deprecated_templates[$name] && $this->template_exists($this->deprecated_templates[$name]))
- ) {
- return true;
- }
+ $filename = $skin_path . '/templates/' . $name . '.html';
+ $found = (is_file($filename) && is_readable($filename)) || ($this->deprecated_templates[$name] && $this->template_exists($this->deprecated_templates[$name]));
+ if ($found)
+ break;
}
-
- return false;
+ return $found;
}
+
/**
* Find the given file in the current skin path stack
*
@@ -236,6 +233,7 @@ class rcmail_output_html extends rcmail_output
return false;
}
+
/**
* Register a GUI object to the client script
*
@@ -248,6 +246,7 @@ class rcmail_output_html extends rcmail_output
$this->add_script(self::JS_OBJECT_NAME.".gui_object('$obj', '$id');");
}
+
/**
* Call a client method
*
@@ -263,6 +262,7 @@ class rcmail_output_html extends rcmail_output
$this->js_commands[] = $cmd;
}
+
/**
* Add a localized label to the client environment
*/
@@ -277,6 +277,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Invoke display_message command
*
@@ -303,6 +304,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Delete all stored env variables and commands
*
@@ -325,6 +327,7 @@ class rcmail_output_html extends rcmail_output
$this->body = '';
}
+
/**
* Redirect to a certain url
*
@@ -340,6 +343,7 @@ class rcmail_output_html extends rcmail_output
exit;
}
+
/**
* Send the request output to the client.
* This will either parse a skin tempalte or send an AJAX response
@@ -373,6 +377,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Process template and write to stdOut
*
@@ -408,6 +413,7 @@ class rcmail_output_html extends rcmail_output
$this->_write($template, $this->config->get('skin_path'));
}
+
/**
* Parse a specific skin template and deliver to stdout (or return)
*
@@ -532,6 +538,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Return executable javascript code for all registered commands
*
@@ -563,6 +570,7 @@ class rcmail_output_html extends rcmail_output
return $out;
}
+
/**
* Make URLs starting with a slash point to skin directory
*
@@ -582,6 +590,7 @@ class rcmail_output_html extends rcmail_output
return $str;
}
+
/**
* Show error page and terminate script execution
*
@@ -616,6 +625,7 @@ class rcmail_output_html extends rcmail_output
array($this, 'globals_callback'), $input);
}
+
/**
* Callback funtion for preg_replace_callback() in parse_with_globals()
*/
@@ -624,6 +634,7 @@ class rcmail_output_html extends rcmail_output
return $GLOBALS[$matches[1]];
}
+
/**
* Correct absolute paths in images and other tags
* add timestamp to .js and .css filename
@@ -635,6 +646,7 @@ class rcmail_output_html extends rcmail_output
array($this, 'file_callback'), $output);
}
+
/**
* Callback function for preg_replace_callback in write()
*
@@ -643,7 +655,7 @@ class rcmail_output_html extends rcmail_output
protected function file_callback($matches)
{
$file = $matches[3];
- $file = preg_replace('!^/this/!', '/', $file);
+ $file[0] = preg_replace('!^/this/!', '/', $file[0]);
// correct absolute paths
if ($file[0] == '/') {
@@ -660,6 +672,7 @@ class rcmail_output_html extends rcmail_output
return $matches[1] . '=' . $matches[2] . $file . $matches[4];
}
+
/**
* Public wrapper to dipp into template parsing.
*
@@ -676,6 +689,7 @@ class rcmail_output_html extends rcmail_output
return $input;
}
+
/**
* Parse for conditional tags
*
@@ -713,18 +727,21 @@ class rcmail_output_html extends rcmail_output
return $input;
}
+
/**
* Determines if a given condition is met
*
+ * @todo Get rid off eval() once I understand what this does.
* @todo Extend this to allow real conditions, not just "set"
* @param string Condition statement
* @return boolean True if condition is met, False if not
*/
protected function check_condition($condition)
{
- return $this->eval_expression($condition);
+ return eval("return (".$this->parse_expression($condition).");");
}
+
/**
* Inserts hidden field with CSRF-prevention-token into POST forms
*/
@@ -741,16 +758,16 @@ class rcmail_output_html extends rcmail_output
return $out;
}
+
/**
- * Parse & evaluate a given expression and return its result.
- *
- * @param string Expression statement
+ * Parses expression and replaces variables
*
- * @return mixed Expression result
+ * @param string Expression statement
+ * @return string Expression value
*/
- protected function eval_expression ($expression)
+ protected function parse_expression($expression)
{
- $expression = preg_replace(
+ return preg_replace(
array(
'/session:([a-z0-9_]+)/i',
'/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i',
@@ -762,31 +779,17 @@ class rcmail_output_html extends rcmail_output
),
array(
"\$_SESSION['\\1']",
- "\$app->config->get('\\1',rcube_utils::get_boolean('\\3'))",
- "\$env['\\1']",
+ "\$this->app->config->get('\\1',rcube_utils::get_boolean('\\3'))",
+ "\$this->env['\\1']",
"rcube_utils::get_input_value('\\1', rcube_utils::INPUT_GPC)",
"\$_COOKIE['\\1']",
- "\$browser->{'\\1'}",
+ "\$this->browser->{'\\1'}",
$this->template_name,
),
- $expression
- );
-
- $fn = create_function('$app,$browser,$env', "return ($expression);");
- if (!$fn) {
- rcube::raise_error(array(
- 'code' => 505,
- 'type' => 'php',
- 'file' => __FILE__,
- 'line' => __LINE__,
- 'message' => "Expression parse error on: ($expression)"), true, false);
-
- return null;
- }
-
- return $fn($this->app, $this->browser, $this->env);
+ $expression);
}
+
/**
* Search for special tags in input and replace them
* with the appropriate content
@@ -801,6 +804,7 @@ class rcmail_output_html extends rcmail_output
return preg_replace_callback('/<roundcube:([-_a-z]+)\s+((?:[^>]|\\\\>)+)(?<!\\\\)>/Ui', array($this, 'xml_command'), $input);
}
+
/**
* Callback function for parsing an xml command tag
* and turn it into real html content
@@ -835,7 +839,7 @@ class rcmail_output_html extends rcmail_output
// show a label
case 'label':
if ($attrib['expression'])
- $attrib['name'] = $this->eval_expression($attrib['expression']);
+ $attrib['name'] = eval("return " . $this->parse_expression($attrib['expression']) .";");
if ($attrib['name'] || $attrib['command']) {
// @FIXME: 'noshow' is useless, remove?
@@ -967,7 +971,8 @@ class rcmail_output_html extends rcmail_output
// return code for a specified eval expression
case 'exp':
- return html::quote($this->eval_expression($attrib['expression']));
+ $value = $this->parse_expression($attrib['expression']);
+ return eval("return html::quote($value);");
// return variable
case 'var':
@@ -1004,13 +1009,12 @@ class rcmail_output_html extends rcmail_output
}
return html::quote($value);
-
- case 'form':
- return $this->form_tag($attrib);
+ break;
}
return '';
}
+
/**
* Include a specific file and return it's contents
*
@@ -1027,6 +1031,7 @@ class rcmail_output_html extends rcmail_output
return $out;
}
+
/**
* Create and register a button
*
@@ -1175,13 +1180,10 @@ class rcmail_output_html extends rcmail_output
$out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);
}
- if ($attrib['wrapper']) {
- $out = html::tag($attrib['wrapper'], null, $out);
- }
-
return $out;
}
+
/**
* Link an external script file
*
@@ -1212,6 +1214,7 @@ class rcmail_output_html extends rcmail_output
$this->script_files[$position][] = $file;
}
+
/**
* Add inline javascript code
*
@@ -1228,6 +1231,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Link an external css file
*
@@ -1238,6 +1242,7 @@ class rcmail_output_html extends rcmail_output
$this->css_files[] = $file;
}
+
/**
* Add HTML code to the page header
*
@@ -1248,6 +1253,7 @@ class rcmail_output_html extends rcmail_output
$this->header .= "\n" . $str;
}
+
/**
* Add HTML code to the page footer
* To be added right befor </body>
@@ -1259,6 +1265,7 @@ class rcmail_output_html extends rcmail_output
$this->footer .= "\n" . $str;
}
+
/**
* Process template and write to stdOut
*
@@ -1267,7 +1274,12 @@ class rcmail_output_html extends rcmail_output
*/
public function _write($templ = '', $base_path = '')
{
- $output = empty($templ) ? $this->default_template : trim($templ);
+ $output = trim($templ);
+
+ if (empty($output)) {
+ $output = $this->default_template;
+ $is_empty = true;
+ }
// set default page title
if (empty($this->pagetitle)) {
@@ -1358,8 +1370,8 @@ class rcmail_output_html extends rcmail_output
}
// add css files in head, before scripts, for speed up with parallel downloads
- if (!empty($this->css_files) &&
- (($pos = stripos($output, '<script ')) || ($pos = stripos($output, '</head>')))
+ if (!empty($this->css_files) && !$is_empty
+ && (($pos = stripos($output, '<script ')) || ($pos = stripos($output, '</head>')))
) {
$css = '';
foreach ($this->css_files as $file) {
@@ -1383,6 +1395,7 @@ class rcmail_output_html extends rcmail_output
}
}
+
/**
* Returns iframe object, registers some related env variables
*
@@ -1413,6 +1426,7 @@ class rcmail_output_html extends rcmail_output
/* ************* common functions delivering gui objects ************** */
+
/**
* Create a form tag with the necessary hidden fields
*
@@ -1434,11 +1448,12 @@ class rcmail_output_html extends rcmail_output
$attrib['noclose'] = true;
return html::tag('form',
- $attrib + array('action' => $this->app->comm_path, 'method' => "get"),
+ $attrib + array('action' => "./", 'method' => "get"),
$hidden . $content,
array('id','class','style','name','method','action','enctype','onsubmit'));
}
+
/**
* Build a form tag with a unique request token
*
@@ -1469,6 +1484,7 @@ class rcmail_output_html extends rcmail_output
return $this->form_tag($attrib, $hidden->show() . $content);
}
+
/**
* GUI object 'username'
* Showing IMAP username of the current session
@@ -1500,6 +1516,7 @@ class rcmail_output_html extends rcmail_output
return rcube_utils::idn_to_utf8($username);
}
+
/**
* GUI object 'loginform'
* Returns code for the webmail login form
@@ -1531,9 +1548,9 @@ class rcmail_output_html extends rcmail_output
$input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'login'));
$input_tzone = new html_hiddenfield(array('name' => '_timezone', 'id' => 'rcmlogintz', 'value' => '_default_'));
$input_url = new html_hiddenfield(array('name' => '_url', 'id' => 'rcmloginurl', 'value' => $url));
- $input_user = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser', 'required' => 'required')
+ $input_user = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser')
+ $attrib + $user_attrib);
- $input_pass = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'required' => 'required')
+ $input_pass = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd')
+ $attrib + $pass_attrib);
$input_host = null;
@@ -1599,6 +1616,7 @@ class rcmail_output_html extends rcmail_output
return $out;
}
+
/**
* GUI object 'preloader'
* Loads javascript code for images preloading
@@ -1621,6 +1639,7 @@ class rcmail_output_html extends rcmail_output
}', 'docready');
}
+
/**
* GUI object 'searchform'
* Returns code for search function
@@ -1659,6 +1678,7 @@ class rcmail_output_html extends rcmail_output
return $out;
}
+
/**
* Builder for GUI object 'message'
*
@@ -1676,6 +1696,7 @@ class rcmail_output_html extends rcmail_output
return html::div($attrib, '');
}
+
/**
* GUI object 'charsetselector'
*
diff --git a/program/js/app.js b/program/js/app.js
index 42c661144..efefd3a64 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -1,7015 +1 @@
-/*
- +-----------------------------------------------------------------------+
- | Roundcube Webmail Client Script |
- | |
- | This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
- | Copyright (C) 2011-2013, Kolab Systems AG |
- | |
- | 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. |
- | |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com> |
- | Aleksander 'A.L.E.C' Machniak <alec@alec.pl> |
- | Charles McNulty <charles@charlesmcnulty.com> |
- +-----------------------------------------------------------------------+
- | Requires: jquery.js, common.js, list.js |
- +-----------------------------------------------------------------------+
-*/
-
-function rcube_webmail()
-{
- this.labels = {};
- this.buttons = {};
- this.buttons_sel = {};
- this.gui_objects = {};
- this.gui_containers = {};
- this.commands = {};
- this.command_handlers = {};
- this.onloads = [];
- this.messages = {};
- this.group2expand = {};
-
- // webmail client settings
- this.dblclick_time = 500;
- this.message_time = 4000;
- this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi');
-
- // environment defaults
- this.env = {
- request_timeout: 180, // seconds
- draft_autosave: 0, // seconds
- comm_path: './',
- blankpage: 'program/resources/blank.gif',
- recipients_separator: ',',
- recipients_delimiter: ', ',
- popup_width: 1150,
- popup_width_small: 900
- };
-
- // create protected reference to myself
- this.ref = 'rcmail';
- var ref = this;
-
- // set jQuery ajax options
- $.ajaxSetup({
- cache: false,
- timeout: this.env.request_timeout * 1000,
- error: function(request, status, err){ ref.http_error(request, status, err); },
- beforeSend: function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); }
- });
-
- // unload fix
- $(window).bind('beforeunload', function() { rcmail.unload = true; });
-
- // set environment variable(s)
- this.set_env = function(p, value)
- {
- if (p != null && typeof p === 'object' && !value)
- for (var n in p)
- this.env[n] = p[n];
- else
- this.env[p] = value;
- };
-
- // add a localized label to the client environment
- this.add_label = function(p, value)
- {
- if (typeof p == 'string')
- this.labels[p] = value;
- else if (typeof p == 'object')
- $.extend(this.labels, p);
- };
-
- // add a button to the button list
- this.register_button = function(command, id, type, act, sel, over)
- {
- var button_prop = {id:id, type:type};
-
- if (act) button_prop.act = act;
- if (sel) button_prop.sel = sel;
- if (over) button_prop.over = over;
-
- if (!this.buttons[command])
- this.buttons[command] = [];
-
- this.buttons[command].push(button_prop);
-
- if (this.loaded)
- init_button(command, button_prop);
- };
-
- // register a specific gui object
- this.gui_object = function(name, id)
- {
- this.gui_objects[name] = this.loaded ? rcube_find_object(id) : id;
- };
-
- // register a container object
- this.gui_container = function(name, id)
- {
- this.gui_containers[name] = id;
- };
-
- // add a GUI element (html node) to a specified container
- this.add_element = function(elm, container)
- {
- if (this.gui_containers[container] && this.gui_containers[container].jquery)
- this.gui_containers[container].append(elm);
- };
-
- // register an external handler for a certain command
- this.register_command = function(command, callback, enable)
- {
- this.command_handlers[command] = callback;
-
- if (enable)
- this.enable_command(command, true);
- };
-
- // execute the given script on load
- this.add_onload = function(f)
- {
- this.onloads.push(f);
- };
-
- // initialize webmail client
- this.init = function()
- {
- var n, p = this;
- this.task = this.env.task;
-
- // check browser
- if (!bw.dom || !bw.xmlhttp_test() || (bw.mz && bw.vendver < 1.9)) {
- this.goto_url('error', '_code=0x199');
- return;
- }
-
- // find all registered gui containers
- for (n in this.gui_containers)
- this.gui_containers[n] = $('#'+this.gui_containers[n]);
-
- // find all registered gui objects
- for (n in this.gui_objects)
- this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
-
- // clickjacking protection
- if (this.env.x_frame_options) {
- try {
- // bust frame if not allowed
- if (this.env.x_frame_options == 'deny' && top.location.href != self.location.href)
- top.location.href = self.location.href;
- else if (top.location.hostname != self.location.hostname)
- throw 1;
- } catch (e) {
- // possible clickjacking attack: disable all form elements
- $('form').each(function(){ ref.lock_form(this, true); });
- this.display_message("Blocked: possible clickjacking attack!", 'error');
- return;
- }
- }
-
- // init registered buttons
- this.init_buttons();
-
- // tell parent window that this frame is loaded
- if (this.is_framed()) {
- parent.rcmail.set_busy(false, null, parent.rcmail.env.frame_lock);
- parent.rcmail.env.frame_lock = null;
- }
-
- // enable general commands
- this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref',
- 'compose', 'undo', 'about', 'switch-task', 'menu-open', 'menu-save', true);
-
- if (this.env.permaurl)
- this.enable_command('permaurl', 'extwin', true);
-
- switch (this.task) {
-
- case 'mail':
- // enable mail commands
- this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', 'import-messages', true);
-
- if (this.gui_objects.messagelist) {
- this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {
- multiselect:true, multiexpand:true, draggable:true, keyboard:true,
- column_movable:this.env.col_movable, dblclick_time:this.dblclick_time
- });
- this.message_list.row_init = function(o){ p.init_message_row(o); };
- this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); });
- this.message_list.addEventListener('click', function(o){ p.msglist_click(o); });
- this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
- this.message_list.addEventListener('select', function(o){ p.msglist_select(o); });
- this.message_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
- this.message_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
- this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); });
- this.message_list.addEventListener('expandcollapse', function(e){ p.msglist_expand(e); });
- this.message_list.addEventListener('column_replace', function(e){ p.msglist_set_coltypes(e); });
- this.message_list.addEventListener('listupdate', function(e){ p.triggerEvent('listupdate', e); });
-
- document.onmouseup = function(e){ return p.doc_mouse_up(e); };
- this.gui_objects.messagelist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
-
- this.message_list.init();
- this.enable_command('toggle_status', 'toggle_flag', 'sort', true);
-
- // load messages
- this.command('list');
- }
-
- if (this.gui_objects.qsearchbox) {
- if (this.env.search_text != null)
- this.gui_objects.qsearchbox.value = this.env.search_text;
- $(this.gui_objects.qsearchbox).focusin(function() { rcmail.message_list && rcmail.message_list.blur(); });
- }
-
- this.set_button_titles();
-
- this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list',
- 'move', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource',
- 'print', 'load-attachment', 'download-attachment', 'show-headers', 'hide-headers', 'download',
- 'forward', 'forward-inline', 'forward-attachment', 'change-format'];
-
- if (this.env.action == 'show' || this.env.action == 'preview') {
- this.enable_command(this.env.message_commands, this.env.uid);
- this.enable_command('reply-list', this.env.list_post);
-
- if (this.env.action == 'show') {
- this.http_request('pagenav', {_uid: this.env.uid, _mbox: this.env.mailbox, _search: this.env.search_request},
- this.display_message('', 'loading'));
- }
-
- if (this.env.blockedobjects) {
- if (this.gui_objects.remoteobjectsmsg)
- this.gui_objects.remoteobjectsmsg.style.display = 'block';
- this.enable_command('load-images', 'always-load', true);
- }
-
- // make preview/message frame visible
- if (this.env.action == 'preview' && this.is_framed()) {
- this.enable_command('compose', 'add-contact', false);
- parent.rcmail.show_contentframe(true);
- }
- }
- else if (this.env.action == 'compose') {
- this.env.address_group_stack = [];
- this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'pushgroup', 'search', 'reset-search', 'extwin'];
-
- if (this.env.drafts_mailbox)
- this.env.compose_commands.push('savedraft')
-
- this.enable_command(this.env.compose_commands, 'identities', true);
-
- // add more commands (not enabled)
- $.merge(this.env.compose_commands, ['add-recipient', 'firstpage', 'previouspage', 'nextpage', 'lastpage']);
-
- if (this.env.spellcheck) {
- this.env.spellcheck.spelling_state_observer = function(s) { ref.spellcheck_state(); };
- this.env.compose_commands.push('spellcheck')
- this.enable_command('spellcheck', true);
- }
-
- document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-
- // init message compose form
- this.init_messageform();
- }
- else if (this.env.action == 'get')
- this.enable_command('download', 'print', true);
- // show printing dialog
- else if (this.env.action == 'print' && this.env.uid) {
- if (bw.safari)
- setTimeout('window.print()', 10);
- else
- window.print();
- }
-
- // get unread count for each mailbox
- if (this.gui_objects.mailboxlist) {
- this.env.unread_counts = {};
- this.gui_objects.folderlist = this.gui_objects.mailboxlist;
- this.http_request('getunread');
- }
-
- // init address book widget
- if (this.gui_objects.contactslist) {
- this.contact_list = new rcube_list_widget(this.gui_objects.contactslist,
- { multiselect:true, draggable:false, keyboard:false });
- this.contact_list.addEventListener('select', function(o){ ref.compose_recipient_select(o); });
- this.contact_list.addEventListener('dblclick', function(o){ ref.compose_add_recipient('to'); });
- this.contact_list.init();
- }
-
- if (this.gui_objects.addressbookslist) {
- this.gui_objects.folderlist = this.gui_objects.addressbookslist;
- this.enable_command('list-adresses', true);
- }
-
- // ask user to send MDN
- if (this.env.mdn_request && this.env.uid) {
- var postact = 'sendmdn',
- postdata = {_uid: this.env.uid, _mbox: this.env.mailbox};
- if (!confirm(this.get_label('mdnrequest'))) {
- postdata._flag = 'mdnsent';
- postact = 'mark';
- }
- this.http_post(postact, postdata);
- }
-
- // detect browser capabilities
- if (!this.is_framed() && !this.env.extwin)
- this.browser_capabilities_check();
-
- break;
-
- case 'addressbook':
- this.env.address_group_stack = [];
-
- if (this.gui_objects.folderlist)
- this.env.contactfolders = $.extend($.extend({}, this.env.address_sources), this.env.contactgroups);
-
- this.enable_command('add', 'import', this.env.writable_source);
- this.enable_command('list', 'listgroup', 'pushgroup', 'popgroup', 'listsearch', 'advanced-search', true);
-
- if (this.gui_objects.contactslist) {
- this.contact_list = new rcube_list_widget(this.gui_objects.contactslist,
- {multiselect:true, draggable:this.gui_objects.folderlist?true:false, keyboard:true});
- this.contact_list.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); };
- this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
- this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
- this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
- this.contact_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
- this.contact_list.addEventListener('dragend', function(e){ p.drag_end(e); });
- this.contact_list.init();
-
- if (this.env.cid)
- this.contact_list.highlight_row(this.env.cid);
-
- this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
- document.onmouseup = function(e){ return p.doc_mouse_up(e); };
- if (this.gui_objects.qsearchbox)
- $(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); });
-
- this.update_group_commands();
- this.command('list');
- }
-
- this.set_page_buttons();
-
- if (this.env.cid) {
- this.enable_command('show', 'edit', true);
- // register handlers for group assignment via checkboxes
- if (this.gui_objects.editform) {
- $('input.groupmember').change(function() {
- ref.group_member_change(this.checked ? 'add' : 'del', ref.env.cid, ref.env.source, this.value);
- });
- }
- }
-
- if (this.gui_objects.editform) {
- this.enable_command('save', true);
- if (this.env.action == 'add' || this.env.action == 'edit' || this.env.action == 'search')
- this.init_contact_form();
- }
-
- if (this.gui_objects.qsearchbox)
- this.enable_command('search', 'reset-search', true);
-
- break;
-
- case 'settings':
- this.enable_command('preferences', 'identities', 'save', 'folders', true);
-
- if (this.env.action == 'identities') {
- this.enable_command('add', this.env.identities_level < 2);
- }
- else if (this.env.action == 'edit-identity' || this.env.action == 'add-identity') {
- this.enable_command('save', 'edit', 'toggle-editor', true);
- this.enable_command('delete', this.env.identities_level < 2);
-
- if (this.env.action == 'add-identity')
- $("input[type='text']").first().select();
- }
- else if (this.env.action == 'folders') {
- this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', true);
- }
- else if (this.env.action == 'edit-folder' && this.gui_objects.editform) {
- this.enable_command('save', 'folder-size', true);
- parent.rcmail.env.exists = this.env.messagecount;
- parent.rcmail.enable_command('purge', this.env.messagecount);
- $("input[type='text']").first().select();
- }
-
- if (this.gui_objects.identitieslist) {
- this.identity_list = new rcube_list_widget(this.gui_objects.identitieslist, {multiselect:false, draggable:false, keyboard:false});
- this.identity_list.addEventListener('select', function(o){ p.identity_select(o); });
- this.identity_list.init();
- this.identity_list.focus();
-
- if (this.env.iid)
- this.identity_list.highlight_row(this.env.iid);
- }
- else if (this.gui_objects.sectionslist) {
- this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:false});
- this.sections_list.addEventListener('select', function(o){ p.section_select(o); });
- this.sections_list.init();
- this.sections_list.focus();
- }
- else if (this.gui_objects.subscriptionlist)
- this.init_subscription_list();
-
- break;
-
- case 'login':
- var input_user = $('#rcmloginuser');
- input_user.bind('keyup', function(e){ return rcmail.login_user_keyup(e); });
-
- if (input_user.val() == '')
- input_user.focus();
- else
- $('#rcmloginpwd').focus();
-
- // detect client timezone
- if (window.jstz && !bw.ie6) {
- var timezone = jstz.determine();
- if (timezone.name())
- $('#rcmlogintz').val(timezone.name());
- }
- else {
- $('#rcmlogintz').val(new Date().getStdTimezoneOffset() / -60);
- }
-
- // display 'loading' message on form submit, lock submit button
- $('form').submit(function () {
- $('input[type=submit]', this).prop('disabled', true);
- rcmail.clear_messages();
- rcmail.display_message('', 'loading');
- });
-
- this.enable_command('login', true);
- break;
- }
-
- // unset contentframe variable if preview_pane is enabled
- if (this.env.contentframe && !$('#' + this.env.contentframe).is(':visible'))
- this.env.contentframe = null;
-
- // prevent from form submit with Enter key in file input fields
- if (bw.ie)
- $('input[type=file]').keydown(function(e) { if (e.keyCode == '13') e.preventDefault(); });
-
- // flag object as complete
- this.loaded = true;
-
- // show message
- if (this.pending_message)
- this.display_message(this.pending_message[0], this.pending_message[1], this.pending_message[2]);
-
- // map implicit containers
- if (this.gui_objects.folderlist) {
- this.gui_containers.foldertray = $(this.gui_objects.folderlist);
-
- // init treelist widget
- if (window.rcube_treelist_widget) {
- this.treelist = new rcube_treelist_widget(this.gui_objects.folderlist, {
- id_prefix: 'rcmli',
- id_encode: this.html_identifier_encode,
- id_decode: this.html_identifier_decode,
- check_droptarget: function(node){ return !node.virtual && ref.check_droptarget(node.id) }
- });
- this.treelist.addEventListener('collapse', function(node){ ref.folder_collapsed(node) });
- this.treelist.addEventListener('expand', function(node){ ref.folder_collapsed(node) });
- this.treelist.addEventListener('select', function(node){ ref.triggerEvent('selectfolder', { folder:node.id, prefix:'rcmli' }) });
- }
- }
-
- // activate html5 file drop feature (if browser supports it and if configured)
- if (this.gui_objects.filedrop && this.env.filedrop && ((window.XMLHttpRequest && XMLHttpRequest.prototype && XMLHttpRequest.prototype.sendAsBinary) || window.FormData)) {
- $(document.body).bind('dragover dragleave drop', function(e){ return ref.document_drag_hover(e, e.type == 'dragover'); });
- $(this.gui_objects.filedrop).addClass('droptarget')
- .bind('dragover dragleave', function(e){ return ref.file_drag_hover(e, e.type == 'dragover'); })
- .get(0).addEventListener('drop', function(e){ return ref.file_dropped(e); }, false);
- }
-
- // trigger init event hook
- this.triggerEvent('init', { task:this.task, action:this.env.action });
-
- // execute all foreign onload scripts
- // @deprecated
- for (var i in this.onloads) {
- if (typeof this.onloads[i] === 'string')
- eval(this.onloads[i]);
- else if (typeof this.onloads[i] === 'function')
- this.onloads[i]();
- }
-
- // start keep-alive and refresh intervals
- this.start_refresh();
- this.start_keepalive();
- };
-
- this.log = function(msg)
- {
- if (window.console && console.log)
- console.log(msg);
- };
-
- /*********************************************************/
- /********* client command interface *********/
- /*********************************************************/
-
- // execute a specific command on the web client
- this.command = function(command, props, obj, event)
- {
- var ret, uid, cid, url, flag;
-
- if (obj && obj.blur)
- obj.blur();
-
- if (this.busy)
- return false;
-
- // let the browser handle this click (shift/ctrl usually opens the link in a new window/tab)
- if ((obj && obj.href && String(obj.href).indexOf('#') < 0) && rcube_event.get_modifier(event)) {
- return true;
- }
-
- // command not supported or allowed
- if (!this.commands[command]) {
- // pass command to parent window
- if (this.is_framed())
- parent.rcmail.command(command, props);
-
- return false;
- }
-
- // check input before leaving compose step
- if (this.task == 'mail' && this.env.action == 'compose' && $.inArray(command, this.env.compose_commands)<0) {
- if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
- return false;
- }
-
- // process external commands
- if (typeof this.command_handlers[command] === 'function') {
- ret = this.command_handlers[command](props, obj);
- return ret !== undefined ? ret : (obj ? false : true);
- }
- else if (typeof this.command_handlers[command] === 'string') {
- ret = window[this.command_handlers[command]](props, obj);
- return ret !== undefined ? ret : (obj ? false : true);
- }
-
- // trigger plugin hooks
- this.triggerEvent('actionbefore', {props:props, action:command});
- ret = this.triggerEvent('before'+command, props);
- if (ret !== undefined) {
- // abort if one of the handlers returned false
- if (ret === false)
- return false;
- else
- props = ret;
- }
-
- ret = undefined;
-
- // process internal command
- switch (command) {
-
- case 'login':
- if (this.gui_objects.loginform)
- this.gui_objects.loginform.submit();
- break;
-
- // commands to switch task
- case 'mail':
- case 'addressbook':
- case 'settings':
- case 'logout':
- this.switch_task(command);
- break;
-
- case 'about':
- this.redirect('?_task=settings&_action=about', false);
- break;
-
- case 'permaurl':
- if (obj && obj.href && obj.target)
- return true;
- else if (this.env.permaurl)
- parent.location.href = this.env.permaurl;
- break;
-
- case 'extwin':
- if (this.env.action == 'compose') {
- var form = this.gui_objects.messageform,
- win = this.open_window('');
-
- $("input[name='_action']", form).val('compose');
- form.action = this.url('mail/compose', { _id: this.env.compose_id, _extwin: 1 });
- form.target = win.name;
- form.submit();
- }
- else {
- this.open_window(this.env.permaurl, true);
- }
- break;
-
- case 'change-format':
- url = this.env.permaurl + '&_format=' + props;
-
- if (this.env.action == 'preview')
- url = url.replace(/_action=show/, '_action=preview') + '&_framed=1';
- if (this.env.extwin)
- url += '&_extwin=1';
-
- location.href = url;
- break;
-
- case 'menu-open':
- if (props && props.menu == 'attachmentmenu') {
- var mimetype = this.env.attachments[props.id];
- this.enable_command('open-attachment', mimetype && this.env.mimetypes && $.inArray(mimetype, this.env.mimetypes) >= 0);
- }
-
- case 'menu-save':
- this.triggerEvent(command, {props:props});
- return false;
-
- case 'open':
- if (uid = this.get_single_uid()) {
- obj.href = this.url('show', {_mbox: this.env.mailbox, _uid: uid});
- return true;
- }
- break;
-
- case 'close':
- if (this.env.extwin)
- window.close();
- break;
-
- case 'list':
- if (props && props != '')
- this.reset_qsearch();
- if (this.env.action == 'compose' && this.env.extwin)
- window.close();
- else if (this.task == 'mail') {
- this.list_mailbox(props);
- this.set_button_titles();
- }
- else if (this.task == 'addressbook')
- this.list_contacts(props);
- break;
-
- case 'sort':
- var sort_order = this.env.sort_order,
- sort_col = !this.env.disabled_sort_col ? props : this.env.sort_col;
-
- if (!this.env.disabled_sort_order)
- sort_order = this.env.sort_col == sort_col && sort_order == 'ASC' ? 'DESC' : 'ASC';
-
- // set table header and update env
- this.set_list_sorting(sort_col, sort_order);
-
- // reload message list
- this.list_mailbox('', '', sort_col+'_'+sort_order);
- break;
-
- case 'nextpage':
- this.list_page('next');
- break;
-
- case 'lastpage':
- this.list_page('last');
- break;
-
- case 'previouspage':
- this.list_page('prev');
- break;
-
- case 'firstpage':
- this.list_page('first');
- break;
-
- case 'expunge':
- if (this.env.exists)
- this.expunge_mailbox(this.env.mailbox);
- break;
-
- case 'purge':
- case 'empty-mailbox':
- if (this.env.exists)
- this.purge_mailbox(this.env.mailbox);
- break;
-
- // common commands used in multiple tasks
- case 'show':
- if (this.task == 'mail') {
- uid = this.get_single_uid();
- if (uid && (!this.env.uid || uid != this.env.uid)) {
- if (this.env.mailbox == this.env.drafts_mailbox)
- this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox });
- else
- this.show_message(uid);
- }
- }
- else if (this.task == 'addressbook') {
- cid = props ? props : this.get_single_cid();
- if (cid && !(this.env.action == 'show' && cid == this.env.cid))
- this.load_contact(cid, 'show');
- }
- break;
-
- case 'add':
- if (this.task == 'addressbook')
- this.load_contact(0, 'add');
- else if (this.task == 'settings') {
- this.identity_list.clear_selection();
- this.load_identity(0, 'add-identity');
- }
- break;
-
- case 'edit':
- if (this.task == 'addressbook' && (cid = this.get_single_cid()))
- this.load_contact(cid, 'edit');
- else if (this.task == 'settings' && props)
- this.load_identity(props, 'edit-identity');
- else if (this.task == 'mail' && (cid = this.get_single_uid())) {
- url = { _mbox: this.env.mailbox };
- url[this.env.mailbox == this.env.drafts_mailbox && props != 'new' ? '_draft_uid' : '_uid'] = cid;
- this.open_compose_step(url);
- }
- break;
-
- case 'save':
- var input, form = this.gui_objects.editform;
- if (form) {
- // adv. search
- if (this.env.action == 'search') {
- }
- // user prefs
- else if ((input = $("input[name='_pagesize']", form)) && input.length && isNaN(parseInt(input.val()))) {
- alert(this.get_label('nopagesizewarning'));
- input.focus();
- break;
- }
- // contacts/identities
- else {
- // reload form
- if (props == 'reload') {
- form.action += '?_reload=1';
- }
- else if (this.task == 'settings' && (this.env.identities_level % 2) == 0 &&
- (input = $("input[name='_email']", form)) && input.length && !rcube_check_email(input.val())
- ) {
- alert(this.get_label('noemailwarning'));
- input.focus();
- break;
- }
-
- // clear empty input fields
- $('input.placeholder').each(function(){ if (this.value == this._placeholder) this.value = ''; });
- }
-
- // add selected source (on the list)
- if (parent.rcmail && parent.rcmail.env.source)
- form.action = this.add_url(form.action, '_orig_source', parent.rcmail.env.source);
-
- form.submit();
- }
- break;
-
- case 'delete':
- // mail task
- if (this.task == 'mail')
- this.delete_messages(event);
- // addressbook task
- else if (this.task == 'addressbook')
- this.delete_contacts();
- // user settings task
- else if (this.task == 'settings')
- this.delete_identity();
- break;
-
- // mail task commands
- case 'move':
- case 'moveto': // deprecated
- if (this.task == 'mail')
- this.move_messages(props);
- else if (this.task == 'addressbook')
- this.move_contacts(props);
- break;
-
- case 'copy':
- if (this.task == 'mail')
- this.copy_messages(props);
- else if (this.task == 'addressbook')
- this.copy_contacts(props);
- break;
-
- case 'mark':
- if (props)
- this.mark_message(props);
- break;
-
- case 'toggle_status':
- if (props && !props._row)
- break;
-
- flag = 'read';
-
- if (props._row.uid) {
- uid = props._row.uid;
-
- // toggle read/unread
- if (this.message_list.rows[uid].deleted)
- flag = 'undelete';
- else if (!this.message_list.rows[uid].unread)
- flag = 'unread';
- }
-
- this.mark_message(flag, uid);
- break;
-
- case 'toggle_flag':
- if (props && !props._row)
- break;
-
- flag = 'flagged';
-
- if (props._row.uid) {
- uid = props._row.uid;
- // toggle flagged/unflagged
- if (this.message_list.rows[uid].flagged)
- flag = 'unflagged';
- }
- this.mark_message(flag, uid);
- break;
-
- case 'always-load':
- if (this.env.uid && this.env.sender) {
- this.add_contact(this.env.sender);
- setTimeout(function(){ ref.command('load-images'); }, 300);
- break;
- }
-
- case 'load-images':
- if (this.env.uid)
- this.show_message(this.env.uid, true, this.env.action=='preview');
- break;
-
- case 'load-attachment':
- case 'open-attachment':
- case 'download-attachment':
- var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props,
- mimetype = this.env.attachments[props];
-
- // open attachment in frame if it's of a supported mimetype
- if (command != 'download-attachment' && mimetype && this.env.mimetypes && $.inArray(mimetype, this.env.mimetypes) >= 0) {
- if (this.open_window(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1'))
- break;
- }
-
- this.goto_url('get', qstring+'&_download=1', false);
- break;
-
- case 'select-all':
- this.select_all_mode = props ? false : true;
- this.dummy_select = true; // prevent msg opening if there's only one msg on the list
- if (props == 'invert')
- this.message_list.invert_selection();
- else
- this.message_list.select_all(props == 'page' ? '' : props);
- this.dummy_select = null;
- break;
-
- case 'select-none':
- this.select_all_mode = false;
- this.message_list.clear_selection();
- break;
-
- case 'expand-all':
- this.env.autoexpand_threads = 1;
- this.message_list.expand_all();
- break;
-
- case 'expand-unread':
- this.env.autoexpand_threads = 2;
- this.message_list.collapse_all();
- this.expand_unread();
- break;
-
- case 'collapse-all':
- this.env.autoexpand_threads = 0;
- this.message_list.collapse_all();
- break;
-
- case 'nextmessage':
- if (this.env.next_uid)
- this.show_message(this.env.next_uid, false, this.env.action == 'preview');
- break;
-
- case 'lastmessage':
- if (this.env.last_uid)
- this.show_message(this.env.last_uid);
- break;
-
- case 'previousmessage':
- if (this.env.prev_uid)
- this.show_message(this.env.prev_uid, false, this.env.action == 'preview');
- break;
-
- case 'firstmessage':
- if (this.env.first_uid)
- this.show_message(this.env.first_uid);
- break;
-
- case 'compose':
- url = {};
-
- if (this.task == 'mail') {
- url._mbox = this.env.mailbox;
- if (props)
- url._to = props;
- // also send search request so we can go back to search result after message is sent
- if (this.env.search_request)
- url._search = this.env.search_request;
- }
- // modify url if we're in addressbook
- else if (this.task == 'addressbook') {
- // switch to mail compose step directly
- if (props && props.indexOf('@') > 0) {
- url._to = props;
- }
- else {
- var a_cids = [];
- // use contact id passed as command parameter
- if (props)
- a_cids.push(props);
- // get selected contacts
- else if (this.contact_list)
- a_cids = this.contact_list.get_selection();
-
- if (a_cids.length)
- this.http_post('mailto', { _cid: a_cids.join(','), _source: this.env.source }, true);
- else if (this.env.group)
- this.http_post('mailto', { _gid: this.env.group, _source: this.env.source }, true);
-
- break;
- }
- }
- else if (props)
- url._to = props;
-
- this.open_compose_step(url);
- break;
-
- case 'spellcheck':
- if (this.spellcheck_state()) {
- this.stop_spellchecking();
- }
- else {
- if (window.tinyMCE && tinyMCE.get(this.env.composebody)) {
- tinyMCE.execCommand('mceSpellCheck', true);
- }
- else if (this.env.spellcheck && this.env.spellcheck.spellCheck) {
- this.env.spellcheck.spellCheck();
- }
- }
- this.spellcheck_state();
- break;
-
- case 'savedraft':
- // Reset the auto-save timer
- clearTimeout(this.save_timer);
-
- // compose form did not change (and draft wasn't saved already)
- if (this.env.draft_id && this.cmp_hash == this.compose_field_hash()) {
- this.auto_save_start();
- break;
- }
-
- this.submit_messageform(true);
- break;
-
- case 'send':
- if (!props.nocheck && !this.check_compose_input(command))
- break;
-
- // Reset the auto-save timer
- clearTimeout(this.save_timer);
-
- this.submit_messageform();
- break;
-
- case 'send-attachment':
- // Reset the auto-save timer
- clearTimeout(this.save_timer);
-
- this.upload_file(props || this.gui_objects.uploadform, 'upload');
- break;
-
- case 'insert-sig':
- this.change_identity($("[name='_from']")[0], true);
- break;
-
- case 'list-adresses':
- this.list_contacts(props);
- this.enable_command('add-recipient', false);
- break;
-
- case 'add-recipient':
- this.compose_add_recipient(props);
- break;
-
- case 'reply-all':
- case 'reply-list':
- case 'reply':
- if (uid = this.get_single_uid()) {
- url = {_reply_uid: uid, _mbox: this.env.mailbox};
- if (command == 'reply-all')
- // do reply-list, when list is detected and popup menu wasn't used
- url._all = (!props && this.commands['reply-list'] ? 'list' : 'all');
- else if (command == 'reply-list')
- url._all = 'list';
-
- this.open_compose_step(url);
- }
- break;
-
- case 'forward-attachment':
- case 'forward-inline':
- case 'forward':
- var uids = this.env.uid ? [this.env.uid] : (this.message_list ? this.message_list.get_selection() : []);
- if (uids.length) {
- url = { _forward_uid: this.uids_to_list(uids), _mbox: this.env.mailbox };
- if (command == 'forward-attachment' || (!props && this.env.forward_attachment) || uids.length > 1)
- url._attachment = 1;
- this.open_compose_step(url);
- }
- break;
-
- case 'print':
- if (this.env.action == 'get') {
- this.gui_objects.messagepartframe.contentWindow.print();
- }
- else if (uid = this.get_single_uid()) {
- ref.printwin = this.open_window(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''), true, true);
- if (this.printwin) {
- if (this.env.action != 'show')
- this.mark_message('read', uid);
- }
- }
- break;
-
- case 'viewsource':
- if (uid = this.get_single_uid())
- this.open_window(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true, true);
- break;
-
- case 'download':
- if (this.env.action == 'get') {
- location.href = location.href.replace(/_frame=/, '_download=');
- }
- else if (uid = this.get_single_uid())
- this.goto_url('viewsource', { _uid: uid, _mbox: this.env.mailbox, _save: 1 });
- break;
-
- // quicksearch
- case 'search':
- if (!props && this.gui_objects.qsearchbox)
- props = this.gui_objects.qsearchbox.value;
- if (props) {
- this.qsearch(props);
- break;
- }
-
- // reset quicksearch
- case 'reset-search':
- var n, s = this.env.search_request || this.env.qsearch;
-
- this.reset_qsearch();
- this.select_all_mode = false;
-
- if (s && this.env.action == 'compose') {
- if (this.contact_list)
- this.list_contacts_clear();
- }
- else if (s && this.env.mailbox) {
- this.list_mailbox(this.env.mailbox, 1);
- }
- else if (s && this.task == 'addressbook') {
- if (this.env.source == '') {
- for (n in this.env.address_sources) break;
- this.env.source = n;
- this.env.group = '';
- }
- this.list_contacts(this.env.source, this.env.group, 1);
- }
- break;
-
- case 'pushgroup':
- // add group ID to stack
- this.env.address_group_stack.push(props.id);
- if (obj && event)
- rcube_event.cancel(event);
-
- case 'listgroup':
- this.reset_qsearch();
- this.list_contacts(props.source, props.id);
- break;
-
- case 'popgroup':
- if (this.env.address_group_stack.length > 1) {
- this.env.address_group_stack.pop();
- this.reset_qsearch();
- this.list_contacts(props.source, this.env.address_group_stack[this.env.address_group_stack.length-1]);
- }
- break;
-
- case 'import-messages':
- var form = props || this.gui_objects.importform;
- $('input[name="_unlock"]', form).val(this.set_busy(true, 'importwait'));
- this.upload_file(form, 'import');
- break;
-
- case 'import':
- if (this.env.action == 'import' && this.gui_objects.importform) {
- var file = document.getElementById('rcmimportfile');
- if (file && !file.value) {
- alert(this.get_label('selectimportfile'));
- break;
- }
- this.gui_objects.importform.submit();
- this.set_busy(true, 'importwait');
- this.lock_form(this.gui_objects.importform, true);
- }
- else
- this.goto_url('import', (this.env.source ? '_target='+urlencode(this.env.source)+'&' : ''));
- break;
-
- case 'export':
- if (this.contact_list.rowcount > 0) {
- this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _search: this.env.search_request });
- }
- break;
-
- case 'export-selected':
- if (this.contact_list.rowcount > 0) {
- this.goto_url('export', { _source: this.env.source, _gid: this.env.group, _cid: this.contact_list.get_selection().join(',') });
- }
- break;
-
- case 'upload-photo':
- this.upload_contact_photo(props || this.gui_objects.uploadform);
- break;
-
- case 'delete-photo':
- this.replace_contact_photo('-del-');
- break;
-
- // user settings commands
- case 'preferences':
- case 'identities':
- case 'folders':
- this.goto_url('settings/' + command);
- break;
-
- case 'undo':
- this.http_request('undo', '', this.display_message('', 'loading'));
- break;
-
- // unified command call (command name == function name)
- default:
- var func = command.replace(/-/g, '_');
- if (this[func] && typeof this[func] === 'function') {
- ret = this[func](props, obj);
- }
- break;
- }
-
- if (this.triggerEvent('after'+command, props) === false)
- ret = false;
- this.triggerEvent('actionafter', {props:props, action:command});
-
- return ret === false ? false : obj ? false : true;
- };
-
- // set command(s) enabled or disabled
- this.enable_command = function()
- {
- var i, n, args = Array.prototype.slice.call(arguments),
- enable = args.pop(), cmd;
-
- for (n=0; n<args.length; n++) {
- cmd = args[n];
- // argument of type array
- if (typeof cmd === 'string') {
- this.commands[cmd] = enable;
- this.set_button(cmd, (enable ? 'act' : 'pas'));
- this.triggerEvent('enable-command', {command: cmd, status: enable});
- }
- // push array elements into commands array
- else {
- for (i in cmd)
- args.push(cmd[i]);
- }
- }
- };
-
- // lock/unlock interface
- this.set_busy = function(a, message, id)
- {
- if (a && message) {
- var msg = this.get_label(message);
- if (msg == message)
- msg = 'Loading...';
-
- id = this.display_message(msg, 'loading');
- }
- else if (!a && id) {
- this.hide_message(id);
- }
-
- this.busy = a;
- //document.body.style.cursor = a ? 'wait' : 'default';
-
- if (this.gui_objects.editform)
- this.lock_form(this.gui_objects.editform, a);
-
- return id;
- };
-
- // return a localized string
- this.get_label = function(name, domain)
- {
- if (domain && this.labels[domain+'.'+name])
- return this.labels[domain+'.'+name];
- else if (this.labels[name])
- return this.labels[name];
- else
- return name;
- };
-
- // alias for convenience reasons
- this.gettext = this.get_label;
-
- // switch to another application task
- this.switch_task = function(task)
- {
- if (this.task===task && task!='mail')
- return;
-
- var url = this.get_task_url(task);
- if (task=='mail')
- url += '&_mbox=INBOX';
-
- this.redirect(url);
- };
-
- this.get_task_url = function(task, url)
- {
- if (!url)
- url = this.env.comm_path;
-
- return url.replace(/_task=[a-z0-9_-]+/i, '_task='+task);
- };
-
- this.reload = function(delay)
- {
- if (this.is_framed())
- parent.rcmail.reload(delay);
- else if (delay)
- setTimeout(function(){ rcmail.reload(); }, delay);
- else if (window.location)
- location.href = this.env.comm_path + (this.env.action ? '&_action='+this.env.action : '');
- };
-
- // Add variable to GET string, replace old value if exists
- this.add_url = function(url, name, value)
- {
- value = urlencode(value);
-
- if (/(\?.*)$/.test(url)) {
- var urldata = RegExp.$1,
- datax = RegExp('((\\?|&)'+RegExp.escape(name)+'=[^&]*)');
-
- if (datax.test(urldata)) {
- urldata = urldata.replace(datax, RegExp.$2 + name + '=' + value);
- }
- else
- urldata += '&' + name + '=' + value
-
- return url.replace(/(\?.*)$/, urldata);
- }
-
- return url + '?' + name + '=' + value;
- };
-
- this.is_framed = function()
- {
- return (this.env.framed && parent.rcmail && parent.rcmail != this && parent.rcmail.command);
- };
-
- this.save_pref = function(prop)
- {
- var request = {'_name': prop.name, '_value': prop.value};
-
- if (prop.session)
- request['_session'] = prop.session;
- if (prop.env)
- this.env[prop.env] = prop.value;
-
- this.http_post('save-pref', request);
- };
-
- this.html_identifier = function(str, encode)
- {
- return encode ? this.html_identifier_encode(str) : String(str).replace(this.identifier_expr, '_');
- };
-
- this.html_identifier_encode = function(str)
- {
- return Base64.encode(String(str)).replace(/=+$/, '').replace(/\+/g, '-').replace(/\//g, '_');
- };
-
- this.html_identifier_decode = function(str)
- {
- str = String(str).replace(/-/g, '+').replace(/_/g, '/');
-
- while (str.length % 4) str += '=';
-
- return Base64.decode(str);
- };
-
-
- /*********************************************************/
- /********* event handling methods *********/
- /*********************************************************/
-
- this.drag_menu = function(e, target)
- {
- var modkey = rcube_event.get_modifier(e),
- menu = this.gui_objects.dragmenu;
-
- if (menu && modkey == SHIFT_KEY && this.commands['copy']) {
- var pos = rcube_event.get_mouse_pos(e);
- this.env.drag_target = target;
- $(menu).css({top: (pos.y-10)+'px', left: (pos.x-10)+'px'}).show();
- return true;
- }
-
- return false;
- };
-
- this.drag_menu_action = function(action)
- {
- var menu = this.gui_objects.dragmenu;
- if (menu) {
- $(menu).hide();
- }
- this.command(action, this.env.drag_target);
- this.env.drag_target = null;
- };
-
- this.drag_start = function(list)
- {
- var model = this.task == 'mail' ? this.env.mailboxes : this.env.contactfolders;
-
- this.drag_active = true;
-
- if (this.preview_timer)
- clearTimeout(this.preview_timer);
- if (this.preview_read_timer)
- clearTimeout(this.preview_read_timer);
-
- // prepare treelist widget for dragging interactions
- if (this.treelist)
- this.treelist.drag_start();
- };
-
- this.drag_end = function(e)
- {
- this.drag_active = false;
- this.env.last_folder_target = null;
-
- if (this.treelist)
- this.treelist.drag_end();
- };
-
- this.drag_move = function(e)
- {
- if (this.gui_objects.folderlist) {
- var drag_target, oldclass,
- layerclass = 'draglayernormal',
- mouse = rcube_event.get_mouse_pos(e);
-
- if (this.contact_list && this.contact_list.draglayer)
- oldclass = this.contact_list.draglayer.attr('class');
-
- // mouse intersects a valid drop target on the treelist
- if (this.treelist && (drag_target = this.treelist.intersects(mouse, true))) {
- this.env.last_folder_target = drag_target;
- layerclass = 'draglayer' + (this.check_droptarget(drag_target) > 1 ? 'copy' : 'normal');
- }
- else {
- // Clear target, otherwise drag end will trigger move into last valid droptarget
- this.env.last_folder_target = null;
- }
-
- if (layerclass != oldclass && this.contact_list && this.contact_list.draglayer)
- this.contact_list.draglayer.attr('class', layerclass);
- }
- };
-
- this.collapse_folder = function(name)
- {
- if (this.treelist)
- this.treelist.toggle(name);
- };
-
- this.folder_collapsed = function(node)
- {
- var prefname = this.env.task == 'addressbook' ? 'collapsed_abooks' : 'collapsed_folders';
-
- if (node.collapsed) {
- this.env[prefname] = this.env[prefname] + '&'+urlencode(node.id)+'&';
-
- // select the folder if one of its childs is currently selected
- // don't select if it's virtual (#1488346)
- if (this.env.mailbox && this.env.mailbox.indexOf(name + this.env.delimiter) == 0 && !node.virtual)
- this.command('list', name);
- }
- else {
- var reg = new RegExp('&'+urlencode(node.id)+'&');
- this.env[prefname] = this.env[prefname].replace(reg, '');
- }
-
- if (!this.drag_active) {
- this.command('save-pref', { name: prefname, value: this.env[prefname] });
-
- if (this.env.unread_counts)
- this.set_unread_count_display(node.id, false);
- }
- };
-
- this.doc_mouse_up = function(e)
- {
- var model, list, id;
-
- // ignore event if jquery UI dialog is open
- if ($(rcube_event.get_target(e)).closest('.ui-dialog, .ui-widget-overlay').length)
- return;
-
- if (list = this.message_list)
- model = this.env.mailboxes;
- else if (list = this.contact_list)
- model = this.env.contactfolders;
- else if (this.ksearch_value)
- this.ksearch_blur();
-
- if (list && !rcube_mouse_is_over(e, list.list.parentNode))
- list.blur();
-
- // handle mouse release when dragging
- if (this.drag_active && model && this.env.last_folder_target) {
- var target = model[this.env.last_folder_target];
-
- this.env.last_folder_target = null;
- list.draglayer.hide();
- this.drag_end(e);
-
- if (this.contact_list) {
- if (!this.contacts_drag_menu(e, target))
- this.command('move', target);
- }
- else if (!this.drag_menu(e, target))
- this.command('move', target);
- }
-
- // reset 'pressed' buttons
- if (this.buttons_sel) {
- for (id in this.buttons_sel)
- if (typeof id !== 'function')
- this.button_out(this.buttons_sel[id], id);
- this.buttons_sel = {};
- }
- };
-
- this.click_on_list = function(e)
- {
- if (this.gui_objects.qsearchbox)
- this.gui_objects.qsearchbox.blur();
-
- if (this.message_list)
- this.message_list.focus();
- else if (this.contact_list)
- this.contact_list.focus();
-
- return true;
- };
-
- this.msglist_select = function(list)
- {
- if (this.preview_timer)
- clearTimeout(this.preview_timer);
- if (this.preview_read_timer)
- clearTimeout(this.preview_read_timer);
-
- var selected = list.get_single_selection();
-
- this.enable_command(this.env.message_commands, selected != null);
- if (selected) {
- // Hide certain command buttons when Drafts folder is selected
- if (this.env.mailbox == this.env.drafts_mailbox)
- this.enable_command('reply', 'reply-all', 'reply-list', 'forward', 'forward-attachment', 'forward-inline', false);
- // Disable reply-list when List-Post header is not set
- else {
- var msg = this.env.messages[selected];
- if (!msg.ml)
- this.enable_command('reply-list', false);
- }
- }
- // Multi-message commands
- this.enable_command('delete', 'move', 'copy', 'mark', 'forward', 'forward-attachment', list.selection.length > 0);
-
- // reset all-pages-selection
- if (selected || (list.selection.length && list.selection.length != list.rowcount))
- this.select_all_mode = false;
-
- // start timer for message preview (wait for double click)
- if (selected && this.env.contentframe && !list.multi_selecting && !this.dummy_select)
- this.preview_timer = setTimeout(function() { ref.msglist_get_preview(); }, this.dblclick_time);
- else if (this.env.contentframe)
- this.show_contentframe(false);
- };
-
- // This allow as to re-select selected message and display it in preview frame
- this.msglist_click = function(list)
- {
- if (list.multi_selecting || !this.env.contentframe)
- return;
-
- if (list.get_single_selection())
- return;
-
- var win = this.get_frame_window(this.env.contentframe);
-
- if (win && win.location.href.indexOf(this.env.blankpage) >= 0) {
- if (this.preview_timer)
- clearTimeout(this.preview_timer);
- if (this.preview_read_timer)
- clearTimeout(this.preview_read_timer);
-
- this.preview_timer = setTimeout(function() { ref.msglist_get_preview(); }, this.dblclick_time);
- }
- };
-
- this.msglist_dbl_click = function(list)
- {
- if (this.preview_timer)
- clearTimeout(this.preview_timer);
- if (this.preview_read_timer)
- clearTimeout(this.preview_read_timer);
-
- var uid = list.get_single_selection();
-
- if (uid && this.env.mailbox == this.env.drafts_mailbox)
- this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox });
- else if (uid)
- this.show_message(uid, false, false);
- };
-
- this.msglist_keypress = function(list)
- {
- if (list.modkey == CONTROL_KEY)
- return;
-
- if (list.key_pressed == list.ENTER_KEY)
- this.command('show');
- else if (list.key_pressed == list.DELETE_KEY || list.key_pressed == list.BACKSPACE_KEY)
- this.command('delete');
- else if (list.key_pressed == 33)
- this.command('previouspage');
- else if (list.key_pressed == 34)
- this.command('nextpage');
- };
-
- this.msglist_get_preview = function()
- {
- var uid = this.get_single_uid();
- if (uid && this.env.contentframe && !this.drag_active)
- this.show_message(uid, false, true);
- else if (this.env.contentframe)
- this.show_contentframe(false);
- };
-
- this.msglist_expand = function(row)
- {
- if (this.env.messages[row.uid])
- this.env.messages[row.uid].expanded = row.expanded;
- $(row.obj)[row.expanded?'addClass':'removeClass']('expanded');
- };
-
- this.msglist_set_coltypes = function(list)
- {
- var i, found, name, cols = list.thead.rows[0].cells;
-
- this.env.coltypes = [];
-
- for (i=0; i<cols.length; i++)
- if (cols[i].id && cols[i].id.match(/^rcm/)) {
- name = cols[i].id.replace(/^rcm/, '');
- this.env.coltypes.push(name);
- }
-
- if ((found = $.inArray('flag', this.env.coltypes)) >= 0)
- this.env.flagged_col = found;
-
- if ((found = $.inArray('subject', this.env.coltypes)) >= 0)
- this.env.subject_col = found;
-
- this.command('save-pref', { name: 'list_cols', value: this.env.coltypes, session: 'list_attrib/columns' });
- };
-
- this.check_droptarget = function(id)
- {
- switch (this.task) {
- case 'mail':
- return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual) ? 1 : 0;
-
- case 'settings':
- return id != this.env.mailbox ? 1 : 0;
-
- case 'addressbook':
- var target;
- if (id != this.env.source && (target = this.env.contactfolders[id])) {
- // droptarget is a group
- if (target.type == 'group') {
- if (target.id != this.env.group && !this.env.contactfolders[target.source].readonly) {
- var is_other = this.env.selection_sources.length > 1 || $.inArray(target.source, this.env.selection_sources) == -1;
- return !is_other || this.commands.move ? 1 : 2;
- }
- }
- // droptarget is a (writable) addressbook and it's not the source
- else if (!target.readonly && (this.env.selection_sources.length > 1 || $.inArray(id, this.env.selection_sources) == -1)) {
- return this.commands.move ? 1 : 2;
- }
- }
- }
-
- return 0;
- };
-
- // open popup window
- this.open_window = function(url, small, toolbar)
- {
- var wname = 'rcmextwin' + new Date().getTime();
-
- url += (url.match(/\?/) ? '&' : '?') + '_extwin=1';
-
- if (this.env.standard_windows)
- extwin = window.open(url, wname);
- else {
- var win = this.is_framed() ? parent.window : window,
- page = $(win),
- page_width = page.width(),
- page_height = bw.mz ? $('body', win).height() : page.height(),
- w = Math.min(small ? this.env.popup_width_small : this.env.popup_width, page_width),
- h = page_height, // always use same height
- l = (win.screenLeft || win.screenX) + 20,
- t = (win.screenTop || win.screenY) + 20,
- extwin = window.open(url, wname,
- 'width='+w+',height='+h+',top='+t+',left='+l+',resizable=yes,location=no,scrollbars=yes'
- +(toolbar ? ',toolbar=yes,menubar=yes,status=yes' : ',toolbar=no,menubar=no,status=no'));
- }
-
- // write loading... message to empty windows
- if (!url && extwin.document) {
- extwin.document.write('<html><body>' + this.get_label('loading') + '</body></html>');
- }
-
- // focus window, delayed to bring to front
- window.setTimeout(function() { extwin.focus(); }, 10);
-
- return extwin;
- };
-
-
- /*********************************************************/
- /********* (message) list functionality *********/
- /*********************************************************/
-
- this.init_message_row = function(row)
- {
- var expando, self = this, uid = row.uid,
- status_icon = (this.env.status_col != null ? 'status' : 'msg') + 'icn' + row.uid;
-
- if (uid && this.env.messages[uid])
- $.extend(row, this.env.messages[uid]);
-
- // set eventhandler to status icon
- if (row.icon = document.getElementById(status_icon)) {
- row.icon._row = row.obj;
- row.icon.onmousedown = function(e) { self.command('toggle_status', this); rcube_event.cancel(e); };
- }
-
- // save message icon position too
- if (this.env.status_col != null)
- row.msgicon = document.getElementById('msgicn'+row.uid);
- else
- row.msgicon = row.icon;
-
- // set eventhandler to flag icon, if icon found
- if (this.env.flagged_col != null && (row.flagicon = document.getElementById('flagicn'+row.uid))) {
- row.flagicon._row = row.obj;
- row.flagicon.onmousedown = function(e) { self.command('toggle_flag', this); rcube_event.cancel(e); };
- }
-
- if (!row.depth && row.has_children && (expando = document.getElementById('rcmexpando'+row.uid))) {
- row.expando = expando;
- expando.onmousedown = function(e) { return self.expand_message_row(e, uid); };
- if (bw.touch) {
- expando.addEventListener('touchend', function(e) {
- if (e.changedTouches.length == 1) {
- self.expand_message_row(e, uid);
- return rcube_event.cancel(e);
- }
- }, false);
- }
- }
-
- this.triggerEvent('insertrow', { uid:uid, row:row });
- };
-
- // create a table row in the message list
- this.add_message_row = function(uid, cols, flags, attop)
- {
- if (!this.gui_objects.messagelist || !this.message_list)
- return false;
-
- // Prevent from adding messages from different folder (#1487752)
- if (flags.mbox != this.env.mailbox && !flags.skip_mbox_check)
- return false;
-
- if (!this.env.messages[uid])
- this.env.messages[uid] = {};
-
- // merge flags over local message object
- $.extend(this.env.messages[uid], {
- deleted: flags.deleted?1:0,
- replied: flags.answered?1:0,
- unread: !flags.seen?1:0,
- forwarded: flags.forwarded?1:0,
- flagged: flags.flagged?1:0,
- has_children: flags.has_children?1:0,
- depth: flags.depth?flags.depth:0,
- unread_children: flags.unread_children?flags.unread_children:0,
- parent_uid: flags.parent_uid?flags.parent_uid:0,
- selected: this.select_all_mode || this.message_list.in_selection(uid),
- ml: flags.ml?1:0,
- ctype: flags.ctype,
- // flags from plugins
- flags: flags.extra_flags
- });
-
- var c, n, col, html, css_class,
- tree = '', expando = '',
- list = this.message_list,
- rows = list.rows,
- message = this.env.messages[uid],
- row_class = 'message'
- + (!flags.seen ? ' unread' : '')
- + (flags.deleted ? ' deleted' : '')
- + (flags.flagged ? ' flagged' : '')
- + (message.selected ? ' selected' : ''),
- row = { cols:[], style:{}, id:'rcmrow'+uid };
-
- // message status icons
- css_class = 'msgicon';
- if (this.env.status_col === null) {
- css_class += ' status';
- if (flags.deleted)
- css_class += ' deleted';
- else if (!flags.seen)
- css_class += ' unread';
- else if (flags.unread_children > 0)
- css_class += ' unreadchildren';
- }
- if (flags.answered)
- css_class += ' replied';
- if (flags.forwarded)
- css_class += ' forwarded';
-
- // update selection
- if (message.selected && !list.in_selection(uid))
- list.selection.push(uid);
-
- // threads
- if (this.env.threading) {
- if (message.depth) {
- // This assumes that div width is hardcoded to 15px,
- tree += '<span id="rcmtab' + uid + '" class="branch" style="width:' + (message.depth * 15) + 'px;">&nbsp;&nbsp;</span>';
-
- if ((rows[message.parent_uid] && rows[message.parent_uid].expanded === false)
- || ((this.env.autoexpand_threads == 0 || this.env.autoexpand_threads == 2) &&
- (!rows[message.parent_uid] || !rows[message.parent_uid].expanded))
- ) {
- row.style.display = 'none';
- message.expanded = false;
- }
- else
- message.expanded = true;
-
- row_class += ' thread expanded';
- }
- else if (message.has_children) {
- if (message.expanded === undefined && (this.env.autoexpand_threads == 1 || (this.env.autoexpand_threads == 2 && message.unread_children))) {
- message.expanded = true;
- }
-
- expando = '<div id="rcmexpando' + uid + '" class="' + (message.expanded ? 'expanded' : 'collapsed') + '">&nbsp;&nbsp;</div>';
- row_class += ' thread' + (message.expanded? ' expanded' : '');
- }
-
- if (flags.unread_children && flags.seen && !message.expanded)
- row_class += ' unroot';
- }
-
- tree += '<span id="msgicn'+uid+'" class="'+css_class+'">&nbsp;</span>';
- row.className = row_class;
-
- // build subject link
- if (!bw.ie && cols.subject) {
- var action = flags.mbox == this.env.drafts_mailbox ? 'compose' : 'show';
- var uid_param = flags.mbox == this.env.drafts_mailbox ? '_draft_uid' : '_uid';
- cols.subject = '<a href="./?_task=mail&_action='+action+'&_mbox='+urlencode(flags.mbox)+'&'+uid_param+'='+uid+'"'+
- ' onclick="return rcube_event.cancel(event)" onmouseover="rcube_webmail.long_subject_title(this,'+(message.depth+1)+')">'+cols.subject+'</a>';
- }
-
- // add each submitted col
- for (n in this.env.coltypes) {
- c = this.env.coltypes[n];
- col = { className: String(c).toLowerCase() };
-
- if (c == 'flag') {
- css_class = (flags.flagged ? 'flagged' : 'unflagged');
- html = '<span id="flagicn'+uid+'" class="'+css_class+'">&nbsp;</span>';
- }
- else if (c == 'attachment') {
- if (/application\/|multipart\/(m|signed)/.test(flags.ctype))
- html = '<span class="attachment">&nbsp;</span>';
- else if (/multipart\/report/.test(flags.ctype))
- html = '<span class="report">&nbsp;</span>';
- else
- html = '&nbsp;';
- }
- else if (c == 'status') {
- if (flags.deleted)
- css_class = 'deleted';
- else if (!flags.seen)
- css_class = 'unread';
- else if (flags.unread_children > 0)
- css_class = 'unreadchildren';
- else
- css_class = 'msgicon';
- html = '<span id="statusicn'+uid+'" class="'+css_class+'">&nbsp;</span>';
- }
- else if (c == 'threads')
- html = expando;
- else if (c == 'subject') {
- if (bw.ie) {
- col.onmouseover = function() { rcube_webmail.long_subject_title_ie(this, message.depth+1); };
- if (bw.ie8)
- tree = '<span></span>' + tree; // #1487821
- }
- html = tree + cols[c];
- }
- else if (c == 'priority') {
- if (flags.prio > 0 && flags.prio < 6)
- html = '<span class="prio'+flags.prio+'">&nbsp;</span>';
- else
- html = '&nbsp;';
- }
- else
- html = cols[c];
-
- col.innerHTML = html;
- row.cols.push(col);
- }
-
- list.insert_row(row, attop);
-
- // remove 'old' row
- if (attop && this.env.pagesize && list.rowcount > this.env.pagesize) {
- var uid = list.get_last_row();
- list.remove_row(uid);
- list.clear_selection(uid);
- }
- };
-
- this.set_list_sorting = function(sort_col, sort_order)
- {
- // set table header class
- $('#rcm'+this.env.sort_col).removeClass('sorted'+(this.env.sort_order.toUpperCase()));
- if (sort_col)
- $('#rcm'+sort_col).addClass('sorted'+sort_order);
-
- this.env.sort_col = sort_col;
- this.env.sort_order = sort_order;
- };
-
- this.set_list_options = function(cols, sort_col, sort_order, threads)
- {
- var update, post_data = {};
-
- if (sort_col === undefined)
- sort_col = this.env.sort_col;
- if (!sort_order)
- sort_order = this.env.sort_order;
-
- if (this.env.sort_col != sort_col || this.env.sort_order != sort_order) {
- update = 1;
- this.set_list_sorting(sort_col, sort_order);
- }
-
- if (this.env.threading != threads) {
- update = 1;
- post_data._threads = threads;
- }
-
- if (cols && cols.length) {
- // make sure new columns are added at the end of the list
- var i, idx, name, newcols = [], oldcols = this.env.coltypes;
- for (i=0; i<oldcols.length; i++) {
- name = oldcols[i];
- idx = $.inArray(name, cols);
- if (idx != -1) {
- newcols.push(name);
- delete cols[idx];
- }
- }
- for (i=0; i<cols.length; i++)
- if (cols[i])
- newcols.push(cols[i]);
-
- if (newcols.join() != oldcols.join()) {
- update = 1;
- post_data._cols = newcols.join(',');
- }
- }
-
- if (update)
- this.list_mailbox('', '', sort_col+'_'+sort_order, post_data);
- };
-
- // when user double-clicks on a row
- this.show_message = function(id, safe, preview)
- {
- if (!id)
- return;
-
- var win, target = window,
- action = preview ? 'preview': 'show',
- url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox);
-
- if (preview && (win = this.get_frame_window(this.env.contentframe))) {
- target = win;
- url += '&_framed=1';
- }
-
- if (safe)
- url += '&_safe=1';
-
- // also send search request to get the right messages
- if (this.env.search_request)
- url += '&_search='+this.env.search_request;
-
- // add browser capabilities, so we can properly handle attachments
- url += '&_caps='+urlencode(this.browser_capabilities());
-
- if (this.env.extwin)
- url += '&_extwin=1';
-
- if (preview && String(target.location.href).indexOf(url) >= 0) {
- this.show_contentframe(true);
- }
- else {
- if (!preview && this.env.message_extwin && !this.env.extwin)
- this.open_window(this.env.comm_path+url, true);
- else
- this.location_href(this.env.comm_path+url, target, true);
-
- // mark as read and change mbox unread counter
- if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read >= 0) {
- this.preview_read_timer = setTimeout(function() {
- ref.set_message(id, 'unread', false);
- ref.update_thread_root(id, 'read');
- if (ref.env.unread_counts[ref.env.mailbox]) {
- ref.env.unread_counts[ref.env.mailbox] -= 1;
- ref.set_unread_count(ref.env.mailbox, ref.env.unread_counts[ref.env.mailbox], ref.env.mailbox == 'INBOX');
- }
- if (ref.env.preview_pane_mark_read > 0)
- ref.http_post('mark', {_uid: id, _flag: 'read', _quiet: 1});
- }, this.env.preview_pane_mark_read * 1000);
- }
- }
- };
-
- this.show_contentframe = function(show)
- {
- var frame, win, name = this.env.contentframe;
-
- if (name && (frame = this.get_frame_element(name))) {
- if (!show && (win = this.get_frame_window(name))) {
- if (win.stop)
- win.stop();
- else // IE
- win.document.execCommand('Stop');
-
- win.location.href = this.env.blankpage;
- }
- else if (!bw.safari && !bw.konq)
- $(frame)[show ? 'show' : 'hide']();
- }
-
- if (!show && this.env.frame_lock)
- this.set_busy(false, null, this.env.frame_lock);
- };
-
- this.get_frame_element = function(id)
- {
- var frame;
-
- if (id && (frame = document.getElementById(id)))
- return frame;
- };
-
- this.get_frame_window = function(id)
- {
- var frame = this.get_frame_element(id);
-
- if (frame && frame.name && window.frames)
- return window.frames[frame.name];
- };
-
- this.lock_frame = function()
- {
- if (!this.env.frame_lock)
- (this.is_framed() ? parent.rcmail : this).env.frame_lock = this.set_busy(true, 'loading');
- };
-
- // list a specific page
- this.list_page = function(page)
- {
- if (page == 'next')
- page = this.env.current_page+1;
- else if (page == 'last')
- page = this.env.pagecount;
- else if (page == 'prev' && this.env.current_page > 1)
- page = this.env.current_page-1;
- else if (page == 'first' && this.env.current_page > 1)
- page = 1;
-
- if (page > 0 && page <= this.env.pagecount) {
- this.env.current_page = page;
-
- if (this.task == 'addressbook' || this.contact_list)
- this.list_contacts(this.env.source, this.env.group, page);
- else if (this.task == 'mail')
- this.list_mailbox(this.env.mailbox, page);
- }
- };
-
- // sends request to check for recent messages
- this.checkmail = function()
- {
- var lock = this.set_busy(true, 'checkingmail'),
- params = this.check_recent_params();
-
- this.http_request('check-recent', params, lock);
- };
-
- // list messages of a specific mailbox using filter
- this.filter_mailbox = function(filter)
- {
- var lock = this.set_busy(true, 'searching');
-
- this.clear_message_list();
-
- // reset vars
- this.env.current_page = 1;
- this.http_request('search', this.search_params(false, filter), lock);
- };
-
- // list messages of a specific mailbox
- this.list_mailbox = function(mbox, page, sort, url)
- {
- var win, target = window;
-
- if (typeof url != 'object')
- url = {};
-
- if (!mbox)
- mbox = this.env.mailbox ? this.env.mailbox : 'INBOX';
-
- // add sort to url if set
- if (sort)
- url._sort = sort;
-
- // also send search request to get the right messages
- if (this.env.search_request)
- url._search = this.env.search_request;
-
- // set page=1 if changeing to another mailbox
- if (this.env.mailbox != mbox) {
- page = 1;
- this.env.current_page = page;
- this.select_all_mode = false;
- }
-
- // unselect selected messages and clear the list and message data
- this.clear_message_list();
-
- if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
- url._refresh = 1;
-
- this.select_folder(mbox, '', true);
- this.unmark_folder(mbox, 'recent', '', true);
- this.env.mailbox = mbox;
-
- // load message list remotely
- if (this.gui_objects.messagelist) {
- this.list_mailbox_remote(mbox, page, url);
- return;
- }
-
- if (win = this.get_frame_window(this.env.contentframe)) {
- target = win;
- url._framed = 1;
- }
-
- // load message list to target frame/window
- if (mbox) {
- this.set_busy(true, 'loading');
- url._mbox = mbox;
- if (page)
- url._page = page;
- this.location_href(url, target);
- }
- };
-
- this.clear_message_list = function()
- {
- this.env.messages = {};
- this.last_selected = 0;
-
- this.show_contentframe(false);
- if (this.message_list)
- this.message_list.clear(true);
- };
-
- // send remote request to load message list
- this.list_mailbox_remote = function(mbox, page, post_data)
- {
- // clear message list first
- this.message_list.clear();
-
- var lock = this.set_busy(true, 'loading');
-
- if (typeof post_data != 'object')
- post_data = {};
- post_data._mbox = mbox;
- if (page)
- post_data._page = page;
-
- this.http_request('list', post_data, lock);
- };
-
- // removes messages that doesn't exists from list selection array
- this.update_selection = function()
- {
- var selected = this.message_list.selection,
- rows = this.message_list.rows,
- i, selection = [];
-
- for (i in selected)
- if (rows[selected[i]])
- selection.push(selected[i]);
-
- this.message_list.selection = selection;
- }
-
- // expand all threads with unread children
- this.expand_unread = function()
- {
- var r, tbody = this.gui_objects.messagelist.tBodies[0],
- new_row = tbody.firstChild;
-
- while (new_row) {
- if (new_row.nodeType == 1 && (r = this.message_list.rows[new_row.uid]) && r.unread_children) {
- this.message_list.expand_all(r);
- this.set_unread_children(r.uid);
- }
- new_row = new_row.nextSibling;
- }
- return false;
- };
-
- // thread expanding/collapsing handler
- this.expand_message_row = function(e, uid)
- {
- var row = this.message_list.rows[uid];
-
- // handle unread_children mark
- row.expanded = !row.expanded;
- this.set_unread_children(uid);
- row.expanded = !row.expanded;
-
- this.message_list.expand_row(e, uid);
- };
-
- // message list expanding
- this.expand_threads = function()
- {
- if (!this.env.threading || !this.env.autoexpand_threads || !this.message_list)
- return;
-
- switch (this.env.autoexpand_threads) {
- case 2: this.expand_unread(); break;
- case 1: this.message_list.expand_all(); break;
- }
- };
-
- // Initializes threads indicators/expanders after list update
- this.init_threads = function(roots, mbox)
- {
- // #1487752
- if (mbox && mbox != this.env.mailbox)
- return false;
-
- for (var n=0, len=roots.length; n<len; n++)
- this.add_tree_icons(roots[n]);
- this.expand_threads();
- };
-
- // adds threads tree icons to the list (or specified thread)
- this.add_tree_icons = function(root)
- {
- var i, l, r, n, len, pos, tmp = [], uid = [],
- row, rows = this.message_list.rows;
-
- if (root)
- row = rows[root] ? rows[root].obj : null;
- else
- row = this.message_list.tbody.firstChild;
-
- while (row) {
- if (row.nodeType == 1 && (r = rows[row.uid])) {
- if (r.depth) {
- for (i=tmp.length-1; i>=0; i--) {
- len = tmp[i].length;
- if (len > r.depth) {
- pos = len - r.depth;
- if (!(tmp[i][pos] & 2))
- tmp[i][pos] = tmp[i][pos] ? tmp[i][pos]+2 : 2;
- }
- else if (len == r.depth) {
- if (!(tmp[i][0] & 2))
- tmp[i][0] += 2;
- }
- if (r.depth > len)
- break;
- }
-
- tmp.push(new Array(r.depth));
- tmp[tmp.length-1][0] = 1;
- uid.push(r.uid);
- }
- else {
- if (tmp.length) {
- for (i in tmp) {
- this.set_tree_icons(uid[i], tmp[i]);
- }
- tmp = [];
- uid = [];
- }
- if (root && row != rows[root].obj)
- break;
- }
- }
- row = row.nextSibling;
- }
-
- if (tmp.length) {
- for (i in tmp) {
- this.set_tree_icons(uid[i], tmp[i]);
- }
- }
- };
-
- // adds tree icons to specified message row
- this.set_tree_icons = function(uid, tree)
- {
- var i, divs = [], html = '', len = tree.length;
-
- for (i=0; i<len; i++) {
- if (tree[i] > 2)
- divs.push({'class': 'l3', width: 15});
- else if (tree[i] > 1)
- divs.push({'class': 'l2', width: 15});
- else if (tree[i] > 0)
- divs.push({'class': 'l1', width: 15});
- // separator div
- else if (divs.length && !divs[divs.length-1]['class'])
- divs[divs.length-1].width += 15;
- else
- divs.push({'class': null, width: 15});
- }
-
- for (i=divs.length-1; i>=0; i--) {
- if (divs[i]['class'])
- html += '<div class="tree '+divs[i]['class']+'" />';
- else
- html += '<div style="width:'+divs[i].width+'px" />';
- }
-
- if (html)
- $('#rcmtab'+uid).html(html);
- };
-
- // update parent in a thread
- this.update_thread_root = function(uid, flag)
- {
- if (!this.env.threading)
- return;
-
- var root = this.message_list.find_root(uid);
-
- if (uid == root)
- return;
-
- var p = this.message_list.rows[root];
-
- if (flag == 'read' && p.unread_children) {
- p.unread_children--;
- }
- else if (flag == 'unread' && p.has_children) {
- // unread_children may be undefined
- p.unread_children = p.unread_children ? p.unread_children + 1 : 1;
- }
- else {
- return;
- }
-
- this.set_message_icon(root);
- this.set_unread_children(root);
- };
-
- // update thread indicators for all messages in a thread below the specified message
- // return number of removed/added root level messages
- this.update_thread = function (uid)
- {
- if (!this.env.threading)
- return 0;
-
- var r, parent, count = 0,
- rows = this.message_list.rows,
- row = rows[uid],
- depth = rows[uid].depth,
- roots = [];
-
- if (!row.depth) // root message: decrease roots count
- count--;
- else if (row.unread) {
- // update unread_children for thread root
- parent = this.message_list.find_root(uid);
- rows[parent].unread_children--;
- this.set_unread_children(parent);
- }
-
- parent = row.parent_uid;
-
- // childrens
- row = row.obj.nextSibling;
- while (row) {
- if (row.nodeType == 1 && (r = rows[row.uid])) {
- if (!r.depth || r.depth <= depth)
- break;
-
- r.depth--; // move left
- // reset width and clear the content of a tab, icons will be added later
- $('#rcmtab'+r.uid).width(r.depth * 15).html('');
- if (!r.depth) { // a new root
- count++; // increase roots count
- r.parent_uid = 0;
- if (r.has_children) {
- // replace 'leaf' with 'collapsed'
- $('#rcmrow'+r.uid+' '+'.leaf:first')
- .attr('id', 'rcmexpando' + r.uid)
- .attr('class', (r.obj.style.display != 'none' ? 'expanded' : 'collapsed'))
- .bind('mousedown', {uid:r.uid, p:this},
- function(e) { return e.data.p.expand_message_row(e, e.data.uid); });
-
- r.unread_children = 0;
- roots.push(r);
- }
- // show if it was hidden
- if (r.obj.style.display == 'none')
- $(r.obj).show();
- }
- else {
- if (r.depth == depth)
- r.parent_uid = parent;
- if (r.unread && roots.length)
- roots[roots.length-1].unread_children++;
- }
- }
- row = row.nextSibling;
- }
-
- // update unread_children for roots
- for (var i=0; i<roots.length; i++)
- this.set_unread_children(roots[i].uid);
-
- return count;
- };
-
- this.delete_excessive_thread_rows = function()
- {
- var rows = this.message_list.rows,
- tbody = this.message_list.tbody,
- row = tbody.firstChild,
- cnt = this.env.pagesize + 1;
-
- while (row) {
- if (row.nodeType == 1 && (r = rows[row.uid])) {
- if (!r.depth && cnt)
- cnt--;
-
- if (!cnt)
- this.message_list.remove_row(row.uid);
- }
- row = row.nextSibling;
- }
- };
-
- // set message icon
- this.set_message_icon = function(uid)
- {
- var css_class,
- row = this.message_list.rows[uid];
-
- if (!row)
- return false;
-
- if (row.icon) {
- css_class = 'msgicon';
- if (row.deleted)
- css_class += ' deleted';
- else if (row.unread)
- css_class += ' unread';
- else if (row.unread_children)
- css_class += ' unreadchildren';
- if (row.msgicon == row.icon) {
- if (row.replied)
- css_class += ' replied';
- if (row.forwarded)
- css_class += ' forwarded';
- css_class += ' status';
- }
-
- row.icon.className = css_class;
- }
-
- if (row.msgicon && row.msgicon != row.icon) {
- css_class = 'msgicon';
- if (!row.unread && row.unread_children)
- css_class += ' unreadchildren';
- if (row.replied)
- css_class += ' replied';
- if (row.forwarded)
- css_class += ' forwarded';
-
- row.msgicon.className = css_class;
- }
-
- if (row.flagicon) {
- css_class = (row.flagged ? 'flagged' : 'unflagged');
- row.flagicon.className = css_class;
- }
- };
-
- // set message status
- this.set_message_status = function(uid, flag, status)
- {
- var row = this.message_list.rows[uid];
-
- if (!row)
- return false;
-
- if (flag == 'unread')
- row.unread = status;
- else if(flag == 'deleted')
- row.deleted = status;
- else if (flag == 'replied')
- row.replied = status;
- else if (flag == 'forwarded')
- row.forwarded = status;
- else if (flag == 'flagged')
- row.flagged = status;
- };
-
- // set message row status, class and icon
- this.set_message = function(uid, flag, status)
- {
- var row = this.message_list && this.message_list.rows[uid];
-
- if (!row)
- return false;
-
- if (flag)
- this.set_message_status(uid, flag, status);
-
- var rowobj = $(row.obj);
-
- if (row.unread && !rowobj.hasClass('unread'))
- rowobj.addClass('unread');
- else if (!row.unread && rowobj.hasClass('unread'))
- rowobj.removeClass('unread');
-
- if (row.deleted && !rowobj.hasClass('deleted'))
- rowobj.addClass('deleted');
- else if (!row.deleted && rowobj.hasClass('deleted'))
- rowobj.removeClass('deleted');
-
- if (row.flagged && !rowobj.hasClass('flagged'))
- rowobj.addClass('flagged');
- else if (!row.flagged && rowobj.hasClass('flagged'))
- rowobj.removeClass('flagged');
-
- this.set_unread_children(uid);
- this.set_message_icon(uid);
- };
-
- // sets unroot (unread_children) class of parent row
- this.set_unread_children = function(uid)
- {
- var row = this.message_list.rows[uid];
-
- if (row.parent_uid)
- return;
-
- if (!row.unread && row.unread_children && !row.expanded)
- $(row.obj).addClass('unroot');
- else
- $(row.obj).removeClass('unroot');
- };
-
- // copy selected messages to the specified mailbox
- this.copy_messages = function(mbox)
- {
- if (mbox && typeof mbox === 'object')
- mbox = mbox.id;
-
- // exit if current or no mailbox specified
- if (!mbox || mbox == this.env.mailbox)
- return;
-
- var post_data = this.selection_post_data({_target_mbox: mbox});
-
- // exit if selection is empty
- if (!post_data._uid)
- return;
-
- // send request to server
- this.http_post('copy', post_data, this.display_message(this.get_label('copyingmessage'), 'loading'));
- };
-
- // move selected messages to the specified mailbox
- this.move_messages = function(mbox)
- {
- if (mbox && typeof mbox === 'object')
- mbox = mbox.id;
-
- // exit if current or no mailbox specified
- if (!mbox || mbox == this.env.mailbox)
- return;
-
- var lock = false, post_data = this.selection_post_data({_target_mbox: mbox});
-
- // exit if selection is empty
- if (!post_data._uid)
- return;
-
- // show wait message
- if (this.env.action == 'show')
- lock = this.set_busy(true, 'movingmessage');
- else
- this.show_contentframe(false);
-
- // Hide message command buttons until a message is selected
- this.enable_command(this.env.message_commands, false);
-
- this._with_selected_messages('move', post_data, lock);
- };
-
- // delete selected messages from the current mailbox
- this.delete_messages = function(event)
- {
- var uid, i, len, trash = this.env.trash_mailbox,
- list = this.message_list,
- selection = list ? list.get_selection() : [];
-
- // exit if no mailbox specified or if selection is empty
- if (!this.env.uid && !selection.length)
- return;
-
- // also select childs of collapsed rows
- for (i=0, len=selection.length; i<len; i++) {
- uid = selection[i];
- if (list.rows[uid].has_children && !list.rows[uid].expanded)
- list.select_children(uid);
- }
-
- // if config is set to flag for deletion
- if (this.env.flag_for_deletion) {
- this.mark_message('delete');
- return false;
- }
- // if there isn't a defined trash mailbox or we are in it
- else if (!trash || this.env.mailbox == trash)
- this.permanently_remove_messages();
- // we're in Junk folder and delete_junk is enabled
- else if (this.env.delete_junk && this.env.junk_mailbox && this.env.mailbox == this.env.junk_mailbox)
- this.permanently_remove_messages();
- // if there is a trash mailbox defined and we're not currently in it
- else {
- // if shift was pressed delete it immediately
- if ((list && list.modkey == SHIFT_KEY) || (event && rcube_event.get_modifier(event) == SHIFT_KEY)) {
- if (confirm(this.get_label('deletemessagesconfirm')))
- this.permanently_remove_messages();
- }
- else
- this.move_messages(trash);
- }
-
- return true;
- };
-
- // delete the selected messages permanently
- this.permanently_remove_messages = function()
- {
- var post_data = this.selection_post_data();
-
- // exit if selection is empty
- if (!post_data._uid)
- return;
-
- this.show_contentframe(false);
- this._with_selected_messages('delete', post_data);
- };
-
- // Send a specifc move/delete request with UIDs of all selected messages
- // @private
- this._with_selected_messages = function(action, post_data, lock)
- {
- var count = 0, msg;
-
- // update the list (remove rows, clear selection)
- if (this.message_list) {
- var n, id, root, roots = [],
- selection = this.message_list.get_selection();
-
- for (n=0, len=selection.length; n<len; n++) {
- id = selection[n];
-
- if (this.env.threading) {
- count += this.update_thread(id);
- root = this.message_list.find_root(id);
- if (root != id && $.inArray(root, roots) < 0) {
- roots.push(root);
- }
- }
- this.message_list.remove_row(id, (this.env.display_next && n == selection.length-1));
- }
- // make sure there are no selected rows
- if (!this.env.display_next)
- this.message_list.clear_selection();
- // update thread tree icons
- for (n=0, len=roots.length; n<len; n++) {
- this.add_tree_icons(roots[n]);
- }
- }
-
- if (this.env.display_next && this.env.next_uid)
- post_data._next_uid = this.env.next_uid;
-
- if (count < 0)
- post_data._count = (count*-1);
- // remove threads from the end of the list
- else if (count > 0)
- this.delete_excessive_thread_rows();
-
- if (!lock) {
- msg = action == 'move' ? 'movingmessage' : 'deletingmessage';
- lock = this.display_message(this.get_label(msg), 'loading');
- }
-
- // send request to server
- this.http_post(action, post_data, lock);
- };
-
- // build post data for message delete/move/copy/flag requests
- this.selection_post_data = function(data)
- {
- if (typeof(data) != 'object')
- data = {};
-
- data._mbox = this.env.mailbox;
-
- if (!data._uid) {
- var uids = this.env.uid ? [this.env.uid] : this.message_list.get_selection();
- data._uid = this.uids_to_list(uids);
- }
-
- if (this.env.action)
- data._from = this.env.action;
-
- // also send search request to get the right messages
- if (this.env.search_request)
- data._search = this.env.search_request;
-
- return data;
- };
-
- // set a specific flag to one or more messages
- this.mark_message = function(flag, uid)
- {
- var a_uids = [], r_uids = [], len, n, id,
- list = this.message_list;
-
- if (uid)
- a_uids[0] = uid;
- else if (this.env.uid)
- a_uids[0] = this.env.uid;
- else if (list)
- a_uids = list.get_selection();
-
- if (!list)
- r_uids = a_uids;
- else {
- list.focus();
- for (n=0, len=a_uids.length; n<len; n++) {
- id = a_uids[n];
- if ((flag == 'read' && list.rows[id].unread)
- || (flag == 'unread' && !list.rows[id].unread)
- || (flag == 'delete' && !list.rows[id].deleted)
- || (flag == 'undelete' && list.rows[id].deleted)
- || (flag == 'flagged' && !list.rows[id].flagged)
- || (flag == 'unflagged' && list.rows[id].flagged))
- {
- r_uids.push(id);
- }
- }
- }
-
- // nothing to do
- if (!r_uids.length && !this.select_all_mode)
- return;
-
- switch (flag) {
- case 'read':
- case 'unread':
- this.toggle_read_status(flag, r_uids);
- break;
- case 'delete':
- case 'undelete':
- this.toggle_delete_status(r_uids);
- break;
- case 'flagged':
- case 'unflagged':
- this.toggle_flagged_status(flag, a_uids);
- break;
- }
- };
-
- // set class to read/unread
- this.toggle_read_status = function(flag, a_uids)
- {
- var i, len = a_uids.length,
- post_data = this.selection_post_data({_uid: this.uids_to_list(a_uids), _flag: flag}),
- lock = this.display_message(this.get_label('markingmessage'), 'loading');
-
- // mark all message rows as read/unread
- for (i=0; i<len; i++)
- this.set_message(a_uids[i], 'unread', (flag == 'unread' ? true : false));
-
- this.http_post('mark', post_data, lock);
-
- for (i=0; i<len; i++)
- this.update_thread_root(a_uids[i], flag);
- };
-
- // set image to flagged or unflagged
- this.toggle_flagged_status = function(flag, a_uids)
- {
- var i, len = a_uids.length,
- post_data = this.selection_post_data({_uid: this.uids_to_list(a_uids), _flag: flag}),
- lock = this.display_message(this.get_label('markingmessage'), 'loading');
-
- // mark all message rows as flagged/unflagged
- for (i=0; i<len; i++)
- this.set_message(a_uids[i], 'flagged', (flag == 'flagged' ? true : false));
-
- this.http_post('mark', post_data, lock);
- };
-
- // mark all message rows as deleted/undeleted
- this.toggle_delete_status = function(a_uids)
- {
- var len = a_uids.length,
- i, uid, all_deleted = true,
- rows = this.message_list ? this.message_list.rows : [];
-
- if (len == 1) {
- if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted))
- this.flag_as_deleted(a_uids);
- else
- this.flag_as_undeleted(a_uids);
-
- return true;
- }
-
- for (i=0; i<len; i++) {
- uid = a_uids[i];
- if (rows[uid] && !rows[uid].deleted) {
- all_deleted = false;
- break;
- }
- }
-
- if (all_deleted)
- this.flag_as_undeleted(a_uids);
- else
- this.flag_as_deleted(a_uids);
-
- return true;
- };
-
- this.flag_as_undeleted = function(a_uids)
- {
- var i, len = a_uids.length,
- post_data = this.selection_post_data({_uid: this.uids_to_list(a_uids), _flag: 'undelete'}),
- lock = this.display_message(this.get_label('markingmessage'), 'loading');
-
- for (i=0; i<len; i++)
- this.set_message(a_uids[i], 'deleted', false);
-
- this.http_post('mark', post_data, lock);
- };
-
- this.flag_as_deleted = function(a_uids)
- {
- var r_uids = [],
- post_data = this.selection_post_data({_uid: this.uids_to_list(a_uids), _flag: 'delete'}),
- lock = this.display_message(this.get_label('markingmessage'), 'loading'),
- rows = this.message_list ? this.message_list.rows : [],
- count = 0;
-
- for (var i=0, len=a_uids.length; i<len; i++) {
- uid = a_uids[i];
- if (rows[uid]) {
- if (rows[uid].unread)
- r_uids[r_uids.length] = uid;
-
- if (this.env.skip_deleted) {
- count += this.update_thread(uid);
- this.message_list.remove_row(uid, (this.env.display_next && i == this.message_list.selection.length-1));
- }
- else
- this.set_message(uid, 'deleted', true);
- }
- }
-
- // make sure there are no selected rows
- if (this.env.skip_deleted && this.message_list) {
- if(!this.env.display_next)
- this.message_list.clear_selection();
- if (count < 0)
- post_data._count = (count*-1);
- else if (count > 0)
- // remove threads from the end of the list
- this.delete_excessive_thread_rows();
- }
-
- // ??
- if (r_uids.length)
- post_data._ruid = this.uids_to_list(r_uids);
-
- if (this.env.skip_deleted && this.env.display_next && this.env.next_uid)
- post_data._next_uid = this.env.next_uid;
-
- this.http_post('mark', post_data, lock);
- };
-
- // flag as read without mark request (called from backend)
- // argument should be a coma-separated list of uids
- this.flag_deleted_as_read = function(uids)
- {
- var icn_src, uid, i, len,
- rows = this.message_list ? this.message_list.rows : [];
-
- uids = String(uids).split(',');
-
- for (i=0, len=uids.length; i<len; i++) {
- uid = uids[i];
- if (rows[uid])
- this.set_message(uid, 'unread', false);
- }
- };
-
- // Converts array of message UIDs to comma-separated list for use in URL
- // with select_all mode checking
- this.uids_to_list = function(uids)
- {
- return this.select_all_mode ? '*' : uids.join(',');
- };
-
- // Sets title of the delete button
- this.set_button_titles = function()
- {
- var label = 'deletemessage';
-
- if (!this.env.flag_for_deletion
- && this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox
- && (!this.env.delete_junk || !this.env.junk_mailbox || this.env.mailbox != this.env.junk_mailbox)
- )
- label = 'movemessagetotrash';
-
- this.set_alttext('delete', label);
- };
-
- /*********************************************************/
- /********* mailbox folders methods *********/
- /*********************************************************/
-
- this.expunge_mailbox = function(mbox)
- {
- var lock, post_data = {_mbox: mbox};
-
- // lock interface if it's the active mailbox
- if (mbox == this.env.mailbox) {
- lock = this.set_busy(true, 'loading');
- post_data._reload = 1;
- if (this.env.search_request)
- post_data._search = this.env.search_request;
- }
-
- // send request to server
- this.http_post('expunge', post_data, lock);
- };
-
- this.purge_mailbox = function(mbox)
- {
- var lock, post_data = {_mbox: mbox};
-
- if (!confirm(this.get_label('purgefolderconfirm')))
- return false;
-
- // lock interface if it's the active mailbox
- if (mbox == this.env.mailbox) {
- lock = this.set_busy(true, 'loading');
- post_data._reload = 1;
- }
-
- // send request to server
- this.http_post('purge', post_data, lock);
- };
-
- // test if purge command is allowed
- this.purge_mailbox_test = function()
- {
- return (this.env.exists && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox
- || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter))
- || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter))));
- };
-
-
- /*********************************************************/
- /********* login form methods *********/
- /*********************************************************/
-
- // handler for keyboard events on the _user field
- this.login_user_keyup = function(e)
- {
- var key = rcube_event.get_keycode(e);
- var passwd = $('#rcmloginpwd');
-
- // enter
- if (key == 13 && passwd.length && !passwd.val()) {
- passwd.focus();
- return rcube_event.cancel(e);
- }
-
- return true;
- };
-
-
- /*********************************************************/
- /********* message compose methods *********/
- /*********************************************************/
-
- this.open_compose_step = function(p)
- {
- var url = this.url('mail/compose', p);
-
- // open new compose window
- if (this.env.compose_extwin && !this.env.extwin) {
- this.open_window(url);
- }
- else {
- this.redirect(url);
- if (this.env.extwin)
- window.resizeTo(Math.max(this.env.popup_width, $(window).width()), $(window).height() + 24);
- }
- };
-
- // init message compose form: set focus and eventhandlers
- this.init_messageform = function()
- {
- if (!this.gui_objects.messageform)
- return false;
-
- var input_from = $("[name='_from']"),
- input_to = $("[name='_to']"),
- input_subject = $("input[name='_subject']"),
- input_message = $("[name='_message']").get(0),
- html_mode = $("input[name='_is_html']").val() == '1',
- ac_fields = ['cc', 'bcc', 'replyto', 'followupto'],
- ac_props, opener_rc = this.opener();
-
- // close compose step in opener
- if (opener_rc && opener_rc.env.action == 'compose') {
- setTimeout(function(){ opener.history.back(); }, 100);
- this.env.opened_extwin = true;
- }
-
- // configure parallel autocompletion
- if (this.env.autocomplete_threads > 0) {
- ac_props = {
- threads: this.env.autocomplete_threads,
- sources: this.env.autocomplete_sources
- };
- }
-
- // init live search events
- this.init_address_input_events(input_to, ac_props);
- for (var i in ac_fields) {
- this.init_address_input_events($("[name='_"+ac_fields[i]+"']"), ac_props);
- }
-
- if (!html_mode) {
- this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length);
- // add signature according to selected identity
- // if we have HTML editor, signature is added in callback
- if (input_from.prop('type') == 'select-one') {
- this.change_identity(input_from[0]);
- }
- }
-
- if (input_to.val() == '')
- input_to.focus();
- else if (input_subject.val() == '')
- input_subject.focus();
- else if (input_message)
- input_message.focus();
-
- this.env.compose_focus_elem = document.activeElement;
-
- // get summary of all field values
- this.compose_field_hash(true);
-
- // start the auto-save timer
- this.auto_save_start();
- };
-
- this.init_address_input_events = function(obj, props)
- {
- this.env.recipients_delimiter = this.env.recipients_separator + ' ';
-
- obj[bw.ie || bw.safari || bw.chrome ? 'keydown' : 'keypress'](function(e) { return ref.ksearch_keydown(e, this, props); })
- .attr('autocomplete', 'off');
- };
-
- this.submit_messageform = function(draft)
- {
- var form = this.gui_objects.messageform;
-
- if (!form)
- return;
-
- // all checks passed, send message
- var msgid = this.set_busy(true, draft ? 'savingmessage' : 'sendingmessage'),
- lang = this.spellcheck_lang(),
- files = [];
-
- // send files list
- $('li', this.gui_objects.attachmentlist).each(function() { files.push(this.id.replace(/^rcmfile/, '')); });
- $('input[name="_attachments"]', form).val(files.join());
-
- form.target = 'savetarget';
- form._draft.value = draft ? '1' : '';
- form.action = this.add_url(form.action, '_unlock', msgid);
- form.action = this.add_url(form.action, '_lang', lang);
-
- // register timer to notify about connection timeout
- this.submit_timer = setTimeout(function(){
- ref.set_busy(false, null, msgid);
- ref.display_message(ref.get_label('requesttimedout'), 'error');
- }, this.env.request_timeout * 1000);
-
- form.submit();
- };
-
- this.compose_recipient_select = function(list)
- {
- var id, n, recipients = 0;
- for (n=0; n < list.selection.length; n++) {
- id = list.selection[n];
- if (this.env.contactdata[id])
- recipients++;
- }
- this.enable_command('add-recipient', recipients);
- };
-
- this.compose_add_recipient = function(field)
- {
- var recipients = [], input = $('#_'+field), delim = this.env.recipients_delimiter;
-
- if (this.contact_list && this.contact_list.selection.length) {
- for (var id, n=0; n < this.contact_list.selection.length; n++) {
- id = this.contact_list.selection[n];
- if (id && this.env.contactdata[id]) {
- recipients.push(this.env.contactdata[id]);
-
- // group is added, expand it
- if (id.charAt(0) == 'E' && this.env.contactdata[id].indexOf('@') < 0 && input.length) {
- var gid = id.substr(1);
- this.group2expand[gid] = { name:this.env.contactdata[id], input:input.get(0) };
- this.http_request('group-expand', {_source: this.env.source, _gid: gid}, false);
- }
- }
- }
- }
-
- if (recipients.length && input.length) {
- var oldval = input.val(), rx = new RegExp(RegExp.escape(delim) + '\\s*$');
- if (oldval && !rx.test(oldval))
- oldval += delim + ' ';
- input.val(oldval + recipients.join(delim + ' ') + delim + ' ');
- this.triggerEvent('add-recipient', { field:field, recipients:recipients });
- }
- };
-
- // checks the input fields before sending a message
- this.check_compose_input = function(cmd)
- {
- // check input fields
- var ed, input_to = $("[name='_to']"),
- input_cc = $("[name='_cc']"),
- input_bcc = $("[name='_bcc']"),
- input_from = $("[name='_from']"),
- input_subject = $("[name='_subject']"),
- input_message = $("[name='_message']");
-
- // check sender (if have no identities)
- if (input_from.prop('type') == 'text' && !rcube_check_email(input_from.val(), true)) {
- alert(this.get_label('nosenderwarning'));
- input_from.focus();
- return false;
- }
-
- // check for empty recipient
- var recipients = input_to.val() ? input_to.val() : (input_cc.val() ? input_cc.val() : input_bcc.val());
- if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true)) {
- alert(this.get_label('norecipientwarning'));
- input_to.focus();
- return false;
- }
-
- // check if all files has been uploaded
- for (var key in this.env.attachments) {
- if (typeof this.env.attachments[key] === 'object' && !this.env.attachments[key].complete) {
- alert(this.get_label('notuploadedwarning'));
- return false;
- }
- }
-
- // display localized warning for missing subject
- if (input_subject.val() == '') {
- var myprompt = $('<div class="prompt">').html('<div class="message">' + this.get_label('nosubjectwarning') + '</div>').appendTo(document.body);
- var prompt_value = $('<input>').attr('type', 'text').attr('size', 30).appendTo(myprompt).val(this.get_label('nosubject'));
-
- var buttons = {};
- buttons[this.get_label('cancel')] = function(){
- input_subject.focus();
- $(this).dialog('close');
- };
- buttons[this.get_label('sendmessage')] = function(){
- input_subject.val(prompt_value.val());
- $(this).dialog('close');
- ref.command(cmd, { nocheck:true }); // repeat command which triggered this
- };
-
- myprompt.dialog({
- modal: true,
- resizable: false,
- buttons: buttons,
- close: function(event, ui) { $(this).remove() }
- });
- prompt_value.select();
- return false;
- }
-
- // Apply spellcheck changes if spell checker is active
- this.stop_spellchecking();
-
- if (window.tinyMCE)
- ed = tinyMCE.get(this.env.composebody);
-
- // check for empty body
- if (!ed && input_message.val() == '' && !confirm(this.get_label('nobodywarning'))) {
- input_message.focus();
- return false;
- }
- else if (ed) {
- if (!ed.getContent() && !confirm(this.get_label('nobodywarning'))) {
- ed.focus();
- return false;
- }
- // move body from html editor to textarea (just to be sure, #1485860)
- tinyMCE.triggerSave();
- }
-
- return true;
- };
-
- this.toggle_editor = function(props)
- {
- this.stop_spellchecking();
-
- if (props.mode == 'html') {
- this.plain2html($('#'+props.id).val(), props.id);
- tinyMCE.execCommand('mceAddControl', false, props.id);
-
- if (this.env.default_font)
- setTimeout(function() {
- $(tinyMCE.get(props.id).getBody()).css('font-family', rcmail.env.default_font);
- }, 500);
- }
- else {
- var thisMCE = tinyMCE.get(props.id), existingHtml;
-
- if (existingHtml = thisMCE.getContent()) {
- if (!confirm(this.get_label('editorwarning'))) {
- return false;
- }
- this.html2plain(existingHtml, props.id);
- }
- tinyMCE.execCommand('mceRemoveControl', false, props.id);
- }
-
- return true;
- };
-
- this.stop_spellchecking = function()
- {
- var ed;
-
- if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody))) {
- if (ed.plugins && ed.plugins.spellchecker && ed.plugins.spellchecker.active)
- ed.execCommand('mceSpellCheck');
- }
- else if (ed = this.env.spellcheck) {
- if (ed.state && ed.state != 'ready' && ed.state != 'no_error_found')
- $(ed.spell_span).trigger('click');
- }
-
- this.spellcheck_state();
- };
-
- this.spellcheck_state = function()
- {
- var ed, active;
-
- if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)) && ed.plugins && ed.plugins.spellchecker)
- active = ed.plugins.spellchecker.active;
- else if ((ed = this.env.spellcheck) && ed.state)
- active = ed.state != 'ready' && ed.state != 'no_error_found';
-
- if (rcmail.buttons.spellcheck)
- $('#'+rcmail.buttons.spellcheck[0].id)[active ? 'addClass' : 'removeClass']('selected');
-
- return active;
- };
-
- // get selected language
- this.spellcheck_lang = function()
- {
- var ed;
-
- if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)) && ed.plugins && ed.plugins.spellchecker)
- return ed.plugins.spellchecker.selectedLang;
- else if (this.env.spellcheck)
- return GOOGIE_CUR_LANG;
- };
-
- this.spellcheck_lang_set = function(lang)
- {
- var ed;
-
- if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)) && ed.plugins)
- ed.plugins.spellchecker.selectedLang = lang;
- else if (this.env.spellcheck)
- this.env.spellcheck.setCurrentLanguage(lang);
- };
-
- // resume spellchecking, highlight provided mispellings without new ajax request
- this.spellcheck_resume = function(ishtml, data)
- {
- if (ishtml) {
- var ed = tinyMCE.get(this.env.composebody);
- sp = ed.plugins.spellchecker;
-
- sp.active = 1;
- sp._markWords(data);
- ed.nodeChanged();
- }
- else {
- var sp = this.env.spellcheck;
- sp.prepare(false, true);
- sp.processData(data);
- }
-
- this.spellcheck_state();
- }
-
- this.set_draft_id = function(id)
- {
- var rc;
-
- if (!this.env.draft_id && id && (rc = this.opener())) {
- // refresh the drafts folder in opener window
- if (rc.env.task == 'mail' && rc.env.action == '' && rc.env.mailbox == this.env.drafts_mailbox)
- rc.command('checkmail');
- }
-
- this.env.draft_id = id;
- $("input[name='_draft_saveid']").val(id);
- };
-
- this.auto_save_start = function()
- {
- if (this.env.draft_autosave)
- this.save_timer = setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
-
- // Unlock interface now that saving is complete
- this.busy = false;
- };
-
- this.compose_field_hash = function(save)
- {
- // check input fields
- var ed, i, val, str = '', hash_fields = ['to', 'cc', 'bcc', 'subject'];
-
- for (i=0; i<hash_fields.length; i++)
- if (val = $('[name="_' + hash_fields[i] + '"]').val())
- str += val + ':';
-
- if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)))
- str += ed.getContent();
- else
- str += $("[name='_message']").val();
-
- if (this.env.attachments)
- for (var upload_id in this.env.attachments)
- str += upload_id;
-
- if (save)
- this.cmp_hash = str;
-
- return str;
- };
-
- this.change_identity = function(obj, show_sig)
- {
- if (!obj || !obj.options)
- return false;
-
- if (!show_sig)
- show_sig = this.env.show_sig;
-
- // first function execution
- if (!this.env.identities_initialized) {
- this.env.identities_initialized = true;
- if (this.env.show_sig_later)
- this.env.show_sig = true;
- if (this.env.opened_extwin)
- return;
- }
-
- var i, rx, cursor_pos, p = -1,
- id = obj.options[obj.selectedIndex].value,
- input_message = $("[name='_message']"),
- message = input_message.val(),
- is_html = ($("input[name='_is_html']").val() == '1'),
- sig = this.env.identity,
- delim = this.env.recipients_delimiter,
- headers = ['replyto', 'bcc'];
-
- // update reply-to/bcc fields with addresses defined in identities
- for (i in headers) {
- var key = headers[i],
- old_val = sig && this.env.identities[sig] ? this.env.identities[sig][key] : '',
- new_val = id && this.env.identities[id] ? this.env.identities[id][key] : '',
- input = $('[name="_'+key+'"]'), input_val = input.val();
-
- // remove old address(es)
- if (old_val && input_val) {
- rx = new RegExp('\\s*' + RegExp.escape(old_val) + '\\s*');
- input_val = input_val.replace(rx, '');
- }
-
- // cleanup
- rx = new RegExp(RegExp.escape(delim) + '\\s*' + RegExp(delim), 'g');
- input_val = input_val.replace(rx, delim)
- rx = new RegExp('^\\s*' + RegExp.escape(delim) + '\\s*$');
- input_val = input_val.replace(rx, '')
-
- // add new address(es)
- if (new_val) {
- rx = new RegExp(RegExp.escape(delim) + '\\s*$');
- if (input_val && !rx.test(input_val))
- input_val += delim + ' ';
- input_val += new_val + delim + ' ';
- }
-
- if (old_val || new_val)
- input.val(input_val).change();
- }
-
- // enable manual signature insert
- if (this.env.signatures && this.env.signatures[id]) {
- this.enable_command('insert-sig', true);
- this.env.compose_commands.push('insert-sig');
- }
- else
- this.enable_command('insert-sig', false);
-
- if (!is_html) {
- // remove the 'old' signature
- if (show_sig && sig && this.env.signatures && this.env.signatures[sig]) {
- sig = this.env.signatures[sig].text;
- sig = sig.replace(/\r\n/g, '\n');
-
- p = this.env.top_posting ? message.indexOf(sig) : message.lastIndexOf(sig);
- if (p >= 0)
- message = message.substring(0, p) + message.substring(p+sig.length, message.length);
- }
- // add the new signature string
- if (show_sig && this.env.signatures && this.env.signatures[id]) {
- sig = this.env.signatures[id].text;
- sig = sig.replace(/\r\n/g, '\n');
-
- if (this.env.top_posting) {
- if (p >= 0) { // in place of removed signature
- message = message.substring(0, p) + sig + message.substring(p, message.length);
- cursor_pos = p - 1;
- }
- else if (!message) { // empty message
- cursor_pos = 0;
- message = '\n\n' + sig;
- }
- else if (pos = this.get_caret_pos(input_message.get(0))) { // at cursor position
- message = message.substring(0, pos) + '\n' + sig + '\n\n' + message.substring(pos, message.length);
- cursor_pos = pos;
- }
- else { // on top
- cursor_pos = 0;
- message = '\n\n' + sig + '\n\n' + message.replace(/^[\r\n]+/, '');
- }
- }
- else {
- message = message.replace(/[\r\n]+$/, '');
- cursor_pos = !this.env.top_posting && message.length ? message.length+1 : 0;
- message += '\n\n' + sig;
- }
- }
- else
- cursor_pos = this.env.top_posting ? 0 : message.length;
-
- input_message.val(message);
-
- // move cursor before the signature
- this.set_caret_pos(input_message.get(0), cursor_pos);
- }
- else if (show_sig && this.env.signatures) { // html
- var editor = tinyMCE.get(this.env.composebody),
- 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 (this.env.top_posting) {
- // if no existing sig and top posting then insert at caret pos
- editor.getWin().focus(); // correct focus in IE & Chrome
-
- var node = editor.selection.getNode();
- if (node.nodeName == 'BODY') {
- // no real focus, insert at start
- body.insertBefore(sigElem, body.firstChild);
- body.insertBefore(doc.createElement('br'), body.firstChild);
- }
- else {
- body.insertBefore(sigElem, node.nextSibling);
- body.insertBefore(doc.createElement('br'), node.nextSibling);
- }
- }
- else {
- if (bw.ie) // add empty line before signature on IE
- body.appendChild(doc.createElement('br'));
-
- body.appendChild(sigElem);
- }
- }
-
- if (this.env.signatures[id])
- sigElem.innerHTML = this.env.signatures[id].html;
- }
-
- this.env.identity = id;
- return true;
- };
-
- // upload (attachment) file
- this.upload_file = function(form, action)
- {
- if (!form)
- return false;
-
- // count files and size on capable browser
- var size = 0, numfiles = 0;
-
- $('input[type=file]', form).each(function(i, field) {
- var files = field.files ? field.files.length : (field.value ? 1 : 0);
-
- // check file size
- if (field.files) {
- for (var i=0; i < files; i++)
- size += field.files[i].size;
- }
-
- numfiles += files;
- });
-
- // create hidden iframe and post upload form
- if (numfiles) {
- if (this.env.max_filesize && this.env.filesizeerror && size > this.env.max_filesize) {
- this.display_message(this.env.filesizeerror, 'error');
- return;
- }
-
- var frame_name = this.async_upload_form(form, action || 'upload', function(e) {
- var d, content = '';
- try {
- if (this.contentDocument) {
- d = this.contentDocument;
- } else if (this.contentWindow) {
- d = this.contentWindow.document;
- }
- content = d.childNodes[0].innerHTML;
- } catch (err) {}
-
- if (!content.match(/add2attachment/) && (!bw.opera || (rcmail.env.uploadframe && rcmail.env.uploadframe == e.data.ts))) {
- if (!content.match(/display_message/))
- rcmail.display_message(rcmail.get_label('fileuploaderror'), 'error');
- rcmail.remove_from_attachment_list(e.data.ts);
- }
- // Opera hack: handle double onload
- if (bw.opera)
- rcmail.env.uploadframe = e.data.ts;
- });
-
- // display upload indicator and cancel button
- var content = '<span>' + this.get_label('uploading' + (numfiles > 1 ? 'many' : '')) + '</span>',
- ts = frame_name.replace(/^rcmupload/, '');
-
- this.add2attachment_list(ts, { name:'', html:content, classname:'uploading', frame:frame_name, complete:false });
-
- // upload progress support
- if (this.env.upload_progress_time) {
- this.upload_progress_start('upload', ts);
- }
- }
-
- // set reference to the form object
- this.gui_objects.attachmentform = form;
- return true;
- };
-
- // add file name to attachment list
- // called from upload page
- this.add2attachment_list = function(name, att, upload_id)
- {
- if (!this.gui_objects.attachmentlist)
- return false;
-
- if (!att.complete && ref.env.loadingicon)
- att.html = '<img src="'+ref.env.loadingicon+'" alt="" class="uploading" />' + att.html;
-
- if (!att.complete && att.frame)
- att.html = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+name+'\', \''+att.frame+'\');" href="#cancelupload" class="cancelupload">'
- + (this.env.cancelicon ? '<img src="'+this.env.cancelicon+'" alt="" />' : this.get_label('cancel')) + '</a>' + att.html;
-
- var indicator, li = $('<li>').attr('id', name).addClass(att.classname).html(att.html);
-
- // replace indicator's li
- if (upload_id && (indicator = document.getElementById(upload_id))) {
- li.replaceAll(indicator);
- }
- else { // add new li
- li.appendTo(this.gui_objects.attachmentlist);
- }
-
- if (upload_id && this.env.attachments[upload_id])
- delete this.env.attachments[upload_id];
-
- this.env.attachments[name] = att;
-
- return true;
- };
-
- this.remove_from_attachment_list = function(name)
- {
- delete this.env.attachments[name];
- $('#'+name).remove();
- };
-
- this.remove_attachment = function(name)
- {
- if (name && this.env.attachments[name])
- this.http_post('remove-attachment', { _id:this.env.compose_id, _file:name });
-
- return true;
- };
-
- this.cancel_attachment_upload = function(name, frame_name)
- {
- if (!name || !frame_name)
- return false;
-
- this.remove_from_attachment_list(name);
- $("iframe[name='"+frame_name+"']").remove();
- return false;
- };
-
- this.upload_progress_start = function(action, name)
- {
- setTimeout(function() { rcmail.http_request(action, {_progress: name}); },
- this.env.upload_progress_time * 1000);
- };
-
- this.upload_progress_update = function(param)
- {
- var elem = $('#'+param.name + '> span');
-
- if (!elem.length || !param.text)
- return;
-
- elem.text(param.text);
-
- if (!param.done)
- this.upload_progress_start(param.action, param.name);
- };
-
- // send remote request to add a new contact
- this.add_contact = function(value)
- {
- if (value)
- this.http_post('addcontact', {_address: value});
-
- return true;
- };
-
- // send remote request to search mail or contacts
- this.qsearch = function(value)
- {
- if (value != '') {
- var r, lock = this.set_busy(true, 'searching'),
- url = this.search_params(value);
-
- if (this.message_list)
- this.clear_message_list();
- else if (this.contact_list)
- this.list_contacts_clear();
-
- if (this.env.source)
- url._source = this.env.source;
- if (this.env.group)
- url._gid = this.env.group;
-
- // reset vars
- this.env.current_page = 1;
-
- var action = this.env.action == 'compose' && this.contact_list ? 'search-contacts' : 'search';
- r = this.http_request(action, url, lock);
-
- this.env.qsearch = {lock: lock, request: r};
- }
- };
-
- // build URL params for search
- this.search_params = function(search, filter)
- {
- var n, url = {}, mods_arr = [],
- mods = this.env.search_mods,
- mbox = this.env.mailbox;
-
- if (!filter && this.gui_objects.search_filter)
- filter = this.gui_objects.search_filter.value;
-
- if (!search && this.gui_objects.qsearchbox)
- search = this.gui_objects.qsearchbox.value;
-
- if (filter)
- url._filter = filter;
-
- if (search) {
- url._q = search;
-
- if (mods && this.message_list)
- mods = mods[mbox] ? mods[mbox] : mods['*'];
-
- if (mods) {
- for (n in mods)
- mods_arr.push(n);
- url._headers = mods_arr.join(',');
- }
- }
-
- if (mbox)
- url._mbox = mbox;
-
- return url;
- };
-
- // reset quick-search form
- this.reset_qsearch = function()
- {
- if (this.gui_objects.qsearchbox)
- this.gui_objects.qsearchbox.value = '';
-
- if (this.env.qsearch)
- this.abort_request(this.env.qsearch);
-
- this.env.qsearch = null;
- this.env.search_request = null;
- this.env.search_id = null;
- };
-
- this.sent_successfully = function(type, msg, folders)
- {
- this.display_message(msg, type);
-
- if (this.env.extwin) {
- var rc = this.opener();
- this.lock_form(this.gui_objects.messageform);
- if (rc) {
- rc.display_message(msg, type);
- // refresh the folder where sent message was saved or replied message comes from
- if (folders && rc.env.task == 'mail' && rc.env.action == '' && $.inArray(rc.env.mailbox, folders) >= 0) {
- // @TODO: try with 'checkmail' here when #1485186 is fixed. See also #1489249.
- rc.command('list', rc.env.mailbox);
- }
- }
- setTimeout(function(){ window.close() }, 1000);
- }
- else {
- // before redirect we need to wait some time for Chrome (#1486177)
- setTimeout(function(){ ref.list_mailbox(); }, 500);
- }
- };
-
-
- /*********************************************************/
- /********* keyboard live-search methods *********/
- /*********************************************************/
-
- // handler for keyboard events on address-fields
- this.ksearch_keydown = function(e, obj, props)
- {
- if (this.ksearch_timer)
- clearTimeout(this.ksearch_timer);
-
- var highlight,
- key = rcube_event.get_keycode(e),
- mod = rcube_event.get_modifier(e);
-
- switch (key) {
- case 38: // arrow up
- case 40: // arrow down
- if (!this.ksearch_visible())
- break;
-
- var dir = key==38 ? 1 : 0;
-
- highlight = document.getElementById('rcmksearchSelected');
- if (!highlight)
- highlight = this.ksearch_pane.__ul.firstChild;
-
- if (highlight)
- this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling);
-
- return rcube_event.cancel(e);
-
- case 9: // tab
- if (mod == SHIFT_KEY || !this.ksearch_visible()) {
- this.ksearch_hide();
- return;
- }
-
- case 13: // enter
- if (!this.ksearch_visible())
- return false;
-
- // insert selected address and hide ksearch pane
- this.insert_recipient(this.ksearch_selected);
- this.ksearch_hide();
-
- return rcube_event.cancel(e);
-
- case 27: // escape
- this.ksearch_hide();
- return;
-
- case 37: // left
- case 39: // right
- if (mod != SHIFT_KEY)
- return;
- }
-
- // start timer
- this.ksearch_timer = setTimeout(function(){ ref.ksearch_get_results(props); }, 200);
- this.ksearch_input = obj;
-
- return true;
- };
-
- this.ksearch_visible = function()
- {
- return (this.ksearch_selected !== null && this.ksearch_selected !== undefined && this.ksearch_value);
- };
-
- this.ksearch_select = function(node)
- {
- var current = $('#rcmksearchSelected');
- if (current[0] && node) {
- current.removeAttr('id').removeClass('selected');
- }
-
- if (node) {
- $(node).attr('id', 'rcmksearchSelected').addClass('selected');
- this.ksearch_selected = node._rcm_id;
- }
- };
-
- this.insert_recipient = function(id)
- {
- if (id === null || !this.env.contacts[id] || !this.ksearch_input)
- return;
-
- // get cursor pos
- var inp_value = this.ksearch_input.value,
- cpos = this.get_caret_pos(this.ksearch_input),
- p = inp_value.lastIndexOf(this.ksearch_value, cpos),
- trigger = false,
- insert = '',
- // replace search string with full address
- pre = inp_value.substring(0, p),
- end = inp_value.substring(p+this.ksearch_value.length, inp_value.length);
-
- this.ksearch_destroy();
-
- // insert all members of a group
- if (typeof this.env.contacts[id] === 'object' && this.env.contacts[id].id) {
- insert += this.env.contacts[id].name + this.env.recipients_delimiter;
- this.group2expand[this.env.contacts[id].id] = $.extend({ input: this.ksearch_input }, this.env.contacts[id]);
- this.http_request('mail/group-expand', {_source: this.env.contacts[id].source, _gid: this.env.contacts[id].id}, false);
- }
- else if (typeof this.env.contacts[id] === 'string') {
- insert = this.env.contacts[id] + this.env.recipients_delimiter;
- trigger = true;
- }
-
- this.ksearch_input.value = pre + insert + end;
-
- // set caret to insert pos
- cpos = p+insert.length;
- if (this.ksearch_input.setSelectionRange)
- this.ksearch_input.setSelectionRange(cpos, cpos);
-
- if (trigger)
- this.triggerEvent('autocomplete_insert', { field:this.ksearch_input, insert:insert });
- };
-
- this.replace_group_recipients = function(id, recipients)
- {
- if (this.group2expand[id]) {
- this.group2expand[id].input.value = this.group2expand[id].input.value.replace(this.group2expand[id].name, recipients);
- this.triggerEvent('autocomplete_insert', { field:this.group2expand[id].input, insert:recipients });
- this.group2expand[id] = null;
- }
- };
-
- // address search processor
- this.ksearch_get_results = function(props)
- {
- var inp_value = this.ksearch_input ? this.ksearch_input.value : null;
-
- if (inp_value === null)
- return;
-
- if (this.ksearch_pane && this.ksearch_pane.is(":visible"))
- this.ksearch_pane.hide();
-
- // get string from current cursor pos to last comma
- var cpos = this.get_caret_pos(this.ksearch_input),
- p = inp_value.lastIndexOf(this.env.recipients_separator, cpos-1),
- q = inp_value.substring(p+1, cpos),
- min = this.env.autocomplete_min_length,
- ac = this.ksearch_data;
-
- // trim query string
- q = $.trim(q);
-
- // Don't (re-)search if the last results are still active
- if (q == this.ksearch_value)
- return;
-
- this.ksearch_destroy();
-
- if (q.length && q.length < min) {
- if (!this.ksearch_info) {
- this.ksearch_info = this.display_message(
- this.get_label('autocompletechars').replace('$min', min));
- }
- return;
- }
-
- var old_value = this.ksearch_value;
- this.ksearch_value = q;
-
- // ...string is empty
- if (!q.length)
- return;
-
- // ...new search value contains old one and previous search was not finished or its result was empty
- if (old_value && old_value.length && q.indexOf(old_value) == 0 && (!ac || ac.num <= 0) && this.env.contacts && !this.env.contacts.length)
- return;
-
- var i, lock, source, xhr, reqid = new Date().getTime(),
- post_data = {_search: q, _id: reqid},
- threads = props && props.threads ? props.threads : 1,
- sources = props && props.sources ? props.sources : [],
- action = props && props.action ? props.action : 'mail/autocomplete';
-
- this.ksearch_data = {id: reqid, sources: sources.slice(), action: action,
- locks: [], requests: [], num: sources.length};
-
- for (i=0; i<threads; i++) {
- source = this.ksearch_data.sources.shift();
- if (threads > 1 && source === undefined)
- break;
-
- post_data._source = source ? source : '';
- lock = this.display_message(this.get_label('searching'), 'loading');
- xhr = this.http_post(action, post_data, lock);
-
- this.ksearch_data.locks.push(lock);
- this.ksearch_data.requests.push(xhr);
- }
- };
-
- this.ksearch_query_results = function(results, search, reqid)
- {
- // search stopped in meantime?
- if (!this.ksearch_value)
- return;
-
- // ignore this outdated search response
- if (this.ksearch_input && search != this.ksearch_value)
- return;
-
- // display search results
- var i, len, ul, li, text, init,
- value = this.ksearch_value,
- data = this.ksearch_data,
- maxlen = this.env.autocomplete_max ? this.env.autocomplete_max : 15;
-
- // create results pane if not present
- if (!this.ksearch_pane) {
- ul = $('<ul>');
- this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane')
- .css({ position:'absolute', 'z-index':30000 }).append(ul).appendTo(document.body);
- this.ksearch_pane.__ul = ul[0];
- }
-
- ul = this.ksearch_pane.__ul;
-
- // remove all search results or add to existing list if parallel search
- if (reqid && this.ksearch_pane.data('reqid') == reqid) {
- maxlen -= ul.childNodes.length;
- }
- else {
- this.ksearch_pane.data('reqid', reqid);
- init = 1;
- // reset content
- ul.innerHTML = '';
- this.env.contacts = [];
- // move the results pane right under the input box
- var pos = $(this.ksearch_input).offset();
- this.ksearch_pane.css({ left:pos.left+'px', top:(pos.top + this.ksearch_input.offsetHeight)+'px', display: 'none'});
- }
-
- // add each result line to list
- if (results && (len = results.length)) {
- for (i=0; i < len && maxlen > 0; i++) {
- text = typeof results[i] === 'object' ? results[i].name : results[i];
- li = document.createElement('LI');
- li.innerHTML = text.replace(new RegExp('('+RegExp.escape(value)+')', 'ig'), '##$1%%').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/##([^%]+)%%/g, '<b>$1</b>');
- li.onmouseover = function(){ ref.ksearch_select(this); };
- li.onmouseup = function(){ ref.ksearch_click(this) };
- li._rcm_id = this.env.contacts.length + i;
- ul.appendChild(li);
- maxlen -= 1;
- }
- }
-
- if (ul.childNodes.length) {
- this.ksearch_pane.show();
- // select the first
- if (!this.env.contacts.length) {
- $('li:first', ul).attr('id', 'rcmksearchSelected').addClass('selected');
- this.ksearch_selected = 0;
- }
- }
-
- if (len)
- this.env.contacts = this.env.contacts.concat(results);
-
- // run next parallel search
- if (data.id == reqid) {
- data.num--;
- if (maxlen > 0 && data.sources.length) {
- var lock, xhr, source = data.sources.shift(), post_data;
- if (source) {
- post_data = {_search: value, _id: reqid, _source: source};
- lock = this.display_message(this.get_label('searching'), 'loading');
- xhr = this.http_post(data.action, post_data, lock);
-
- this.ksearch_data.locks.push(lock);
- this.ksearch_data.requests.push(xhr);
- }
- }
- else if (!maxlen) {
- if (!this.ksearch_msg)
- this.ksearch_msg = this.display_message(this.get_label('autocompletemore'));
- // abort pending searches
- this.ksearch_abort();
- }
- }
- };
-
- this.ksearch_click = function(node)
- {
- if (this.ksearch_input)
- this.ksearch_input.focus();
-
- this.insert_recipient(node._rcm_id);
- this.ksearch_hide();
- };
-
- this.ksearch_blur = function()
- {
- if (this.ksearch_timer)
- clearTimeout(this.ksearch_timer);
-
- this.ksearch_input = null;
- this.ksearch_hide();
- };
-
- this.ksearch_hide = function()
- {
- this.ksearch_selected = null;
- this.ksearch_value = '';
-
- if (this.ksearch_pane)
- this.ksearch_pane.hide();
-
- this.ksearch_destroy();
- };
-
- // Clears autocomplete data/requests
- this.ksearch_destroy = function()
- {
- this.ksearch_abort();
-
- if (this.ksearch_info)
- this.hide_message(this.ksearch_info);
-
- if (this.ksearch_msg)
- this.hide_message(this.ksearch_msg);
-
- this.ksearch_data = null;
- this.ksearch_info = null;
- this.ksearch_msg = null;
- }
-
- // Aborts pending autocomplete requests
- this.ksearch_abort = function()
- {
- var i, len, ac = this.ksearch_data;
-
- if (!ac)
- return;
-
- for (i=0, len=ac.locks.length; i<len; i++)
- this.abort_request({request: ac.requests[i], lock: ac.locks[i]});
- };
-
-
- /*********************************************************/
- /********* address book methods *********/
- /*********************************************************/
-
- this.contactlist_keypress = function(list)
- {
- if (list.key_pressed == list.DELETE_KEY)
- this.command('delete');
- };
-
- this.contactlist_select = function(list)
- {
- if (this.preview_timer)
- clearTimeout(this.preview_timer);
-
- var n, id, sid, contact, ref = this, writable = false,
- source = this.env.source ? this.env.address_sources[this.env.source] : null;
-
- // we don't have dblclick handler here, so use 200 instead of this.dblclick_time
- if (id = list.get_single_selection())
- this.preview_timer = setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
- else if (this.env.contentframe)
- this.show_contentframe(false);
-
- if (list.selection.length) {
- list.draggable = false;
-
- // no source = search result, we'll need to detect if any of
- // selected contacts are in writable addressbook to enable edit/delete
- // we'll also need to know sources used in selection for copy
- // and group-addmember operations (drag&drop)
- this.env.selection_sources = [];
-
- if (source) {
- this.env.selection_sources.push(this.env.source);
- }
-
- for (n in list.selection) {
- contact = list.data[list.selection[n]];
- if (!source) {
- sid = String(list.selection[n]).replace(/^[^-]+-/, '');
- if (sid && this.env.address_sources[sid]) {
- writable = writable || (!this.env.address_sources[sid].readonly && !contact.readonly);
- this.env.selection_sources.push(sid);
- }
- }
- else {
- writable = writable || (!source.readonly && !contact.readonly);
- }
-
- if (contact._type != 'group')
- list.draggable = true;
- }
-
- this.env.selection_sources = $.unique(this.env.selection_sources);
- }
-
- // if a group is currently selected, and there is at least one contact selected
- // thend we can enable the group-remove-selected command
- this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0 && writable);
- this.enable_command('compose', this.env.group || list.selection.length > 0);
- this.enable_command('export-selected', 'copy', list.selection.length > 0);
- this.enable_command('edit', id && writable);
- this.enable_command('delete', 'move', list.selection.length > 0 && writable);
-
- return false;
- };
-
- this.list_contacts = function(src, group, page)
- {
- var win, folder, url = {},
- target = window;
-
- if (!src)
- src = this.env.source;
-
- if (page && this.current_page == page && src == this.env.source && group == this.env.group)
- return false;
-
- if (src != this.env.source) {
- page = this.env.current_page = 1;
- this.reset_qsearch();
- }
- else if (group != this.env.group)
- page = this.env.current_page = 1;
-
- if (this.env.search_id)
- folder = 'S'+this.env.search_id;
- else if (!this.env.search_request)
- folder = group ? 'G'+src+group : src;
-
- this.env.source = src;
- this.env.group = group;
-
- // truncate groups listing stack
- var index = $.inArray(this.env.group, this.env.address_group_stack);
- if (index < 0)
- this.env.address_group_stack = [];
- else
- this.env.address_group_stack = this.env.address_group_stack.slice(0,index);
-
- // make sure the current group is on top of the stack
- if (this.env.group) {
- this.env.address_group_stack.push(this.env.group);
-
- // mark the first group on the stack as selected in the directory list
- folder = 'G'+src+this.env.address_group_stack[0];
- }
- else if (this.gui_objects.addresslist_title) {
- $(this.gui_objects.addresslist_title).html(this.get_label('contacts'));
- }
-
- this.select_folder(folder, '', true);
-
- // load contacts remotely
- if (this.gui_objects.contactslist) {
- this.list_contacts_remote(src, group, page);
- return;
- }
-
- if (win = this.get_frame_window(this.env.contentframe)) {
- target = win;
- url._framed = 1;
- }
-
- if (group)
- url._gid = group;
- if (page)
- url._page = page;
- if (src)
- url._source = src;
-
- // also send search request to get the correct listing
- if (this.env.search_request)
- url._search = this.env.search_request;
-
- this.set_busy(true, 'loading');
- this.location_href(url, target);
- };
-
- // send remote request to load contacts list
- this.list_contacts_remote = function(src, group, page)
- {
- // clear message list first
- this.list_contacts_clear();
-
- // send request to server
- var url = {}, lock = this.set_busy(true, 'loading');
-
- if (src)
- url._source = src;
- if (page)
- url._page = page;
- if (group)
- url._gid = group;
-
- this.env.source = src;
- this.env.group = group;
-
- // also send search request to get the right records
- if (this.env.search_request)
- url._search = this.env.search_request;
-
- this.http_request(this.env.task == 'mail' ? 'list-contacts' : 'list', url, lock);
- };
-
- this.list_contacts_clear = function()
- {
- this.contact_list.data = {};
- this.contact_list.clear(true);
- this.show_contentframe(false);
- this.enable_command('delete', 'move', 'copy', false);
- this.enable_command('compose', this.env.group ? true : false);
- };
-
- this.set_group_prop = function(prop)
- {
- if (this.gui_objects.addresslist_title) {
- var boxtitle = $(this.gui_objects.addresslist_title).html(''); // clear contents
-
- // add link to pop back to parent group
- if (this.env.address_group_stack.length > 1) {
- $('<a href="#list">...</a>')
- .addClass('poplink')
- .appendTo(boxtitle)
- .click(function(e){ return ref.command('popgroup','',this); });
- boxtitle.append('&nbsp;&raquo;&nbsp;');
- }
-
- boxtitle.append($('<span>'+prop.name+'</span>'));
- }
-
- this.triggerEvent('groupupdate', prop);
- };
-
- // load contact record
- this.load_contact = function(cid, action, framed)
- {
- var win, url = {}, target = window,
- rec = this.contact_list ? this.contact_list.data[cid] : null;
-
- if (win = this.get_frame_window(this.env.contentframe)) {
- url._framed = 1;
- target = win;
- this.show_contentframe(true);
-
- // load dummy content, unselect selected row(s)
- if (!cid)
- this.contact_list.clear_selection();
-
- this.enable_command('compose', rec && rec.email);
- this.enable_command('export-selected', rec && rec._type != 'group');
- }
- else if (framed)
- return false;
-
- if (action && (cid || action=='add') && !this.drag_active) {
- if (this.env.group)
- url._gid = this.env.group;
-
- url._action = action;
- url._source = this.env.source;
- url._cid = cid;
-
- this.location_href(url, target, true);
- }
-
- return true;
- };
-
- // add/delete member to/from the group
- this.group_member_change = function(what, cid, source, gid)
- {
- what = what == 'add' ? 'add' : 'del';
- var label = this.get_label(what == 'add' ? 'addingmember' : 'removingmember'),
- lock = this.display_message(label, 'loading'),
- post_data = {_cid: cid, _source: source, _gid: gid};
-
- this.http_post('group-'+what+'members', post_data, lock);
- };
-
- this.contacts_drag_menu = function(e, to)
- {
- var dest = to.type == 'group' ? to.source : to.id,
- source = this.env.source;
-
- if (!this.env.address_sources[dest] || this.env.address_sources[dest].readonly)
- return true;
-
- // search result may contain contacts from many sources, but if there is only one...
- if (source == '' && this.env.selection_sources.length == 1)
- source = this.env.selection_sources[0];
-
- if (to.type == 'group' && dest == source) {
- var cid = this.contact_list.get_selection().join(',');
- this.group_member_change('add', cid, dest, to.id);
- return true;
- }
- // move action is not possible, "redirect" to copy if menu wasn't requested
- else if (!this.commands.move && rcube_event.get_modifier(e) != SHIFT_KEY) {
- this.copy_contacts(to);
- return true;
- }
-
- return this.drag_menu(e, to);
- };
-
- // copy contact(s) to the specified target (group or directory)
- this.copy_contacts = function(to)
- {
- var n, dest = to.type == 'group' ? to.source : to.id,
- source = this.env.source,
- group = this.env.group ? this.env.group : '',
- cid = this.contact_list.get_selection().join(',');
-
- if (!cid || !this.env.address_sources[dest] || this.env.address_sources[dest].readonly)
- return;
-
- // search result may contain contacts from many sources, but if there is only one...
- if (source == '' && this.env.selection_sources.length == 1)
- source = this.env.selection_sources[0];
-
- // tagret is a group
- if (to.type == 'group') {
- if (dest == source)
- return;
-
- var lock = this.display_message(this.get_label('copyingcontact'), 'loading'),
- post_data = {_cid: cid, _source: this.env.source, _to: dest, _togid: to.id, _gid: group};
-
- this.http_post('copy', post_data, lock);
- }
- // target is an addressbook
- else if (to.id != source) {
- var lock = this.display_message(this.get_label('copyingcontact'), 'loading'),
- post_data = {_cid: cid, _source: this.env.source, _to: to.id, _gid: group};
-
- this.http_post('copy', post_data, lock);
- }
- };
-
- // move contact(s) to the specified target (group or directory)
- this.move_contacts = function(to)
- {
- var dest = to.type == 'group' ? to.source : to.id,
- source = this.env.source,
- group = this.env.group ? this.env.group : '';
-
- if (!this.env.address_sources[dest] || this.env.address_sources[dest].readonly)
- return;
-
- // search result may contain contacts from many sources, but if there is only one...
- if (source == '' && this.env.selection_sources.length == 1)
- source = this.env.selection_sources[0];
-
- if (to.type == 'group') {
- if (dest == source)
- return;
-
- this._with_selected_contacts('move', {_to: dest, _togid: to.id});
- }
- // target is an addressbook
- else if (to.id != source)
- this._with_selected_contacts('move', {_to: to.id});
- };
-
- // delete contact(s)
- this.delete_contacts = function()
- {
- var undelete = this.env.source && this.env.address_sources[this.env.source].undelete;
-
- if (!undelete && !confirm(this.get_label('deletecontactconfirm')))
- return;
-
- return this._with_selected_contacts('delete');
- };
-
- this._with_selected_contacts = function(action, post_data)
- {
- var selection = this.contact_list ? this.contact_list.get_selection() : [];
-
- // exit if no mailbox specified or if selection is empty
- if (!selection.length && !this.env.cid)
- return;
-
- var n, a_cids = [],
- label = action == 'delete' ? 'contactdeleting' : 'movingcontact',
- lock = this.display_message(this.get_label(label), 'loading');
- if (this.env.cid)
- a_cids.push(this.env.cid);
- else {
- for (n=0; n<selection.length; n++) {
- id = selection[n];
- a_cids.push(id);
- this.contact_list.remove_row(id, (n == selection.length-1));
- }
-
- // hide content frame if we delete the currently displayed contact
- if (selection.length == 1)
- this.show_contentframe(false);
- }
-
- if (!post_data)
- post_data = {};
-
- post_data._source = this.env.source;
- post_data._from = this.env.action;
- post_data._cid = a_cids.join(',');
-
- if (this.env.group)
- post_data._gid = this.env.group;
-
- // also send search request to get the right records from the next page
- if (this.env.search_request)
- post_data._search = this.env.search_request;
-
- // send request to server
- this.http_post(action, post_data, lock)
-
- return true;
- };
-
- // update a contact record in the list
- this.update_contact_row = function(cid, cols_arr, newcid, source, data)
- {
- var c, row, list = this.contact_list;
-
- cid = this.html_identifier(cid);
-
- // when in searching mode, concat cid with the source name
- if (!list.rows[cid]) {
- cid = cid+'-'+source;
- if (newcid)
- newcid = newcid+'-'+source;
- }
-
- list.update_row(cid, cols_arr, newcid, true);
- list.data[cid] = data;
- };
-
- // add row to contacts list
- this.add_contact_row = function(cid, cols, classes, data)
- {
- if (!this.gui_objects.contactslist)
- return false;
-
- var c, col, list = this.contact_list,
- row = { cols:[] };
-
- row.id = 'rcmrow'+this.html_identifier(cid);
- row.className = 'contact ' + (classes || '');
-
- if (list.in_selection(cid))
- row.className += ' selected';
-
- // add each submitted col
- for (c in cols) {
- col = {};
- col.className = String(c).toLowerCase();
- col.innerHTML = cols[c];
- row.cols.push(col);
- }
-
- // store data in list member
- list.data[cid] = data;
- list.insert_row(row);
-
- this.enable_command('export', list.rowcount > 0);
- };
-
- this.init_contact_form = function()
- {
- var ref = this, col;
-
- if (this.env.coltypes) {
- this.set_photo_actions($('#ff_photo').val());
- for (col in this.env.coltypes)
- this.init_edit_field(col, null);
- }
-
- $('.contactfieldgroup .row a.deletebutton').click(function() {
- ref.delete_edit_field(this);
- return false;
- });
-
- $('select.addfieldmenu').change(function(e) {
- ref.insert_edit_field($(this).val(), $(this).attr('rel'), this);
- this.selectedIndex = 0;
- });
-
- // enable date pickers on date fields
- if ($.datepicker && this.env.date_format) {
- $.datepicker.setDefaults({
- dateFormat: this.env.date_format,
- changeMonth: true,
- changeYear: true,
- yearRange: '-100:+10',
- showOtherMonths: true,
- selectOtherMonths: true,
- onSelect: function(dateText) { $(this).focus().val(dateText) }
- });
- $('input.datepicker').datepicker();
- }
-
- $("input[type='text']:visible").first().focus();
-
- // Submit search form on Enter
- if (this.env.action == 'search')
- $(this.gui_objects.editform).append($('<input type="submit">').hide())
- .submit(function() { $('input.mainaction').click(); return false; });
- };
-
- this.group_create = function()
- {
- this.add_input_row('contactgroup');
- };
-
- this.group_rename = function()
- {
- if (!this.env.group || !this.gui_objects.folderlist)
- return;
-
- if (!this.name_input) {
- this.enable_command('list', 'listgroup', false);
- this.name_input = $('<input>').attr('type', 'text').val(this.env.contactgroups['G'+this.env.source+this.env.group].name);
- this.name_input.bind('keydown', function(e){ return rcmail.add_input_keydown(e); });
- this.env.group_renaming = true;
-
- var link, li = this.get_folder_li('G'+this.env.source+this.env.group,'',true);
- if (li && (link = li.firstChild)) {
- $(link).hide().before(this.name_input);
- }
- }
-
- this.name_input.select().focus();
- };
-
- this.group_delete = function()
- {
- if (this.env.group && confirm(this.get_label('deletegroupconfirm'))) {
- var lock = this.set_busy(true, 'groupdeleting');
- this.http_post('group-delete', {_source: this.env.source, _gid: this.env.group}, lock);
- }
- };
-
- // callback from server upon group-delete command
- this.remove_group_item = function(prop)
- {
- var key = 'G'+prop.source+prop.id;
- if (this.treelist.remove(key)) {
- delete this.env.contactfolders[key];
- delete this.env.contactgroups[key];
- }
-
- this.list_contacts(prop.source, 0);
- };
-
- // @TODO: maybe it would be better to use popup instead of inserting input to the list?
- this.add_input_row = function(type)
- {
- if (!this.gui_objects.folderlist)
- return;
-
- if (!this.name_input) {
- this.name_input = $('<input>').attr('type', 'text').data('tt', type);
- this.name_input.bind('keydown', function(e){ return rcmail.add_input_keydown(e); });
- this.name_input_li = $('<li>').addClass(type).append(this.name_input);
-
- var ul, li;
-
- // find list (UL) element
- if (type == 'contactsearch')
- ul = this.gui_objects.folderlist;
- else
- ul = $('ul.groups', this.get_folder_li(this.env.source,'',true));
-
- // append to the list
- li = $('li:last', ul);
- if (li.length)
- this.name_input_li.insertAfter(li);
- else {
- this.name_input_li.appendTo(ul);
- ul.show(); // make sure the list is visible
- }
- }
-
- this.name_input.select().focus();
- };
-
- //remove selected contacts from current active group
- this.group_remove_selected = function()
- {
- ref.http_post('group-delmembers', {_cid: this.contact_list.selection,
- _source: this.env.source, _gid: this.env.group});
- };
-
- //callback after deleting contact(s) from current group
- this.remove_group_contacts = function(props)
- {
- if('undefined' != typeof this.env.group && (this.env.group === props.gid)){
- var n, selection = this.contact_list.get_selection();
- for (n=0; n<selection.length; n++) {
- id = selection[n];
- this.contact_list.remove_row(id, (n == selection.length-1));
- }
- }
- }
-
- // handler for keyboard events on the input field
- this.add_input_keydown = function(e)
- {
- var key = rcube_event.get_keycode(e),
- input = $(e.target), itype = input.data('tt');
-
- // enter
- if (key == 13) {
- var newname = input.val();
-
- if (newname) {
- var lock = this.set_busy(true, 'loading');
-
- if (itype == 'contactsearch')
- this.http_post('search-create', {_search: this.env.search_request, _name: newname}, lock);
- else if (this.env.group_renaming)
- this.http_post('group-rename', {_source: this.env.source, _gid: this.env.group, _name: newname}, lock);
- else
- this.http_post('group-create', {_source: this.env.source, _name: newname}, lock);
- }
- return false;
- }
- // escape
- else if (key == 27)
- this.reset_add_input();
-
- return true;
- };
-
- this.reset_add_input = function()
- {
- if (this.name_input) {
- var li = this.name_input.parent();
- if (this.env.group_renaming) {
- li.children().last().show();
- this.env.group_renaming = false;
- }
- else if ($('li', li.parent()).length == 1)
- li.parent().hide();
-
- this.name_input.remove();
-
- if (this.name_input_li)
- this.name_input_li.remove();
-
- this.name_input = this.name_input_li = null;
- }
-
- this.enable_command('list', 'listgroup', true);
- };
-
- // callback for creating a new contact group
- this.insert_contact_group = function(prop)
- {
- this.reset_add_input();
-
- prop.type = 'group';
- var key = 'G'+prop.source+prop.id,
- link = $('<a>').attr('href', '#')
- .attr('rel', prop.source+':'+prop.id)
- .click(function() { return rcmail.command('listgroup', prop, this); })
- .html(prop.name);
-
- this.env.contactfolders[key] = this.env.contactgroups[key] = prop;
- this.treelist.insert({ id:key, html:link, classes:['contactgroup'] }, prop.source, true);
-
- this.triggerEvent('group_insert', { id:prop.id, source:prop.source, name:prop.name, li:this.treelist.get_item(key) });
- };
-
- // callback for renaming a contact group
- this.update_contact_group = function(prop)
- {
- this.reset_add_input();
-
- var key = 'G'+prop.source+prop.id,
- newnode = {};
-
- // group ID has changed, replace link node and identifiers
- if (prop.newid) {
- var newkey = 'G'+prop.source+prop.newid,
- newprop = $.extend({}, prop);
-
- this.env.contactfolders[newkey] = this.env.contactfolders[key];
- this.env.contactfolders[newkey].id = prop.newid;
- this.env.group = prop.newid;
-
- delete this.env.contactfolders[key];
- delete this.env.contactgroups[key];
-
- newprop.id = prop.newid;
- newprop.type = 'group';
-
- newnode.id = newkey;
- newnode.html = $('<a>').attr('href', '#')
- .attr('rel', prop.source+':'+prop.newid)
- .click(function() { return rcmail.command('listgroup', newprop, this); })
- .html(prop.name);
- }
- // update displayed group name
- else {
- $(this.treelist.get_item(key)).children().first().html(prop.name);
- this.env.contactfolders[key].name = this.env.contactgroups[key].name = prop.name;
- }
-
- // update list node and re-sort it
- this.treelist.update(key, newnode, true);
-
- this.triggerEvent('group_update', { id:prop.id, source:prop.source, name:prop.name, li:this.treelist.get_item(key), newid:prop.newid });
- };
-
- this.update_group_commands = function()
- {
- var source = this.env.source != '' ? this.env.address_sources[this.env.source] : null;
- this.enable_command('group-create', (source && source.groups && !source.readonly));
- this.enable_command('group-rename', 'group-delete', (source && source.groups && this.env.group && !source.readonly));
- };
-
- this.init_edit_field = function(col, elem)
- {
- var label = this.env.coltypes[col].label;
-
- if (!elem)
- elem = $('.ff_' + col);
-
- if (label)
- elem.placeholder(label);
- };
-
- this.insert_edit_field = function(col, section, menu)
- {
- // just make pre-defined input field visible
- var elem = $('#ff_'+col);
- if (elem.length) {
- elem.show().focus();
- $(menu).children('option[value="'+col+'"]').prop('disabled', true);
- }
- else {
- var lastelem = $('.ff_'+col),
- appendcontainer = $('#contactsection'+section+' .contactcontroller'+col);
-
- if (!appendcontainer.length) {
- var sect = $('#contactsection'+section),
- lastgroup = $('.contactfieldgroup', sect).last();
- appendcontainer = $('<fieldset>').addClass('contactfieldgroup contactcontroller'+col);
- if (lastgroup.length)
- appendcontainer.insertAfter(lastgroup);
- else
- sect.prepend(appendcontainer);
- }
-
- if (appendcontainer.length && appendcontainer.get(0).nodeName == 'FIELDSET') {
- var input, colprop = this.env.coltypes[col],
- row = $('<div>').addClass('row'),
- cell = $('<div>').addClass('contactfieldcontent data'),
- label = $('<div>').addClass('contactfieldlabel label');
-
- if (colprop.subtypes_select)
- label.html(colprop.subtypes_select);
- else
- label.html(colprop.label);
-
- var name_suffix = colprop.limit != 1 ? '[]' : '';
- if (colprop.type == 'text' || colprop.type == 'date') {
- input = $('<input>')
- .addClass('ff_'+col)
- .attr({type: 'text', name: '_'+col+name_suffix, size: colprop.size})
- .appendTo(cell);
-
- this.init_edit_field(col, input);
-
- if (colprop.type == 'date' && $.datepicker)
- input.datepicker();
- }
- else if (colprop.type == 'textarea') {
- input = $('<textarea>')
- .addClass('ff_'+col)
- .attr({ name: '_'+col+name_suffix, cols:colprop.size, rows:colprop.rows })
- .appendTo(cell);
-
- this.init_edit_field(col, input);
- }
- else if (colprop.type == 'composite') {
- var childcol, cp, first, templ, cols = [], suffices = [];
- // read template for composite field order
- if ((templ = this.env[col+'_template'])) {
- for (var j=0; j < templ.length; j++) {
- cols.push(templ[j][1]);
- suffices.push(templ[j][2]);
- }
- }
- else { // list fields according to appearance in colprop
- for (childcol in colprop.childs)
- cols.push(childcol);
- }
-
- for (var i=0; i < cols.length; i++) {
- childcol = cols[i];
- cp = colprop.childs[childcol];
- input = $('<input>')
- .addClass('ff_'+childcol)
- .attr({ type: 'text', name: '_'+childcol+name_suffix, size: cp.size })
- .appendTo(cell);
- cell.append(suffices[i] || " ");
- this.init_edit_field(childcol, input);
- if (!first) first = input;
- }
- input = first; // set focus to the first of this composite fields
- }
- else if (colprop.type == 'select') {
- input = $('<select>')
- .addClass('ff_'+col)
- .attr('name', '_'+col+name_suffix)
- .appendTo(cell);
-
- var options = input.attr('options');
- options[options.length] = new Option('---', '');
- if (colprop.options)
- $.each(colprop.options, function(i, val){ options[options.length] = new Option(val, i); });
- }
-
- if (input) {
- var delbutton = $('<a href="#del"></a>')
- .addClass('contactfieldbutton deletebutton')
- .attr({title: this.get_label('delete'), rel: col})
- .html(this.env.delbutton)
- .click(function(){ ref.delete_edit_field(this); return false })
- .appendTo(cell);
-
- row.append(label).append(cell).appendTo(appendcontainer.show());
- input.first().focus();
-
- // disable option if limit reached
- if (!colprop.count) colprop.count = 0;
- if (++colprop.count == colprop.limit && colprop.limit)
- $(menu).children('option[value="'+col+'"]').prop('disabled', true);
- }
- }
- }
- };
-
- this.delete_edit_field = function(elem)
- {
- var col = $(elem).attr('rel'),
- colprop = this.env.coltypes[col],
- fieldset = $(elem).parents('fieldset.contactfieldgroup'),
- addmenu = fieldset.parent().find('select.addfieldmenu');
-
- // just clear input but don't hide the last field
- if (--colprop.count <= 0 && colprop.visible)
- $(elem).parent().children('input').val('').blur();
- else {
- $(elem).parents('div.row').remove();
- // hide entire fieldset if no more rows
- if (!fieldset.children('div.row').length)
- fieldset.hide();
- }
-
- // enable option in add-field selector or insert it if necessary
- if (addmenu.length) {
- var option = addmenu.children('option[value="'+col+'"]');
- if (option.length)
- option.prop('disabled', false);
- else
- option = $('<option>').attr('value', col).html(colprop.label).appendTo(addmenu);
- addmenu.show();
- }
- };
-
- this.upload_contact_photo = function(form)
- {
- if (form && form.elements._photo.value) {
- this.async_upload_form(form, 'upload-photo', function(e) {
- rcmail.set_busy(false, null, rcmail.file_upload_id);
- });
-
- // display upload indicator
- this.file_upload_id = this.set_busy(true, 'uploading');
- }
- };
-
- this.replace_contact_photo = function(id)
- {
- var img_src = id == '-del-' ? this.env.photo_placeholder :
- this.env.comm_path + '&_action=photo&_source=' + this.env.source + '&_cid=' + (this.env.cid || 0) + '&_photo=' + id;
-
- this.set_photo_actions(id);
- $(this.gui_objects.contactphoto).children('img').attr('src', img_src);
- };
-
- this.photo_upload_end = function()
- {
- this.set_busy(false, null, this.file_upload_id);
- delete this.file_upload_id;
- };
-
- this.set_photo_actions = function(id)
- {
- var n, buttons = this.buttons['upload-photo'];
- for (n=0; buttons && n < buttons.length; n++)
- $('a#'+buttons[n].id).html(this.get_label(id == '-del-' ? 'addphoto' : 'replacephoto'));
-
- $('#ff_photo').val(id);
- this.enable_command('upload-photo', this.env.coltypes.photo ? true : false);
- this.enable_command('delete-photo', this.env.coltypes.photo && id != '-del-');
- };
-
- // load advanced search page
- this.advanced_search = function()
- {
- var win, url = {_form: 1, _action: 'search'}, target = window;
-
- if (win = this.get_frame_window(this.env.contentframe)) {
- url._framed = 1;
- target = win;
- this.contact_list.clear_selection();
- }
-
- this.location_href(url, target, true);
-
- return true;
- };
-
- // unselect directory/group
- this.unselect_directory = function()
- {
- this.select_folder('');
- this.enable_command('search-delete', false);
- };
-
- // callback for creating a new saved search record
- this.insert_saved_search = function(name, id)
- {
- this.reset_add_input();
-
- var key = 'S'+id,
- link = $('<a>').attr('href', '#')
- .attr('rel', id)
- .click(function() { return rcmail.command('listsearch', id, this); })
- .html(name),
- prop = { name:name, id:id };
-
- this.treelist.insert({ id:key, html:link, classes:['contactsearch'] }, null, 'contactsearch');
- this.select_folder(key,'',true);
- this.enable_command('search-delete', true);
- this.env.search_id = id;
-
- this.triggerEvent('abook_search_insert', prop);
- };
-
- // creates an input for saved search name
- this.search_create = function()
- {
- this.add_input_row('contactsearch');
- };
-
- this.search_delete = function()
- {
- if (this.env.search_request) {
- var lock = this.set_busy(true, 'savedsearchdeleting');
- this.http_post('search-delete', {_sid: this.env.search_id}, lock);
- }
- };
-
- // callback from server upon search-delete command
- this.remove_search_item = function(id)
- {
- var li, key = 'S'+id;
- if (this.treelist.remove(key)) {
- this.triggerEvent('search_delete', { id:id, li:li });
- }
-
- this.env.search_id = null;
- this.env.search_request = null;
- this.list_contacts_clear();
- this.reset_qsearch();
- this.enable_command('search-delete', 'search-create', false);
- };
-
- this.listsearch = function(id)
- {
- var folder, lock = this.set_busy(true, 'searching');
-
- if (this.contact_list) {
- this.list_contacts_clear();
- }
-
- this.reset_qsearch();
- this.select_folder('S'+id, '', true);
-
- // reset vars
- this.env.current_page = 1;
- this.http_request('search', {_sid: id}, lock);
- };
-
-
- /*********************************************************/
- /********* user settings methods *********/
- /*********************************************************/
-
- // preferences section select and load options frame
- this.section_select = function(list)
- {
- var win, id = list.get_single_selection(), target = window,
- url = {_action: 'edit-prefs', _section: id};
-
- if (id) {
- if (win = this.get_frame_window(this.env.contentframe)) {
- url._framed = 1;
- target = win;
- }
- this.location_href(url, target, true);
- }
-
- return true;
- };
-
- this.identity_select = function(list)
- {
- var id;
- if (id = list.get_single_selection()) {
- this.enable_command('delete', list.rowcount > 1 && this.env.identities_level < 2);
- this.load_identity(id, 'edit-identity');
- }
- };
-
- // load identity record
- this.load_identity = function(id, action)
- {
- if (action == 'edit-identity' && (!id || id == this.env.iid))
- return false;
-
- var win, target = window,
- url = {_action: action, _iid: id};
-
- if (win = this.get_frame_window(this.env.contentframe)) {
- url._framed = 1;
- target = win;
- }
-
- if (action && (id || action == 'add-identity')) {
- this.set_busy(true);
- this.location_href(url, target);
- }
-
- return true;
- };
-
- this.delete_identity = function(id)
- {
- // exit if no identity is specified or if selection is empty
- var selection = this.identity_list.get_selection();
- if (!(selection.length || this.env.iid))
- return;
-
- if (!id)
- id = this.env.iid ? this.env.iid : selection[0];
-
- // submit request with appended token
- if (confirm(this.get_label('deleteidentityconfirm')))
- this.goto_url('delete-identity', { _iid: id, _token: this.env.request_token }, true);
-
- return true;
- };
-
- this.update_identity_row = function(id, name, add)
- {
- var list = this.identity_list,
- rid = this.html_identifier(id);
-
- if (add) {
- list.insert_row({ id:'rcmrow'+rid, cols:[ { className:'mail', innerHTML:name } ] });
- list.select(rid);
- }
- else {
- list.update_row(rid, [ name ]);
- }
- };
-
-
- /*********************************************************/
- /********* folder manager methods *********/
- /*********************************************************/
-
- this.init_subscription_list = function()
- {
- var p = this;
- this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist,
- {multiselect:false, draggable:true, keyboard:false, toggleselect:true});
- this.subscription_list.addEventListener('select', function(o){ p.subscription_select(o); });
- this.subscription_list.addEventListener('dragstart', function(o){ p.drag_active = true; });
- this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); });
- this.subscription_list.row_init = function (row) {
- row.obj.onmouseover = function() { p.focus_subscription(row.id); };
- row.obj.onmouseout = function() { p.unfocus_subscription(row.id); };
- };
- this.subscription_list.init();
- $('#mailboxroot')
- .mouseover(function(){ p.focus_subscription(this.id); })
- .mouseout(function(){ p.unfocus_subscription(this.id); })
- };
-
- this.focus_subscription = function(id)
- {
- var row, folder,
- delim = RegExp.escape(this.env.delimiter),
- reg = RegExp('['+delim+']?[^'+delim+']+$');
-
- if (this.drag_active && this.env.mailbox && (row = document.getElementById(id)))
- if (this.env.subscriptionrows[id] &&
- (folder = this.env.subscriptionrows[id][0]) !== null
- ) {
- if (this.check_droptarget(folder) &&
- !this.env.subscriptionrows[this.get_folder_row_id(this.env.mailbox)][2] &&
- (folder != this.env.mailbox.replace(reg, '')) &&
- (!folder.match(new RegExp('^'+RegExp.escape(this.env.mailbox+this.env.delimiter))))
- ) {
- this.env.dstfolder = folder;
- $(row).addClass('droptarget');
- }
- }
- };
-
- this.unfocus_subscription = function(id)
- {
- var row = $('#'+id);
-
- this.env.dstfolder = null;
- if (this.env.subscriptionrows[id] && row[0])
- row.removeClass('droptarget');
- else
- $(this.subscription_list.frame).removeClass('droptarget');
- };
-
- this.subscription_select = function(list)
- {
- var id, folder;
-
- if (list && (id = list.get_single_selection()) &&
- (folder = this.env.subscriptionrows['rcmrow'+id])
- ) {
- this.env.mailbox = folder[0];
- this.show_folder(folder[0]);
- this.enable_command('delete-folder', !folder[2]);
- }
- else {
- this.env.mailbox = null;
- this.show_contentframe(false);
- this.enable_command('delete-folder', 'purge', false);
- }
- };
-
- this.subscription_move_folder = function(list)
- {
- var delim = RegExp.escape(this.env.delimiter),
- reg = RegExp('['+delim+']?[^'+delim+']+$');
-
- if (this.env.mailbox && this.env.dstfolder !== null && (this.env.dstfolder != this.env.mailbox) &&
- (this.env.dstfolder != this.env.mailbox.replace(reg, ''))
- ) {
- reg = new RegExp('[^'+delim+']*['+delim+']', 'g');
- var basename = this.env.mailbox.replace(reg, ''),
- newname = this.env.dstfolder === '' ? basename : this.env.dstfolder+this.env.delimiter+basename;
-
- if (newname != this.env.mailbox) {
- this.http_post('rename-folder', {_folder_oldname: this.env.mailbox, _folder_newname: newname}, this.set_busy(true, 'foldermoving'));
- this.subscription_list.draglayer.hide();
- }
- }
- this.drag_active = false;
- this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
- };
-
- // tell server to create and subscribe a new mailbox
- this.create_folder = function()
- {
- this.show_folder('', this.env.mailbox);
- };
-
- // delete a specific mailbox with all its messages
- this.delete_folder = function(name)
- {
- var id = this.get_folder_row_id(name ? name : this.env.mailbox),
- folder = this.env.subscriptionrows[id][0];
-
- if (folder && confirm(this.get_label('deletefolderconfirm'))) {
- var lock = this.set_busy(true, 'folderdeleting');
- this.http_post('delete-folder', {_mbox: folder}, lock);
- }
- };
-
- // Add folder row to the table and initialize it
- this.add_folder_row = function (name, display_name, is_protected, subscribed, skip_init, class_name)
- {
- if (!this.gui_objects.subscriptionlist)
- return false;
-
- var row, n, i, tmp, tmp_name, folders, rowid, list = [], slist = [],
- tbody = this.gui_objects.subscriptionlist.tBodies[0],
- refrow = $('tr', tbody).get(1),
- id = 'rcmrow'+((new Date).getTime());
-
- if (!refrow) {
- // Refresh page if we don't have a table row to clone
- this.goto_url('folders');
- return false;
- }
-
- // clone a table row if there are existing rows
- row = $(refrow).clone(true);
-
- // set ID, reset css class
- row.attr('id', id);
- row.attr('class', class_name);
-
- // set folder name
- row.find('td:first').html(display_name);
-
- // update subscription checkbox
- $('input[name="_subscribed[]"]', row).val(name)
- .prop({checked: subscribed ? true : false, disabled: is_protected ? true : false});
-
- // add to folder/row-ID map
- this.env.subscriptionrows[id] = [name, display_name, 0];
-
- // sort folders, to find a place where to insert the row
- folders = [];
- $.each(this.env.subscriptionrows, function(k,v){ folders.push(v) });
- folders.sort(function(a,b){ return a[0] < b[0] ? -1 : (a[0] > b[0] ? 1 : 0) });
-
- for (n in folders) {
- // protected folder
- if (folders[n][2]) {
- tmp_name = folders[n][0] + this.env.delimiter;
- // prefix namespace cannot have subfolders (#1488349)
- if (tmp_name == this.env.prefix_ns)
- continue;
- slist.push(folders[n][0]);
- tmp = tmp_name;
- }
- // protected folder's child
- else if (tmp && folders[n][0].indexOf(tmp) == 0)
- slist.push(folders[n][0]);
- // other
- else {
- list.push(folders[n][0]);
- tmp = null;
- }
- }
-
- // check if subfolder of a protected folder
- for (n=0; n<slist.length; n++) {
- if (name.indexOf(slist[n]+this.env.delimiter) == 0)
- rowid = this.get_folder_row_id(slist[n]);
- }
-
- // find folder position after sorting
- for (n=0; !rowid && n<list.length; n++) {
- if (n && list[n] == name)
- rowid = this.get_folder_row_id(list[n-1]);
- }
-
- // add row to the table
- if (rowid)
- $('#'+rowid).after(row);
- else
- row.appendTo(tbody);
-
- // update list widget
- this.subscription_list.clear_selection();
- if (!skip_init)
- this.init_subscription_list();
-
- row = row.get(0);
- if (row.scrollIntoView)
- row.scrollIntoView();
-
- return row;
- };
-
- // replace an existing table row with a new folder line (with subfolders)
- this.replace_folder_row = function(oldfolder, newfolder, display_name, is_protected, class_name)
- {
- if (!this.gui_objects.subscriptionlist)
- return false;
-
- var i, n, len, name, dispname, oldrow, tmprow, row, level,
- tbody = this.gui_objects.subscriptionlist.tBodies[0],
- folders = this.env.subscriptionrows,
- id = this.get_folder_row_id(oldfolder),
- regex = new RegExp('^'+RegExp.escape(oldfolder)),
- subscribed = $('input[name="_subscribed[]"]', $('#'+id)).prop('checked'),
- // find subfolders of renamed folder
- list = this.get_subfolders(oldfolder);
-
- // replace an existing table row
- this._remove_folder_row(id);
- row = $(this.add_folder_row(newfolder, display_name, is_protected, subscribed, true, class_name));
-
- // detect tree depth change
- if (len = list.length) {
- level = (oldfolder.split(this.env.delimiter)).length - (newfolder.split(this.env.delimiter)).length;
- }
-
- // move subfolders to the new branch
- for (n=0; n<len; n++) {
- id = list[n];
- name = this.env.subscriptionrows[id][0];
- dispname = this.env.subscriptionrows[id][1];
- oldrow = $('#'+id);
- tmprow = oldrow.clone(true);
- oldrow.remove();
- row.after(tmprow);
- row = tmprow;
- // update folder index
- name = name.replace(regex, newfolder);
- $('input[name="_subscribed[]"]', row).val(name);
- this.env.subscriptionrows[id][0] = name;
- // update the name if level is changed
- if (level != 0) {
- if (level > 0) {
- for (i=level; i>0; i--)
- dispname = dispname.replace(/^&nbsp;&nbsp;&nbsp;&nbsp;/, '');
- }
- else {
- for (i=level; i<0; i++)
- dispname = '&nbsp;&nbsp;&nbsp;&nbsp;' + dispname;
- }
- row.find('td:first').html(dispname);
- this.env.subscriptionrows[id][1] = dispname;
- }
- }
-
- // update list widget
- this.init_subscription_list();
- };
-
- // remove the table row of a specific mailbox from the table
- this.remove_folder_row = function(folder, subs)
- {
- var n, len, list = [], id = this.get_folder_row_id(folder);
-
- // get subfolders if any
- if (subs)
- list = this.get_subfolders(folder);
-
- // remove old row
- this._remove_folder_row(id);
-
- // remove subfolders
- for (n=0, len=list.length; n<len; n++)
- this._remove_folder_row(list[n]);
- };
-
- this._remove_folder_row = function(id)
- {
- this.subscription_list.remove_row(id.replace(/^rcmrow/, ''));
- $('#'+id).remove();
- delete this.env.subscriptionrows[id];
- }
-
- this.get_subfolders = function(folder)
- {
- var name, list = [],
- regex = new RegExp('^'+RegExp.escape(folder)+RegExp.escape(this.env.delimiter)),
- row = $('#'+this.get_folder_row_id(folder)).get(0);
-
- while (row = row.nextSibling) {
- if (row.id) {
- name = this.env.subscriptionrows[row.id][0];
- if (regex.test(name)) {
- list.push(row.id);
- }
- else
- break;
- }
- }
-
- return list;
- }
-
- this.subscribe = function(folder)
- {
- if (folder) {
- var lock = this.display_message(this.get_label('foldersubscribing'), 'loading');
- this.http_post('subscribe', {_mbox: folder}, lock);
- }
- };
-
- this.unsubscribe = function(folder)
- {
- if (folder) {
- var lock = this.display_message(this.get_label('folderunsubscribing'), 'loading');
- this.http_post('unsubscribe', {_mbox: folder}, lock);
- }
- };
-
- // helper method to find a specific mailbox row ID
- this.get_folder_row_id = function(folder)
- {
- var id, folders = this.env.subscriptionrows;
- for (id in folders)
- if (folders[id] && folders[id][0] == folder)
- break;
-
- return id;
- };
-
- // when user select a folder in manager
- this.show_folder = function(folder, path, force)
- {
- var win, target = window,
- url = '&_action=edit-folder&_mbox='+urlencode(folder);
-
- if (path)
- url += '&_path='+urlencode(path);
-
- if (win = this.get_frame_window(this.env.contentframe)) {
- target = win;
- url += '&_framed=1';
- }
-
- if (String(target.location.href).indexOf(url) >= 0 && !force)
- this.show_contentframe(true);
- else
- this.location_href(this.env.comm_path+url, target, true);
- };
-
- // disables subscription checkbox (for protected folder)
- this.disable_subscription = function(folder)
- {
- var id = this.get_folder_row_id(folder);
- if (id)
- $('input[name="_subscribed[]"]', $('#'+id)).prop('disabled', true);
- };
-
- this.folder_size = function(folder)
- {
- var lock = this.set_busy(true, 'loading');
- this.http_post('folder-size', {_mbox: folder}, lock);
- };
-
- this.folder_size_update = function(size)
- {
- $('#folder-size').replaceWith(size);
- };
-
-
- /*********************************************************/
- /********* GUI functionality *********/
- /*********************************************************/
-
- var init_button = function(cmd, prop)
- {
- var elm = document.getElementById(prop.id);
- if (!elm)
- return;
-
- var preload = false;
- if (prop.type == 'image') {
- elm = elm.parentNode;
- preload = true;
- }
-
- elm._command = cmd;
- elm._id = prop.id;
- if (prop.sel) {
- elm.onmousedown = function(e){ return rcmail.button_sel(this._command, this._id); };
- elm.onmouseup = function(e){ return rcmail.button_out(this._command, this._id); };
- if (preload)
- new Image().src = prop.sel;
- }
- if (prop.over) {
- elm.onmouseover = function(e){ return rcmail.button_over(this._command, this._id); };
- elm.onmouseout = function(e){ return rcmail.button_out(this._command, this._id); };
- if (preload)
- new Image().src = prop.over;
- }
- };
-
- // set event handlers on registered buttons
- this.init_buttons = function()
- {
- for (var cmd in this.buttons) {
- if (typeof cmd !== 'string')
- continue;
-
- for (var i=0; i<this.buttons[cmd].length; i++) {
- init_button(cmd, this.buttons[cmd][i]);
- }
- }
-
- // set active task button
- this.set_button(this.task, 'sel');
- };
-
- // set button to a specific state
- this.set_button = function(command, state)
- {
- var n, button, obj, a_buttons = this.buttons[command],
- len = a_buttons ? a_buttons.length : 0;
-
- for (n=0; n<len; n++) {
- button = a_buttons[n];
- obj = document.getElementById(button.id);
-
- if (!obj)
- continue;
-
- // get default/passive setting of the button
- if (button.type == 'image' && !button.status) {
- button.pas = obj._original_src ? obj._original_src : obj.src;
- // respect PNG fix on IE browsers
- if (obj.runtimeStyle && obj.runtimeStyle.filter && obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))
- button.pas = RegExp.$1;
- }
- else if (!button.status)
- button.pas = String(obj.className);
-
- // set image according to button state
- if (button.type == 'image' && button[state]) {
- button.status = state;
- obj.src = button[state];
- }
- // set class name according to button state
- else if (button[state] !== undefined) {
- button.status = state;
- obj.className = button[state];
- }
- // disable/enable input buttons
- if (button.type == 'input') {
- button.status = state;
- obj.disabled = !state;
- }
- }
- };
-
- // display a specific alttext
- this.set_alttext = function(command, label)
- {
- var n, button, obj, link, a_buttons = this.buttons[command],
- len = a_buttons ? a_buttons.length : 0;
-
- for (n=0; n<len; n++) {
- button = a_buttons[n];
- obj = document.getElementById(button.id);
-
- if (button.type == 'image' && obj) {
- obj.setAttribute('alt', this.get_label(label));
- if ((link = obj.parentNode) && link.tagName.toLowerCase() == 'a')
- link.setAttribute('title', this.get_label(label));
- }
- else if (obj)
- obj.setAttribute('title', this.get_label(label));
- }
- };
-
- // mouse over button
- this.button_over = function(command, id)
- {
- var n, button, obj, a_buttons = this.buttons[command],
- len = a_buttons ? a_buttons.length : 0;
-
- for (n=0; n<len; n++) {
- button = a_buttons[n];
- if (button.id == id && button.status == 'act') {
- obj = document.getElementById(button.id);
- if (obj && button.over) {
- if (button.type == 'image')
- obj.src = button.over;
- else
- obj.className = button.over;
- }
- }
- }
- };
-
- // mouse down on button
- this.button_sel = function(command, id)
- {
- var n, button, obj, a_buttons = this.buttons[command],
- len = a_buttons ? a_buttons.length : 0;
-
- for (n=0; n<len; n++) {
- button = a_buttons[n];
- if (button.id == id && button.status == 'act') {
- obj = document.getElementById(button.id);
- if (obj && button.sel) {
- if (button.type == 'image')
- obj.src = button.sel;
- else
- obj.className = button.sel;
- }
- this.buttons_sel[id] = command;
- }
- }
- };
-
- // mouse out of button
- this.button_out = function(command, id)
- {
- var n, button, obj, a_buttons = this.buttons[command],
- len = a_buttons ? a_buttons.length : 0;
-
- for (n=0; n<len; n++) {
- button = a_buttons[n];
- if (button.id == id && button.status == 'act') {
- obj = document.getElementById(button.id);
- if (obj && button.act) {
- if (button.type == 'image')
- obj.src = button.act;
- else
- obj.className = button.act;
- }
- }
- }
- };
-
- // write to the document/window title
- this.set_pagetitle = function(title)
- {
- if (title && document.title)
- document.title = title;
- };
-
- // display a system message, list of types in common.css (below #message definition)
- this.display_message = function(msg, type, timeout)
- {
- // pass command to parent window
- if (this.is_framed())
- return parent.rcmail.display_message(msg, type, timeout);
-
- if (!this.gui_objects.message) {
- // save message in order to display after page loaded
- if (type != 'loading')
- this.pending_message = [msg, type, timeout];
- return 1;
- }
-
- type = type ? type : 'notice';
-
- var ref = this,
- key = this.html_identifier(msg),
- date = new Date(),
- id = type + date.getTime();
-
- if (!timeout)
- timeout = this.message_time * (type == 'error' || type == 'warning' ? 2 : 1);
-
- if (type == 'loading') {
- key = 'loading';
- timeout = this.env.request_timeout * 1000;
- if (!msg)
- msg = this.get_label('loading');
- }
-
- // The same message is already displayed
- if (this.messages[key]) {
- // replace label
- if (this.messages[key].obj)
- this.messages[key].obj.html(msg);
- // store label in stack
- if (type == 'loading') {
- this.messages[key].labels.push({'id': id, 'msg': msg});
- }
- // add element and set timeout
- this.messages[key].elements.push(id);
- setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout);
- return id;
- }
-
- // create DOM object and display it
- var obj = $('<div>').addClass(type).html(msg).data('key', key),
- cont = $(this.gui_objects.message).append(obj).show();
-
- this.messages[key] = {'obj': obj, 'elements': [id]};
-
- if (type == 'loading') {
- this.messages[key].labels = [{'id': id, 'msg': msg}];
- }
- else {
- obj.click(function() { return ref.hide_message(obj); });
- }
-
- this.triggerEvent('message', { message:msg, type:type, timeout:timeout, object:obj });
-
- if (timeout > 0)
- setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout);
- return id;
- };
-
- // make a message to disapear
- this.hide_message = function(obj, fade)
- {
- // pass command to parent window
- if (this.is_framed())
- return parent.rcmail.hide_message(obj, fade);
-
- if (!this.gui_objects.message)
- return;
-
- var k, n, i, o, m = this.messages;
-
- // Hide message by object, don't use for 'loading'!
- if (typeof obj === 'object') {
- o = $(obj);
- k = o.data('key');
- this.hide_message_object(o, fade);
- if (m[k])
- delete m[k];
- }
- // Hide message by id
- else {
- for (k in m) {
- for (n in m[k].elements) {
- if (m[k] && m[k].elements[n] == obj) {
- m[k].elements.splice(n, 1);
- // hide DOM element if last instance is removed
- if (!m[k].elements.length) {
- this.hide_message_object(m[k].obj, fade);
- delete m[k];
- }
- // set pending action label for 'loading' message
- else if (k == 'loading') {
- for (i in m[k].labels) {
- if (m[k].labels[i].id == obj) {
- delete m[k].labels[i];
- }
- else {
- o = m[k].labels[i].msg;
- m[k].obj.html(o);
- }
- }
- }
- }
- }
- }
- }
- };
-
- // hide message object and remove from the DOM
- this.hide_message_object = function(o, fade)
- {
- if (fade)
- o.fadeOut(600, function() {$(this).remove(); });
- else
- o.hide().remove();
- };
-
- // remove all messages immediately
- this.clear_messages = function()
- {
- // pass command to parent window
- if (this.is_framed())
- return parent.rcmail.clear_messages();
-
- var k, n, m = this.messages;
-
- for (k in m)
- for (n in m[k].elements)
- if (m[k].obj)
- this.hide_message_object(m[k].obj);
-
- this.messages = {};
- };
-
- // open a jquery UI dialog with the given content
- this.show_popup_dialog = function(html, title, buttons)
- {
- // forward call to parent window
- if (this.is_framed()) {
- parent.rcmail.show_popup_dialog(html, title, buttons);
- return;
- }
-
- var popup = $('<div class="popup">')
- .html(html)
- .dialog({
- title: title,
- buttons: buttons,
- modal: true,
- resizable: true,
- width: 500,
- close: function(event, ui) { $(this).remove() }
- });
-
- // resize and center popup
- var win = $(window), w = win.width(), h = win.height(),
- width = popup.width(), height = popup.height();
-
- popup.dialog('option', {
- height: Math.min(h - 40, height + 75 + (buttons ? 50 : 0)),
- width: Math.min(w - 20, width + 20)
- });
- };
-
- // enable/disable buttons for page shifting
- this.set_page_buttons = function()
- {
- this.enable_command('nextpage', 'lastpage', (this.env.pagecount > this.env.current_page));
- this.enable_command('previouspage', 'firstpage', (this.env.current_page > 1));
- };
-
- // mark a mailbox as selected and set environment variable
- this.select_folder = function(name, prefix, encode)
- {
- if (this.treelist) {
- this.treelist.select(name);
- }
- else if (this.gui_objects.folderlist) {
- var current_li, target_li;
-
- if ((current_li = $('li.selected', this.gui_objects.folderlist))) {
- current_li.removeClass('selected').addClass('unfocused');
- }
- if ((target_li = this.get_folder_li(name, prefix, encode))) {
- $(target_li).removeClass('unfocused').addClass('selected');
- }
-
- // trigger event hook
- this.triggerEvent('selectfolder', { folder:name, prefix:prefix });
- }
- };
-
- // adds a class to selected folder
- this.mark_folder = function(name, class_name, prefix, encode)
- {
- $(this.get_folder_li(name, prefix, encode)).addClass(class_name);
- };
-
- // adds a class to selected folder
- this.unmark_folder = function(name, class_name, prefix, encode)
- {
- $(this.get_folder_li(name, prefix, encode)).removeClass(class_name);
- };
-
- // helper method to find a folder list item
- this.get_folder_li = function(name, prefix, encode)
- {
- if (!prefix)
- prefix = 'rcmli';
-
- if (this.gui_objects.folderlist) {
- name = this.html_identifier(name, encode);
- return document.getElementById(prefix+name);
- }
-
- return null;
- };
-
- // for reordering column array (Konqueror workaround)
- // and for setting some message list global variables
- this.set_message_coltypes = function(coltypes, repl, smart_col)
- {
- var list = this.message_list,
- thead = list ? list.thead : null,
- cell, col, n, len, th, tr;
-
- this.env.coltypes = coltypes;
-
- // replace old column headers
- if (thead) {
- if (repl) {
- th = document.createElement('thead');
- tr = document.createElement('tr');
-
- for (c=0, len=repl.length; c < len; c++) {
- cell = document.createElement('td');
- cell.innerHTML = repl[c].html || '';
- if (repl[c].id) cell.id = repl[c].id;
- if (repl[c].className) cell.className = repl[c].className;
- tr.appendChild(cell);
- }
- th.appendChild(tr);
- thead.parentNode.replaceChild(th, thead);
- list.thead = thead = th;
- }
-
- for (n=0, len=this.env.coltypes.length; n<len; n++) {
- col = this.env.coltypes[n];
- if ((cell = thead.rows[0].cells[n]) && (col == 'from' || col == 'to' || col == 'fromto')) {
- cell.id = 'rcm'+col;
- $('span,a', cell).text(this.get_label(col == 'fromto' ? smart_col : col));
- // if we have links for sorting, it's a bit more complicated...
- $('a', cell).click(function(){
- return rcmail.command('sort', this.id.replace(/^rcm/, ''), this);
- });
- }
- }
- }
-
- this.env.subject_col = null;
- this.env.flagged_col = null;
- this.env.status_col = null;
-
- if ((n = $.inArray('subject', this.env.coltypes)) >= 0) {
- this.env.subject_col = n;
- if (list)
- list.subject_col = n;
- }
- if ((n = $.inArray('flag', this.env.coltypes)) >= 0)
- this.env.flagged_col = n;
- if ((n = $.inArray('status', this.env.coltypes)) >= 0)
- this.env.status_col = n;
-
- if (list)
- list.init_header();
- };
-
- // replace content of row count display
- this.set_rowcount = function(text, mbox)
- {
- // #1487752
- if (mbox && mbox != this.env.mailbox)
- return false;
-
- $(this.gui_objects.countdisplay).html(text);
-
- // update page navigation buttons
- this.set_page_buttons();
- };
-
- // replace content of mailboxname display
- this.set_mailboxname = function(content)
- {
- if (this.gui_objects.mailboxname && content)
- this.gui_objects.mailboxname.innerHTML = content;
- };
-
- // replace content of quota display
- this.set_quota = function(content)
- {
- if (this.gui_objects.quotadisplay && content && content.type == 'text')
- $(this.gui_objects.quotadisplay).html(content.percent+'%').attr('title', content.title);
-
- this.triggerEvent('setquota', content);
- this.env.quota_content = content;
- };
-
- // update the mailboxlist
- this.set_unread_count = function(mbox, count, set_title, mark)
- {
- if (!this.gui_objects.mailboxlist)
- return false;
-
- this.env.unread_counts[mbox] = count;
- this.set_unread_count_display(mbox, set_title);
-
- if (mark)
- this.mark_folder(mbox, mark, '', true);
- else if (!count)
- this.unmark_folder(mbox, 'recent', '', true);
- };
-
- // update the mailbox count display
- this.set_unread_count_display = function(mbox, set_title)
- {
- var reg, link, text_obj, item, mycount, childcount, div;
-
- if (item = this.get_folder_li(mbox, '', true)) {
- mycount = this.env.unread_counts[mbox] ? this.env.unread_counts[mbox] : 0;
- link = $(item).children('a').eq(0);
- text_obj = link.children('span.unreadcount');
- if (!text_obj.length && mycount)
- text_obj = $('<span>').addClass('unreadcount').appendTo(link);
- reg = /\s+\([0-9]+\)$/i;
-
- childcount = 0;
- if ((div = item.getElementsByTagName('div')[0]) &&
- div.className.match(/collapsed/)) {
- // add children's counters
- for (var k in this.env.unread_counts)
- if (k.indexOf(mbox + this.env.delimiter) == 0)
- childcount += this.env.unread_counts[k];
- }
-
- if (mycount && text_obj.length)
- text_obj.html(this.env.unreadwrap.replace(/%[sd]/, mycount));
- else if (text_obj.length)
- text_obj.remove();
-
- // set parent's display
- reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+$');
- if (mbox.match(reg))
- this.set_unread_count_display(mbox.replace(reg, ''), false);
-
- // set the right classes
- if ((mycount+childcount)>0)
- $(item).addClass('unread');
- else
- $(item).removeClass('unread');
- }
-
- // set unread count to window title
- reg = /^\([0-9]+\)\s+/i;
- if (set_title && document.title) {
- var new_title = '',
- doc_title = String(document.title);
-
- if (mycount && doc_title.match(reg))
- new_title = doc_title.replace(reg, '('+mycount+') ');
- else if (mycount)
- new_title = '('+mycount+') '+doc_title;
- else
- new_title = doc_title.replace(reg, '');
-
- this.set_pagetitle(new_title);
- }
- };
-
- // display fetched raw headers
- this.set_headers = function(content)
- {
- if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content)
- $(this.gui_objects.all_headers_box).html(content).show();
- };
-
- // display all-headers row and fetch raw message headers
- this.show_headers = function(props, elem)
- {
- if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid)
- return;
-
- $(elem).removeClass('show-headers').addClass('hide-headers');
- $(this.gui_objects.all_headers_row).show();
- elem.onclick = function() { rcmail.command('hide-headers', '', elem); };
-
- // fetch headers only once
- if (!this.gui_objects.all_headers_box.innerHTML) {
- var lock = this.display_message(this.get_label('loading'), 'loading');
- this.http_post('headers', {_uid: this.env.uid}, lock);
- }
- };
-
- // hide all-headers row
- this.hide_headers = function(props, elem)
- {
- if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box)
- return;
-
- $(elem).removeClass('hide-headers').addClass('show-headers');
- $(this.gui_objects.all_headers_row).hide();
- elem.onclick = function() { rcmail.command('show-headers', '', elem); };
- };
-
-
- /********************************************************/
- /********* html to text conversion functions *********/
- /********************************************************/
-
- this.html2plain = function(htmlText, id)
- {
- var rcmail = this,
- url = '?_task=utils&_action=html2text',
- lock = this.set_busy(true, 'converting');
-
- this.log('HTTP POST: ' + url);
-
- $.ajax({ type: 'POST', url: url, data: htmlText, contentType: 'application/octet-stream',
- error: function(o, status, err) { rcmail.http_error(o, status, err, lock); },
- success: function(data) { rcmail.set_busy(false, null, lock); $('#'+id).val(data); rcmail.log(data); }
- });
- };
-
- this.plain2html = function(plain, id)
- {
- var lock = this.set_busy(true, 'converting');
-
- plain = plain.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
- $('#'+id).val(plain ? '<pre>'+plain+'</pre>' : '');
-
- this.set_busy(false, null, lock);
- };
-
-
- /********************************************************/
- /********* remote request methods *********/
- /********************************************************/
-
- // compose a valid url with the given parameters
- this.url = function(action, query)
- {
- var querystring = typeof query === 'string' ? '&' + query : '';
-
- if (typeof action !== 'string')
- query = action;
- else if (!query || typeof query !== 'object')
- query = {};
-
- if (action)
- query._action = action;
- else
- query._action = this.env.action;
-
- var base = this.env.comm_path, k, param = {};
-
- // overwrite task name
- if (query._action.match(/([a-z0-9_-]+)\/([a-z0-9-_.]+)/)) {
- query._action = RegExp.$2;
- base = base.replace(/\_task=[a-z0-9_-]+/, '_task='+RegExp.$1);
- }
-
- // remove undefined values
- for (k in query) {
- if (query[k] !== undefined && query[k] !== null)
- param[k] = query[k];
- }
-
- return base + '&' + $.param(param) + querystring;
- };
-
- this.redirect = function(url, lock)
- {
- if (lock || lock === null)
- this.set_busy(true);
-
- if (this.is_framed()) {
- parent.rcmail.redirect(url, lock);
- }
- else {
- if (this.env.extwin) {
- if (typeof url == 'string')
- url += (url.indexOf('?') < 0 ? '?' : '&') + '_extwin=1';
- else
- url._extwin = 1;
- }
- this.location_href(url, window);
- }
- };
-
- this.goto_url = function(action, query, lock)
- {
- this.redirect(this.url(action, query));
- };
-
- this.location_href = function(url, target, frame)
- {
- if (frame)
- this.lock_frame();
-
- if (typeof url == 'object')
- url = this.env.comm_path + '&' + $.param(url);
-
- // simulate real link click to force IE to send referer header
- if (bw.ie && target == window)
- $('<a>').attr('href', url).appendTo(document.body).get(0).click();
- else
- target.location.href = url;
-
- // reset keep-alive interval
- this.start_keepalive();
- };
-
- // send a http request to the server
- this.http_request = function(action, query, lock)
- {
- var url = this.url(action, query);
-
- // trigger plugin hook
- var result = this.triggerEvent('request'+action, query);
-
- if (result !== undefined) {
- // abort if one the handlers returned false
- if (result === false)
- return false;
- else
- query = result;
- }
-
- url += '&_remote=1';
-
- // send request
- this.log('HTTP GET: ' + url);
-
- // reset keep-alive interval
- this.start_keepalive();
-
- return $.ajax({
- type: 'GET', url: url, data: { _unlock:(lock?lock:0) }, dataType: 'json',
- success: function(data){ ref.http_response(data); },
- error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
- });
- };
-
- // send a http POST request to the server
- this.http_post = function(action, postdata, lock)
- {
- var url = this.url(action);
-
- if (postdata && typeof postdata === 'object') {
- postdata._remote = 1;
- postdata._unlock = (lock ? lock : 0);
- }
- else
- postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock='+lock : '');
-
- // trigger plugin hook
- var result = this.triggerEvent('request'+action, postdata);
- if (result !== undefined) {
- // abort if one of the handlers returned false
- if (result === false)
- return false;
- else
- postdata = result;
- }
-
- // send request
- this.log('HTTP POST: ' + url);
-
- // reset keep-alive interval
- this.start_keepalive();
-
- return $.ajax({
- type: 'POST', url: url, data: postdata, dataType: 'json',
- success: function(data){ ref.http_response(data); },
- error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
- });
- };
-
- // aborts ajax request
- this.abort_request = function(r)
- {
- if (r.request)
- r.request.abort();
- if (r.lock)
- this.set_busy(false, null, r.lock);
- };
-
- // handle HTTP response
- this.http_response = function(response)
- {
- if (!response)
- return;
-
- if (response.unlock)
- this.set_busy(false);
-
- this.triggerEvent('responsebefore', {response: response});
- this.triggerEvent('responsebefore'+response.action, {response: response});
-
- // set env vars
- if (response.env)
- this.set_env(response.env);
-
- // we have labels to add
- if (typeof response.texts === 'object') {
- for (var name in response.texts)
- if (typeof response.texts[name] === 'string')
- this.add_label(name, response.texts[name]);
- }
-
- // if we get javascript code from server -> execute it
- if (response.exec) {
- this.log(response.exec);
- eval(response.exec);
- }
-
- // execute callback functions of plugins
- if (response.callbacks && response.callbacks.length) {
- for (var i=0; i < response.callbacks.length; i++)
- this.triggerEvent(response.callbacks[i][0], response.callbacks[i][1]);
- }
-
- // process the response data according to the sent action
- switch (response.action) {
- case 'delete':
- if (this.task == 'addressbook') {
- var sid, uid = this.contact_list.get_selection(), writable = false;
-
- if (uid && this.contact_list.rows[uid]) {
- // search results, get source ID from record ID
- if (this.env.source == '') {
- sid = String(uid).replace(/^[^-]+-/, '');
- writable = sid && this.env.address_sources[sid] && !this.env.address_sources[sid].readonly;
- }
- else {
- writable = !this.env.address_sources[this.env.source].readonly;
- }
- }
- this.enable_command('compose', (uid && this.contact_list.rows[uid]));
- this.enable_command('delete', 'edit', writable);
- this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
- this.enable_command('export-selected', false);
- }
-
- case 'move':
- if (this.env.action == 'show') {
- // re-enable commands on move/delete error
- this.enable_command(this.env.message_commands, true);
- if (!this.env.list_post)
- this.enable_command('reply-list', false);
- }
- else if (this.task == 'addressbook') {
- this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
- }
-
- case 'purge':
- case 'expunge':
- if (this.task == 'mail') {
- if (!this.env.exists) {
- // clear preview pane content
- if (this.env.contentframe)
- this.show_contentframe(false);
- // disable commands useless when mailbox is empty
- this.enable_command(this.env.message_commands, 'purge', 'expunge',
- 'select-all', 'select-none', 'expand-all', 'expand-unread', 'collapse-all', false);
- }
- if (this.message_list)
- this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
- }
- break;
-
- case 'refresh':
- case 'check-recent':
- case 'getunread':
- case 'search':
- this.env.qsearch = null;
- case 'list':
- if (this.task == 'mail') {
- this.enable_command('show', 'select-all', 'select-none', this.env.messagecount > 0);
- this.enable_command('expunge', this.env.exists);
- this.enable_command('purge', this.purge_mailbox_test());
- this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading && this.env.messagecount);
-
- if ((response.action == 'list' || response.action == 'search') && this.message_list) {
- this.msglist_select(this.message_list);
- this.message_list.resize();
- this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
- }
- }
- else if (this.task == 'addressbook') {
- this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
-
- if (response.action == 'list' || response.action == 'search') {
- this.enable_command('search-create', this.env.source == '');
- this.enable_command('search-delete', this.env.search_id);
- this.update_group_commands();
- this.contact_list.resize();
- this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
- }
- }
- break;
- }
-
- if (response.unlock)
- this.hide_message(response.unlock);
-
- this.triggerEvent('responseafter', {response: response});
- this.triggerEvent('responseafter'+response.action, {response: response});
-
- // reset keep-alive interval
- this.start_keepalive();
- };
-
- // handle HTTP request errors
- this.http_error = function(request, status, err, lock, action)
- {
- var errmsg = request.statusText;
-
- this.set_busy(false, null, lock);
- request.abort();
-
- // don't display error message on page unload (#1488547)
- if (this.unload)
- return;
-
- if (request.status && errmsg)
- this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error');
- else if (status == 'timeout')
- this.display_message(this.get_label('requesttimedout'), 'error');
- else if (request.status == 0 && status != 'abort')
- this.display_message(this.get_label('servererror') + ' (No connection)', 'error');
-
- // redirect to url specified in location header if not empty
- var location_url = request.getResponseHeader("Location");
- if (location_url && this.env.action != 'compose') // don't redirect on compose screen, contents might get lost (#1488926)
- this.redirect(location_url);
-
- // 403 Forbidden response (CSRF prevention) - reload the page.
- // In case there's a new valid session it will be used, otherwise
- // login form will be presented (#1488960).
- if (request.status == 403) {
- (this.is_framed() ? parent : window).location.reload();
- return;
- }
-
- // re-send keep-alive requests after 30 seconds
- if (action == 'keep-alive')
- setTimeout(function(){ ref.keep_alive(); ref.start_keepalive(); }, 30000);
- };
-
- // callback when an iframe finished loading
- this.iframe_loaded = function(unlock)
- {
- this.set_busy(false, null, unlock);
-
- if (this.submit_timer)
- clearTimeout(this.submit_timer);
- };
-
- // post the given form to a hidden iframe
- this.async_upload_form = function(form, action, onload)
- {
- var ts = new Date().getTime(),
- frame_name = 'rcmupload'+ts;
-
- // upload progress support
- if (this.env.upload_progress_name) {
- var fname = this.env.upload_progress_name,
- field = $('input[name='+fname+']', form);
-
- if (!field.length) {
- field = $('<input>').attr({type: 'hidden', name: fname});
- field.prependTo(form);
- }
-
- field.val(ts);
- }
-
- // have to do it this way for IE
- // otherwise the form will be posted to a new window
- if (document.all) {
- var html = '<iframe name="'+frame_name+'" src="program/resources/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>';
- document.body.insertAdjacentHTML('BeforeEnd', html);
- }
- else { // for standards-compilant browsers
- var frame = document.createElement('iframe');
- frame.name = frame_name;
- frame.style.border = 'none';
- frame.style.width = 0;
- frame.style.height = 0;
- frame.style.visibility = 'hidden';
- document.body.appendChild(frame);
- }
-
- // handle upload errors, parsing iframe content in onload
- $(frame_name).bind('load', {ts:ts}, onload);
-
- $(form).attr({
- target: frame_name,
- action: this.url(action, { _id:this.env.compose_id||'', _uploadid:ts }),
- method: 'POST'})
- .attr(form.encoding ? 'encoding' : 'enctype', 'multipart/form-data')
- .submit();
-
- return frame_name;
- };
-
- // html5 file-drop API
- this.document_drag_hover = function(e, over)
- {
- e.preventDefault();
- $(ref.gui_objects.filedrop)[(over?'addClass':'removeClass')]('active');
- };
-
- this.file_drag_hover = function(e, over)
- {
- e.preventDefault();
- e.stopPropagation();
- $(ref.gui_objects.filedrop)[(over?'addClass':'removeClass')]('hover');
- };
-
- // handler when files are dropped to a designated area.
- // compose a multipart form data and submit it to the server
- this.file_dropped = function(e)
- {
- // abort event and reset UI
- this.file_drag_hover(e, false);
-
- // prepare multipart form data composition
- var files = e.target.files || e.dataTransfer.files,
- formdata = window.FormData ? new FormData() : null,
- fieldname = (this.env.filedrop.fieldname || '_file') + (this.env.filedrop.single ? '' : '[]'),
- boundary = '------multipartformboundary' + (new Date).getTime(),
- dashdash = '--', crlf = '\r\n',
- multipart = dashdash + boundary + crlf;
-
- if (!files || !files.length)
- return;
-
- // inline function to submit the files to the server
- var submit_data = function() {
- var multiple = files.length > 1,
- ts = new Date().getTime(),
- content = '<span>' + (multiple ? ref.get_label('uploadingmany') : files[0].name) + '</span>';
-
- // add to attachments list
- if (!ref.add2attachment_list(ts, { name:'', html:content, classname:'uploading', complete:false }))
- ref.file_upload_id = ref.set_busy(true, 'uploading');
-
- // complete multipart content and post request
- multipart += dashdash + boundary + dashdash + crlf;
-
- $.ajax({
- type: 'POST',
- dataType: 'json',
- url: ref.url(ref.env.filedrop.action||'upload', { _id:ref.env.compose_id||ref.env.cid||'', _uploadid:ts, _remote:1 }),
- contentType: formdata ? false : 'multipart/form-data; boundary=' + boundary,
- processData: false,
- timeout: 0, // disable default timeout set in ajaxSetup()
- data: formdata || multipart,
- headers: {'X-Roundcube-Request': ref.env.request_token},
- xhr: function() { var xhr = jQuery.ajaxSettings.xhr(); if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; return xhr; },
- success: function(data){ ref.http_response(data); },
- error: function(o, status, err) { ref.http_error(o, status, err, null, 'attachment'); }
- });
- };
-
- // get contents of all dropped files
- var last = this.env.filedrop.single ? 0 : files.length - 1;
- for (var j=0, i=0, f; j <= last && (f = files[i]); i++) {
- if (!f.name) f.name = f.fileName;
- if (!f.size) f.size = f.fileSize;
- if (!f.type) f.type = 'application/octet-stream';
-
- // file name contains non-ASCII characters, do UTF8-binary string conversion.
- if (!formdata && /[^\x20-\x7E]/.test(f.name))
- f.name_bin = unescape(encodeURIComponent(f.name));
-
- // filter by file type if requested
- if (this.env.filedrop.filter && !f.type.match(new RegExp(this.env.filedrop.filter))) {
- // TODO: show message to user
- continue;
- }
-
- // do it the easy way with FormData (FF 4+, Chrome 5+, Safari 5+)
- if (formdata) {
- formdata.append(fieldname, f);
- if (j == last)
- return submit_data();
- }
- // use FileReader supporetd by Firefox 3.6
- else if (window.FileReader) {
- var reader = new FileReader();
-
- // closure to pass file properties to async callback function
- reader.onload = (function(file, j) {
- return function(e) {
- multipart += 'Content-Disposition: form-data; name="' + fieldname + '"';
- multipart += '; filename="' + (f.name_bin || file.name) + '"' + crlf;
- multipart += 'Content-Length: ' + file.size + crlf;
- multipart += 'Content-Type: ' + file.type + crlf + crlf;
- multipart += reader.result + crlf;
- multipart += dashdash + boundary + crlf;
-
- if (j == last) // we're done, submit the data
- return submit_data();
- }
- })(f,j);
- reader.readAsBinaryString(f);
- }
- // Firefox 3
- else if (f.getAsBinary) {
- multipart += 'Content-Disposition: form-data; name="' + fieldname + '"';
- multipart += '; filename="' + (f.name_bin || f.name) + '"' + crlf;
- multipart += 'Content-Length: ' + f.size + crlf;
- multipart += 'Content-Type: ' + f.type + crlf + crlf;
- multipart += f.getAsBinary() + crlf;
- multipart += dashdash + boundary +crlf;
-
- if (j == last)
- return submit_data();
- }
-
- j++;
- }
- };
-
- // starts interval for keep-alive signal
- this.start_keepalive = function()
- {
- if (!this.env.session_lifetime || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print')
- return;
-
- if (this._keepalive)
- clearInterval(this._keepalive);
-
- this._keepalive = setInterval(function(){ ref.keep_alive(); }, this.env.session_lifetime * 0.5 * 1000);
- };
-
- // starts interval for refresh signal
- this.start_refresh = function()
- {
- if (!this.env.refresh_interval || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print')
- return;
-
- if (this._refresh)
- clearInterval(this._refresh);
-
- this._refresh = setInterval(function(){ ref.refresh(); }, this.env.refresh_interval * 1000);
- };
-
- // sends keep-alive signal
- this.keep_alive = function()
- {
- if (!this.busy)
- this.http_request('keep-alive');
- };
-
- // sends refresh signal
- this.refresh = function()
- {
- if (this.busy) {
- // try again after 10 seconds
- setTimeout(function(){ ref.refresh(); ref.start_refresh(); }, 10000);
- return;
- }
-
- var params = {}, lock = this.set_busy(true, 'refreshing');
-
- if (this.task == 'mail' && this.gui_objects.mailboxlist)
- params = this.check_recent_params();
-
- // plugins should bind to 'requestrefresh' event to add own params
- this.http_request('refresh', params, lock);
- };
-
- // returns check-recent request parameters
- this.check_recent_params = function()
- {
- var params = {_mbox: this.env.mailbox};
-
- if (this.gui_objects.mailboxlist)
- params._folderlist = 1;
- if (this.gui_objects.messagelist)
- params._list = 1;
- if (this.gui_objects.quotadisplay)
- params._quota = 1;
- if (this.env.search_request)
- params._search = this.env.search_request;
-
- return params;
- };
-
-
- /********************************************************/
- /********* helper methods *********/
- /********************************************************/
-
- // get window.opener.rcmail if available
- this.opener = function()
- {
- // catch Error: Permission denied to access property rcmail
- try {
- if (window.opener && !opener.closed && opener.rcmail)
- return opener.rcmail;
- }
- catch (e) {}
- };
-
- // check if we're in show mode or if we have a unique selection
- // and return the message uid
- this.get_single_uid = function()
- {
- return this.env.uid ? this.env.uid : (this.message_list ? this.message_list.get_single_selection() : null);
- };
-
- // same as above but for contacts
- this.get_single_cid = function()
- {
- return this.env.cid ? this.env.cid : (this.contact_list ? this.contact_list.get_single_selection() : null);
- };
-
- // gets cursor position
- this.get_caret_pos = function(obj)
- {
- if (obj.selectionEnd !== undefined)
- return obj.selectionEnd;
-
- if (document.selection && document.selection.createRange) {
- var range = document.selection.createRange();
- if (range.parentElement() != obj)
- return 0;
-
- var gm = range.duplicate();
- if (obj.tagName == 'TEXTAREA')
- gm.moveToElementText(obj);
- else
- gm.expand('textedit');
-
- gm.setEndPoint('EndToStart', range);
- var p = gm.text.length;
-
- return p <= obj.value.length ? p : -1;
- }
-
- return obj.value.length;
- };
-
- // moves cursor to specified position
- this.set_caret_pos = function(obj, pos)
- {
- if (obj.setSelectionRange)
- obj.setSelectionRange(pos, pos);
- else if (obj.createTextRange) {
- var range = obj.createTextRange();
- range.collapse(true);
- range.moveEnd('character', pos);
- range.moveStart('character', pos);
- range.select();
- }
- };
-
- // disable/enable all fields of a form
- this.lock_form = function(form, lock)
- {
- if (!form || !form.elements)
- return;
-
- var n, len, elm;
-
- if (lock)
- this.disabled_form_elements = [];
-
- for (n=0, len=form.elements.length; n<len; n++) {
- elm = form.elements[n];
-
- if (elm.type == 'hidden')
- continue;
- // remember which elem was disabled before lock
- if (lock && elm.disabled)
- this.disabled_form_elements.push(elm);
- // check this.disabled_form_elements before inArray() as a workaround for FF5 bug
- // http://bugs.jquery.com/ticket/9873
- else if (lock || (this.disabled_form_elements && $.inArray(elm, this.disabled_form_elements)<0))
- elm.disabled = lock;
- }
- };
-
- this.mailto_handler_uri = function()
- {
- return location.href.split('?')[0] + '?_task=mail&_action=compose&_to=%s';
- };
-
- this.register_protocol_handler = function(name)
- {
- try {
- window.navigator.registerProtocolHandler('mailto', this.mailto_handler_uri(), name);
- }
- catch(e) {};
- };
-
- this.check_protocol_handler = function(name, elem)
- {
- var nav = window.navigator;
- if (!nav
- || (typeof nav.registerProtocolHandler != 'function')
- || ((typeof nav.isProtocolHandlerRegistered == 'function')
- && nav.isProtocolHandlerRegistered('mailto', this.mailto_handler_uri()) == 'registered')
- )
- $(elem).addClass('disabled');
- else
- $(elem).click(function() { rcmail.register_protocol_handler(name); return false; });
- };
-
- // Checks browser capabilities eg. PDF support, TIF support
- this.browser_capabilities_check = function()
- {
- if (!this.env.browser_capabilities)
- this.env.browser_capabilities = {};
-
- if (this.env.browser_capabilities.pdf === undefined)
- this.env.browser_capabilities.pdf = this.pdf_support_check();
-
- if (this.env.browser_capabilities.flash === undefined)
- this.env.browser_capabilities.flash = this.flash_support_check();
-
- if (this.env.browser_capabilities.tif === undefined)
- this.tif_support_check();
- };
-
- // Returns browser capabilities string
- this.browser_capabilities = function()
- {
- if (!this.env.browser_capabilities)
- return '';
-
- var n, ret = [];
-
- for (n in this.env.browser_capabilities)
- ret.push(n + '=' + this.env.browser_capabilities[n]);
-
- return ret.join();
- };
-
- this.tif_support_check = function()
- {
- var img = new Image();
-
- img.onload = function() { rcmail.env.browser_capabilities.tif = 1; };
- img.onerror = function() { rcmail.env.browser_capabilities.tif = 0; };
- img.src = 'program/resources/blank.tif';
- };
-
- this.pdf_support_check = function()
- {
- var plugin = navigator.mimeTypes ? navigator.mimeTypes["application/pdf"] : {},
- plugins = navigator.plugins,
- len = plugins.length,
- regex = /Adobe Reader|PDF|Acrobat/i;
-
- if (plugin && plugin.enabledPlugin)
- return 1;
-
- if (window.ActiveXObject) {
- try {
- if (axObj = new ActiveXObject("AcroPDF.PDF"))
- return 1;
- }
- catch (e) {}
- try {
- if (axObj = new ActiveXObject("PDF.PdfCtrl"))
- return 1;
- }
- catch (e) {}
- }
-
- for (i=0; i<len; i++) {
- plugin = plugins[i];
- if (typeof plugin === 'String') {
- if (regex.test(plugin))
- return 1;
- }
- else if (plugin.name && regex.test(plugin.name))
- return 1;
- }
-
- return 0;
- };
-
- this.flash_support_check = function()
- {
- var plugin = navigator.mimeTypes ? navigator.mimeTypes["application/x-shockwave-flash"] : {};
-
- if (plugin && plugin.enabledPlugin)
- return 1;
-
- if (window.ActiveXObject) {
- try {
- if (axObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"))
- return 1;
- }
- catch (e) {}
- }
-
- return 0;
- };
-
- // Cookie setter
- this.set_cookie = function(name, value, expires)
- {
- setCookie(name, value, expires, this.env.cookie_path, this.env.cookie_domain, this.env.cookie_secure);
- }
-
-} // end object rcube_webmail
-
-
-// some static methods
-rcube_webmail.long_subject_title = function(elem, indent)
-{
- if (!elem.title) {
- var $elem = $(elem);
- if ($elem.width() + indent * 15 > $elem.parent().width())
- elem.title = $elem.html();
- }
-};
-
-rcube_webmail.long_subject_title_ie = function(elem, indent)
-{
- if (!elem.title) {
- var $elem = $(elem),
- txt = $.trim($elem.text()),
- tmp = $('<span>').text(txt)
- .css({'position': 'absolute', 'float': 'left', 'visibility': 'hidden',
- 'font-size': $elem.css('font-size'), 'font-weight': $elem.css('font-weight')})
- .appendTo($('body')),
- w = tmp.width();
-
- tmp.remove();
- if (w + indent * 15 > $elem.width())
- elem.title = txt;
- }
-};
-
-rcube_webmail.prototype.get_cookie = getCookie;
-
-// copy event engine prototype
-rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
-rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
-rcube_webmail.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
+function rcube_webmail(){this.labels={};this.buttons={};this.buttons_sel={};this.gui_objects={};this.gui_containers={};this.commands={};this.command_handlers={};this.onloads=[];this.messages={};this.group2expand={};this.dblclick_time=500;this.message_time=4000;this.identifier_expr=new RegExp("[^0-9a-z-_]","gi");this.env={request_timeout:180,draft_autosave:0,comm_path:"./",blankpage:"program/resources/blank.gif",recipients_separator:",",recipients_delimiter:", "};this.ref="rcmail";var ref=this;$.ajaxSetup({cache:false,timeout:this.env.request_timeout*1000,error:function(request,status,err){ref.http_error(request,status,err)},beforeSend:function(xmlhttp){xmlhttp.setRequestHeader("X-Roundcube-Request",ref.env.request_token)}});$(window).bind("beforeunload",function(){rcmail.unload=true});this.set_env=function(p,value){if(p!=null&&typeof p==="object"&&!value){for(var n in p){this.env[n]=p[n]}}else{this.env[p]=value}};this.add_label=function(p,value){if(typeof p=="string"){this.labels[p]=value}else{if(typeof p=="object"){$.extend(this.labels,p)}}};this.register_button=function(command,id,type,act,sel,over){var button_prop={id:id,type:type};if(act){button_prop.act=act}if(sel){button_prop.sel=sel}if(over){button_prop.over=over}if(!this.buttons[command]){this.buttons[command]=[]}this.buttons[command].push(button_prop);if(this.loaded){init_button(command,button_prop)}};this.gui_object=function(name,id){this.gui_objects[name]=this.loaded?rcube_find_object(id):id};this.gui_container=function(name,id){this.gui_containers[name]=id};this.add_element=function(elm,container){if(this.gui_containers[container]&&this.gui_containers[container].jquery){this.gui_containers[container].append(elm)}};this.register_command=function(command,callback,enable){this.command_handlers[command]=callback;if(enable){this.enable_command(command,true)}};this.add_onload=function(f){this.onloads.push(f)};this.init=function(){var n,p=this;this.task=this.env.task;if(!bw.dom||!bw.xmlhttp_test()||(bw.mz&&bw.vendver<1.9)){this.goto_url("error","_code=0x199");return}for(n in this.gui_containers){this.gui_containers[n]=$("#"+this.gui_containers[n])}for(n in this.gui_objects){this.gui_objects[n]=rcube_find_object(this.gui_objects[n])}if(this.env.x_frame_options){try{if(this.env.x_frame_options=="deny"&&top.location.href!=self.location.href){top.location.href=self.location.href}else{if(top.location.hostname!=self.location.hostname){throw 1}}}catch(e){$("form").each(function(){ref.lock_form(this,true)});this.display_message("Blocked: possible clickjacking attack!","error");return}}this.init_buttons();if(this.is_framed()){parent.rcmail.set_busy(false,null,parent.rcmail.env.frame_lock);parent.rcmail.env.frame_lock=null}this.enable_command("close","logout","mail","addressbook","settings","save-pref","compose","undo","about","switch-task",true);if(this.env.permaurl){this.enable_command("permaurl","extwin",true)}switch(this.task){case"mail":this.enable_command("list","checkmail","add-contact","search","reset-search","collapse-folder",true);if(this.gui_objects.messagelist){this.message_list=new rcube_list_widget(this.gui_objects.messagelist,{multiselect:true,multiexpand:true,draggable:true,keyboard:true,column_movable:this.env.col_movable,dblclick_time:this.dblclick_time});this.message_list.row_init=function(o){p.init_message_row(o)};this.message_list.addEventListener("dblclick",function(o){p.msglist_dbl_click(o)});this.message_list.addEventListener("click",function(o){p.msglist_click(o)});this.message_list.addEventListener("keypress",function(o){p.msglist_keypress(o)});this.message_list.addEventListener("select",function(o){p.msglist_select(o)});this.message_list.addEventListener("dragstart",function(o){p.drag_start(o)});this.message_list.addEventListener("dragmove",function(e){p.drag_move(e)});this.message_list.addEventListener("dragend",function(e){p.drag_end(e)});this.message_list.addEventListener("expandcollapse",function(e){p.msglist_expand(e)});this.message_list.addEventListener("column_replace",function(e){p.msglist_set_coltypes(e)});document.onmouseup=function(e){return p.doc_mouse_up(e)};this.gui_objects.messagelist.parentNode.onmousedown=function(e){return p.click_on_list(e)};this.message_list.init();this.enable_command("toggle_status","toggle_flag","menu-open","menu-save","sort",true);this.command("list")}if(this.gui_objects.qsearchbox){if(this.env.search_text!=null){this.gui_objects.qsearchbox.value=this.env.search_text}$(this.gui_objects.qsearchbox).focusin(function(){rcmail.message_list&&rcmail.message_list.blur()})}this.set_button_titles();this.env.message_commands=["show","reply","reply-all","reply-list","moveto","copy","delete","open","mark","edit","viewsource","print","load-attachment","show-headers","hide-headers","download","forward","forward-inline","forward-attachment"];if(this.env.action=="show"||this.env.action=="preview"){this.enable_command(this.env.message_commands,this.env.uid);this.enable_command("reply-list",this.env.list_post);if(this.env.action=="show"){this.http_request("pagenav",{_uid:this.env.uid,_mbox:this.env.mailbox,_search:this.env.search_request},this.display_message("","loading"))}if(this.env.blockedobjects){if(this.gui_objects.remoteobjectsmsg){this.gui_objects.remoteobjectsmsg.style.display="block"}this.enable_command("load-images","always-load",true)}if(this.env.action=="preview"&&this.is_framed()){this.enable_command("compose","add-contact",false);parent.rcmail.show_contentframe(true)}}else{if(this.env.action=="compose"){this.env.compose_commands=["send-attachment","remove-attachment","send","cancel","toggle-editor","list-adresses","search","reset-search","extwin"];if(this.env.drafts_mailbox){this.env.compose_commands.push("savedraft")}this.enable_command(this.env.compose_commands,"identities",true);$.merge(this.env.compose_commands,["add-recipient","firstpage","previouspage","nextpage","lastpage"]);if(this.env.spellcheck){this.env.spellcheck.spelling_state_observer=function(s){ref.spellcheck_state()};this.env.compose_commands.push("spellcheck");this.enable_command("spellcheck",true)}document.onmouseup=function(e){return p.doc_mouse_up(e)};this.init_messageform()}else{if(this.env.action=="print"&&this.env.uid){if(bw.safari){setTimeout("window.print()",10)}else{window.print()}}}}if(this.gui_objects.mailboxlist){this.env.unread_counts={};this.gui_objects.folderlist=this.gui_objects.mailboxlist;this.http_request("getunread")}if(this.gui_objects.contactslist){this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:true,draggable:false,keyboard:false});this.contact_list.addEventListener("select",function(o){ref.compose_recipient_select(o)});this.contact_list.addEventListener("dblclick",function(o){ref.compose_add_recipient("to")});this.contact_list.init()}if(this.gui_objects.addressbookslist){this.gui_objects.folderlist=this.gui_objects.addressbookslist;this.enable_command("list-adresses",true)}if(this.env.mdn_request&&this.env.uid){var postact="sendmdn",postdata={_uid:this.env.uid,_mbox:this.env.mailbox};if(!confirm(this.get_label("mdnrequest"))){postdata._flag="mdnsent";postact="mark"}this.http_post(postact,postdata)}if(!this.is_framed()&&!this.env.extwin){this.browser_capabilities_check()}break;case"addressbook":if(this.gui_objects.folderlist){this.env.contactfolders=$.extend($.extend({},this.env.address_sources),this.env.contactgroups)}this.enable_command("add","import",this.env.writable_source);this.enable_command("list","listgroup","listsearch","advanced-search",true);if(this.gui_objects.contactslist){this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:true,draggable:this.gui_objects.folderlist?true:false,keyboard:true});this.contact_list.row_init=function(row){p.triggerEvent("insertrow",{cid:row.uid,row:row})};this.contact_list.addEventListener("keypress",function(o){p.contactlist_keypress(o)});this.contact_list.addEventListener("select",function(o){p.contactlist_select(o)});this.contact_list.addEventListener("dragstart",function(o){p.drag_start(o)});this.contact_list.addEventListener("dragmove",function(e){p.drag_move(e)});this.contact_list.addEventListener("dragend",function(e){p.drag_end(e)});this.contact_list.init();if(this.env.cid){this.contact_list.highlight_row(this.env.cid)}this.gui_objects.contactslist.parentNode.onmousedown=function(e){return p.click_on_list(e)};document.onmouseup=function(e){return p.doc_mouse_up(e)};if(this.gui_objects.qsearchbox){$(this.gui_objects.qsearchbox).focusin(function(){rcmail.contact_list.blur()})}this.update_group_commands();this.command("list")}this.set_page_buttons();if(this.env.cid){this.enable_command("show","edit",true);if(this.gui_objects.editform){$("input.groupmember").change(function(){ref.group_member_change(this.checked?"add":"del",ref.env.cid,ref.env.source,this.value)})}}if(this.gui_objects.editform){this.enable_command("save",true);if(this.env.action=="add"||this.env.action=="edit"||this.env.action=="search"){this.init_contact_form()}}if(this.gui_objects.qsearchbox){this.enable_command("search","reset-search","moveto",true)}break;case"settings":this.enable_command("preferences","identities","save","folders",true);if(this.env.action=="identities"){this.enable_command("add",this.env.identities_level<2)}else{if(this.env.action=="edit-identity"||this.env.action=="add-identity"){this.enable_command("save","edit","toggle-editor",true);this.enable_command("delete",this.env.identities_level<2);if(this.env.action=="add-identity"){$("input[type='text']").first().select()}}else{if(this.env.action=="folders"){this.enable_command("subscribe","unsubscribe","create-folder","rename-folder",true)}else{if(this.env.action=="edit-folder"&&this.gui_objects.editform){this.enable_command("save","folder-size",true);parent.rcmail.env.exists=this.env.messagecount;parent.rcmail.enable_command("purge",this.env.messagecount);$("input[type='text']").first().select()}}}}if(this.gui_objects.identitieslist){this.identity_list=new rcube_list_widget(this.gui_objects.identitieslist,{multiselect:false,draggable:false,keyboard:false});this.identity_list.addEventListener("select",function(o){p.identity_select(o)});this.identity_list.init();this.identity_list.focus();if(this.env.iid){this.identity_list.highlight_row(this.env.iid)}}else{if(this.gui_objects.sectionslist){this.sections_list=new rcube_list_widget(this.gui_objects.sectionslist,{multiselect:false,draggable:false,keyboard:false});this.sections_list.addEventListener("select",function(o){p.section_select(o)});this.sections_list.init();this.sections_list.focus()}else{if(this.gui_objects.subscriptionlist){this.init_subscription_list()}}}break;case"login":var input_user=$("#rcmloginuser");input_user.bind("keyup",function(e){return rcmail.login_user_keyup(e)});if(input_user.val()==""){input_user.focus()}else{$("#rcmloginpwd").focus()}if(window.jstz&&!bw.ie6){var timezone=jstz.determine();if(timezone.name()){$("#rcmlogintz").val(timezone.name())}}else{$("#rcmlogintz").val(new Date().getStdTimezoneOffset()/-60)}$("form").submit(function(){$("input[type=submit]",this).prop("disabled",true);rcmail.clear_messages();rcmail.display_message("","loading")});this.enable_command("login",true);break}if(this.env.contentframe&&!$("#"+this.env.contentframe).is(":visible")){this.env.contentframe=null}if(bw.ie){$("input[type=file]").keydown(function(e){if(e.keyCode=="13"){e.preventDefault()}})}this.loaded=true;if(this.pending_message){this.display_message(this.pending_message[0],this.pending_message[1],this.pending_message[2])}if(this.gui_objects.folderlist){this.gui_containers.foldertray=$(this.gui_objects.folderlist)}if(this.gui_objects.filedrop&&this.env.filedrop&&((window.XMLHttpRequest&&XMLHttpRequest.prototype&&XMLHttpRequest.prototype.sendAsBinary)||window.FormData)){$(document.body).bind("dragover dragleave drop",function(e){return ref.document_drag_hover(e,e.type=="dragover")});$(this.gui_objects.filedrop).addClass("droptarget").bind("dragover dragleave",function(e){return ref.file_drag_hover(e,e.type=="dragover")}).get(0).addEventListener("drop",function(e){return ref.file_dropped(e)},false)}this.triggerEvent("init",{task:this.task,action:this.env.action});for(var i in this.onloads){if(typeof this.onloads[i]==="string"){eval(this.onloads[i])}else{if(typeof this.onloads[i]==="function"){this.onloads[i]()}}}this.start_refresh();this.start_keepalive()};this.log=function(msg){if(window.console&&console.log){console.log(msg)}};this.command=function(command,props,obj,event){var ret,uid,cid,url,flag;if(obj&&obj.blur){obj.blur()}if(this.busy){return false}if((obj&&obj.href&&String(obj.href).indexOf("#")<0)&&rcube_event.get_modifier(event)){return true}if(!this.commands[command]){if(this.is_framed()){parent.rcmail.command(command,props)}return false}if(this.task=="mail"&&this.env.action=="compose"&&$.inArray(command,this.env.compose_commands)<0){if(this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning"))){return false}}if(typeof this.command_handlers[command]==="function"){ret=this.command_handlers[command](props,obj);return ret!==undefined?ret:(obj?false:true)}else{if(typeof this.command_handlers[command]==="string"){ret=window[this.command_handlers[command]](props,obj);return ret!==undefined?ret:(obj?false:true)}}this.triggerEvent("actionbefore",{props:props,action:command});ret=this.triggerEvent("before"+command,props);if(ret!==undefined){if(ret===false){return false}else{props=ret}}ret=undefined;switch(command){case"login":if(this.gui_objects.loginform){this.gui_objects.loginform.submit()}break;case"mail":case"addressbook":case"settings":case"logout":this.switch_task(command);break;case"about":this.redirect("?_task=settings&_action=about",false);break;case"permaurl":if(obj&&obj.href&&obj.target){return true}else{if(this.env.permaurl){parent.location.href=this.env.permaurl}}break;case"extwin":if(this.env.action=="compose"){var prevstate=this.env.compose_extwin;$("input[name='_action']",this.gui_objects.messageform).val("compose");this.gui_objects.messageform.action=this.url("mail/compose",{_id:this.env.compose_id,_extwin:1});this.gui_objects.messageform.target=this.open_window("",1100);this.gui_objects.messageform.submit()}else{this.open_window(this.env.permaurl,900)}break;case"menu-open":case"menu-save":this.triggerEvent(command,{props:props});return false;case"open":if(uid=this.get_single_uid()){obj.href=this.url("show",{_mbox:this.env.mailbox,_uid:uid});return true}break;case"close":if(this.env.extwin){window.close()}break;case"list":if(props&&props!=""){this.reset_qsearch()}if(this.env.action=="compose"&&this.env.extwin){window.close()}else{if(this.task=="mail"){this.list_mailbox(props);this.set_button_titles()}else{if(this.task=="addressbook"){this.list_contacts(props)}}}break;case"sort":var sort_order=this.env.sort_order,sort_col=!this.env.disabled_sort_col?props:this.env.sort_col;if(!this.env.disabled_sort_order){sort_order=this.env.sort_col==sort_col&&sort_order=="ASC"?"DESC":"ASC"}this.set_list_sorting(sort_col,sort_order);this.list_mailbox("","",sort_col+"_"+sort_order);break;case"nextpage":this.list_page("next");break;case"lastpage":this.list_page("last");break;case"previouspage":this.list_page("prev");break;case"firstpage":this.list_page("first");break;case"expunge":if(this.env.exists){this.expunge_mailbox(this.env.mailbox)}break;case"purge":case"empty-mailbox":if(this.env.exists){this.purge_mailbox(this.env.mailbox)}break;case"show":if(this.task=="mail"){uid=this.get_single_uid();if(uid&&(!this.env.uid||uid!=this.env.uid)){if(this.env.mailbox==this.env.drafts_mailbox){this.open_compose_step({_draft_uid:uid,_mbox:this.env.mailbox})}else{this.show_message(uid)}}}else{if(this.task=="addressbook"){cid=props?props:this.get_single_cid();if(cid&&!(this.env.action=="show"&&cid==this.env.cid)){this.load_contact(cid,"show")}}}break;case"add":if(this.task=="addressbook"){this.load_contact(0,"add")}else{if(this.task=="settings"){this.identity_list.clear_selection();this.load_identity(0,"add-identity")}}break;case"edit":if(this.task=="addressbook"&&(cid=this.get_single_cid())){this.load_contact(cid,"edit")}else{if(this.task=="settings"&&props){this.load_identity(props,"edit-identity")}else{if(this.task=="mail"&&(cid=this.get_single_uid())){url={_mbox:this.env.mailbox};url[this.env.mailbox==this.env.drafts_mailbox&&props!="new"?"_draft_uid":"_uid"]=cid;this.open_compose_step(url)}}}break;case"save":var input,form=this.gui_objects.editform;if(form){if(this.env.action=="search"){}else{if((input=$("input[name='_pagesize']",form))&&input.length&&isNaN(parseInt(input.val()))){alert(this.get_label("nopagesizewarning"));input.focus();break}else{if(props=="reload"){form.action+="?_reload=1"}else{if(this.task=="settings"&&(this.env.identities_level%2)==0&&(input=$("input[name='_email']",form))&&input.length&&!rcube_check_email(input.val())){alert(this.get_label("noemailwarning"));input.focus();break}}$("input.placeholder").each(function(){if(this.value==this._placeholder){this.value=""}})}}if(parent.rcmail&&parent.rcmail.env.source){form.action=this.add_url(form.action,"_orig_source",parent.rcmail.env.source)}form.submit()}break;case"delete":if(this.task=="mail"){this.delete_messages(event)}else{if(this.task=="addressbook"){this.delete_contacts()}else{if(this.task=="settings"){this.delete_identity()}}}break;case"move":case"moveto":if(this.task=="mail"){this.move_messages(props)}else{if(this.task=="addressbook"&&this.drag_active){this.copy_contact(null,props)}}break;case"copy":if(this.task=="mail"){this.copy_messages(props)}break;case"mark":if(props){this.mark_message(props)}break;case"toggle_status":if(props&&!props._row){break}flag="read";if(props._row.uid){uid=props._row.uid;if(this.message_list.rows[uid].deleted){flag="undelete"}else{if(!this.message_list.rows[uid].unread){flag="unread"}}}this.mark_message(flag,uid);break;case"toggle_flag":if(props&&!props._row){break}flag="flagged";if(props._row.uid){uid=props._row.uid;if(this.message_list.rows[uid].flagged){flag="unflagged"}}this.mark_message(flag,uid);break;case"always-load":if(this.env.uid&&this.env.sender){this.add_contact(this.env.sender);setTimeout(function(){ref.command("load-images")},300);break}case"load-images":if(this.env.uid){this.show_message(this.env.uid,true,this.env.action=="preview")}break;case"load-attachment":var qstring="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+props.part;if(this.env.uid&&props.mimetype&&this.env.mimetypes&&$.inArray(props.mimetype,this.env.mimetypes)>=0){var attachment_win=window.open(this.env.comm_path+"&_action=get&"+qstring+"&_frame=1",this.html_identifier("rcubemailattachment"+this.env.uid+props.part));if(attachment_win){setTimeout(function(){attachment_win.focus()},10);break}}this.goto_url("get",qstring+"&_download=1",false);break;case"select-all":this.select_all_mode=props?false:true;this.dummy_select=true;if(props=="invert"){this.message_list.invert_selection()}else{this.message_list.select_all(props=="page"?"":props)}this.dummy_select=null;break;case"select-none":this.select_all_mode=false;this.message_list.clear_selection();break;case"expand-all":this.env.autoexpand_threads=1;this.message_list.expand_all();break;case"expand-unread":this.env.autoexpand_threads=2;this.message_list.collapse_all();this.expand_unread();break;case"collapse-all":this.env.autoexpand_threads=0;this.message_list.collapse_all();break;case"nextmessage":if(this.env.next_uid){this.show_message(this.env.next_uid,false,this.env.action=="preview")}break;case"lastmessage":if(this.env.last_uid){this.show_message(this.env.last_uid)}break;case"previousmessage":if(this.env.prev_uid){this.show_message(this.env.prev_uid,false,this.env.action=="preview")}break;case"firstmessage":if(this.env.first_uid){this.show_message(this.env.first_uid)}break;case"compose":url={};if(this.task=="mail"){url._mbox=this.env.mailbox;if(props){url._to=props}if(this.env.search_request){url._search=this.env.search_request}}else{if(this.task=="addressbook"){if(props&&props.indexOf("@")>0){url._to=props}else{var n,len,a_cids=[];if(props){a_cids.push(props)}else{if(this.contact_list){var selection=this.contact_list.get_selection();for(n=0,len=selection.length;n<len;n++){a_cids.push(selection[n])}}}if(a_cids.length){this.http_post("mailto",{_cid:a_cids.join(","),_source:this.env.source},true)}else{if(this.env.group){this.http_post("mailto",{_gid:this.env.group,_source:this.env.source},true)}}break}}else{if(props){url._to=props}}}this.open_compose_step(url);break;case"spellcheck":if(this.spellcheck_state()){this.stop_spellchecking()}else{if(window.tinyMCE&&tinyMCE.get(this.env.composebody)){tinyMCE.execCommand("mceSpellCheck",true)}else{if(this.env.spellcheck&&this.env.spellcheck.spellCheck){this.env.spellcheck.spellCheck()}}}this.spellcheck_state();break;case"savedraft":clearTimeout(this.save_timer);if(this.env.draft_id&&this.cmp_hash==this.compose_field_hash()){this.auto_save_start();break}this.submit_messageform(true);break;case"send":if(!props.nocheck&&!this.check_compose_input(command)){break}clearTimeout(this.save_timer);this.submit_messageform();break;case"send-attachment":clearTimeout(this.save_timer);this.upload_file(props||this.gui_objects.uploadform);break;case"insert-sig":this.change_identity($("[name='_from']")[0],true);break;case"list-adresses":this.list_contacts(props);this.enable_command("add-recipient",false);break;case"add-recipient":this.compose_add_recipient(props);break;case"reply-all":case"reply-list":case"reply":if(uid=this.get_single_uid()){url={_reply_uid:uid,_mbox:this.env.mailbox};if(command=="reply-all"){url._all=(!props&&this.commands["reply-list"]?"list":"all")}else{if(command=="reply-list"){url._all="list"}}this.open_compose_step(url)}break;case"forward-attachment":case"forward-inline":case"forward":var uids=this.env.uid?[this.env.uid]:(this.message_list?this.message_list.get_selection():[]);if(uids.length){url={_forward_uid:this.uids_to_list(uids),_mbox:this.env.mailbox};if(command=="forward-attachment"||(!props&&this.env.forward_attachment)||uids.length>1){url._attachment=1}this.open_compose_step(url)}break;case"print":if(uid=this.get_single_uid()){ref.printwin=window.open(this.env.comm_path+"&_action=print&_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(this.env.safemode?"&_safe=1":""));if(this.printwin){setTimeout(function(){ref.printwin.focus()},20);if(this.env.action!="show"){this.mark_message("read",uid)}}}break;case"viewsource":if(uid=this.get_single_uid()){ref.sourcewin=window.open(this.env.comm_path+"&_action=viewsource&_uid="+uid+"&_mbox="+urlencode(this.env.mailbox));if(this.sourcewin){setTimeout(function(){ref.sourcewin.focus()},20)}}break;case"download":if(uid=this.get_single_uid()){this.goto_url("viewsource",{_uid:uid,_mbox:this.env.mailbox,_save:1})}break;case"search":if(!props&&this.gui_objects.qsearchbox){props=this.gui_objects.qsearchbox.value}if(props){this.qsearch(props);break}case"reset-search":var n,s=this.env.search_request||this.env.qsearch;this.reset_qsearch();this.select_all_mode=false;if(s&&this.env.action=="compose"){if(this.contact_list){this.list_contacts_clear()}}else{if(s&&this.env.mailbox){this.list_mailbox(this.env.mailbox,1)}else{if(s&&this.task=="addressbook"){if(this.env.source==""){for(n in this.env.address_sources){break}this.env.source=n;this.env.group=""}this.list_contacts(this.env.source,this.env.group,1)}}}break;case"listgroup":this.reset_qsearch();this.list_contacts(props.source,props.id);break;case"import":if(this.env.action=="import"&&this.gui_objects.importform){var file=document.getElementById("rcmimportfile");if(file&&!file.value){alert(this.get_label("selectimportfile"));break}this.gui_objects.importform.submit();this.set_busy(true,"importwait");this.lock_form(this.gui_objects.importform,true)}else{this.goto_url("import",(this.env.source?"_target="+urlencode(this.env.source)+"&":""))}break;case"export":if(this.contact_list.rowcount>0){this.goto_url("export",{_source:this.env.source,_gid:this.env.group,_search:this.env.search_request})}break;case"upload-photo":this.upload_contact_photo(props||this.gui_objects.uploadform);break;case"delete-photo":this.replace_contact_photo("-del-");break;case"preferences":case"identities":case"folders":this.goto_url("settings/"+command);break;case"undo":this.http_request("undo","",this.display_message("","loading"));break;default:var func=command.replace(/-/g,"_");if(this[func]&&typeof this[func]==="function"){ret=this[func](props,obj)}break}if(this.triggerEvent("after"+command,props)===false){ret=false}this.triggerEvent("actionafter",{props:props,action:command});return ret===false?false:obj?false:true};this.enable_command=function(){var i,n,args=Array.prototype.slice.call(arguments),enable=args.pop(),cmd;for(n=0;n<args.length;n++){cmd=args[n];if(typeof cmd==="string"){this.commands[cmd]=enable;this.set_button(cmd,(enable?"act":"pas"))}else{for(i in cmd){args.push(cmd[i])}}}};this.set_busy=function(a,message,id){if(a&&message){var msg=this.get_label(message);if(msg==message){msg="Loading..."}id=this.display_message(msg,"loading")}else{if(!a&&id){this.hide_message(id)}}this.busy=a;if(this.gui_objects.editform){this.lock_form(this.gui_objects.editform,a)}return id};this.get_label=function(name,domain){if(domain&&this.labels[domain+"."+name]){return this.labels[domain+"."+name]}else{if(this.labels[name]){return this.labels[name]}else{return name}}};this.gettext=this.get_label;this.switch_task=function(task){if(this.task===task&&task!="mail"){return}var url=this.get_task_url(task);if(task=="mail"){url+="&_mbox=INBOX"}this.redirect(url)};this.get_task_url=function(task,url){if(!url){url=this.env.comm_path}return url.replace(/_task=[a-z]+/,"_task="+task)};this.reload=function(delay){if(this.is_framed()){parent.rcmail.reload(delay)}else{if(delay){setTimeout(function(){rcmail.reload()},delay)}else{if(window.location){location.href=this.env.comm_path+(this.env.action?"&_action="+this.env.action:"")}}}};this.add_url=function(url,name,value){value=urlencode(value);if(/(\?.*)$/.test(url)){var urldata=RegExp.$1,datax=RegExp("((\\?|&)"+RegExp.escape(name)+"=[^&]*)");if(datax.test(urldata)){urldata=urldata.replace(datax,RegExp.$2+name+"="+value)}else{urldata+="&"+name+"="+value}return url.replace(/(\?.*)$/,urldata)}return url+"?"+name+"="+value};this.is_framed=function(){return(this.env.framed&&parent.rcmail&&parent.rcmail!=this&&parent.rcmail.command)};this.save_pref=function(prop){var request={_name:prop.name,_value:prop.value};if(prop.session){request._session=prop.session}if(prop.env){this.env[prop.env]=prop.value}this.http_post("save-pref",request)};this.html_identifier=function(str,encode){str=String(str);if(encode){return Base64.encode(str).replace(/=+$/,"").replace(/\+/g,"-").replace(/\//g,"_")}else{return str.replace(this.identifier_expr,"_")}};this.html_identifier_decode=function(str){str=String(str).replace(/-/g,"+").replace(/_/g,"/");while(str.length%4){str+="="}return Base64.decode(str)};this.drag_menu=function(e,target){var modkey=rcube_event.get_modifier(e),menu=this.gui_objects.message_dragmenu;if(menu&&modkey==SHIFT_KEY&&this.commands.copy){var pos=rcube_event.get_mouse_pos(e);this.env.drag_target=target;$(menu).css({top:(pos.y-10)+"px",left:(pos.x-10)+"px"}).show();return true}return false};this.drag_menu_action=function(action){var menu=this.gui_objects.message_dragmenu;if(menu){$(menu).hide()}this.command(action,this.env.drag_target);this.env.drag_target=null};this.drag_start=function(list){var model=this.task=="mail"?this.env.mailboxes:this.env.contactfolders;this.drag_active=true;if(this.preview_timer){clearTimeout(this.preview_timer)}if(this.preview_read_timer){clearTimeout(this.preview_read_timer)}if(this.gui_objects.folderlist&&model){this.initialBodyScrollTop=bw.ie?0:window.pageYOffset;this.initialListScrollTop=this.gui_objects.folderlist.parentNode.scrollTop;var k,li,height,list=$(this.gui_objects.folderlist);pos=list.offset();this.env.folderlist_coords={x1:pos.left,y1:pos.top,x2:pos.left+list.width(),y2:pos.top+list.height()};this.env.folder_coords=[];for(k in model){if(li=this.get_folder_li(k)){if(height=li.firstChild.offsetHeight){pos=$(li.firstChild).offset();this.env.folder_coords[k]={x1:pos.left,y1:pos.top,x2:pos.left+li.firstChild.offsetWidth,y2:pos.top+height,on:0}}}}}};this.drag_end=function(e){this.drag_active=false;this.env.last_folder_target=null;if(this.folder_auto_timer){clearTimeout(this.folder_auto_timer);this.folder_auto_timer=null;this.folder_auto_expand=null}if(this.gui_objects.folderlist&&this.env.folder_coords){for(var k in this.env.folder_coords){if(this.env.folder_coords[k].on){$(this.get_folder_li(k)).removeClass("droptarget")}}}};this.drag_move=function(e){if(this.gui_objects.folderlist&&this.env.folder_coords){var k,li,div,check,oldclass,layerclass="draglayernormal",mouse=rcube_event.get_mouse_pos(e),pos=this.env.folderlist_coords,boffset=bw.ie?-document.documentElement.scrollTop:this.initialBodyScrollTop,moffset=this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop;if(this.contact_list&&this.contact_list.draglayer){oldclass=this.contact_list.draglayer.attr("class")}mouse.y+=-moffset-boffset;if(mouse.x<pos.x1||mouse.x>=pos.x2||mouse.y<pos.y1||mouse.y>=pos.y2){if(this.env.last_folder_target){$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget");this.env.folder_coords[this.env.last_folder_target].on=0;this.env.last_folder_target=null}if(layerclass!=oldclass&&this.contact_list&&this.contact_list.draglayer){this.contact_list.draglayer.attr("class",layerclass)}return}for(k in this.env.folder_coords){pos=this.env.folder_coords[k];if(mouse.x>=pos.x1&&mouse.x<pos.x2&&mouse.y>=pos.y1&&mouse.y<pos.y2){if(check=this.check_droptarget(k)){li=this.get_folder_li(k);div=$(li.getElementsByTagName("div")[0]);if(div.hasClass("collapsed")){if(this.folder_auto_timer){clearTimeout(this.folder_auto_timer)}this.folder_auto_expand=this.env.mailboxes[k].id;this.folder_auto_timer=setTimeout(function(){rcmail.command("collapse-folder",rcmail.folder_auto_expand);rcmail.drag_start(null)},1000)}else{if(this.folder_auto_timer){clearTimeout(this.folder_auto_timer);this.folder_auto_timer=null;this.folder_auto_expand=null}}$(li).addClass("droptarget");this.env.folder_coords[k].on=1;this.env.last_folder_target=k;layerclass="draglayer"+(check>1?"copy":"normal")}else{this.env.last_folder_target=null}}else{if(pos.on){$(this.get_folder_li(k)).removeClass("droptarget");this.env.folder_coords[k].on=0}}}if(layerclass!=oldclass&&this.contact_list&&this.contact_list.draglayer){this.contact_list.draglayer.attr("class",layerclass)}}};this.collapse_folder=function(name){var li=this.get_folder_li(name,"",true),div=$("div:first",li),ul=$("ul:first",li);if(div.hasClass("collapsed")){ul.show();div.removeClass("collapsed").addClass("expanded");var reg=new RegExp("&"+urlencode(name)+"&");this.env.collapsed_folders=this.env.collapsed_folders.replace(reg,"")}else{if(div.hasClass("expanded")){ul.hide();div.removeClass("expanded").addClass("collapsed");this.env.collapsed_folders=this.env.collapsed_folders+"&"+urlencode(name)+"&";if(this.env.mailbox.indexOf(name+this.env.delimiter)==0&&!$(li).hasClass("virtual")){this.command("list",name)}}else{return}}if(bw.ie6||bw.ie7){var siblings=li.nextSibling?li.nextSibling.getElementsByTagName("ul"):null;if(siblings&&siblings.length&&(li=siblings[0])&&li.style&&li.style.display!="none"){li.style.display="none";li.style.display=""}}this.command("save-pref",{name:"collapsed_folders",value:this.env.collapsed_folders});this.set_unread_count_display(name,false)};this.doc_mouse_up=function(e){var model,list,id;if($(rcube_event.get_target(e)).closest(".ui-dialog, .ui-widget-overlay").length){return}if(list=this.message_list){model=this.env.mailboxes}else{if(list=this.contact_list){model=this.env.contactfolders}else{if(this.ksearch_value){this.ksearch_blur()}}}if(list&&!rcube_mouse_is_over(e,list.list.parentNode)){list.blur()}if(this.drag_active&&model&&this.env.last_folder_target){var target=model[this.env.last_folder_target];$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget");this.env.last_folder_target=null;list.draglayer.hide();if(!this.drag_menu(e,target)){this.command("moveto",target)}}if(this.buttons_sel){for(id in this.buttons_sel){if(typeof id!=="function"){this.button_out(this.buttons_sel[id],id)}}this.buttons_sel={}}};this.click_on_list=function(e){if(this.gui_objects.qsearchbox){this.gui_objects.qsearchbox.blur()}if(this.message_list){this.message_list.focus()}else{if(this.contact_list){this.contact_list.focus()}}return true};this.msglist_select=function(list){if(this.preview_timer){clearTimeout(this.preview_timer)}if(this.preview_read_timer){clearTimeout(this.preview_read_timer)}var selected=list.get_single_selection();this.enable_command(this.env.message_commands,selected!=null);if(selected){if(this.env.mailbox==this.env.drafts_mailbox){this.enable_command("reply","reply-all","reply-list","forward","forward-attachment","forward-inline",false)}else{var msg=this.env.messages[selected];if(!msg.ml){this.enable_command("reply-list",false)}}}this.enable_command("delete","moveto","copy","mark","forward","forward-attachment",list.selection.length>0);if(selected||(list.selection.length&&list.selection.length!=list.rowcount)){this.select_all_mode=false}if(selected&&this.env.contentframe&&!list.multi_selecting&&!this.dummy_select){this.preview_timer=setTimeout(function(){ref.msglist_get_preview()},this.dblclick_time)}else{if(this.env.contentframe){this.show_contentframe(false)}}};this.msglist_click=function(list){if(list.multi_selecting||!this.env.contentframe){return}if(list.get_single_selection()){return}var win=this.get_frame_window(this.env.contentframe);if(win&&win.location.href.indexOf(this.env.blankpage)>=0){if(this.preview_timer){clearTimeout(this.preview_timer)}if(this.preview_read_timer){clearTimeout(this.preview_read_timer)}this.preview_timer=setTimeout(function(){ref.msglist_get_preview()},this.dblclick_time)}};this.msglist_dbl_click=function(list){if(this.preview_timer){clearTimeout(this.preview_timer)}if(this.preview_read_timer){clearTimeout(this.preview_read_timer)}var uid=list.get_single_selection();if(uid&&this.env.mailbox==this.env.drafts_mailbox){this.open_compose_step({_draft_uid:uid,_mbox:this.env.mailbox})}else{if(uid){this.show_message(uid,false,false)}}};this.msglist_keypress=function(list){if(list.modkey==CONTROL_KEY){return}if(list.key_pressed==list.ENTER_KEY){this.command("show")}else{if(list.key_pressed==list.DELETE_KEY||list.key_pressed==list.BACKSPACE_KEY){this.command("delete")}else{if(list.key_pressed==33){this.command("previouspage")}else{if(list.key_pressed==34){this.command("nextpage")}}}}};this.msglist_get_preview=function(){var uid=this.get_single_uid();if(uid&&this.env.contentframe&&!this.drag_active){this.show_message(uid,false,true)}else{if(this.env.contentframe){this.show_contentframe(false)}}};this.msglist_expand=function(row){if(this.env.messages[row.uid]){this.env.messages[row.uid].expanded=row.expanded}$(row.obj)[row.expanded?"addClass":"removeClass"]("expanded")};this.msglist_set_coltypes=function(list){var i,found,name,cols=list.list.tHead.rows[0].cells;this.env.coltypes=[];for(i=0;i<cols.length;i++){if(cols[i].id&&cols[i].id.match(/^rcm/)){name=cols[i].id.replace(/^rcm/,"");this.env.coltypes.push(name)}}if((found=$.inArray("flag",this.env.coltypes))>=0){this.env.flagged_col=found}if((found=$.inArray("subject",this.env.coltypes))>=0){this.env.subject_col=found}this.command("save-pref",{name:"list_cols",value:this.env.coltypes,session:"list_attrib/columns"})};this.check_droptarget=function(id){if(this.task=="mail"){return(this.env.mailboxes[id]&&this.env.mailboxes[id].id!=this.env.mailbox&&!this.env.mailboxes[id].virtual)?1:0}if(this.task=="settings"){return id!=this.env.mailbox?1:0}if(this.task=="addressbook"){if(id!=this.env.source&&this.env.contactfolders[id]){if(this.env.contactfolders[id].type=="group"){var target_abook=this.env.contactfolders[id].source;if(this.env.contactfolders[id].id!=this.env.group&&!this.env.contactfolders[target_abook].readonly){return(this.env.selection_sources.length>1||$.inArray(target_abook,this.env.selection_sources)==-1)?2:1}}else{if(!this.env.contactfolders[id].readonly){return(this.env.selection_sources.length>1||$.inArray(id,this.env.selection_sources)==-1)?2:0}}}}return 0};this.open_window=function(url,width){var win=this.is_framed()?parent.window:window,page=$(win),page_width=page.width(),page_height=bw.mz?$("body",win).height():page.height(),w=Math.min(width,page_width),h=page_height,l=(win.screenLeft||win.screenX)+20,t=(win.screenTop||win.screenY)+20,wname="rcmextwin"+new Date().getTime(),extwin=window.open(url+(url.match(/\?/)?"&":"?")+"_extwin=1",wname,"width="+w+",height="+h+",top="+t+",left="+l+",resizable=yes,toolbar=no,status=no,location=no");if(!url&&extwin.document){extwin.document.write("<html><body>"+this.get_label("loading")+"</body></html>")}window.setTimeout(function(){extwin.focus()},10);return wname};this.init_message_row=function(row){var expando,self=this,uid=row.uid,status_icon=(this.env.status_col!=null?"status":"msg")+"icn"+row.uid;if(uid&&this.env.messages[uid]){$.extend(row,this.env.messages[uid])}if(row.icon=document.getElementById(status_icon)){row.icon._row=row.obj;row.icon.onmousedown=function(e){self.command("toggle_status",this);rcube_event.cancel(e)}}if(this.env.status_col!=null){row.msgicon=document.getElementById("msgicn"+row.uid)}else{row.msgicon=row.icon}if(this.env.flagged_col!=null&&(row.flagicon=document.getElementById("flagicn"+row.uid))){row.flagicon._row=row.obj;row.flagicon.onmousedown=function(e){self.command("toggle_flag",this);rcube_event.cancel(e)}}if(!row.depth&&row.has_children&&(expando=document.getElementById("rcmexpando"+row.uid))){row.expando=expando;expando.onmousedown=function(e){return self.expand_message_row(e,uid)};if(bw.touch){expando.addEventListener("touchend",function(e){if(e.changedTouches.length==1){self.expand_message_row(e,uid);return rcube_event.cancel(e)}},false)}}this.triggerEvent("insertrow",{uid:uid,row:row})};this.add_message_row=function(uid,cols,flags,attop){if(!this.gui_objects.messagelist||!this.message_list){return false}if(flags.mbox!=this.env.mailbox&&!flags.skip_mbox_check){return false}if(!this.env.messages[uid]){this.env.messages[uid]={}}$.extend(this.env.messages[uid],{deleted:flags.deleted?1:0,replied:flags.answered?1:0,unread:!flags.seen?1:0,forwarded:flags.forwarded?1:0,flagged:flags.flagged?1:0,has_children:flags.has_children?1:0,depth:flags.depth?flags.depth:0,unread_children:flags.unread_children?flags.unread_children:0,parent_uid:flags.parent_uid?flags.parent_uid:0,selected:this.select_all_mode||this.message_list.in_selection(uid),ml:flags.ml?1:0,ctype:flags.ctype,flags:flags.extra_flags});var c,n,col,html,css_class,tree="",expando="",list=this.message_list,rows=list.rows,message=this.env.messages[uid],row_class="message"+(!flags.seen?" unread":"")+(flags.deleted?" deleted":"")+(flags.flagged?" flagged":"")+(message.selected?" selected":""),row=document.createElement("tr");row.id="rcmrow"+uid;css_class="msgicon";if(this.env.status_col===null){css_class+=" status";if(flags.deleted){css_class+=" deleted"}else{if(!flags.seen){css_class+=" unread"}else{if(flags.unread_children>0){css_class+=" unreadchildren"}}}}if(flags.answered){css_class+=" replied"}if(flags.forwarded){css_class+=" forwarded"}if(message.selected&&!list.in_selection(uid)){list.selection.push(uid)}if(this.env.threading){if(message.depth){tree+='<span id="rcmtab'+uid+'" class="branch" style="width:'+(message.depth*15)+'px;">&nbsp;&nbsp;</span>';if((rows[message.parent_uid]&&rows[message.parent_uid].expanded===false)||((this.env.autoexpand_threads==0||this.env.autoexpand_threads==2)&&(!rows[message.parent_uid]||!rows[message.parent_uid].expanded))){row.style.display="none";message.expanded=false}else{message.expanded=true}row_class+=" thread expanded"}else{if(message.has_children){if(message.expanded===undefined&&(this.env.autoexpand_threads==1||(this.env.autoexpand_threads==2&&message.unread_children))){message.expanded=true}expando='<div id="rcmexpando'+uid+'" class="'+(message.expanded?"expanded":"collapsed")+'">&nbsp;&nbsp;</div>';row_class+=" thread"+(message.expanded?" expanded":"")}}if(flags.unread_children&&flags.seen&&!message.expanded){row_class+=" unroot"}}tree+='<span id="msgicn'+uid+'" class="'+css_class+'">&nbsp;</span>';row.className=row_class;if(!bw.ie&&cols.subject){var action=flags.mbox==this.env.drafts_mailbox?"compose":"show";var uid_param=flags.mbox==this.env.drafts_mailbox?"_draft_uid":"_uid";cols.subject='<a href="./?_task=mail&_action='+action+"&_mbox="+urlencode(flags.mbox)+"&"+uid_param+"="+uid+'" onclick="return rcube_event.cancel(event)" onmouseover="rcube_webmail.long_subject_title(this,'+(message.depth+1)+')">'+cols.subject+"</a>"}for(n in this.env.coltypes){c=this.env.coltypes[n];col=document.createElement("td");col.className=String(c).toLowerCase();if(c=="flag"){css_class=(flags.flagged?"flagged":"unflagged");html='<span id="flagicn'+uid+'" class="'+css_class+'">&nbsp;</span>'}else{if(c=="attachment"){if(/application\/|multipart\/(m|signed)/.test(flags.ctype)){html='<span class="attachment">&nbsp;</span>'}else{if(/multipart\/report/.test(flags.ctype)){html='<span class="report">&nbsp;</span>'}else{html="&nbsp;"}}}else{if(c=="status"){if(flags.deleted){css_class="deleted"}else{if(!flags.seen){css_class="unread"}else{if(flags.unread_children>0){css_class="unreadchildren"}else{css_class="msgicon"}}}html='<span id="statusicn'+uid+'" class="'+css_class+'">&nbsp;</span>'}else{if(c=="threads"){html=expando}else{if(c=="subject"){if(bw.ie){col.onmouseover=function(){rcube_webmail.long_subject_title_ex(this,message.depth+1)};if(bw.ie8){tree="<span></span>"+tree}}html=tree+cols[c]}else{if(c=="priority"){if(flags.prio>0&&flags.prio<6){html='<span class="prio'+flags.prio+'">&nbsp;</span>'}else{html="&nbsp;"}}else{html=cols[c]}}}}}}if(html){col.innerHTML=html}row.appendChild(col)}list.insert_row(row,attop);if(attop&&this.env.pagesize&&list.rowcount>this.env.pagesize){var uid=list.get_last_row();list.remove_row(uid);list.clear_selection(uid)}};this.set_list_sorting=function(sort_col,sort_order){$("#rcm"+this.env.sort_col).removeClass("sorted"+(this.env.sort_order.toUpperCase()));if(sort_col){$("#rcm"+sort_col).addClass("sorted"+sort_order)}this.env.sort_col=sort_col;this.env.sort_order=sort_order};this.set_list_options=function(cols,sort_col,sort_order,threads){var update,post_data={};if(sort_col===undefined){sort_col=this.env.sort_col}if(!sort_order){sort_order=this.env.sort_order}if(this.env.sort_col!=sort_col||this.env.sort_order!=sort_order){update=1;this.set_list_sorting(sort_col,sort_order)}if(this.env.threading!=threads){update=1;post_data._threads=threads}if(cols&&cols.length){var i,idx,name,newcols=[],oldcols=this.env.coltypes;for(i=0;i<oldcols.length;i++){name=oldcols[i];idx=$.inArray(name,cols);if(idx!=-1){newcols.push(name);delete cols[idx]}}for(i=0;i<cols.length;i++){if(cols[i]){newcols.push(cols[i])}}if(newcols.join()!=oldcols.join()){update=1;post_data._cols=newcols.join(",")}}if(update){this.list_mailbox("","",sort_col+"_"+sort_order,post_data)}};this.show_message=function(id,safe,preview){if(!id){return}var win,target=window,action=preview?"preview":"show",url="&_action="+action+"&_uid="+id+"&_mbox="+urlencode(this.env.mailbox);if(preview&&(win=this.get_frame_window(this.env.contentframe))){target=win;url+="&_framed=1"}if(safe){url+="&_safe=1"}if(this.env.search_request){url+="&_search="+this.env.search_request}url+="&_caps="+urlencode(this.browser_capabilities());if(this.env.extwin){url+="&_extwin=1"}if(preview&&String(target.location.href).indexOf(url)>=0){this.show_contentframe(true)}else{if(!preview&&this.env.message_extwin&&!this.env.extwin){this.open_window(this.env.comm_path+url,1000)}else{this.location_href(this.env.comm_path+url,target,true)}if(preview&&this.message_list&&this.message_list.rows[id]&&this.message_list.rows[id].unread&&this.env.preview_pane_mark_read>=0){this.preview_read_timer=setTimeout(function(){ref.set_message(id,"unread",false);ref.update_thread_root(id,"read");if(ref.env.unread_counts[ref.env.mailbox]){ref.env.unread_counts[ref.env.mailbox]-=1;ref.set_unread_count(ref.env.mailbox,ref.env.unread_counts[ref.env.mailbox],ref.env.mailbox=="INBOX")}if(ref.env.preview_pane_mark_read>0){ref.http_post("mark",{_uid:id,_flag:"read",_quiet:1})}},this.env.preview_pane_mark_read*1000)}}};this.show_contentframe=function(show){var frame,win,name=this.env.contentframe;if(name&&(frame=this.get_frame_element(name))){if(!show&&(win=this.get_frame_window(name))){if(win.location&&win.location.href.indexOf(this.env.blankpage)<0){win.location.href=this.env.blankpage}}else{if(!bw.safari&&!bw.konq){$(frame)[show?"show":"hide"]()}}}if(!show&&this.busy){this.set_busy(false,null,this.env.frame_lock)}};this.get_frame_element=function(id){var frame;if(id&&(frame=document.getElementById(id))){return frame}};this.get_frame_window=function(id){var frame=this.get_frame_element(id);if(frame&&frame.name&&window.frames){return window.frames[frame.name]}};this.lock_frame=function(){if(!this.env.frame_lock){(this.is_framed()?parent.rcmail:this).env.frame_lock=this.set_busy(true,"loading")}};this.list_page=function(page){if(page=="next"){page=this.env.current_page+1}else{if(page=="last"){page=this.env.pagecount}else{if(page=="prev"&&this.env.current_page>1){page=this.env.current_page-1}else{if(page=="first"&&this.env.current_page>1){page=1}}}}if(page>0&&page<=this.env.pagecount){this.env.current_page=page;if(this.task=="addressbook"||this.contact_list){this.list_contacts(this.env.source,this.env.group,page)}else{if(this.task=="mail"){this.list_mailbox(this.env.mailbox,page)}}}};this.checkmail=function(){var lock=this.set_busy(true,"checkingmail"),params=this.check_recent_params();this.http_request("check-recent",params,lock)};this.filter_mailbox=function(filter){var lock=this.set_busy(true,"searching");this.clear_message_list();this.env.current_page=1;this.http_request("search",this.search_params(false,filter),lock)};this.list_mailbox=function(mbox,page,sort,url){var win,target=window;if(typeof url!="object"){url={}}if(!mbox){mbox=this.env.mailbox?this.env.mailbox:"INBOX"}if(sort){url._sort=sort}if(this.env.search_request){url._search=this.env.search_request}if(this.env.mailbox!=mbox){page=1;this.env.current_page=page;this.select_all_mode=false}this.clear_message_list();if(mbox!=this.env.mailbox||(mbox==this.env.mailbox&&!page&&!sort)){url._refresh=1}this.select_folder(mbox,"",true);this.unmark_folder(mbox,"recent","",true);this.env.mailbox=mbox;if(this.gui_objects.messagelist){this.list_mailbox_remote(mbox,page,url);return}if(win=this.get_frame_window(this.env.contentframe)){target=win;url._framed=1}if(mbox){this.set_busy(true,"loading");url._mbox=mbox;if(page){url._page=page}this.location_href(url,target)}};this.clear_message_list=function(){this.env.messages={};this.last_selected=0;this.show_contentframe(false);if(this.message_list){this.message_list.clear(true)}};this.list_mailbox_remote=function(mbox,page,post_data){this.message_list.clear();var lock=this.set_busy(true,"loading");if(typeof post_data!="object"){post_data={}}post_data._mbox=mbox;if(page){post_data._page=page}this.http_request("list",post_data,lock)};this.update_selection=function(){var selected=this.message_list.selection,rows=this.message_list.rows,i,selection=[];for(i in selected){if(rows[selected[i]]){selection.push(selected[i])}}this.message_list.selection=selection};this.expand_unread=function(){var r,tbody=this.gui_objects.messagelist.tBodies[0],new_row=tbody.firstChild;while(new_row){if(new_row.nodeType==1&&(r=this.message_list.rows[new_row.uid])&&r.unread_children){this.message_list.expand_all(r);this.set_unread_children(r.uid)}new_row=new_row.nextSibling}return false};this.expand_message_row=function(e,uid){var row=this.message_list.rows[uid];row.expanded=!row.expanded;this.set_unread_children(uid);row.expanded=!row.expanded;this.message_list.expand_row(e,uid)};this.expand_threads=function(){if(!this.env.threading||!this.env.autoexpand_threads||!this.message_list){return}switch(this.env.autoexpand_threads){case 2:this.expand_unread();break;case 1:this.message_list.expand_all();break}};this.init_threads=function(roots,mbox){if(mbox&&mbox!=this.env.mailbox){return false}for(var n=0,len=roots.length;n<len;n++){this.add_tree_icons(roots[n])}this.expand_threads()};this.add_tree_icons=function(root){var i,l,r,n,len,pos,tmp=[],uid=[],row,rows=this.message_list.rows;if(root){row=rows[root]?rows[root].obj:null}else{row=this.message_list.list.tBodies[0].firstChild}while(row){if(row.nodeType==1&&(r=rows[row.uid])){if(r.depth){for(i=tmp.length-1;i>=0;i--){len=tmp[i].length;if(len>r.depth){pos=len-r.depth;if(!(tmp[i][pos]&2)){tmp[i][pos]=tmp[i][pos]?tmp[i][pos]+2:2}}else{if(len==r.depth){if(!(tmp[i][0]&2)){tmp[i][0]+=2}}}if(r.depth>len){break}}tmp.push(new Array(r.depth));tmp[tmp.length-1][0]=1;uid.push(r.uid)}else{if(tmp.length){for(i in tmp){this.set_tree_icons(uid[i],tmp[i])}tmp=[];uid=[]}if(root&&row!=rows[root].obj){break}}}row=row.nextSibling}if(tmp.length){for(i in tmp){this.set_tree_icons(uid[i],tmp[i])}}};this.set_tree_icons=function(uid,tree){var i,divs=[],html="",len=tree.length;for(i=0;i<len;i++){if(tree[i]>2){divs.push({"class":"l3",width:15})}else{if(tree[i]>1){divs.push({"class":"l2",width:15})}else{if(tree[i]>0){divs.push({"class":"l1",width:15})}else{if(divs.length&&!divs[divs.length-1]["class"]){divs[divs.length-1].width+=15}else{divs.push({"class":null,width:15})}}}}}for(i=divs.length-1;i>=0;i--){if(divs[i]["class"]){html+='<div class="tree '+divs[i]["class"]+'" />'}else{html+='<div style="width:'+divs[i].width+'px" />'}}if(html){$("#rcmtab"+uid).html(html)}};this.update_thread_root=function(uid,flag){if(!this.env.threading){return}var root=this.message_list.find_root(uid);if(uid==root){return}var p=this.message_list.rows[root];if(flag=="read"&&p.unread_children){p.unread_children--}else{if(flag=="unread"&&p.has_children){p.unread_children=p.unread_children?p.unread_children+1:1}else{return}}this.set_message_icon(root);this.set_unread_children(root)};this.update_thread=function(uid){if(!this.env.threading){return 0}var r,parent,count=0,rows=this.message_list.rows,row=rows[uid],depth=rows[uid].depth,roots=[];if(!row.depth){count--}else{if(row.unread){parent=this.message_list.find_root(uid);rows[parent].unread_children--;this.set_unread_children(parent)}}parent=row.parent_uid;row=row.obj.nextSibling;while(row){if(row.nodeType==1&&(r=rows[row.uid])){if(!r.depth||r.depth<=depth){break}r.depth--;$("#rcmtab"+r.uid).width(r.depth*15).html("");if(!r.depth){count++;r.parent_uid=0;if(r.has_children){$("#rcmrow"+r.uid+" .leaf:first").attr("id","rcmexpando"+r.uid).attr("class",(r.obj.style.display!="none"?"expanded":"collapsed")).bind("mousedown",{uid:r.uid,p:this},function(e){return e.data.p.expand_message_row(e,e.data.uid)});r.unread_children=0;roots.push(r)}if(r.obj.style.display=="none"){$(r.obj).show()}}else{if(r.depth==depth){r.parent_uid=parent}if(r.unread&&roots.length){roots[roots.length-1].unread_children++}}}row=row.nextSibling}for(var i=0;i<roots.length;i++){this.set_unread_children(roots[i].uid)}return count};this.delete_excessive_thread_rows=function(){var rows=this.message_list.rows,tbody=this.message_list.list.tBodies[0],row=tbody.firstChild,cnt=this.env.pagesize+1;while(row){if(row.nodeType==1&&(r=rows[row.uid])){if(!r.depth&&cnt){cnt--}if(!cnt){this.message_list.remove_row(row.uid)}}row=row.nextSibling}};this.set_message_icon=function(uid){var css_class,row=this.message_list.rows[uid];if(!row){return false}if(row.icon){css_class="msgicon";if(row.deleted){css_class+=" deleted"}else{if(row.unread){css_class+=" unread"}else{if(row.unread_children){css_class+=" unreadchildren"}}}if(row.msgicon==row.icon){if(row.replied){css_class+=" replied"}if(row.forwarded){css_class+=" forwarded"}css_class+=" status"}row.icon.className=css_class}if(row.msgicon&&row.msgicon!=row.icon){css_class="msgicon";if(!row.unread&&row.unread_children){css_class+=" unreadchildren"}if(row.replied){css_class+=" replied"}if(row.forwarded){css_class+=" forwarded"}row.msgicon.className=css_class}if(row.flagicon){css_class=(row.flagged?"flagged":"unflagged");row.flagicon.className=css_class}};this.set_message_status=function(uid,flag,status){var row=this.message_list.rows[uid];if(!row){return false}if(flag=="unread"){row.unread=status}else{if(flag=="deleted"){row.deleted=status}else{if(flag=="replied"){row.replied=status}else{if(flag=="forwarded"){row.forwarded=status}else{if(flag=="flagged"){row.flagged=status}}}}}};this.set_message=function(uid,flag,status){var row=this.message_list&&this.message_list.rows[uid];if(!row){return false}if(flag){this.set_message_status(uid,flag,status)}var rowobj=$(row.obj);if(row.unread&&!rowobj.hasClass("unread")){rowobj.addClass("unread")}else{if(!row.unread&&rowobj.hasClass("unread")){rowobj.removeClass("unread")}}if(row.deleted&&!rowobj.hasClass("deleted")){rowobj.addClass("deleted")}else{if(!row.deleted&&rowobj.hasClass("deleted")){rowobj.removeClass("deleted")}}if(row.flagged&&!rowobj.hasClass("flagged")){rowobj.addClass("flagged")}else{if(!row.flagged&&rowobj.hasClass("flagged")){rowobj.removeClass("flagged")}}this.set_unread_children(uid);this.set_message_icon(uid)};this.set_unread_children=function(uid){var row=this.message_list.rows[uid];if(row.parent_uid){return}if(!row.unread&&row.unread_children&&!row.expanded){$(row.obj).addClass("unroot")}else{$(row.obj).removeClass("unroot")}};this.copy_messages=function(mbox){if(mbox&&typeof mbox==="object"){mbox=mbox.id}if(!mbox||mbox==this.env.mailbox){return}var post_data=this.selection_post_data({_target_mbox:mbox});if(!post_data._uid){return}this.http_post("copy",post_data,this.display_message(this.get_label("copyingmessage"),"loading"))};this.move_messages=function(mbox){if(mbox&&typeof mbox==="object"){mbox=mbox.id}if(!mbox||mbox==this.env.mailbox){return}var lock=false,post_data=this.selection_post_data({_target_mbox:mbox});if(!post_data._uid){return}if(this.env.action=="show"){lock=this.set_busy(true,"movingmessage")}else{this.show_contentframe(false)}this.enable_command(this.env.message_commands,false);this._with_selected_messages("moveto",post_data,lock)};this.delete_messages=function(event){var uid,i,len,trash=this.env.trash_mailbox,list=this.message_list,selection=list?list.get_selection():[];if(!this.env.uid&&!selection.length){return}for(i=0,len=selection.length;i<len;i++){uid=selection[i];if(list.rows[uid].has_children&&!list.rows[uid].expanded){list.select_children(uid)}}if(this.env.flag_for_deletion){this.mark_message("delete");return false}else{if(!trash||this.env.mailbox==trash){this.permanently_remove_messages()}else{if(this.env.delete_junk&&this.env.junk_mailbox&&this.env.mailbox==this.env.junk_mailbox){this.permanently_remove_messages()}else{if((list&&list.modkey==SHIFT_KEY)||(event&&rcube_event.get_modifier(event)==SHIFT_KEY)){if(confirm(this.get_label("deletemessagesconfirm"))){this.permanently_remove_messages()}}else{this.move_messages(trash)}}}}return true};this.permanently_remove_messages=function(){var post_data=this.selection_post_data();if(!post_data._uid){return}this.show_contentframe(false);this._with_selected_messages("delete",post_data)};this._with_selected_messages=function(action,post_data,lock){var count=0,msg;if(this.message_list){var n,id,root,roots=[],selection=this.message_list.get_selection();for(n=0,len=selection.length;n<len;n++){id=selection[n];if(this.env.threading){count+=this.update_thread(id);root=this.message_list.find_root(id);if(root!=id&&$.inArray(root,roots)<0){roots.push(root)}}this.message_list.remove_row(id,(this.env.display_next&&n==selection.length-1))}if(!this.env.display_next){this.message_list.clear_selection()}for(n=0,len=roots.length;n<len;n++){this.add_tree_icons(roots[n])}}if(this.env.display_next&&this.env.next_uid){post_data._next_uid=this.env.next_uid}if(count<0){post_data._count=(count*-1)}else{if(count>0){this.delete_excessive_thread_rows()}}if(!lock){msg=action=="moveto"?"movingmessage":"deletingmessage";lock=this.display_message(this.get_label(msg),"loading")}this.http_post(action,post_data,lock)};this.selection_post_data=function(data){if(typeof(data)!="object"){data={}}data._mbox=this.env.mailbox;if(!data._uid){var uids=this.env.uid?[this.env.uid]:this.message_list.get_selection();data._uid=this.uids_to_list(uids)}if(this.env.action){data._from=this.env.action}if(this.env.search_request){data._search=this.env.search_request}return data};this.mark_message=function(flag,uid){var a_uids=[],r_uids=[],len,n,id,list=this.message_list;if(uid){a_uids[0]=uid}else{if(this.env.uid){a_uids[0]=this.env.uid}else{if(list){a_uids=list.get_selection()}}}if(!list){r_uids=a_uids}else{list.focus();for(n=0,len=a_uids.length;n<len;n++){id=a_uids[n];if((flag=="read"&&list.rows[id].unread)||(flag=="unread"&&!list.rows[id].unread)||(flag=="delete"&&!list.rows[id].deleted)||(flag=="undelete"&&list.rows[id].deleted)||(flag=="flagged"&&!list.rows[id].flagged)||(flag=="unflagged"&&list.rows[id].flagged)){r_uids.push(id)}}}if(!r_uids.length&&!this.select_all_mode){return}switch(flag){case"read":case"unread":this.toggle_read_status(flag,r_uids);break;case"delete":case"undelete":this.toggle_delete_status(r_uids);break;case"flagged":case"unflagged":this.toggle_flagged_status(flag,a_uids);break}};this.toggle_read_status=function(flag,a_uids){var i,len=a_uids.length,post_data=this.selection_post_data({_uid:this.uids_to_list(a_uids),_flag:flag}),lock=this.display_message(this.get_label("markingmessage"),"loading");for(i=0;i<len;i++){this.set_message(a_uids[i],"unread",(flag=="unread"?true:false))}this.http_post("mark",post_data,lock);for(i=0;i<len;i++){this.update_thread_root(a_uids[i],flag)}};this.toggle_flagged_status=function(flag,a_uids){var i,len=a_uids.length,post_data=this.selection_post_data({_uid:this.uids_to_list(a_uids),_flag:flag}),lock=this.display_message(this.get_label("markingmessage"),"loading");for(i=0;i<len;i++){this.set_message(a_uids[i],"flagged",(flag=="flagged"?true:false))}this.http_post("mark",post_data,lock)};this.toggle_delete_status=function(a_uids){var len=a_uids.length,i,uid,all_deleted=true,rows=this.message_list?this.message_list.rows:[];if(len==1){if(!rows.length||(rows[a_uids[0]]&&!rows[a_uids[0]].deleted)){this.flag_as_deleted(a_uids)}else{this.flag_as_undeleted(a_uids)}return true}for(i=0;i<len;i++){uid=a_uids[i];if(rows[uid]&&!rows[uid].deleted){all_deleted=false;break}}if(all_deleted){this.flag_as_undeleted(a_uids)}else{this.flag_as_deleted(a_uids)}return true};this.flag_as_undeleted=function(a_uids){var i,len=a_uids.length,post_data=this.selection_post_data({_uid:this.uids_to_list(a_uids),_flag:"undelete"}),lock=this.display_message(this.get_label("markingmessage"),"loading");for(i=0;i<len;i++){this.set_message(a_uids[i],"deleted",false)}this.http_post("mark",post_data,lock)};this.flag_as_deleted=function(a_uids){var r_uids=[],post_data=this.selection_post_data({_uid:this.uids_to_list(a_uids),_flag:"delete"}),lock=this.display_message(this.get_label("markingmessage"),"loading"),rows=this.message_list?this.message_list.rows:[],count=0;for(var i=0,len=a_uids.length;i<len;i++){uid=a_uids[i];if(rows[uid]){if(rows[uid].unread){r_uids[r_uids.length]=uid}if(this.env.skip_deleted){count+=this.update_thread(uid);this.message_list.remove_row(uid,(this.env.display_next&&i==this.message_list.selection.length-1))}else{this.set_message(uid,"deleted",true)}}}if(this.env.skip_deleted&&this.message_list){if(!this.env.display_next){this.message_list.clear_selection()}if(count<0){post_data._count=(count*-1)}else{if(count>0){this.delete_excessive_thread_rows()}}}if(r_uids.length){post_data._ruid=this.uids_to_list(r_uids)}if(this.env.skip_deleted&&this.env.display_next&&this.env.next_uid){post_data._next_uid=this.env.next_uid}this.http_post("mark",post_data,lock)};this.flag_deleted_as_read=function(uids){var icn_src,uid,i,len,rows=this.message_list?this.message_list.rows:[];uids=String(uids).split(",");for(i=0,len=uids.length;i<len;i++){uid=uids[i];if(rows[uid]){this.set_message(uid,"unread",false)}}};this.uids_to_list=function(uids){return this.select_all_mode?"*":uids.join(",")};this.set_button_titles=function(){var label="deletemessage";if(!this.env.flag_for_deletion&&this.env.trash_mailbox&&this.env.mailbox!=this.env.trash_mailbox&&(!this.env.delete_junk||!this.env.junk_mailbox||this.env.mailbox!=this.env.junk_mailbox)){label="movemessagetotrash"}this.set_alttext("delete",label)};this.expunge_mailbox=function(mbox){var lock,post_data={_mbox:mbox};if(mbox==this.env.mailbox){lock=this.set_busy(true,"loading");post_data._reload=1;if(this.env.search_request){post_data._search=this.env.search_request}}this.http_post("expunge",post_data,lock)};this.purge_mailbox=function(mbox){var lock,post_data={_mbox:mbox};if(!confirm(this.get_label("purgefolderconfirm"))){return false}if(mbox==this.env.mailbox){lock=this.set_busy(true,"loading");post_data._reload=1}this.http_post("purge",post_data,lock)};this.purge_mailbox_test=function(){return(this.env.exists&&(this.env.mailbox==this.env.trash_mailbox||this.env.mailbox==this.env.junk_mailbox||this.env.mailbox.match("^"+RegExp.escape(this.env.trash_mailbox)+RegExp.escape(this.env.delimiter))||this.env.mailbox.match("^"+RegExp.escape(this.env.junk_mailbox)+RegExp.escape(this.env.delimiter))))};this.login_user_keyup=function(e){var key=rcube_event.get_keycode(e);var passwd=$("#rcmloginpwd");if(key==13&&passwd.length&&!passwd.val()){passwd.focus();return rcube_event.cancel(e)}return true};this.open_compose_step=function(p){var url=this.url("mail/compose",p);if(this.env.compose_extwin&&!this.env.extwin){this.open_window(url,1150)}else{this.redirect(url);if(this.env.extwin){window.resizeTo(Math.max(1150,$(window).width()),$(window).height()+24)}}};this.init_messageform=function(){if(!this.gui_objects.messageform){return false}var input_from=$("[name='_from']"),input_to=$("[name='_to']"),input_subject=$("input[name='_subject']"),input_message=$("[name='_message']").get(0),html_mode=$("input[name='_is_html']").val()=="1",ac_fields=["cc","bcc","replyto","followupto"],ac_props,opener_rc=this.opener();if(opener_rc&&opener_rc.env.action=="compose"){setTimeout(function(){opener.history.back()},100);this.env.opened_extwin=true}if(this.env.autocomplete_threads>0){ac_props={threads:this.env.autocomplete_threads,sources:this.env.autocomplete_sources}}this.init_address_input_events(input_to,ac_props);for(var i in ac_fields){this.init_address_input_events($("[name='_"+ac_fields[i]+"']"),ac_props)}if(!html_mode){this.set_caret_pos(input_message,this.env.top_posting?0:$(input_message).val().length);if(input_from.prop("type")=="select-one"){this.change_identity(input_from[0])}}if(input_to.val()==""){input_to.focus()}else{if(input_subject.val()==""){input_subject.focus()}else{if(input_message){input_message.focus()}}}this.env.compose_focus_elem=document.activeElement;this.compose_field_hash(true);this.auto_save_start()};this.init_address_input_events=function(obj,props){this.env.recipients_delimiter=this.env.recipients_separator+" ";obj[bw.ie||bw.safari||bw.chrome?"keydown":"keypress"](function(e){return ref.ksearch_keydown(e,this,props)}).attr("autocomplete","off")};this.submit_messageform=function(draft){var form=this.gui_objects.messageform;if(!form){return}var msgid=this.set_busy(true,draft?"savingmessage":"sendingmessage"),lang=this.spellcheck_lang(),files=[];$("li",this.gui_objects.attachmentlist).each(function(){files.push(this.id.replace(/^rcmfile/,""))});$('input[name="_attachments"]',form).val(files.join());form.target="savetarget";form._draft.value=draft?"1":"";form.action=this.add_url(form.action,"_unlock",msgid);form.action=this.add_url(form.action,"_lang",lang);this.submit_timer=setTimeout(function(){ref.set_busy(false,null,msgid);ref.display_message(ref.get_label("requesttimedout"),"error")},this.env.request_timeout*1000);form.submit()};this.compose_recipient_select=function(list){this.enable_command("add-recipient",list.selection.length>0)};this.compose_add_recipient=function(field){var recipients=[],input=$("#_"+field),delim=this.env.recipients_delimiter;if(this.contact_list&&this.contact_list.selection.length){for(var id,n=0;n<this.contact_list.selection.length;n++){id=this.contact_list.selection[n];if(id&&this.env.contactdata[id]){recipients.push(this.env.contactdata[id]);if(id.charAt(0)=="E"&&this.env.contactdata[id].indexOf("@")<0&&input.length){var gid=id.substr(1);this.group2expand[gid]={name:this.env.contactdata[id],input:input.get(0)};this.http_request("group-expand",{_source:this.env.source,_gid:gid},false)}}}}if(recipients.length&&input.length){var oldval=input.val(),rx=new RegExp(RegExp.escape(delim)+"\\s*$");if(oldval&&!rx.test(oldval)){oldval+=delim+" "}input.val(oldval+recipients.join(delim+" ")+delim+" ");this.triggerEvent("add-recipient",{field:field,recipients:recipients})}};this.check_compose_input=function(cmd){var ed,input_to=$("[name='_to']"),input_cc=$("[name='_cc']"),input_bcc=$("[name='_bcc']"),input_from=$("[name='_from']"),input_subject=$("[name='_subject']"),input_message=$("[name='_message']");if(input_from.prop("type")=="text"&&!rcube_check_email(input_from.val(),true)){alert(this.get_label("nosenderwarning"));input_from.focus();return false}var recipients=input_to.val()?input_to.val():(input_cc.val()?input_cc.val():input_bcc.val());if(!rcube_check_email(recipients.replace(/^\s+/,"").replace(/[\s,;]+$/,""),true)){alert(this.get_label("norecipientwarning"));input_to.focus();return false}for(var key in this.env.attachments){if(typeof this.env.attachments[key]==="object"&&!this.env.attachments[key].complete){alert(this.get_label("notuploadedwarning"));return false}}if(input_subject.val()==""){var myprompt=$('<div class="prompt">').html('<div class="message">'+this.get_label("nosubjectwarning")+"</div>").appendTo(document.body);var prompt_value=$("<input>").attr("type","text").attr("size",30).appendTo(myprompt).val(this.get_label("nosubject"));var buttons={};buttons[this.get_label("cancel")]=function(){input_subject.focus();$(this).dialog("close")};buttons[this.get_label("sendmessage")]=function(){input_subject.val(prompt_value.val());$(this).dialog("close");ref.command(cmd,{nocheck:true})};myprompt.dialog({modal:true,resizable:false,buttons:buttons,close:function(event,ui){$(this).remove()}});prompt_value.select();return false}this.stop_spellchecking();if(window.tinyMCE){ed=tinyMCE.get(this.env.composebody)}if(!ed&&input_message.val()==""&&!confirm(this.get_label("nobodywarning"))){input_message.focus();return false}else{if(ed){if(!ed.getContent()&&!confirm(this.get_label("nobodywarning"))){ed.focus();return false}tinyMCE.triggerSave()}}return true};this.toggle_editor=function(props){this.stop_spellchecking();if(props.mode=="html"){this.plain2html($("#"+props.id).val(),props.id);tinyMCE.execCommand("mceAddControl",false,props.id);if(this.env.default_font){setTimeout(function(){$(tinyMCE.get(props.id).getBody()).css("font-family",rcmail.env.default_font)},500)}}else{var thisMCE=tinyMCE.get(props.id),existingHtml;if(existingHtml=thisMCE.getContent()){if(!confirm(this.get_label("editorwarning"))){return false}this.html2plain(existingHtml,props.id)}tinyMCE.execCommand("mceRemoveControl",false,props.id)}return true};this.stop_spellchecking=function(){var ed;if(window.tinyMCE&&(ed=tinyMCE.get(this.env.composebody))){if(ed.plugins&&ed.plugins.spellchecker&&ed.plugins.spellchecker.active){ed.execCommand("mceSpellCheck")}}else{if(ed=this.env.spellcheck){if(ed.state&&ed.state!="ready"&&ed.state!="no_error_found"){$(ed.spell_span).trigger("click")}}}this.spellcheck_state()};this.spellcheck_state=function(){var ed,active;if(window.tinyMCE&&(ed=tinyMCE.get(this.env.composebody))&&ed.plugins&&ed.plugins.spellchecker){active=ed.plugins.spellchecker.active}else{if((ed=this.env.spellcheck)&&ed.state){active=ed.state!="ready"&&ed.state!="no_error_found"}}if(rcmail.buttons.spellcheck){$("#"+rcmail.buttons.spellcheck[0].id)[active?"addClass":"removeClass"]("selected")}return active};this.spellcheck_lang=function(){var ed;if(window.tinyMCE&&(ed=tinyMCE.get(this.env.composebody))&&ed.plugins&&ed.plugins.spellchecker){return ed.plugins.spellchecker.selectedLang}else{if(this.env.spellcheck){return GOOGIE_CUR_LANG}}};this.spellcheck_lang_set=function(lang){var ed;if(window.tinyMCE&&(ed=tinyMCE.get(this.env.composebody))&&ed.plugins){ed.plugins.spellchecker.selectedLang=lang}else{if(this.env.spellcheck){this.env.spellcheck.setCurrentLanguage(lang)}}};this.spellcheck_resume=function(ishtml,data){if(ishtml){var ed=tinyMCE.get(this.env.composebody);sp=ed.plugins.spellchecker;sp.active=1;sp._markWords(data);ed.nodeChanged()}else{var sp=this.env.spellcheck;sp.prepare(false,true);sp.processData(data)}this.spellcheck_state()};this.set_draft_id=function(id){var rc;if(!this.env.draft_id&&id&&(rc=this.opener())){if(rc.env.task=="mail"&&rc.env.action==""&&rc.env.mailbox==this.env.drafts_mailbox){rc.command("checkmail")}}this.env.draft_id=id;$("input[name='_draft_saveid']").val(id)};this.auto_save_start=function(){if(this.env.draft_autosave){this.save_timer=setTimeout(function(){ref.command("savedraft")},this.env.draft_autosave*1000)}this.busy=false};this.compose_field_hash=function(save){var ed,i,val,str="",hash_fields=["to","cc","bcc","subject"];for(i=0;i<hash_fields.length;i++){if(val=$('[name="_'+hash_fields[i]+'"]').val()){str+=val+":"}}if(window.tinyMCE&&(ed=tinyMCE.get(this.env.composebody))){str+=ed.getContent()}else{str+=$("[name='_message']").val()}if(this.env.attachments){for(var upload_id in this.env.attachments){str+=upload_id}}if(save){this.cmp_hash=str}return str};this.change_identity=function(obj,show_sig){if(!obj||!obj.options){return false}if(!show_sig){show_sig=this.env.show_sig}if(!this.env.identities_initialized){this.env.identities_initialized=true;if(this.env.show_sig_later){this.env.show_sig=true}if(this.env.opened_extwin){return}}var cursor_pos,p=-1,id=obj.options[obj.selectedIndex].value,input_message=$("[name='_message']"),message=input_message.val(),is_html=($("input[name='_is_html']").val()=="1"),sig=this.env.identity;if(this.env.signatures&&this.env.signatures[id]){this.enable_command("insert-sig",true);this.env.compose_commands.push("insert-sig")}else{this.enable_command("insert-sig",false)}if(!is_html){if(show_sig&&sig&&this.env.signatures&&this.env.signatures[sig]){sig=this.env.signatures[sig].text;sig=sig.replace(/\r\n/g,"\n");p=this.env.top_posting?message.indexOf(sig):message.lastIndexOf(sig);if(p>=0){message=message.substring(0,p)+message.substring(p+sig.length,message.length)}}if(show_sig&&this.env.signatures&&this.env.signatures[id]){sig=this.env.signatures[id].text;sig=sig.replace(/\r\n/g,"\n");if(this.env.top_posting){if(p>=0){message=message.substring(0,p)+sig+message.substring(p,message.length);cursor_pos=p-1}else{if(!message){cursor_pos=0;message="\n\n"+sig}else{if(pos=this.get_caret_pos(input_message.get(0))){message=message.substring(0,pos)+"\n"+sig+"\n\n"+message.substring(pos,message.length);cursor_pos=pos}else{cursor_pos=0;message="\n\n"+sig+"\n\n"+message.replace(/^[\r\n]+/,"")}}}}else{message=message.replace(/[\r\n]+$/,"");cursor_pos=!this.env.top_posting&&message.length?message.length+1:0;message+="\n\n"+sig}}else{cursor_pos=this.env.top_posting?0:message.length}input_message.val(message);this.set_caret_pos(input_message.get(0),cursor_pos)}else{if(show_sig&&this.env.signatures){var editor=tinyMCE.get(this.env.composebody),sigElem=editor.dom.get("_rc_sig");if(!sigElem){var body=editor.getBody(),doc=editor.getDoc();sigElem=doc.createElement("div");sigElem.setAttribute("id","_rc_sig");if(this.env.top_posting){editor.getWin().focus();var node=editor.selection.getNode();if(node.nodeName=="BODY"){body.insertBefore(sigElem,body.firstChild);body.insertBefore(doc.createElement("br"),body.firstChild)}else{body.insertBefore(sigElem,node.nextSibling);body.insertBefore(doc.createElement("br"),node.nextSibling)}}else{if(bw.ie){body.appendChild(doc.createElement("br"))}body.appendChild(sigElem)}}if(this.env.signatures[id]){sigElem.innerHTML=this.env.signatures[id].html}}}this.env.identity=id;return true};this.upload_file=function(form){if(!form){return false}var size=0,numfiles=0;$("input[type=file]",form).each(function(i,field){var files=field.files?field.files.length:(field.value?1:0);if(field.files){for(var i=0;i<files;i++){size+=field.files[i].size}}numfiles+=files});if(numfiles){if(this.env.max_filesize&&this.env.filesizeerror&&size>this.env.max_filesize){this.display_message(this.env.filesizeerror,"error");return}var frame_name=this.async_upload_form(form,"upload",function(e){var d,content="";try{if(this.contentDocument){d=this.contentDocument}else{if(this.contentWindow){d=this.contentWindow.document}}content=d.childNodes[0].innerHTML}catch(err){}if(!content.match(/add2attachment/)&&(!bw.opera||(rcmail.env.uploadframe&&rcmail.env.uploadframe==e.data.ts))){if(!content.match(/display_message/)){rcmail.display_message(rcmail.get_label("fileuploaderror"),"error")}rcmail.remove_from_attachment_list(e.data.ts)}if(bw.opera){rcmail.env.uploadframe=e.data.ts}});var content="<span>"+this.get_label("uploading"+(numfiles>1?"many":""))+"</span>",ts=frame_name.replace(/^rcmupload/,"");this.add2attachment_list(ts,{name:"",html:content,classname:"uploading",frame:frame_name,complete:false});if(this.env.upload_progress_time){this.upload_progress_start("upload",ts)}}this.gui_objects.attachmentform=form;return true};this.add2attachment_list=function(name,att,upload_id){if(!this.gui_objects.attachmentlist){return false}if(!att.complete&&ref.env.loadingicon){att.html='<img src="'+ref.env.loadingicon+'" alt="" class="uploading" />'+att.html}if(!att.complete&&att.frame){att.html='<a title="'+this.get_label("cancel")+'" onclick="return rcmail.cancel_attachment_upload(\''+name+"', '"+att.frame+'\');" href="#cancelupload" class="cancelupload">'+(this.env.cancelicon?'<img src="'+this.env.cancelicon+'" alt="" />':this.get_label("cancel"))+"</a>"+att.html}var indicator,li=$("<li>");li.attr("id",name).addClass(att.classname).html(att.html).on("mouseover",function(){rcube_webmail.long_subject_title_ex(this,0)});if(upload_id&&(indicator=document.getElementById(upload_id))){li.replaceAll(indicator)}else{li.appendTo(this.gui_objects.attachmentlist)}if(upload_id&&this.env.attachments[upload_id]){delete this.env.attachments[upload_id]}this.env.attachments[name]=att;return true};this.remove_from_attachment_list=function(name){delete this.env.attachments[name];$("#"+name).remove()};this.remove_attachment=function(name){if(name&&this.env.attachments[name]){this.http_post("remove-attachment",{_id:this.env.compose_id,_file:name})}return true};this.cancel_attachment_upload=function(name,frame_name){if(!name||!frame_name){return false}this.remove_from_attachment_list(name);$("iframe[name='"+frame_name+"']").remove();return false};this.upload_progress_start=function(action,name){setTimeout(function(){rcmail.http_request(action,{_progress:name})},this.env.upload_progress_time*1000)};this.upload_progress_update=function(param){var elem=$("#"+param.name+"> span");if(!elem.length||!param.text){return}elem.text(param.text);if(!param.done){this.upload_progress_start(param.action,param.name)}};this.add_contact=function(value){if(value){this.http_post("addcontact",{_address:value})}return true};this.qsearch=function(value){if(value!=""){var r,lock=this.set_busy(true,"searching"),url=this.search_params(value);if(this.message_list){this.clear_message_list()}else{if(this.contact_list){this.list_contacts_clear()}}if(this.env.source){url._source=this.env.source}if(this.env.group){url._gid=this.env.group}this.env.current_page=1;var action=this.env.action=="compose"&&this.contact_list?"search-contacts":"search";r=this.http_request(action,url,lock);this.env.qsearch={lock:lock,request:r}}};this.search_params=function(search,filter){var n,url={},mods_arr=[],mods=this.env.search_mods,mbox=this.env.mailbox;if(!filter&&this.gui_objects.search_filter){filter=this.gui_objects.search_filter.value}if(!search&&this.gui_objects.qsearchbox){search=this.gui_objects.qsearchbox.value}if(filter){url._filter=filter}if(search){url._q=search;if(mods&&this.message_list){mods=mods[mbox]?mods[mbox]:mods["*"]}if(mods){for(n in mods){mods_arr.push(n)}url._headers=mods_arr.join(",")}}if(mbox){url._mbox=mbox}return url};this.reset_qsearch=function(){if(this.gui_objects.qsearchbox){this.gui_objects.qsearchbox.value=""}if(this.env.qsearch){this.abort_request(this.env.qsearch)}this.env.qsearch=null;this.env.search_request=null;this.env.search_id=null};this.sent_successfully=function(type,msg,target){this.display_message(msg,type);if(this.env.extwin){var rc=this.opener();this.lock_form(this.gui_objects.messageform);if(rc){rc.display_message(msg,type);if(target&&rc.env.task=="mail"&&rc.env.action==""&&rc.env.mailbox==target){rc.command("checkmail")}}setTimeout(function(){window.close()},1000)}else{setTimeout(function(){ref.list_mailbox()},500)}};this.ksearch_keydown=function(e,obj,props){if(this.ksearch_timer){clearTimeout(this.ksearch_timer)}var highlight,key=rcube_event.get_keycode(e),mod=rcube_event.get_modifier(e);switch(key){case 38:case 40:if(!this.ksearch_visible()){break}var dir=key==38?1:0;highlight=document.getElementById("rcmksearchSelected");if(!highlight){highlight=this.ksearch_pane.__ul.firstChild}if(highlight){this.ksearch_select(dir?highlight.previousSibling:highlight.nextSibling)}return rcube_event.cancel(e);case 9:if(mod==SHIFT_KEY||!this.ksearch_visible()){this.ksearch_hide();return}case 13:if(!this.ksearch_visible()){return false}this.insert_recipient(this.ksearch_selected);this.ksearch_hide();return rcube_event.cancel(e);case 27:this.ksearch_hide();return;case 37:case 39:if(mod!=SHIFT_KEY){return}}this.ksearch_timer=setTimeout(function(){ref.ksearch_get_results(props)},200);this.ksearch_input=obj;return true};this.ksearch_visible=function(){return(this.ksearch_selected!==null&&this.ksearch_selected!==undefined&&this.ksearch_value)};this.ksearch_select=function(node){var current=$("#rcmksearchSelected");if(current[0]&&node){current.removeAttr("id").removeClass("selected")}if(node){$(node).attr("id","rcmksearchSelected").addClass("selected");this.ksearch_selected=node._rcm_id}};this.insert_recipient=function(id){if(id===null||!this.env.contacts[id]||!this.ksearch_input){return}var inp_value=this.ksearch_input.value,cpos=this.get_caret_pos(this.ksearch_input),p=inp_value.lastIndexOf(this.ksearch_value,cpos),trigger=false,insert="",pre=inp_value.substring(0,p),end=inp_value.substring(p+this.ksearch_value.length,inp_value.length);this.ksearch_destroy();if(typeof this.env.contacts[id]==="object"&&this.env.contacts[id].id){insert+=this.env.contacts[id].name+this.env.recipients_delimiter;this.group2expand[this.env.contacts[id].id]=$.extend({input:this.ksearch_input},this.env.contacts[id]);this.http_request("mail/group-expand",{_source:this.env.contacts[id].source,_gid:this.env.contacts[id].id},false)}else{if(typeof this.env.contacts[id]==="string"){insert=this.env.contacts[id]+this.env.recipients_delimiter;trigger=true}}this.ksearch_input.value=pre+insert+end;cpos=p+insert.length;if(this.ksearch_input.setSelectionRange){this.ksearch_input.setSelectionRange(cpos,cpos)}if(trigger){this.triggerEvent("autocomplete_insert",{field:this.ksearch_input,insert:insert})}};this.replace_group_recipients=function(id,recipients){if(this.group2expand[id]){this.group2expand[id].input.value=this.group2expand[id].input.value.replace(this.group2expand[id].name,recipients);this.triggerEvent("autocomplete_insert",{field:this.group2expand[id].input,insert:recipients});this.group2expand[id]=null}};this.ksearch_get_results=function(props){var inp_value=this.ksearch_input?this.ksearch_input.value:null;if(inp_value===null){return}if(this.ksearch_pane&&this.ksearch_pane.is(":visible")){this.ksearch_pane.hide()}var cpos=this.get_caret_pos(this.ksearch_input),p=inp_value.lastIndexOf(this.env.recipients_separator,cpos-1),q=inp_value.substring(p+1,cpos),min=this.env.autocomplete_min_length,ac=this.ksearch_data;q=$.trim(q);if(q==this.ksearch_value){return}this.ksearch_destroy();if(q.length&&q.length<min){if(!this.ksearch_info){this.ksearch_info=this.display_message(this.get_label("autocompletechars").replace("$min",min))}return}var old_value=this.ksearch_value;this.ksearch_value=q;if(!q.length){return}if(old_value&&old_value.length&&q.indexOf(old_value)==0&&(!ac||ac.num<=0)&&this.env.contacts&&!this.env.contacts.length){return}var i,lock,source,xhr,reqid=new Date().getTime(),post_data={_search:q,_id:reqid},threads=props&&props.threads?props.threads:1,sources=props&&props.sources?props.sources:[],action=props&&props.action?props.action:"mail/autocomplete";this.ksearch_data={id:reqid,sources:sources.slice(),action:action,locks:[],requests:[],num:sources.length};for(i=0;i<threads;i++){source=this.ksearch_data.sources.shift();if(threads>1&&source===undefined){break}post_data._source=source?source:"";lock=this.display_message(this.get_label("searching"),"loading");xhr=this.http_post(action,post_data,lock);this.ksearch_data.locks.push(lock);this.ksearch_data.requests.push(xhr)}};this.ksearch_query_results=function(results,search,reqid){if(!this.ksearch_value){return}if(this.ksearch_input&&search!=this.ksearch_value){return}var i,len,ul,li,text,init,value=this.ksearch_value,data=this.ksearch_data,maxlen=this.env.autocomplete_max?this.env.autocomplete_max:15;if(!this.ksearch_pane){ul=$("<ul>");this.ksearch_pane=$("<div>").attr("id","rcmKSearchpane").css({position:"absolute","z-index":30000}).append(ul).appendTo(document.body);this.ksearch_pane.__ul=ul[0]}ul=this.ksearch_pane.__ul;if(reqid&&this.ksearch_pane.data("reqid")==reqid){maxlen-=ul.childNodes.length}else{this.ksearch_pane.data("reqid",reqid);init=1;ul.innerHTML="";this.env.contacts=[];var pos=$(this.ksearch_input).offset();this.ksearch_pane.css({left:pos.left+"px",top:(pos.top+this.ksearch_input.offsetHeight)+"px",display:"none"})}if(results&&(len=results.length)){for(i=0;i<len&&maxlen>0;i++){text=typeof results[i]==="object"?results[i].name:results[i];li=document.createElement("LI");li.innerHTML=text.replace(new RegExp("("+RegExp.escape(value)+")","ig"),"##$1%%").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/##([^%]+)%%/g,"<b>$1</b>");li.onmouseover=function(){ref.ksearch_select(this)};li.onmouseup=function(){ref.ksearch_click(this)};li._rcm_id=this.env.contacts.length+i;ul.appendChild(li);maxlen-=1}}if(ul.childNodes.length){this.ksearch_pane.show();if(!this.env.contacts.length){$("li:first",ul).attr("id","rcmksearchSelected").addClass("selected");this.ksearch_selected=0}}if(len){this.env.contacts=this.env.contacts.concat(results)}if(data.id==reqid){data.num--;if(maxlen>0&&data.sources.length){var lock,xhr,source=data.sources.shift(),post_data;if(source){post_data={_search:value,_id:reqid,_source:source};lock=this.display_message(this.get_label("searching"),"loading");xhr=this.http_post(data.action,post_data,lock);this.ksearch_data.locks.push(lock);this.ksearch_data.requests.push(xhr)}}else{if(!maxlen){if(!this.ksearch_msg){this.ksearch_msg=this.display_message(this.get_label("autocompletemore"))}this.ksearch_abort()}}}};this.ksearch_click=function(node){if(this.ksearch_input){this.ksearch_input.focus()}this.insert_recipient(node._rcm_id);this.ksearch_hide()};this.ksearch_blur=function(){if(this.ksearch_timer){clearTimeout(this.ksearch_timer)}this.ksearch_input=null;this.ksearch_hide()};this.ksearch_hide=function(){this.ksearch_selected=null;this.ksearch_value="";if(this.ksearch_pane){this.ksearch_pane.hide()}this.ksearch_destroy()};this.ksearch_destroy=function(){this.ksearch_abort();if(this.ksearch_info){this.hide_message(this.ksearch_info)}if(this.ksearch_msg){this.hide_message(this.ksearch_msg)}this.ksearch_data=null;this.ksearch_info=null;this.ksearch_msg=null};this.ksearch_abort=function(){var i,len,ac=this.ksearch_data;if(!ac){return}for(i=0,len=ac.locks.length;i<len;i++){this.abort_request({request:ac.requests[i],lock:ac.locks[i]})}};this.contactlist_keypress=function(list){if(list.key_pressed==list.DELETE_KEY){this.command("delete")}};this.contactlist_select=function(list){if(this.preview_timer){clearTimeout(this.preview_timer)}var n,id,sid,ref=this,writable=false,source=this.env.source?this.env.address_sources[this.env.source]:null;if(id=list.get_single_selection()){this.preview_timer=setTimeout(function(){ref.load_contact(id,"show")},200)}else{if(this.env.contentframe){this.show_contentframe(false)}}if(list.selection.length){this.env.selection_sources=[];if(!source){for(n in list.selection){sid=String(list.selection[n]).replace(/^[^-]+-/,"");if(sid&&this.env.address_sources[sid]){writable=writable||!this.env.address_sources[sid].readonly;this.env.selection_sources.push(sid)}}this.env.selection_sources=$.unique(this.env.selection_sources)}else{this.env.selection_sources.push(this.env.source);writable=!source.readonly}}this.enable_command("group-remove-selected",this.env.group&&list.selection.length>0);this.enable_command("compose",this.env.group||list.selection.length>0);this.enable_command("edit",id&&writable);this.enable_command("delete",list.selection.length&&writable);return false};this.list_contacts=function(src,group,page){var win,folder,url={},target=window;if(!src){src=this.env.source}if(page&&this.current_page==page&&src==this.env.source&&group==this.env.group){return false}if(src!=this.env.source){page=this.env.current_page=1;this.reset_qsearch()}else{if(group!=this.env.group){page=this.env.current_page=1}}if(this.env.search_id){folder="S"+this.env.search_id}else{if(!this.env.search_request){folder=group?"G"+src+group:src}}this.select_folder(folder);this.env.source=src;this.env.group=group;if(this.gui_objects.contactslist){this.list_contacts_remote(src,group,page);return}if(win=this.get_frame_window(this.env.contentframe)){target=win;url._framed=1}if(group){url._gid=group}if(page){url._page=page}if(src){url._source=src}if(this.env.search_request){url._search=this.env.search_request}this.set_busy(true,"loading");this.location_href(url,target)};this.list_contacts_remote=function(src,group,page){this.list_contacts_clear();var url={},lock=this.set_busy(true,"loading");if(src){url._source=src}if(page){url._page=page}if(group){url._gid=group}this.env.source=src;this.env.group=group;if(this.env.search_request){url._search=this.env.search_request}this.http_request(this.env.task=="mail"?"list-contacts":"list",url,lock)};this.list_contacts_clear=function(){this.contact_list.clear(true);this.show_contentframe(false);this.enable_command("delete",false);this.enable_command("compose",this.env.group?true:false)};this.load_contact=function(cid,action,framed){var win,url={},target=window;if(win=this.get_frame_window(this.env.contentframe)){url._framed=1;target=win;this.show_contentframe(true);if(!cid){this.contact_list.clear_selection();this.enable_command("delete","compose",false)}}else{if(framed){return false}}if(action&&(cid||action=="add")&&!this.drag_active){if(this.env.group){url._gid=this.env.group}url._action=action;url._source=this.env.source;url._cid=cid;this.location_href(url,target,true)}return true};this.group_member_change=function(what,cid,source,gid){what=what=="add"?"add":"del";var label=this.get_label(what=="add"?"addingmember":"removingmember"),lock=this.display_message(label,"loading"),post_data={_cid:cid,_source:source,_gid:gid};this.http_post("group-"+what+"members",post_data,lock)};this.copy_contact=function(cid,to){var n,dest=to.type=="group"?to.source:to.id,source=this.env.source,group=this.env.group?this.env.group:"";if(!cid){cid=this.contact_list.get_selection().join(",")}if(!cid||!this.env.address_sources[dest]||this.env.address_sources[dest].readonly){return}if(source==""&&this.env.selection_sources.length==1){source=this.env.selection_sources[0]}if(to.type=="group"){if(dest==source){this.group_member_change("add",cid,dest,to.id)}else{var lock=this.display_message(this.get_label("copyingcontact"),"loading"),post_data={_cid:cid,_source:this.env.source,_to:dest,_togid:to.id,_gid:group};this.http_post("copy",post_data,lock)}}else{if(to.id!=source){var lock=this.display_message(this.get_label("copyingcontact"),"loading"),post_data={_cid:cid,_source:this.env.source,_to:to.id,_gid:group};this.http_post("copy",post_data,lock)}}};this.delete_contacts=function(){var selection=this.contact_list.get_selection(),undelete=this.env.source&&this.env.address_sources[this.env.source].undelete;if(!(selection.length||this.env.cid)||(!undelete&&!confirm(this.get_label("deletecontactconfirm")))){return}var id,n,a_cids=[],post_data={_source:this.env.source,_from:(this.env.action?this.env.action:"")},lock=this.display_message(this.get_label("contactdeleting"),"loading");if(this.env.cid){a_cids.push(this.env.cid)}else{for(n=0;n<selection.length;n++){id=selection[n];a_cids.push(id);this.contact_list.remove_row(id,(n==selection.length-1))}if(selection.length==1){this.show_contentframe(false)}}post_data._cid=a_cids.join(",");if(this.env.group){post_data._gid=this.env.group}if(this.env.search_request){post_data._search=this.env.search_request}this.http_post("delete",post_data,lock);return true};this.update_contact_row=function(cid,cols_arr,newcid,source){var c,row,list=this.contact_list;cid=this.html_identifier(cid);if(!list.rows[cid]){cid=cid+"-"+source;if(newcid){newcid=newcid+"-"+source}}if(list.rows[cid]&&(row=list.rows[cid].obj)){for(c=0;c<cols_arr.length;c++){if(row.cells[c]){$(row.cells[c]).html(cols_arr[c])}}if(newcid){newcid=this.html_identifier(newcid);row.id="rcmrow"+newcid;list.remove_row(cid);list.init_row(row);list.selection[0]=newcid;row.style.display=""}}};this.add_contact_row=function(cid,cols,classes){if(!this.gui_objects.contactslist){return false}var c,col,list=this.contact_list,row=document.createElement("tr");row.id="rcmrow"+this.html_identifier(cid);row.className="contact "+(classes||"");if(list.in_selection(cid)){row.className+=" selected"}for(c in cols){col=document.createElement("td");col.className=String(c).toLowerCase();if(cols[c]){col.innerHTML=cols[c]}row.appendChild(col)}list.insert_row(row);this.enable_command("export",list.rowcount>0)};this.init_contact_form=function(){var ref=this,col;if(this.env.coltypes){this.set_photo_actions($("#ff_photo").val());for(col in this.env.coltypes){this.init_edit_field(col,null)}}$(".contactfieldgroup .row a.deletebutton").click(function(){ref.delete_edit_field(this);return false});$("select.addfieldmenu").change(function(e){ref.insert_edit_field($(this).val(),$(this).attr("rel"),this);this.selectedIndex=0});if($.datepicker&&this.env.date_format){$.datepicker.setDefaults({dateFormat:this.env.date_format,changeMonth:true,changeYear:true,yearRange:"-100:+10",showOtherMonths:true,selectOtherMonths:true,onSelect:function(dateText){$(this).focus().val(dateText)}});$("input.datepicker").datepicker()}$("input[type='text']:visible").first().focus();if(this.env.action=="search"){$(this.gui_objects.editform).append($('<input type="submit">').hide()).submit(function(){$("input.mainaction").click();return false})}};this.group_create=function(){this.add_input_row("contactgroup")};this.group_rename=function(){if(!this.env.group||!this.gui_objects.folderlist){return}if(!this.name_input){this.enable_command("list","listgroup",false);this.name_input=$("<input>").attr("type","text").val(this.env.contactgroups["G"+this.env.source+this.env.group].name);this.name_input.bind("keydown",function(e){return rcmail.add_input_keydown(e)});this.env.group_renaming=true;var link,li=this.get_folder_li(this.env.source+this.env.group,"rcmliG");if(li&&(link=li.firstChild)){$(link).hide().before(this.name_input)}}this.name_input.select().focus()};this.group_delete=function(){if(this.env.group&&confirm(this.get_label("deletegroupconfirm"))){var lock=this.set_busy(true,"groupdeleting");this.http_post("group-delete",{_source:this.env.source,_gid:this.env.group},lock)}};this.remove_group_item=function(prop){var li,key="G"+prop.source+prop.id;if((li=this.get_folder_li(key))){this.triggerEvent("group_delete",{source:prop.source,id:prop.id,li:li});li.parentNode.removeChild(li);delete this.env.contactfolders[key];delete this.env.contactgroups[key]}this.list_contacts(prop.source,0)};this.add_input_row=function(type){if(!this.gui_objects.folderlist){return}if(!this.name_input){this.name_input=$("<input>").attr("type","text").data("tt",type);this.name_input.bind("keydown",function(e){return rcmail.add_input_keydown(e)});this.name_input_li=$("<li>").addClass(type).append(this.name_input);var li=type=="contactsearch"?$("li:last",this.gui_objects.folderlist):this.get_folder_li(this.env.source);this.name_input_li.insertAfter(li)}this.name_input.select().focus()};this.group_remove_selected=function(){ref.http_post("group-delmembers",{_cid:this.contact_list.selection,_source:this.env.source,_gid:this.env.group})};this.remove_group_contacts=function(props){if("undefined"!=typeof this.env.group&&(this.env.group===props.gid)){var n,selection=this.contact_list.get_selection();for(n=0;n<selection.length;n++){id=selection[n];this.contact_list.remove_row(id,(n==selection.length-1))}}};this.add_input_keydown=function(e){var key=rcube_event.get_keycode(e),input=$(e.target),itype=input.data("tt");if(key==13){var newname=input.val();if(newname){var lock=this.set_busy(true,"loading");if(itype=="contactsearch"){this.http_post("search-create",{_search:this.env.search_request,_name:newname},lock)}else{if(this.env.group_renaming){this.http_post("group-rename",{_source:this.env.source,_gid:this.env.group,_name:newname},lock)}else{this.http_post("group-create",{_source:this.env.source,_name:newname},lock)}}}return false}else{if(key==27){this.reset_add_input()}}return true};this.reset_add_input=function(){if(this.name_input){if(this.env.group_renaming){var li=this.name_input.parent();li.children().last().show();this.env.group_renaming=false}this.name_input.remove();if(this.name_input_li){this.name_input_li.remove()}this.name_input=this.name_input_li=null}this.enable_command("list","listgroup",true)};this.insert_contact_group=function(prop){this.reset_add_input();prop.type="group";var key="G"+prop.source+prop.id,link=$("<a>").attr("href","#").attr("rel",prop.source+":"+prop.id).click(function(){return rcmail.command("listgroup",prop,this)}).html(prop.name),li=$("<li>").attr({id:"rcmli"+this.html_identifier(key),"class":"contactgroup"}).append(link);this.env.contactfolders[key]=this.env.contactgroups[key]=prop;this.add_contact_group_row(prop,li);this.triggerEvent("group_insert",{id:prop.id,source:prop.source,name:prop.name,li:li[0]})};this.update_contact_group=function(prop){this.reset_add_input();var key="G"+prop.source+prop.id,li=this.get_folder_li(key),link;if(li&&prop.newid){var newkey="G"+prop.source+prop.newid,newprop=$.extend({},prop);li.id="rcmli"+this.html_identifier(newkey);this.env.contactfolders[newkey]=this.env.contactfolders[key];this.env.contactfolders[newkey].id=prop.newid;this.env.group=prop.newid;delete this.env.contactfolders[key];delete this.env.contactgroups[key];newprop.id=prop.newid;newprop.type="group";link=$("<a>").attr("href","#").attr("rel",prop.source+":"+prop.newid).click(function(){return rcmail.command("listgroup",newprop,this)}).html(prop.name);$(li).children().replaceWith(link)}else{if(li&&(link=li.firstChild)&&link.tagName.toLowerCase()=="a"){link.innerHTML=prop.name}}this.env.contactfolders[key].name=this.env.contactgroups[key].name=prop.name;this.add_contact_group_row(prop,$(li),true);this.triggerEvent("group_update",{id:prop.id,source:prop.source,name:prop.name,li:li[0],newid:prop.newid})};this.add_contact_group_row=function(prop,li,reloc){var row,name=prop.name.toUpperCase(),sibling=this.get_folder_li(prop.source),prefix="rcmliG"+this.html_identifier(prop.source);if(reloc){row=li.clone(true);li.remove()}else{row=li}$('li[id^="'+prefix+'"]',this.gui_objects.folderlist).each(function(i,elem){if(name>=$(this).text().toUpperCase()){sibling=elem}else{return false}});row.insertAfter(sibling)};this.update_group_commands=function(){var source=this.env.source!=""?this.env.address_sources[this.env.source]:null;this.enable_command("group-create",(source&&source.groups&&!source.readonly));this.enable_command("group-rename","group-delete",(source&&source.groups&&this.env.group&&!source.readonly))};this.init_edit_field=function(col,elem){var label=this.env.coltypes[col].label;if(!elem){elem=$(".ff_"+col)}if(label){elem.placeholder(label)}};this.insert_edit_field=function(col,section,menu){var elem=$("#ff_"+col);if(elem.length){elem.show().focus();$(menu).children('option[value="'+col+'"]').prop("disabled",true)}else{var lastelem=$(".ff_"+col),appendcontainer=$("#contactsection"+section+" .contactcontroller"+col);if(!appendcontainer.length){var sect=$("#contactsection"+section),lastgroup=$(".contactfieldgroup",sect).last();appendcontainer=$("<fieldset>").addClass("contactfieldgroup contactcontroller"+col);if(lastgroup.length){appendcontainer.insertAfter(lastgroup)}else{sect.prepend(appendcontainer)}}if(appendcontainer.length&&appendcontainer.get(0).nodeName=="FIELDSET"){var input,colprop=this.env.coltypes[col],row=$("<div>").addClass("row"),cell=$("<div>").addClass("contactfieldcontent data"),label=$("<div>").addClass("contactfieldlabel label");if(colprop.subtypes_select){label.html(colprop.subtypes_select)}else{label.html(colprop.label)}var name_suffix=colprop.limit!=1?"[]":"";if(colprop.type=="text"||colprop.type=="date"){input=$("<input>").addClass("ff_"+col).attr({type:"text",name:"_"+col+name_suffix,size:colprop.size}).appendTo(cell);this.init_edit_field(col,input);if(colprop.type=="date"&&$.datepicker){input.datepicker()}}else{if(colprop.type=="textarea"){input=$("<textarea>").addClass("ff_"+col).attr({name:"_"+col+name_suffix,cols:colprop.size,rows:colprop.rows}).appendTo(cell);this.init_edit_field(col,input)}else{if(colprop.type=="composite"){var childcol,cp,first,templ,cols=[],suffices=[];if((templ=this.env[col+"_template"])){for(var j=0;j<templ.length;j++){cols.push(templ[j][1]);suffices.push(templ[j][2])}}else{for(childcol in colprop.childs){cols.push(childcol)}}for(var i=0;i<cols.length;i++){childcol=cols[i];cp=colprop.childs[childcol];input=$("<input>").addClass("ff_"+childcol).attr({type:"text",name:"_"+childcol+name_suffix,size:cp.size}).appendTo(cell);cell.append(suffices[i]||" ");this.init_edit_field(childcol,input);if(!first){first=input}}input=first}else{if(colprop.type=="select"){input=$("<select>").addClass("ff_"+col).attr("name","_"+col+name_suffix).appendTo(cell);var options=input.attr("options");options[options.length]=new Option("---","");if(colprop.options){$.each(colprop.options,function(i,val){options[options.length]=new Option(val,i)})}}}}}if(input){var delbutton=$('<a href="#del"></a>').addClass("contactfieldbutton deletebutton").attr({title:this.get_label("delete"),rel:col}).html(this.env.delbutton).click(function(){ref.delete_edit_field(this);return false}).appendTo(cell);row.append(label).append(cell).appendTo(appendcontainer.show());input.first().focus();if(!colprop.count){colprop.count=0}if(++colprop.count==colprop.limit&&colprop.limit){$(menu).children('option[value="'+col+'"]').prop("disabled",true)}}}}};this.delete_edit_field=function(elem){var col=$(elem).attr("rel"),colprop=this.env.coltypes[col],fieldset=$(elem).parents("fieldset.contactfieldgroup"),addmenu=fieldset.parent().find("select.addfieldmenu");if(--colprop.count<=0&&colprop.visible){$(elem).parent().children("input").val("").blur()}else{$(elem).parents("div.row").remove();if(!fieldset.children("div.row").length){fieldset.hide()}}if(addmenu.length){var option=addmenu.children('option[value="'+col+'"]');if(option.length){option.prop("disabled",false)}else{option=$("<option>").attr("value",col).html(colprop.label).appendTo(addmenu)}addmenu.show()}};this.upload_contact_photo=function(form){if(form&&form.elements._photo.value){this.async_upload_form(form,"upload-photo",function(e){rcmail.set_busy(false,null,rcmail.file_upload_id)});this.file_upload_id=this.set_busy(true,"uploading")}};this.replace_contact_photo=function(id){var img_src=id=="-del-"?this.env.photo_placeholder:this.env.comm_path+"&_action=photo&_source="+this.env.source+"&_cid="+this.env.cid+"&_photo="+id;this.set_photo_actions(id);$(this.gui_objects.contactphoto).children("img").attr("src",img_src)};this.photo_upload_end=function(){this.set_busy(false,null,this.file_upload_id);delete this.file_upload_id};this.set_photo_actions=function(id){var n,buttons=this.buttons["upload-photo"];for(n=0;buttons&&n<buttons.length;n++){$("a#"+buttons[n].id).html(this.get_label(id=="-del-"?"addphoto":"replacephoto"))}$("#ff_photo").val(id);this.enable_command("upload-photo",this.env.coltypes.photo?true:false);this.enable_command("delete-photo",this.env.coltypes.photo&&id!="-del-")};this.advanced_search=function(){var win,url={_form:1,_action:"search"},target=window;if(win=this.get_frame_window(this.env.contentframe)){url._framed=1;target=win;this.contact_list.clear_selection()}this.location_href(url,target,true);return true};this.unselect_directory=function(){this.select_folder("");this.enable_command("search-delete",false)};this.insert_saved_search=function(name,id){this.reset_add_input();var key="S"+id,link=$("<a>").attr("href","#").attr("rel",id).click(function(){return rcmail.command("listsearch",id,this)}).html(name),li=$("<li>").attr({id:"rcmli"+this.html_identifier(key),"class":"contactsearch"}).append(link),prop={name:name,id:id,li:li[0]};this.add_saved_search_row(prop,li);this.select_folder("S"+id);this.enable_command("search-delete",true);this.env.search_id=id;this.triggerEvent("abook_search_insert",prop)};this.add_saved_search_row=function(prop,li,reloc){var row,sibling,name=prop.name.toUpperCase();if(reloc){row=li.clone(true);li.remove()}else{row=li}$('li[class~="contactsearch"]',this.gui_objects.folderlist).each(function(i,elem){if(!sibling){sibling=this.previousSibling}if(name>=$(this).text().toUpperCase()){sibling=elem}else{return false}});if(sibling){row.insertAfter(sibling)}else{row.appendTo(this.gui_objects.folderlist)}};this.search_create=function(){this.add_input_row("contactsearch")};this.search_delete=function(){if(this.env.search_request){var lock=this.set_busy(true,"savedsearchdeleting");this.http_post("search-delete",{_sid:this.env.search_id},lock)}};this.remove_search_item=function(id){var li,key="S"+id;if((li=this.get_folder_li(key))){this.triggerEvent("search_delete",{id:id,li:li});li.parentNode.removeChild(li)}this.env.search_id=null;this.env.search_request=null;this.list_contacts_clear();this.reset_qsearch();this.enable_command("search-delete","search-create",false)};this.listsearch=function(id){var folder,lock=this.set_busy(true,"searching");if(this.contact_list){this.list_contacts_clear()}this.reset_qsearch();this.select_folder("S"+id);this.env.current_page=1;this.http_request("search",{_sid:id},lock)};this.section_select=function(list){var win,id=list.get_single_selection(),target=window,url={_action:"edit-prefs",_section:id};if(id){if(win=this.get_frame_window(this.env.contentframe)){url._framed=1;target=win}this.location_href(url,target,true)}return true};this.identity_select=function(list){var id;if(id=list.get_single_selection()){this.enable_command("delete",list.rowcount>1&&this.env.identities_level<2);this.load_identity(id,"edit-identity")}};this.load_identity=function(id,action){if(action=="edit-identity"&&(!id||id==this.env.iid)){return false}var win,target=window,url={_action:action,_iid:id};if(win=this.get_frame_window(this.env.contentframe)){url._framed=1;target=win}if(action&&(id||action=="add-identity")){this.set_busy(true);this.location_href(url,target)}return true};this.delete_identity=function(id){var selection=this.identity_list.get_selection();if(!(selection.length||this.env.iid)){return}if(!id){id=this.env.iid?this.env.iid:selection[0]}if(confirm(this.get_label("deleteidentityconfirm"))){this.goto_url("delete-identity",{_iid:id,_token:this.env.request_token},true)}return true};this.update_identity_row=function(id,name,add){var row,col,list=this.identity_list,rid=this.html_identifier(id);if(list.rows[rid]&&(row=list.rows[rid].obj)){$(row.cells[0]).html(name)}else{if(add){row=$("<tr>").attr("id","rcmrow"+rid).get(0);col=$("<td>").addClass("mail").html(name).appendTo(row);list.insert_row(row);list.select(rid)}}};this.init_subscription_list=function(){var p=this;this.subscription_list=new rcube_list_widget(this.gui_objects.subscriptionlist,{multiselect:false,draggable:true,keyboard:false,toggleselect:true});this.subscription_list.addEventListener("select",function(o){p.subscription_select(o)});this.subscription_list.addEventListener("dragstart",function(o){p.drag_active=true});this.subscription_list.addEventListener("dragend",function(o){p.subscription_move_folder(o)});this.subscription_list.row_init=function(row){row.obj.onmouseover=function(){p.focus_subscription(row.id)};row.obj.onmouseout=function(){p.unfocus_subscription(row.id)}};this.subscription_list.init();$("#mailboxroot").mouseover(function(){p.focus_subscription(this.id)}).mouseout(function(){p.unfocus_subscription(this.id)})};this.focus_subscription=function(id){var row,folder,delim=RegExp.escape(this.env.delimiter),reg=RegExp("["+delim+"]?[^"+delim+"]+$");if(this.drag_active&&this.env.mailbox&&(row=document.getElementById(id))){if(this.env.subscriptionrows[id]&&(folder=this.env.subscriptionrows[id][0])!==null){if(this.check_droptarget(folder)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.mailbox)][2]&&(folder!=this.env.mailbox.replace(reg,""))&&(!folder.match(new RegExp("^"+RegExp.escape(this.env.mailbox+this.env.delimiter))))){this.env.dstfolder=folder;$(row).addClass("droptarget")}}}};this.unfocus_subscription=function(id){var row=$("#"+id);this.env.dstfolder=null;if(this.env.subscriptionrows[id]&&row[0]){row.removeClass("droptarget")}else{$(this.subscription_list.frame).removeClass("droptarget")}};this.subscription_select=function(list){var id,folder;if(list&&(id=list.get_single_selection())&&(folder=this.env.subscriptionrows["rcmrow"+id])){this.env.mailbox=folder[0];this.show_folder(folder[0]);this.enable_command("delete-folder",!folder[2])}else{this.env.mailbox=null;this.show_contentframe(false);this.enable_command("delete-folder","purge",false)}};this.subscription_move_folder=function(list){var delim=RegExp.escape(this.env.delimiter),reg=RegExp("["+delim+"]?[^"+delim+"]+$");if(this.env.mailbox&&this.env.dstfolder!==null&&(this.env.dstfolder!=this.env.mailbox)&&(this.env.dstfolder!=this.env.mailbox.replace(reg,""))){reg=new RegExp("[^"+delim+"]*["+delim+"]","g");var basename=this.env.mailbox.replace(reg,""),newname=this.env.dstfolder===""?basename:this.env.dstfolder+this.env.delimiter+basename;if(newname!=this.env.mailbox){this.http_post("rename-folder",{_folder_oldname:this.env.mailbox,_folder_newname:newname},this.set_busy(true,"foldermoving"));this.subscription_list.draglayer.hide()}}this.drag_active=false;this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder))};this.create_folder=function(){this.show_folder("",this.env.mailbox)};this.delete_folder=function(name){var id=this.get_folder_row_id(name?name:this.env.mailbox),folder=this.env.subscriptionrows[id][0];if(folder&&confirm(this.get_label("deletefolderconfirm"))){var lock=this.set_busy(true,"folderdeleting");this.http_post("delete-folder",{_mbox:folder},lock)}};this.add_folder_row=function(name,display_name,is_protected,subscribed,skip_init,class_name){if(!this.gui_objects.subscriptionlist){return false}var row,n,i,tmp,tmp_name,folders,rowid,list=[],slist=[],tbody=this.gui_objects.subscriptionlist.tBodies[0],refrow=$("tr",tbody).get(1),id="rcmrow"+((new Date).getTime());if(!refrow){this.goto_url("folders");return false}row=$(refrow).clone(true);row.attr("id",id);row.attr("class",class_name);row.find("td:first").html(display_name);$('input[name="_subscribed[]"]',row).val(name).prop({checked:subscribed?true:false,disabled:is_protected?true:false});this.env.subscriptionrows[id]=[name,display_name,0];folders=[];$.each(this.env.subscriptionrows,function(k,v){folders.push(v)});folders.sort(function(a,b){return a[0]<b[0]?-1:(a[0]>b[0]?1:0)});for(n in folders){if(folders[n][2]){tmp_name=folders[n][0]+this.env.delimiter;if(tmp_name==this.env.prefix_ns){continue}slist.push(folders[n][0]);tmp=tmp_name}else{if(tmp&&folders[n][0].indexOf(tmp)==0){slist.push(folders[n][0])}else{list.push(folders[n][0]);tmp=null}}}for(n=0;n<slist.length;n++){if(name.indexOf(slist[n]+this.env.delimiter)==0){rowid=this.get_folder_row_id(slist[n])}}for(n=0;!rowid&&n<list.length;n++){if(n&&list[n]==name){rowid=this.get_folder_row_id(list[n-1])}}if(rowid){$("#"+rowid).after(row)}else{row.appendTo(tbody)}this.subscription_list.clear_selection();if(!skip_init){this.init_subscription_list()}row=row.get(0);if(row.scrollIntoView){row.scrollIntoView()}return row};this.replace_folder_row=function(oldfolder,newfolder,display_name,is_protected,class_name){if(!this.gui_objects.subscriptionlist){return false}var i,n,len,name,dispname,oldrow,tmprow,row,level,tbody=this.gui_objects.subscriptionlist.tBodies[0],folders=this.env.subscriptionrows,id=this.get_folder_row_id(oldfolder),regex=new RegExp("^"+RegExp.escape(oldfolder)),subscribed=$('input[name="_subscribed[]"]',$("#"+id)).prop("checked"),list=this.get_subfolders(oldfolder);this._remove_folder_row(id);row=$(this.add_folder_row(newfolder,display_name,is_protected,subscribed,true,class_name));if(len=list.length){level=(oldfolder.split(this.env.delimiter)).length-(newfolder.split(this.env.delimiter)).length}for(n=0;n<len;n++){id=list[n];name=this.env.subscriptionrows[id][0];dispname=this.env.subscriptionrows[id][1];oldrow=$("#"+id);tmprow=oldrow.clone(true);oldrow.remove();row.after(tmprow);row=tmprow;name=name.replace(regex,newfolder);$('input[name="_subscribed[]"]',row).val(name);this.env.subscriptionrows[id][0]=name;if(level!=0){if(level>0){for(i=level;i>0;i--){dispname=dispname.replace(/^&nbsp;&nbsp;&nbsp;&nbsp;/,"")}}else{for(i=level;i<0;i++){dispname="&nbsp;&nbsp;&nbsp;&nbsp;"+dispname}}row.find("td:first").html(dispname);this.env.subscriptionrows[id][1]=dispname}}this.init_subscription_list()};this.remove_folder_row=function(folder,subs){var n,len,list=[],id=this.get_folder_row_id(folder);if(subs){list=this.get_subfolders(folder)}this._remove_folder_row(id);for(n=0,len=list.length;n<len;n++){this._remove_folder_row(list[n])}};this._remove_folder_row=function(id){this.subscription_list.remove_row(id.replace(/^rcmrow/,""));$("#"+id).remove();delete this.env.subscriptionrows[id]};this.get_subfolders=function(folder){var name,list=[],regex=new RegExp("^"+RegExp.escape(folder)+RegExp.escape(this.env.delimiter)),row=$("#"+this.get_folder_row_id(folder)).get(0);while(row=row.nextSibling){if(row.id){name=this.env.subscriptionrows[row.id][0];if(regex.test(name)){list.push(row.id)}else{break}}}return list};this.subscribe=function(folder){if(folder){var lock=this.display_message(this.get_label("foldersubscribing"),"loading");this.http_post("subscribe",{_mbox:folder},lock)}};this.unsubscribe=function(folder){if(folder){var lock=this.display_message(this.get_label("folderunsubscribing"),"loading");this.http_post("unsubscribe",{_mbox:folder},lock)}};this.get_folder_row_id=function(folder){var id,folders=this.env.subscriptionrows;for(id in folders){if(folders[id]&&folders[id][0]==folder){break}}return id};this.show_folder=function(folder,path,force){var win,target=window,url="&_action=edit-folder&_mbox="+urlencode(folder);if(path){url+="&_path="+urlencode(path)}if(win=this.get_frame_window(this.env.contentframe)){target=win;url+="&_framed=1"}if(String(target.location.href).indexOf(url)>=0&&!force){this.show_contentframe(true)}else{this.location_href(this.env.comm_path+url,target,true)}};this.disable_subscription=function(folder){var id=this.get_folder_row_id(folder);if(id){$('input[name="_subscribed[]"]',$("#"+id)).prop("disabled",true)}};this.folder_size=function(folder){var lock=this.set_busy(true,"loading");this.http_post("folder-size",{_mbox:folder},lock)};this.folder_size_update=function(size){$("#folder-size").replaceWith(size)};var init_button=function(cmd,prop){var elm=document.getElementById(prop.id);if(!elm){return}var preload=false;if(prop.type=="image"){elm=elm.parentNode;preload=true}elm._command=cmd;elm._id=prop.id;if(prop.sel){elm.onmousedown=function(e){return rcmail.button_sel(this._command,this._id)};elm.onmouseup=function(e){return rcmail.button_out(this._command,this._id)};if(preload){new Image().src=prop.sel}}if(prop.over){elm.onmouseover=function(e){return rcmail.button_over(this._command,this._id)};elm.onmouseout=function(e){return rcmail.button_out(this._command,this._id)};if(preload){new Image().src=prop.over}}};this.init_buttons=function(){for(var cmd in this.buttons){if(typeof cmd!=="string"){continue}for(var i=0;i<this.buttons[cmd].length;i++){init_button(cmd,this.buttons[cmd][i])}}this.set_button(this.task,"sel")};this.set_button=function(command,state){var n,button,obj,a_buttons=this.buttons[command],len=a_buttons?a_buttons.length:0;for(n=0;n<len;n++){button=a_buttons[n];obj=document.getElementById(button.id);if(!obj){continue}if(button.type=="image"&&!button.status){button.pas=obj._original_src?obj._original_src:obj.src;if(obj.runtimeStyle&&obj.runtimeStyle.filter&&obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/)){button.pas=RegExp.$1}}else{if(!button.status){button.pas=String(obj.className)}}if(button.type=="image"&&button[state]){button.status=state;obj.src=button[state]}else{if(button[state]!==undefined){button.status=state;obj.className=button[state]}}if(button.type=="input"){button.status=state;obj.disabled=!state}}};this.set_alttext=function(command,label){var n,button,obj,link,a_buttons=this.buttons[command],len=a_buttons?a_buttons.length:0;for(n=0;n<len;n++){button=a_buttons[n];obj=document.getElementById(button.id);if(button.type=="image"&&obj){obj.setAttribute("alt",this.get_label(label));if((link=obj.parentNode)&&link.tagName.toLowerCase()=="a"){link.setAttribute("title",this.get_label(label))}}else{if(obj){obj.setAttribute("title",this.get_label(label))}}}};this.button_over=function(command,id){var n,button,obj,a_buttons=this.buttons[command],len=a_buttons?a_buttons.length:0;for(n=0;n<len;n++){button=a_buttons[n];if(button.id==id&&button.status=="act"){obj=document.getElementById(button.id);if(obj&&button.over){if(button.type=="image"){obj.src=button.over}else{obj.className=button.over}}}}};this.button_sel=function(command,id){var n,button,obj,a_buttons=this.buttons[command],len=a_buttons?a_buttons.length:0;for(n=0;n<len;n++){button=a_buttons[n];if(button.id==id&&button.status=="act"){obj=document.getElementById(button.id);if(obj&&button.sel){if(button.type=="image"){obj.src=button.sel}else{obj.className=button.sel}}this.buttons_sel[id]=command}}};this.button_out=function(command,id){var n,button,obj,a_buttons=this.buttons[command],len=a_buttons?a_buttons.length:0;for(n=0;n<len;n++){button=a_buttons[n];if(button.id==id&&button.status=="act"){obj=document.getElementById(button.id);if(obj&&button.act){if(button.type=="image"){obj.src=button.act}else{obj.className=button.act}}}}};this.set_pagetitle=function(title){if(title&&document.title){document.title=title}};this.display_message=function(msg,type,timeout){if(this.is_framed()){return parent.rcmail.display_message(msg,type,timeout)}if(!this.gui_objects.message){if(type!="loading"){this.pending_message=[msg,type,timeout]}return 1}type=type?type:"notice";var ref=this,key=this.html_identifier(msg),date=new Date(),id=type+date.getTime();if(!timeout){timeout=this.message_time*(type=="error"||type=="warning"?2:1)}if(type=="loading"){key="loading";timeout=this.env.request_timeout*1000;if(!msg){msg=this.get_label("loading")}}if(this.messages[key]){if(this.messages[key].obj){this.messages[key].obj.html(msg)}if(type=="loading"){this.messages[key].labels.push({id:id,msg:msg})}this.messages[key].elements.push(id);setTimeout(function(){ref.hide_message(id,type=="loading")},timeout);return id}var obj=$("<div>").addClass(type).html(msg).data("key",key),cont=$(this.gui_objects.message).append(obj).show();this.messages[key]={obj:obj,elements:[id]};if(type=="loading"){this.messages[key].labels=[{id:id,msg:msg}]}else{obj.click(function(){return ref.hide_message(obj)})}this.triggerEvent("message",{message:msg,type:type,timeout:timeout,object:obj});if(timeout>0){setTimeout(function(){ref.hide_message(id,type=="loading")},timeout)}return id};this.hide_message=function(obj,fade){if(this.is_framed()){return parent.rcmail.hide_message(obj,fade)}if(!this.gui_objects.message){return}var k,n,i,msg,m=this.messages;if(typeof obj==="object"){$(obj)[fade?"fadeOut":"hide"]();msg=$(obj).data("key");if(this.messages[msg]){delete this.messages[msg]}}else{for(k in m){for(n in m[k].elements){if(m[k]&&m[k].elements[n]==obj){m[k].elements.splice(n,1);if(!m[k].elements.length){m[k].obj[fade?"fadeOut":"hide"]();delete m[k]}else{if(k=="loading"){for(i in m[k].labels){if(m[k].labels[i].id==obj){delete m[k].labels[i]}else{msg=m[k].labels[i].msg}m[k].obj.html(msg)}}}}}}}};this.clear_messages=function(){if(this.is_framed()){return parent.rcmail.clear_messages()}var k,n,m=this.messages;for(k in m){for(n in m[k].elements){if(m[k].obj){m[k].obj.hide()}}}this.messages={}};this.show_popup_dialog=function(html,title){if(this.is_framed()){parent.rcmail.show_popup_dialog(html,title);return}var popup=$('<div class="popup">').html(html).dialog({title:title,modal:true,resizable:true,width:580,close:function(event,ui){$(this).remove()}});var win=$(window),w=win.width(),h=win.height(),width=popup.width(),height=popup.height();popup.dialog("option",{height:Math.min(h-40,height+50),width:Math.min(w-20,width+50)}).dialog("option","position",["center","center"])};this.set_page_buttons=function(){this.enable_command("nextpage","lastpage",(this.env.pagecount>this.env.current_page));this.enable_command("previouspage","firstpage",(this.env.current_page>1))};this.select_folder=function(name,prefix,encode){if(this.gui_objects.folderlist){var current_li,target_li;if((current_li=$("li.selected",this.gui_objects.folderlist))){current_li.removeClass("selected").addClass("unfocused")}if((target_li=this.get_folder_li(name,prefix,encode))){$(target_li).removeClass("unfocused").addClass("selected")}this.triggerEvent("selectfolder",{folder:name,prefix:prefix})}};this.mark_folder=function(name,class_name,prefix,encode){$(this.get_folder_li(name,prefix,encode)).addClass(class_name)};this.unmark_folder=function(name,class_name,prefix,encode){$(this.get_folder_li(name,prefix,encode)).removeClass(class_name)};this.get_folder_li=function(name,prefix,encode){if(!prefix){prefix="rcmli"}if(this.gui_objects.folderlist){name=this.html_identifier(name,encode);return document.getElementById(prefix+name)}return null};this.set_message_coltypes=function(coltypes,repl,smart_col){var list=this.message_list,thead=list?list.list.tHead:null,cell,col,n,len,th,tr;this.env.coltypes=coltypes;if(thead){if(repl){th=document.createElement("thead");tr=document.createElement("tr");for(c=0,len=repl.length;c<len;c++){cell=document.createElement("td");cell.innerHTML=repl[c].html||"";if(repl[c].id){cell.id=repl[c].id}if(repl[c].className){cell.className=repl[c].className}tr.appendChild(cell)}th.appendChild(tr);thead.parentNode.replaceChild(th,thead);list.thead=thead=th}for(n=0,len=this.env.coltypes.length;n<len;n++){col=this.env.coltypes[n];if((cell=thead.rows[0].cells[n])&&(col=="from"||col=="to"||col=="fromto")){cell.id="rcm"+col;$("span,a",cell).text(this.get_label(col=="fromto"?smart_col:col));$("a",cell).click(function(){return rcmail.command("sort",this.id.replace(/^rcm/,""),this)})}}}this.env.subject_col=null;this.env.flagged_col=null;this.env.status_col=null;if((n=$.inArray("subject",this.env.coltypes))>=0){this.env.subject_col=n;if(list){list.subject_col=n}}if((n=$.inArray("flag",this.env.coltypes))>=0){this.env.flagged_col=n}if((n=$.inArray("status",this.env.coltypes))>=0){this.env.status_col=n}if(list){list.init_header()}};this.set_rowcount=function(text,mbox){if(mbox&&mbox!=this.env.mailbox){return false}$(this.gui_objects.countdisplay).html(text);this.set_page_buttons()};this.set_mailboxname=function(content){if(this.gui_objects.mailboxname&&content){this.gui_objects.mailboxname.innerHTML=content}};this.set_quota=function(content){if(this.gui_objects.quotadisplay&&content&&content.type=="text"){$(this.gui_objects.quotadisplay).html(content.percent+"%").attr("title",content.title)}this.triggerEvent("setquota",content);this.env.quota_content=content};this.set_unread_count=function(mbox,count,set_title,mark){if(!this.gui_objects.mailboxlist){return false}this.env.unread_counts[mbox]=count;this.set_unread_count_display(mbox,set_title);if(mark){this.mark_folder(mbox,mark,"",true)}else{if(!count){this.unmark_folder(mbox,"recent","",true)}}};this.set_unread_count_display=function(mbox,set_title){var reg,link,text_obj,item,mycount,childcount,div;if(item=this.get_folder_li(mbox,"",true)){mycount=this.env.unread_counts[mbox]?this.env.unread_counts[mbox]:0;link=$(item).children("a").eq(0);text_obj=link.children("span.unreadcount");if(!text_obj.length&&mycount){text_obj=$("<span>").addClass("unreadcount").appendTo(link)}reg=/\s+\([0-9]+\)$/i;childcount=0;if((div=item.getElementsByTagName("div")[0])&&div.className.match(/collapsed/)){for(var k in this.env.unread_counts){if(k.indexOf(mbox+this.env.delimiter)==0){childcount+=this.env.unread_counts[k]}}}if(mycount&&text_obj.length){text_obj.html(this.env.unreadwrap.replace(/%[sd]/,mycount))}else{if(text_obj.length){text_obj.remove()}}reg=new RegExp(RegExp.escape(this.env.delimiter)+"[^"+RegExp.escape(this.env.delimiter)+"]+$");if(mbox.match(reg)){this.set_unread_count_display(mbox.replace(reg,""),false)}if((mycount+childcount)>0){$(item).addClass("unread")}else{$(item).removeClass("unread")}}reg=/^\([0-9]+\)\s+/i;if(set_title&&document.title){var new_title="",doc_title=String(document.title);if(mycount&&doc_title.match(reg)){new_title=doc_title.replace(reg,"("+mycount+") ")}else{if(mycount){new_title="("+mycount+") "+doc_title}else{new_title=doc_title.replace(reg,"")}}this.set_pagetitle(new_title)}};this.set_headers=function(content){if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&content){$(this.gui_objects.all_headers_box).html(content).show()}};this.show_headers=function(props,elem){if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box||!this.env.uid){return}$(elem).removeClass("show-headers").addClass("hide-headers");$(this.gui_objects.all_headers_row).show();elem.onclick=function(){rcmail.command("hide-headers","",elem)};if(!this.gui_objects.all_headers_box.innerHTML){var lock=this.display_message(this.get_label("loading"),"loading");this.http_post("headers",{_uid:this.env.uid},lock)}};this.hide_headers=function(props,elem){if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box){return}$(elem).removeClass("hide-headers").addClass("show-headers");$(this.gui_objects.all_headers_row).hide();elem.onclick=function(){rcmail.command("show-headers","",elem)}};this.html2plain=function(htmlText,id){var rcmail=this,url="?_task=utils&_action=html2text",lock=this.set_busy(true,"converting");this.log("HTTP POST: "+url);$.ajax({type:"POST",url:url,data:htmlText,contentType:"application/octet-stream",error:function(o,status,err){rcmail.http_error(o,status,err,lock)},success:function(data){rcmail.set_busy(false,null,lock);$("#"+id).val(data);rcmail.log(data)}})};this.plain2html=function(plain,id){var lock=this.set_busy(true,"converting");plain=plain.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");$("#"+id).val(plain?"<pre>"+plain+"</pre>":"");this.set_busy(false,null,lock)};this.url=function(action,query){var querystring=typeof query==="string"?"&"+query:"";if(typeof action!=="string"){query=action}else{if(!query||typeof query!=="object"){query={}}}if(action){query._action=action}else{query._action=this.env.action}var base=this.env.comm_path,k,param={};if(query._action.match(/([a-z]+)\/([a-z0-9-_.]+)/)){query._action=RegExp.$2;base=base.replace(/\_task=[a-z]+/,"_task="+RegExp.$1)}for(k in query){if(query[k]!==undefined&&query[k]!==null){param[k]=query[k]}}return base+"&"+$.param(param)+querystring};this.redirect=function(url,lock){if(lock||lock===null){this.set_busy(true)}if(this.is_framed()){parent.rcmail.redirect(url,lock)}else{if(this.env.extwin){if(typeof url=="string"){url+=(url.indexOf("?")<0?"?":"&")+"_extwin=1"}else{url._extwin=1}}this.location_href(url,window)}};this.goto_url=function(action,query,lock){this.redirect(this.url(action,query))};this.location_href=function(url,target,frame){if(frame){this.lock_frame()}if(typeof url=="object"){url=this.env.comm_path+"&"+$.param(url)}if(bw.ie&&target==window){$("<a>").attr("href",url).appendTo(document.body).get(0).click()}else{target.location.href=url}this.start_keepalive()};this.http_request=function(action,query,lock){var url=this.url(action,query);var result=this.triggerEvent("request"+action,query);if(result!==undefined){if(result===false){return false}else{query=result}}url+="&_remote=1";this.log("HTTP GET: "+url);this.start_keepalive();return $.ajax({type:"GET",url:url,data:{_unlock:(lock?lock:0)},dataType:"json",success:function(data){ref.http_response(data)},error:function(o,status,err){ref.http_error(o,status,err,lock,action)}})};this.http_post=function(action,postdata,lock){var url=this.url(action);if(postdata&&typeof postdata==="object"){postdata._remote=1;postdata._unlock=(lock?lock:0)}else{postdata+=(postdata?"&":"")+"_remote=1"+(lock?"&_unlock="+lock:"")}var result=this.triggerEvent("request"+action,postdata);if(result!==undefined){if(result===false){return false}else{postdata=result}}this.log("HTTP POST: "+url);this.start_keepalive();return $.ajax({type:"POST",url:url,data:postdata,dataType:"json",success:function(data){ref.http_response(data)},error:function(o,status,err){ref.http_error(o,status,err,lock,action)}})};this.abort_request=function(r){if(r.request){r.request.abort()}if(r.lock){this.set_busy(false,null,r.lock)}};this.http_response=function(response){if(!response){return}if(response.unlock){this.set_busy(false)}this.triggerEvent("responsebefore",{response:response});this.triggerEvent("responsebefore"+response.action,{response:response});if(response.env){this.set_env(response.env)}if(typeof response.texts==="object"){for(var name in response.texts){if(typeof response.texts[name]==="string"){this.add_label(name,response.texts[name])}}}if(response.exec){this.log(response.exec);eval(response.exec)}if(response.callbacks&&response.callbacks.length){for(var i=0;i<response.callbacks.length;i++){this.triggerEvent(response.callbacks[i][0],response.callbacks[i][1])}}switch(response.action){case"delete":if(this.task=="addressbook"){var sid,uid=this.contact_list.get_selection(),writable=false;if(uid&&this.contact_list.rows[uid]){if(this.env.source==""){sid=String(uid).replace(/^[^-]+-/,"");writable=sid&&this.env.address_sources[sid]&&!this.env.address_sources[sid].readonly}else{writable=!this.env.address_sources[this.env.source].readonly}}this.enable_command("compose",(uid&&this.contact_list.rows[uid]));this.enable_command("delete","edit",writable);this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0))}case"moveto":if(this.env.action=="show"){this.enable_command(this.env.message_commands,true);if(!this.env.list_post){this.enable_command("reply-list",false)}}else{if(this.task=="addressbook"){this.triggerEvent("listupdate",{folder:this.env.source,rowcount:this.contact_list.rowcount})}}case"purge":case"expunge":if(this.task=="mail"){if(!this.env.exists){if(this.env.contentframe){this.show_contentframe(false)}this.enable_command(this.env.message_commands,"purge","expunge","select-all","select-none","expand-all","expand-unread","collapse-all",false)}if(this.message_list){this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount})}}break;case"refresh":case"check-recent":case"getunread":case"search":this.env.qsearch=null;case"list":if(this.task=="mail"){this.enable_command("show","select-all","select-none",this.env.messagecount>0);this.enable_command("expunge",this.env.exists);this.enable_command("purge",this.purge_mailbox_test());this.enable_command("expand-all","expand-unread","collapse-all",this.env.threading&&this.env.messagecount);if((response.action=="list"||response.action=="search")&&this.message_list){this.msglist_select(this.message_list);this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount})}}else{if(this.task=="addressbook"){this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0));if(response.action=="list"||response.action=="search"){this.enable_command("search-create",this.env.source=="");this.enable_command("search-delete",this.env.search_id);this.update_group_commands();this.triggerEvent("listupdate",{folder:this.env.source,rowcount:this.contact_list.rowcount})}}}break}if(response.unlock){this.hide_message(response.unlock)}this.triggerEvent("responseafter",{response:response});this.triggerEvent("responseafter"+response.action,{response:response});this.start_keepalive()};this.http_error=function(request,status,err,lock,action){var errmsg=request.statusText;this.set_busy(false,null,lock);request.abort();if(this.unload){return}if(request.status&&errmsg){this.display_message(this.get_label("servererror")+" ("+errmsg+")","error")}else{if(status=="timeout"){this.display_message(this.get_label("requesttimedout"),"error")}else{if(request.status==0&&status!="abort"){this.display_message(this.get_label("servererror")+" (No connection)","error")}}}var location_url=request.getResponseHeader("Location");if(location_url&&this.env.action!="compose"){this.redirect(location_url)}if(request.status==403){(this.is_framed()?parent:window).location.reload();return}if(action=="keep-alive"){setTimeout(function(){ref.keep_alive();ref.start_keepalive()},30000)}};this.iframe_loaded=function(unlock){this.set_busy(false,null,unlock);if(this.submit_timer){clearTimeout(this.submit_timer)}};this.async_upload_form=function(form,action,onload){var frame,ts=new Date().getTime(),frame_name="rcmupload"+ts;if(this.env.upload_progress_name){var fname=this.env.upload_progress_name,field=$("input[name="+fname+"]",form);if(!field.length){field=$("<input>").attr({type:"hidden",name:fname});field.prependTo(form)}field.val(ts)}if(document.all){document.body.insertAdjacentHTML("BeforeEnd",'<iframe name="'+frame_name+'" src="program/resources/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>');frame=$('iframe[name="'+frame_name+'"]')}else{frame=$("<iframe>").attr("name",frame_name).css({border:"none",width:0,height:0,visibility:"hidden"}).appendTo(document.body)}frame.bind("load",{ts:ts},onload);$(form).attr({target:frame_name,action:this.url(action,{_id:this.env.compose_id||"",_uploadid:ts}),method:"POST"}).attr(form.encoding?"encoding":"enctype","multipart/form-data").submit();return frame_name};this.document_drag_hover=function(e,over){e.preventDefault();$(ref.gui_objects.filedrop)[(over?"addClass":"removeClass")]("active")};this.file_drag_hover=function(e,over){e.preventDefault();e.stopPropagation();$(ref.gui_objects.filedrop)[(over?"addClass":"removeClass")]("hover")};this.file_dropped=function(e){this.file_drag_hover(e,false);var files=e.target.files||e.dataTransfer.files,formdata=window.FormData?new FormData():null,fieldname=(this.env.filedrop.fieldname||"_file")+(this.env.filedrop.single?"":"[]"),boundary="------multipartformboundary"+(new Date).getTime(),dashdash="--",crlf="\r\n",multipart=dashdash+boundary+crlf;if(!files||!files.length){return}var submit_data=function(){var multiple=files.length>1,ts=new Date().getTime(),content="<span>"+(multiple?ref.get_label("uploadingmany"):files[0].name)+"</span>";if(!ref.add2attachment_list(ts,{name:"",html:content,classname:"uploading",complete:false})){ref.file_upload_id=ref.set_busy(true,"uploading")}multipart+=dashdash+boundary+dashdash+crlf;$.ajax({type:"POST",dataType:"json",url:ref.url(ref.env.filedrop.action||"upload",{_id:ref.env.compose_id||ref.env.cid||"",_uploadid:ts,_remote:1}),contentType:formdata?false:"multipart/form-data; boundary="+boundary,processData:false,timeout:0,data:formdata||multipart,headers:{"X-Roundcube-Request":ref.env.request_token},xhr:function(){var xhr=jQuery.ajaxSettings.xhr();if(!formdata&&xhr.sendAsBinary){xhr.send=xhr.sendAsBinary}return xhr},success:function(data){ref.http_response(data)},error:function(o,status,err){ref.http_error(o,status,err,null,"attachment")}})};var last=this.env.filedrop.single?0:files.length-1;for(var j=0,i=0,f;j<=last&&(f=files[i]);i++){if(!f.name){f.name=f.fileName}if(!f.size){f.size=f.fileSize}if(!f.type){f.type="application/octet-stream"}if(!formdata&&/[^\x20-\x7E]/.test(f.name)){f.name_bin=unescape(encodeURIComponent(f.name))}if(this.env.filedrop.filter&&!f.type.match(new RegExp(this.env.filedrop.filter))){continue}if(formdata){formdata.append(fieldname,f);if(j==last){return submit_data()}}else{if(window.FileReader){var reader=new FileReader();reader.onload=(function(file,j){return function(e){multipart+='Content-Disposition: form-data; name="'+fieldname+'"';multipart+='; filename="'+(f.name_bin||file.name)+'"'+crlf;multipart+="Content-Length: "+file.size+crlf;multipart+="Content-Type: "+file.type+crlf+crlf;multipart+=reader.result+crlf;multipart+=dashdash+boundary+crlf;if(j==last){return submit_data()}}})(f,j);reader.readAsBinaryString(f)}else{if(f.getAsBinary){multipart+='Content-Disposition: form-data; name="'+fieldname+'"';multipart+='; filename="'+(f.name_bin||f.name)+'"'+crlf;multipart+="Content-Length: "+f.size+crlf;multipart+="Content-Type: "+f.type+crlf+crlf;multipart+=f.getAsBinary()+crlf;multipart+=dashdash+boundary+crlf;if(j==last){return submit_data()}}}}j++}};this.start_keepalive=function(){if(!this.env.session_lifetime||this.env.framed||this.env.extwin||this.task=="login"||this.env.action=="print"){return}if(this._keepalive){clearInterval(this._keepalive)}this._keepalive=setInterval(function(){ref.keep_alive()},this.env.session_lifetime*0.5*1000)};this.start_refresh=function(){if(!this.env.refresh_interval||this.env.framed||this.env.extwin||this.task=="login"||this.env.action=="print"){return}if(this._refresh){clearInterval(this._refresh)}this._refresh=setInterval(function(){ref.refresh()},this.env.refresh_interval*1000)};this.keep_alive=function(){if(!this.busy){this.http_request("keep-alive")}};this.refresh=function(){if(this.busy){setTimeout(function(){ref.refresh();ref.start_refresh()},10000);return}var params={},lock=this.set_busy(true,"refreshing");if(this.task=="mail"&&this.gui_objects.mailboxlist){params=this.check_recent_params()}this.http_request("refresh",params,lock)};this.check_recent_params=function(){var params={_mbox:this.env.mailbox};if(this.gui_objects.mailboxlist){params._folderlist=1}if(this.gui_objects.messagelist){params._list=1}if(this.gui_objects.quotadisplay){params._quota=1}if(this.env.search_request){params._search=this.env.search_request}return params};this.opener=function(){try{if(window.opener&&!opener.closed&&opener.rcmail){return opener.rcmail}}catch(e){}};this.get_single_uid=function(){return this.env.uid?this.env.uid:(this.message_list?this.message_list.get_single_selection():null)};this.get_single_cid=function(){return this.env.cid?this.env.cid:(this.contact_list?this.contact_list.get_single_selection():null)};this.get_caret_pos=function(obj){if(obj.selectionEnd!==undefined){return obj.selectionEnd}if(document.selection&&document.selection.createRange){var range=document.selection.createRange();if(range.parentElement()!=obj){return 0}var gm=range.duplicate();if(obj.tagName=="TEXTAREA"){gm.moveToElementText(obj)}else{gm.expand("textedit")}gm.setEndPoint("EndToStart",range);var p=gm.text.length;return p<=obj.value.length?p:-1}return obj.value.length};this.set_caret_pos=function(obj,pos){if(obj.setSelectionRange){obj.setSelectionRange(pos,pos)}else{if(obj.createTextRange){var range=obj.createTextRange();range.collapse(true);range.moveEnd("character",pos);range.moveStart("character",pos);range.select()}}};this.lock_form=function(form,lock){if(!form||!form.elements){return}var n,len,elm;if(lock){this.disabled_form_elements=[]}for(n=0,len=form.elements.length;n<len;n++){elm=form.elements[n];if(elm.type=="hidden"){continue}if(lock&&elm.disabled){this.disabled_form_elements.push(elm)}else{if(lock||(this.disabled_form_elements&&$.inArray(elm,this.disabled_form_elements)<0)){elm.disabled=lock}}}};this.mailto_handler_uri=function(){return location.href.split("?")[0]+"?_task=mail&_action=compose&_to=%s"};this.register_protocol_handler=function(name){try{window.navigator.registerProtocolHandler("mailto",this.mailto_handler_uri(),name)}catch(e){}};this.check_protocol_handler=function(name,elem){var nav=window.navigator;if(!nav||(typeof nav.registerProtocolHandler!="function")||((typeof nav.isProtocolHandlerRegistered=="function")&&nav.isProtocolHandlerRegistered("mailto",this.mailto_handler_uri())=="registered")){$(elem).addClass("disabled")}else{$(elem).click(function(){rcmail.register_protocol_handler(name);return false})}};this.browser_capabilities_check=function(){if(!this.env.browser_capabilities){this.env.browser_capabilities={}}if(this.env.browser_capabilities.pdf===undefined){this.env.browser_capabilities.pdf=this.pdf_support_check()}if(this.env.browser_capabilities.flash===undefined){this.env.browser_capabilities.flash=this.flash_support_check()}if(this.env.browser_capabilities.tif===undefined){this.tif_support_check()}};this.browser_capabilities=function(){if(!this.env.browser_capabilities){return""}var n,ret=[];for(n in this.env.browser_capabilities){ret.push(n+"="+this.env.browser_capabilities[n])}return ret.join()};this.tif_support_check=function(){var img=new Image();img.onload=function(){rcmail.env.browser_capabilities.tif=1};img.onerror=function(){rcmail.env.browser_capabilities.tif=0};img.src="program/resources/blank.tif"};this.pdf_support_check=function(){var plugin=navigator.mimeTypes?navigator.mimeTypes["application/pdf"]:{},plugins=navigator.plugins,len=plugins.length,regex=/Adobe Reader|PDF|Acrobat/i;if(plugin&&plugin.enabledPlugin){return 1}if(window.ActiveXObject){try{if(axObj=new ActiveXObject("AcroPDF.PDF")){return 1}}catch(e){}try{if(axObj=new ActiveXObject("PDF.PdfCtrl")){return 1}}catch(e){}}for(i=0;i<len;i++){plugin=plugins[i];if(typeof plugin==="String"){if(regex.test(plugin)){return 1}}else{if(plugin.name&&regex.test(plugin.name)){return 1}}}return 0};this.flash_support_check=function(){var plugin=navigator.mimeTypes?navigator.mimeTypes["application/x-shockwave-flash"]:{};if(plugin&&plugin.enabledPlugin){return 1}if(window.ActiveXObject){try{if(axObj=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")){return 1}}catch(e){}}return 0};this.set_cookie=function(name,value,expires){setCookie(name,value,expires,this.env.cookie_path,this.env.cookie_domain,this.env.cookie_secure)}}rcube_webmail.long_subject_title=function(d,a){if(!d.title){var b=$(d);if(b.width()+a*15>b.parent().width()){d.title=b.text()}}};rcube_webmail.long_subject_title_ex=function(g,b){if(!g.title){var e=$(g),a=$.trim(e.text()),f=$("<span>").text(a).css({position:"absolute","float":"left",visibility:"hidden","font-size":e.css("font-size"),"font-weight":e.css("font-weight")}).appendTo($("body")),d=f.width();f.remove();if(d+b*15>e.width()){g.title=a}}};rcube_webmail.prototype.get_cookie=getCookie;rcube_webmail.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;rcube_webmail.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;rcube_webmail.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent; \ No newline at end of file
diff --git a/program/js/common.js b/program/js/common.js
index afaf91639..f6fa154ef 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -1,723 +1 @@
-/*
- +-----------------------------------------------------------------------+
- | Roundcube common js library |
- | |
- | This file is part of the Roundcube web development suite |
- | 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. |
- | |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com> |
- +-----------------------------------------------------------------------+
-*/
-
-// Constants
-var CONTROL_KEY = 1;
-var SHIFT_KEY = 2;
-var CONTROL_SHIFT_KEY = 3;
-
-
-/**
- * Default browser check class
- * @constructor
- */
-function roundcube_browser()
-{
- var n = navigator;
-
- this.ver = parseFloat(n.appVersion);
- this.appver = n.appVersion;
- this.agent = n.userAgent;
- this.agent_lc = n.userAgent.toLowerCase();
- this.name = n.appName;
- this.vendor = n.vendor ? n.vendor : '';
- this.vendver = n.vendorSub ? parseFloat(n.vendorSub) : 0;
- this.product = n.product ? n.product : '';
- this.platform = String(n.platform).toLowerCase();
- this.lang = (n.language) ? n.language.substring(0,2) :
- (n.browserLanguage) ? n.browserLanguage.substring(0,2) :
- (n.systemLanguage) ? n.systemLanguage.substring(0,2) : 'en';
-
- this.win = (this.platform.indexOf('win') >= 0);
- this.mac = (this.platform.indexOf('mac') >= 0);
- this.linux = (this.platform.indexOf('linux') >= 0);
- this.unix = (this.platform.indexOf('unix') >= 0);
-
- this.dom = document.getElementById ? true : false;
- this.dom2 = (document.addEventListener && document.removeEventListener);
-
- this.ie = (document.all && !window.opera);
- this.ie4 = (this.ie && !this.dom);
- this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0);
- this.ie8 = (this.dom && this.appver.indexOf('MSIE 8')>0);
- this.ie9 = (this.dom && this.appver.indexOf('MSIE 9')>0);
- this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0);
- this.ie6 = (this.dom && !this.ie8 && !this.ie7 && this.appver.indexOf('MSIE 6')>0);
-
- this.ns = ((this.ver < 5 && this.name == 'Netscape') || (this.ver >= 5 && this.vendor.indexOf('Netscape') >= 0));
- this.chrome = (this.agent_lc.indexOf('chrome') > 0);
- this.safari = (!this.chrome && (this.agent_lc.indexOf('safari') > 0 || this.agent_lc.indexOf('applewebkit') > 0));
- this.konq = (this.agent_lc.indexOf('konqueror') > 0);
- this.mz = (this.dom && !this.ie && !this.ns && !this.chrome && !this.safari && !this.konq && this.agent.indexOf('Mozilla') >= 0);
- this.iphone = (this.safari && (this.agent_lc.indexOf('iphone') > 0 || this.agent_lc.indexOf('ipod') > 0));
- this.ipad = (this.safari && this.agent_lc.indexOf('ipad') > 0);
- this.opera = window.opera ? true : false;
-
- if (this.opera && window.RegExp)
- this.vendver = (/opera(\s|\/)([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$2) : -1;
- else if (this.chrome && window.RegExp)
- this.vendver = (/chrome\/([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$1) : 0;
- else if (!this.vendver && this.safari)
- this.vendver = (/(safari|applewebkit)\/([0-9]+)/.test(this.agent_lc)) ? parseInt(RegExp.$2) : 0;
- else if ((!this.vendver && this.mz) || this.agent.indexOf('Camino')>0)
- this.vendver = (/rv:([0-9\.]+)/.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
- else if (this.ie && window.RegExp)
- this.vendver = (/msie\s+([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$1) : 0;
- else if (this.konq && window.RegExp)
- this.vendver = (/khtml\/([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$1) : 0;
-
- // get real language out of safari's user agent
- if (this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/.test(this.agent_lc)))
- this.lang = RegExp.$1;
-
- this.tablet = /ipad|android|xoom|sch-i800|playbook|tablet|kindle/i.test(this.agent_lc);
- this.mobile = /iphone|ipod|blackberry|iemobile|opera mini|opera mobi|mobile/i.test(this.agent_lc);
- this.touch = this.mobile || this.tablet;
- this.dhtml = ((this.ie4 && this.win) || this.ie5 || this.ie6 || this.ns4 || this.mz);
- this.vml = (this.win && this.ie && this.dom && !this.opera);
- this.pngalpha = (this.mz || (this.opera && this.vendver >= 6) || (this.ie && this.mac && this.vendver >= 5) ||
- (this.ie && this.win && this.vendver >= 5.5) || this.safari);
- this.opacity = (this.mz || (this.ie && this.vendver >= 5.5 && !this.opera) || (this.safari && this.vendver >= 100));
- this.cookies = n.cookieEnabled;
-
- // test for XMLHTTP support
- this.xmlhttp_test = function()
- {
- var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
- this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test()));
- return this.xmlhttp;
- };
-
- // set class names to html tag according to the current user agent detection
- // this allows browser-specific css selectors like "html.chrome .someclass"
- this.set_html_class = function()
- {
- var classname = ' js';
-
- if (this.ie)
- classname += ' ie ie'+parseInt(this.vendver);
- else if (this.opera)
- classname += ' opera';
- else if (this.konq)
- classname += ' konqueror';
- else if (this.safari)
- classname += ' chrome';
- else if (this.chrome)
- classname += ' chrome';
- else if (this.mz)
- classname += ' mozilla';
-
- if (this.iphone)
- classname += ' iphone';
- else if (this.ipad)
- classname += ' ipad';
- else if (this.safari || this.chrome)
- classname += ' webkit';
-
- if (this.mobile)
- classname += ' mobile';
- if (this.tablet)
- classname += ' tablet';
-
- if (document.documentElement)
- document.documentElement.className += classname;
- };
-};
-
-
-// static functions for DOM event handling
-var rcube_event = {
-
-/**
- * returns the event target element
- */
-get_target: function(e)
-{
- e = e || window.event;
- return e && e.target ? e.target : e.srcElement;
-},
-
-/**
- * returns the event key code
- */
-get_keycode: function(e)
-{
- e = e || window.event;
- return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns the event key code
- */
-get_button: function(e)
-{
- e = e || window.event;
- return e && e.button !== undefined ? e.button : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns modifier key (constants defined at top of file)
- */
-get_modifier: function(e)
-{
- var opcode = 0;
- e = e || window.event;
-
- if (bw.mac && e)
- opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
- else if (e)
- opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
-
- return opcode;
-},
-
-/**
- * Return absolute mouse position of an event
- */
-get_mouse_pos: function(e)
-{
- if (!e) e = window.event;
- var mX = (e.pageX) ? e.pageX : e.clientX,
- mY = (e.pageY) ? e.pageY : e.clientY;
-
- if (document.body && document.all) {
- mX += document.body.scrollLeft;
- mY += document.body.scrollTop;
- }
-
- if (e._offset) {
- mX += e._offset.left;
- mY += e._offset.top;
- }
-
- return { x:mX, y:mY };
-},
-
-/**
- * Add an object method as event listener to a certain element
- */
-add_listener: function(p)
-{
- if (!p.object || !p.method) // not enough arguments
- return;
- if (!p.element)
- p.element = document;
-
- if (!p.object._rc_events)
- p.object._rc_events = [];
-
- var key = p.event + '*' + p.method;
- if (!p.object._rc_events[key])
- p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
-
- if (p.element.addEventListener)
- p.element.addEventListener(p.event, p.object._rc_events[key], false);
- else if (p.element.attachEvent) {
- // IE allows multiple events with the same function to be applied to the same object
- // forcibly detach the event, then attach
- p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
- p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
- }
- else
- p.element['on'+p.event] = p.object._rc_events[key];
-},
-
-/**
- * Remove event listener
- */
-remove_listener: function(p)
-{
- if (!p.element)
- p.element = document;
-
- var key = p.event + '*' + p.method;
- if (p.object && p.object._rc_events && p.object._rc_events[key]) {
- if (p.element.removeEventListener)
- p.element.removeEventListener(p.event, p.object._rc_events[key], false);
- else if (p.element.detachEvent)
- p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
- else
- p.element['on'+p.event] = null;
- }
-},
-
-/**
- * Prevent event propagation and bubbling
- */
-cancel: function(evt)
-{
- var e = evt ? evt : window.event;
- if (e.preventDefault)
- e.preventDefault();
- if (e.stopPropagation)
- e.stopPropagation();
-
- e.cancelBubble = true;
- e.returnValue = false;
- return false;
-},
-
-touchevent: function(e)
-{
- return { pageX:e.pageX, pageY:e.pageY, offsetX:e.pageX - e.target.offsetLeft, offsetY:e.pageY - e.target.offsetTop, target:e.target, istouch:true };
-}
-
-};
-
-
-/**
- * rcmail objects event interface
- */
-function rcube_event_engine()
-{
- this._events = {};
-};
-
-rcube_event_engine.prototype = {
-
-/**
- * Setter for object event handlers
- *
- * @param {String} Event name
- * @param {Function} Handler function
- * @return Listener ID (used to remove this handler later on)
- */
-addEventListener: function(evt, func, obj)
-{
- if (!this._events)
- this._events = {};
- if (!this._events[evt])
- this._events[evt] = [];
-
- this._events[evt].push({func:func, obj:obj ? obj : window});
-},
-
-/**
- * Removes a specific event listener
- *
- * @param {String} Event name
- * @param {Int} Listener ID to remove
- */
-removeEventListener: function(evt, func, obj)
-{
- if (obj === undefined)
- obj = window;
-
- for (var h,i=0; this._events && this._events[evt] && i < this._events[evt].length; i++)
- if ((h = this._events[evt][i]) && h.func == func && h.obj == obj)
- this._events[evt][i] = null;
-},
-
-/**
- * This will execute all registered event handlers
- *
- * @param {String} Event to trigger
- * @param {Object} Event object/arguments
- */
-triggerEvent: function(evt, e)
-{
- var ret, h;
- if (e === undefined)
- e = this;
- else if (typeof e === 'object')
- e.event = evt;
-
- if (this._events && this._events[evt] && !this._event_exec) {
- this._event_exec = true;
- for (var i=0; i < this._events[evt].length; i++) {
- if ((h = this._events[evt][i])) {
- if (typeof h.func === 'function')
- ret = h.func.call ? h.func.call(h.obj, e) : h.func(e);
- else if (typeof h.obj[h.func] === 'function')
- ret = h.obj[h.func](e);
-
- // cancel event execution
- if (ret !== undefined && !ret)
- break;
- }
- }
- if (ret && ret.event) {
- try {
- delete ret.event;
- } catch (err) {
- // IE6-7 doesn't support deleting HTMLFormElement attributes (#1488017)
- $(ret).removeAttr('event');
- }
- }
- }
-
- this._event_exec = false;
- if (e.event) {
- try {
- delete e.event;
- } catch (err) {
- // IE6-7 doesn't support deleting HTMLFormElement attributes (#1488017)
- $(e).removeAttr('event');
- }
- }
-
- return ret;
-}
-
-}; // end rcube_event_engine.prototype
-
-
-// check if input is a valid email address
-// By Cal Henderson <cal@iamcal.com>
-// http://code.iamcal.com/php/rfc822/
-function rcube_check_email(input, inline)
-{
- if (input && window.RegExp) {
- var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]',
- dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]',
- atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+',
- quoted_pair = '\\x5c[\\x00-\\x7f]',
- quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22',
- ipv4 = '\\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\\]',
- ipv6 = '\\[IPv6:[0-9a-f:.]+\\]',
- ip_addr = '(' + ipv4 + ')|(' + ipv6 + ')',
- // Use simplified domain matching, because we need to allow Unicode characters here
- // So, e-mail address should be validated also on server side after idn_to_ascii() use
- //domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d',
- //sub_domain = '('+atom+'|'+domain_literal+')',
- // allow punycode/unicode top-level domain
- domain = '(('+ip_addr+')|(([^@\\x2e]+\\x2e)+([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,})))',
- // ICANN e-mail test (http://idn.icann.org/E-mail_test)
- icann_domains = [
- '\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631',
- '\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5',
- '\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66',
- '\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae',
- '\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e',
- '\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8',
- '\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8',
- '\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc',
- '\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435',
- '\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8',
- '\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8'
- ],
- icann_addr = 'mailtest\\x40('+icann_domains.join('|')+')',
- word = '('+atom+'|'+quoted_string+')',
- delim = '[,;\s\n]',
- local_part = word+'(\\x2e'+word+')*',
- addr_spec = '(('+local_part+'\\x40'+domain+')|('+icann_addr+'))',
- reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');
-
- return reg1.test(input) ? true : false;
- }
-
- return false;
-};
-
-// recursively copy an object
-function rcube_clone_object(obj)
-{
- var out = {};
-
- for (var key in obj) {
- if (obj[key] && typeof obj[key] === 'object')
- out[key] = rcube_clone_object(obj[key]);
- else
- out[key] = obj[key];
- }
-
- return out;
-};
-
-// make a string URL safe (and compatible with PHP's rawurlencode())
-function urlencode(str)
-{
- if (window.encodeURIComponent)
- return encodeURIComponent(str).replace('*', '%2A');
-
- return escape(str)
- .replace('+', '%2B')
- .replace('*', '%2A')
- .replace('/', '%2F')
- .replace('@', '%40');
-};
-
-
-// get any type of html objects by id/name
-function rcube_find_object(id, d)
-{
- var n, f, obj, e;
- if(!d) d = document;
-
- if(d.getElementsByName && (e = d.getElementsByName(id)))
- obj = e[0];
- if(!obj && d.getElementById)
- obj = d.getElementById(id);
- if(!obj && d.all)
- obj = d.all[id];
-
- if(!obj && d.images.length)
- obj = d.images[id];
-
- if (!obj && d.forms.length) {
- for (f=0; f<d.forms.length; f++) {
- if(d.forms[f].name == id)
- obj = d.forms[f];
- else if(d.forms[f].elements[id])
- obj = d.forms[f].elements[id];
- }
- }
-
- if (!obj && d.layers) {
- if (d.layers[id]) obj = d.layers[id];
- for (n=0; !obj && n<d.layers.length; n++)
- obj = rcube_find_object(id, d.layers[n].document);
- }
-
- return obj;
-};
-
-// determine whether the mouse is over the given object or not
-function rcube_mouse_is_over(ev, obj)
-{
- var mouse = rcube_event.get_mouse_pos(ev),
- pos = $(obj).offset();
-
- return ((mouse.x >= pos.left) && (mouse.x < (pos.left + obj.offsetWidth)) &&
- (mouse.y >= pos.top) && (mouse.y < (pos.top + obj.offsetHeight)));
-};
-
-
-// cookie functions by GoogieSpell
-function setCookie(name, value, expires, path, domain, secure)
-{
- var curCookie = name + "=" + escape(value) +
- (expires ? "; expires=" + expires.toGMTString() : "") +
- (path ? "; path=" + path : "") +
- (domain ? "; domain=" + domain : "") +
- (secure ? "; secure" : "");
- document.cookie = curCookie;
-};
-
-function getCookie(name)
-{
- var dc = document.cookie,
- prefix = name + "=",
- begin = dc.indexOf("; " + prefix);
-
- if (begin == -1) {
- begin = dc.indexOf(prefix);
- if (begin != 0)
- return null;
- }
- else {
- begin += 2;
- }
-
- var end = dc.indexOf(";", begin);
- if (end == -1)
- end = dc.length;
-
- return unescape(dc.substring(begin + prefix.length, end));
-};
-
-// deprecated aliases, to be removed, use rcmail.set_cookie/rcmail.get_cookie
-roundcube_browser.prototype.set_cookie = setCookie;
-roundcube_browser.prototype.get_cookie = getCookie;
-
-// tiny replacement for Firebox functionality
-function rcube_console()
-{
- this.log = function(msg)
- {
- var box = rcube_find_object('dbgconsole');
-
- if (box) {
- if (msg.charAt(msg.length-1)=='\n')
- msg += '--------------------------------------\n';
- else
- msg += '\n--------------------------------------\n';
-
- // Konqueror doesn't allow to just change the value of hidden element
- if (bw.konq) {
- box.innerText += msg;
- box.value = box.innerText;
- } else
- box.value += msg;
- }
- };
-
- this.reset = function()
- {
- var box = rcube_find_object('dbgconsole');
- if (box)
- box.innerText = box.value = '';
- };
-};
-
-var bw = new roundcube_browser();
-bw.set_html_class();
-
-
-// Add escape() method to RegExp object
-// http://dev.rubyonrails.org/changeset/7271
-RegExp.escape = function(str)
-{
- return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
-};
-
-// Extend Date prototype to detect Standard timezone without DST
-// from http://www.michaelapproved.com/articles/timezone-detect-and-ignore-daylight-saving-time-dst/
-Date.prototype.getStdTimezoneOffset = function()
-{
- var m = 12,
- d = new Date(null, m, 1),
- tzo = d.getTimezoneOffset();
-
- while (--m) {
- d.setUTCMonth(m);
- if (tzo != d.getTimezoneOffset()) {
- return Math.max(tzo, d.getTimezoneOffset());
- }
- }
-
- return tzo;
-}
-
-// Make getElementById() case-sensitive on IE
-if (bw.ie) {
- document._getElementById = document.getElementById;
- document.getElementById = function(id) {
- var i = 0, obj = document._getElementById(id);
-
- if (obj && obj.id != id)
- while ((obj = document.all[i]) && obj.id != id)
- i++;
-
- return obj;
- }
-}
-
-// jQuery plugin to emulate HTML5 placeholder attributes on input elements
-jQuery.fn.placeholder = function(text) {
- return this.each(function() {
- var active = false, elem = $(this);
- this.title = text;
-
- // Try HTML5 placeholder attribute first
- if ('placeholder' in this) {
- elem.attr('placeholder', text);
- }
- // Fallback to Javascript emulation of placeholder
- else {
- this._placeholder = text;
- elem.blur(function(e) {
- if ($.trim(elem.val()) == "")
- elem.val(text);
- elem.triggerHandler('change');
- })
- .focus(function(e) {
- if ($.trim(elem.val()) == text)
- elem.val("");
- elem.triggerHandler('change');
- })
- .change(function(e) {
- var active = elem.val() == text;
- elem[(active ? 'addClass' : 'removeClass')]('placeholder').attr('spellcheck', active);
- });
-
- // Do not blur currently focused element (catch exception: #1489008)
- try { active = this == document.activeElement; } catch(e) {}
- if (!active)
- elem.blur();
- }
- });
-};
-
-
-// This code was written by Tyler Akins and has been placed in the
-// public domain. It would be nice if you left this header intact.
-// Base64 code from Tyler Akins -- http://rumkin.com
-var Base64 = (function () {
- var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
- var obj = {
- /**
- * Encodes a string in base64
- * @param {String} input The string to encode in base64.
- */
- encode: function (input) {
- if (typeof(window.btoa) === 'function')
- return btoa(input);
-
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0, output = '', len = input.length;
-
- do {
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
-
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
-
- if (isNaN(chr2))
- enc3 = enc4 = 64;
- else if (isNaN(chr3))
- enc4 = 64;
-
- output = output
- + keyStr.charAt(enc1) + keyStr.charAt(enc2)
- + keyStr.charAt(enc3) + keyStr.charAt(enc4);
- } while (i < len);
-
- return output;
- },
-
- /**
- * Decodes a base64 string.
- * @param {String} input The string to decode.
- */
- decode: function (input) {
- if (typeof(window.atob) === 'function')
- return atob(input);
-
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4, len, i = 0, output = '';
-
- // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- len = input.length;
-
- do {
- enc1 = keyStr.indexOf(input.charAt(i++));
- enc2 = keyStr.indexOf(input.charAt(i++));
- enc3 = keyStr.indexOf(input.charAt(i++));
- enc4 = keyStr.indexOf(input.charAt(i++));
-
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
-
- output = output + String.fromCharCode(chr1);
-
- if (enc3 != 64)
- output = output + String.fromCharCode(chr2);
- if (enc4 != 64)
- output = output + String.fromCharCode(chr3);
- } while (i < len);
-
- return output;
- }
- };
-
- return obj;
-})();
+var CONTROL_KEY=1;var SHIFT_KEY=2;var CONTROL_SHIFT_KEY=3;function roundcube_browser(){var a=navigator;this.ver=parseFloat(a.appVersion);this.appver=a.appVersion;this.agent=a.userAgent;this.agent_lc=a.userAgent.toLowerCase();this.name=a.appName;this.vendor=a.vendor?a.vendor:"";this.vendver=a.vendorSub?parseFloat(a.vendorSub):0;this.product=a.product?a.product:"";this.platform=String(a.platform).toLowerCase();this.lang=(a.language)?a.language.substring(0,2):(a.browserLanguage)?a.browserLanguage.substring(0,2):(a.systemLanguage)?a.systemLanguage.substring(0,2):"en";this.win=(this.platform.indexOf("win")>=0);this.mac=(this.platform.indexOf("mac")>=0);this.linux=(this.platform.indexOf("linux")>=0);this.unix=(this.platform.indexOf("unix")>=0);this.dom=document.getElementById?true:false;this.dom2=(document.addEventListener&&document.removeEventListener);this.ie=(document.all&&!window.opera);this.ie4=(this.ie&&!this.dom);this.ie5=(this.dom&&this.appver.indexOf("MSIE 5")>0);this.ie8=(this.dom&&this.appver.indexOf("MSIE 8")>0);this.ie9=(this.dom&&this.appver.indexOf("MSIE 9")>0);this.ie7=(this.dom&&this.appver.indexOf("MSIE 7")>0);this.ie6=(this.dom&&!this.ie8&&!this.ie7&&this.appver.indexOf("MSIE 6")>0);this.ns=((this.ver<5&&this.name=="Netscape")||(this.ver>=5&&this.vendor.indexOf("Netscape")>=0));this.chrome=(this.agent_lc.indexOf("chrome")>0);this.safari=(!this.chrome&&(this.agent_lc.indexOf("safari")>0||this.agent_lc.indexOf("applewebkit")>0));this.konq=(this.agent_lc.indexOf("konqueror")>0);this.mz=(this.dom&&!this.ie&&!this.ns&&!this.chrome&&!this.safari&&!this.konq&&this.agent.indexOf("Mozilla")>=0);this.iphone=(this.safari&&(this.agent_lc.indexOf("iphone")>0||this.agent_lc.indexOf("ipod")>0));this.ipad=(this.safari&&this.agent_lc.indexOf("ipad")>0);this.opera=window.opera?true:false;if(this.opera&&window.RegExp){this.vendver=(/opera(\s|\/)([0-9\.]+)/.test(this.agent_lc))?parseFloat(RegExp.$2):-1}else{if(this.chrome&&window.RegExp){this.vendver=(/chrome\/([0-9\.]+)/.test(this.agent_lc))?parseFloat(RegExp.$1):0}else{if(!this.vendver&&this.safari){this.vendver=(/(safari|applewebkit)\/([0-9]+)/.test(this.agent_lc))?parseInt(RegExp.$2):0}else{if((!this.vendver&&this.mz)||this.agent.indexOf("Camino")>0){this.vendver=(/rv:([0-9\.]+)/.test(this.agent))?parseFloat(RegExp.$1):0}else{if(this.ie&&window.RegExp){this.vendver=(/msie\s+([0-9\.]+)/.test(this.agent_lc))?parseFloat(RegExp.$1):0}else{if(this.konq&&window.RegExp){this.vendver=(/khtml\/([0-9\.]+)/.test(this.agent_lc))?parseFloat(RegExp.$1):0}}}}}}if(this.safari&&(/;\s+([a-z]{2})-[a-z]{2}\)/.test(this.agent_lc))){this.lang=RegExp.$1}this.tablet=/ipad|android|xoom|sch-i800|playbook|tablet|kindle/i.test(this.agent_lc);this.mobile=/iphone|ipod|blackberry|iemobile|opera mini|opera mobi|mobile/i.test(this.agent_lc);this.touch=this.mobile||this.tablet;this.dhtml=((this.ie4&&this.win)||this.ie5||this.ie6||this.ns4||this.mz);this.vml=(this.win&&this.ie&&this.dom&&!this.opera);this.pngalpha=(this.mz||(this.opera&&this.vendver>=6)||(this.ie&&this.mac&&this.vendver>=5)||(this.ie&&this.win&&this.vendver>=5.5)||this.safari);this.opacity=(this.mz||(this.ie&&this.vendver>=5.5&&!this.opera)||(this.safari&&this.vendver>=100));this.cookies=a.cookieEnabled;this.xmlhttp_test=function(){var b=new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");this.xmlhttp=(window.XMLHttpRequest||(window.ActiveXObject&&b()));return this.xmlhttp};this.set_html_class=function(){var b=" js";if(this.ie){b+=" ie ie"+parseInt(this.vendver)}else{if(this.opera){b+=" opera"}else{if(this.konq){b+=" konqueror"}else{if(this.safari){b+=" chrome"}else{if(this.chrome){b+=" chrome"}else{if(this.mz){b+=" mozilla"}}}}}}if(this.iphone){b+=" iphone"}else{if(this.ipad){b+=" ipad"}else{if(this.safari||this.chrome){b+=" webkit"}}}if(this.mobile){b+=" mobile"}if(this.tablet){b+=" tablet"}if(document.documentElement){document.documentElement.className+=b}}}var rcube_event={get_target:function(a){a=a||window.event;return a&&a.target?a.target:a.srcElement},get_keycode:function(a){a=a||window.event;return a&&a.keyCode?a.keyCode:(a&&a.which?a.which:0)},get_button:function(a){a=a||window.event;return a&&a.button!==undefined?a.button:(a&&a.which?a.which:0)},get_modifier:function(b){var a=0;b=b||window.event;if(bw.mac&&b){a+=(b.metaKey&&CONTROL_KEY)+(b.shiftKey&&SHIFT_KEY)}else{if(b){a+=(b.ctrlKey&&CONTROL_KEY)+(b.shiftKey&&SHIFT_KEY)}}return a},get_mouse_pos:function(c){if(!c){c=window.event}var b=(c.pageX)?c.pageX:c.clientX,a=(c.pageY)?c.pageY:c.clientY;if(document.body&&document.all){b+=document.body.scrollLeft;a+=document.body.scrollTop}if(c._offset){b+=c._offset.left;a+=c._offset.top}return{x:b,y:a}},add_listener:function(b){if(!b.object||!b.method){return}if(!b.element){b.element=document}if(!b.object._rc_events){b.object._rc_events=[]}var a=b.event+"*"+b.method;if(!b.object._rc_events[a]){b.object._rc_events[a]=function(c){return b.object[b.method](c)}}if(b.element.addEventListener){b.element.addEventListener(b.event,b.object._rc_events[a],false)}else{if(b.element.attachEvent){b.element.detachEvent("on"+b.event,b.object._rc_events[a]);b.element.attachEvent("on"+b.event,b.object._rc_events[a])}else{b.element["on"+b.event]=b.object._rc_events[a]}}},remove_listener:function(b){if(!b.element){b.element=document}var a=b.event+"*"+b.method;if(b.object&&b.object._rc_events&&b.object._rc_events[a]){if(b.element.removeEventListener){b.element.removeEventListener(b.event,b.object._rc_events[a],false)}else{if(b.element.detachEvent){b.element.detachEvent("on"+b.event,b.object._rc_events[a])}else{b.element["on"+b.event]=null}}}},cancel:function(a){var b=a?a:window.event;if(b.preventDefault){b.preventDefault()}if(b.stopPropagation){b.stopPropagation()}b.cancelBubble=true;b.returnValue=false;return false},touchevent:function(a){return{pageX:a.pageX,pageY:a.pageY,offsetX:a.pageX-a.target.offsetLeft,offsetY:a.pageY-a.target.offsetTop,target:a.target,istouch:true}}};function rcube_event_engine(){this._events={}}rcube_event_engine.prototype={addEventListener:function(a,b,d){if(!this._events){this._events={}}if(!this._events[a]){this._events[a]=[]}var c={func:b,obj:d?d:window};this._events[a][this._events[a].length]=c},removeEventListener:function(a,d,e){if(e===undefined){e=window}for(var c,b=0;this._events&&this._events[a]&&b<this._events[a].length;b++){if((c=this._events[a][b])&&c.func==d&&c.obj==e){this._events[a][b]=null}}},triggerEvent:function(a,g){var b,d;if(g===undefined){g=this}else{if(typeof g==="object"){g.event=a}}if(this._events&&this._events[a]&&!this._event_exec){this._event_exec=true;for(var c=0;c<this._events[a].length;c++){if((d=this._events[a][c])){if(typeof d.func==="function"){b=d.func.call?d.func.call(d.obj,g):d.func(g)}else{if(typeof d.obj[d.func]==="function"){b=d.obj[d.func](g)}}if(b!==undefined&&!b){break}}}if(b&&b.event){try{delete b.event}catch(f){$(b).removeAttr("event")}}}this._event_exec=false;if(g.event){try{delete g.event}catch(f){$(g).removeAttr("event")}}return b}};function rcube_layer(b,a){this.name=b;this.create=function(m){var d=(m.x)?m.x:0,k=(m.y)?m.y:0,j=m.width,f=m.height,g=m.zindex,c=m.vis,i=m.parent,e=document.createElement("DIV");e.id=this.name;e.style.position="absolute";e.style.visibility=(c)?(c==2)?"inherit":"visible":"hidden";e.style.left=d+"px";e.style.top=k+"px";if(j){e.style.width=j.toString().match(/\%$/)?j:j+"px"}if(f){e.style.height=f.toString().match(/\%$/)?f:f+"px"}if(g){e.style.zIndex=g}if(i){i.appendChild(e)}else{document.body.appendChild(e)}this.elm=e};if(a!=null){this.create(a);this.name=this.elm.id}else{this.elm=document.getElementById(b)}if(!this.elm){return false}this.css=this.elm.style;this.event=this.elm;this.width=this.elm.offsetWidth;this.height=this.elm.offsetHeight;this.x=parseInt(this.elm.offsetLeft);this.y=parseInt(this.elm.offsetTop);this.visible=(this.css.visibility=="visible"||this.css.visibility=="show"||this.css.visibility=="inherit")?true:false;this.move=function(c,d){this.x=c;this.y=d;this.css.left=Math.round(this.x)+"px";this.css.top=Math.round(this.y)+"px"};this.resize=function(c,d){this.css.width=c+"px";this.css.height=d+"px";this.width=c;this.height=d};this.show=function(c){if(c==1){this.css.visibility="visible";this.visible=true}else{if(c==2){this.css.visibility="inherit";this.visible=true}else{this.css.visibility="hidden";this.visible=false}}};this.write=function(c){this.elm.innerHTML=c}}function rcube_check_email(h,c){if(h&&window.RegExp){var f="[^\\x0d\\x22\\x5c\\x80-\\xff]",e="[^\\x0d\\x5b-\\x5d\\x80-\\xff]",a="[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+",g="\\x5c[\\x00-\\x7f]",l="\\x22("+f+"|"+g+")*\\x22",k="\\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\\]",j="\\[IPv6:[0-9a-f:.]+\\]",i="("+k+")|("+j+")",r="(("+i+")|(([^@\\x2e]+\\x2e)+([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,})))",d=["\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631","\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5","\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66","\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae","\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e","\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8","\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8","\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc","\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435","\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8","\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8"],p="mailtest\\x40("+d.join("|")+")",n="("+a+"|"+l+")",q="[,;s\n]",m=n+"(\\x2e"+n+")*",b="(("+m+"\\x40"+r+")|("+p+"))",o=c?new RegExp("(^|<|"+q+")"+b+"($|>|"+q+")","i"):new RegExp("^"+b+"$","i");return o.test(h)?true:false}return false}function rcube_clone_object(c){var a={};for(var b in c){if(c[b]&&typeof c[b]==="object"){a[b]=clone_object(c[b])}else{a[b]=c[b]}}return a}function urlencode(a){if(window.encodeURIComponent){return encodeURIComponent(a).replace("*","%2A")}return escape(a).replace("+","%2B").replace("*","%2A").replace("/","%2F").replace("@","%40")}function rcube_find_object(i,g){var h,a,c,b;if(!g){g=document}if(g.getElementsByName&&(b=g.getElementsByName(i))){c=b[0]}if(!c&&g.getElementById){c=g.getElementById(i)}if(!c&&g.all){c=g.all[i]}if(!c&&g.images.length){c=g.images[i]}if(!c&&g.forms.length){for(a=0;a<g.forms.length;a++){if(g.forms[a].name==i){c=g.forms[a]}else{if(g.forms[a].elements[i]){c=g.forms[a].elements[i]}}}}if(!c&&g.layers){if(g.layers[i]){c=g.layers[i]}for(h=0;!c&&h<g.layers.length;h++){c=rcube_find_object(i,g.layers[h].document)}}return c}function rcube_mouse_is_over(b,c){var a=rcube_event.get_mouse_pos(b),d=$(c).offset();return((a.x>=d.left)&&(a.x<(d.left+c.offsetWidth))&&(a.y>=d.top)&&(a.y<(d.top+c.offsetHeight)))}function setCookie(c,e,a,g,d,f){var b=c+"="+escape(e)+(a?"; expires="+a.toGMTString():"")+(g?"; path="+g:"")+(d?"; domain="+d:"")+(f?"; secure":"");document.cookie=b}function getCookie(c){var b=document.cookie,e=c+"=",d=b.indexOf("; "+e);if(d==-1){d=b.indexOf(e);if(d!=0){return null}}else{d+=2}var a=b.indexOf(";",d);if(a==-1){a=b.length}return unescape(b.substring(d+e.length,a))}roundcube_browser.prototype.set_cookie=setCookie;roundcube_browser.prototype.get_cookie=getCookie;function rcube_console(){this.log=function(b){var a=rcube_find_object("dbgconsole");if(a){if(b.charAt(b.length-1)=="\n"){b+="--------------------------------------\n"}else{b+="\n--------------------------------------\n"}if(bw.konq){a.innerText+=b;a.value=a.innerText}else{a.value+=b}}};this.reset=function(){var a=rcube_find_object("dbgconsole");if(a){a.innerText=a.value=""}}}var bw=new roundcube_browser();bw.set_html_class();RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};Date.prototype.getStdTimezoneOffset=function(){var a=12,c=new Date(null,a,1),b=c.getTimezoneOffset();while(--a){c.setUTCMonth(a);if(b!=c.getTimezoneOffset()){return Math.max(b,c.getTimezoneOffset())}}return b};if(bw.ie){document._getElementById=document.getElementById;document.getElementById=function(c){var a=0,b=document._getElementById(c);if(b&&b.id!=c){while((b=document.all[a])&&b.id!=c){a++}}return b}}jQuery.fn.placeholder=function(a){return this.each(function(){var d=false,b=$(this);this.title=a;if("placeholder" in this){b.attr("placeholder",a)}else{this._placeholder=a;b.blur(function(f){if($.trim(b.val())==""){b.val(a)}b.triggerHandler("change")}).focus(function(f){if($.trim(b.val())==a){b.val("")}b.triggerHandler("change")}).change(function(g){var f=b.val()==a;b[(f?"addClass":"removeClass")]("placeholder").attr("spellcheck",f)});try{d=this==document.activeElement}catch(c){}if(!d){b.blur()}}})};var Base64=(function(){var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var b={encode:function(f){if(typeof(window.btoa)==="function"){return btoa(f)}var n,l,j,m,k,h,g,d=0,c="",e=f.length;do{n=f.charCodeAt(d++);l=f.charCodeAt(d++);j=f.charCodeAt(d++);m=n>>2;k=((n&3)<<4)|(l>>4);h=((l&15)<<2)|(j>>6);g=j&63;if(isNaN(l)){h=g=64}else{if(isNaN(j)){g=64}}c=c+a.charAt(m)+a.charAt(k)+a.charAt(h)+a.charAt(g)}while(d<e);return c},decode:function(f){if(typeof(window.atob)==="function"){return atob(f)}var n,l,j,m,k,h,g,e,d=0,c="";f=f.replace(/[^A-Za-z0-9\+\/\=]/g,"");e=f.length;do{m=a.indexOf(f.charAt(d++));k=a.indexOf(f.charAt(d++));h=a.indexOf(f.charAt(d++));g=a.indexOf(f.charAt(d++));n=(m<<2)|(k>>4);l=((k&15)<<4)|(h>>2);j=((h&3)<<6)|g;c=c+String.fromCharCode(n);if(h!=64){c=c+String.fromCharCode(l)}if(g!=64){c=c+String.fromCharCode(j)}}while(d<e);return c}};return b})(); \ No newline at end of file
diff --git a/program/js/editor.js b/program/js/editor.js
index e403d1f63..bc36e9a39 100644
--- a/program/js/editor.js
+++ b/program/js/editor.js
@@ -41,7 +41,7 @@ function rcmail_editor_init(config)
$.extend(conf, {
plugins: 'paste,tabfocus',
theme_advanced_buttons1: 'bold,italic,underline,strikethrough,justifyleft,justifycenter,justifyright,justifyfull,separator,outdent,indent,charmap,hr,link,unlink,code,forecolor',
- theme_advanced_buttons2: 'fontselect,fontsizeselect'
+ theme_advanced_buttons2: ',fontselect,fontsizeselect'
});
else { // mail compose
$.extend(conf, {
diff --git a/program/js/googiespell.js b/program/js/googiespell.js
index 9832116dd..6d0a19c06 100644
--- a/program/js/googiespell.js
+++ b/program/js/googiespell.js
@@ -1,1135 +1 @@
-/*
- +-----------------------------------------------------------------------+
- | Roundcube SpellCheck script |
- | jQuery'fied spell checker based on GoogieSpell 4.0 |
- | (which was published under GPL "version 2 or any later version") |
- | |
- | This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006 Amir Salihefendic |
- | Copyright (C) 2009 The Roundcube Dev Team |
- | Copyright (C) 2011 Kolab Systems AG |
- | |
- | 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. |
- | |
- +-----------------------------------------------------------------------+
- | Authors: 4mir Salihefendic <amix@amix.dk> |
- | Aleksander Machniak - <alec [at] alec.pl> |
- +-----------------------------------------------------------------------+
-*/
-
-var GOOGIE_CUR_LANG,
- GOOGIE_DEFAULT_LANG = 'en';
-
-function GoogieSpell(img_dir, server_url, has_dict)
-{
- var ref = this,
- cookie_value = rcmail.get_cookie('language');
-
- GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG;
-
- this.array_keys = function(arr) {
- var res = [];
- for (var key in arr) { res.push([key]); }
- return res;
- }
-
- this.img_dir = img_dir;
- this.server_url = server_url;
-
- this.org_lang_to_word = {
- "da": "Dansk", "de": "Deutsch", "en": "English",
- "es": "Español", "fr": "Français", "it": "Italiano",
- "nl": "Nederlands", "pl": "Polski", "pt": "Português",
- "ru": "РуÑÑкий", "fi": "Suomi", "sv": "Svenska"
- };
- this.lang_to_word = this.org_lang_to_word;
- this.langlist_codes = this.array_keys(this.lang_to_word);
- this.show_change_lang_pic = true;
- this.change_lang_pic_placement = 'right';
- this.report_state_change = true;
-
- this.ta_scroll_top = 0;
- this.el_scroll_top = 0;
-
- this.lang_chck_spell = "Check spelling";
- this.lang_revert = "Revert to";
- this.lang_close = "Close";
- this.lang_rsm_edt = "Resume editing";
- this.lang_no_error_found = "No spelling errors found";
- this.lang_no_suggestions = "No suggestions";
- this.lang_learn_word = "Add to dictionary";
-
- this.show_spell_img = false; // roundcube mod.
- this.decoration = true;
- this.use_close_btn = false;
- this.edit_layer_dbl_click = true;
- this.report_ta_not_found = true;
-
- // Extensions
- this.custom_ajax_error = null;
- this.custom_no_spelling_error = null;
- this.custom_menu_builder = []; // Should take an eval function and a build menu function
- this.custom_item_evaulator = null; // Should take an eval function and a build menu function
- this.extra_menu_items = [];
- this.custom_spellcheck_starter = null;
- this.main_controller = true;
- this.has_dictionary = has_dict;
-
- // Observers
- this.lang_state_observer = null;
- this.spelling_state_observer = null;
- this.show_menu_observer = null;
- this.all_errors_fixed_observer = null;
-
- // Focus links - used to give the text box focus
- this.use_focus = false;
- this.focus_link_t = null;
- this.focus_link_b = null;
-
- // Counters
- this.cnt_errors = 0;
- this.cnt_errors_fixed = 0;
-
- // Set document's onclick to hide the language and error menu
- $(document).bind('click', function(e) {
- var target = $(e.target);
- if(target.attr('googie_action_btn') != '1' && ref.isLangWindowShown())
- ref.hideLangWindow();
- if(target.attr('googie_action_btn') != '1' && ref.isErrorWindowShown())
- ref.hideErrorWindow();
- });
-
-
-this.decorateTextarea = function(id)
-{
- this.text_area = typeof id === 'string' ? document.getElementById(id) : id;
-
- if (this.text_area) {
- if (!this.spell_container && this.decoration) {
- var table = document.createElement('table'),
- tbody = document.createElement('tbody'),
- tr = document.createElement('tr'),
- spell_container = document.createElement('td'),
- r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth,
- r_height = this.isDefined(this.force_height) ? this.force_height : 16;
-
- tr.appendChild(spell_container);
- tbody.appendChild(tr);
- $(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height);
- $(spell_container).height(r_height).width(r_width).css('text-align', 'right');
-
- this.spell_container = spell_container;
- }
-
- this.checkSpellingState();
- }
- else if (this.report_ta_not_found)
- alert('Text area not found');
-};
-
-//////
-// API Functions (the ones that you can call)
-/////
-this.setSpellContainer = function(id)
-{
- this.spell_container = typeof id === 'string' ? document.getElementById(id) : id;
-};
-
-this.setLanguages = function(lang_dict)
-{
- this.lang_to_word = lang_dict;
- this.langlist_codes = this.array_keys(lang_dict);
-};
-
-this.setCurrentLanguage = function(lan_code)
-{
- GOOGIE_CUR_LANG = lan_code;
-
- //Set cookie
- var now = new Date();
- now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
- rcmail.set_cookie('language', lan_code, now);
-};
-
-this.setForceWidthHeight = function(width, height)
-{
- // Set to null if you want to use one of them
- this.force_width = width;
- this.force_height = height;
-};
-
-this.setDecoration = function(bool)
-{
- this.decoration = bool;
-};
-
-this.dontUseCloseButtons = function()
-{
- this.use_close_btn = false;
-};
-
-this.appendNewMenuItem = function(name, call_back_fn, checker)
-{
- this.extra_menu_items.push([name, call_back_fn, checker]);
-};
-
-this.appendCustomMenuBuilder = function(eval_fn, builder)
-{
- this.custom_menu_builder.push([eval_fn, builder]);
-};
-
-this.setFocus = function()
-{
- try {
- this.focus_link_b.focus();
- this.focus_link_t.focus();
- return true;
- }
- catch(e) {
- return false;
- }
-};
-
-
-//////
-// Set functions (internal)
-/////
-this.setStateChanged = function(current_state)
-{
- this.state = current_state;
- if (this.spelling_state_observer != null && this.report_state_change)
- this.spelling_state_observer(current_state, this);
-};
-
-this.setReportStateChange = function(bool)
-{
- this.report_state_change = bool;
-};
-
-
-//////
-// Request functions
-/////
-this.getUrl = function()
-{
- return this.server_url + GOOGIE_CUR_LANG;
-};
-
-this.escapeSpecial = function(val)
-{
- return val ? val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") : '';
-};
-
-this.createXMLReq = function (text)
-{
- return '<?xml version="1.0" encoding="utf-8" ?>'
- + '<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
- + '<text>' + text + '</text></spellrequest>';
-};
-
-this.spellCheck = function(ignore)
-{
- this.prepare(ignore);
-
- var req_text = this.escapeSpecial(this.orginal_text),
- ref = this;
-
- $.ajax({ type: 'POST', url: this.getUrl(), data: this.createXMLReq(req_text), dataType: 'text',
- error: function(o) {
- if (ref.custom_ajax_error)
- ref.custom_ajax_error(ref);
- else
- alert('An error was encountered on the server. Please try again later.');
- if (ref.main_controller) {
- $(ref.spell_span).remove();
- ref.removeIndicator();
- }
- ref.checkSpellingState();
- },
- success: function(data) {
- ref.processData(data);
- if (!ref.results.length) {
- if (!ref.custom_no_spelling_error)
- ref.flashNoSpellingErrorState();
- else
- ref.custom_no_spelling_error(ref);
- }
- ref.removeIndicator();
- }
- });
-};
-
-this.learnWord = function(word, id)
-{
- word = this.escapeSpecial(word.innerHTML);
-
- var ref = this,
- req_text = '<?xml version="1.0" encoding="utf-8" ?><learnword><text>' + word + '</text></learnword>';
-
- $.ajax({ type: 'POST', url: this.getUrl(), data: req_text, dataType: 'text',
- error: function(o) {
- if (ref.custom_ajax_error)
- ref.custom_ajax_error(ref);
- else
- alert('An error was encountered on the server. Please try again later.');
- },
- success: function(data) {
- }
- });
-};
-
-
-//////
-// Spell checking functions
-/////
-this.prepare = function(ignore, no_indicator)
-{
- this.cnt_errors_fixed = 0;
- this.cnt_errors = 0;
- this.setStateChanged('checking_spell');
-
- if (!no_indicator && this.main_controller)
- this.appendIndicator(this.spell_span);
-
- this.error_links = [];
- this.ta_scroll_top = this.text_area.scrollTop;
- this.ignore = ignore;
- this.hideLangWindow();
-
- if ($(this.text_area).val() == '' || ignore) {
- if (!this.custom_no_spelling_error)
- this.flashNoSpellingErrorState();
- else
- this.custom_no_spelling_error(this);
- this.removeIndicator();
- return;
- }
-
- this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
- this.createErrorWindow();
- $('body').append(this.error_window);
-
- try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); }
- catch (e) { }
-
- if (this.main_controller)
- $(this.spell_span).unbind('click');
-
- this.orginal_text = $(this.text_area).val();
-};
-
-this.parseResult = function(r_text)
-{
- // Returns an array: result[item] -> ['attrs'], ['suggestions']
- var re_split_attr_c = /\w+="(\d+|true)"/g,
- re_split_text = /\t/g,
- matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g),
- results = [];
-
- if (matched_c == null)
- return results;
-
- for (var i=0, len=matched_c.length; i < len; i++) {
- var item = [];
- this.errorFound();
-
- // Get attributes
- item['attrs'] = [];
- var c_attr, val,
- split_c = matched_c[i].match(re_split_attr_c);
- for (var j=0; j < split_c.length; j++) {
- c_attr = split_c[j].split(/=/);
- val = c_attr[1].replace(/"/g, '');
- item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val;
- }
-
- // Get suggestions
- item['suggestions'] = [];
- var only_text = matched_c[i].replace(/<[^>]*>/g, ''),
- split_t = only_text.split(re_split_text);
- for (var k=0; k < split_t.length; k++) {
- if(split_t[k] != '')
- item['suggestions'].push(split_t[k]);
- }
- results.push(item);
- }
-
- return results;
-};
-
-this.processData = function(data)
-{
- this.results = this.parseResult(data);
- if (this.results.length) {
- this.showErrorsInIframe();
- this.resumeEditingState();
- }
-};
-
-//////
-// Error menu functions
-/////
-this.createErrorWindow = function()
-{
- this.error_window = document.createElement('div');
- $(this.error_window).addClass('googie_window popupmenu').attr('googie_action_btn', '1');
-};
-
-this.isErrorWindowShown = function()
-{
- return $(this.error_window).is(':visible');
-};
-
-this.hideErrorWindow = function()
-{
- $(this.error_window).hide();
- $(this.error_window_iframe).hide();
-};
-
-this.updateOrginalText = function(offset, old_value, new_value, id)
-{
- var part_1 = this.orginal_text.substring(0, offset),
- part_2 = this.orginal_text.substring(offset+old_value.length),
- add_2_offset = new_value.length - old_value.length;
-
- this.orginal_text = part_1 + new_value + part_2;
- $(this.text_area).val(this.orginal_text);
- for (var j=0, len=this.results.length; j<len; j++) {
- // Don't edit the offset of the current item
- if (j != id && j > id)
- this.results[j]['attrs']['o'] += add_2_offset;
- }
-};
-
-this.saveOldValue = function(elm, old_value) {
- elm.is_changed = true;
- elm.old_value = old_value;
-};
-
-this.createListSeparator = function()
-{
- var td = document.createElement('td'),
- tr = document.createElement('tr');
-
- $(td).html(' ').attr('googie_action_btn', '1')
- .css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'});
- tr.appendChild(td);
-
- return tr;
-};
-
-this.correctError = function(id, elm, l_elm, rm_pre_space)
-{
- var old_value = elm.innerHTML,
- new_value = l_elm.nodeType == 3 ? l_elm.nodeValue : l_elm.innerHTML,
- offset = this.results[id]['attrs']['o'];
-
- if (rm_pre_space) {
- var pre_length = elm.previousSibling.innerHTML;
- elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1);
- old_value = " " + old_value;
- offset--;
- }
-
- this.hideErrorWindow();
- this.updateOrginalText(offset, old_value, new_value, id);
-
- $(elm).html(new_value).css('color', 'green').attr('is_corrected', true);
-
- this.results[id]['attrs']['l'] = new_value.length;
-
- if (!this.isDefined(elm.old_value))
- this.saveOldValue(elm, old_value);
-
- this.errorFixed();
-};
-
-this.ignoreError = function(elm, id)
-{
- // @TODO: ignore all same words
- $(elm).removeAttr('class').css('color', '').unbind();
- this.hideErrorWindow();
-};
-
-this.showErrorWindow = function(elm, id)
-{
- if (this.show_menu_observer)
- this.show_menu_observer(this);
-
- var ref = this,
- pos = $(elm).offset(),
- table = document.createElement('table'),
- list = document.createElement('tbody');
-
- $(this.error_window).html('');
- $(table).addClass('googie_list').attr('googie_action_btn', '1');
-
- // Check if we should use custom menu builder, if not we use the default
- var changed = false;
- for (var k=0; k<this.custom_menu_builder.length; k++) {
- var eb = this.custom_menu_builder[k];
- if (eb[0](this.results[id])) {
- changed = eb[1](this, list, elm);
- break;
- }
- }
-
- if (!changed) {
- // Build up the result list
- var suggestions = this.results[id]['suggestions'],
- offset = this.results[id]['attrs']['o'],
- len = this.results[id]['attrs']['l'],
- row, item, dummy;
-
- // [Add to dictionary] button
- if (this.has_dictionary && !$(elm).attr('is_corrected')) {
- row = document.createElement('tr'),
- item = document.createElement('td'),
- dummy = document.createElement('span');
-
- $(dummy).text(this.lang_learn_word);
- $(item).attr('googie_action_btn', '1').css('cursor', 'default')
- .mouseover(ref.item_onmouseover)
- .mouseout(ref.item_onmouseout)
- .click(function(e) {
- ref.learnWord(elm, id);
- ref.ignoreError(elm, id);
- });
-
- item.appendChild(dummy);
- row.appendChild(item);
- list.appendChild(row);
- }
-/*
- if (suggestions.length == 0) {
- row = document.createElement('tr'),
- item = document.createElement('td'),
- dummy = document.createElement('span');
-
- $(dummy).text(this.lang_no_suggestions);
- $(item).attr('googie_action_btn', '1').css('cursor', 'default');
-
- item.appendChild(dummy);
- row.appendChild(item);
- list.appendChild(row);
- }
-*/
- for (var i=0, len=suggestions.length; i < len; i++) {
- row = document.createElement('tr'),
- item = document.createElement('td'),
- dummy = document.createElement('span');
-
- $(dummy).html(suggestions[i]);
-
- $(item).mouseover(this.item_onmouseover).mouseout(this.item_onmouseout)
- .click(function(e) { ref.correctError(id, elm, e.target.firstChild) });
-
- item.appendChild(dummy);
- row.appendChild(item);
- list.appendChild(row);
- }
-
- // The element is changed, append the revert
- if (elm.is_changed && elm.innerHTML != elm.old_value) {
- var old_value = elm.old_value,
- revert_row = document.createElement('tr'),
- revert = document.createElement('td'),
- rev_span = document.createElement('span');
-
- $(rev_span).addClass('googie_list_revert').html(this.lang_revert + ' ' + old_value);
-
- $(revert).mouseover(this.item_onmouseover).mouseout(this.item_onmouseout)
- .click(function(e) {
- ref.updateOrginalText(offset, elm.innerHTML, old_value, id);
- $(elm).removeAttr('is_corrected').css('color', '#b91414').html(old_value);
- ref.hideErrorWindow();
- });
-
- revert.appendChild(rev_span);
- revert_row.appendChild(revert);
- list.appendChild(revert_row);
- }
-
- // Append the edit box
- var edit_row = document.createElement('tr'),
- edit = document.createElement('td'),
- edit_input = document.createElement('input'),
- ok_pic = document.createElement('img'),
- edit_form = document.createElement('form');
-
- var onsub = function () {
- if (edit_input.value != '') {
- if (!ref.isDefined(elm.old_value))
- ref.saveOldValue(elm, elm.innerHTML);
-
- ref.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
- $(elm).attr('is_corrected', true).css('color', 'green').html(edit_input.value);
- ref.hideErrorWindow();
- }
- return false;
- };
-
- $(edit_input).width(120).css({'margin': 0, 'padding': 0});
- $(edit_input).val(elm.innerHTML).attr('googie_action_btn', '1');
- $(edit).css('cursor', 'default').attr('googie_action_btn', '1');
-
- $(ok_pic).attr('src', this.img_dir + 'ok.gif')
- .width(32).height(16)
- .css({'cursor': 'pointer', 'margin-left': '2px', 'margin-right': '2px'})
- .click(onsub);
-
- $(edit_form).attr('googie_action_btn', '1')
- .css({'margin': 0, 'padding': 0, 'cursor': 'default', 'white-space': 'nowrap'})
- .submit(onsub);
-
- edit_form.appendChild(edit_input);
- edit_form.appendChild(ok_pic);
- edit.appendChild(edit_form);
- edit_row.appendChild(edit);
- list.appendChild(edit_row);
-
- // Append extra menu items
- if (this.extra_menu_items.length > 0)
- list.appendChild(this.createListSeparator());
-
- var loop = function(i) {
- if (i < ref.extra_menu_items.length) {
- var e_elm = ref.extra_menu_items[i];
-
- if (!e_elm[2] || e_elm[2](elm, ref)) {
- var e_row = document.createElement('tr'),
- e_col = document.createElement('td');
-
- $(e_col).html(e_elm[0])
- .mouseover(ref.item_onmouseover)
- .mouseout(ref.item_onmouseout)
- .click(function() { return e_elm[1](elm, ref) });
-
- e_row.appendChild(e_col);
- list.appendChild(e_row);
- }
- loop(i+1);
- }
- };
-
- loop(0);
- loop = null;
-
- //Close button
- if (this.use_close_btn) {
- list.appendChild(this.createCloseButton(this.hideErrorWindow));
- }
- }
-
- table.appendChild(list);
- this.error_window.appendChild(table);
-
- // calculate and set position
- var height = $(this.error_window).height(),
- width = $(this.error_window).width(),
- pageheight = $(document).height(),
- pagewidth = $(document).width(),
- top = pos.top + height + 20 < pageheight ? pos.top + 20 : pos.top - height,
- left = pos.left + width < pagewidth ? pos.left : pos.left - width;
-
- $(this.error_window).css({'top': top+'px', 'left': left+'px'}).show();
-
- // Dummy for IE - dropdown bug fix
- if (document.all && !window.opera) {
- if (!this.error_window_iframe) {
- var iframe = $('<iframe>').css({'position': 'absolute', 'z-index': -1});
- $('body').append(iframe);
- this.error_window_iframe = iframe;
- }
-
- $(this.error_window_iframe)
- .css({'top': this.error_window.offsetTop, 'left': this.error_window.offsetLeft,
- 'width': this.error_window.offsetWidth, 'height': this.error_window.offsetHeight})
- .show();
- }
-};
-
-
-//////
-// Edit layer (the layer where the suggestions are stored)
-//////
-this.createEditLayer = function(width, height)
-{
- this.edit_layer = document.createElement('div');
- $(this.edit_layer).addClass('googie_edit_layer').attr('id', 'googie_edit_layer')
- .width('auto').height(height);
-
- if (this.text_area.nodeName.toLowerCase() != 'input' || $(this.text_area).val() == '') {
- $(this.edit_layer).css('overflow', 'auto').height(height-4);
- } else {
- $(this.edit_layer).css('overflow', 'hidden');
- }
-
- var ref = this;
-
- if (this.edit_layer_dbl_click) {
- $(this.edit_layer).dblclick(function(e) {
- if (e.target.className != 'googie_link' && !ref.isErrorWindowShown()) {
- ref.resumeEditing();
- var fn1 = function() {
- $(ref.text_area).focus();
- fn1 = null;
- };
- window.setTimeout(fn1, 10);
- }
- return false;
- });
- }
-};
-
-this.resumeEditing = function()
-{
- this.setStateChanged('ready');
-
- if (this.edit_layer)
- this.el_scroll_top = this.edit_layer.scrollTop;
-
- this.hideErrorWindow();
-
- if (this.main_controller)
- $(this.spell_span).removeClass().addClass('googie_no_style');
-
- if (!this.ignore) {
- if (this.use_focus) {
- $(this.focus_link_t).remove();
- $(this.focus_link_b).remove();
- }
-
- $(this.edit_layer).remove();
- $(this.text_area).show();
-
- if (this.el_scroll_top != undefined)
- this.text_area.scrollTop = this.el_scroll_top;
- }
- this.checkSpellingState(false);
-};
-
-this.createErrorLink = function(text, id)
-{
- var elm = document.createElement('span'),
- ref = this,
- d = function (e) {
- ref.showErrorWindow(elm, id);
- d = null;
- return false;
- };
-
- $(elm).html(text).addClass('googie_link').click(d).removeAttr('is_corrected')
- .attr({'googie_action_btn' : '1', 'g_id' : id});
-
- return elm;
-};
-
-this.createPart = function(txt_part)
-{
- if (txt_part == " ")
- return document.createTextNode(" ");
-
- txt_part = this.escapeSpecial(txt_part);
- txt_part = txt_part.replace(/\n/g, "<br>");
- txt_part = txt_part.replace(/ /g, " &nbsp;");
- txt_part = txt_part.replace(/^ /g, "&nbsp;");
- txt_part = txt_part.replace(/ $/g, "&nbsp;");
-
- var span = document.createElement('span');
- $(span).html(txt_part);
- return span;
-};
-
-this.showErrorsInIframe = function()
-{
- var output = document.createElement('div'),
- pointer = 0,
- results = this.results;
-
- if (results.length > 0) {
- for (var i=0, length=results.length; i < length; i++) {
- var offset = results[i]['attrs']['o'],
- len = results[i]['attrs']['l'],
- part_1_text = this.orginal_text.substring(pointer, offset),
- part_1 = this.createPart(part_1_text);
-
- output.appendChild(part_1);
- pointer += offset - pointer;
-
- // If the last child was an error, then insert some space
- var err_link = this.createErrorLink(this.orginal_text.substr(offset, len), i);
- this.error_links.push(err_link);
- output.appendChild(err_link);
- pointer += len;
- }
-
- // Insert the rest of the orginal text
- var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length),
- part_2 = this.createPart(part_2_text);
-
- output.appendChild(part_2);
- }
- else
- output.innerHTML = this.orginal_text;
-
- $(output).css('text-align', 'left');
-
- var me = this;
- if (this.custom_item_evaulator)
- $.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)});
-
- $(this.edit_layer).append(output);
-
- // Hide text area and show edit layer
- $(this.text_area).hide();
- $(this.edit_layer).insertBefore(this.text_area);
-
- if (this.use_focus) {
- this.focus_link_t = this.createFocusLink('focus_t');
- this.focus_link_b = this.createFocusLink('focus_b');
-
- $(this.focus_link_t).insertBefore(this.edit_layer);
- $(this.focus_link_b).insertAfter(this.edit_layer);
- }
-
-// this.edit_layer.scrollTop = this.ta_scroll_top;
-};
-
-
-//////
-// Choose language menu
-//////
-this.createLangWindow = function()
-{
- this.language_window = document.createElement('div');
- $(this.language_window).addClass('googie_window popupmenu')
- .width(100).attr('googie_action_btn', '1');
-
- // Build up the result list
- var table = document.createElement('table'),
- list = document.createElement('tbody'),
- ref = this,
- row, item, span;
-
- $(table).addClass('googie_list').width('100%');
- this.lang_elms = [];
-
- for (i=0; i < this.langlist_codes.length; i++) {
- row = document.createElement('tr');
- item = document.createElement('td');
- span = document.createElement('span');
-
- $(span).text(this.lang_to_word[this.langlist_codes[i]]);
- this.lang_elms.push(item);
-
- $(item).attr('googieId', this.langlist_codes[i])
- .bind('click', function(e) {
- ref.deHighlightCurSel();
- ref.setCurrentLanguage($(this).attr('googieId'));
-
- if (ref.lang_state_observer != null) {
- ref.lang_state_observer();
- }
-
- ref.highlightCurSel();
- ref.hideLangWindow();
- })
- .bind('mouseover', function(e) {
- if (this.className != "googie_list_selected")
- this.className = "googie_list_onhover";
- })
- .bind('mouseout', function(e) {
- if (this.className != "googie_list_selected")
- this.className = "googie_list_onout";
- });
-
- item.appendChild(span);
- row.appendChild(item);
- list.appendChild(row);
- }
-
- // Close button
- if (this.use_close_btn) {
- list.appendChild(this.createCloseButton(function () { ref.hideLangWindow.apply(ref) }));
- }
-
- this.highlightCurSel();
-
- table.appendChild(list);
- this.language_window.appendChild(table);
-};
-
-this.isLangWindowShown = function()
-{
- return $(this.language_window).is(':visible');
-};
-
-this.hideLangWindow = function()
-{
- $(this.language_window).hide();
- $(this.switch_lan_pic).removeClass().addClass('googie_lang_3d_on');
-};
-
-this.showLangWindow = function(elm)
-{
- if (this.show_menu_observer)
- this.show_menu_observer(this);
-
- this.createLangWindow();
- $('body').append(this.language_window);
-
- var pos = $(elm).offset(),
- height = $(elm).height(),
- width = $(elm).width(),
- h = $(this.language_window).height(),
- pageheight = $(document).height(),
- left = this.change_lang_pic_placement == 'right' ?
- pos.left - 100 + width : pos.left + width,
- top = pos.top + h < pageheight ? pos.top + height : pos.top - h - 4;
-
- $(this.language_window).css({'top' : top+'px','left' : left+'px'}).show();
-
- this.highlightCurSel();
-};
-
-this.deHighlightCurSel = function()
-{
- $(this.lang_cur_elm).removeClass().addClass('googie_list_onout');
-};
-
-this.highlightCurSel = function()
-{
- if (GOOGIE_CUR_LANG == null)
- GOOGIE_CUR_LANG = GOOGIE_DEFAULT_LANG;
- for (var i=0; i < this.lang_elms.length; i++) {
- if ($(this.lang_elms[i]).attr('googieId') == GOOGIE_CUR_LANG) {
- this.lang_elms[i].className = 'googie_list_selected';
- this.lang_cur_elm = this.lang_elms[i];
- }
- else {
- this.lang_elms[i].className = 'googie_list_onout';
- }
- }
-};
-
-this.createChangeLangPic = function()
-{
- var img = $('<img>')
- .attr({src: this.img_dir + 'change_lang.gif', 'alt': 'Change language', 'googie_action_btn': '1'}),
- switch_lan = document.createElement('span');
- ref = this;
-
- $(switch_lan).addClass('googie_lang_3d_on')
- .append(img)
- .bind('click', function(e) {
- var elm = this.tagName.toLowerCase() == 'img' ? this.parentNode : this;
- if($(elm).hasClass('googie_lang_3d_click')) {
- elm.className = 'googie_lang_3d_on';
- ref.hideLangWindow();
- }
- else {
- elm.className = 'googie_lang_3d_click';
- ref.showLangWindow(elm);
- }
- });
-
- return switch_lan;
-};
-
-this.createSpellDiv = function()
-{
- var span = document.createElement('span');
-
- $(span).addClass('googie_check_spelling_link').text(this.lang_chck_spell);
-
- if (this.show_spell_img) {
- $(span).append(' ').append($('<img>').attr('src', this.img_dir + 'spellc.gif'));
- }
- return span;
-};
-
-
-//////
-// State functions
-/////
-this.flashNoSpellingErrorState = function(on_finish)
-{
- this.setStateChanged('no_error_found');
-
- var ref = this;
- if (this.main_controller) {
- var no_spell_errors;
- if (on_finish) {
- var fn = function() {
- on_finish();
- ref.checkSpellingState();
- };
- no_spell_errors = fn;
- }
- else
- no_spell_errors = function () { ref.checkSpellingState() };
-
- var rsm = $('<span>').text(this.lang_no_error_found);
-
- $(this.switch_lan_pic).hide();
- $(this.spell_span).empty().append(rsm)
- .removeClass().addClass('googie_check_spelling_ok');
-
- window.setTimeout(no_spell_errors, 1000);
- }
-};
-
-this.resumeEditingState = function()
-{
- this.setStateChanged('resume_editing');
-
- //Change link text to resume
- if (this.main_controller) {
- var rsm = $('<span>').text(this.lang_rsm_edt);
- var ref = this;
-
- $(this.switch_lan_pic).hide();
- $(this.spell_span).empty().unbind().append(rsm)
- .bind('click', function() { ref.resumeEditing() })
- .removeClass().addClass('googie_resume_editing');
- }
-
- try { this.edit_layer.scrollTop = this.ta_scroll_top; }
- catch (e) {};
-};
-
-this.checkSpellingState = function(fire)
-{
- if (fire)
- this.setStateChanged('ready');
-
- if (this.show_change_lang_pic)
- this.switch_lan_pic = this.createChangeLangPic();
- else
- this.switch_lan_pic = document.createElement('span');
-
- var span_chck = this.createSpellDiv(),
- ref = this;
-
- if (this.custom_spellcheck_starter)
- $(span_chck).bind('click', function(e) { ref.custom_spellcheck_starter() });
- else {
- $(span_chck).bind('click', function(e) { ref.spellCheck() });
- }
-
- if (this.main_controller) {
- if (this.change_lang_pic_placement == 'left') {
- $(this.spell_container).empty().append(this.switch_lan_pic).append(' ').append(span_chck);
- } else {
- $(this.spell_container).empty().append(span_chck).append(' ').append(this.switch_lan_pic);
- }
- }
-
- this.spell_span = span_chck;
-};
-
-
-//////
-// Misc. functions
-/////
-this.isDefined = function(o)
-{
- return (o !== undefined && o !== null)
-};
-
-this.errorFixed = function()
-{
- this.cnt_errors_fixed++;
- if (this.all_errors_fixed_observer)
- if (this.cnt_errors_fixed == this.cnt_errors) {
- this.hideErrorWindow();
- this.all_errors_fixed_observer();
- }
-};
-
-this.errorFound = function()
-{
- this.cnt_errors++;
-};
-
-this.createCloseButton = function(c_fn)
-{
- return this.createButton(this.lang_close, 'googie_list_close', c_fn);
-};
-
-this.createButton = function(name, css_class, c_fn)
-{
- var btn_row = document.createElement('tr'),
- btn = document.createElement('td'),
- spn_btn;
-
- if (css_class) {
- spn_btn = document.createElement('span');
- $(spn_btn).addClass(css_class).html(name);
- } else {
- spn_btn = document.createTextNode(name);
- }
-
- $(btn).bind('click', c_fn)
- .bind('mouseover', this.item_onmouseover)
- .bind('mouseout', this.item_onmouseout);
-
- btn.appendChild(spn_btn);
- btn_row.appendChild(btn);
-
- return btn_row;
-};
-
-this.removeIndicator = function(elm)
-{
- //$(this.indicator).remove();
- // roundcube mod.
- if (window.rcmail)
- rcmail.set_busy(false, null, this.rc_msg_id);
-};
-
-this.appendIndicator = function(elm)
-{
- // modified by roundcube
- if (window.rcmail)
- this.rc_msg_id = rcmail.set_busy(true, 'checking');
-/*
- this.indicator = document.createElement('img');
- $(this.indicator).attr('src', this.img_dir + 'indicator.gif')
- .css({'margin-right': '5px', 'text-decoration': 'none'}).width(16).height(16);
-
- if (elm)
- $(this.indicator).insertBefore(elm);
- else
- $('body').append(this.indicator);
-*/
-}
-
-this.createFocusLink = function(name)
-{
- var link = document.createElement('a');
- $(link).attr({'href': 'javascript:;', 'name': name});
- return link;
-};
-
-this.item_onmouseover = function(e)
-{
- if (this.className != 'googie_list_revert' && this.className != 'googie_list_close')
- this.className = 'googie_list_onhover';
- else
- this.parentNode.className = 'googie_list_onhover';
-};
-
-this.item_onmouseout = function(e)
-{
- if (this.className != 'googie_list_revert' && this.className != 'googie_list_close')
- this.className = 'googie_list_onout';
- else
- this.parentNode.className = 'googie_list_onout';
-};
-
-
-};
+var GOOGIE_CUR_LANG,GOOGIE_DEFAULT_LANG="en";function GoogieSpell(c,a,e){var b=this,d=rcmail.get_cookie("language");GOOGIE_CUR_LANG=d!=null?d:GOOGIE_DEFAULT_LANG;this.array_keys=function(f){var h=[];for(var g in f){h.push([g])}return h};this.img_dir=c;this.server_url=a;this.org_lang_to_word={da:"Dansk",de:"Deutsch",en:"English",es:"Español",fr:"Français",it:"Italiano",nl:"Nederlands",pl:"Polski",pt:"Português",ru:"РуÑÑкий",fi:"Suomi",sv:"Svenska"};this.lang_to_word=this.org_lang_to_word;this.langlist_codes=this.array_keys(this.lang_to_word);this.show_change_lang_pic=true;this.change_lang_pic_placement="right";this.report_state_change=true;this.ta_scroll_top=0;this.el_scroll_top=0;this.lang_chck_spell="Check spelling";this.lang_revert="Revert to";this.lang_close="Close";this.lang_rsm_edt="Resume editing";this.lang_no_error_found="No spelling errors found";this.lang_no_suggestions="No suggestions";this.lang_learn_word="Add to dictionary";this.show_spell_img=false;this.decoration=true;this.use_close_btn=false;this.edit_layer_dbl_click=true;this.report_ta_not_found=true;this.custom_ajax_error=null;this.custom_no_spelling_error=null;this.custom_menu_builder=[];this.custom_item_evaulator=null;this.extra_menu_items=[];this.custom_spellcheck_starter=null;this.main_controller=true;this.has_dictionary=e;this.lang_state_observer=null;this.spelling_state_observer=null;this.show_menu_observer=null;this.all_errors_fixed_observer=null;this.use_focus=false;this.focus_link_t=null;this.focus_link_b=null;this.cnt_errors=0;this.cnt_errors_fixed=0;$(document).bind("click",function(g){var f=$(g.target);if(f.attr("googie_action_btn")!="1"&&b.isLangWindowShown()){b.hideLangWindow()}if(f.attr("googie_action_btn")!="1"&&b.isErrorWindowShown()){b.hideErrorWindow()}});this.decorateTextarea=function(m){this.text_area=typeof m==="string"?document.getElementById(m):m;if(this.text_area){if(!this.spell_container&&this.decoration){var j=document.createElement("table"),g=document.createElement("tbody"),l=document.createElement("tr"),k=document.createElement("td"),f=this.isDefined(this.force_width)?this.force_width:this.text_area.offsetWidth,h=this.isDefined(this.force_height)?this.force_height:16;l.appendChild(k);g.appendChild(l);$(j).append(g).insertBefore(this.text_area).width("100%").height(h);$(k).height(h).width(f).css("text-align","right");this.spell_container=k}this.checkSpellingState()}else{if(this.report_ta_not_found){alert("Text area not found")}}};this.setSpellContainer=function(f){this.spell_container=typeof f==="string"?document.getElementById(f):f};this.setLanguages=function(f){this.lang_to_word=f;this.langlist_codes=this.array_keys(f)};this.setCurrentLanguage=function(g){GOOGIE_CUR_LANG=g;var f=new Date();f.setTime(f.getTime()+365*24*60*60*1000);rcmail.set_cookie("language",g,f)};this.setForceWidthHeight=function(g,f){this.force_width=g;this.force_height=f};this.setDecoration=function(f){this.decoration=f};this.dontUseCloseButtons=function(){this.use_close_btn=false};this.appendNewMenuItem=function(g,h,f){this.extra_menu_items.push([g,h,f])};this.appendCustomMenuBuilder=function(g,f){this.custom_menu_builder.push([g,f])};this.setFocus=function(){try{this.focus_link_b.focus();this.focus_link_t.focus();return true}catch(f){return false}};this.setStateChanged=function(f){this.state=f;if(this.spelling_state_observer!=null&&this.report_state_change){this.spelling_state_observer(f,this)}};this.setReportStateChange=function(f){this.report_state_change=f};this.getUrl=function(){return this.server_url+GOOGIE_CUR_LANG};this.escapeSpecial=function(f){return f?f.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):""};this.createXMLReq=function(f){return'<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>'+f+"</text></spellrequest>"};this.spellCheck=function(h){this.prepare(h);var g=this.escapeSpecial(this.orginal_text),f=this;$.ajax({type:"POST",url:this.getUrl(),data:this.createXMLReq(g),dataType:"text",error:function(j){if(f.custom_ajax_error){f.custom_ajax_error(f)}else{alert("An error was encountered on the server. Please try again later.")}if(f.main_controller){$(f.spell_span).remove();f.removeIndicator()}f.checkSpellingState()},success:function(j){f.processData(j);if(!f.results.length){if(!f.custom_no_spelling_error){f.flashNoSpellingErrorState()}else{f.custom_no_spelling_error(f)}}f.removeIndicator()}})};this.learnWord=function(h,j){h=this.escapeSpecial(h.innerHTML);var g=this,f='<?xml version="1.0" encoding="utf-8" ?><learnword><text>'+h+"</text></learnword>";$.ajax({type:"POST",url:this.getUrl(),data:f,dataType:"text",error:function(k){if(g.custom_ajax_error){g.custom_ajax_error(g)}else{alert("An error was encountered on the server. Please try again later.")}},success:function(k){}})};this.prepare=function(h,g){this.cnt_errors_fixed=0;this.cnt_errors=0;this.setStateChanged("checking_spell");if(!g&&this.main_controller){this.appendIndicator(this.spell_span)}this.error_links=[];this.ta_scroll_top=this.text_area.scrollTop;this.ignore=h;this.hideLangWindow();if($(this.text_area).val()==""||h){if(!this.custom_no_spelling_error){this.flashNoSpellingErrorState()}else{this.custom_no_spelling_error(this)}this.removeIndicator();return}this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight);this.createErrorWindow();$("body").append(this.error_window);try{netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead")}catch(f){}if(this.main_controller){$(this.spell_span).unbind("click")}this.orginal_text=$(this.text_area).val()};this.parseResult=function(s){var l=/\w+="(\d+|true)"/g,o=/\t/g,f=s.match(/<c[^>]*>[^<]*<\/c>/g),p=[];if(f==null){return p}for(var q=0,r=f.length;q<r;q++){var w=[];this.errorFound();w.attrs=[];var u,h,v=f[q].match(l);for(var n=0;n<v.length;n++){u=v[n].split(/=/);h=u[1].replace(/"/g,"");w.attrs[u[0]]=h!="true"?parseInt(h):h}w.suggestions=[];var t=f[q].replace(/<[^>]*>/g,""),g=t.split(o);for(var m=0;m<g.length;m++){if(g[m]!=""){w.suggestions.push(g[m])}}p.push(w)}return p};this.processData=function(f){this.results=this.parseResult(f);if(this.results.length){this.showErrorsInIframe();this.resumeEditingState()}};this.createErrorWindow=function(){this.error_window=document.createElement("div");$(this.error_window).addClass("googie_window popupmenu").attr("googie_action_btn","1")};this.isErrorWindowShown=function(){return $(this.error_window).is(":visible")};this.hideErrorWindow=function(){$(this.error_window).hide();$(this.error_window_iframe).hide()};this.updateOrginalText=function(k,n,p,f){var h=this.orginal_text.substring(0,k),g=this.orginal_text.substring(k+n.length),o=p.length-n.length;this.orginal_text=h+p+g;$(this.text_area).val(this.orginal_text);for(var l=0,m=this.results.length;l<m;l++){if(l!=f&&l>f){this.results[l]["attrs"]["o"]+=o}}};this.saveOldValue=function(g,f){g.is_changed=true;g.old_value=f};this.createListSeparator=function(){var g=document.createElement("td"),f=document.createElement("tr");$(g).html(" ").attr("googie_action_btn","1").css({cursor:"default","font-size":"3px","border-top":"1px solid #ccc","padding-top":"3px"});f.appendChild(g);return f};this.correctError=function(n,m,l,f){var g=m.innerHTML,h=l.nodeType==3?l.nodeValue:l.innerHTML,k=this.results[n]["attrs"]["o"];if(f){var j=m.previousSibling.innerHTML;m.previousSibling.innerHTML=j.slice(0,j.length-1);g=" "+g;k--}this.hideErrorWindow();this.updateOrginalText(k,g,h,n);$(m).html(h).css("color","green").attr("is_corrected",true);this.results[n]["attrs"]["l"]=h.length;if(!this.isDefined(m.old_value)){this.saveOldValue(m,g)}this.errorFixed()};this.ignoreError=function(g,f){$(g).removeAttr("class").css("color","").unbind();this.hideErrorWindow()};this.showErrorWindow=function(u,B){if(this.show_menu_observer){this.show_menu_observer(this)}var o=this,p=$(u).offset(),I=document.createElement("table"),J=document.createElement("tbody");$(this.error_window).html("");$(I).addClass("googie_list").attr("googie_action_btn","1");var r=false;for(var F=0;F<this.custom_menu_builder.length;F++){var q=this.custom_menu_builder[F];if(q[0](this.results[B])){r=q[1](this,J,u);break}}if(!r){var z=this.results[B]["suggestions"],n=this.results[B]["attrs"]["o"],H=this.results[B]["attrs"]["l"],t,K,O;if(this.has_dictionary&&!$(u).attr("is_corrected")){t=document.createElement("tr"),K=document.createElement("td"),O=document.createElement("span");$(O).text(this.lang_learn_word);$(K).attr("googie_action_btn","1").css("cursor","default").mouseover(o.item_onmouseover).mouseout(o.item_onmouseout).click(function(k){o.learnWord(u,B);o.ignoreError(u,B)});K.appendChild(O);t.appendChild(K);J.appendChild(t)}for(var G=0,H=z.length;G<H;G++){t=document.createElement("tr"),K=document.createElement("td"),O=document.createElement("span");$(O).html(z[G]);$(K).mouseover(this.item_onmouseover).mouseout(this.item_onmouseout).click(function(k){o.correctError(B,u,k.target.firstChild)});K.appendChild(O);t.appendChild(K);J.appendChild(t)}if(u.is_changed&&u.innerHTML!=u.old_value){var g=u.old_value,j=document.createElement("tr"),f=document.createElement("td"),s=document.createElement("span");$(s).addClass("googie_list_revert").html(this.lang_revert+" "+g);$(f).mouseover(this.item_onmouseover).mouseout(this.item_onmouseout).click(function(k){o.updateOrginalText(n,u.innerHTML,g,B);$(u).removeAttr("is_corrected").css("color","#b91414").html(g);o.hideErrorWindow()});f.appendChild(s);j.appendChild(f);J.appendChild(j)}var M=document.createElement("tr"),C=document.createElement("td"),N=document.createElement("input"),w=document.createElement("img"),h=document.createElement("form");var m=function(){if(N.value!=""){if(!o.isDefined(u.old_value)){o.saveOldValue(u,u.innerHTML)}o.updateOrginalText(n,u.innerHTML,N.value,B);$(u).attr("is_corrected",true).css("color","green").html(N.value);o.hideErrorWindow()}return false};$(N).width(120).css({margin:0,padding:0});$(N).val(u.innerHTML).attr("googie_action_btn","1");$(C).css("cursor","default").attr("googie_action_btn","1");$(w).attr("src",this.img_dir+"ok.gif").width(32).height(16).css({cursor:"pointer","margin-left":"2px","margin-right":"2px"}).click(m);$(h).attr("googie_action_btn","1").css({margin:0,padding:0,cursor:"default","white-space":"nowrap"}).submit(m);h.appendChild(N);h.appendChild(w);C.appendChild(h);M.appendChild(C);J.appendChild(M);if(this.extra_menu_items.length>0){J.appendChild(this.createListSeparator())}var L=function(Q){if(Q<o.extra_menu_items.length){var P=o.extra_menu_items[Q];if(!P[2]||P[2](u,o)){var k=document.createElement("tr"),R=document.createElement("td");$(R).html(P[0]).mouseover(o.item_onmouseover).mouseout(o.item_onmouseout).click(function(){return P[1](u,o)});k.appendChild(R);J.appendChild(k)}L(Q+1)}};L(0);L=null;if(this.use_close_btn){J.appendChild(this.createCloseButton(this.hideErrorWindow))}}I.appendChild(J);this.error_window.appendChild(I);var A=$(this.error_window).height(),E=$(this.error_window).width(),x=$(document).height(),D=$(document).width(),y=p.top+A+20<x?p.top+20:p.top-A,l=p.left+E<D?p.left:p.left-E;$(this.error_window).css({top:y+"px",left:l+"px"}).show();if($.browser.msie){if(!this.error_window_iframe){var v=$("<iframe>").css({position:"absolute","z-index":-1});$("body").append(v);this.error_window_iframe=v}$(this.error_window_iframe).css({top:this.error_window.offsetTop,left:this.error_window.offsetLeft,width:this.error_window.offsetWidth,height:this.error_window.offsetHeight}).show()}};this.createEditLayer=function(g,f){this.edit_layer=document.createElement("div");$(this.edit_layer).addClass("googie_edit_layer").attr("id","googie_edit_layer").width("auto").height(f);if(this.text_area.nodeName.toLowerCase()!="input"||$(this.text_area).val()==""){$(this.edit_layer).css("overflow","auto").height(f-4)}else{$(this.edit_layer).css("overflow","hidden")}var h=this;if(this.edit_layer_dbl_click){$(this.edit_layer).dblclick(function(k){if(k.target.className!="googie_link"&&!h.isErrorWindowShown()){h.resumeEditing();var j=function(){$(h.text_area).focus();j=null};window.setTimeout(j,10)}return false})}};this.resumeEditing=function(){this.setStateChanged("ready");if(this.edit_layer){this.el_scroll_top=this.edit_layer.scrollTop}this.hideErrorWindow();if(this.main_controller){$(this.spell_span).removeClass().addClass("googie_no_style")}if(!this.ignore){if(this.use_focus){$(this.focus_link_t).remove();$(this.focus_link_b).remove()}$(this.edit_layer).remove();$(this.text_area).show();if(this.el_scroll_top!=undefined){this.text_area.scrollTop=this.el_scroll_top}}this.checkSpellingState(false)};this.createErrorLink=function(h,k){var j=document.createElement("span"),f=this,g=function(l){f.showErrorWindow(j,k);g=null;return false};$(j).html(h).addClass("googie_link").click(g).removeAttr("is_corrected").attr({googie_action_btn:"1",g_id:k});return j};this.createPart=function(g){if(g==" "){return document.createTextNode(" ")}g=this.escapeSpecial(g);g=g.replace(/\n/g,"<br>");g=g.replace(/ /g," &nbsp;");g=g.replace(/^ /g,"&nbsp;");g=g.replace(/ $/g,"&nbsp;");var f=document.createElement("span");$(f).html(g);return f};this.showErrorsInIframe=function(){var m=document.createElement("div"),f=0,o=this.results;if(o.length>0){for(var p=0,k=o.length;p<k;p++){var n=o[p]["attrs"]["o"],r=o[p]["attrs"]["l"],j=this.orginal_text.substring(f,n),l=this.createPart(j);m.appendChild(l);f+=n-f;var g=this.createErrorLink(this.orginal_text.substr(n,r),p);this.error_links.push(g);m.appendChild(g);f+=r}var q=this.orginal_text.substr(f,this.orginal_text.length),h=this.createPart(q);m.appendChild(h)}else{m.innerHTML=this.orginal_text}$(m).css("text-align","left");var s=this;if(this.custom_item_evaulator){$.map(this.error_links,function(t){s.custom_item_evaulator(s,t)})}$(this.edit_layer).append(m);$(this.text_area).hide();$(this.edit_layer).insertBefore(this.text_area);if(this.use_focus){this.focus_link_t=this.createFocusLink("focus_t");this.focus_link_b=this.createFocusLink("focus_b");$(this.focus_link_t).insertBefore(this.edit_layer);$(this.focus_link_b).insertAfter(this.edit_layer)}};this.createLangWindow=function(){this.language_window=document.createElement("div");$(this.language_window).addClass("googie_window popupmenu").width(100).attr("googie_action_btn","1");var j=document.createElement("table"),k=document.createElement("tbody"),h=this,l,g,f;$(j).addClass("googie_list").width("100%");this.lang_elms=[];for(i=0;i<this.langlist_codes.length;i++){l=document.createElement("tr");g=document.createElement("td");f=document.createElement("span");$(f).text(this.lang_to_word[this.langlist_codes[i]]);this.lang_elms.push(g);$(g).attr("googieId",this.langlist_codes[i]).bind("click",function(m){h.deHighlightCurSel();h.setCurrentLanguage($(this).attr("googieId"));if(h.lang_state_observer!=null){h.lang_state_observer()}h.highlightCurSel();h.hideLangWindow()}).bind("mouseover",function(m){if(this.className!="googie_list_selected"){this.className="googie_list_onhover"}}).bind("mouseout",function(m){if(this.className!="googie_list_selected"){this.className="googie_list_onout"}});g.appendChild(f);l.appendChild(g);k.appendChild(l)}if(this.use_close_btn){k.appendChild(this.createCloseButton(function(){h.hideLangWindow.apply(h)}))}this.highlightCurSel();j.appendChild(k);this.language_window.appendChild(j)};this.isLangWindowShown=function(){return $(this.language_window).is(":visible")};this.hideLangWindow=function(){$(this.language_window).hide();$(this.switch_lan_pic).removeClass().addClass("googie_lang_3d_on")};this.showLangWindow=function(o){if(this.show_menu_observer){this.show_menu_observer(this)}this.createLangWindow();$("body").append(this.language_window);var n=$(o).offset(),f=$(o).height(),j=$(o).width(),g=$(this.language_window).height(),k=$(document).height(),m=this.change_lang_pic_placement=="right"?n.left-100+j:n.left+j,l=n.top+g<k?n.top+f:n.top-g-4;$(this.language_window).css({top:l+"px",left:m+"px"}).show();this.highlightCurSel()};this.deHighlightCurSel=function(){$(this.lang_cur_elm).removeClass().addClass("googie_list_onout")};this.highlightCurSel=function(){if(GOOGIE_CUR_LANG==null){GOOGIE_CUR_LANG=GOOGIE_DEFAULT_LANG}for(var f=0;f<this.lang_elms.length;f++){if($(this.lang_elms[f]).attr("googieId")==GOOGIE_CUR_LANG){this.lang_elms[f].className="googie_list_selected";this.lang_cur_elm=this.lang_elms[f]}else{this.lang_elms[f].className="googie_list_onout"}}};this.createChangeLangPic=function(){var f=$("<img>").attr({src:this.img_dir+"change_lang.gif",alt:"Change language",googie_action_btn:"1"}),g=document.createElement("span");b=this;$(g).addClass("googie_lang_3d_on").append(f).bind("click",function(h){var j=this.tagName.toLowerCase()=="img"?this.parentNode:this;if($(j).hasClass("googie_lang_3d_click")){j.className="googie_lang_3d_on";b.hideLangWindow()}else{j.className="googie_lang_3d_click";b.showLangWindow(j)}});return g};this.createSpellDiv=function(){var f=document.createElement("span");$(f).addClass("googie_check_spelling_link").text(this.lang_chck_spell);if(this.show_spell_img){$(f).append(" ").append($("<img>").attr("src",this.img_dir+"spellc.gif"))}return f};this.flashNoSpellingErrorState=function(f){this.setStateChanged("no_error_found");var j=this;if(this.main_controller){var k;if(f){var h=function(){f();j.checkSpellingState()};k=h}else{k=function(){j.checkSpellingState()}}var g=$("<span>").text(this.lang_no_error_found);$(this.switch_lan_pic).hide();$(this.spell_span).empty().append(g).removeClass().addClass("googie_check_spelling_ok");window.setTimeout(k,1000)}};this.resumeEditingState=function(){this.setStateChanged("resume_editing");if(this.main_controller){var f=$("<span>").text(this.lang_rsm_edt);var g=this;$(this.switch_lan_pic).hide();$(this.spell_span).empty().unbind().append(f).bind("click",function(){g.resumeEditing()}).removeClass().addClass("googie_resume_editing")}try{this.edit_layer.scrollTop=this.ta_scroll_top}catch(h){}};this.checkSpellingState=function(g){if(g){this.setStateChanged("ready")}if(this.show_change_lang_pic){this.switch_lan_pic=this.createChangeLangPic()}else{this.switch_lan_pic=document.createElement("span")}var f=this.createSpellDiv(),h=this;if(this.custom_spellcheck_starter){$(f).bind("click",function(j){h.custom_spellcheck_starter()})}else{$(f).bind("click",function(j){h.spellCheck()})}if(this.main_controller){if(this.change_lang_pic_placement=="left"){$(this.spell_container).empty().append(this.switch_lan_pic).append(" ").append(f)}else{$(this.spell_container).empty().append(f).append(" ").append(this.switch_lan_pic)}}this.spell_span=f};this.isDefined=function(f){return(f!==undefined&&f!==null)};this.errorFixed=function(){this.cnt_errors_fixed++;if(this.all_errors_fixed_observer){if(this.cnt_errors_fixed==this.cnt_errors){this.hideErrorWindow();this.all_errors_fixed_observer()}}};this.errorFound=function(){this.cnt_errors++};this.createCloseButton=function(f){return this.createButton(this.lang_close,"googie_list_close",f)};this.createButton=function(g,j,l){var k=document.createElement("tr"),h=document.createElement("td"),f;if(j){f=document.createElement("span");$(f).addClass(j).html(g)}else{f=document.createTextNode(g)}$(h).bind("click",l).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout);h.appendChild(f);k.appendChild(h);return k};this.removeIndicator=function(f){if(window.rcmail){rcmail.set_busy(false,null,this.rc_msg_id)}};this.appendIndicator=function(f){if(window.rcmail){this.rc_msg_id=rcmail.set_busy(true,"checking")}};this.createFocusLink=function(f){var g=document.createElement("a");$(g).attr({href:"javascript:;",name:f});return g};this.item_onmouseover=function(f){if(this.className!="googie_list_revert"&&this.className!="googie_list_close"){this.className="googie_list_onhover"}else{this.parentNode.className="googie_list_onhover"}};this.item_onmouseout=function(f){if(this.className!="googie_list_revert"&&this.className!="googie_list_close"){this.className="googie_list_onout"}else{this.parentNode.className="googie_list_onout"}}}; \ No newline at end of file
diff --git a/program/js/jquery.min.js b/program/js/jquery.min.js
index 83589daa7..5cb76ea03 100644..120000
--- a/program/js/jquery.min.js
+++ b/program/js/jquery.min.js
@@ -1,2 +1 @@
-/*! jQuery v1.8.3 jquery.com | jquery.org/license */
-(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file
+../../../javascript/jquery/jquery.min.js \ No newline at end of file
diff --git a/program/js/jstz.min.js b/program/js/jstz.min.js
index d5f888cac..81c5057fd 100644
--- a/program/js/jstz.min.js
+++ b/program/js/jstz.min.js
@@ -1,2 +1,11 @@
-/*! jsTimezoneDetect - v1.0.5 - 2013-04-01 */
-(function(e){var t=function(){"use strict";var e="s",n=2011,r=function(e){var t=-e.getTimezoneOffset();return t!==null?t:0},i=function(e,t,n){var r=new Date;return e!==undefined&&r.setFullYear(e),r.setDate(n),r.setMonth(t),r},s=function(e){return r(i(e,0,2))},o=function(e){return r(i(e,5,2))},u=function(e){var t=e.getMonth()>7?o(e.getFullYear()):s(e.getFullYear()),n=r(e);return t-n!==0},a=function(){var t=s(n),r=o(n),i=t-r;return i<0?t+",1":i>0?r+",1,"+e:t+",0"},f=function(){var e=a();return new t.TimeZone(t.olson.timezones[e])},l=function(e){var t=new Date(2010,6,15,1,0,0,0),n={"America/Denver":new Date(2011,2,13,3,0,0,0),"America/Mazatlan":new Date(2011,3,3,3,0,0,0),"America/Chicago":new Date(2011,2,13,3,0,0,0),"America/Mexico_City":new Date(2011,3,3,3,0,0,0),"America/Asuncion":new Date(2012,9,7,3,0,0,0),"America/Santiago":new Date(2012,9,3,3,0,0,0),"America/Campo_Grande":new Date(2012,9,21,5,0,0,0),"America/Montevideo":new Date(2011,9,2,3,0,0,0),"America/Sao_Paulo":new Date(2011,9,16,5,0,0,0),"America/Los_Angeles":new Date(2011,2,13,8,0,0,0),"America/Santa_Isabel":new Date(2011,3,5,8,0,0,0),"America/Havana":new Date(2012,2,10,2,0,0,0),"America/New_York":new Date(2012,2,10,7,0,0,0),"Asia/Beirut":new Date(2011,2,27,1,0,0,0),"Europe/Helsinki":new Date(2011,2,27,4,0,0,0),"Europe/Istanbul":new Date(2011,2,28,5,0,0,0),"Asia/Damascus":new Date(2011,3,1,2,0,0,0),"Asia/Jerusalem":new Date(2011,3,1,6,0,0,0),"Asia/Gaza":new Date(2009,2,28,0,30,0,0),"Africa/Cairo":new Date(2009,3,25,0,30,0,0),"Pacific/Auckland":new Date(2011,8,26,7,0,0,0),"Pacific/Fiji":new Date(2010,10,29,23,0,0,0),"America/Halifax":new Date(2011,2,13,6,0,0,0),"America/Goose_Bay":new Date(2011,2,13,2,1,0,0),"America/Miquelon":new Date(2011,2,13,5,0,0,0),"America/Godthab":new Date(2011,2,27,1,0,0,0),"Europe/Moscow":t,"Asia/Yekaterinburg":t,"Asia/Omsk":t,"Asia/Krasnoyarsk":t,"Asia/Irkutsk":t,"Asia/Yakutsk":t,"Asia/Vladivostok":t,"Asia/Kamchatka":t,"Europe/Minsk":t,"Pacific/Apia":new Date(2010,10,1,1,0,0,0),"Australia/Perth":new Date(2008,10,1,1,0,0,0)};return n[e]};return{determine:f,date_is_dst:u,dst_start_for:l}}();t.TimeZone=function(e){"use strict";var n={"America/Denver":["America/Denver","America/Mazatlan"],"America/Chicago":["America/Chicago","America/Mexico_City"],"America/Santiago":["America/Santiago","America/Asuncion","America/Campo_Grande"],"America/Montevideo":["America/Montevideo","America/Sao_Paulo"],"Asia/Beirut":["Asia/Beirut","Europe/Helsinki","Europe/Istanbul","Asia/Damascus","Asia/Jerusalem","Asia/Gaza"],"Pacific/Auckland":["Pacific/Auckland","Pacific/Fiji"],"America/Los_Angeles":["America/Los_Angeles","America/Santa_Isabel"],"America/New_York":["America/Havana","America/New_York"],"America/Halifax":["America/Goose_Bay","America/Halifax"],"America/Godthab":["America/Miquelon","America/Godthab"],"Asia/Dubai":["Europe/Moscow"],"Asia/Dhaka":["Asia/Yekaterinburg"],"Asia/Jakarta":["Asia/Omsk"],"Asia/Shanghai":["Asia/Krasnoyarsk","Australia/Perth"],"Asia/Tokyo":["Asia/Irkutsk"],"Australia/Brisbane":["Asia/Yakutsk"],"Pacific/Noumea":["Asia/Vladivostok"],"Pacific/Tarawa":["Asia/Kamchatka"],"Pacific/Tongatapu":["Pacific/Apia"],"Africa/Johannesburg":["Asia/Gaza","Africa/Cairo"],"Asia/Baghdad":["Europe/Minsk"]},r=e,i=function(){var e=n[r],i=e.length,s=0,o=e[0];for(;s<i;s+=1){o=e[s];if(t.date_is_dst(t.dst_start_for(o))){r=o;return}}},s=function(){return typeof n[r]!="undefined"};return s()&&i(),{name:function(){return r}}},t.olson={},t.olson.timezones={"-720,0":"Pacific/Majuro","-660,0":"Pacific/Pago_Pago","-600,1":"America/Adak","-600,0":"Pacific/Honolulu","-570,0":"Pacific/Marquesas","-540,0":"Pacific/Gambier","-540,1":"America/Anchorage","-480,1":"America/Los_Angeles","-480,0":"Pacific/Pitcairn","-420,0":"America/Phoenix","-420,1":"America/Denver","-360,0":"America/Guatemala","-360,1":"America/Chicago","-360,1,s":"Pacific/Easter","-300,0":"America/Bogota","-300,1":"America/New_York","-270,0":"America/Caracas","-240,1":"America/Halifax","-240,0":"America/Santo_Domingo","-240,1,s":"America/Santiago","-210,1":"America/St_Johns","-180,1":"America/Godthab","-180,0":"America/Argentina/Buenos_Aires","-180,1,s":"America/Montevideo","-120,0":"America/Noronha","-120,1":"America/Noronha","-60,1":"Atlantic/Azores","-60,0":"Atlantic/Cape_Verde","0,0":"UTC","0,1":"Europe/London","60,1":"Europe/Berlin","60,0":"Africa/Lagos","60,1,s":"Africa/Windhoek","120,1":"Asia/Beirut","120,0":"Africa/Johannesburg","180,0":"Asia/Baghdad","180,1":"Europe/Moscow","210,1":"Asia/Tehran","240,0":"Asia/Dubai","240,1":"Asia/Baku","270,0":"Asia/Kabul","300,1":"Asia/Yekaterinburg","300,0":"Asia/Karachi","330,0":"Asia/Kolkata","345,0":"Asia/Kathmandu","360,0":"Asia/Dhaka","360,1":"Asia/Omsk","390,0":"Asia/Rangoon","420,1":"Asia/Krasnoyarsk","420,0":"Asia/Jakarta","480,0":"Asia/Shanghai","480,1":"Asia/Irkutsk","525,0":"Australia/Eucla","525,1,s":"Australia/Eucla","540,1":"Asia/Yakutsk","540,0":"Asia/Tokyo","570,0":"Australia/Darwin","570,1,s":"Australia/Adelaide","600,0":"Australia/Brisbane","600,1":"Asia/Vladivostok","600,1,s":"Australia/Sydney","630,1,s":"Australia/Lord_Howe","660,1":"Asia/Kamchatka","660,0":"Pacific/Noumea","690,0":"Pacific/Norfolk","720,1,s":"Pacific/Auckland","720,0":"Pacific/Tarawa","765,1,s":"Pacific/Chatham","780,0":"Pacific/Tongatapu","780,1,s":"Pacific/Apia","840,0":"Pacific/Kiritimati"},typeof exports!="undefined"?exports.jstz=t:e.jstz=t})(this); \ No newline at end of file
+var jstz=function(){var b=function(a){a=-a.getTimezoneOffset();return null!==a?a:0},c=function(){return b(new Date(2010,0,1,0,0,0,0))},f=function(){return b(new Date(2010,5,1,0,0,0,0))},e=function(){var a=c(),d=f(),b=c()-f();return new jstz.TimeZone(jstz.olson.timezones[0>b?a+",1":0<b?d+",1,s":a+",0"])};return{determine_timezone:function(){"undefined"!==typeof console&&console.log("jstz.determine_timezone() is deprecated and will be removed in an upcoming version. Please use jstz.determine() instead.");
+return e()},determine:e,date_is_dst:function(a){var d=5<a.getMonth()?f():c(),a=b(a);return 0!==d-a}}}();jstz.TimeZone=function(b){var c=null,c=b;"undefined"!==typeof jstz.olson.ambiguity_list[c]&&function(){for(var b=jstz.olson.ambiguity_list[c],e=b.length,a=0,d=b[0];a<e;a+=1)if(d=b[a],jstz.date_is_dst(jstz.olson.dst_start_dates[d])){c=d;break}}();return{name:function(){return c}}};jstz.olson={};
+jstz.olson.timezones={"-720,0":"Etc/GMT+12","-660,0":"Pacific/Pago_Pago","-600,1":"America/Adak","-600,0":"Pacific/Honolulu","-570,0":"Pacific/Marquesas","-540,0":"Pacific/Gambier","-540,1":"America/Anchorage","-480,1":"America/Los_Angeles","-480,0":"Pacific/Pitcairn","-420,0":"America/Phoenix","-420,1":"America/Denver","-360,0":"America/Guatemala","-360,1":"America/Chicago","-360,1,s":"Pacific/Easter","-300,0":"America/Bogota","-300,1":"America/New_York","-270,0":"America/Caracas","-240,1":"America/Halifax",
+"-240,0":"America/Santo_Domingo","-240,1,s":"America/Asuncion","-210,1":"America/St_Johns","-180,1":"America/Godthab","-180,0":"America/Argentina/Buenos_Aires","-180,1,s":"America/Montevideo","-120,0":"America/Noronha","-120,1":"Etc/GMT+2","-60,1":"Atlantic/Azores","-60,0":"Atlantic/Cape_Verde","0,0":"Etc/UTC","0,1":"Europe/London","60,1":"Europe/Berlin","60,0":"Africa/Lagos","60,1,s":"Africa/Windhoek","120,1":"Asia/Beirut","120,0":"Africa/Johannesburg","180,1":"Europe/Moscow","180,0":"Asia/Baghdad",
+"210,1":"Asia/Tehran","240,0":"Asia/Dubai","240,1":"Asia/Yerevan","270,0":"Asia/Kabul","300,1":"Asia/Yekaterinburg","300,0":"Asia/Karachi","330,0":"Asia/Kolkata","345,0":"Asia/Kathmandu","360,0":"Asia/Dhaka","360,1":"Asia/Omsk","390,0":"Asia/Rangoon","420,1":"Asia/Krasnoyarsk","420,0":"Asia/Jakarta","480,0":"Asia/Shanghai","480,1":"Asia/Irkutsk","525,0":"Australia/Eucla","525,1,s":"Australia/Eucla","540,1":"Asia/Yakutsk","540,0":"Asia/Tokyo","570,0":"Australia/Darwin","570,1,s":"Australia/Adelaide",
+"600,0":"Australia/Brisbane","600,1":"Asia/Vladivostok","600,1,s":"Australia/Sydney","630,1,s":"Australia/Lord_Howe","660,1":"Asia/Kamchatka","660,0":"Pacific/Noumea","690,0":"Pacific/Norfolk","720,1,s":"Pacific/Auckland","720,0":"Pacific/Tarawa","765,1,s":"Pacific/Chatham","780,0":"Pacific/Tongatapu","780,1,s":"Pacific/Apia","840,0":"Pacific/Kiritimati"};
+jstz.olson.dst_start_dates={"America/Denver":new Date(2011,2,13,3,0,0,0),"America/Mazatlan":new Date(2011,3,3,3,0,0,0),"America/Chicago":new Date(2011,2,13,3,0,0,0),"America/Mexico_City":new Date(2011,3,3,3,0,0,0),"Atlantic/Stanley":new Date(2011,8,4,7,0,0,0),"America/Asuncion":new Date(2011,9,2,3,0,0,0),"America/Santiago":new Date(2011,9,9,3,0,0,0),"America/Campo_Grande":new Date(2011,9,16,5,0,0,0),"America/Montevideo":new Date(2011,9,2,3,0,0,0),"America/Sao_Paulo":new Date(2011,9,16,5,0,0,0),"America/Los_Angeles":new Date(2011,
+2,13,8,0,0,0),"America/Santa_Isabel":new Date(2011,3,5,8,0,0,0),"America/Havana":new Date(2011,2,13,2,0,0,0),"America/New_York":new Date(2011,2,13,7,0,0,0),"Asia/Gaza":new Date(2011,2,26,23,0,0,0),"Asia/Beirut":new Date(2011,2,27,1,0,0,0),"Europe/Minsk":new Date(2011,2,27,2,0,0,0),"Europe/Helsinki":new Date(2011,2,27,4,0,0,0),"Europe/Istanbul":new Date(2011,2,28,5,0,0,0),"Asia/Damascus":new Date(2011,3,1,2,0,0,0),"Asia/Jerusalem":new Date(2011,3,1,6,0,0,0),"Africa/Cairo":new Date(2010,3,30,4,0,0,
+0),"Asia/Yerevan":new Date(2011,2,27,4,0,0,0),"Asia/Baku":new Date(2011,2,27,8,0,0,0),"Pacific/Auckland":new Date(2011,8,26,7,0,0,0),"Pacific/Fiji":new Date(2010,11,29,23,0,0,0),"America/Halifax":new Date(2011,2,13,6,0,0,0),"America/Goose_Bay":new Date(2011,2,13,2,1,0,0),"America/Miquelon":new Date(2011,2,13,5,0,0,0),"America/Godthab":new Date(2011,2,27,1,0,0,0)};
+jstz.olson.ambiguity_list={"America/Denver":["America/Denver","America/Mazatlan"],"America/Chicago":["America/Chicago","America/Mexico_City"],"America/Asuncion":["Atlantic/Stanley","America/Asuncion","America/Santiago","America/Campo_Grande"],"America/Montevideo":["America/Montevideo","America/Sao_Paulo"],"Asia/Beirut":"Asia/Gaza Asia/Beirut Europe/Minsk Europe/Helsinki Europe/Istanbul Asia/Damascus Asia/Jerusalem Africa/Cairo".split(" "),"Asia/Yerevan":["Asia/Yerevan","Asia/Baku"],"Pacific/Auckland":["Pacific/Auckland",
+"Pacific/Fiji"],"America/Los_Angeles":["America/Los_Angeles","America/Santa_Isabel"],"America/New_York":["America/Havana","America/New_York"],"America/Halifax":["America/Goose_Bay","America/Halifax"],"America/Godthab":["America/Miquelon","America/Godthab"]}; \ No newline at end of file
diff --git a/program/js/list.js b/program/js/list.js
index c2ad3f7c3..fbb478db7 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -1,1606 +1 @@
-/*
- +-----------------------------------------------------------------------+
- | Roundcube List Widget |
- | |
- | This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2013, 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. |
- | |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com> |
- | Charles McNulty <charles@charlesmcnulty.com> |
- +-----------------------------------------------------------------------+
- | Requires: common.js |
- +-----------------------------------------------------------------------+
-*/
-
-
-/**
- * Roundcube List Widget class
- * @contructor
- */
-function rcube_list_widget(list, p)
-{
- // static contants
- this.ENTER_KEY = 13;
- this.DELETE_KEY = 46;
- this.BACKSPACE_KEY = 8;
-
- this.list = list ? list : null;
- this.tagname = this.list ? this.list.nodeName.toLowerCase() : 'table';
- this.thead;
- this.tbody;
- this.fixed_header;
- this.frame = null;
- this.rows = [];
- this.selection = [];
- this.rowcount = 0;
- this.colcount = 0;
-
- this.subject_col = -1;
- this.modkey = 0;
- this.multiselect = false;
- this.multiexpand = false;
- this.multi_selecting = false;
- this.draggable = false;
- this.column_movable = false;
- this.keyboard = false;
- this.toggleselect = false;
-
- this.dont_select = false;
- this.drag_active = false;
- this.col_drag_active = false;
- this.column_fixed = null;
- this.last_selected = 0;
- this.shift_start = 0;
- this.in_selection_before = false;
- this.focused = false;
- this.drag_mouse_start = null;
- this.dblclick_time = 500; // default value on MS Windows is 500
- this.row_init = function(){}; // @deprecated; use list.addEventListener('initrow') instead
-
- // overwrite default paramaters
- if (p && typeof p === 'object')
- for (var n in p)
- this[n] = p[n];
-};
-
-
-rcube_list_widget.prototype = {
-
-
-/**
- * get all message rows from HTML table and init each row
- */
-init: function()
-{
- if (this.tagname == 'table' && this.list && this.list.tBodies[0]) {
- this.thead = this.list.tHead;
- this.tbody = this.list.tBodies[0];
- }
- else if (this.tagname != 'table' && this.list) {
- this.tbody = this.list;
- }
-
- if (this.tbody) {
- this.rows = [];
- this.rowcount = 0;
-
- var r, len, rows = this.tbody.childNodes;
-
- for (r=0, len=rows.length; r<len; r++) {
- this.init_row(rows[r]);
- this.rowcount++;
- }
-
- this.init_header();
- this.frame = this.list.parentNode;
-
- // set body events
- if (this.keyboard)
- rcube_event.add_listener({event:'keydown', object:this, method:'key_press'});
- }
-},
-
-
-/**
- * Init list row and set mouse events on it
- */
-init_row: function(row)
-{
- // make references in internal array and set event handlers
- if (row && String(row.id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i)) {
- var self = this,
- uid = RegExp.$1;
- row.uid = uid;
- this.rows[uid] = {uid:uid, id:row.id, obj:row};
-
- // set eventhandlers to table row
- row.onmousedown = function(e){ return self.drag_row(e, this.uid); };
- row.onmouseup = function(e){ return self.click_row(e, this.uid); };
-
- if (bw.touch) {
- row.addEventListener('touchstart', function(e) {
- if (e.touches.length == 1) {
- self.touchmoved = false;
- self.drag_row(rcube_event.touchevent(e.touches[0]), this.uid)
- }
- }, false);
- row.addEventListener('touchend', function(e) {
- if (e.changedTouches.length == 1) {
- if (!self.touchmoved && !self.click_row(rcube_event.touchevent(e.changedTouches[0]), this.uid))
- e.preventDefault();
- }
- }, false);
- row.addEventListener('touchmove', function(e) {
- if (e.changedTouches.length == 1) {
- self.touchmoved = true;
- if (self.drag_active)
- e.preventDefault();
- }
- }, false);
- }
-
- if (document.all)
- row.onselectstart = function() { return false; };
-
- this.row_init(this.rows[uid]); // legacy support
- this.triggerEvent('initrow', this.rows[uid]);
- }
-},
-
-
-/**
- * Init list column headers and set mouse events on them
- */
-init_header: function()
-{
- if (this.thead) {
- this.colcount = 0;
-
- if (this.fixed_header) { // copy (modified) fixed header back to the actual table
- $(this.list.tHead).replaceWith($(this.fixed_header).find('thead').clone());
- $(this.list.tHead).find('tr td').attr('style', ''); // remove fixed widths
- }
- else if (!bw.touch && this.list.className.indexOf('fixedheader') >= 0) {
- this.init_fixed_header();
- }
-
- var col, r, p = this;
- // add events for list columns moving
- if (this.column_movable && this.thead && this.thead.rows) {
- for (r=0; r<this.thead.rows[0].cells.length; r++) {
- if (this.column_fixed == r)
- continue;
- col = this.thead.rows[0].cells[r];
- col.onmousedown = function(e){ return p.drag_column(e, this); };
- this.colcount++;
- }
- }
- }
-},
-
-init_fixed_header: function()
-{
- var clone = $(this.list.tHead).clone();
-
- if (!this.fixed_header) {
- this.fixed_header = $('<table>')
- .attr('class', this.list.className + ' fixedcopy')
- .css({ position:'fixed' })
- .append(clone)
- .append('<tbody></tbody>');
- $(this.list).before(this.fixed_header);
-
- var me = this;
- $(window).resize(function(){ me.resize() });
- }
- else {
- $(this.fixed_header).find('thead').replaceWith(clone);
- }
-
- this.thead = clone.get(0);
- this.resize();
-},
-
-resize: function()
-{
- if (!this.fixed_header)
- return;
-
- var column_widths = [];
-
- // get column widths from original thead
- $(this.tbody).parent().find('thead tr td').each(function(index) {
- column_widths[index] = $(this).width();
- });
-
- // apply fixed widths to fixed table header
- $(this.thead).parent().width($(this.tbody).parent().width());
- $(this.thead).find('tr td').each(function(index) {
- $(this).css('width', column_widths[index]);
- });
-},
-
-/**
- * Remove all list rows
- */
-clear: function(sel)
-{
- if (this.tagname == 'table') {
- var tbody = document.createElement('tbody');
- this.list.insertBefore(tbody, this.tbody);
- this.list.removeChild(this.list.tBodies[1]);
- this.tbody = tbody;
- }
- else {
- $(this.row_tagname() + ':not(.thead)', this.tbody).remove();
- }
-
- this.rows = [];
- this.rowcount = 0;
-
- if (sel)
- this.clear_selection();
-
- // reset scroll position (in Opera)
- if (this.frame)
- this.frame.scrollTop = 0;
-},
-
-
-/**
- * 'remove' message row from list (just hide it)
- */
-remove_row: function(uid, sel_next)
-{
- var node = this.rows[uid] ? this.rows[uid].obj : null;
-
- if (!node)
- return;
-
- node.style.display = 'none';
-
- if (sel_next)
- this.select_next();
-
- delete this.rows[uid];
- this.rowcount--;
-},
-
-
-/**
- * Add row to the list and initialize it
- */
-insert_row: function(row, before)
-{
- var tbody = this.tbody;
-
- // create a real dom node first
- if (row.nodeName === undefined) {
- // for performance reasons use DOM instead of jQuery here
- var domrow = document.createElement(this.row_tagname());
- if (row.id) domrow.id = row.id;
- if (row.className) domrow.className = row.className;
- if (row.style) $.extend(domrow.style, row.style);
-
- for (var domcell, col, i=0; row.cols && i < row.cols.length; i++) {
- col = row.cols[i];
- domcell = document.createElement(this.col_tagname());
- if (col.className) domcell.className = col.className;
- if (col.innerHTML) domcell.innerHTML = col.innerHTML;
- domrow.appendChild(domcell);
- }
-
- row = domrow;
- }
-
- if (before && tbody.childNodes.length)
- tbody.insertBefore(row, (typeof before == 'object' && before.parentNode == tbody) ? before : tbody.firstChild);
- else
- tbody.appendChild(row);
-
- this.init_row(row);
- this.rowcount++;
-},
-
-/**
- *
- */
-update_row: function(id, cols, newid, select)
-{
- var row = this.rows[id];
- if (!row) return false;
-
- var domrow = row.obj;
- for (var domcell, col, i=0; cols && i < cols.length; i++) {
- this.get_cell(domrow, i).html(cols[i]);
- }
-
- if (newid) {
- delete this.rows[id];
- domrow.id = 'rcmrow' + newid;
- this.init_row(domrow);
-
- if (select)
- this.selection[0] = newid;
- }
-},
-
-
-/**
- * Set focus to the list
- */
-focus: function(e)
-{
- var n, id;
- this.focused = true;
-
- for (n in this.selection) {
- id = this.selection[n];
- if (this.rows[id] && this.rows[id].obj) {
- $(this.rows[id].obj).addClass('selected').removeClass('unfocused');
- }
- }
-
- // Un-focus already focused elements (#1487123, #1487316, #1488600, #1488620)
- // It looks that window.focus() does the job for all browsers, but not Firefox (#1489058)
- $(':focus:not(body)').blur();
- window.focus();
-
- if (e || (e = window.event))
- rcube_event.cancel(e);
-},
-
-
-/**
- * remove focus from the list
- */
-blur: function()
-{
- var n, id;
- this.focused = false;
- for (n in this.selection) {
- id = this.selection[n];
- if (this.rows[id] && this.rows[id].obj) {
- $(this.rows[id].obj).removeClass('selected focused').addClass('unfocused');
- }
- }
-},
-
-
-/**
- * onmousedown-handler of message list column
- */
-drag_column: function(e, col)
-{
- if (this.colcount > 1) {
- this.drag_start = true;
- this.drag_mouse_start = rcube_event.get_mouse_pos(e);
-
- rcube_event.add_listener({event:'mousemove', object:this, method:'column_drag_mouse_move'});
- rcube_event.add_listener({event:'mouseup', object:this, method:'column_drag_mouse_up'});
-
- // enable dragging over iframes
- this.add_dragfix();
-
- // find selected column number
- for (var i=0; i<this.thead.rows[0].cells.length; i++) {
- if (col == this.thead.rows[0].cells[i]) {
- this.selected_column = i;
- break;
- }
- }
- }
-
- return false;
-},
-
-
-/**
- * onmousedown-handler of message list row
- */
-drag_row: function(e, id)
-{
- // don't do anything (another action processed before)
- var evtarget = rcube_event.get_target(e),
- tagname = evtarget.tagName.toLowerCase();
-
- if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img')))
- return true;
-
- // accept right-clicks
- if (rcube_event.get_button(e) == 2)
- return true;
-
- this.in_selection_before = e && e.istouch || this.in_selection(id) ? id : false;
-
- // selects currently unselected row
- if (!this.in_selection_before) {
- var mod_key = rcube_event.get_modifier(e);
- this.select_row(id, mod_key, false);
- }
-
- if (this.draggable && this.selection.length && this.in_selection(id)) {
- this.drag_start = true;
- this.drag_mouse_start = rcube_event.get_mouse_pos(e);
- rcube_event.add_listener({event:'mousemove', object:this, method:'drag_mouse_move'});
- rcube_event.add_listener({event:'mouseup', object:this, method:'drag_mouse_up'});
- if (bw.touch) {
- rcube_event.add_listener({event:'touchmove', object:this, method:'drag_mouse_move'});
- rcube_event.add_listener({event:'touchend', object:this, method:'drag_mouse_up'});
- }
-
- // enable dragging over iframes
- this.add_dragfix();
- }
-
- return false;
-},
-
-
-/**
- * onmouseup-handler of message list row
- */
-click_row: function(e, id)
-{
- var now = new Date().getTime(),
- mod_key = rcube_event.get_modifier(e),
- evtarget = rcube_event.get_target(e),
- tagname = evtarget.tagName.toLowerCase();
-
- if ((evtarget && (tagname == 'input' || tagname == 'img')))
- return true;
-
- // don't do anything (another action processed before)
- if (this.dont_select) {
- this.dont_select = false;
- return false;
- }
-
- var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
-
- // unselects currently selected row
- if (!this.drag_active && this.in_selection_before == id && !dblclicked)
- this.select_row(id, mod_key, false);
-
- this.drag_start = false;
- this.in_selection_before = false;
-
- // row was double clicked
- if (this.rows && dblclicked && this.in_selection(id)) {
- this.triggerEvent('dblclick');
- now = 0;
- }
- else
- this.triggerEvent('click');
-
- if (!this.drag_active) {
- // remove temp divs
- this.del_dragfix();
- rcube_event.cancel(e);
- }
-
- this.rows[id].clicked = now;
- return false;
-},
-
-
-/*
- * Returns thread root ID for specified row ID
- */
-find_root: function(uid)
-{
- var r = this.rows[uid];
-
- if (r && r.parent_uid)
- return this.find_root(r.parent_uid);
- else
- return uid;
-},
-
-
-expand_row: function(e, id)
-{
- var row = this.rows[id],
- evtarget = rcube_event.get_target(e),
- mod_key = rcube_event.get_modifier(e);
-
- // Don't select this message
- this.dont_select = true;
- // Don't treat double click on the expando as double click on the message.
- row.clicked = 0;
-
- if (row.expanded) {
- evtarget.className = 'collapsed';
- if (mod_key == CONTROL_KEY || this.multiexpand)
- this.collapse_all(row);
- else
- this.collapse(row);
- }
- else {
- evtarget.className = 'expanded';
- if (mod_key == CONTROL_KEY || this.multiexpand)
- this.expand_all(row);
- else
- this.expand(row);
- }
-},
-
-collapse: function(row)
-{
- row.expanded = false;
- this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
- var depth = row.depth;
- var new_row = row ? row.obj.nextSibling : null;
- var r;
-
- while (new_row) {
- if (new_row.nodeType == 1) {
- var r = this.rows[new_row.uid];
- if (r && r.depth <= depth)
- break;
- $(new_row).css('display', 'none');
- if (r.expanded) {
- r.expanded = false;
- this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
- }
- }
- new_row = new_row.nextSibling;
- }
-
- this.resize();
- this.triggerEvent('listupdate');
- return false;
-},
-
-expand: function(row)
-{
- var r, p, depth, new_row, last_expanded_parent_depth;
-
- if (row) {
- row.expanded = true;
- depth = row.depth;
- new_row = row.obj.nextSibling;
- this.update_expando(row.uid, true);
- this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
- }
- else {
- var tbody = this.tbody;
- new_row = tbody.firstChild;
- depth = 0;
- last_expanded_parent_depth = 0;
- }
-
- while (new_row) {
- if (new_row.nodeType == 1) {
- r = this.rows[new_row.uid];
- if (r) {
- if (row && (!r.depth || r.depth <= depth))
- break;
-
- if (r.parent_uid) {
- p = this.rows[r.parent_uid];
- if (p && p.expanded) {
- if ((row && p == row) || last_expanded_parent_depth >= p.depth - 1) {
- last_expanded_parent_depth = p.depth;
- $(new_row).css('display', '');
- r.expanded = true;
- this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
- }
- }
- else
- if (row && (! p || p.depth <= depth))
- break;
- }
- }
- }
- new_row = new_row.nextSibling;
- }
-
- this.resize();
- this.triggerEvent('listupdate');
- return false;
-},
-
-
-collapse_all: function(row)
-{
- var depth, new_row, r;
-
- if (row) {
- row.expanded = false;
- depth = row.depth;
- new_row = row.obj.nextSibling;
- this.update_expando(row.uid);
- this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
-
- // don't collapse sub-root tree in multiexpand mode
- if (depth && this.multiexpand)
- return false;
- }
- else {
- new_row = this.tbody.firstChild;
- depth = 0;
- }
-
- while (new_row) {
- if (new_row.nodeType == 1) {
- if (r = this.rows[new_row.uid]) {
- if (row && (!r.depth || r.depth <= depth))
- break;
-
- if (row || r.depth)
- $(new_row).css('display', 'none');
- if (r.has_children && r.expanded) {
- r.expanded = false;
- this.update_expando(r.uid, false);
- this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
- }
- }
- }
- new_row = new_row.nextSibling;
- }
-
- this.resize();
- this.triggerEvent('listupdate');
- return false;
-},
-
-
-expand_all: function(row)
-{
- var depth, new_row, r;
-
- if (row) {
- row.expanded = true;
- depth = row.depth;
- new_row = row.obj.nextSibling;
- this.update_expando(row.uid, true);
- this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
- }
- else {
- new_row = this.tbody.firstChild;
- depth = 0;
- }
-
- while (new_row) {
- if (new_row.nodeType == 1) {
- if (r = this.rows[new_row.uid]) {
- if (row && r.depth <= depth)
- break;
-
- $(new_row).css('display', '');
- if (r.has_children && !r.expanded) {
- r.expanded = true;
- this.update_expando(r.uid, true);
- this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
- }
- }
- }
- new_row = new_row.nextSibling;
- }
-
- this.resize();
- this.triggerEvent('listupdate');
- return false;
-},
-
-
-update_expando: function(uid, expanded)
-{
- var expando = document.getElementById('rcmexpando' + uid);
- if (expando)
- expando.className = expanded ? 'expanded' : 'collapsed';
-},
-
-
-/**
- * get first/next/previous/last rows that are not hidden
- */
-get_next_row: function()
-{
- if (!this.rows)
- return false;
-
- var last_selected_row = this.rows[this.last_selected],
- new_row = last_selected_row ? last_selected_row.obj.nextSibling : null;
-
- while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
- new_row = new_row.nextSibling;
-
- return new_row;
-},
-
-get_prev_row: function()
-{
- if (!this.rows)
- return false;
-
- var last_selected_row = this.rows[this.last_selected],
- new_row = last_selected_row ? last_selected_row.obj.previousSibling : null;
-
- while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
- new_row = new_row.previousSibling;
-
- return new_row;
-},
-
-get_first_row: function()
-{
- if (this.rowcount) {
- var i, len, rows = this.tbody.childNodes;
-
- for (i=0, len=rows.length-1; i<len; i++)
- if (rows[i].id && String(rows[i].id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
- return RegExp.$1;
- }
-
- return null;
-},
-
-get_last_row: function()
-{
- if (this.rowcount) {
- var i, rows = this.tbody.childNodes;
-
- for (i=rows.length-1; i>=0; i--)
- if (rows[i].id && String(rows[i].id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
- return RegExp.$1;
- }
-
- return null;
-},
-
-row_tagname: function()
-{
- var row_tagnames = { table:'tr', ul:'li', '*':'div' };
- return row_tagnames[this.tagname] || row_tagnames['*'];
-},
-
-col_tagname: function()
-{
- var col_tagnames = { table:'td', '*':'span' };
- return col_tagnames[this.tagname] || col_tagnames['*'];
-},
-
-get_cell: function(row, index)
-{
- return $(this.col_tagname(), row).eq(index);
-},
-
-/**
- * selects or unselects the proper row depending on the modifier key pressed
- */
-select_row: function(id, mod_key, with_mouse)
-{
- var select_before = this.selection.join(',');
- if (!this.multiselect)
- mod_key = 0;
-
- if (!this.shift_start)
- this.shift_start = id
-
- if (!mod_key) {
- this.shift_start = id;
- this.highlight_row(id, false);
- this.multi_selecting = false;
- }
- else {
- switch (mod_key) {
- case SHIFT_KEY:
- this.shift_select(id, false);
- break;
-
- case CONTROL_KEY:
- if (!with_mouse)
- this.highlight_row(id, true);
- break;
-
- case CONTROL_SHIFT_KEY:
- this.shift_select(id, true);
- break;
-
- default:
- this.highlight_row(id, false);
- break;
- }
- this.multi_selecting = true;
- }
-
- // trigger event if selection changed
- if (this.selection.join(',') != select_before)
- this.triggerEvent('select');
-
- if (this.last_selected != 0 && this.rows[this.last_selected])
- $(this.rows[this.last_selected].obj).removeClass('focused');
-
- // unselect if toggleselect is active and the same row was clicked again
- if (this.toggleselect && this.last_selected == id) {
- this.clear_selection();
- id = null;
- }
- else
- $(this.rows[id].obj).addClass('focused');
-
- if (!this.selection.length)
- this.shift_start = null;
-
- this.last_selected = id;
-},
-
-
-/**
- * Alias method for select_row
- */
-select: function(id)
-{
- this.select_row(id, false);
- this.scrollto(id);
-},
-
-
-/**
- * Select row next to the last selected one.
- * Either below or above.
- */
-select_next: function()
-{
- var next_row = this.get_next_row(),
- prev_row = this.get_prev_row(),
- new_row = (next_row) ? next_row : prev_row;
-
- if (new_row)
- this.select_row(new_row.uid, false, false);
-},
-
-
-/**
- * Select first row
- */
-select_first: function(mod_key)
-{
- var row = this.get_first_row();
- if (row) {
- if (mod_key) {
- this.shift_select(row, mod_key);
- this.triggerEvent('select');
- this.scrollto(row);
- }
- else {
- this.select(row);
- }
- }
-},
-
-
-/**
- * Select last row
- */
-select_last: function(mod_key)
-{
- var row = this.get_last_row();
- if (row) {
- if (mod_key) {
- this.shift_select(row, mod_key);
- this.triggerEvent('select');
- this.scrollto(row);
- }
- else {
- this.select(row);
- }
- }
-},
-
-
-/**
- * Add all childs of the given row to selection
- */
-select_children: function(uid)
-{
- var i, children = this.row_children(uid), len = children.length;
-
- for (i=0; i<len; i++)
- if (!this.in_selection(children[i]))
- this.select_row(children[i], CONTROL_KEY);
-},
-
-
-/**
- * Perform selection when shift key is pressed
- */
-shift_select: function(id, control)
-{
- if (!this.rows[this.shift_start] || !this.selection.length)
- this.shift_start = id;
-
- var n, i, j, to_row = this.rows[id],
- from_rowIndex = this._rowIndex(this.rows[this.shift_start].obj),
- to_rowIndex = this._rowIndex(to_row.obj);
-
- if (!to_row.expanded && to_row.has_children)
- if (to_row = this.rows[(this.row_children(id)).pop()])
- to_rowIndex = this._rowIndex(to_row.obj);
-
- i = ((from_rowIndex < to_rowIndex) ? from_rowIndex : to_rowIndex),
- j = ((from_rowIndex > to_rowIndex) ? from_rowIndex : to_rowIndex);
-
- // iterate through the entire message list
- for (n in this.rows) {
- if (this._rowIndex(this.rows[n].obj) >= i && this._rowIndex(this.rows[n].obj) <= j) {
- if (!this.in_selection(n)) {
- this.highlight_row(n, true);
- }
- }
- else {
- if (this.in_selection(n) && !control) {
- this.highlight_row(n, true);
- }
- }
- }
-},
-
-/**
- * Helper method to emulate the rowIndex property of non-tr elements
- */
-_rowIndex: function(obj)
-{
- return (obj.rowIndex !== undefined) ? obj.rowIndex : $(obj).prevAll().length;
-},
-
-/**
- * Check if given id is part of the current selection
- */
-in_selection: function(id)
-{
- for (var n in this.selection)
- if (this.selection[n]==id)
- return true;
-
- return false;
-},
-
-
-/**
- * Select each row in list
- */
-select_all: function(filter)
-{
- if (!this.rows || !this.rows.length)
- return false;
-
- // reset but remember selection first
- var n, select_before = this.selection.join(',');
- this.selection = [];
-
- for (n in this.rows) {
- if (!filter || this.rows[n][filter] == true) {
- this.last_selected = n;
- this.highlight_row(n, true, true);
- }
- else {
- $(this.rows[n].obj).removeClass('selected').removeClass('unfocused');
- }
- }
-
- // trigger event if selection changed
- if (this.selection.join(',') != select_before)
- this.triggerEvent('select');
-
- this.focus();
-
- return true;
-},
-
-
-/**
- * Invert selection
- */
-invert_selection: function()
-{
- if (!this.rows || !this.rows.length)
- return false;
-
- // remember old selection
- var n, select_before = this.selection.join(',');
-
- for (n in this.rows)
- this.highlight_row(n, true);
-
- // trigger event if selection changed
- if (this.selection.join(',') != select_before)
- this.triggerEvent('select');
-
- this.focus();
-
- return true;
-},
-
-
-/**
- * Unselect selected row(s)
- */
-clear_selection: function(id)
-{
- var n, num_select = this.selection.length;
-
- // one row
- if (id) {
- for (n in this.selection)
- if (this.selection[n] == id) {
- this.selection.splice(n,1);
- break;
- }
- }
- // all rows
- else {
- for (n in this.selection)
- if (this.rows[this.selection[n]]) {
- $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused');
- }
-
- this.selection = [];
- }
-
- if (num_select && !this.selection.length)
- this.triggerEvent('select');
-},
-
-
-/**
- * Getter for the selection array
- */
-get_selection: function()
-{
- return this.selection;
-},
-
-
-/**
- * Return the ID if only one row is selected
- */
-get_single_selection: function()
-{
- if (this.selection.length == 1)
- return this.selection[0];
- else
- return null;
-},
-
-
-/**
- * Highlight/unhighlight a row
- */
-highlight_row: function(id, multiple, norecur)
-{
- if (!this.rows[id])
- return;
-
- if (!multiple) {
- if (this.selection.length > 1 || !this.in_selection(id)) {
- this.clear_selection();
- this.selection[0] = id;
- $(this.rows[id].obj).addClass('selected');
- }
- }
- else {
- if (!this.in_selection(id)) { // select row
- this.selection.push(id);
- $(this.rows[id].obj).addClass('selected');
- if (!norecur && !this.rows[id].expanded)
- this.highlight_children(id, true);
- }
- else { // unselect row
- var p = $.inArray(id, this.selection),
- a_pre = this.selection.slice(0, p),
- a_post = this.selection.slice(p+1, this.selection.length);
-
- this.selection = a_pre.concat(a_post);
- $(this.rows[id].obj).removeClass('selected').removeClass('unfocused');
- if (!norecur && !this.rows[id].expanded)
- this.highlight_children(id, false);
- }
- }
-},
-
-
-/**
- * Highlight/unhighlight all childs of the given row
- */
-highlight_children: function(id, status)
-{
- var i, selected,
- children = this.row_children(id), len = children.length;
-
- for (i=0; i<len; i++) {
- selected = this.in_selection(children[i]);
- if ((status && !selected) || (!status && selected))
- this.highlight_row(children[i], true, true);
- }
-},
-
-
-/**
- * Handler for keyboard events
- */
-key_press: function(e)
-{
- var target = e.target || {};
- if (this.focused != true || target.nodeName == 'INPUT' || target.nodeName == 'TEXTAREA' || target.nodeName == 'SELECT')
- return true;
-
- var keyCode = rcube_event.get_keycode(e),
- mod_key = rcube_event.get_modifier(e);
-
- switch (keyCode) {
- case 40:
- case 38:
- case 63233: // "down", in safari keypress
- case 63232: // "up", in safari keypress
- // Stop propagation so that the browser doesn't scroll
- rcube_event.cancel(e);
- return this.use_arrow_key(keyCode, mod_key);
- case 61:
- case 107: // Plus sign on a numeric keypad (fc11 + firefox 3.5.2)
- case 109:
- case 32:
- // Stop propagation
- rcube_event.cancel(e);
- var ret = this.use_plusminus_key(keyCode, mod_key);
- this.key_pressed = keyCode;
- this.modkey = mod_key;
- this.triggerEvent('keypress');
- this.modkey = 0;
- return ret;
- case 36: // Home
- this.select_first(mod_key);
- return rcube_event.cancel(e);
- case 35: // End
- this.select_last(mod_key);
- return rcube_event.cancel(e);
- case 27:
- if (this.drag_active)
- return this.drag_mouse_up(e);
- if (this.col_drag_active) {
- this.selected_column = null;
- return this.column_drag_mouse_up(e);
- }
- return rcube_event.cancel(e);
- default:
- this.key_pressed = keyCode;
- this.modkey = mod_key;
- this.triggerEvent('keypress');
- this.modkey = 0;
-
- if (this.key_pressed == this.BACKSPACE_KEY)
- return rcube_event.cancel(e);
- }
-
- return true;
-},
-
-
-/**
- * Special handling method for arrow keys
- */
-use_arrow_key: function(keyCode, mod_key)
-{
- var new_row;
- // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
- // using the keypress event (but not the keydown or keyup event).
- if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
- new_row = this.get_next_row();
- else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
- new_row = this.get_prev_row();
-
- if (new_row) {
- this.select_row(new_row.uid, mod_key, false);
- this.scrollto(new_row.uid);
- }
-
- return false;
-},
-
-
-/**
- * Special handling method for +/- keys
- */
-use_plusminus_key: function(keyCode, mod_key)
-{
- var selected_row = this.rows[this.last_selected];
- if (!selected_row)
- return;
-
- if (keyCode == 32)
- keyCode = selected_row.expanded ? 109 : 61;
- if (keyCode == 61 || keyCode == 107)
- if (mod_key == CONTROL_KEY || this.multiexpand)
- this.expand_all(selected_row);
- else
- this.expand(selected_row);
- else
- if (mod_key == CONTROL_KEY || this.multiexpand)
- this.collapse_all(selected_row);
- else
- this.collapse(selected_row);
-
- this.update_expando(selected_row.uid, selected_row.expanded);
-
- return false;
-},
-
-
-/**
- * Try to scroll the list to make the specified row visible
- */
-scrollto: function(id)
-{
- var row = this.rows[id].obj;
- if (row && this.frame) {
- var scroll_to = Number(row.offsetTop);
-
- // expand thread if target row is hidden (collapsed)
- if (!scroll_to && this.rows[id].parent_uid) {
- var parent = this.find_root(this.rows[id].uid);
- this.expand_all(this.rows[parent]);
- scroll_to = Number(row.offsetTop);
- }
-
- if (scroll_to < Number(this.frame.scrollTop))
- this.frame.scrollTop = scroll_to;
- else if (scroll_to + Number(row.offsetHeight) > Number(this.frame.scrollTop) + Number(this.frame.offsetHeight))
- this.frame.scrollTop = (scroll_to + Number(row.offsetHeight)) - Number(this.frame.offsetHeight);
- }
-},
-
-
-/**
- * Handler for mouse move events
- */
-drag_mouse_move: function(e)
-{
- // convert touch event
- if (e.type == 'touchmove') {
- if (e.touches.length == 1 && e.changedTouches.length == 1)
- e = rcube_event.touchevent(e.changedTouches[0]);
- else
- return rcube_event.cancel(e);
- }
-
- if (this.drag_start) {
- // check mouse movement, of less than 3 pixels, don't start dragging
- var m = rcube_event.get_mouse_pos(e);
-
- if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3))
- return false;
-
- if (!this.draglayer)
- this.draglayer = $('<div>').attr('id', 'rcmdraglayer')
- .css({ position:'absolute', display:'none', 'z-index':2000 })
- .appendTo(document.body);
-
- // also select childs of (collapsed) threads for dragging
- var n, uid, selection = $.merge([], this.selection);
- for (n in selection) {
- uid = selection[n];
- if (!this.rows[uid].expanded)
- this.select_children(uid);
- }
-
- // reset content
- this.draglayer.html('');
-
- // get subjects of selected messages
- var i, n, obj, me;
- for (n=0; n<this.selection.length; n++) {
- // only show 12 lines
- if (n>12) {
- this.draglayer.append('...');
- break;
- }
-
- me = this;
- if (obj = this.rows[this.selection[n]].obj) {
- $('> '+this.col_tagname(), obj).each(function(i,elem){
- if (n == 0)
- me.drag_start_pos = $(elem).offset();
-
- if (me.subject_col < 0 || (me.subject_col >= 0 && me.subject_col == i)) {
- var subject = $(elem).text();
-
- if (subject) {
- // remove leading spaces
- subject = $.trim(subject);
- // truncate line to 50 characters
- subject = (subject.length > 50 ? subject.substring(0, 50) + '...' : subject);
-
- var entry = $('<div>').text(subject);
- me.draglayer.append(entry);
- }
-
- return false; // break
- }
- });
- }
- }
-
- this.draglayer.show();
- this.drag_active = true;
- this.triggerEvent('dragstart');
- }
-
- if (this.drag_active && this.draglayer) {
- var pos = rcube_event.get_mouse_pos(e);
- this.draglayer.css({ left:(pos.x+20)+'px', top:(pos.y-5 + (bw.ie ? document.documentElement.scrollTop : 0))+'px' });
- this.triggerEvent('dragmove', e?e:window.event);
- }
-
- this.drag_start = false;
-
- return false;
-},
-
-
-/**
- * Handler for mouse up events
- */
-drag_mouse_up: function(e)
-{
- document.onmousemove = null;
-
- if (e.type == 'touchend') {
- if (e.changedTouches.length != 1)
- return rcube_event.cancel(e);
- }
-
- if (this.draglayer && this.draglayer.is(':visible')) {
- if (this.drag_start_pos)
- this.draglayer.animate(this.drag_start_pos, 300, 'swing').hide(20);
- else
- this.draglayer.hide();
- }
-
- if (this.drag_active)
- this.focus();
- this.drag_active = false;
-
- rcube_event.remove_listener({event:'mousemove', object:this, method:'drag_mouse_move'});
- rcube_event.remove_listener({event:'mouseup', object:this, method:'drag_mouse_up'});
-
- if (bw.touch) {
- rcube_event.remove_listener({event:'touchmove', object:this, method:'drag_mouse_move'});
- rcube_event.remove_listener({event:'touchend', object:this, method:'drag_mouse_up'});
- }
-
- // remove temp divs
- this.del_dragfix();
-
- this.triggerEvent('dragend', e);
-
- return rcube_event.cancel(e);
-},
-
-
-/**
- * Handler for mouse move events for dragging list column
- */
-column_drag_mouse_move: function(e)
-{
- if (this.drag_start) {
- // check mouse movement, of less than 3 pixels, don't start dragging
- var i, m = rcube_event.get_mouse_pos(e);
-
- if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3))
- return false;
-
- if (!this.col_draglayer) {
- var lpos = $(this.list).offset(),
- cells = this.thead.rows[0].cells;
-
- // create dragging layer
- this.col_draglayer = $('<div>').attr('id', 'rcmcoldraglayer')
- .css(lpos).css({ position:'absolute', 'z-index':2001,
- 'background-color':'white', opacity:0.75,
- height: (this.frame.offsetHeight-2)+'px', width: (this.frame.offsetWidth-2)+'px' })
- .appendTo(document.body)
- // ... and column position indicator
- .append($('<div>').attr('id', 'rcmcolumnindicator')
- .css({ position:'absolute', 'border-right':'2px dotted #555',
- 'z-index':2002, height: (this.frame.offsetHeight-2)+'px' }));
-
- this.cols = [];
- this.list_pos = this.list_min_pos = lpos.left;
- // save columns positions
- for (i=0; i<cells.length; i++) {
- this.cols[i] = cells[i].offsetWidth;
- if (this.column_fixed !== null && i <= this.column_fixed) {
- this.list_min_pos += this.cols[i];
- }
- }
- }
-
- this.col_draglayer.show();
- this.col_drag_active = true;
- this.triggerEvent('column_dragstart');
- }
-
- // set column indicator position
- if (this.col_drag_active && this.col_draglayer) {
- var i, cpos = 0, pos = rcube_event.get_mouse_pos(e);
-
- for (i=0; i<this.cols.length; i++) {
- if (pos.x >= this.cols[i]/2 + this.list_pos + cpos)
- cpos += this.cols[i];
- else
- break;
- }
-
- // handle fixed columns on left
- if (i == 0 && this.list_min_pos > pos.x)
- cpos = this.list_min_pos - this.list_pos;
- // empty list needs some assignment
- else if (!this.list.rowcount && i == this.cols.length)
- cpos -= 2;
- $('#rcmcolumnindicator').css({ width: cpos+'px'});
- this.triggerEvent('column_dragmove', e?e:window.event);
- }
-
- this.drag_start = false;
-
- return false;
-},
-
-
-/**
- * Handler for mouse up events for dragging list columns
- */
-column_drag_mouse_up: function(e)
-{
- document.onmousemove = null;
-
- if (this.col_draglayer) {
- (this.col_draglayer).remove();
- this.col_draglayer = null;
- }
-
- if (this.col_drag_active)
- this.focus();
- this.col_drag_active = false;
-
- rcube_event.remove_listener({event:'mousemove', object:this, method:'column_drag_mouse_move'});
- rcube_event.remove_listener({event:'mouseup', object:this, method:'column_drag_mouse_up'});
- // remove temp divs
- this.del_dragfix();
-
- if (this.selected_column !== null && this.cols && this.cols.length) {
- var i, cpos = 0, pos = rcube_event.get_mouse_pos(e);
-
- // find destination position
- for (i=0; i<this.cols.length; i++) {
- if (pos.x >= this.cols[i]/2 + this.list_pos + cpos)
- cpos += this.cols[i];
- else
- break;
- }
-
- if (i != this.selected_column && i != this.selected_column+1) {
- this.column_replace(this.selected_column, i);
- }
- }
-
- this.triggerEvent('column_dragend', e);
-
- return rcube_event.cancel(e);
-},
-
-
-/**
- * Returns IDs of all rows in a thread (except root) for specified root
- */
-row_children: function(uid)
-{
- if (!this.rows[uid] || !this.rows[uid].has_children)
- return [];
-
- var res = [], depth = this.rows[uid].depth,
- row = this.rows[uid].obj.nextSibling;
-
- while (row) {
- if (row.nodeType == 1) {
- if ((r = this.rows[row.uid])) {
- if (!r.depth || r.depth <= depth)
- break;
- res.push(r.uid);
- }
- }
- row = row.nextSibling;
- }
-
- return res;
-},
-
-
-/**
- * Creates a layer for drag&drop over iframes
- */
-add_dragfix: function()
-{
- $('iframe').each(function() {
- $('<div class="iframe-dragdrop-fix"></div>')
- .css({background: '#fff',
- width: this.offsetWidth+'px', height: this.offsetHeight+'px',
- position: 'absolute', opacity: '0.001', zIndex: 1000
- })
- .css($(this).offset())
- .appendTo(document.body);
- });
-},
-
-
-/**
- * Removes the layer for drag&drop over iframes
- */
-del_dragfix: function()
-{
- $('div.iframe-dragdrop-fix').each(function() { this.parentNode.removeChild(this); });
-},
-
-
-/**
- * Replaces two columns
- */
-column_replace: function(from, to)
-{
- // only supported for <table> lists
- if (!this.thead || !this.thead.rows)
- return;
-
- var len, cells = this.thead.rows[0].cells,
- elem = cells[from],
- before = cells[to],
- td = document.createElement('td');
-
- // replace header cells
- if (before)
- cells[0].parentNode.insertBefore(td, before);
- else
- cells[0].parentNode.appendChild(td);
- cells[0].parentNode.replaceChild(elem, td);
-
- // replace list cells
- for (r=0, len=this.tbody.rows.length; r<len; r++) {
- row = this.tbody.rows[r];
-
- elem = row.cells[from];
- before = row.cells[to];
- td = document.createElement('td');
-
- if (before)
- row.insertBefore(td, before);
- else
- row.appendChild(td);
- row.replaceChild(elem, td);
- }
-
- // update subject column position
- if (this.subject_col == from)
- this.subject_col = to > from ? to - 1 : to;
- else if (this.subject_col < from && to <= this.subject_col)
- this.subject_col++;
- else if (this.subject_col > from && to >= this.subject_col)
- this.subject_col--;
-
- if (this.fixed_header)
- this.init_header();
-
- this.triggerEvent('column_replace');
-}
-
-};
-
-rcube_list_widget.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
-rcube_list_widget.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
-rcube_list_widget.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
+function rcube_list_widget(a,b){this.ENTER_KEY=13;this.DELETE_KEY=46;this.BACKSPACE_KEY=8;this.list=a?a:null;this.frame=null;this.rows=[];this.selection=[];this.rowcount=0;this.colcount=0;this.subject_col=-1;this.modkey=0;this.multiselect=false;this.multiexpand=false;this.multi_selecting=false;this.draggable=false;this.column_movable=false;this.keyboard=false;this.toggleselect=false;this.dont_select=false;this.drag_active=false;this.col_drag_active=false;this.column_fixed=null;this.last_selected=0;this.shift_start=0;this.in_selection_before=false;this.focused=false;this.drag_mouse_start=null;this.dblclick_time=600;this.row_init=function(){};if(b&&typeof b==="object"){for(var c in b){this[c]=b[c]}}}rcube_list_widget.prototype={init:function(){if(this.list&&this.list.tBodies[0]){this.rows=[];this.rowcount=0;var b,a,c=this.list.tBodies[0].rows;for(b=0,a=c.length;b<a;b++){this.init_row(c[b]);this.rowcount++}this.init_header();this.frame=this.list.parentNode;if(this.keyboard){rcube_event.add_listener({event:"keydown",object:this,method:"key_press"})}}},init_row:function(c){if(c&&String(c.id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i)){var a=this,b=RegExp.$1;c.uid=b;this.rows[b]={uid:b,id:c.id,obj:c};c.onmousedown=function(d){return a.drag_row(d,this.uid)};c.onmouseup=function(d){return a.click_row(d,this.uid)};if(bw.touch){c.addEventListener("touchstart",function(d){if(d.touches.length==1){a.touchmoved=false;a.drag_row(rcube_event.touchevent(d.touches[0]),this.uid)}},false);c.addEventListener("touchend",function(d){if(d.changedTouches.length==1){if(!a.touchmoved&&!a.click_row(rcube_event.touchevent(d.changedTouches[0]),this.uid)){d.preventDefault()}}},false);c.addEventListener("touchmove",function(d){if(d.changedTouches.length==1){a.touchmoved=true;if(a.drag_active){d.preventDefault()}}},false)}if(document.all){c.onselectstart=function(){return false}}this.row_init(this.rows[b])}},init_header:function(){if(this.list&&this.list.tHead){this.colcount=0;var a,b,c=this;if(this.column_movable&&this.list.tHead&&this.list.tHead.rows){for(b=0;b<this.list.tHead.rows[0].cells.length;b++){if(this.column_fixed==b){continue}a=this.list.tHead.rows[0].cells[b];a.onmousedown=function(d){return c.drag_column(d,this)};this.colcount++}}}},clear:function(b){var a=document.createElement("tbody");this.list.insertBefore(a,this.list.tBodies[0]);this.list.removeChild(this.list.tBodies[1]);this.rows=[];this.rowcount=0;if(b){this.clear_selection()}if(this.frame){this.frame.scrollTop=0}},remove_row:function(a,b){var c=this.rows[a]?this.rows[a].obj:null;if(!c){return}c.style.display="none";if(b){this.select_next()}delete this.rows[a];this.rowcount--},insert_row:function(c,a){var b=this.list.tBodies[0];if(a&&b.rows.length){b.insertBefore(c,b.firstChild)}else{b.appendChild(c)}this.init_row(c);this.rowcount++},focus:function(a){var c,b;this.focused=true;for(c in this.selection){b=this.selection[c];if(this.rows[b]&&this.rows[b].obj){$(this.rows[b].obj).addClass("selected").removeClass("unfocused")}}$(":focus:not(body)").blur();window.focus();if(a||(a=window.event)){rcube_event.cancel(a)}},blur:function(){var b,a;this.focused=false;for(b in this.selection){a=this.selection[b];if(this.rows[a]&&this.rows[a].obj){$(this.rows[a].obj).removeClass("selected focused").addClass("unfocused")}}},drag_column:function(c,a){if(this.colcount>1){this.drag_start=true;this.drag_mouse_start=rcube_event.get_mouse_pos(c);rcube_event.add_listener({event:"mousemove",object:this,method:"column_drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.add_dragfix();for(var b=0;b<this.list.tHead.rows[0].cells.length;b++){if(a==this.list.tHead.rows[0].cells[b]){this.selected_column=b;break}}}return false},drag_row:function(d,f){var c=rcube_event.get_target(d),b=c.tagName.toLowerCase();if(this.dont_select||(c&&(b=="input"||b=="img"))){return true}if(rcube_event.get_button(d)==2){return true}this.in_selection_before=d&&d.istouch||this.in_selection(f)?f:false;if(!this.in_selection_before){var a=rcube_event.get_modifier(d);this.select_row(f,a,false)}if(this.draggable&&this.selection.length&&this.in_selection(f)){this.drag_start=true;this.drag_mouse_start=rcube_event.get_mouse_pos(d);rcube_event.add_listener({event:"mousemove",object:this,method:"drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"drag_mouse_up"});if(bw.touch){rcube_event.add_listener({event:"touchmove",object:this,method:"drag_mouse_move"});rcube_event.add_listener({event:"touchend",object:this,method:"drag_mouse_up"})}this.add_dragfix()}return false},click_row:function(g,h){var c=new Date().getTime(),b=rcube_event.get_modifier(g),f=rcube_event.get_target(g),d=f.tagName.toLowerCase();if((f&&(d=="input"||d=="img"))){return true}if(this.dont_select){this.dont_select=false;return false}var a=c-this.rows[h].clicked<this.dblclick_time;if(!this.drag_active&&this.in_selection_before==h&&!a){this.select_row(h,b,false)}this.drag_start=false;this.in_selection_before=false;if(this.rows&&a&&this.in_selection(h)){this.triggerEvent("dblclick");c=0}else{this.triggerEvent("click")}if(!this.drag_active){this.del_dragfix();rcube_event.cancel(g)}this.rows[h].clicked=c;return false},find_root:function(a){var b=this.rows[a];if(b&&b.parent_uid){return this.find_root(b.parent_uid)}else{return a}},expand_row:function(c,f){var d=this.rows[f],b=rcube_event.get_target(c),a=rcube_event.get_modifier(c);this.dont_select=true;d.clicked=0;if(d.expanded){b.className="collapsed";if(a==CONTROL_KEY||this.multiexpand){this.collapse_all(d)}else{this.collapse(d)}}else{b.className="expanded";if(a==CONTROL_KEY||this.multiexpand){this.expand_all(d)}else{this.expand(d)}}},collapse:function(d){d.expanded=false;this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded,obj:d.obj});var c=d.depth;var a=d?d.obj.nextSibling:null;var b;while(a){if(a.nodeType==1){var b=this.rows[a.uid];if(b&&b.depth<=c){break}$(a).css("display","none");if(b.expanded){b.expanded=false;this.triggerEvent("expandcollapse",{uid:b.uid,expanded:b.expanded,obj:a})}}a=a.nextSibling}return false},expand:function(g){var d,e,f,b,a;if(g){g.expanded=true;f=g.depth;b=g.obj.nextSibling;this.update_expando(g.uid,true);this.triggerEvent("expandcollapse",{uid:g.uid,expanded:g.expanded,obj:g.obj})}else{var c=this.list.tBodies[0];b=c.firstChild;f=0;a=0}while(b){if(b.nodeType==1){d=this.rows[b.uid];if(d){if(g&&(!d.depth||d.depth<=f)){break}if(d.parent_uid){e=this.rows[d.parent_uid];if(e&&e.expanded){if((g&&e==g)||a>=e.depth-1){a=e.depth;$(b).css("display","");d.expanded=true;this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded,obj:b})}}else{if(g&&(!e||e.depth<=f)){break}}}}}b=b.nextSibling}return false},collapse_all:function(d){var c,a,b;if(d){d.expanded=false;c=d.depth;a=d.obj.nextSibling;this.update_expando(d.uid);this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded,obj:d.obj});if(c&&this.multiexpand){return false}}else{a=this.list.tBodies[0].firstChild;c=0}while(a){if(a.nodeType==1){if(b=this.rows[a.uid]){if(d&&(!b.depth||b.depth<=c)){break}if(d||b.depth){$(a).css("display","none")}if(b.has_children&&b.expanded){b.expanded=false;this.update_expando(b.uid,false);this.triggerEvent("expandcollapse",{uid:b.uid,expanded:b.expanded,obj:a})}}}a=a.nextSibling}return false},expand_all:function(d){var c,a,b;if(d){d.expanded=true;c=d.depth;a=d.obj.nextSibling;this.update_expando(d.uid,true);this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded,obj:d.obj})}else{a=this.list.tBodies[0].firstChild;c=0}while(a){if(a.nodeType==1){if(b=this.rows[a.uid]){if(d&&b.depth<=c){break}$(a).css("display","");if(b.has_children&&!b.expanded){b.expanded=true;this.update_expando(b.uid,true);this.triggerEvent("expandcollapse",{uid:b.uid,expanded:b.expanded,obj:a})}}}a=a.nextSibling}return false},update_expando:function(b,a){var c=document.getElementById("rcmexpando"+b);if(c){c.className=a?"expanded":"collapsed"}},get_next_row:function(){if(!this.rows){return false}var b=this.rows[this.last_selected],a=b?b.obj.nextSibling:null;while(a&&(a.nodeType!=1||a.style.display=="none")){a=a.nextSibling}return a},get_prev_row:function(){if(!this.rows){return false}var b=this.rows[this.last_selected],a=b?b.obj.previousSibling:null;while(a&&(a.nodeType!=1||a.style.display=="none")){a=a.previousSibling}return a},get_first_row:function(){if(this.rowcount){var b,a,c=this.list.tBodies[0].rows;for(b=0,a=c.length-1;b<a;b++){if(c[b].id&&String(c[b].id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null){return RegExp.$1}}}return null},get_last_row:function(){if(this.rowcount){var a,b=this.list.tBodies[0].rows;for(a=b.length-1;a>=0;a--){if(b[a].id&&String(b[a].id).match(/^rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null){return RegExp.$1}}}return null},select_row:function(d,a,c){var b=this.selection.join(",");if(!this.multiselect){a=0}if(!this.shift_start){this.shift_start=d}if(!a){this.shift_start=d;this.highlight_row(d,false);this.multi_selecting=false}else{switch(a){case SHIFT_KEY:this.shift_select(d,false);break;case CONTROL_KEY:if(!c){this.highlight_row(d,true)}break;case CONTROL_SHIFT_KEY:this.shift_select(d,true);break;default:this.highlight_row(d,false);break}this.multi_selecting=true}if(this.selection.join(",")!=b){this.triggerEvent("select")}if(this.last_selected!=0&&this.rows[this.last_selected]){$(this.rows[this.last_selected].obj).removeClass("focused")}if(this.toggleselect&&this.last_selected==d){this.clear_selection();d=null}else{$(this.rows[d].obj).addClass("focused")}if(!this.selection.length){this.shift_start=null}this.last_selected=d},select:function(a){this.select_row(a,false);this.scrollto(a)},select_next:function(){var b=this.get_next_row(),c=this.get_prev_row(),a=(b)?b:c;if(a){this.select_row(a.uid,false,false)}},select_first:function(a){var b=this.get_first_row();if(b){if(a){this.shift_select(b,a);this.triggerEvent("select");this.scrollto(b)}else{this.select(b)}}},select_last:function(a){var b=this.get_last_row();if(b){if(a){this.shift_select(b,a);this.triggerEvent("select");this.scrollto(b)}else{this.select(b)}}},select_children:function(d){var c,b=this.row_children(d),a=b.length;for(c=0;c<a;c++){if(!this.in_selection(b[c])){this.select_row(b[c],CONTROL_KEY)}}},shift_select:function(h,f){if(!this.rows[this.shift_start]||!this.selection.length){this.shift_start=h}var g,d,c,a=this.rows[h],e=this.rows[this.shift_start].obj.rowIndex,b=a.obj.rowIndex;if(!a.expanded&&a.has_children){if(a=this.rows[(this.row_children(h)).pop()]){b=a.obj.rowIndex}}d=((e<b)?e:b),c=((e>b)?e:b);for(g in this.rows){if(this.rows[g].obj.rowIndex>=d&&this.rows[g].obj.rowIndex<=c){if(!this.in_selection(g)){this.highlight_row(g,true)}}else{if(this.in_selection(g)&&!f){this.highlight_row(g,true)}}}},in_selection:function(b){for(var a in this.selection){if(this.selection[a]==b){return true}}return false},select_all:function(b){if(!this.rows||!this.rows.length){return false}var c,a=this.selection.join(",");this.selection=[];for(c in this.rows){if(!b||this.rows[c][b]==true){this.last_selected=c;this.highlight_row(c,true,true)}else{$(this.rows[c].obj).removeClass("selected").removeClass("unfocused")}}if(this.selection.join(",")!=a){this.triggerEvent("select")}this.focus();return true},invert_selection:function(){if(!this.rows||!this.rows.length){return false}var b,a=this.selection.join(",");for(b in this.rows){this.highlight_row(b,true)}if(this.selection.join(",")!=a){this.triggerEvent("select")}this.focus();return true},clear_selection:function(c){var b,a=this.selection.length;if(c){for(b in this.selection){if(this.selection[b]==c){this.selection.splice(b,1);break}}}else{for(b in this.selection){if(this.rows[this.selection[b]]){$(this.rows[this.selection[b]].obj).removeClass("selected").removeClass("unfocused")}}this.selection=[]}if(a&&!this.selection.length){this.triggerEvent("select")}},get_selection:function(){return this.selection},get_single_selection:function(){if(this.selection.length==1){return this.selection[0]}else{return null}},highlight_row:function(f,a,e){if(!this.rows[f]){return}if(!a){if(this.selection.length>1||!this.in_selection(f)){this.clear_selection();this.selection[0]=f;$(this.rows[f].obj).addClass("selected")}}else{if(!this.in_selection(f)){this.selection.push(f);$(this.rows[f].obj).addClass("selected");if(!e&&!this.rows[f].expanded){this.highlight_children(f,true)}}else{var d=$.inArray(f,this.selection),c=this.selection.slice(0,d),b=this.selection.slice(d+1,this.selection.length);this.selection=c.concat(b);$(this.rows[f].obj).removeClass("selected").removeClass("unfocused");if(!e&&!this.rows[f].expanded){this.highlight_children(f,false)}}}},highlight_children:function(f,b){var d,e,c=this.row_children(f),a=c.length;for(d=0;d<a;d++){e=this.in_selection(c[d]);if((b&&!e)||(!b&&e)){this.highlight_row(c[d],true,true)}}},key_press:function(f){var d=f.target||{};if(this.focused!=true||d.nodeName=="INPUT"||d.nodeName=="TEXTAREA"||d.nodeName=="SELECT"){return true}var c=rcube_event.get_keycode(f),a=rcube_event.get_modifier(f);switch(c){case 40:case 38:case 63233:case 63232:rcube_event.cancel(f);return this.use_arrow_key(c,a);case 61:case 107:case 109:case 32:rcube_event.cancel(f);var b=this.use_plusminus_key(c,a);this.key_pressed=c;this.modkey=a;this.triggerEvent("keypress");this.modkey=0;return b;case 36:this.select_first(a);return rcube_event.cancel(f);case 35:this.select_last(a);return rcube_event.cancel(f);case 27:if(this.drag_active){return this.drag_mouse_up(f)}if(this.col_drag_active){this.selected_column=null;return this.column_drag_mouse_up(f)}return rcube_event.cancel(f);default:this.key_pressed=c;this.modkey=a;this.triggerEvent("keypress");this.modkey=0;if(this.key_pressed==this.BACKSPACE_KEY){return rcube_event.cancel(f)}}return true},use_arrow_key:function(c,b){var a;if(c==40||c==63233){a=this.get_next_row()}else{if(c==38||c==63232){a=this.get_prev_row()}}if(a){this.select_row(a.uid,b,false);this.scrollto(a.uid)}return false},use_plusminus_key:function(c,a){var b=this.rows[this.last_selected];if(!b){return}if(c==32){c=b.expanded?109:61}if(c==61||c==107){if(a==CONTROL_KEY||this.multiexpand){this.expand_all(b)}else{this.expand(b)}}else{if(a==CONTROL_KEY||this.multiexpand){this.collapse_all(b)}else{this.collapse(b)}}this.update_expando(b.uid,b.expanded);return false},scrollto:function(d){var c=this.rows[d].obj;if(c&&this.frame){var b=Number(c.offsetTop);if(!b&&this.rows[d].parent_uid){var a=this.find_root(this.rows[d].uid);this.expand_all(this.rows[a]);b=Number(c.offsetTop)}if(b<Number(this.frame.scrollTop)){this.frame.scrollTop=b}else{if(b+Number(c.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight)){this.frame.scrollTop=(b+Number(c.offsetHeight))-Number(this.frame.offsetHeight)}}}},drag_mouse_move:function(l){if(l.type=="touchmove"){if(l.touches.length==1&&l.changedTouches.length==1){l=rcube_event.touchevent(l.changedTouches[0])}else{return rcube_event.cancel(l)}}if(this.drag_start){var f=rcube_event.get_mouse_pos(l);if(!this.drag_mouse_start||(Math.abs(f.x-this.drag_mouse_start.x)<3&&Math.abs(f.y-this.drag_mouse_start.y)<3)){return false}if(!this.draglayer){this.draglayer=$("<div>").attr("id","rcmdraglayer").css({position:"absolute",display:"none","z-index":2000}).appendTo(document.body)}var b,j,t=$.merge([],this.selection);for(b in t){j=t[b];if(!this.rows[j].expanded){this.select_children(j)}}this.draglayer.html("");var o,h,b,p,g;for(b=0;b<this.selection.length;b++){if(b>12){this.draglayer.append("...");break}if(g=this.rows[this.selection[b]].obj){p="";for(o=0,h=0;h<g.childNodes.length;h++){if(g.childNodes[h].nodeName=="TD"){if(b==0){this.drag_start_pos=$(g.childNodes[h]).offset()}if(this.subject_col<0||(this.subject_col>=0&&this.subject_col==o)){var s,d,k,a=g.childNodes[h].childNodes;for(f=0;f<a.length;f++){if((k=g.childNodes[h].childNodes[f])&&(k.nodeType==3||k.nodeName=="A")){d=k}}if(!d){break}p=$(d).text();p=$.trim(p);p=(p.length>50?p.substring(0,50)+"...":p);s=$("<div>").text(p);this.draglayer.append(s);break}o++}}}}this.draglayer.show();this.drag_active=true;this.triggerEvent("dragstart")}if(this.drag_active&&this.draglayer){var q=rcube_event.get_mouse_pos(l);this.draglayer.css({left:(q.x+20)+"px",top:(q.y-5+(bw.ie?document.documentElement.scrollTop:0))+"px"});this.triggerEvent("dragmove",l?l:window.event)}this.drag_start=false;return false},drag_mouse_up:function(a){document.onmousemove=null;if(a.type=="touchend"){if(a.changedTouches.length!=1){return rcube_event.cancel(a)}}if(this.draglayer&&this.draglayer.is(":visible")){if(this.drag_start_pos){this.draglayer.animate(this.drag_start_pos,300,"swing").hide(20)}else{this.draglayer.hide()}}if(this.drag_active){this.focus()}this.drag_active=false;rcube_event.remove_listener({event:"mousemove",object:this,method:"drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"drag_mouse_up"});if(bw.touch){rcube_event.remove_listener({event:"touchmove",object:this,method:"drag_mouse_move"});rcube_event.remove_listener({event:"touchend",object:this,method:"drag_mouse_up"})}this.del_dragfix();this.triggerEvent("dragend");return rcube_event.cancel(a)},column_drag_mouse_move:function(f){if(this.drag_start){var c,a=rcube_event.get_mouse_pos(f);if(!this.drag_mouse_start||(Math.abs(a.x-this.drag_mouse_start.x)<3&&Math.abs(a.y-this.drag_mouse_start.y)<3)){return false}if(!this.col_draglayer){var d=$(this.list).offset(),b=this.list.tHead.rows[0].cells;this.col_draglayer=$("<div>").attr("id","rcmcoldraglayer").css(d).css({position:"absolute","z-index":2001,"background-color":"white",opacity:0.75,height:(this.frame.offsetHeight-2)+"px",width:(this.frame.offsetWidth-2)+"px"}).appendTo(document.body).append($("<div>").attr("id","rcmcolumnindicator").css({position:"absolute","border-right":"2px dotted #555","z-index":2002,height:(this.frame.offsetHeight-2)+"px"}));this.cols=[];this.list_pos=this.list_min_pos=d.left;for(c=0;c<b.length;c++){this.cols[c]=b[c].offsetWidth;if(this.column_fixed!==null&&c<=this.column_fixed){this.list_min_pos+=this.cols[c]}}}this.col_draglayer.show();this.col_drag_active=true;this.triggerEvent("column_dragstart")}if(this.col_drag_active&&this.col_draglayer){var c,h=0,g=rcube_event.get_mouse_pos(f);for(c=0;c<this.cols.length;c++){if(g.x>=this.cols[c]/2+this.list_pos+h){h+=this.cols[c]}else{break}}if(c==0&&this.list_min_pos>g.x){h=this.list_min_pos-this.list_pos}else{if(!this.list.rowcount&&c==this.cols.length){h-=2}}$("#rcmcolumnindicator").css({width:h+"px"});this.triggerEvent("column_dragmove",f?f:window.event)}this.drag_start=false;return false},column_drag_mouse_up:function(b){document.onmousemove=null;if(this.col_draglayer){(this.col_draglayer).remove();this.col_draglayer=null}if(this.col_drag_active){this.focus()}this.col_drag_active=false;rcube_event.remove_listener({event:"mousemove",object:this,method:"column_drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.del_dragfix();if(this.selected_column!==null&&this.cols&&this.cols.length){var a,d=0,c=rcube_event.get_mouse_pos(b);for(a=0;a<this.cols.length;a++){if(c.x>=this.cols[a]/2+this.list_pos+d){d+=this.cols[a]}else{break}}if(a!=this.selected_column&&a!=this.selected_column+1){this.column_replace(this.selected_column,a)}}this.triggerEvent("column_dragend");return rcube_event.cancel(b)},row_children:function(b){if(!this.rows[b]||!this.rows[b].has_children){return[]}var a=[],d=this.rows[b].depth,c=this.rows[b].obj.nextSibling;while(c){if(c.nodeType==1){if((r=this.rows[c.uid])){if(!r.depth||r.depth<=d){break}a.push(r.uid)}}c=c.nextSibling}return a},add_dragfix:function(){$("iframe").each(function(){$('<div class="iframe-dragdrop-fix"></div>').css({background:"#fff",width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css($(this).offset()).appendTo(document.body)})},del_dragfix:function(){$("div.iframe-dragdrop-fix").each(function(){this.parentNode.removeChild(this)})},column_replace:function(g,f){var a,b=this.list.tHead.rows[0].cells,c=b[g],d=b[f],e=document.createElement("td");if(d){b[0].parentNode.insertBefore(e,d)}else{b[0].parentNode.appendChild(e)}b[0].parentNode.replaceChild(c,e);for(r=0,a=this.list.tBodies[0].rows.length;r<a;r++){row=this.list.tBodies[0].rows[r];c=row.cells[g];d=row.cells[f];e=document.createElement("td");if(d){row.insertBefore(e,d)}else{row.appendChild(e)}row.replaceChild(c,e)}if(this.subject_col==g){this.subject_col=f>g?f-1:f}else{if(this.subject_col<g&&f<=this.subject_col){this.subject_col++}else{if(this.subject_col>g&&f>=this.subject_col){this.subject_col--}}}this.triggerEvent("column_replace")}};rcube_list_widget.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;rcube_list_widget.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;rcube_list_widget.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent; \ No newline at end of file
diff --git a/plugins/enigma/lib/Crypt/GPG.php b/program/lib/Crypt/GPG.php
index 6e8e717e8..6e8e717e8 100644
--- a/plugins/enigma/lib/Crypt/GPG.php
+++ b/program/lib/Crypt/GPG.php
diff --git a/plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php b/program/lib/Crypt/GPG/DecryptStatusHandler.php
index 40e8d50ed..40e8d50ed 100644
--- a/plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php
+++ b/program/lib/Crypt/GPG/DecryptStatusHandler.php
diff --git a/plugins/enigma/lib/Crypt/GPG/Engine.php b/program/lib/Crypt/GPG/Engine.php
index 081be8e21..081be8e21 100644
--- a/plugins/enigma/lib/Crypt/GPG/Engine.php
+++ b/program/lib/Crypt/GPG/Engine.php
diff --git a/plugins/enigma/lib/Crypt/GPG/Exceptions.php b/program/lib/Crypt/GPG/Exceptions.php
index 744acf5d4..744acf5d4 100644
--- a/plugins/enigma/lib/Crypt/GPG/Exceptions.php
+++ b/program/lib/Crypt/GPG/Exceptions.php
diff --git a/plugins/enigma/lib/Crypt/GPG/Key.php b/program/lib/Crypt/GPG/Key.php
index 67a4b9c7d..67a4b9c7d 100644
--- a/plugins/enigma/lib/Crypt/GPG/Key.php
+++ b/program/lib/Crypt/GPG/Key.php
diff --git a/plugins/enigma/lib/Crypt/GPG/Signature.php b/program/lib/Crypt/GPG/Signature.php
index 03ab44c53..03ab44c53 100644
--- a/plugins/enigma/lib/Crypt/GPG/Signature.php
+++ b/program/lib/Crypt/GPG/Signature.php
diff --git a/plugins/enigma/lib/Crypt/GPG/SubKey.php b/program/lib/Crypt/GPG/SubKey.php
index b6316e99f..b6316e99f 100644
--- a/plugins/enigma/lib/Crypt/GPG/SubKey.php
+++ b/program/lib/Crypt/GPG/SubKey.php
diff --git a/plugins/enigma/lib/Crypt/GPG/UserId.php b/program/lib/Crypt/GPG/UserId.php
index 04435708c..04435708c 100644
--- a/plugins/enigma/lib/Crypt/GPG/UserId.php
+++ b/program/lib/Crypt/GPG/UserId.php
diff --git a/plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php b/program/lib/Crypt/GPG/VerifyStatusHandler.php
index 083bd3012..083bd3012 100644
--- a/plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php
+++ b/program/lib/Crypt/GPG/VerifyStatusHandler.php
diff --git a/program/lib/Net/Sieve.php b/program/lib/Net/Sieve.php
new file mode 100644
index 000000000..8ebdf0958
--- /dev/null
+++ b/program/lib/Net/Sieve.php
@@ -0,0 +1,1274 @@
+<?php
+/**
+ * This file contains the Net_Sieve class.
+ *
+ * PHP version 4
+ *
+ * +-----------------------------------------------------------------------+
+ * | All rights reserved. |
+ * | |
+ * | Redistribution and use in source and binary forms, with or without |
+ * | modification, are permitted provided that the following conditions |
+ * | are met: |
+ * | |
+ * | o Redistributions of source code must retain the above copyright |
+ * | notice, this list of conditions and the following disclaimer. |
+ * | o Redistributions in binary form must reproduce the above copyright |
+ * | notice, this list of conditions and the following disclaimer in the |
+ * | documentation and/or other materials provided with the distribution.|
+ * | |
+ * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * +-----------------------------------------------------------------------+
+ *
+ * @category Networking
+ * @package Net_Sieve
+ * @author Richard Heyes <richard@phpguru.org>
+ * @author Damian Fernandez Sosa <damlists@cnba.uba.ar>
+ * @author Anish Mistry <amistry@am-productions.biz>
+ * @author Jan Schneider <jan@horde.org>
+ * @copyright 2002-2003 Richard Heyes
+ * @copyright 2006-2008 Anish Mistry
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version SVN: $Id$
+ * @link http://pear.php.net/package/Net_Sieve
+ */
+
+require_once 'PEAR.php';
+require_once 'Net/Socket.php';
+
+/**
+ * TODO
+ *
+ * o supportsAuthMech()
+ */
+
+/**
+ * Disconnected state
+ * @const NET_SIEVE_STATE_DISCONNECTED
+ */
+define('NET_SIEVE_STATE_DISCONNECTED', 1, true);
+
+/**
+ * Authorisation state
+ * @const NET_SIEVE_STATE_AUTHORISATION
+ */
+define('NET_SIEVE_STATE_AUTHORISATION', 2, true);
+
+/**
+ * Transaction state
+ * @const NET_SIEVE_STATE_TRANSACTION
+ */
+define('NET_SIEVE_STATE_TRANSACTION', 3, true);
+
+
+/**
+ * A class for talking to the timsieved server which comes with Cyrus IMAP.
+ *
+ * @category Networking
+ * @package Net_Sieve
+ * @author Richard Heyes <richard@phpguru.org>
+ * @author Damian Fernandez Sosa <damlists@cnba.uba.ar>
+ * @author Anish Mistry <amistry@am-productions.biz>
+ * @author Jan Schneider <jan@horde.org>
+ * @copyright 2002-2003 Richard Heyes
+ * @copyright 2006-2008 Anish Mistry
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version Release: 1.3.2
+ * @link http://pear.php.net/package/Net_Sieve
+ * @link http://tools.ietf.org/html/rfc5228 RFC 5228 (Sieve: An Email
+ * Filtering Language)
+ * @link http://tools.ietf.org/html/rfc5804 RFC 5804 A Protocol for
+ * Remotely Managing Sieve Scripts
+ */
+class Net_Sieve
+{
+ /**
+ * The authentication methods this class supports.
+ *
+ * Can be overwritten if having problems with certain methods.
+ *
+ * @var array
+ */
+ var $supportedAuthMethods = array('DIGEST-MD5', 'CRAM-MD5', 'EXTERNAL',
+ 'PLAIN' , 'LOGIN');
+
+ /**
+ * SASL authentication methods that require Auth_SASL.
+ *
+ * @var array
+ */
+ var $supportedSASLAuthMethods = array('DIGEST-MD5', 'CRAM-MD5');
+
+ /**
+ * The socket handle.
+ *
+ * @var resource
+ */
+ var $_sock;
+
+ /**
+ * Parameters and connection information.
+ *
+ * @var array
+ */
+ var $_data;
+
+ /**
+ * Current state of the connection.
+ *
+ * One of the NET_SIEVE_STATE_* constants.
+ *
+ * @var integer
+ */
+ var $_state;
+
+ /**
+ * Constructor error.
+ *
+ * @var PEAR_Error
+ */
+ var $_error;
+
+ /**
+ * Whether to enable debugging.
+ *
+ * @var boolean
+ */
+ var $_debug = false;
+
+ /**
+ * Debug output handler.
+ *
+ * This has to be a valid callback.
+ *
+ * @var string|array
+ */
+ var $_debug_handler = null;
+
+ /**
+ * Whether to pick up an already established connection.
+ *
+ * @var boolean
+ */
+ var $_bypassAuth = false;
+
+ /**
+ * Whether to use TLS if available.
+ *
+ * @var boolean
+ */
+ var $_useTLS = true;
+
+ /**
+ * Additional options for stream_context_create().
+ *
+ * @var array
+ */
+ var $_options = null;
+
+ /**
+ * Maximum number of referral loops
+ *
+ * @var array
+ */
+ var $_maxReferralCount = 15;
+
+ /**
+ * Constructor.
+ *
+ * Sets up the object, connects to the server and logs in. Stores any
+ * generated error in $this->_error, which can be retrieved using the
+ * getError() method.
+ *
+ * @param string $user Login username.
+ * @param string $pass Login password.
+ * @param string $host Hostname of server.
+ * @param string $port Port of server.
+ * @param string $logintype Type of login to perform (see
+ * $supportedAuthMethods).
+ * @param string $euser Effective user. If authenticating as an
+ * administrator, login as this user.
+ * @param boolean $debug Whether to enable debugging (@see setDebug()).
+ * @param string $bypassAuth Skip the authentication phase. Useful if the
+ * socket is already open.
+ * @param boolean $useTLS Use TLS if available.
+ * @param array $options Additional options for
+ * stream_context_create().
+ * @param mixed $handler A callback handler for the debug output.
+ */
+ function Net_Sieve($user = null, $pass = null, $host = 'localhost',
+ $port = 2000, $logintype = '', $euser = '',
+ $debug = false, $bypassAuth = false, $useTLS = true,
+ $options = null, $handler = null)
+ {
+ $this->_state = NET_SIEVE_STATE_DISCONNECTED;
+ $this->_data['user'] = $user;
+ $this->_data['pass'] = $pass;
+ $this->_data['host'] = $host;
+ $this->_data['port'] = $port;
+ $this->_data['logintype'] = $logintype;
+ $this->_data['euser'] = $euser;
+ $this->_sock = new Net_Socket();
+ $this->_bypassAuth = $bypassAuth;
+ $this->_useTLS = $useTLS;
+ $this->_options = $options;
+ $this->setDebug($debug, $handler);
+
+ /* Try to include the Auth_SASL package. If the package is not
+ * available, we disable the authentication methods that depend upon
+ * it. */
+ if ((@include_once 'Auth/SASL.php') === false) {
+ $this->_debug('Auth_SASL not present');
+ foreach ($this->supportedSASLAuthMethods as $SASLMethod) {
+ $pos = array_search($SASLMethod, $this->supportedAuthMethods);
+ $this->_debug('Disabling method ' . $SASLMethod);
+ unset($this->supportedAuthMethods[$pos]);
+ }
+ }
+
+ if (strlen($user) && strlen($pass)) {
+ $this->_error = $this->_handleConnectAndLogin();
+ }
+ }
+
+ /**
+ * Returns any error that may have been generated in the constructor.
+ *
+ * @return boolean|PEAR_Error False if no error, PEAR_Error otherwise.
+ */
+ function getError()
+ {
+ return PEAR::isError($this->_error) ? $this->_error : false;
+ }
+
+ /**
+ * Sets the debug state and handler function.
+ *
+ * @param boolean $debug Whether to enable debugging.
+ * @param string $handler A custom debug handler. Must be a valid callback.
+ *
+ * @return void
+ */
+ function setDebug($debug = true, $handler = null)
+ {
+ $this->_debug = $debug;
+ $this->_debug_handler = $handler;
+ }
+
+ /**
+ * Connects to the server and logs in.
+ *
+ * @return boolean True on success, PEAR_Error on failure.
+ */
+ function _handleConnectAndLogin()
+ {
+ if (PEAR::isError($res = $this->connect($this->_data['host'], $this->_data['port'], $this->_options, $this->_useTLS))) {
+ return $res;
+ }
+ if ($this->_bypassAuth === false) {
+ if (PEAR::isError($res = $this->login($this->_data['user'], $this->_data['pass'], $this->_data['logintype'], $this->_data['euser'], $this->_bypassAuth))) {
+ return $res;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Handles connecting to the server and checks the response validity.
+ *
+ * @param string $host Hostname of server.
+ * @param string $port Port of server.
+ * @param array $options List of options to pass to
+ * stream_context_create().
+ * @param boolean $useTLS Use TLS if available.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function connect($host, $port, $options = null, $useTLS = true)
+ {
+ $this->_data['host'] = $host;
+ $this->_data['port'] = $port;
+ $this->_useTLS = $useTLS;
+ if (is_array($options)) {
+ $this->_options = array_merge($this->_options, $options);
+ }
+
+ if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) {
+ return PEAR::raiseError('Not currently in DISCONNECTED state', 1);
+ }
+
+ if (PEAR::isError($res = $this->_sock->connect($host, $port, false, 5, $options))) {
+ return $res;
+ }
+
+ if ($this->_bypassAuth) {
+ $this->_state = NET_SIEVE_STATE_TRANSACTION;
+ } else {
+ $this->_state = NET_SIEVE_STATE_AUTHORISATION;
+ if (PEAR::isError($res = $this->_doCmd())) {
+ return $res;
+ }
+ }
+
+ // Explicitly ask for the capabilities in case the connection is
+ // picked up from an existing connection.
+ if (PEAR::isError($res = $this->_cmdCapability())) {
+ return PEAR::raiseError(
+ 'Failed to connect, server said: ' . $res->getMessage(), 2
+ );
+ }
+
+ // Check if we can enable TLS via STARTTLS.
+ if ($useTLS && !empty($this->_capability['starttls'])
+ && function_exists('stream_socket_enable_crypto')
+ ) {
+ if (PEAR::isError($res = $this->_startTLS())) {
+ return $res;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Disconnect from the Sieve server.
+ *
+ * @param boolean $sendLogoutCMD Whether to send LOGOUT command before
+ * disconnecting.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function disconnect($sendLogoutCMD = true)
+ {
+ return $this->_cmdLogout($sendLogoutCMD);
+ }
+
+ /**
+ * Logs into server.
+ *
+ * @param string $user Login username.
+ * @param string $pass Login password.
+ * @param string $logintype Type of login method to use.
+ * @param string $euser Effective UID (perform on behalf of $euser).
+ * @param boolean $bypassAuth Do not perform authentication.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function login($user, $pass, $logintype = null, $euser = '', $bypassAuth = false)
+ {
+ $this->_data['user'] = $user;
+ $this->_data['pass'] = $pass;
+ $this->_data['logintype'] = $logintype;
+ $this->_data['euser'] = $euser;
+ $this->_bypassAuth = $bypassAuth;
+
+ if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) {
+ return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
+ }
+
+ if (!$bypassAuth ) {
+ if (PEAR::isError($res = $this->_cmdAuthenticate($user, $pass, $logintype, $euser))) {
+ return $res;
+ }
+ }
+ $this->_state = NET_SIEVE_STATE_TRANSACTION;
+
+ return true;
+ }
+
+ /**
+ * Returns an indexed array of scripts currently on the server.
+ *
+ * @return array Indexed array of scriptnames.
+ */
+ function listScripts()
+ {
+ if (is_array($scripts = $this->_cmdListScripts())) {
+ $this->_active = $scripts[1];
+ return $scripts[0];
+ } else {
+ return $scripts;
+ }
+ }
+
+ /**
+ * Returns the active script.
+ *
+ * @return string The active scriptname.
+ */
+ function getActive()
+ {
+ if (!empty($this->_active)) {
+ return $this->_active;
+ }
+ if (is_array($scripts = $this->_cmdListScripts())) {
+ $this->_active = $scripts[1];
+ return $scripts[1];
+ }
+ }
+
+ /**
+ * Sets the active script.
+ *
+ * @param string $scriptname The name of the script to be set as active.
+ *
+ * @return boolean True on success, PEAR_Error on failure.
+ */
+ function setActive($scriptname)
+ {
+ return $this->_cmdSetActive($scriptname);
+ }
+
+ /**
+ * Retrieves a script.
+ *
+ * @param string $scriptname The name of the script to be retrieved.
+ *
+ * @return string The script on success, PEAR_Error on failure.
+ */
+ function getScript($scriptname)
+ {
+ return $this->_cmdGetScript($scriptname);
+ }
+
+ /**
+ * Adds a script to the server.
+ *
+ * @param string $scriptname Name of the script.
+ * @param string $script The script content.
+ * @param boolean $makeactive Whether to make this the active script.
+ *
+ * @return boolean True on success, PEAR_Error on failure.
+ */
+ function installScript($scriptname, $script, $makeactive = false)
+ {
+ if (PEAR::isError($res = $this->_cmdPutScript($scriptname, $script))) {
+ return $res;
+ }
+ if ($makeactive) {
+ return $this->_cmdSetActive($scriptname);
+ }
+ return true;
+ }
+
+ /**
+ * Removes a script from the server.
+ *
+ * @param string $scriptname Name of the script.
+ *
+ * @return boolean True on success, PEAR_Error on failure.
+ */
+ function removeScript($scriptname)
+ {
+ return $this->_cmdDeleteScript($scriptname);
+ }
+
+ /**
+ * Checks if the server has space to store the script by the server.
+ *
+ * @param string $scriptname The name of the script to mark as active.
+ * @param integer $size The size of the script.
+ *
+ * @return boolean|PEAR_Error True if there is space, PEAR_Error otherwise.
+ *
+ * @todo Rename to hasSpace()
+ */
+ function haveSpace($scriptname, $size)
+ {
+ if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+ return PEAR::raiseError('Not currently in TRANSACTION state', 1);
+ }
+
+ if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size)))) {
+ return $res;
+ }
+ return true;
+ }
+
+ /**
+ * Returns the list of extensions the server supports.
+ *
+ * @return array List of extensions or PEAR_Error on failure.
+ */
+ function getExtensions()
+ {
+ if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
+ return PEAR::raiseError('Not currently connected', 7);
+ }
+ return $this->_capability['extensions'];
+ }
+
+ /**
+ * Returns whether the server supports an extension.
+ *
+ * @param string $extension The extension to check.
+ *
+ * @return boolean Whether the extension is supported or PEAR_Error on
+ * failure.
+ */
+ function hasExtension($extension)
+ {
+ if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
+ return PEAR::raiseError('Not currently connected', 7);
+ }
+
+ $extension = trim($this->_toUpper($extension));
+ if (is_array($this->_capability['extensions'])) {
+ foreach ($this->_capability['extensions'] as $ext) {
+ if ($ext == $extension) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the list of authentication methods the server supports.
+ *
+ * @return array List of authentication methods or PEAR_Error on failure.
+ */
+ function getAuthMechs()
+ {
+ if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
+ return PEAR::raiseError('Not currently connected', 7);
+ }
+ return $this->_capability['sasl'];
+ }
+
+ /**
+ * Returns whether the server supports an authentication method.
+ *
+ * @param string $method The method to check.
+ *
+ * @return boolean Whether the method is supported or PEAR_Error on
+ * failure.
+ */
+ function hasAuthMech($method)
+ {
+ if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
+ return PEAR::raiseError('Not currently connected', 7);
+ }
+
+ $method = trim($this->_toUpper($method));
+ if (is_array($this->_capability['sasl'])) {
+ foreach ($this->_capability['sasl'] as $sasl) {
+ if ($sasl == $method) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles the authentication using any known method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $userMethod The method to use. If empty, the class chooses
+ * the best (strongest) available method.
+ * @param string $euser The effective uid to authenticate as.
+ *
+ * @return void
+ */
+ function _cmdAuthenticate($uid, $pwd, $userMethod = null, $euser = '')
+ {
+ if (PEAR::isError($method = $this->_getBestAuthMethod($userMethod))) {
+ return $method;
+ }
+ switch ($method) {
+ case 'DIGEST-MD5':
+ return $this->_authDigestMD5($uid, $pwd, $euser);
+ case 'CRAM-MD5':
+ $result = $this->_authCRAMMD5($uid, $pwd, $euser);
+ break;
+ case 'LOGIN':
+ $result = $this->_authLOGIN($uid, $pwd, $euser);
+ break;
+ case 'PLAIN':
+ $result = $this->_authPLAIN($uid, $pwd, $euser);
+ break;
+ case 'EXTERNAL':
+ $result = $this->_authEXTERNAL($uid, $pwd, $euser);
+ break;
+ default :
+ $result = PEAR::raiseError(
+ $method . ' is not a supported authentication method'
+ );
+ break;
+ }
+
+ if (PEAR::isError($res = $this->_doCmd())) {
+ return $res;
+ }
+
+ // Query the server capabilities again now that we are authenticated.
+ if (PEAR::isError($res = $this->_cmdCapability())) {
+ return PEAR::raiseError(
+ 'Failed to connect, server said: ' . $res->getMessage(), 2
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Authenticates the user using the PLAIN method.
+ *
+ * @param string $user The userid to authenticate as.
+ * @param string $pass The password to authenticate with.
+ * @param string $euser The effective uid to authenticate as.
+ *
+ * @return void
+ */
+ function _authPLAIN($user, $pass, $euser)
+ {
+ return $this->_sendCmd(
+ sprintf(
+ 'AUTHENTICATE "PLAIN" "%s"',
+ base64_encode($euser . chr(0) . $user . chr(0) . $pass)
+ )
+ );
+ }
+
+ /**
+ * Authenticates the user using the LOGIN method.
+ *
+ * @param string $user The userid to authenticate as.
+ * @param string $pass The password to authenticate with.
+ * @param string $euser The effective uid to authenticate as.
+ *
+ * @return void
+ */
+ function _authLOGIN($user, $pass, $euser)
+ {
+ if (PEAR::isError($result = $this->_sendCmd('AUTHENTICATE "LOGIN"'))) {
+ return $result;
+ }
+ if (PEAR::isError($result = $this->_doCmd('"' . base64_encode($user) . '"', true))) {
+ return $result;
+ }
+ return $this->_doCmd('"' . base64_encode($pass) . '"', true);
+ }
+
+ /**
+ * Authenticates the user using the CRAM-MD5 method.
+ *
+ * @param string $user The userid to authenticate as.
+ * @param string $pass The password to authenticate with.
+ * @param string $euser The effective uid to authenticate as.
+ *
+ * @return void
+ */
+ function _authCRAMMD5($user, $pass, $euser)
+ {
+ if (PEAR::isError($challenge = $this->_doCmd('AUTHENTICATE "CRAM-MD5"', true))) {
+ return $challenge;
+ }
+
+ $challenge = base64_decode(trim($challenge));
+ $cram = Auth_SASL::factory('crammd5');
+ if (PEAR::isError($response = $cram->getResponse($user, $pass, $challenge))) {
+ return $response;
+ }
+
+ return $this->_sendStringResponse(base64_encode($response));
+ }
+
+ /**
+ * Authenticates the user using the DIGEST-MD5 method.
+ *
+ * @param string $user The userid to authenticate as.
+ * @param string $pass The password to authenticate with.
+ * @param string $euser The effective uid to authenticate as.
+ *
+ * @return void
+ */
+ function _authDigestMD5($user, $pass, $euser)
+ {
+ if (PEAR::isError($challenge = $this->_doCmd('AUTHENTICATE "DIGEST-MD5"', true))) {
+ return $challenge;
+ }
+
+ $challenge = base64_decode(trim($challenge));
+ $digest = Auth_SASL::factory('digestmd5');
+ // @todo Really 'localhost'?
+ if (PEAR::isError($response = $digest->getResponse($user, $pass, $challenge, 'localhost', 'sieve', $euser))) {
+ return $response;
+ }
+
+ if (PEAR::isError($result = $this->_sendStringResponse(base64_encode($response)))) {
+ return $result;
+ }
+ if (PEAR::isError($result = $this->_doCmd('', true))) {
+ return $result;
+ }
+ if ($this->_toUpper(substr($result, 0, 2)) == 'OK') {
+ return;
+ }
+
+ /* We don't use the protocol's third step because SIEVE doesn't allow
+ * subsequent authentication, so we just silently ignore it. */
+ if (PEAR::isError($result = $this->_sendStringResponse(''))) {
+ return $result;
+ }
+
+ return $this->_doCmd();
+ }
+
+ /**
+ * Authenticates the user using the EXTERNAL method.
+ *
+ * @param string $user The userid to authenticate as.
+ * @param string $pass The password to authenticate with.
+ * @param string $euser The effective uid to authenticate as.
+ *
+ * @return void
+ *
+ * @since 1.1.7
+ */
+ function _authEXTERNAL($user, $pass, $euser)
+ {
+ $cmd = sprintf(
+ 'AUTHENTICATE "EXTERNAL" "%s"',
+ base64_encode(strlen($euser) ? $euser : $user)
+ );
+ return $this->_sendCmd($cmd);
+ }
+
+ /**
+ * Removes a script from the server.
+ *
+ * @param string $scriptname Name of the script to delete.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function _cmdDeleteScript($scriptname)
+ {
+ if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+ return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
+ }
+
+ if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT %s', $this->_escape($scriptname))))) {
+ return $res;
+ }
+ return true;
+ }
+
+ /**
+ * Retrieves the contents of the named script.
+ *
+ * @param string $scriptname Name of the script to retrieve.
+ *
+ * @return string The script if successful, PEAR_Error otherwise.
+ */
+ function _cmdGetScript($scriptname)
+ {
+ if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+ return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
+ }
+
+ if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT %s', $this->_escape($scriptname))))) {
+ return $res;
+ }
+
+ return preg_replace('/^{[0-9]+}\r\n/', '', $res);
+ }
+
+ /**
+ * Sets the active script, i.e. the one that gets run on new mail by the
+ * server.
+ *
+ * @param string $scriptname The name of the script to mark as active.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function _cmdSetActive($scriptname)
+ {
+ if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+ return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
+ }
+
+ if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE %s', $this->_escape($scriptname))))) {
+ return $res;
+ }
+
+ $this->_activeScript = $scriptname;
+ return true;
+ }
+
+ /**
+ * Returns the list of scripts on the server.
+ *
+ * @return array An array with the list of scripts in the first element
+ * and the active script in the second element on success,
+ * PEAR_Error otherwise.
+ */
+ function _cmdListScripts()
+ {
+ if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+ return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
+ }
+
+ if (PEAR::isError($res = $this->_doCmd('LISTSCRIPTS'))) {
+ return $res;
+ }
+
+ $scripts = array();
+ $activescript = null;
+ $res = explode("\r\n", $res);
+ foreach ($res as $value) {
+ if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) {
+ $script_name = stripslashes($matches[1]);
+ $scripts[] = $script_name;
+ if (!empty($matches[2])) {
+ $activescript = $script_name;
+ }
+ }
+ }
+
+ return array($scripts, $activescript);
+ }
+
+ /**
+ * Adds a script to the server.
+ *
+ * @param string $scriptname Name of the new script.
+ * @param string $scriptdata The new script.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function _cmdPutScript($scriptname, $scriptdata)
+ {
+ if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+ return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
+ }
+
+ $stringLength = $this->_getLineLength($scriptdata);
+ $command = sprintf("PUTSCRIPT %s {%d+}\r\n%s",
+ $this->_escape($scriptname),
+ $stringLength,
+ $scriptdata);
+ if (PEAR::isError($res = $this->_doCmd($command))) {
+ return $res;
+ }
+
+ return true;
+ }
+
+ /**
+ * Logs out of the server and terminates the connection.
+ *
+ * @param boolean $sendLogoutCMD Whether to send LOGOUT command before
+ * disconnecting.
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function _cmdLogout($sendLogoutCMD = true)
+ {
+ if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
+ return PEAR::raiseError('Not currently connected', 1);
+ }
+
+ if ($sendLogoutCMD) {
+ if (PEAR::isError($res = $this->_doCmd('LOGOUT'))) {
+ return $res;
+ }
+ }
+
+ $this->_sock->disconnect();
+ $this->_state = NET_SIEVE_STATE_DISCONNECTED;
+
+ return true;
+ }
+
+ /**
+ * Sends the CAPABILITY command
+ *
+ * @return boolean True on success, PEAR_Error otherwise.
+ */
+ function _cmdCapability()
+ {
+ if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
+ return PEAR::raiseError('Not currently connected', 1);
+ }
+ if (PEAR::isError($res = $this->_doCmd('CAPABILITY'))) {
+ return $res;
+ }
+ $this->_parseCapability($res);
+ return true;
+ }
+
+ /**
+ * Parses the response from the CAPABILITY command and stores the result
+ * in $_capability.
+ *
+ * @param string $data The response from the capability command.
+ *
+ * @return void
+ */
+ function _parseCapability($data)
+ {
+ // Clear the cached capabilities.
+ $this->_capability = array('sasl' => array(),
+ 'extensions' => array());
+
+ $data = preg_split('/\r?\n/', $this->_toUpper($data), -1, PREG_SPLIT_NO_EMPTY);
+
+ for ($i = 0; $i < count($data); $i++) {
+ if (!preg_match('/^"([A-Z]+)"( "(.*)")?$/', $data[$i], $matches)) {
+ continue;
+ }
+ switch ($matches[1]) {
+ case 'IMPLEMENTATION':
+ $this->_capability['implementation'] = $matches[3];
+ break;
+
+ case 'SASL':
+ $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]);
+ break;
+
+ case 'SIEVE':
+ $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]);
+ break;
+
+ case 'STARTTLS':
+ $this->_capability['starttls'] = true;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Sends a command to the server
+ *
+ * @param string $cmd The command to send.
+ *
+ * @return void
+ */
+ function _sendCmd($cmd)
+ {
+ $status = $this->_sock->getStatus();
+ if (PEAR::isError($status) || $status['eof']) {
+ return PEAR::raiseError('Failed to write to socket: connection lost');
+ }
+ if (PEAR::isError($error = $this->_sock->write($cmd . "\r\n"))) {
+ return PEAR::raiseError(
+ 'Failed to write to socket: ' . $error->getMessage()
+ );
+ }
+ $this->_debug("C: $cmd");
+ }
+
+ /**
+ * Sends a string response to the server.
+ *
+ * @param string $str The string to send.
+ *
+ * @return void
+ */
+ function _sendStringResponse($str)
+ {
+ return $this->_sendCmd('{' . $this->_getLineLength($str) . "+}\r\n" . $str);
+ }
+
+ /**
+ * Receives a single line from the server.
+ *
+ * @return string The server response line.
+ */
+ function _recvLn()
+ {
+ if (PEAR::isError($lastline = $this->_sock->gets(8192))) {
+ return PEAR::raiseError(
+ 'Failed to read from socket: ' . $lastline->getMessage()
+ );
+ }
+
+ $lastline = rtrim($lastline);
+ $this->_debug("S: $lastline");
+
+ if ($lastline === '') {
+ return PEAR::raiseError('Failed to read from socket');
+ }
+
+ return $lastline;
+ }
+
+ /**
+ * Receives a number of bytes from the server.
+ *
+ * @param integer $length Number of bytes to read.
+ *
+ * @return string The server response.
+ */
+ function _recvBytes($length)
+ {
+ $response = '';
+ $response_length = 0;
+ while ($response_length < $length) {
+ $response .= $this->_sock->read($length - $response_length);
+ $response_length = $this->_getLineLength($response);
+ }
+ $this->_debug('S: ' . rtrim($response));
+ return $response;
+ }
+
+ /**
+ * Send a command and retrieves a response from the server.
+ *
+ * @param string $cmd The command to send.
+ * @param boolean $auth Whether this is an authentication command.
+ *
+ * @return string|PEAR_Error Reponse string if an OK response, PEAR_Error
+ * if a NO response.
+ */
+ function _doCmd($cmd = '', $auth = false)
+ {
+ $referralCount = 0;
+ while ($referralCount < $this->_maxReferralCount) {
+ if (strlen($cmd)) {
+ if (PEAR::isError($error = $this->_sendCmd($cmd))) {
+ return $error;
+ }
+ }
+
+ $response = '';
+ while (true) {
+ if (PEAR::isError($line = $this->_recvLn())) {
+ return $line;
+ }
+ $uc_line = $this->_toUpper($line);
+
+ if ('OK' == substr($uc_line, 0, 2)) {
+ $response .= $line;
+ return rtrim($response);
+ }
+
+ if ('NO' == substr($uc_line, 0, 2)) {
+ // Check for string literal error message.
+ if (preg_match('/{([0-9]+)}$/', $line, $matches)) {
+ $line = substr($line, 0, -(strlen($matches[1])+2))
+ . str_replace(
+ "\r\n", ' ', $this->_recvBytes($matches[1] + 2)
+ );
+ }
+ return PEAR::raiseError(trim($response . substr($line, 2)), 3);
+ }
+
+ if ('BYE' == substr($uc_line, 0, 3)) {
+ if (PEAR::isError($error = $this->disconnect(false))) {
+ return PEAR::raiseError(
+ 'Cannot handle BYE, the error was: '
+ . $error->getMessage(),
+ 4
+ );
+ }
+ // Check for referral, then follow it. Otherwise, carp an
+ // error.
+ if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) {
+ // Replace the old host with the referral host
+ // preserving any protocol prefix.
+ $this->_data['host'] = preg_replace(
+ '/\w+(?!(\w|\:\/\/)).*/', $matches[2],
+ $this->_data['host']
+ );
+ if (PEAR::isError($error = $this->_handleConnectAndLogin())) {
+ return PEAR::raiseError(
+ 'Cannot follow referral to '
+ . $this->_data['host'] . ', the error was: '
+ . $error->getMessage(),
+ 5
+ );
+ }
+ break;
+ }
+ return PEAR::raiseError(trim($response . $line), 6);
+ }
+
+ if (preg_match('/^{([0-9]+)}/', $line, $matches)) {
+ // Matches literal string responses.
+ $line = $this->_recvBytes($matches[1] + 2);
+ if (!$auth) {
+ // Receive the pending OK only if we aren't
+ // authenticating since string responses during
+ // authentication don't need an OK.
+ $this->_recvLn();
+ }
+ return $line;
+ }
+
+ if ($auth) {
+ // String responses during authentication don't need an
+ // OK.
+ $response .= $line;
+ return rtrim($response);
+ }
+
+ $response .= $line . "\r\n";
+ $referralCount++;
+ }
+ }
+
+ return PEAR::raiseError('Max referral count (' . $referralCount . ') reached. Cyrus murder loop error?', 7);
+ }
+
+ /**
+ * Returns the name of the best authentication method that the server
+ * has advertised.
+ *
+ * @param string $userMethod Only consider this method as available.
+ *
+ * @return string The name of the best supported authentication method or
+ * a PEAR_Error object on failure.
+ */
+ function _getBestAuthMethod($userMethod = null)
+ {
+ if (!isset($this->_capability['sasl'])) {
+ return PEAR::raiseError('This server doesn\'t support any authentication methods. SASL problem?');
+ }
+ if (!$this->_capability['sasl']) {
+ return PEAR::raiseError('This server doesn\'t support any authentication methods.');
+ }
+
+ if ($userMethod) {
+ if (in_array($userMethod, $this->_capability['sasl'])) {
+ return $userMethod;
+ }
+ return PEAR::raiseError(
+ sprintf('No supported authentication method found. The server supports these methods: %s, but we want to use: %s',
+ implode(', ', $this->_capability['sasl']),
+ $userMethod));
+ }
+
+ foreach ($this->supportedAuthMethods as $method) {
+ if (in_array($method, $this->_capability['sasl'])) {
+ return $method;
+ }
+ }
+
+ return PEAR::raiseError(
+ sprintf('No supported authentication method found. The server supports these methods: %s, but we only support: %s',
+ implode(', ', $this->_capability['sasl']),
+ implode(', ', $this->supportedAuthMethods)));
+ }
+
+ /**
+ * Starts a TLS connection.
+ *
+ * @return boolean True on success, PEAR_Error on failure.
+ */
+ function _startTLS()
+ {
+ if (PEAR::isError($res = $this->_doCmd('STARTTLS'))) {
+ return $res;
+ }
+
+ if (!stream_socket_enable_crypto($this->_sock->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+ return PEAR::raiseError('Failed to establish TLS connection', 2);
+ }
+
+ $this->_debug('STARTTLS negotiation successful');
+
+ // The server should be sending a CAPABILITY response after
+ // negotiating TLS. Read it, and ignore if it doesn't.
+ // Unfortunately old Cyrus versions are broken and don't send a
+ // CAPABILITY response, thus we would wait here forever. Parse the
+ // Cyrus version and work around this broken behavior.
+ if (!preg_match('/^CYRUS TIMSIEVED V([0-9.]+)/', $this->_capability['implementation'], $matches) ||
+ version_compare($matches[1], '2.3.10', '>=')) {
+ $this->_doCmd();
+ }
+
+ // Query the server capabilities again now that we are under
+ // encryption.
+ if (PEAR::isError($res = $this->_cmdCapability())) {
+ return PEAR::raiseError(
+ 'Failed to connect, server said: ' . $res->getMessage(), 2
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the length of a string.
+ *
+ * @param string $string A string.
+ *
+ * @return integer The length of the string.
+ */
+ function _getLineLength($string)
+ {
+ if (extension_loaded('mbstring')) {
+ return mb_strlen($string, 'latin1');
+ } else {
+ return strlen($string);
+ }
+ }
+
+ /**
+ * Locale independant strtoupper() implementation.
+ *
+ * @param string $string The string to convert to lowercase.
+ *
+ * @return string The lowercased string, based on ASCII encoding.
+ */
+ function _toUpper($string)
+ {
+ $language = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $string = strtoupper($string);
+ setlocale(LC_CTYPE, $language);
+ return $string;
+ }
+
+ /**
+ * Converts strings into RFC's quoted-string or literal-c2s form.
+ *
+ * @param string $string The string to convert.
+ *
+ * @return string Result string.
+ */
+ function _escape($string)
+ {
+ // Some implementations don't allow UTF-8 characters in quoted-string,
+ // use literal-c2s.
+ if (preg_match('/[^\x01-\x09\x0B-\x0C\x0E-\x7F]/', $string)) {
+ return sprintf("{%d+}\r\n%s", $this->_getLineLength($string), $string);
+ }
+
+ return '"' . addcslashes($string, '\\"') . '"';
+ }
+
+ /**
+ * Write debug text to the current debug output handler.
+ *
+ * @param string $message Debug message text.
+ *
+ * @return void
+ */
+ function _debug($message)
+ {
+ if ($this->_debug) {
+ if ($this->_debug_handler) {
+ call_user_func_array($this->_debug_handler, array(&$this, $message));
+ } else {
+ echo "$message\n";
+ }
+ }
+ }
+}
diff --git a/program/lib/Roundcube/bootstrap.php b/program/lib/Roundcube/bootstrap.php
index 6e5143382..c3fac1f4d 100644
--- a/program/lib/Roundcube/bootstrap.php
+++ b/program/lib/Roundcube/bootstrap.php
@@ -54,11 +54,11 @@ foreach ($config as $optname => $optval) {
}
// framework constants
-define('RCUBE_VERSION', '1.0-git');
+define('RCUBE_VERSION', '0.9.5');
define('RCUBE_CHARSET', 'UTF-8');
if (!defined('RCUBE_LIB_DIR')) {
- define('RCUBE_LIB_DIR', dirname(__FILE__).DIRECTORY_SEPARATOR);
+ define('RCUBE_LIB_DIR', dirname(__FILE__).'/');
}
if (!defined('RCUBE_INSTALL_PATH')) {
@@ -303,6 +303,32 @@ function is_ascii($str, $control_chars = true)
/**
+ * Remove single and double quotes from a given string
+ *
+ * @param string Input value
+ *
+ * @return string Dequoted string
+ */
+function strip_quotes($str)
+{
+ return str_replace(array("'", '"'), '', $str);
+}
+
+
+/**
+ * Remove new lines characters from given string
+ *
+ * @param string $str Input value
+ *
+ * @return string Stripped string
+ */
+function strip_newlines($str)
+{
+ return preg_replace('/[\r\n]/', '', $str);
+}
+
+
+/**
* Compose a valid representation of name and e-mail address
*
* @param string $email E-mail address
diff --git a/program/lib/Roundcube/html.php b/program/lib/Roundcube/html.php
index a36711281..1a4c3beba 100644
--- a/program/lib/Roundcube/html.php
+++ b/program/lib/Roundcube/html.php
@@ -21,7 +21,7 @@
* Class for HTML code creation
*
* @package Framework
- * @subpackage View
+ * @subpackage HTML
*/
class html
{
@@ -218,7 +218,7 @@ class html
$attr = array('src' => $attr);
}
return self::tag('iframe', $attr, $cont, array_merge(self::$common_attrib,
- array('src','name','width','height','border','frameborder','onload')));
+ array('src','name','width','height','border','frameborder')));
}
/**
@@ -288,7 +288,7 @@ class html
}
// attributes with no value
- if (in_array($key, array('checked', 'multiple', 'disabled', 'selected', 'autofocus'))) {
+ if (in_array($key, array('checked', 'multiple', 'disabled', 'selected'))) {
if ($value) {
$attrib_arr[] = $key . '="' . $key . '"';
}
@@ -350,18 +350,16 @@ class html
/**
* Class to create an HTML input field
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_inputfield extends html
{
protected $tagname = 'input';
protected $type = 'text';
protected $allowed = array(
- 'type','name','value','size','tabindex','autocapitalize','required',
+ 'type','name','value','size','tabindex','autocapitalize',
'autocomplete','checked','onchange','onclick','disabled','readonly',
- 'spellcheck','results','maxlength','src','multiple','accept',
- 'placeholder','autofocus',
+ 'spellcheck','results','maxlength','src','multiple','placeholder',
);
/**
@@ -407,8 +405,7 @@ class html_inputfield extends html
/**
* Class to create an HTML password field
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_passwordfield extends html_inputfield
{
@@ -418,9 +415,9 @@ class html_passwordfield extends html_inputfield
/**
* Class to create an hidden HTML input field
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
+
class html_hiddenfield extends html
{
protected $tagname = 'input';
@@ -468,8 +465,7 @@ class html_hiddenfield extends html
/**
* Class to create HTML radio buttons
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_radiobutton extends html_inputfield
{
@@ -499,8 +495,7 @@ class html_radiobutton extends html_inputfield
/**
* Class to create HTML checkboxes
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_checkbox extends html_inputfield
{
@@ -530,8 +525,7 @@ class html_checkbox extends html_inputfield
/**
* Class to create an HTML textarea
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_textarea extends html
{
@@ -589,8 +583,7 @@ class html_textarea extends html
* print $select->show('CH');
* </pre>
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_select extends html
{
@@ -655,8 +648,7 @@ class html_select extends html
/**
* Class to build an HTML table
*
- * @package Framework
- * @subpackage View
+ * @package HTML
*/
class html_table extends html
{
@@ -678,11 +670,6 @@ class html_table extends html
{
$default_attrib = self::$doctype == 'xhtml' ? array('summary' => '', 'border' => 0) : array();
$this->attrib = array_merge($attrib, $default_attrib);
-
- if (!empty($attrib['tagname']) && $attrib['tagname'] != 'table') {
- $this->tagname = $attrib['tagname'];
- $this->allowed = self::$common_attrib;
- }
}
/**
@@ -826,20 +813,19 @@ class html_table extends html
if (!empty($this->header)) {
$rowcontent = '';
foreach ($this->header as $c => $col) {
- $rowcontent .= self::tag($this->_col_tagname(), $col->attrib, $col->content);
+ $rowcontent .= self::tag('td', $col->attrib, $col->content);
}
- $thead = $this->tagname == 'table' ? self::tag('thead', null, self::tag('tr', null, $rowcontent, parent::$common_attrib)) :
- self::tag($this->_row_tagname(), array('class' => 'thead'), $rowcontent, parent::$common_attrib);
+ $thead = self::tag('thead', null, self::tag('tr', null, $rowcontent, parent::$common_attrib));
}
foreach ($this->rows as $r => $row) {
$rowcontent = '';
foreach ($row->cells as $c => $col) {
- $rowcontent .= self::tag($this->_col_tagname(), $col->attrib, $col->content);
+ $rowcontent .= self::tag('td', $col->attrib, $col->content);
}
if ($r < $this->rowindex || count($row->cells)) {
- $tbody .= self::tag($this->_row_tagname(), $row->attrib, $rowcontent, parent::$common_attrib);
+ $tbody .= self::tag('tr', $row->attrib, $rowcontent, parent::$common_attrib);
}
}
@@ -848,7 +834,7 @@ class html_table extends html
}
// add <tbody>
- $this->content = $thead . ($this->tagname == 'table' ? self::tag('tbody', null, $tbody) : $tbody);
+ $this->content = $thead . self::tag('tbody', null, $tbody);
unset($this->attrib['cols'], $this->attrib['rowsonly']);
return parent::show();
@@ -873,22 +859,4 @@ class html_table extends html
$this->rowindex = 0;
}
- /**
- * Getter for the corresponding tag name for table row elements
- */
- private function _row_tagname()
- {
- static $row_tagnames = array('table' => 'tr', 'ul' => 'li', '*' => 'div');
- return $row_tagnames[$this->tagname] ?: $row_tagnames['*'];
- }
-
- /**
- * Getter for the corresponding tag name for table cell elements
- */
- private function _col_tagname()
- {
- static $col_tagnames = array('table' => 'td', '*' => 'span');
- return $col_tagnames[$this->tagname] ?: $col_tagnames['*'];
- }
-
}
diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php
index d9c3dd8b9..7329b09fb 100644
--- a/program/lib/Roundcube/rcube.php
+++ b/program/lib/Roundcube/rcube.php
@@ -99,20 +99,20 @@ class rcube
protected $texts;
protected $caches = array();
protected $shutdown_functions = array();
+ protected $expunge_cache = false;
/**
* This implements the 'singleton' design pattern
*
* @param integer Options to initialize with this instance. See rcube::INIT_WITH_* constants
- * @param string Environment name to run (e.g. live, dev, test)
*
* @return rcube The one and only instance
*/
- static function get_instance($mode = 0, $env = '')
+ static function get_instance($mode = 0)
{
if (!self::$instance) {
- self::$instance = new rcube($env);
+ self::$instance = new rcube();
self::$instance->init($mode);
}
@@ -123,10 +123,10 @@ class rcube
/**
* Private constructor
*/
- protected function __construct($env = '')
+ protected function __construct()
{
// load configuration
- $this->config = new rcube_config($env);
+ $this->config = new rcube_config;
$this->plugins = new rcube_dummy_plugin_api;
register_shutdown_function(array($this, 'shutdown'));
@@ -258,39 +258,6 @@ class rcube
/**
- * Initialize and get shared cache object
- *
- * @param string $name Cache identifier
- * @param bool $packed Enables/disables data serialization
- *
- * @return rcube_cache_shared Cache object
- */
- public function get_cache_shared($name, $packed=true)
- {
- $shared_name = "shared_$name";
-
- if (!array_key_exists($shared_name, $this->caches)) {
- $opt = strtolower($name) . '_cache';
- $type = $this->config->get($opt);
- $ttl = $this->config->get($opt . '_ttl');
-
- if (!$type) {
- // cache is disabled
- return $this->caches[$shared_name] = null;
- }
-
- if ($ttl === null) {
- $ttl = $this->config->get('shared_cache_ttl', '10d');
- }
-
- $this->caches[$shared_name] = new rcube_cache_shared($type, $name, $ttl, $packed);
- }
-
- return $this->caches[$shared_name];
- }
-
-
- /**
* Create SMTP object and connect to server
*
* @param boolean True if connection should be established
@@ -378,7 +345,6 @@ class rcube
'auth_pw' => $this->config->get("{$driver}_auth_pw"),
'debug' => (bool) $this->config->get("{$driver}_debug"),
'force_caps' => (bool) $this->config->get("{$driver}_force_caps"),
- 'disabled_caps' => $this->config->get("{$driver}_disabled_caps"),
'timeout' => (int) $this->config->get("{$driver}_timeout"),
'skip_deleted' => (bool) $this->config->get('skip_deleted'),
'driver' => $driver,
@@ -458,12 +424,15 @@ class rcube
ini_set('session.name', $sess_name ? $sess_name : 'roundcube_sessid');
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
+ ini_set('session.serialize_handler', 'php');
ini_set('session.cookie_httponly', 1);
// use database for storing session data
$this->session = new rcube_session($this->get_dbh(), $this->config);
- $this->session->register_gc_handler(array($this, 'gc'));
+ $this->session->register_gc_handler(array($this, 'temp_gc'));
+ $this->session->register_gc_handler(array($this, 'cache_gc'));
+
$this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
$this->session->set_ip_check($this->config->get('ip_check'));
@@ -473,47 +442,27 @@ class rcube
// start PHP session (if not in CLI mode)
if ($_SERVER['REMOTE_ADDR']) {
- $this->session->start();
+ session_start();
}
}
/**
- * Garbage collector - cache/temp cleaner
- */
- public function gc()
- {
- rcube_cache::gc();
- rcube_cache_shared::gc();
- $this->get_storage()->cache_gc();
-
- $this->gc_temp();
- }
-
-
- /**
* Garbage collector function for temp files.
* Remove temp files older than two days
*/
- public function gc_temp()
+ public function temp_gc()
{
$tmp = unslashify($this->config->get('temp_dir'));
-
- // expire in 48 hours by default
- $temp_dir_ttl = $this->config->get('temp_dir_ttl', '48h');
- $temp_dir_ttl = get_offset_sec($temp_dir_ttl);
- if ($temp_dir_ttl < 6*3600)
- $temp_dir_ttl = 6*3600; // 6 hours sensible lower bound.
-
- $expire = time() - $temp_dir_ttl;
+ $expire = time() - 172800; // expire in 48 hours
if ($tmp && ($dir = opendir($tmp))) {
while (($fname = readdir($dir)) !== false) {
- if ($fname[0] == '.') {
+ if ($fname{0} == '.') {
continue;
}
- if (@filemtime($tmp.'/'.$fname) < $expire) {
+ if (filemtime($tmp.'/'.$fname) < $expire) {
@unlink($tmp.'/'.$fname);
}
}
@@ -524,21 +473,14 @@ class rcube
/**
- * Runs garbage collector with probability based on
- * session settings. This is intended for environments
- * without a session.
+ * Garbage collector for cache entries.
+ * Set flag to expunge caches on shutdown
*/
- public function gc_run()
+ public function cache_gc()
{
- $probability = (int) ini_get('session.gc_probability');
- $divisor = (int) ini_get('session.gc_divisor');
-
- if ($divisor > 0 && $probability > 0) {
- $random = mt_rand(1, $divisor);
- if ($random <= $probability) {
- $this->gc();
- }
- }
+ // because this gc function is called before storage is initialized,
+ // we just set a flag to expunge storage cache on shutdown.
+ $this->expunge_cache = true;
}
@@ -797,7 +739,7 @@ class rcube
mcrypt_module_close($td);
}
else {
- @include_once 'des.inc';
+ // @include_once 'des.inc'; (not shipped with this distribution)
if (function_exists('des')) {
$des_iv_size = 8;
@@ -852,7 +794,7 @@ class rcube
mcrypt_module_close($td);
}
else {
- @include_once 'des.inc';
+ // @include_once 'des.inc'; (not shipped with this distribution)
if (function_exists('des')) {
$des_iv_size = 8;
@@ -922,14 +864,6 @@ class rcube
call_user_func($function);
}
- // write session data as soon as possible and before
- // closing database connection, don't do this before
- // registered shutdown functions, they may need the session
- // Note: this will run registered gc handlers (ie. cache gc)
- if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
- $this->session->write_close();
- }
-
if (is_object($this->smtp)) {
$this->smtp->disconnect();
}
@@ -941,6 +875,9 @@ class rcube
}
if (is_object($this->storage)) {
+ if ($this->expunge_cache) {
+ $this->storage->expunge_cache();
+ }
$this->storage->close();
}
}
@@ -1132,8 +1069,8 @@ class rcube
* - code: Error code (required)
* - type: Error type [php|db|imap|javascript] (required)
* - message: Error message
- * - file: File where error occured
- * - line: Line where error occured
+ * - file: File where error occurred
+ * - line: Line where error occurred
* @param boolean True to log the error
* @param boolean Terminate script execution
*/
@@ -1359,191 +1296,6 @@ class rcube
}
}
- /**
- * Unique Message-ID generator.
- *
- * @return string Message-ID
- */
- public function gen_message_id()
- {
- $local_part = md5(uniqid('rcube'.mt_rand(), true));
- $domain_part = $this->user->get_username('domain');
-
- // Try to find FQDN, some spamfilters doesn't like 'localhost' (#1486924)
- if (!preg_match('/\.[a-z]+$/i', $domain_part)) {
- foreach (array($_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME']) as $host) {
- $host = preg_replace('/:[0-9]+$/', '', $host);
- if ($host && preg_match('/\.[a-z]+$/i', $host)) {
- $domain_part = $host;
- }
- }
- }
-
- return sprintf('<%s@%s>', $local_part, $domain_part);
- }
-
- /**
- * Send the given message using the configured method.
- *
- * @param object $message Reference to Mail_MIME object
- * @param string $from Sender address string
- * @param array $mailto Array of recipient address strings
- * @param array $error SMTP error array (reference)
- * @param string $body_file Location of file with saved message body (reference),
- * used when delay_file_io is enabled
- * @param array $options SMTP options (e.g. DSN request)
- *
- * @return boolean Send status.
- */
- public function deliver_message(&$message, $from, $mailto, &$error, &$body_file = null, $options = null)
- {
- $plugin = $this->plugins->exec_hook('message_before_send', array(
- 'message' => $message,
- 'from' => $from,
- 'mailto' => $mailto,
- 'options' => $options,
- ));
-
- if ($plugin['abort']) {
- return isset($plugin['result']) ? $plugin['result'] : false;
- }
-
- $from = $plugin['from'];
- $mailto = $plugin['mailto'];
- $options = $plugin['options'];
- $message = $plugin['message'];
- $headers = $message->headers();
-
- // send thru SMTP server using custom SMTP library
- if ($this->config->get('smtp_server')) {
- // generate list of recipients
- $a_recipients = array($mailto);
-
- if (strlen($headers['Cc']))
- $a_recipients[] = $headers['Cc'];
- if (strlen($headers['Bcc']))
- $a_recipients[] = $headers['Bcc'];
-
- // clean Bcc from header for recipients
- $send_headers = $headers;
- unset($send_headers['Bcc']);
- // here too, it because txtHeaders() below use $message->_headers not only $send_headers
- unset($message->_headers['Bcc']);
-
- $smtp_headers = $message->txtHeaders($send_headers, true);
-
- if ($message->getParam('delay_file_io')) {
- // use common temp dir
- $temp_dir = $this->config->get('temp_dir');
- $body_file = tempnam($temp_dir, 'rcmMsg');
- if (PEAR::isError($mime_result = $message->saveMessageBody($body_file))) {
- self::raise_error(array('code' => 650, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Could not create message: ".$mime_result->getMessage()),
- TRUE, FALSE);
- return false;
- }
- $msg_body = fopen($body_file, 'r');
- }
- else {
- $msg_body = $message->get();
- }
-
- // send message
- if (!is_object($this->smtp)) {
- $this->smtp_init(true);
- }
-
- $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $options);
- $response = $this->smtp->get_response();
- $error = $this->smtp->get_error();
-
- // log error
- if (!$sent) {
- self::raise_error(array('code' => 800, 'type' => 'smtp',
- 'line' => __LINE__, 'file' => __FILE__,
- 'message' => "SMTP error: ".join("\n", $response)), TRUE, FALSE);
- }
- }
- // send mail using PHP's mail() function
- else {
- // unset some headers because they will be added by the mail() function
- $headers_enc = $message->headers($headers);
- $headers_php = $message->_headers;
- unset($headers_php['To'], $headers_php['Subject']);
-
- // reset stored headers and overwrite
- $message->_headers = array();
- $header_str = $message->txtHeaders($headers_php);
-
- // #1485779
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) {
- $headers_enc['To'] = implode(', ', $m[1]);
- }
- }
-
- $msg_body = $message->get();
-
- if (PEAR::isError($msg_body)) {
- self::raise_error(array('code' => 650, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Could not create message: ".$msg_body->getMessage()),
- TRUE, FALSE);
- }
- else {
- $delim = $this->config->header_delimiter();
- $to = $headers_enc['To'];
- $subject = $headers_enc['Subject'];
- $header_str = rtrim($header_str);
-
- if ($delim != "\r\n") {
- $header_str = str_replace("\r\n", $delim, $header_str);
- $msg_body = str_replace("\r\n", $delim, $msg_body);
- $to = str_replace("\r\n", $delim, $to);
- $subject = str_replace("\r\n", $delim, $subject);
- }
-
- if (filter_var(ini_get('safe_mode'), FILTER_VALIDATE_BOOLEAN))
- $sent = mail($to, $subject, $msg_body, $header_str);
- else
- $sent = mail($to, $subject, $msg_body, $header_str, "-f$from");
- }
- }
-
- if ($sent) {
- $this->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body));
-
- // remove MDN headers after sending
- unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']);
-
- // get all recipients
- if ($headers['Cc'])
- $mailto .= $headers['Cc'];
- if ($headers['Bcc'])
- $mailto .= $headers['Bcc'];
- if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m))
- $mailto = implode(', ', array_unique($m[1]));
-
- if ($this->config->get('smtp_log')) {
- self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s",
- $this->user->get_username(),
- $_SERVER['REMOTE_ADDR'],
- $mailto,
- !empty($response) ? join('; ', $response) : ''));
- }
- }
-
- if (is_resource($msg_body)) {
- fclose($msg_body);
- }
-
- $message->_headers = array();
- $message->headers($headers);
-
- return $sent;
- }
-
}
diff --git a/program/lib/Roundcube/rcube_addressbook.php b/program/lib/Roundcube/rcube_addressbook.php
index 9301211ff..13016ecc7 100644
--- a/program/lib/Roundcube/rcube_addressbook.php
+++ b/program/lib/Roundcube/rcube_addressbook.php
@@ -3,7 +3,7 @@
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 2006-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -35,7 +35,6 @@ abstract class rcube_addressbook
/** public properties (mandatory) */
public $primary_key;
public $groups = false;
- public $export_groups = true;
public $readonly = true;
public $searchonly = false;
public $undelete = false;
@@ -134,7 +133,7 @@ abstract class rcube_addressbook
abstract function get_record($id, $assoc=false);
/**
- * Returns the last error occured (e.g. when updating/inserting failed)
+ * Returns the last error occurred (e.g. when updating/inserting failed)
*
* @return array Hash array with the following fields: type, message
*/
@@ -424,7 +423,7 @@ abstract class rcube_addressbook
* @param boolean True to return one array with all values, False for hash array with values grouped by type
* @return array List of column values
*/
- public static function get_col_values($col, $data, $flat = false)
+ function get_col_values($col, $data, $flat = false)
{
$out = array();
foreach ((array)$data as $c => $values) {
@@ -433,7 +432,7 @@ abstract class rcube_addressbook
$out = array_merge($out, (array)$values);
}
else {
- list(, $type) = explode(':', $c);
+ list($f, $type) = explode(':', $c);
$out[$type] = array_merge((array)$out[$type], (array)$values);
}
}
@@ -477,8 +476,7 @@ abstract class rcube_addressbook
$fn = trim(join(' ', array_filter(array($contact['prefix'], $contact['firstname'], $contact['middlename'], $contact['surname'], $contact['suffix']))));
// use email address part for name
- $email = self::get_col_values('email', $contact, true);
- $email = $email[0];
+ $email = is_array($contact['email']) ? $contact['email'][0] : $contact['email'];
if ($email && (empty($fn) || $fn == $email)) {
// return full email
@@ -525,9 +523,9 @@ abstract class rcube_addressbook
$fn = $contact['name'];
// fallback to email address
- if (empty($fn) && ($email = self::get_col_values('email', $contact, true)) && !empty($email)) {
- return $email[0];
- }
+ $email = is_array($contact['email']) ? $contact['email'][0] : $contact['email'];
+ if (empty($fn) && $email)
+ return $email;
return $fn;
}
@@ -540,11 +538,11 @@ abstract class rcube_addressbook
$key = $contact[$sort_col] . ':' . $contact['sourceid'];
// add email to a key to not skip contacts with the same name (#1488375)
- if (($email = self::get_col_values('email', $contact, true)) && !empty($email)) {
- $key .= ':' . implode(':', (array)$email);
- }
+ if (!empty($contact['email'])) {
+ $key .= ':' . implode(':', (array)$contact['email']);
+ }
- return $key;
+ return $key;
}
/**
@@ -563,9 +561,9 @@ abstract class rcube_addressbook
// use only strict comparison (mode = 1)
// @TODO: partial search, e.g. match only day and month
if (in_array($colname, $this->date_cols)) {
- return (($value = rcube_utils::anytodatetime($value))
- && ($search = rcube_utils::anytodatetime($search))
- && $value->format('Ymd') == $search->format('Ymd'));
+ return (($value = rcube_utils::strtotime($value))
+ && ($search = rcube_utils::strtotime($search))
+ && date('Ymd', $value) == date('Ymd', $search));
}
// composite field, e.g. address
diff --git a/program/lib/Roundcube/rcube_base_replacer.php b/program/lib/Roundcube/rcube_base_replacer.php
index a59bba926..aaaa2028c 100644
--- a/program/lib/Roundcube/rcube_base_replacer.php
+++ b/program/lib/Roundcube/rcube_base_replacer.php
@@ -21,7 +21,7 @@
* using a predefined base
*
* @package Framework
- * @subpackage Utils
+ * @subpackage Core
* @author Thomas Bruederli <roundcube@gmail.com>
*/
class rcube_base_replacer
diff --git a/program/lib/Roundcube/rcube_browser.php b/program/lib/Roundcube/rcube_browser.php
index 34128291b..d10fe2a2c 100644
--- a/program/lib/Roundcube/rcube_browser.php
+++ b/program/lib/Roundcube/rcube_browser.php
@@ -20,7 +20,7 @@
* Provide details about the client's browser based on the User-Agent header
*
* @package Framework
- * @subpackage Utils
+ * @subpackage Core
*/
class rcube_browser
{
diff --git a/program/lib/Roundcube/rcube_cache.php b/program/lib/Roundcube/rcube_cache.php
index a708cb292..deaba68e9 100644
--- a/program/lib/Roundcube/rcube_cache.php
+++ b/program/lib/Roundcube/rcube_cache.php
@@ -38,7 +38,6 @@ class rcube_cache
private $type;
private $userid;
private $prefix;
- private $table;
private $ttl;
private $packed;
private $index;
@@ -72,9 +71,8 @@ class rcube_cache
$this->db = function_exists('apc_exists'); // APC 3.1.4 required
}
else {
- $this->type = 'db';
- $this->db = $rcube->get_dbh();
- $this->table = $this->db->table_name('cache');
+ $this->type = 'db';
+ $this->db = $rcube->get_dbh();
}
// convert ttl string to seconds
@@ -194,31 +192,20 @@ class rcube_cache
*/
function expunge()
{
- if ($this->type == 'db' && $this->db && $this->ttl) {
+ if ($this->type == 'db' && $this->db) {
$this->db->query(
- "DELETE FROM ".$this->table.
+ "DELETE FROM ".$this->db->table_name('cache').
" WHERE user_id = ?".
" AND cache_key LIKE ?".
- " AND expires < " . $this->db->now(),
+ " AND " . $this->db->unixtimestamp('created')." < ?",
$this->userid,
- $this->prefix.'.%');
+ $this->prefix.'.%',
+ time() - $this->ttl);
}
}
/**
- * Remove expired records of all caches
- */
- static function gc()
- {
- $rcube = rcube::get_instance();
- $db = $rcube->get_dbh();
-
- $db->query("DELETE FROM " . $db->table_name('cache') . " WHERE expires < " . $db->now());
- }
-
-
- /**
* Writes the cache back to the DB.
*/
function close()
@@ -284,7 +271,7 @@ class rcube_cache
else {
$sql_result = $this->db->limitquery(
"SELECT data, cache_key".
- " FROM " . $this->table.
+ " FROM ".$this->db->table_name('cache').
" WHERE user_id = ?".
" AND cache_key = ?".
// for better performance we allow more records for one key
@@ -339,7 +326,7 @@ class rcube_cache
// Remove NULL rows (here we don't need to check if the record exist)
if ($data == 'N;') {
$this->db->query(
- "DELETE FROM " . $this->table.
+ "DELETE FROM ".$this->db->table_name('cache').
" WHERE user_id = ?".
" AND cache_key = ?",
$this->userid, $key);
@@ -350,10 +337,8 @@ class rcube_cache
// update existing cache record
if ($key_exists) {
$result = $this->db->query(
- "UPDATE " . $this->table.
- " SET created = " . $this->db->now().
- ", expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL').
- ", data = ?".
+ "UPDATE ".$this->db->table_name('cache').
+ " SET created = ". $this->db->now().", data = ?".
" WHERE user_id = ?".
" AND cache_key = ?",
$data, $this->userid, $key);
@@ -363,9 +348,9 @@ class rcube_cache
// for better performance we allow more records for one key
// so, no need to check if record exist (see rcube_cache::read_record())
$result = $this->db->query(
- "INSERT INTO " . $this->table.
- " (created, expires, user_id, cache_key, data)".
- " VALUES (" . $this->db->now() . ", " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?, ?, ?)",
+ "INSERT INTO ".$this->db->table_name('cache').
+ " (created, user_id, cache_key, data)".
+ " VALUES (".$this->db->now().", ?, ?, ?)",
$this->userid, $key, $data);
}
@@ -426,7 +411,7 @@ class rcube_cache
}
$this->db->query(
- "DELETE FROM " . $this->table.
+ "DELETE FROM ".$this->db->table_name('cache').
" WHERE user_id = ?" . $where,
$this->userid);
}
diff --git a/program/lib/Roundcube/rcube_config.php b/program/lib/Roundcube/rcube_config.php
index ac3ea678c..3edec4242 100644
--- a/program/lib/Roundcube/rcube_config.php
+++ b/program/lib/Roundcube/rcube_config.php
@@ -3,7 +3,7 @@
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2008-2013, The Roundcube Dev Team |
+ | Copyright (C) 2008-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -26,8 +26,6 @@ class rcube_config
{
const DEFAULT_SKIN = 'larry';
- private $env = '';
- private $paths = array();
private $prop = array();
private $errors = array();
private $userprefs = array();
@@ -45,46 +43,14 @@ class rcube_config
'reply_mode' => 'top_posting',
'refresh_interval' => 'keep_alive',
'min_refresh_interval' => 'min_keep_alive',
- 'messages_cache_ttl' => 'message_cache_lifetime',
- 'redundant_attachments_cache_ttl' => 'redundant_attachments_memcache_ttl',
);
/**
* Object constructor
- *
- * @param string Environment suffix for config files to load
*/
- public function __construct($env = '')
+ public function __construct()
{
- $this->env = $env;
-
- if ($paths = getenv('RCUBE_CONFIG_PATH')) {
- $this->paths = explode(PATH_SEPARATOR, $paths);
- // make all paths absolute
- foreach ($this->paths as $i => $path) {
- if (!$this->_is_absolute($path)) {
- if ($realpath = realpath(RCUBE_INSTALL_PATH . $path)) {
- $this->paths[$i] = unslashify($realpath) . '/';
- }
- else {
- unset($this->paths[$i]);
- }
- }
- else {
- $this->paths[$i] = unslashify($path) . '/';
- }
- }
- }
-
- if (defined('RCUBE_CONFIG_DIR') && !in_array(RCUBE_CONFIG_DIR, $this->paths)) {
- $this->paths[] = RCUBE_CONFIG_DIR;
- }
-
- if (empty($this->paths)) {
- $this->paths[] = RCUBE_INSTALL_PATH . 'config/';
- }
-
$this->load();
// Defaults, that we do not require you to configure,
@@ -101,26 +67,16 @@ class rcube_config
*/
private function load()
{
- // Load default settings
- if (!$this->load_from_file('defaults.inc.php')) {
- $this->errors[] = 'defaults.inc.php was not found.';
- }
-
// load main config file
- if (!$this->load_from_file('config.inc.php')) {
- // Old configuration files
- if (!$this->load_from_file('main.inc.php') ||
- !$this->load_from_file('db.inc.php')) {
- $this->errors[] = 'config.inc.php was not found.';
- }
- else if (rand(1,100) == 10) { // log warning on every 100th request (average)
- trigger_error("config.inc.php was not found. Please migrate your config by running bin/update.sh", E_USER_WARNING);
- }
- }
+ if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'main.inc.php'))
+ $this->errors[] = 'main.inc.php was not found.';
+
+ // load database config
+ if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'db.inc.php'))
+ $this->errors[] = 'db.inc.php was not found.';
// load host-specific configuration
- if (!empty($_SERVER['HTTP_HOST']))
- $this->load_host_config();
+ $this->load_host_config();
// set skin (with fallback to old 'skin_path' property)
if (empty($this->prop['skin'])) {
@@ -163,6 +119,17 @@ class rcube_config
// enable display_errors in 'show' level, but not for ajax requests
ini_set('display_errors', intval(empty($_REQUEST['_remote']) && ($this->prop['debug_level'] & 4)));
+ // set timezone auto settings values
+ if ($this->prop['timezone'] == 'auto') {
+ $this->prop['_timezone_value'] = $this->client_timezone();
+ }
+ else if (is_numeric($this->prop['timezone']) && ($tz = timezone_name_from_abbr("", $this->prop['timezone'] * 3600, 0))) {
+ $this->prop['timezone'] = $tz;
+ }
+ else if (empty($this->prop['timezone'])) {
+ $this->prop['timezone'] = 'UTC';
+ }
+
// remove deprecated properties
unset($this->prop['dst_active']);
@@ -186,7 +153,7 @@ class rcube_config
}
if ($fname) {
- $this->load_from_file($fname);
+ $this->load_from_file(RCUBE_CONFIG_DIR . $fname);
}
}
@@ -195,78 +162,26 @@ class rcube_config
* Read configuration from a file
* and merge with the already stored config values
*
- * @param string $file Name of the config file to be loaded
+ * @param string $fpath Full path to the config file to be loaded
* @return booelan True on success, false on failure
*/
- public function load_from_file($file)
- {
- $success = false;
-
- foreach ($this->resolve_paths($file) as $fpath) {
- if ($fpath && is_file($fpath) && is_readable($fpath)) {
- // use output buffering, we don't need any output here
- ob_start();
- include($fpath);
- ob_end_clean();
-
- if (is_array($config)) {
- $this->merge($config);
- $success = true;
- }
- // deprecated name of config variable
- else if (is_array($rcmail_config)) {
- $this->merge($rcmail_config);
- $success = true;
- }
- }
- }
-
- return $success;
- }
-
- /**
- * Helper method to resolve absolute paths to the given config file.
- * This also takes the 'env' property into account.
- *
- * @param string Filename or absolute file path
- * @param boolean Return -$env file path if exists
- * @return array List of candidates in config dir path(s)
- */
- public function resolve_paths($file, $use_env = true)
+ public function load_from_file($fpath)
{
- $files = array();
- $abs_path = $this->_is_absolute($file);
-
- foreach ($this->paths as $basepath) {
- $realpath = $abs_path ? $file : realpath($basepath . '/' . $file);
-
- // check if <file>-env.ini exists
- if ($realpath && $use_env && !empty($this->env)) {
- $envfile = preg_replace('/\.(inc.php)$/', '-' . $this->env . '.\\1', $realpath);
- if (is_file($envfile))
- $realpath = $envfile;
- }
-
- if ($realpath) {
- $files[] = $realpath;
-
- // no need to continue the loop if an absolute file path is given
- if ($abs_path) {
- break;
- }
+ if (is_file($fpath) && is_readable($fpath)) {
+ // use output buffering, we don't need any output here
+ ob_start();
+ include($fpath);
+ ob_end_clean();
+
+ if (is_array($rcmail_config)) {
+ $this->merge($rcmail_config);
+ return true;
}
}
- return $files;
+ return false;
}
- /**
- * Determine whether the given file path is absolute or relative
- */
- private function _is_absolute($path)
- {
- return $path[0] == DIRECTORY_SEPARATOR || preg_match('!^[a-z]:[\\\\/]!i', $path);
- }
/**
* Getter for a specific config parameter
@@ -286,10 +201,8 @@ class rcube_config
$rcube = rcube::get_instance();
- if ($name == 'timezone') {
- if (empty($result) || $result == 'auto') {
- $result = $this->client_timezone();
- }
+ if ($name == 'timezone' && isset($this->prop['_timezone_value'])) {
+ $result = $this->prop['_timezone_value'];
}
else if ($name == 'client_mimetypes') {
if ($result == null && $def == null)
@@ -347,6 +260,11 @@ class rcube_config
}
}
+ // convert user's timezone into the new format
+ if (is_numeric($prefs['timezone']) && ($tz = timezone_name_from_abbr('', $prefs['timezone'] * 3600, 0))) {
+ $prefs['timezone'] = $tz;
+ }
+
// larry is the new default skin :-)
if ($prefs['skin'] == 'default') {
$prefs['skin'] = self::DEFAULT_SKIN;
@@ -354,6 +272,13 @@ class rcube_config
$this->userprefs = $prefs;
$this->prop = array_merge($this->prop, $prefs);
+
+ // override timezone settings with client values
+ if ($this->prop['timezone'] == 'auto') {
+ $this->prop['_timezone_value'] = isset($_SESSION['timezone']) ? $this->client_timezone() : $this->prop['_timezone_value'];
+ }
+ else if (isset($this->prop['_timezone_value']))
+ unset($this->prop['_timezone_value']);
}
@@ -494,12 +419,13 @@ class rcube_config
*/
private function client_timezone()
{
- // @TODO: remove this legacy timezone handling in the future
- $props = $this->fix_legacy_props(array('timezone' => $_SESSION['timezone']));
-
- if (!empty($props['timezone'])) {
+ if (isset($_SESSION['timezone']) && is_numeric($_SESSION['timezone'])
+ && ($ctz = timezone_name_from_abbr("", $_SESSION['timezone'] * 3600, 0))) {
+ return $ctz;
+ }
+ else if (!empty($_SESSION['timezone'])) {
try {
- $tz = new DateTimeZone($props['timezone']);
+ $tz = timezone_open($_SESSION['timezone']);
return $tz->getName();
}
catch (Exception $e) { /* gracefully ignore */ }
@@ -527,77 +453,6 @@ class rcube_config
}
}
- // convert deprecated numeric timezone value
- if (isset($props['timezone']) && is_numeric($props['timezone'])) {
- if ($tz = self::timezone_name_from_abbr($props['timezone'])) {
- $props['timezone'] = $tz;
- }
- else {
- unset($props['timezone']);
- }
- }
-
return $props;
}
-
- /**
- * timezone_name_from_abbr() replacement. Converts timezone offset
- * into timezone name abbreviation.
- *
- * @param float $offset Timezone offset (in hours)
- *
- * @return string Timezone abbreviation
- */
- static public function timezone_name_from_abbr($offset)
- {
- // List of timezones here is not complete - https://bugs.php.net/bug.php?id=44780
- if ($tz = timezone_name_from_abbr('', $offset * 3600, 0)) {
- return $tz;
- }
-
- // try with more complete list (#1489261)
- $timezones = array(
- '-660' => "Pacific/Apia",
- '-600' => "Pacific/Honolulu",
- '-570' => "Pacific/Marquesas",
- '-540' => "America/Anchorage",
- '-480' => "America/Los_Angeles",
- '-420' => "America/Denver",
- '-360' => "America/Chicago",
- '-300' => "America/New_York",
- '-270' => "America/Caracas",
- '-240' => "America/Halifax",
- '-210' => "Canada/Newfoundland",
- '-180' => "America/Sao_Paulo",
- '-60' => "Atlantic/Azores",
- '0' => "Europe/London",
- '60' => "Europe/Paris",
- '120' => "Europe/Helsinki",
- '180' => "Europe/Moscow",
- '210' => "Asia/Tehran",
- '240' => "Asia/Dubai",
- '300' => "Asia/Karachi",
- '270' => "Asia/Kabul",
- '300' => "Asia/Karachi",
- '330' => "Asia/Kolkata",
- '345' => "Asia/Katmandu",
- '360' => "Asia/Yekaterinburg",
- '390' => "Asia/Rangoon",
- '420' => "Asia/Krasnoyarsk",
- '480' => "Asia/Shanghai",
- '525' => "Australia/Eucla",
- '540' => "Asia/Tokyo",
- '570' => "Australia/Adelaide",
- '600' => "Australia/Melbourne",
- '630' => "Australia/Lord_Howe",
- '660' => "Asia/Vladivostok",
- '690' => "Pacific/Norfolk",
- '720' => "Pacific/Auckland",
- '765' => "Pacific/Chatham",
- '780' => "Pacific/Enderbury",
- '840' => "Pacific/Kiritimati",
- );
-
- return $timezones[(string) intval($offset * 60)];
- }
}
diff --git a/program/lib/Roundcube/rcube_contacts.php b/program/lib/Roundcube/rcube_contacts.php
index 6d01368a1..3919cdc6e 100644
--- a/program/lib/Roundcube/rcube_contacts.php
+++ b/program/lib/Roundcube/rcube_contacts.php
@@ -718,10 +718,6 @@ class rcube_contacts extends rcube_addressbook
foreach ($save_data as $key => $values) {
list($field, $section) = explode(':', $key);
$fulltext = in_array($field, $this->fulltext_cols);
- // avoid casting DateTime objects to array
- if (is_object($values) && is_a($values, 'DateTime')) {
- $values = array(0 => $values);
- }
foreach ((array)$values as $value) {
if (isset($value))
$vcard->set($field, $value, $section);
diff --git a/program/lib/Roundcube/rcube_content_filter.php b/program/lib/Roundcube/rcube_content_filter.php
index ae6617d1b..b814bb71d 100644
--- a/program/lib/Roundcube/rcube_content_filter.php
+++ b/program/lib/Roundcube/rcube_content_filter.php
@@ -20,7 +20,7 @@
* PHP stream filter to detect html/javascript code in attachments
*
* @package Framework
- * @subpackage Utils
+ * @subpackage Core
*/
class rcube_content_filter extends php_user_filter
{
diff --git a/program/lib/Roundcube/rcube_csv2vcard.php b/program/lib/Roundcube/rcube_csv2vcard.php
index 00e6d4e20..506a4b740 100644
--- a/program/lib/Roundcube/rcube_csv2vcard.php
+++ b/program/lib/Roundcube/rcube_csv2vcard.php
@@ -130,22 +130,6 @@ class rcube_csv2vcard
'work_state' => 'region:work',
'home_city_short' => 'locality:home',
'home_state_short' => 'region:home',
-
- // Atmail
- 'date_of_birth' => 'birthday',
- 'email' => 'email:pref',
- 'home_mobile' => 'phone:cell',
- 'home_zip' => 'zipcode:home',
- 'info' => 'notes',
- 'user_photo' => 'photo',
- 'url' => 'website:homepage',
- 'work_company' => 'organization',
- 'work_dept' => 'departament',
- 'work_fax' => 'phone:work,fax',
- 'work_mobile' => 'phone:work,cell',
- 'work_title' => 'jobtitle',
- 'work_zip' => 'zipcode:work',
- 'group' => 'groups',
);
/**
@@ -246,30 +230,8 @@ class rcube_csv2vcard
'work_phone' => "Work Phone",
'work_address' => "Work Address",
//'work_address_2' => "Work Address 2",
- 'work_city' => "Work City",
'work_country' => "Work Country",
- 'work_state' => "Work State",
'work_zipcode' => "Work ZipCode",
-
- // Atmail
- 'date_of_birth' => "Date of Birth",
- 'email' => "Email",
- //'email_2' => "Email2",
- //'email_3' => "Email3",
- //'email_4' => "Email4",
- //'email_5' => "Email5",
- 'home_mobile' => "Home Mobile",
- 'home_zip' => "Home Zip",
- 'info' => "Info",
- 'user_photo' => "User Photo",
- 'url' => "URL",
- 'work_company' => "Work Company",
- 'work_dept' => "Work Dept",
- 'work_fax' => "Work Fax",
- 'work_mobile' => "Work Mobile",
- 'work_title' => "Work Title",
- 'work_zip' => "Work Zip",
- 'groups' => "Group",
);
protected $local_label_map = array();
@@ -306,6 +268,7 @@ class rcube_csv2vcard
{
// convert to UTF-8
$head = substr($csv, 0, 4096);
+ $fallback = rcube::get_instance()->config->get('default_charset', 'ISO-8859-1'); // fallback to Latin-1?
$charset = rcube_charset::detect($head, RCUBE_CHARSET);
$csv = rcube_charset::convert($csv, $charset);
$head = '';
@@ -313,7 +276,7 @@ class rcube_csv2vcard
$this->map = array();
// Parse file
- foreach (preg_split("/[\r\n]+/", $csv) as $line) {
+ foreach (preg_split("/[\r\n]+/", $csv) as $i => $line) {
$elements = $this->parse_line($line);
if (empty($elements)) {
continue;
@@ -427,13 +390,9 @@ class rcube_csv2vcard
$contact['birthday'] = $contact['birthday-y'] .'-' .$contact['birthday-m'] . '-' . $contact['birthday-d'];
}
- // Empty dates, e.g. "0/0/00", "0000-00-00 00:00:00"
foreach (array('birthday', 'anniversary') as $key) {
- if (!empty($contact[$key])) {
- $date = preg_replace('/[0[:^word:]]/', '', $contact[$key]);
- if (empty($date)) {
- unset($contact[$key]);
- }
+ if (!empty($contact[$key]) && $contact[$key] == '0/0/00') { // @TODO: localization?
+ unset($contact[$key]);
}
}
diff --git a/program/lib/Roundcube/rcube_db.php b/program/lib/Roundcube/rcube_db.php
index 852070073..5083a0dfe 100644
--- a/program/lib/Roundcube/rcube_db.php
+++ b/program/lib/Roundcube/rcube_db.php
@@ -47,7 +47,6 @@ class rcube_db
'identifier_end' => '"',
);
- const DEBUG_LINE_LENGTH = 4096;
/**
* Factory, returns driver-specific instance of the class
@@ -63,6 +62,7 @@ class rcube_db
$driver = strtolower(substr($db_dsnw, 0, strpos($db_dsnw, ':')));
$driver_map = array(
'sqlite2' => 'sqlite',
+ 'sqlite3' => 'sqlite',
'sybase' => 'mssql',
'dblib' => 'mssql',
'mysqli' => 'mysql',
@@ -100,15 +100,27 @@ class rcube_db
$this->db_dsnw_array = self::parse_dsn($db_dsnw);
$this->db_dsnr_array = self::parse_dsn($db_dsnr);
+
+ // Initialize driver class
+ $this->init();
+ }
+
+ /**
+ * Initialization of the object with driver specific code
+ */
+ protected function init()
+ {
+ // To be used by driver classes
}
/**
* Connect to specific database
*
- * @param array $dsn DSN for DB connections
- * @param string $mode Connection mode (r|w)
+ * @param array $dsn DSN for DB connections
+ *
+ * @return PDO database handle
*/
- protected function dsn_connect($dsn, $mode)
+ protected function dsn_connect($dsn)
{
$this->db_error = false;
$this->db_error_msg = null;
@@ -146,10 +158,9 @@ class rcube_db
return null;
}
- $this->dbh = $dbh;
- $this->db_mode = $mode;
- $this->db_connected = true;
$this->conn_configure($dsn, $dbh);
+
+ return $dbh;
}
/**
@@ -172,6 +183,16 @@ class rcube_db
}
/**
+ * Driver-specific database character set setting
+ *
+ * @param string $charset Character set name
+ */
+ protected function set_charset($charset)
+ {
+ $this->query("SET NAMES 'utf8'");
+ }
+
+ /**
* Connect to appropriate database depending on the operation
*
* @param string $mode Connection mode (r|w)
@@ -198,14 +219,23 @@ class rcube_db
$dsn = ($mode == 'r') ? $this->db_dsnr_array : $this->db_dsnw_array;
- $this->dsn_connect($dsn, $mode);
+ $this->dbh = $this->dsn_connect($dsn);
+ $this->db_connected = is_object($this->dbh);
// use write-master when read-only fails
- if (!$this->db_connected && $mode == 'r' && $this->is_replicated()) {
- $this->dsn_connect($this->db_dsnw_array, 'w');
+ if (!$this->db_connected && $mode == 'r') {
+ $mode = 'w';
+ $this->dbh = $this->dsn_connect($this->db_dsnw_array);
+ $this->db_connected = is_object($this->dbh);
}
- $this->conn_failure = !$this->db_connected;
+ if ($this->db_connected) {
+ $this->db_mode = $mode;
+ $this->set_charset('utf8');
+ }
+ else {
+ $this->conn_failure = true;
+ }
}
/**
@@ -226,11 +256,6 @@ class rcube_db
protected function debug($query)
{
if ($this->options['debug_mode']) {
- if (($len = strlen($query)) > self::DEBUG_LINE_LENGTH) {
- $diff = $len - self::DEBUG_LINE_LENGTH;
- $query = substr($query, 0, self::DEBUG_LINE_LENGTH)
- . "... [truncated $diff bytes]";
- }
rcube::write_log('sql', '[' . (++$this->db_index) . '] ' . $query . ';');
}
}
@@ -338,10 +363,8 @@ class rcube_db
*/
protected function _query($query, $offset, $numrows, $params)
{
- $query = trim($query);
-
// Read or write ?
- $mode = preg_match('/^(select|show|set)/i', $query) ? 'r' : 'w';
+ $mode = preg_match('/^(select|show)/i', ltrim($query)) ? 'r' : 'w';
$this->db_connect($mode);
@@ -387,16 +410,13 @@ class rcube_db
if ($result === false) {
$error = $this->dbh->errorInfo();
+ $this->db_error = true;
+ $this->db_error_msg = sprintf('[%s] %s', $error[1], $error[2]);
- if (empty($this->options['ignore_key_errors']) || $error[0] != '23000') {
- $this->db_error = true;
- $this->db_error_msg = sprintf('[%s] %s', $error[1], $error[2]);
-
- rcube::raise_error(array('code' => 500, 'type' => 'db',
- 'line' => __LINE__, 'file' => __FILE__,
- 'message' => $this->db_error_msg . " (SQL Query: $query)"
- ), true, false);
- }
+ rcube::raise_error(array('code' => 500, 'type' => 'db',
+ 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => $this->db_error_msg . " (SQL Query: $query)"
+ ), true, false);
}
$this->last_result = $result;
@@ -683,19 +703,11 @@ class rcube_db
/**
* Return SQL function for current time and date
*
- * @param int $interval Optional interval (in seconds) to add/subtract
- *
* @return string SQL function to use in query
*/
- public function now($interval = 0)
+ public function now()
{
- if ($interval) {
- $add = ' ' . ($interval > 0 ? '+' : '-') . ' INTERVAL ';
- $add .= $interval > 0 ? intval($interval) : intval($interval) * -1;
- $add .= ' SECOND';
- }
-
- return "now()" . $add;
+ return "now()";
}
/**
@@ -856,26 +868,17 @@ class rcube_db
{
$rcube = rcube::get_instance();
- // add prefix to the table name if configured
- if ($prefix = $rcube->config->get('db_prefix')) {
- return $prefix . $table;
+ // return table name if configured
+ $config_key = 'db_table_'.$table;
+
+ if ($name = $rcube->config->get($config_key)) {
+ return $name;
}
return $table;
}
/**
- * Set class option value
- *
- * @param string $name Option name
- * @param mixed $value Option value
- */
- public function set_option($name, $value)
- {
- $this->options[$name] = $value;
- }
-
- /**
* MDB2 DSN string parser
*
* @param string $sequence Secuence name
diff --git a/program/lib/Roundcube/rcube_db_mssql.php b/program/lib/Roundcube/rcube_db_mssql.php
index 3c1b9d71f..37a42678a 100644
--- a/program/lib/Roundcube/rcube_db_mssql.php
+++ b/program/lib/Roundcube/rcube_db_mssql.php
@@ -29,52 +29,38 @@ class rcube_db_mssql extends rcube_db
public $db_provider = 'mssql';
/**
- * Object constructor
- *
- * @param string $db_dsnw DSN for read/write operations
- * @param string $db_dsnr Optional DSN for read only operations
- * @param bool $pconn Enables persistent connections
+ * Driver initialization
*/
- public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
+ protected function init()
{
- parent::__construct($db_dsnw, $db_dsnr, $pconn);
-
$this->options['identifier_start'] = '[';
$this->options['identifier_end'] = ']';
}
/**
- * Driver-specific configuration of database connection
- *
- * @param array $dsn DSN for DB connections
- * @param PDO $dbh Connection handler
+ * Character setting
*/
- protected function conn_configure($dsn, $dbh)
+ protected function set_charset($charset)
{
- // Set date format in case of non-default language (#1488918)
- $this->query("SET DATEFORMAT ymd");
+ // UTF-8 is default
}
/**
* Return SQL function for current time and date
*
- * @param int $interval Optional interval (in seconds) to add/subtract
- *
* @return string SQL function to use in query
*/
- public function now($interval = 0)
+ public function now()
{
- if ($interval) {
- $interval = intval($interval);
- return "dateadd(second, $interval, getdate())";
- }
-
return "getdate()";
}
/**
* Return SQL statement to convert a field value into a unix timestamp
*
+ * This method is deprecated and should not be used anymore due to limitations
+ * of timestamp functions in Mysql (year 2038 problem)
+ *
* @param string $field Field name
*
* @return string SQL statement to use in query
diff --git a/program/lib/Roundcube/rcube_db_mysql.php b/program/lib/Roundcube/rcube_db_mysql.php
index 6fa5ad768..7f5ad2b36 100644
--- a/program/lib/Roundcube/rcube_db_mysql.php
+++ b/program/lib/Roundcube/rcube_db_mysql.php
@@ -30,13 +30,9 @@ class rcube_db_mysql extends rcube_db
public $db_provider = 'mysql';
/**
- * Object constructor
- *
- * @param string $db_dsnw DSN for read/write operations
- * @param string $db_dsnr Optional DSN for read only operations
- * @param bool $pconn Enables persistent connections
+ * Driver initialization/configuration
*/
- public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
+ protected function init()
{
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
rcube::raise_error(array('code' => 600, 'type' => 'db',
@@ -45,25 +41,12 @@ class rcube_db_mysql extends rcube_db
true, true);
}
- parent::__construct($db_dsnw, $db_dsnr, $pconn);
-
// SQL identifiers quoting
$this->options['identifier_start'] = '`';
$this->options['identifier_end'] = '`';
}
/**
- * Driver-specific configuration of database connection
- *
- * @param array $dsn DSN for DB connections
- * @param PDO $dbh Connection handler
- */
- protected function conn_configure($dsn, $dbh)
- {
- $this->query("SET NAMES 'utf8'");
- }
-
- /**
* Abstract SQL statement for value concatenation
*
* @return string SQL statement to be used in query
@@ -151,7 +134,7 @@ class rcube_db_mysql extends rcube_db
$result[PDO::MYSQL_ATTR_FOUND_ROWS] = true;
// Enable AUTOCOMMIT mode (#1488902)
- $result[PDO::ATTR_AUTOCOMMIT] = true;
+ $dsn_options[PDO::ATTR_AUTOCOMMIT] = true;
return $result;
}
diff --git a/program/lib/Roundcube/rcube_db_pgsql.php b/program/lib/Roundcube/rcube_db_pgsql.php
index d72c9d6b3..a06a37c10 100644
--- a/program/lib/Roundcube/rcube_db_pgsql.php
+++ b/program/lib/Roundcube/rcube_db_pgsql.php
@@ -29,17 +29,6 @@ class rcube_db_pgsql extends rcube_db
public $db_provider = 'postgres';
/**
- * Driver-specific configuration of database connection
- *
- * @param array $dsn DSN for DB connections
- * @param PDO $dbh Connection handler
- */
- protected function conn_configure($dsn, $dbh)
- {
- $this->query("SET NAMES 'utf8'");
- }
-
- /**
* Get last inserted record ID
*
* @param string $table Table name (to find the incremented sequence)
@@ -64,20 +53,19 @@ class rcube_db_pgsql extends rcube_db
/**
* Return correct name for a specific database sequence
*
- * @param string $table Table name
+ * @param string $sequence Secuence name
*
* @return string Translated sequence name
*/
- protected function sequence_name($table)
+ protected function sequence_name($sequence)
{
- // Note: we support only one sequence per table
- // Note: The sequence name must be <table_name>_seq
- $sequence = $table . '_seq';
- $rcube = rcube::get_instance();
+ $rcube = rcube::get_instance();
// return sequence name if configured
- if ($prefix = $rcube->config->get('db_prefix')) {
- return $prefix . $sequence;
+ $config_key = 'db_sequence_'.$sequence;
+
+ if ($name = $rcube->config->get($config_key)) {
+ return $name;
}
return $sequence;
@@ -86,6 +74,9 @@ class rcube_db_pgsql extends rcube_db
/**
* Return SQL statement to convert a field value into a unix timestamp
*
+ * This method is deprecated and should not be used anymore due to limitations
+ * of timestamp functions in Mysql (year 2038 problem)
+ *
* @param string $field Field name
*
* @return string SQL statement to use in query
@@ -97,24 +88,6 @@ class rcube_db_pgsql extends rcube_db
}
/**
- * Return SQL function for current time and date
- *
- * @param int $interval Optional interval (in seconds) to add/subtract
- *
- * @return string SQL function to use in query
- */
- public function now($interval = 0)
- {
- if ($interval) {
- $add = ' ' . ($interval > 0 ? '+' : '-') . " interval '";
- $add .= $interval > 0 ? intval($interval) : intval($interval) * -1;
- $add .= " seconds'";
- }
-
- return "now()" . $add;
- }
-
- /**
* Return SQL statement for case insensitive LIKE
*
* @param string $column Field name
diff --git a/program/lib/Roundcube/rcube_db_sqlite.php b/program/lib/Roundcube/rcube_db_sqlite.php
index b66c56097..145b8a371 100644
--- a/program/lib/Roundcube/rcube_db_sqlite.php
+++ b/program/lib/Roundcube/rcube_db_sqlite.php
@@ -29,6 +29,13 @@ class rcube_db_sqlite extends rcube_db
public $db_provider = 'sqlite';
/**
+ * Database character set
+ */
+ protected function set_charset($charset)
+ {
+ }
+
+ /**
* Prepare connection
*/
protected function conn_prepare($dsn)
@@ -49,6 +56,10 @@ class rcube_db_sqlite extends rcube_db
*/
protected function conn_configure($dsn, $dbh)
{
+ // we emulate via callback some missing functions
+ $dbh->sqliteCreateFunction('unix_timestamp', array('rcube_db_sqlite', 'sqlite_unix_timestamp'), 1);
+ $dbh->sqliteCreateFunction('now', array('rcube_db_sqlite', 'sqlite_now'), 0);
+
// Initialize database structure in file is empty
if (!empty($dsn['database']) && !filesize($dsn['database'])) {
$data = file_get_contents(RCUBE_INSTALL_PATH . 'SQL/sqlite.initial.sql');
@@ -72,32 +83,30 @@ class rcube_db_sqlite extends rcube_db
}
/**
- * Return SQL statement to convert a field value into a unix timestamp
- *
- * @param string $field Field name
- *
- * @return string SQL statement to use in query
- * @deprecated
+ * Callback for sqlite: unix_timestamp()
*/
- public function unixtimestamp($field)
+ public static function sqlite_unix_timestamp($timestamp = '')
{
- return "strftime('%s', $field)";
+ $timestamp = trim($timestamp);
+ if (!$timestamp) {
+ $ret = time();
+ }
+ else if (!preg_match('/^[0-9]+$/s', $timestamp)) {
+ $ret = strtotime($timestamp);
+ }
+ else {
+ $ret = $timestamp;
+ }
+
+ return $ret;
}
/**
- * Return SQL function for current time and date
- *
- * @param int $interval Optional interval (in seconds) to add/subtract
- *
- * @return string SQL function to use in query
+ * Callback for sqlite: now()
*/
- public function now($interval = 0)
+ public static function sqlite_now()
{
- if ($interval) {
- $add = ($interval > 0 ? '+' : '') . intval($interval) . ' seconds';
- }
-
- return "datetime('now'" . ($add ? ",'$add'" : "") . ")";
+ return date("Y-m-d H:i:s");
}
/**
diff --git a/program/lib/Roundcube/rcube_db_sqlsrv.php b/program/lib/Roundcube/rcube_db_sqlsrv.php
index 45c41cdaf..e5dfb1154 100644
--- a/program/lib/Roundcube/rcube_db_sqlsrv.php
+++ b/program/lib/Roundcube/rcube_db_sqlsrv.php
@@ -29,46 +29,29 @@ class rcube_db_sqlsrv extends rcube_db
public $db_provider = 'mssql';
/**
- * Object constructor
- *
- * @param string $db_dsnw DSN for read/write operations
- * @param string $db_dsnr Optional DSN for read only operations
- * @param bool $pconn Enables persistent connections
+ * Driver initialization
*/
- public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
+ protected function init()
{
- parent::__construct($db_dsnw, $db_dsnr, $pconn);
-
$this->options['identifier_start'] = '[';
$this->options['identifier_end'] = ']';
}
/**
- * Driver-specific configuration of database connection
- *
- * @param array $dsn DSN for DB connections
- * @param PDO $dbh Connection handler
+ * Database character set setting
*/
- protected function conn_configure($dsn, $dbh)
+ protected function set_charset($charset)
{
- // Set date format in case of non-default language (#1488918)
- $this->query("SET DATEFORMAT ymd");
+ // UTF-8 is default
}
/**
* Return SQL function for current time and date
*
- * @param int $interval Optional interval (in seconds) to add/subtract
- *
* @return string SQL function to use in query
*/
- public function now($interval = 0)
+ public function now()
{
- if ($interval) {
- $interval = intval($interval);
- return "dateadd(second, $interval, getdate())";
- }
-
return "getdate()";
}
diff --git a/program/lib/Roundcube/rcube_enriched.php b/program/lib/Roundcube/rcube_enriched.php
index 12deb33ce..8c628c912 100644
--- a/program/lib/Roundcube/rcube_enriched.php
+++ b/program/lib/Roundcube/rcube_enriched.php
@@ -118,7 +118,7 @@ class rcube_enriched
$quoted = '';
$lines = explode('<br>', $a[2]);
- foreach ($lines as $line)
+ foreach ($lines as $n => $line)
$quoted .= '&gt;'.$line.'<br>';
$body = $a[1].'<span class="quotes">'.$quoted.'</span>'.$a[3];
diff --git a/program/lib/Roundcube/rcube_image.php b/program/lib/Roundcube/rcube_image.php
index 4e4caae93..ffcfd4b1d 100644
--- a/program/lib/Roundcube/rcube_image.php
+++ b/program/lib/Roundcube/rcube_image.php
@@ -93,10 +93,6 @@ class rcube_image
$convert = $rcube->config->get('im_convert_path', false);
$props = $this->props();
- if (empty($props)) {
- return false;
- }
-
if (!$filename) {
$filename = $this->image_file;
}
@@ -105,6 +101,7 @@ class rcube_image
if ($convert) {
$p['out'] = $filename;
$p['in'] = $this->image_file;
+ $p['size'] = $size.'x'.$size;
$type = $props['type'];
if (!$type && ($data = $this->identify())) {
@@ -119,37 +116,11 @@ class rcube_image
$type = 'jpg';
}
- // If only one dimension is greater than the limit convert doesn't
- // work as expected, we need to calculate new dimensions
- $scale = $size / max($props['width'], $props['height']);
+ $p += array('type' => $type, 'types' => "bmp,eps,gif,jp2,jpg,png,svg,tif", 'quality' => 75);
+ $p['-opts'] = array('-resize' => $p['size'].'>');
- // if file is smaller than the limit, we do nothing
- // but copy original file to destination file
- if ($scale >= 1 && $p['intype'] == $type) {
- $result = ($this->image_file == $filename || copy($this->image_file, $filename)) ? '' : false;
- }
- else {
- if ($scale >= 1) {
- $width = $props['width'];
- $height = $props['height'];
- }
- else {
- $width = intval($props['width'] * $scale);
- $height = intval($props['height'] * $scale);
- }
-
- $valid_types = "bmp,eps,gif,jp2,jpg,png,svg,tif";
-
- $p += array(
- 'type' => $type,
- 'quality' => 75,
- 'size' => $width . 'x' . $height,
- );
-
- if (in_array($type, explode(',', $valid_types))) { // Valid type?
- $result = rcube::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace sRGB -strip'
- . ' -quality {quality} -resize {size} {intype}:{in} {type}:{out}', $p);
- }
+ if (in_array($type, explode(',', $p['types']))) { // Valid type?
+ $result = rcube::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace sRGB -quality {quality} {-opts} {intype}:{in} {type}:{out}', $p);
}
if ($result === '') {
@@ -177,43 +148,39 @@ class rcube_image
return false;
}
- if ($image === false) {
- return false;
- }
-
$scale = $size / max($props['width'], $props['height']);
// Imagemagick resize is implemented in shrinking mode (see -resize argument above)
// we do the same here, if an image is smaller than specified size
// we do nothing but copy original file to destination file
- if ($scale >= 1) {
- $result = $this->image_file == $filename || copy($this->image_file, $filename);
+ if ($scale > 1) {
+ return $this->image_file == $filename || copy($this->image_file, $filename) ? $type : false;
}
- else {
- $width = intval($props['width'] * $scale);
- $height = intval($props['height'] * $scale);
- $new_image = imagecreatetruecolor($width, $height);
-
- // Fix transparency of gif/png image
- if ($props['gd_type'] != IMAGETYPE_JPEG) {
- imagealphablending($new_image, false);
- imagesavealpha($new_image, true);
- $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
- imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
- }
-
- imagecopyresampled($new_image, $image, 0, 0, 0, 0, $width, $height, $props['width'], $props['height']);
- $image = $new_image;
-
- if ($props['gd_type'] == IMAGETYPE_JPEG) {
- $result = imagejpeg($image, $filename, 75);
- }
- elseif($props['gd_type'] == IMAGETYPE_GIF) {
- $result = imagegif($image, $filename);
- }
- elseif($props['gd_type'] == IMAGETYPE_PNG) {
- $result = imagepng($image, $filename, 6, PNG_ALL_FILTERS);
- }
+
+ $width = $props['width'] * $scale;
+ $height = $props['height'] * $scale;
+
+ $new_image = imagecreatetruecolor($width, $height);
+
+ // Fix transparency of gif/png image
+ if ($props['gd_type'] != IMAGETYPE_JPEG) {
+ imagealphablending($new_image, false);
+ imagesavealpha($new_image, true);
+ $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
+ imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
+ }
+
+ imagecopyresampled($new_image, $image, 0, 0, 0, 0, $width, $height, $props['width'], $props['height']);
+ $image = $new_image;
+
+ if ($props['gd_type'] == IMAGETYPE_JPEG) {
+ $result = imagejpeg($image, $filename, 75);
+ }
+ elseif($props['gd_type'] == IMAGETYPE_GIF) {
+ $result = imagegif($image, $filename);
+ }
+ elseif($props['gd_type'] == IMAGETYPE_PNG) {
+ $result = imagepng($image, $filename, 6, PNG_ALL_FILTERS);
}
if ($result) {
@@ -255,7 +222,7 @@ class rcube_image
$p['out'] = $filename;
$p['type'] = self::$extensions[$type];
- $result = rcube::exec($convert . ' 2>&1 -colorspace sRGB -strip -quality 75 {in} {type}:{out}', $p);
+ $result = rcube::exec($convert . ' 2>&1 -colorspace sRGB -quality 75 {in} {type}:{out}', $p);
if ($result === '') {
@chmod($filename, 0600);
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index aa074233f..ca5e35f2c 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -308,7 +308,14 @@ class rcube_imap extends rcube_storage
*/
public function set_folder($folder)
{
+ if ($this->folder == $folder) {
+ return;
+ }
+
$this->folder = $folder;
+
+ // clear messagecount cache for this folder
+ $this->clear_messagecount($folder);
}
@@ -606,7 +613,7 @@ class rcube_imap extends rcube_storage
}
if ($mode == 'THREADS') {
- $res = $this->threads($folder);
+ $res = $this->fetch_threads($folder, $force);
$count = $res->count();
if ($status) {
@@ -636,11 +643,11 @@ class rcube_imap extends rcube_storage
$keys[] = 'ALL';
}
if ($status) {
- $keys[] = 'MAX';
+ $keys[] = 'MAX';
}
}
- // @TODO: if $mode == 'ALL' we could try to use cache index here
+ // @TODO: if $force==false && $mode == 'ALL' we could try to use cache index here
// get message count using (E)SEARCH
// not very performant but more precise (using UNDELETED)
@@ -771,7 +778,7 @@ class rcube_imap extends rcube_storage
$threads = $mcache->get_thread($folder);
}
else {
- $threads = $this->threads($folder);
+ $threads = $this->fetch_threads($folder);
}
return $this->fetch_thread_headers($folder, $threads, $page, $slice);
@@ -780,47 +787,32 @@ class rcube_imap extends rcube_storage
/**
* Method for fetching threads data
*
- * @param string $folder Folder name
+ * @param string $folder Folder name
+ * @param bool $force Use IMAP server, no cache
*
* @return rcube_imap_thread Thread data object
*/
- function threads($folder)
+ function fetch_threads($folder, $force = false)
{
- if ($mcache = $this->get_mcache_engine()) {
+ if (!$force && ($mcache = $this->get_mcache_engine())) {
// don't store in self's internal cache, cache has it's own internal cache
return $mcache->get_thread($folder);
}
- if (!empty($this->icache['threads'])) {
- if ($this->icache['threads']->get_parameters('MAILBOX') == $folder) {
- return $this->icache['threads'];
+ if (empty($this->icache['threads'])) {
+ if (!$this->check_connection()) {
+ return new rcube_result_thread();
}
- }
- // get all threads
- $result = $this->threads_direct($folder);
+ // get all threads
+ $result = $this->conn->thread($folder, $this->threading,
+ $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
- // add to internal (fast) cache
- return $this->icache['threads'] = $result;
- }
-
-
- /**
- * Method for direct fetching of threads data
- *
- * @param string $folder Folder name
- *
- * @return rcube_imap_thread Thread data object
- */
- function threads_direct($folder)
- {
- if (!$this->check_connection()) {
- return new rcube_result_thread();
+ // add to internal (fast) cache
+ $this->icache['threads'] = $result;
}
- // get all threads
- return $this->conn->thread($folder, $this->threading,
- $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
+ return $this->icache['threads'];
}
@@ -1091,17 +1083,16 @@ class rcube_imap extends rcube_storage
/**
- * Returns current status of a folder (compared to the last time use)
+ * Returns current status of folder
*
* We compare the maximum UID to determine the number of
* new messages because the RECENT flag is not reliable.
*
* @param string $folder Folder name
- * @param array $diff Difference data
*
- * @return int Folder status
+ * @return int Folder status
*/
- public function folder_status($folder = null, &$diff = array())
+ public function folder_status($folder = null)
{
if (!strlen($folder)) {
$folder = $this->folder;
@@ -1122,9 +1113,6 @@ class rcube_imap extends rcube_storage
// got new messages
if ($new['maxuid'] > $old['maxuid']) {
$result += 1;
- // get new message UIDs range, that can be used for example
- // to get the data of these messages
- $diff['new'] = ($old['maxuid'] + 1 < $new['maxuid'] ? ($old['maxuid']+1).':' : '') . $new['maxuid'];
}
// some messages has been deleted
if ($new['cnt'] < $old['cnt']) {
@@ -1175,15 +1163,12 @@ class rcube_imap extends rcube_storage
* @param string $folder Folder to get index from
* @param string $sort_field Sort column
* @param string $sort_order Sort order [ASC, DESC]
- * @param bool $no_threads Get not threaded index
- * @param bool $no_search Get index not limited to search result (optionally)
*
* @return rcube_result_index|rcube_result_thread List of messages (UIDs)
*/
- public function index($folder = '', $sort_field = NULL, $sort_order = NULL,
- $no_threads = false, $no_search = false
- ) {
- if (!$no_threads && $this->threading) {
+ public function index($folder = '', $sort_field = NULL, $sort_order = NULL)
+ {
+ if ($this->threading) {
return $this->thread_index($folder, $sort_field, $sort_order);
}
@@ -1195,50 +1180,43 @@ class rcube_imap extends rcube_storage
// we have a saved search result, get index from there
if ($this->search_string) {
- if ($this->search_set->is_empty()) {
- return new rcube_result_index($folder, '* SORT');
+ if ($this->search_threads) {
+ $this->search($folder, $this->search_string, $this->search_charset, $this->sort_field);
}
- // search result is an index with the same sorting?
- if (($this->search_set instanceof rcube_result_index)
- && ((!$this->sort_field && !$this->search_sorted) ||
- ($this->search_sorted && $this->search_sort_field == $this->sort_field))
- ) {
+ // use message index sort as default sorting
+ if (!$this->sort_field || $this->search_sorted) {
+ if ($this->sort_field && $this->search_sort_field != $this->sort_field) {
+ $this->search($folder, $this->search_string, $this->search_charset, $this->sort_field);
+ }
$index = $this->search_set;
}
- // $no_search is enabled when we are not interested in
- // fetching index for search result, e.g. to sort
- // threaded search result we can use full mailbox index.
- // This makes possible to use index from cache
- else if (!$no_search) {
- if (!$this->sort_field) {
- // No sorting needed, just build index from the search result
- // @TODO: do we need to sort by UID here?
- $search = $this->search_set->get_compressed();
- $index = new rcube_result_index($folder, '* ESEARCH ALL ' . $search);
- }
- else {
- $index = $this->index_direct($folder, $this->search_charset,
- $this->sort_field, $this->search_set);
- }
+ else if (!$this->check_connection()) {
+ return new rcube_result_index();
+ }
+ else {
+ $index = $this->conn->index($folder, $this->search_set->get(),
+ $this->sort_field, $this->options['skip_deleted'], true, true);
}
- if (isset($index)) {
- if ($this->sort_order != $index->get_parameters('ORDER')) {
- $index->revert();
- }
-
- return $index;
+ if ($this->sort_order != $index->get_parameters('ORDER')) {
+ $index->revert();
}
+
+ return $index;
}
// check local cache
if ($mcache = $this->get_mcache_engine()) {
- return $mcache->get_index($folder, $this->sort_field, $this->sort_order);
+ $index = $mcache->get_index($folder, $this->sort_field, $this->sort_order);
}
-
// fetch from IMAP server
- return $this->index_direct($folder, $this->sort_field, $this->sort_order);
+ else {
+ $index = $this->index_direct(
+ $folder, $this->sort_field, $this->sort_order);
+ }
+
+ return $index;
}
@@ -1246,24 +1224,22 @@ class rcube_imap extends rcube_storage
* Return sorted list of message UIDs ignoring current search settings.
* Doesn't uses cache by default.
*
- * @param string $folder Folder to get index from
- * @param string $sort_field Sort column
- * @param string $sort_order Sort order [ASC, DESC]
- * @param rcube_result_* $search Optional messages set to limit the result
+ * @param string $folder Folder to get index from
+ * @param string $sort_field Sort column
+ * @param string $sort_order Sort order [ASC, DESC]
+ * @param bool $skip_cache Disables cache usage
*
* @return rcube_result_index Sorted list of message UIDs
*/
- public function index_direct($folder, $sort_field = null, $sort_order = null, $search = null)
+ public function index_direct($folder, $sort_field = null, $sort_order = null, $skip_cache = true)
{
- if (!empty($search)) {
- $search = $this->search_set->get_compressed();
+ if (!$skip_cache && ($mcache = $this->get_mcache_engine())) {
+ $index = $mcache->get_index($folder, $sort_field, $sort_order);
}
-
// use message index sort as default sorting
- if (!$sort_field) {
+ else if (!$sort_field) {
// use search result from count() if possible
- if (empty($search) && $this->options['skip_deleted']
- && !empty($this->icache['undeleted_idx'])
+ if ($this->options['skip_deleted'] && !empty($this->icache['undeleted_idx'])
&& $this->icache['undeleted_idx']->get_parameters('ALL') !== null
&& $this->icache['undeleted_idx']->get_parameters('MAILBOX') == $folder
) {
@@ -1273,12 +1249,8 @@ class rcube_imap extends rcube_storage
return new rcube_result_index();
}
else {
- $query = $this->options['skip_deleted'] ? 'UNDELETED' : '';
- if ($search) {
- $query = trim($query . ' UID ' . $search);
- }
-
- $index = $this->conn->search($folder, $query, true);
+ $index = $this->conn->search($folder,
+ 'ALL' .($this->options['skip_deleted'] ? ' UNDELETED' : ''), true);
}
}
else if (!$this->check_connection()) {
@@ -1287,18 +1259,13 @@ class rcube_imap extends rcube_storage
// fetch complete message index
else {
if ($this->get_capability('SORT')) {
- $query = $this->options['skip_deleted'] ? 'UNDELETED' : '';
- if ($search) {
- $query = trim($query . ' UID ' . $search);
- }
-
- $index = $this->conn->sort($folder, $sort_field, $query, true);
+ $index = $this->conn->sort($folder, $sort_field,
+ $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
}
if (empty($index) || $index->is_error()) {
- $index = $this->conn->index($folder, $search ? $search : "1:*",
- $sort_field, $this->options['skip_deleted'],
- $search ? true : false, true);
+ $index = $this->conn->index($folder, "1:*", $sort_field,
+ $this->options['skip_deleted'], false, true);
}
}
@@ -1331,7 +1298,7 @@ class rcube_imap extends rcube_storage
}
else {
// get all threads (default sort order)
- $threads = $this->threads($folder);
+ $threads = $this->fetch_threads($folder);
}
$this->set_sort_order($sort_field, $sort_order);
@@ -1342,10 +1309,9 @@ class rcube_imap extends rcube_storage
/**
- * Sort threaded result, using THREAD=REFS method if available.
- * If not, use any method and re-sort the result in THREAD=REFS way.
+ * Sort threaded result, using THREAD=REFS method
*
- * @param rcube_result_thread $threads Threads result set
+ * @param rcube_result_thread $threads Threads result set
*/
protected function sort_threads($threads)
{
@@ -1359,7 +1325,7 @@ class rcube_imap extends rcube_storage
if ($this->threading != 'REFS' || ($this->sort_field && $this->sort_field != 'date')) {
$sortby = $this->sort_field ? $this->sort_field : 'date';
- $index = $this->index($this->folder, $sortby, $this->sort_order, true, true);
+ $index = $this->index_direct($this->folder, $sortby, $this->sort_order, false);
if (!$index->is_empty()) {
$threads->sort($index);
@@ -1439,6 +1405,8 @@ class rcube_imap extends rcube_storage
*/
protected function search_index($folder, $criteria='ALL', $charset=NULL, $sort_field=NULL)
{
+ $orig_criteria = $criteria;
+
if (!$this->check_connection()) {
if ($this->threading) {
return new rcube_result_thread();
@@ -2079,18 +2047,17 @@ class rcube_imap extends rcube_storage
/**
* Fetch message body of a specific message from the server
*
- * @param int Message UID
- * @param string Part number
- * @param rcube_message_part Part object created by get_structure()
- * @param mixed True to print part, resource to write part contents in
- * @param resource File pointer to save the message part
- * @param boolean Disables charset conversion
- * @param int Only read this number of bytes
- * @param boolean Enables formatting of text/* parts bodies
+ * @param int $uid Message UID
+ * @param string $part Part number
+ * @param rcube_message_part $o_part Part object created by get_structure()
+ * @param mixed $print True to print part, ressource to write part contents in
+ * @param resource $fp File pointer to save the message part
+ * @param boolean $skip_charset_conv Disables charset conversion
+ * @param int $max_bytes Only read this number of bytes
*
* @return string Message/part body if not printed
*/
- public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false, $max_bytes=0, $formatted=true)
+ public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false, $max_bytes=0)
{
if (!$this->check_connection()) {
return null;
@@ -2109,9 +2076,8 @@ class rcube_imap extends rcube_storage
}
if ($o_part && $o_part->size) {
- $formatted = $formatted && $o_part->ctype_primary == 'text';
$body = $this->conn->handlePartBody($this->folder, $uid, true,
- $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $formatted, $max_bytes);
+ $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $o_part->ctype_primary == 'text', $max_bytes);
}
if ($fp || $print) {
@@ -2256,14 +2222,13 @@ class rcube_imap extends rcube_storage
/**
* Append a mail message (source) to a specific folder
*
- * @param string $folder Target folder
- * @param string|array $message The message source string or filename
- * or array (of strings and file pointers)
- * @param string $headers Headers string if $message contains only the body
- * @param boolean $is_file True if $message is a filename
- * @param array $flags Message flags
- * @param mixed $date Message internal date
- * @param bool $binary Enables BINARY append
+ * @param string $folder Target folder
+ * @param string $message The message source string or filename
+ * @param string $headers Headers string if $message contains only the body
+ * @param boolean $is_file True if $message is a filename
+ * @param array $flags Message flags
+ * @param mixed $date Message internal date
+ * @param bool $binary Enables BINARY append
*
* @return int|bool Appended message UID or True on success, False on error
*/
@@ -2354,7 +2319,10 @@ class rcube_imap extends rcube_storage
// move messages
$moved = $this->conn->move($uids, $from_mbox, $to_mbox);
+ // send expunge command in order to have the moved message
+ // really deleted from the source folder
if ($moved) {
+ $this->expunge_message($uids, $from_mbox, false);
$this->clear_messagecount($from_mbox);
$this->clear_messagecount($to_mbox);
}
@@ -2656,6 +2624,7 @@ class rcube_imap extends rcube_storage
if ($list_extended) {
// unsubscribe non-existent folders, remove from the list
+ // we can do this only when LIST response is available
if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) {
foreach ($a_folders as $idx => $folder) {
if (($opts = $this->conn->data['LIST'][$folder])
@@ -2668,14 +2637,19 @@ class rcube_imap extends rcube_storage
}
}
else {
- // unsubscribe non-existent folders, remove them from the list
- if (is_array($a_folders) && !empty($a_folders) && $name == '*') {
- $existing = $this->list_folders($root, $name);
- $nonexisting = array_diff($a_folders, $existing);
- $a_folders = array_diff($a_folders, $nonexisting);
-
- foreach ($nonexisting as $folder) {
- $this->conn->unsubscribe($folder);
+ // unsubscribe non-existent folders, remove them from the list,
+ // we can do this only when LIST response is available
+ if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) {
+ foreach ($a_folders as $idx => $folder) {
+ if (!isset($this->conn->data['LIST'][$folder])
+ || in_array('\\Noselect', $this->conn->data['LIST'][$folder])
+ ) {
+ // Some servers returns \Noselect for existing folders
+ if (!$this->folder_exists($folder)) {
+ $this->conn->unsubscribe($folder);
+ unset($a_folders[$idx]);
+ }
+ }
}
}
}
@@ -2794,6 +2768,7 @@ class rcube_imap extends rcube_storage
*/
private function list_folders_update(&$result, $type = null)
{
+ $delim = $this->get_hierarchy_delimiter();
$namespace = $this->get_namespace();
$search = array();
@@ -3704,7 +3679,7 @@ class rcube_imap extends rcube_storage
{
if ($this->caching && !$this->cache) {
$rcube = rcube::get_instance();
- $ttl = $rcube->config->get('imap_cache_ttl', '10d');
+ $ttl = $rcube->config->get('message_cache_lifetime', '10d');
$this->cache = $rcube->get_cache('IMAP', $this->caching, $ttl);
}
@@ -3752,6 +3727,21 @@ class rcube_imap extends rcube_storage
}
}
+ /**
+ * Delete outdated cache entries
+ */
+ public function expunge_cache()
+ {
+ if ($this->mcache) {
+ $ttl = rcube::get_instance()->config->get('message_cache_lifetime', '10d');
+ $this->mcache->expunge($ttl);
+ }
+
+ if ($this->cache) {
+ $this->cache->expunge();
+ }
+ }
+
/* --------------------------------
* message caching methods
@@ -3785,10 +3775,8 @@ class rcube_imap extends rcube_storage
if ($this->messages_caching && !$this->mcache) {
$rcube = rcube::get_instance();
if (($dbh = $rcube->get_dbh()) && ($userid = $rcube->get_user_id())) {
- $ttl = $rcube->config->get('messages_cache_ttl', '10d');
- $threshold = $rcube->config->get('messages_cache_threshold', 50);
$this->mcache = new rcube_imap_cache(
- $dbh, $this, $userid, $this->options['skip_deleted'], $ttl, $threshold);
+ $dbh, $this, $userid, $this->options['skip_deleted']);
}
}
@@ -3810,15 +3798,6 @@ class rcube_imap extends rcube_storage
}
- /**
- * Delete outdated cache entries
- */
- function cache_gc()
- {
- rcube_imap_cache::gc();
- }
-
-
/* --------------------------------
* protected methods
* --------------------------------*/
@@ -3852,7 +3831,7 @@ class rcube_imap extends rcube_storage
$delimiter = $this->get_hierarchy_delimiter();
// find default folders and skip folders starting with '.'
- foreach ($a_folders as $folder) {
+ foreach ($a_folders as $i => $folder) {
if ($folder[0] == '.') {
continue;
}
@@ -4112,9 +4091,9 @@ class rcube_imap extends rcube_storage
return $this->index($folder, $sort_field, $sort_order);
}
- public function message_index_direct($folder, $sort_field = null, $sort_order = null)
+ public function message_index_direct($folder, $sort_field = null, $sort_order = null, $skip_cache = true)
{
- return $this->index_direct($folder, $sort_field, $sort_order);
+ return $this->index_direct($folder, $sort_field, $sort_order, $skip_cache);
}
public function list_mailboxes($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php
index d72bfe0ab..5170e9e21 100644
--- a/program/lib/Roundcube/rcube_imap_cache.php
+++ b/program/lib/Roundcube/rcube_imap_cache.php
@@ -49,20 +49,6 @@ class rcube_imap_cache
private $userid;
/**
- * Expiration time in seconds
- *
- * @var int
- */
- private $ttl;
-
- /**
- * Maximum cached message size
- *
- * @var int
- */
- private $threshold;
-
- /**
* Internal (in-memory) cache
*
* @var array
@@ -97,26 +83,13 @@ class rcube_imap_cache
/**
* Object constructor.
- *
- * @param rcube_db $db DB handler
- * @param rcube_imap $imap IMAP handler
- * @param int $userid User identifier
- * @param bool $skip_deleted skip_deleted flag
- * @param string $ttl Expiration time of memcache/apc items
- * @param int $threshold Maximum cached message size
*/
- function __construct($db, $imap, $userid, $skip_deleted, $ttl=0, $threshold=0)
+ function __construct($db, $imap, $userid, $skip_deleted)
{
- // convert ttl string to seconds
- $ttl = get_offset_sec($ttl);
- if ($ttl > 2592000) $ttl = 2592000;
-
$this->db = $db;
$this->imap = $imap;
$this->userid = $userid;
$this->skip_deleted = $skip_deleted;
- $this->ttl = $ttl;
- $this->threshold = $threshold;
}
@@ -242,7 +215,9 @@ class rcube_imap_cache
* Return messages thread.
* If threaded index doesn't exist or is invalid, will be updated.
*
- * @param string $mailbox Folder name
+ * @param string $mailbox Folder name
+ * @param string $sort_field Sorting column
+ * @param string $sort_order Sorting order (ASC|DESC)
*
* @return array Messages threaded index
*/
@@ -281,11 +256,19 @@ class rcube_imap_cache
if ($index === null) {
// Get mailbox data (UIDVALIDITY, counters, etc.) for status check
$mbox_data = $this->imap->folder_data($mailbox);
- // Get THREADS result
- $index['object'] = $this->get_thread_data($mailbox, $mbox_data);
+
+ if ($mbox_data['EXISTS']) {
+ // get all threads (default sort order)
+ $threads = $this->imap->fetch_threads($mailbox, true);
+ }
+ else {
+ $threads = new rcube_result_thread($mailbox, '* THREAD');
+ }
+
+ $index['object'] = $threads;
// insert/update
- $this->add_thread_row($mailbox, $index['object'], $mbox_data, $exists);
+ $this->add_thread_row($mailbox, $threads, $mbox_data, $exists);
}
$this->icache[$mailbox]['thread'] = $index;
@@ -443,40 +426,23 @@ class rcube_imap_cache
if (!$force) {
$res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
- ." SET flags = ?, data = ?, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
+ ." SET flags = ?, data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid = ?",
$flags, $msg, $this->userid, $mailbox, (int) $message->uid);
- if ($this->db->affected_rows($res)) {
+ if ($this->db->affected_rows()) {
return;
}
}
- $this->db->set_option('ignore_key_errors', true);
-
// insert new record
- $res = $this->db->query(
+ $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_messages')
- ." (user_id, mailbox, uid, flags, expires, data)"
- ." VALUES (?, ?, ?, ?, ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?)",
+ ." (user_id, mailbox, uid, flags, changed, data)"
+ ." VALUES (?, ?, ?, ?, ".$this->db->now().", ?)",
$this->userid, $mailbox, (int) $message->uid, $flags, $msg);
-
- // race-condition, insert failed so try update (#1489146)
- // thanks to ignore_key_errors "duplicate row" errors will be ignored
- if ($force && !$res && !$this->db->is_error($res)) {
- $this->db->query(
- "UPDATE ".$this->db->table_name('cache_messages')
- ." SET expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
- .", flags = ?, data = ?"
- ." WHERE user_id = ?"
- ." AND mailbox = ?"
- ." AND uid = ?",
- $flags, $msg, $this->userid, $mailbox, (int) $message->uid);
- }
-
- $this->db->set_option('ignore_key_errors', false);
}
@@ -517,7 +483,7 @@ class rcube_imap_cache
$this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
- ." SET expires = ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
+ ." SET changed = ".$this->db->now()
.", flags = flags ".($enabled ? "+ $idx" : "- $idx")
." WHERE user_id = ?"
." AND mailbox = ?"
@@ -640,21 +606,23 @@ class rcube_imap_cache
/**
- * Delete expired cache entries
+ * Delete cache entries older than TTL
+ *
+ * @param string $ttl Lifetime of message cache entries
*/
- static function gc()
+ function expunge($ttl)
{
- $rcube = rcube::get_instance();
- $db = $rcube->get_dbh();
+ // get expiration timestamp
+ $ts = get_offset_time($ttl, -1);
- $db->query("DELETE FROM ".$db->table_name('cache_messages')
- ." WHERE expires < " . $db->now());
+ $this->db->query("DELETE FROM ".$this->db->table_name('cache_messages')
+ ." WHERE changed < " . $this->db->fromunixtime($ts));
- $db->query("DELETE FROM ".$db->table_name('cache_index')
- ." WHERE expires < " . $db->now());
+ $this->db->query("DELETE FROM ".$this->db->table_name('cache_index')
+ ." WHERE changed < " . $this->db->fromunixtime($ts));
- $db->query("DELETE FROM ".$db->table_name('cache_thread')
- ." WHERE expires < " . $db->now());
+ $this->db->query("DELETE FROM ".$this->db->table_name('cache_thread')
+ ." WHERE changed < " . $this->db->fromunixtime($ts));
}
@@ -746,38 +714,20 @@ class rcube_imap_cache
$data = implode('@', $data);
if ($exists) {
- $res = $this->db->query(
+ $sql_result = $this->db->query(
"UPDATE ".$this->db->table_name('cache_index')
- ." SET data = ?, valid = 1, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
+ ." SET data = ?, valid = 1, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
-
- if ($this->db->affected_rows($res)) {
- return;
- }
}
-
- $this->db->set_option('ignore_key_errors', true);
-
- $res = $this->db->query(
- "INSERT INTO ".$this->db->table_name('cache_index')
- ." (user_id, mailbox, valid, expires, data)"
- ." VALUES (?, ?, 1, ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') .", ?)",
- $this->userid, $mailbox, $data);
-
- // race-condition, insert failed so try update (#1489146)
- // thanks to ignore_key_errors "duplicate row" errors will be ignored
- if (!$exists && !$res && !$this->db->is_error($res)) {
- $res = $this->db->query(
- "UPDATE ".$this->db->table_name('cache_index')
- ." SET data = ?, valid = 1, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
- ." WHERE user_id = ?"
- ." AND mailbox = ?",
- $data, $this->userid, $mailbox);
+ else {
+ $sql_result = $this->db->query(
+ "INSERT INTO ".$this->db->table_name('cache_index')
+ ." (user_id, mailbox, data, valid, changed)"
+ ." VALUES (?, ?, ?, 1, ".$this->db->now().")",
+ $this->userid, $mailbox, $data);
}
-
- $this->db->set_option('ignore_key_errors', false);
}
@@ -794,41 +744,21 @@ class rcube_imap_cache
);
$data = implode('@', $data);
- $expires = ($this->ttl ? $this->db->now($this->ttl) : 'NULL');
-
if ($exists) {
- $res = $this->db->query(
+ $sql_result = $this->db->query(
"UPDATE ".$this->db->table_name('cache_thread')
- ." SET data = ?, expires = $expires"
+ ." SET data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
-
- if ($this->db->affected_rows($res)) {
- return;
- }
}
-
- $this->db->set_option('ignore_key_errors', true);
-
- $res = $this->db->query(
- "INSERT INTO ".$this->db->table_name('cache_thread')
- ." (user_id, mailbox, expires, data)"
- ." VALUES (?, ?, $expires, ?)",
- $this->userid, $mailbox, $data);
-
- // race-condition, insert failed so try update (#1489146)
- // thanks to ignore_key_errors "duplicate row" errors will be ignored
- if (!$exists && !$res && !$this->db->is_error($res)) {
- $this->db->query(
- "UPDATE ".$this->db->table_name('cache_thread')
- ." SET expires = $expires, data = ?"
- ." WHERE user_id = ?"
- ." AND mailbox = ?",
- $data, $this->userid, $mailbox);
+ else {
+ $sql_result = $this->db->query(
+ "INSERT INTO ".$this->db->table_name('cache_thread')
+ ." (user_id, mailbox, data, changed)"
+ ." VALUES (?, ?, ?, ".$this->db->now().")",
+ $this->userid, $mailbox, $data);
}
-
- $this->db->set_option('ignore_key_errors', false);
}
@@ -1055,7 +985,7 @@ class rcube_imap_cache
$uids, true, array('FLAGS'), $index['modseq'], $qresync);
if (!empty($result)) {
- foreach ($result as $msg) {
+ foreach ($result as $id => $msg) {
$uid = $msg->uid;
// Remove deleted message
if ($this->skip_deleted && !empty($msg->flags['DELETED'])) {
@@ -1076,7 +1006,7 @@ class rcube_imap_cache
$this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
- ." SET flags = ?, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
+ ." SET flags = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid = ?"
@@ -1104,18 +1034,17 @@ class rcube_imap_cache
}
}
+ // Invalidate thread index (?)
+ if (!$index['valid']) {
+ $this->remove_thread($mailbox);
+ }
+
$sort_field = $index['sort_field'];
$sort_order = $index['object']->get_parameters('ORDER');
$exists = true;
// Validate index
if (!$this->validate($mailbox, $index, $exists)) {
- // Invalidate (remove) thread index
- // if $exists=false it was already removed in validate()
- if ($exists) {
- $this->remove_thread($mailbox);
- }
-
// Update index
$data = $this->get_index_data($mailbox, $sort_field, $sort_order, $mbox_data);
}
@@ -1182,16 +1111,11 @@ class rcube_imap_cache
*
* @param rcube_message_header|rcube_message_part
*/
- private function message_object_prepare(&$msg, &$size = 0)
+ private function message_object_prepare(&$msg)
{
- // Remove body too big
- if ($msg->body && ($length = strlen($msg->body))) {
- $size += $length;
-
- if ($size > $this->threshold * 1024) {
- $size -= $length;
- unset($msg->body);
- }
+ // Remove body too big (>25kB)
+ if ($msg->body && strlen($msg->body) > 25 * 1024) {
+ unset($msg->body);
}
// Fix mimetype which might be broken by some code when message is displayed
@@ -1205,13 +1129,13 @@ class rcube_imap_cache
if (is_array($msg->structure->parts)) {
foreach ($msg->structure->parts as $part) {
- $this->message_object_prepare($part, $size);
+ $this->message_object_prepare($part);
}
}
if (is_array($msg->parts)) {
foreach ($msg->parts as $part) {
- $this->message_object_prepare($part, $size);
+ $this->message_object_prepare($part);
}
}
}
@@ -1236,25 +1160,6 @@ class rcube_imap_cache
return $index;
}
-
-
- /**
- * Fetches thread data from IMAP server
- */
- private function get_thread_data($mailbox, $mbox_data = array())
- {
- if (empty($mbox_data)) {
- $mbox_data = $this->imap->folder_data($mailbox);
- }
-
- if ($mbox_data['EXISTS']) {
- // get all threads (default sort order)
- return $this->imap->threads_direct($mailbox);
- }
-
- return new rcube_result_thread($mailbox, '* THREAD');
- }
-
}
// for backward compat.
diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php
index bce4cd4e2..1b28c3bd7 100644
--- a/program/lib/Roundcube/rcube_imap_generic.php
+++ b/program/lib/Roundcube/rcube_imap_generic.php
@@ -72,8 +72,6 @@ class rcube_imap_generic
const COMMAND_CAPABILITY = 2;
const COMMAND_LASTLINE = 4;
- const DEBUG_LINE_LENGTH = 4098; // 4KB + 2B for \r\n
-
/**
* Object constructor
*/
@@ -789,21 +787,23 @@ class rcube_imap_generic
// TLS connection
if ($this->prefs['ssl_mode'] == 'tls' && $this->getCapability('STARTTLS')) {
- $res = $this->execute('STARTTLS');
+ if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
+ $res = $this->execute('STARTTLS');
- if ($res[0] != self::ERROR_OK) {
- $this->closeConnection();
- return false;
- }
+ if ($res[0] != self::ERROR_OK) {
+ $this->closeConnection();
+ return false;
+ }
- if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
- $this->setError(self::ERROR_BAD, "Unable to negotiate TLS");
- $this->closeConnection();
- return false;
- }
+ if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+ $this->setError(self::ERROR_BAD, "Unable to negotiate TLS");
+ $this->closeConnection();
+ return false;
+ }
- // Now we're secure, capabilities need to be reread
- $this->clearCapability();
+ // Now we're secure, capabilities need to be reread
+ $this->clearCapability();
+ }
}
// Send ID info
@@ -902,11 +902,6 @@ class rcube_imap_generic
$this->prefs['auth_type'] = 'CHECK';
}
- // disabled capabilities
- if (!empty($this->prefs['disabled_caps'])) {
- $this->prefs['disabled_caps'] = array_map('strtoupper', (array)$this->prefs['disabled_caps']);
- }
-
// additional message flags
if (!empty($this->prefs['message_flags'])) {
$this->flags = array_merge($this->flags, $this->prefs['message_flags']);
@@ -1088,8 +1083,8 @@ class rcube_imap_generic
/**
* Executes EXPUNGE command
*
- * @param string $mailbox Mailbox name
- * @param string|array $messages Message UIDs to expunge
+ * @param string $mailbox Mailbox name
+ * @param string $messages Message UIDs to expunge
*
* @return boolean True on success, False on error
*/
@@ -1107,13 +1102,10 @@ class rcube_imap_generic
// Clear internal status cache
unset($this->data['STATUS:'.$mailbox]);
- if (!empty($messages) && $messages != '*' && $this->hasCapability('UIDPLUS')) {
- $messages = self::compressMessageSet($messages);
- $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE);
- }
- else {
+ if ($messages)
+ $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE);
+ else
$result = $this->execute('EXPUNGE', null, self::COMMAND_NORESPONSE);
- }
if ($result == self::ERROR_OK) {
$this->selected = null; // state has changed, need to reselect
@@ -1350,8 +1342,9 @@ class rcube_imap_generic
$folders[$mailbox] = array();
}
- // store folder options
- if ($cmd == 'LIST') {
+ // store LSUB options only if not empty, this way
+ // we can detect a situation when LIST doesn't return specified folder
+ if (!empty($opts) || $cmd == 'LIST') {
// Add to options array
if (empty($this->data['LIST'][$mailbox]))
$this->data['LIST'][$mailbox] = $opts;
@@ -1583,12 +1576,11 @@ class rcube_imap_generic
}
// message IDs
- if (!empty($add)) {
+ if (!empty($add))
$add = $this->compressMessageSet($add);
- }
list($code, $response) = $this->execute($return_uid ? 'UID SORT' : 'SORT',
- array("($field)", $encoding, !empty($add) ? $add : 'ALL'));
+ array("($field)", $encoding, 'ALL' . (!empty($add) ? ' '.$add : '')));
if ($code != self::ERROR_OK) {
$response = null;
@@ -1675,6 +1667,7 @@ class rcube_imap_generic
}
if (!empty($criteria)) {
+ $modseq = stripos($criteria, 'MODSEQ') !== false;
$params .= ($params ? ' ' : '') . $criteria;
}
else {
@@ -1813,6 +1806,7 @@ class rcube_imap_generic
if ($skip_deleted && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
$flags = explode(' ', strtoupper($matches[1]));
if (in_array('\\DELETED', $flags)) {
+ $deleted[$id] = $id;
continue;
}
}
@@ -2004,6 +1998,7 @@ class rcube_imap_generic
/**
* Moves message(s) from one folder to another.
+ * Original message(s) will be marked as deleted.
*
* @param string|array $messages Message UID(s)
* @param string $from Mailbox name
@@ -2022,41 +2017,15 @@ class rcube_imap_generic
return false;
}
- // use MOVE command (RFC 6851)
- if ($this->hasCapability('MOVE')) {
- // Clear last COPYUID data
- unset($this->data['COPYUID']);
+ $r = $this->copy($messages, $from, $to);
+ if ($r) {
// Clear internal status cache
- unset($this->data['STATUS:'.$to]);
unset($this->data['STATUS:'.$from]);
- $result = $this->execute('UID MOVE', array(
- $this->compressMessageSet($messages), $this->escape($to)),
- self::COMMAND_NORESPONSE);
-
- return ($result == self::ERROR_OK);
- }
-
- // use COPY + STORE +FLAGS.SILENT \Deleted + EXPUNGE
- $result = $this->copy($messages, $from, $to);
-
- if ($result) {
- // Clear internal status cache
- unset($this->data['STATUS:'.$from]);
-
- $result = $this->flag($from, $messages, 'DELETED');
-
- if ($messages == '*') {
- // CLOSE+SELECT should be faster than EXPUNGE
- $this->close();
- }
- else {
- $this->expunge($from, $messages);
- }
+ return $this->flag($from, $messages, 'DELETED');
}
-
- return $result;
+ return $r;
}
/**
@@ -2197,7 +2166,7 @@ class rcube_imap_generic
// create array with header field:data
if (!empty($headers)) {
$headers = explode("\n", trim($headers));
- foreach ($headers as $resln) {
+ foreach ($headers as $hid => $resln) {
if (ord($resln[0]) <= 32) {
$lines[$ln] .= (empty($lines[$ln]) ? '' : "\n") . trim($resln);
} else {
@@ -2205,7 +2174,7 @@ class rcube_imap_generic
}
}
- foreach ($lines as $str) {
+ while (list($lines_key, $str) = each($lines)) {
list($field, $string) = explode(':', $str, 2);
$field = strtolower($field);
@@ -2509,7 +2478,7 @@ class rcube_imap_generic
}
if ($binary) {
- // WARNING: Use $formatted argument with care, this may break binary data stream
+ // WARNING: Use $formatting argument with care, this may break binary data stream
$mode = -1;
}
@@ -2530,7 +2499,6 @@ class rcube_imap_generic
// handle one line response
if ($line[0] == '(' && substr($line, -1) == ')') {
// tokenize content inside brackets
- // the content can be e.g.: (UID 9844 BODY[2.4] NIL)
$tokens = $this->tokenizeResponse(preg_replace('/(^\(|\)$)/', '', $line));
for ($i=0; $i<count($tokens); $i+=2) {
@@ -2645,11 +2613,11 @@ class rcube_imap_generic
/**
* Handler for IMAP APPEND command
*
- * @param string $mailbox Mailbox name
- * @param string|array $message The message source string or array (of strings and file pointers)
- * @param array $flags Message flags
- * @param string $date Message internal date
- * @param bool $binary Enable BINARY append (RFC3516)
+ * @param string $mailbox Mailbox name
+ * @param string $message Message content
+ * @param array $flags Message flags
+ * @param string $date Message internal date
+ * @param bool $binary Enable BINARY append (RFC3516)
*
* @return string|bool On success APPENDUID response (if available) or True, False on failure
*/
@@ -2663,28 +2631,13 @@ class rcube_imap_generic
$binary = $binary && $this->getCapability('BINARY');
$literal_plus = !$binary && $this->prefs['literal+'];
- $len = 0;
- $msg = is_array($message) ? $message : array(&$message);
- $chunk_size = 512000;
-
- for ($i=0, $cnt=count($msg); $i<$cnt; $i++) {
- if (is_resource($msg[$i])) {
- $stat = fstat($msg[$i]);
- if ($stat === false) {
- return false;
- }
- $len += $stat['size'];
- }
- else {
- if (!$binary) {
- $msg[$i] = str_replace("\r", '', $msg[$i]);
- $msg[$i] = str_replace("\n", "\r\n", $msg[$i]);
- }
- $len += strlen($msg[$i]);
- }
+ if (!$binary) {
+ $message = str_replace("\r", '', $message);
+ $message = str_replace("\n", "\r\n", $message);
}
+ $len = strlen($message);
if (!$len) {
return false;
}
@@ -2709,32 +2662,7 @@ class rcube_imap_generic
}
}
- foreach ($msg as $msg_part) {
- // file pointer
- if (is_resource($msg_part)) {
- rewind($msg_part);
- while (!feof($msg_part) && $this->fp) {
- $buffer = fread($msg_part, $chunk_size);
- $this->putLine($buffer, false);
- }
- fclose($msg_part);
- }
- // string
- else {
- $size = strlen($msg_part);
-
- // Break up the data by sending one chunk (up to 512k) at a time.
- // This approach reduces our peak memory usage
- for ($offset = 0; $offset < $size; $offset += $chunk_size) {
- $chunk = substr($msg_part, $offset, $chunk_size);
- if (!$this->putLine($chunk, false)) {
- return false;
- }
- }
- }
- }
-
- if (!$this->putLine('')) { // \r\n
+ if (!$this->putLine($message)) {
return false;
}
@@ -2773,23 +2701,94 @@ class rcube_imap_generic
*/
function appendFromFile($mailbox, $path, $headers=null, $flags = array(), $date = null, $binary = false)
{
+ unset($this->data['APPENDUID']);
+
+ if ($mailbox === null || $mailbox === '') {
+ return false;
+ }
+
// open message file
+ $in_fp = false;
if (file_exists(realpath($path))) {
- $fp = fopen($path, 'r');
+ $in_fp = fopen($path, 'r');
}
- if (!$fp) {
+ if (!$in_fp) {
$this->setError(self::ERROR_UNKNOWN, "Couldn't open $path for reading");
return false;
}
- $message = array();
+ $body_separator = "\r\n\r\n";
+ $len = filesize($path);
+
+ if (!$len) {
+ return false;
+ }
+
if ($headers) {
- $message[] = trim($headers, "\r\n") . "\r\n\r\n";
+ $headers = preg_replace('/[\r\n]+$/', '', $headers);
+ $len += strlen($headers) + strlen($body_separator);
+ }
+
+ $binary = $binary && $this->getCapability('BINARY');
+ $literal_plus = !$binary && $this->prefs['literal+'];
+
+ // build APPEND command
+ $key = $this->nextTag();
+ $request = "$key APPEND " . $this->escape($mailbox) . ' (' . $this->flagsToStr($flags) . ')';
+ if (!empty($date)) {
+ $request .= ' ' . $this->escape($date);
}
- $message[] = $fp;
+ $request .= ' ' . ($binary ? '~' : '') . '{' . $len . ($literal_plus ? '+' : '') . '}';
+
+ // send APPEND command
+ if ($this->putLine($request)) {
+ // Don't wait when LITERAL+ is supported
+ if (!$literal_plus) {
+ $line = $this->readReply();
- return $this->append($mailbox, $message, $flags, $date, $binary);
+ if ($line[0] != '+') {
+ $this->parseResult($line, 'APPEND: ');
+ return false;
+ }
+ }
+
+ // send headers with body separator
+ if ($headers) {
+ $this->putLine($headers . $body_separator, false);
+ }
+
+ // send file
+ while (!feof($in_fp) && $this->fp) {
+ $buffer = fgets($in_fp, 4096);
+ $this->putLine($buffer, false);
+ }
+ fclose($in_fp);
+
+ if (!$this->putLine('')) { // \r\n
+ return false;
+ }
+
+ // read response
+ do {
+ $line = $this->readLine();
+ } while (!$this->startsWith($line, $key, true, true));
+
+ // Clear internal status cache
+ unset($this->data['STATUS:'.$mailbox]);
+
+ if ($this->parseResult($line, 'APPEND: ') != self::ERROR_OK)
+ return false;
+ else if (!empty($this->data['APPENDUID']))
+ return $this->data['APPENDUID'];
+ else
+ return true;
+ }
+ else {
+ $this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
+ }
+
+ return false;
}
/**
@@ -3538,7 +3537,7 @@ class rcube_imap_generic
if (is_array($element)) {
reset($element);
- foreach ($element as $value) {
+ while (list($key, $value) = each($element)) {
$string .= ' ' . self::r_implode($value);
}
}
@@ -3566,7 +3565,7 @@ class rcube_imap_generic
// if less than 255 bytes long, let's not bother
if (!$force && strlen($messages)<255) {
return $messages;
- }
+ }
// see if it's already been compressed
if (strpos($messages, ':') !== false) {
@@ -3674,20 +3673,8 @@ class rcube_imap_generic
*/
static function strToTime($date)
{
- // Clean malformed data
- $date = preg_replace(
- array(
- '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal
- '/[^a-z0-9\x20\x09:+-]/i', // remove any invalid characters
- '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names
- ),
- array(
- '\\1',
- '',
- '',
- ), $date);
-
- $date = trim($date);
+ // support non-standard "GMTXXXX" literal
+ $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date);
// if date parsing fails, we have a date in non-rfc format
// remove token from the end and try again
@@ -3712,10 +3699,6 @@ class rcube_imap_generic
$this->capability = explode(' ', strtoupper($str));
- if (!empty($this->prefs['disabled_caps'])) {
- $this->capability = array_diff($this->capability, $this->prefs['disabled_caps']);
- }
-
if (!isset($this->prefs['literal+']) && in_array('LITERAL+', $this->capability)) {
$this->prefs['literal+'] = true;
}
@@ -3761,10 +3744,9 @@ class rcube_imap_generic
/**
* Set the value of the debugging flag.
*
- * @param boolean $debug New value for the debugging flag.
- * @param callback $handler Logging handler function
+ * @param boolean $debug New value for the debugging flag.
*
- * @since 0.5-stable
+ * @since 0.5-stable
*/
function setDebug($debug, $handler = null)
{
@@ -3775,18 +3757,12 @@ class rcube_imap_generic
/**
* Write the given debug text to the current debug output handler.
*
- * @param string $message Debug mesage text.
+ * @param string $message Debug mesage text.
*
- * @since 0.5-stable
+ * @since 0.5-stable
*/
private function debug($message)
{
- if (($len = strlen($message)) > self::DEBUG_LINE_LENGTH) {
- $diff = $len - self::DEBUG_LINE_LENGTH;
- $message = substr($message, 0, self::DEBUG_LINE_LENGTH)
- . "... [truncated $diff bytes]";
- }
-
if ($this->resourceid) {
$message = sprintf('[%s] %s', $this->resourceid, $message);
}
diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php
index 78573789b..7c4002337 100644
--- a/program/lib/Roundcube/rcube_ldap.php
+++ b/program/lib/Roundcube/rcube_ldap.php
@@ -3,8 +3,8 @@
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2013, The Roundcube Dev Team |
- | Copyright (C) 2011-2013, Kolab Systems AG |
+ | Copyright (C) 2006-2012, The Roundcube Dev Team |
+ | Copyright (C) 2011-2012, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -27,51 +27,38 @@
*/
class rcube_ldap extends rcube_addressbook
{
- // public properties
+ /** public properties */
public $primary_key = 'ID';
- public $groups = false;
- public $readonly = true;
- public $ready = false;
- public $group_id = 0;
- public $coltypes = array();
- public $export_groups = false;
-
- // private properties
- protected $ldap;
- protected $prop = array();
+ public $groups = false;
+ public $readonly = true;
+ public $ready = false;
+ public $group_id = 0;
+ public $coltypes = array();
+
+ /** private properties */
+ protected $conn;
+ protected $prop = array();
protected $fieldmap = array();
- protected $filter = '';
protected $sub_filter;
- protected $result;
- protected $ldap_result;
+ protected $filter = '';
+ protected $result = null;
+ protected $ldap_result = null;
protected $mail_domain = '';
protected $debug = false;
- /**
- * Group objectclass (lowercase) to member attribute mapping
- *
- * @var array
- */
- private static $group_types = array(
- 'group' => 'member',
- 'groupofnames' => 'member',
- 'kolabgroupofnames' => 'member',
- 'groupofuniquenames' => 'uniqueMember',
- 'kolabgroupofuniquenames' => 'uniqueMember',
- 'univentiongroup' => 'uniqueMember',
- 'groupofurls' => null,
- );
-
- private $base_dn = '';
+ private $base_dn = '';
private $groups_base_dn = '';
- private $group_url;
+ private $group_url = null;
private $cache;
+ private $vlv_active = false;
+ private $vlv_count = 0;
+
/**
* Object constructor
*
- * @param array $p LDAP connection properties
+ * @param array $p LDAP connection properties
* @param boolean $debug Enables debug mode
* @param string $mail_domain Current user mail domain name
*/
@@ -79,7 +66,8 @@ class rcube_ldap extends rcube_addressbook
{
$this->prop = $p;
- $fetch_attributes = array('objectClass');
+ if (isset($p['searchonly']))
+ $this->searchonly = $p['searchonly'];
// check if groups are configured
if (is_array($p['groups']) && count($p['groups'])) {
@@ -94,21 +82,6 @@ class rcube_ldap extends rcube_addressbook
$this->prop['groups']['name_attr'] = 'cn';
if (empty($this->prop['groups']['scope']))
$this->prop['groups']['scope'] = 'sub';
-
- // add group name attrib to the list of attributes to be fetched
- $fetch_attributes[] = $this->prop['groups']['name_attr'];
- }
- if (is_array($p['group_filters']) && count($p['group_filters'])) {
- $this->groups = true;
-
- foreach ($p['group_filters'] as $k => $group_filter) {
- // set default name attribute to cn
- if (empty($group_filter['name_attr']) && empty($this->prop['groups']['name_attr']))
- $this->prop['group_filters'][$k]['name_attr'] = $group_filter['name_attr'] = 'cn';
-
- if ($group_filter['name_attr'])
- $fetch_attributes[] = $group_filter['name_attr'];
- }
}
// fieldmap property is given
@@ -196,7 +169,7 @@ class rcube_ldap extends rcube_addressbook
// Build sub_fields filter
if (!empty($this->prop['sub_fields']) && is_array($this->prop['sub_fields'])) {
$this->sub_filter = '';
- foreach ($this->prop['sub_fields'] as $class) {
+ foreach ($this->prop['sub_fields'] as $attr => $class) {
if (!empty($class)) {
$class = is_array($class) ? array_pop($class) : $class;
$this->sub_filter .= '(objectClass=' . $class . ')';
@@ -213,24 +186,7 @@ class rcube_ldap extends rcube_addressbook
// initialize cache
$rcube = rcube::get_instance();
- if ($cache_type = $rcube->config->get('ldap_cache', 'db')) {
- $cache_ttl = $rcube->config->get('ldap_cache_ttl', '10m');
- $cache_name = 'LDAP.' . asciiwords($this->prop['name']);
-
- $this->cache = $rcube->get_cache($cache_name, $cache_type, $cache_ttl);
- }
-
- // determine which attributes to fetch
- $this->prop['list_attributes'] = array_unique($fetch_attributes);
- $this->prop['attributes'] = array_merge(array_values($this->fieldmap), $fetch_attributes);
- foreach ($rcube->config->get('contactlist_fields') as $col) {
- $this->prop['list_attributes'] = array_merge($this->prop['list_attributes'], $this->_map_field($col));
- }
-
- // initialize ldap wrapper object
- $this->ldap = new rcube_ldap_generic($this->prop);
- $this->ldap->set_cache($this->cache);
- $this->ldap->set_debug($this->debug);
+ $this->cache = $rcube->get_cache('LDAP.' . asciiwords($this->prop['name']), 'db', 600);
$this->_connect();
}
@@ -243,18 +199,49 @@ class rcube_ldap extends rcube_addressbook
{
$rcube = rcube::get_instance();
- if ($this->ready)
+ if (!function_exists('ldap_connect'))
+ rcube::raise_error(array('code' => 100, 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "No ldap support in this installation of PHP"),
+ true, true);
+
+ if (is_resource($this->conn))
return true;
if (!is_array($this->prop['hosts']))
$this->prop['hosts'] = array($this->prop['hosts']);
+ if (empty($this->prop['ldap_version']))
+ $this->prop['ldap_version'] = 3;
+
// try to connect + bind for every host configured
// with OpenLDAP 2.x ldap_connect() always succeeds but ldap_bind will fail if host isn't reachable
// see http://www.php.net/manual/en/function.ldap-connect.php
foreach ($this->prop['hosts'] as $host) {
- // skip host if connection failed
- if (!$this->ldap->connect($host)) {
+ $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
+ $hostname = $host.($this->prop['port'] ? ':'.$this->prop['port'] : '');
+
+ $this->_debug("C: Connect [$hostname] [{$this->prop['name']}]");
+
+ if ($lc = @ldap_connect($host, $this->prop['port'])) {
+ if ($this->prop['use_tls'] === true)
+ if (!ldap_start_tls($lc))
+ continue;
+
+ $this->_debug("S: OK");
+
+ ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->prop['ldap_version']);
+ $this->prop['host'] = $host;
+ $this->conn = $lc;
+
+ if (!empty($this->prop['network_timeout']))
+ ldap_set_option($lc, LDAP_OPT_NETWORK_TIMEOUT, $this->prop['network_timeout']);
+
+ if (isset($this->prop['referrals']))
+ ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->prop['referrals']);
+ }
+ else {
+ $this->_debug("S: NOT OK");
continue;
}
@@ -269,7 +256,7 @@ class rcube_ldap extends rcube_addressbook
$this->base_dn = $this->prop['base_dn'];
$this->groups_base_dn = ($this->prop['groups']['base_dn']) ?
- $this->prop['groups']['base_dn'] : $this->base_dn;
+ $this->prop['groups']['base_dn'] : $this->base_dn;
// User specific access, generate the proper values to use.
if ($this->prop['user_specific']) {
@@ -288,47 +275,30 @@ class rcube_ldap extends rcube_addressbook
$replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u);
- // Search for the dn to use to authenticate
if ($this->prop['search_base_dn'] && $this->prop['search_filter']) {
- $search_bind_dn = strtr($this->prop['search_bind_dn'], $replaces);
- $search_base_dn = strtr($this->prop['search_base_dn'], $replaces);
- $search_filter = strtr($this->prop['search_filter'], $replaces);
-
- $cache_key = 'DN.' . md5("$host:$search_bind_dn:$search_base_dn:$search_filter:"
- .$this->prop['search_bind_pw']);
-
- if ($this->cache && ($dn = $this->cache->get($cache_key))) {
- $replaces['%dn'] = $dn;
+ if (!empty($this->prop['search_bind_dn']) && !empty($this->prop['search_bind_pw'])) {
+ $this->bind($this->prop['search_bind_dn'], $this->prop['search_bind_pw']);
}
- else {
- $ldap = $this->ldap;
- if (!empty($search_bind_dn) && !empty($this->prop['search_bind_pw'])) {
- // To protect from "Critical extension is unavailable" error
- // we need to use a separate LDAP connection
- if (!empty($this->prop['vlv'])) {
- $ldap = new rcube_ldap_generic($this->prop);
- $ldap->set_debug($this->debug);
- $ldap->set_cache($this->cache);
- if (!$ldap->connect($host)) {
- continue;
- }
- }
-
- if (!$ldap->bind($search_bind_dn, $this->prop['search_bind_pw'])) {
- continue; // bind failed, try next host
- }
- }
- $res = $ldap->search($search_base_dn, $search_filter, 'sub', array('uid'));
- if ($res) {
- $res->rewind();
- $replaces['%dn'] = $res->get_dn();
- }
+ // Search for the dn to use to authenticate
+ $this->prop['search_base_dn'] = strtr($this->prop['search_base_dn'], $replaces);
+ $this->prop['search_filter'] = strtr($this->prop['search_filter'], $replaces);
+
+ $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}");
- if ($ldap != $this->ldap) {
- $ldap->close();
+ $res = @ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid'));
+ if ($res) {
+ if (($entry = ldap_first_entry($this->conn, $res))
+ && ($bind_dn = ldap_get_dn($this->conn, $entry))
+ ) {
+ $this->_debug("S: search returned dn: $bind_dn");
+ $dn = ldap_explode_dn($bind_dn, 1);
+ $replaces['%dn'] = $dn[0];
}
}
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
// DN not found
if (empty($replaces['%dn'])) {
@@ -339,13 +309,9 @@ class rcube_ldap extends rcube_addressbook
'code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "DN not found using LDAP search."), true);
- continue;
+ return false;
}
}
-
- if ($this->cache && !empty($replaces['%dn'])) {
- $this->cache->set($cache_key, $replaces['%dn']);
- }
}
// Replace the bind_dn and base_dn variables.
@@ -363,13 +329,13 @@ class rcube_ldap extends rcube_addressbook
}
else {
if (!empty($bind_dn)) {
- $this->ready = $this->ldap->bind($bind_dn, $bind_pass);
+ $this->ready = $this->bind($bind_dn, $bind_pass);
}
else if (!empty($this->prop['auth_cid'])) {
- $this->ready = $this->ldap->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
+ $this->ready = $this->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
}
else {
- $this->ready = $this->ldap->sasl_bind($bind_user, $bind_pass);
+ $this->ready = $this->sasl_bind($bind_user, $bind_pass);
}
}
@@ -380,10 +346,10 @@ class rcube_ldap extends rcube_addressbook
} // end foreach hosts
- if (!is_resource($this->ldap->conn)) {
+ if (!is_resource($this->conn)) {
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Could not connect to any LDAP server, last tried $host"), true);
+ 'message' => "Could not connect to any LDAP server, last tried $hostname"), true);
return false;
}
@@ -393,47 +359,112 @@ class rcube_ldap extends rcube_addressbook
/**
- * Close connection to LDAP server
+ * Bind connection with (SASL-) user and password
+ *
+ * @param string $authc Authentication user
+ * @param string $pass Bind password
+ * @param string $authz Autorization user
+ *
+ * @return boolean True on success, False on error
*/
- function close()
+ public function sasl_bind($authc, $pass, $authz=null)
{
- if ($this->ldap) {
- $this->ldap->close();
+ if (!$this->conn) {
+ return false;
+ }
+
+ if (!function_exists('ldap_sasl_bind')) {
+ rcube::raise_error(array('code' => 100, 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Unable to bind: ldap_sasl_bind() not exists"),
+ true, true);
}
+
+ if (!empty($authz)) {
+ $authz = 'u:' . $authz;
+ }
+
+ if (!empty($this->prop['auth_method'])) {
+ $method = $this->prop['auth_method'];
+ }
+ else {
+ $method = 'DIGEST-MD5';
+ }
+
+ $this->_debug("C: Bind [mech: $method, authc: $authc, authz: $authz] [pass: $pass]");
+
+ if (ldap_sasl_bind($this->conn, NULL, $pass, $method, NULL, $authc, $authz)) {
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ $this->_debug("S: ".ldap_error($this->conn));
+
+ rcube::raise_error(array(
+ 'code' => ldap_errno($this->conn), 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Bind failed for authcid=$authc ".ldap_error($this->conn)),
+ true);
+
+ return false;
}
/**
- * Returns address book name
+ * Bind connection with DN and password
*
- * @return string Address book name
+ * @param string Bind DN
+ * @param string Bind password
+ *
+ * @return boolean True on success, False on error
*/
- function get_name()
+ public function bind($dn, $pass)
{
- return $this->prop['name'];
+ if (!$this->conn) {
+ return false;
+ }
+
+ $this->_debug("C: Bind [dn: $dn] [pass: $pass]");
+
+ if (@ldap_bind($this->conn, $dn, $pass)) {
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ $this->_debug("S: ".ldap_error($this->conn));
+
+ rcube::raise_error(array(
+ 'code' => ldap_errno($this->conn), 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Bind failed for dn=$dn: ".ldap_error($this->conn)),
+ true);
+
+ return false;
}
/**
- * Set internal list page
- *
- * @param number Page number to list
+ * Close connection to LDAP server
*/
- function set_page($page)
+ function close()
{
- $this->list_page = (int)$page;
- $this->ldap->set_vlv_page($this->list_page, $this->page_size);
+ if ($this->conn)
+ {
+ $this->_debug("C: Close");
+ ldap_unbind($this->conn);
+ $this->conn = null;
+ }
}
+
/**
- * Set internal page size
+ * Returns address book name
*
- * @param number Number of records to display on one page
+ * @return string Address book name
*/
- function set_pagesize($size)
+ function get_name()
{
- $this->page_size = (int)$size;
- $this->ldap->set_vlv_page($this->list_page, $this->page_size);
+ return $this->prop['name'];
}
@@ -493,14 +524,16 @@ class rcube_ldap extends rcube_addressbook
*/
function list_records($cols=null, $subset=0)
{
- if ($this->prop['searchonly'] && empty($this->filter) && !$this->group_id) {
+ if ($this->prop['searchonly'] && empty($this->filter) && !$this->group_id)
+ {
$this->result = new rcube_result_set(0);
$this->result->searchonly = true;
return $this->result;
}
// fetch group members recursively
- if ($this->group_id && $this->group_data['dn']) {
+ if ($this->group_id && $this->group_data['dn'])
+ {
$entries = $this->list_group_members($this->group_data['dn']);
// make list of entries unique and sort it
@@ -514,35 +547,34 @@ class rcube_ldap extends rcube_addressbook
$entries['count'] = count($entries);
$this->result = new rcube_result_set($entries['count'], ($this->list_page-1) * $this->page_size);
}
- else {
- $prop = $this->group_id ? $this->group_data : $this->prop;
- $base_dn = $this->group_id ? $this->group_base_dn : $this->base_dn;
-
- // use global search filter
- if (!empty($this->filter))
- $prop['filter'] = $this->filter;
+ else
+ {
+ // add general filter to query
+ if (!empty($this->prop['filter']) && empty($this->filter))
+ $this->set_search_set($this->prop['filter']);
// exec LDAP search if no result resource is stored
- if ($this->ready && !$this->ldap_result)
- $this->ldap_result = $this->ldap->search($base_dn, $prop['filter'], $prop['scope'], $this->prop['attributes'], $prop);
+ if ($this->conn && !$this->ldap_result)
+ $this->_exec_search();
// count contacts for this user
$this->result = $this->count();
// we have a search result resource
- if ($this->ldap_result && $this->result->count > 0) {
+ if ($this->ldap_result && $this->result->count > 0)
+ {
// sorting still on the ldap server
- if ($this->sort_col && $prop['scope'] !== 'base' && !$this->ldap->vlv_active)
- $this->ldap_result->sort($this->sort_col);
+ if ($this->sort_col && $this->prop['scope'] !== 'base' && !$this->vlv_active)
+ ldap_sort($this->conn, $this->ldap_result, $this->sort_col);
// get all entries from the ldap server
- $entries = $this->ldap_result->entries();
+ $entries = ldap_get_entries($this->conn, $this->ldap_result);
}
} // end else
// start and end of the page
- $start_row = $this->ldap->vlv_active ? 0 : $this->result->first;
+ $start_row = $this->vlv_active ? 0 : $this->result->first;
$start_row = $subset < 0 ? $start_row + $this->page_size + $subset : $start_row;
$last_row = $this->result->first + $this->page_size;
$last_row = $subset != 0 ? $start_row + abs($subset) : $last_row;
@@ -567,34 +599,43 @@ class rcube_ldap extends rcube_addressbook
// fetch group object
if (empty($entries)) {
- $attribs = array('dn','objectClass','member','uniqueMember','memberURL');
- $entries = $this->ldap->read_entries($dn, '(objectClass=*)', $attribs);
- if ($entries === false) {
+ $result = @ldap_read($this->conn, $dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL'));
+ if ($result === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
return $group_members;
}
+
+ $entries = @ldap_get_entries($this->conn, $result);
}
- for ($i=0; $i < $entries['count']; $i++) {
+ for ($i=0; $i < $entries['count']; $i++)
+ {
$entry = $entries[$i];
- $attrs = array();
- foreach ((array)$entry['objectclass'] as $objectclass) {
- if (strtolower($objectclass) == 'groupofurls') {
- $members = $this->_list_group_memberurl($dn, $entry, $count);
- $group_members = array_merge($group_members, $members);
- }
- else if (($member_attr = $this->get_group_member_attr(array($objectclass), ''))
- && ($member_attr = strtolower($member_attr)) && !in_array($member_attr, $attrs)
- ) {
- $members = $this->_list_group_members($dn, $entry, $member_attr, $count);
- $group_members = array_merge($group_members, $members);
- $attrs[] = $member_attr;
- }
+ if (empty($entry['objectclass']))
+ continue;
- if ($this->prop['sizelimit'] && count($group_members) > $this->prop['sizelimit']) {
- break 2;
+ foreach ((array)$entry['objectclass'] as $objectclass)
+ {
+ switch (strtolower($objectclass)) {
+ case "group":
+ case "groupofnames":
+ case "kolabgroupofnames":
+ $group_members = array_merge($group_members, $this->_list_group_members($dn, $entry, 'member', $count));
+ break;
+ case "groupofuniquenames":
+ case "kolabgroupofuniquenames":
+ $group_members = array_merge($group_members, $this->_list_group_members($dn, $entry, 'uniquemember', $count));
+ break;
+ case "groupofurls":
+ $group_members = array_merge($group_members, $this->_list_group_memberurl($dn, $entry, $count));
+ break;
}
}
+
+ if ($this->prop['sizelimit'] && count($group_members) > $this->prop['sizelimit'])
+ break;
}
return array_filter($group_members);
@@ -613,24 +654,28 @@ class rcube_ldap extends rcube_addressbook
// Use the member attributes to return an array of member ldap objects
// NOTE that the member attribute is supposed to contain a DN
$group_members = array();
- if (empty($entry[$attr])) {
+ if (empty($entry[$attr]))
return $group_members;
- }
// read these attributes for all members
- $attrib = $count ? array('dn','objectClass') : $this->prop['list_attributes'];
+ $attrib = $count ? array('dn') : array_values($this->fieldmap);
+ $attrib[] = 'objectClass';
$attrib[] = 'member';
$attrib[] = 'uniqueMember';
$attrib[] = 'memberURL';
- $filter = $this->prop['groups']['member_filter'] ? $this->prop['groups']['member_filter'] : '(objectclass=*)';
-
- for ($i=0; $i < $entry[$attr]['count']; $i++) {
+ for ($i=0; $i < $entry[$attr]['count']; $i++)
+ {
if (empty($entry[$attr][$i]))
continue;
- $members = $this->ldap->read_entries($entry[$attr][$i], $filter, $attrib);
- if ($members == false) {
+ $result = @ldap_read($this->conn, $entry[$attr][$i], '(objectclass=*)',
+ $attrib, 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit']);
+
+ $members = @ldap_get_entries($this->conn, $result);
+ if ($members == false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
$members = array();
}
@@ -656,22 +701,34 @@ class rcube_ldap extends rcube_addressbook
{
$group_members = array();
- for ($i=0; $i < $entry['memberurl']['count']; $i++) {
+ for ($i=0; $i < $entry['memberurl']['count']; $i++)
+ {
// extract components from url
if (!preg_match('!ldap:///([^\?]+)\?\?(\w+)\?(.*)$!', $entry['memberurl'][$i], $m))
continue;
// add search filter if any
$filter = $this->filter ? '(&(' . $m[3] . ')(' . $this->filter . '))' : $m[3];
- $attrs = $count ? array('dn','objectClass') : $this->prop['list_attributes'];
- if ($result = $this->ldap->search($m[1], $filter, $m[2], $attrs, $this->group_data)) {
- $entries = $result->entries();
- for ($j = 0; $j < $entries['count']; $j++) {
- if (self::is_group_entry($entries[$j]) && ($nested_group_members = $this->list_group_members($entries[$j]['dn'], $count)))
- $group_members = array_merge($group_members, $nested_group_members);
- else
- $group_members[] = $entries[$j];
- }
+ $func = $m[2] == 'sub' ? 'ldap_search' : ($m[2] == 'base' ? 'ldap_read' : 'ldap_list');
+
+ $attrib = $count ? array('dn') : array_values($this->fieldmap);
+ if ($result = @$func($this->conn, $m[1], $filter,
+ $attrib, 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit'])
+ ) {
+ $this->_debug("S: ".ldap_count_entries($this->conn, $result)." record(s) for ".$m[1]);
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return $group_members;
+ }
+
+ $entries = @ldap_get_entries($this->conn, $result);
+ for ($j = 0; $j < $entries['count']; $j++)
+ {
+ if ($nested_group_members = $this->list_group_members($entries[$j]['dn'], $count))
+ $group_members = array_merge($group_members, $nested_group_members);
+ else
+ $group_members[] = $entries[$j];
}
}
@@ -707,11 +764,14 @@ class rcube_ldap extends rcube_addressbook
$mode = intval($mode);
// special treatment for ID-based search
- if ($fields == 'ID' || $fields == $this->primary_key) {
+ if ($fields == 'ID' || $fields == $this->primary_key)
+ {
$ids = !is_array($value) ? explode(',', $value) : $value;
$result = new rcube_result_set();
- foreach ($ids as $id) {
- if ($rec = $this->get_record($id, true)) {
+ foreach ($ids as $id)
+ {
+ if ($rec = $this->get_record($id, true))
+ {
$result->add($rec);
$result->count++;
}
@@ -723,20 +783,34 @@ class rcube_ldap extends rcube_addressbook
$rcube = rcube::get_instance();
$list_fields = $rcube->config->get('contactlist_fields');
- if ($this->prop['vlv_search'] && $this->ready && join(',', (array)$fields) == join(',', $list_fields)) {
+ if ($this->prop['vlv_search'] && $this->conn && join(',', (array)$fields) == join(',', $list_fields))
+ {
+ // add general filter to query
+ if (!empty($this->prop['filter']) && empty($this->filter))
+ $this->set_search_set($this->prop['filter']);
+
+ // set VLV controls with encoded search string
+ $this->_vlv_set_controls($this->prop, $this->list_page, $this->page_size, $value);
+
+ $function = $this->_scope2func($this->prop['scope']);
+ $this->ldap_result = @$function($this->conn, $this->base_dn, $this->filter ? $this->filter : '(objectclass=*)',
+ array_values($this->fieldmap), 0, $this->page_size, (int)$this->prop['timelimit']);
+
$this->result = new rcube_result_set(0);
- $search_suffix = $this->prop['fuzzy_search'] && $mode != 1 ? '*' : '';
- $ldap_data = $this->ldap->search($this->base_dn, $this->prop['filter'], $this->prop['scope'], $this->prop['attributes'],
- array('search' => $value . $search_suffix /*, 'sort' => $this->prop['sort'] */));
- if ($ldap_data === false) {
+ if (!$this->ldap_result) {
+ $this->_debug("S: ".ldap_error($this->conn));
return $this->result;
}
+ $this->_debug("S: ".ldap_count_entries($this->conn, $this->ldap_result)." record(s)");
+
// get all entries of this page and post-filter those that really match the query
- $search = mb_strtolower($value);
- foreach ($ldap_data as $i => $entry) {
- $rec = $this->_ldap2result($entry);
+ $search = mb_strtolower($value);
+ $entries = ldap_get_entries($this->conn, $this->ldap_result);
+
+ for ($i = 0; $i < $entries['count']; $i++) {
+ $rec = $this->_ldap2result($entries[$i]);
foreach ($fields as $f) {
foreach ((array)$rec[$f] as $val) {
if ($this->compare_search_value($f, $val, $search, $mode)) {
@@ -762,27 +836,31 @@ class rcube_ldap extends rcube_addressbook
}
}
- if ($fields == '*') {
+ if ($fields == '*')
+ {
// search_fields are required for fulltext search
- if (empty($this->prop['search_fields'])) {
+ if (empty($this->prop['search_fields']))
+ {
$this->set_error(self::ERROR_SEARCH, 'nofulltextsearch');
$this->result = new rcube_result_set();
return $this->result;
}
- if (is_array($this->prop['search_fields'])) {
+ if (is_array($this->prop['search_fields']))
+ {
foreach ($this->prop['search_fields'] as $field) {
- $filter .= "($field=$wp" . rcube_ldap_generic::quote_string($value) . "$ws)";
+ $filter .= "($field=$wp" . $this->_quote_string($value) . "$ws)";
}
}
}
- else {
+ else
+ {
foreach ((array)$fields as $idx => $field) {
$val = is_array($value) ? $value[$idx] : $value;
if ($attrs = $this->_map_field($field)) {
if (count($attrs) > 1)
$filter .= '(|';
foreach ($attrs as $f)
- $filter .= "($f=$wp" . rcube_ldap_generic::quote_string($val) . "$ws)";
+ $filter .= "($f=$wp" . $this->_quote_string($val) . "$ws)";
if (count($attrs) > 1)
$filter .= ')';
}
@@ -817,6 +895,7 @@ class rcube_ldap extends rcube_addressbook
// set filter string and execute search
$this->set_search_set($filter);
+ $this->_exec_search();
if ($select)
$this->list_records();
@@ -835,21 +914,20 @@ class rcube_ldap extends rcube_addressbook
function count()
{
$count = 0;
- if ($this->ldap_result) {
- $count = $this->ldap_result->count();
+ if ($this->conn && $this->ldap_result) {
+ $count = $this->vlv_active ? $this->vlv_count : ldap_count_entries($this->conn, $this->ldap_result);
}
else if ($this->group_id && $this->group_data['dn']) {
$count = count($this->list_group_members($this->group_data['dn'], true));
}
- // We have a connection but no result set, attempt to get one.
- else if ($this->ready) {
- $prop = $this->group_id ? $this->group_data : $this->prop;
- $base_dn = $this->group_id ? $this->group_base_dn : $this->base_dn;
-
- if (!empty($this->filter)) { // Use global search filter
- $prop['filter'] = $this->filter;
+ else if ($this->conn) {
+ // We have a connection but no result set, attempt to get one.
+ if (empty($this->filter)) {
+ // The filter is not set, set it.
+ $this->filter = $this->prop['filter'];
}
- $count = $this->ldap->search($base_dn, $prop['filter'], $prop['scope'], array('dn'), $prop, true);
+
+ $count = (int) $this->_exec_search(true);
}
return new rcube_result_set($count, ($this->list_page-1) * $this->page_size);
@@ -879,16 +957,28 @@ class rcube_ldap extends rcube_addressbook
{
$res = $this->result = null;
- if ($this->ready && $dn) {
+ if ($this->conn && $dn)
+ {
$dn = self::dn_decode($dn);
- if ($rec = $this->ldap->get_entry($dn)) {
- $rec = array_change_key_case($rec, CASE_LOWER);
+ $this->_debug("C: Read [dn: $dn] [(objectclass=*)]");
+
+ if ($ldap_result = @ldap_read($this->conn, $dn, '(objectclass=*)', array_values($this->fieldmap))) {
+ $this->_debug("S: OK");
+
+ $entry = ldap_first_entry($this->conn, $ldap_result);
+
+ if ($entry && ($rec = ldap_get_attributes($this->conn, $entry))) {
+ $rec = array_change_key_case($rec, CASE_LOWER);
+ }
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
}
// Use ldap_list to get subentries like country (c) attribute (#1488123)
if (!empty($rec) && $this->sub_filter) {
- if ($entries = $this->ldap->list_entries($dn, $this->sub_filter, array_keys($this->prop['sub_fields']))) {
+ if ($entries = $this->ldap_list($dn, $this->sub_filter, array_keys($this->prop['sub_fields']))) {
foreach ($entries as $entry) {
$lrec = array_change_key_case($entry, CASE_LOWER);
$rec = array_merge($lrec, $rec);
@@ -900,7 +990,7 @@ class rcube_ldap extends rcube_addressbook
// Add in the dn for the entry.
$rec['dn'] = $dn;
$res = $this->_ldap2result($rec);
- $this->result = new rcube_result_set(1);
+ $this->result = new rcube_result_set();
$this->result->add($res);
}
}
@@ -947,6 +1037,7 @@ class rcube_ldap extends rcube_addressbook
$mail_field = $this->fieldmap['email'];
// try to extract surname and firstname from displayname
+ $reverse_map = array_flip($this->fieldmap);
$name_parts = preg_split('/[\s,.]+/', $save_data['name']);
if ($sn_field && $missing[$sn_field]) {
@@ -1013,12 +1104,12 @@ class rcube_ldap extends rcube_addressbook
}
// Build the new entries DN.
- $dn = $this->prop['LDAP_rdn'].'='.rcube_ldap_generic::quote_string($newentry[$this->prop['LDAP_rdn']], true).','.$this->base_dn;
+ $dn = $this->prop['LDAP_rdn'].'='.$this->_quote_string($newentry[$this->prop['LDAP_rdn']], true).','.$this->base_dn;
// Remove attributes that need to be added separately (child objects)
$xfields = array();
if (!empty($this->prop['sub_fields']) && is_array($this->prop['sub_fields'])) {
- foreach (array_keys($this->prop['sub_fields']) as $xf) {
+ foreach ($this->prop['sub_fields'] as $xf => $xclass) {
if (!empty($newentry[$xf])) {
$xfields[$xf] = $newentry[$xf];
unset($newentry[$xf]);
@@ -1026,19 +1117,19 @@ class rcube_ldap extends rcube_addressbook
}
}
- if (!$this->ldap->add($dn, $newentry)) {
+ if (!$this->ldap_add($dn, $newentry)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
foreach ($xfields as $xidx => $xf) {
- $xdn = $xidx.'='.rcube_ldap_generic::quote_string($xf).','.$dn;
+ $xdn = $xidx.'='.$this->_quote_string($xf).','.$dn;
$xf = array(
$xidx => $xf,
'objectClass' => (array) $this->prop['sub_fields'][$xidx],
);
- $this->ldap->add($xdn, $xf);
+ $this->ldap_add($xdn, $xf);
}
$dn = self::dn_encode($dn);
@@ -1081,7 +1172,7 @@ class rcube_ldap extends rcube_addressbook
}
}
- foreach ($this->fieldmap as $fld) {
+ foreach ($this->fieldmap as $col => $fld) {
if ($fld) {
$val = $ldap_data[$fld];
$old = $old_data[$fld];
@@ -1144,7 +1235,7 @@ class rcube_ldap extends rcube_addressbook
// Update the entry as required.
if (!empty($deletedata)) {
// Delete the fields.
- if (!$this->ldap->mod_del($dn, $deletedata)) {
+ if (!$this->ldap_mod_del($dn, $deletedata)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1154,17 +1245,17 @@ class rcube_ldap extends rcube_addressbook
// Handle RDN change
if ($replacedata[$this->prop['LDAP_rdn']]) {
$newdn = $this->prop['LDAP_rdn'].'='
- .rcube_ldap_generic::quote_string($replacedata[$this->prop['LDAP_rdn']], true)
+ .$this->_quote_string($replacedata[$this->prop['LDAP_rdn']], true)
.','.$this->base_dn;
if ($dn != $newdn) {
$newrdn = $this->prop['LDAP_rdn'].'='
- .rcube_ldap_generic::quote_string($replacedata[$this->prop['LDAP_rdn']], true);
+ .$this->_quote_string($replacedata[$this->prop['LDAP_rdn']], true);
unset($replacedata[$this->prop['LDAP_rdn']]);
}
}
// Replace the fields.
if (!empty($replacedata)) {
- if (!$this->ldap->mod_replace($dn, $replacedata)) {
+ if (!$this->ldap_mod_replace($dn, $replacedata)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1180,8 +1271,8 @@ class rcube_ldap extends rcube_addressbook
// remove sub-entries
if (!empty($subdeldata)) {
foreach ($subdeldata as $fld => $val) {
- $subdn = $fld.'='.rcube_ldap_generic::quote_string($val).','.$dn;
- if (!$this->ldap->delete($subdn)) {
+ $subdn = $fld.'='.$this->_quote_string($val).','.$dn;
+ if (!$this->ldap_delete($subdn)) {
return false;
}
}
@@ -1189,7 +1280,7 @@ class rcube_ldap extends rcube_addressbook
if (!empty($newdata)) {
// Add the fields.
- if (!$this->ldap->mod_add($dn, $newdata)) {
+ if (!$this->ldap_mod_add($dn, $newdata)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1197,7 +1288,7 @@ class rcube_ldap extends rcube_addressbook
// Handle RDN change
if (!empty($newrdn)) {
- if (!$this->ldap->rename($dn, $newrdn, null, true)) {
+ if (!$this->ldap_rename($dn, $newrdn, null, true)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1208,7 +1299,8 @@ class rcube_ldap extends rcube_addressbook
// change the group membership of the contact
if ($this->groups) {
$group_ids = $this->get_record_groups($dn);
- foreach (array_keys($group_ids) as $group_id) {
+ foreach ($group_ids as $group_id)
+ {
$this->remove_from_group($group_id, $dn);
$this->add_to_group($group_id, $newdn);
}
@@ -1220,12 +1312,12 @@ class rcube_ldap extends rcube_addressbook
// add sub-entries
if (!empty($subnewdata)) {
foreach ($subnewdata as $fld => $val) {
- $subdn = $fld.'='.rcube_ldap_generic::quote_string($val).','.$dn;
+ $subdn = $fld.'='.$this->_quote_string($val).','.$dn;
$xf = array(
$fld => $val,
'objectClass' => (array) $this->prop['sub_fields'][$fld],
);
- $this->ldap->add($subdn, $xf);
+ $this->ldap_add($subdn, $xf);
}
}
@@ -1253,9 +1345,9 @@ class rcube_ldap extends rcube_addressbook
// Need to delete all sub-entries first
if ($this->sub_filter) {
- if ($entries = $this->ldap->list_entries($dn, $this->sub_filter)) {
+ if ($entries = $this->ldap_list($dn, $this->sub_filter)) {
foreach ($entries as $entry) {
- if (!$this->ldap->delete($entry['dn'])) {
+ if (!$this->ldap_delete($entry['dn'])) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1264,7 +1356,7 @@ class rcube_ldap extends rcube_addressbook
}
// Delete the record.
- if (!$this->ldap->delete($dn)) {
+ if (!$this->ldap_delete($dn)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1273,7 +1365,7 @@ class rcube_ldap extends rcube_addressbook
if ($this->groups) {
$dn = self::dn_encode($dn);
$group_ids = $this->get_record_groups($dn);
- foreach (array_keys($group_ids) as $group_id) {
+ foreach ($group_ids as $group_id) {
$this->remove_from_group($group_id, $dn);
}
}
@@ -1288,8 +1380,8 @@ class rcube_ldap extends rcube_addressbook
*/
function delete_all()
{
- // searching for contact entries
- $dn_list = $this->ldap->list_entries($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)');
+ //searching for contact entries
+ $dn_list = $this->ldap_list($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)');
if (!empty($dn_list)) {
foreach ($dn_list as $idx => $entry) {
@@ -1306,10 +1398,6 @@ class rcube_ldap extends rcube_addressbook
*/
protected function add_autovalues(&$attrs)
{
- if (empty($this->prop['autovalues'])) {
- return;
- }
-
$attrvals = array();
foreach ($attrs as $k => $v) {
$attrvals['{'.$k.'}'] = is_array($v) ? $v[0] : $v;
@@ -1320,16 +1408,7 @@ class rcube_ldap extends rcube_addressbook
if (strpos($templ, '(') !== false) {
// replace {attr} placeholders with (escaped!) attribute values to be safely eval'd
$code = preg_replace('/\{\w+\}/', '', strtr($templ, array_map('addslashes', $attrvals)));
- $fn = create_function('', "return ($code);");
- if (!$fn) {
- rcube::raise_error(array(
- 'code' => 505, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Expression parse error on: ($code)"), true, false);
- continue;
- }
-
- $attrs[$lf] = $fn();
+ $attrs[$lf] = eval("return ($code);");
}
else {
// replace {attr} placeholders with concrete attribute values
@@ -1339,26 +1418,120 @@ class rcube_ldap extends rcube_addressbook
}
}
+ /**
+ * Execute the LDAP search based on the stored credentials
+ */
+ private function _exec_search($count = false)
+ {
+ if ($this->ready)
+ {
+ $filter = $this->filter ? $this->filter : '(objectclass=*)';
+ $function = $this->_scope2func($this->prop['scope'], $ns_function);
+
+ $this->_debug("C: Search [$filter][dn: $this->base_dn]");
+
+ // when using VLV, we get the total count by...
+ if (!$count && $function != 'ldap_read' && $this->prop['vlv'] && !$this->group_id) {
+ // ...either reading numSubOrdinates attribute
+ if ($this->prop['numsub_filter'] && ($result_count = @$ns_function($this->conn, $this->base_dn, $this->prop['numsub_filter'], array('numSubOrdinates'), 0, 0, 0))) {
+ $counts = ldap_get_entries($this->conn, $result_count);
+ for ($this->vlv_count = $j = 0; $j < $counts['count']; $j++)
+ $this->vlv_count += $counts[$j]['numsubordinates'][0];
+ $this->_debug("D: total numsubordinates = " . $this->vlv_count);
+ }
+ else if (!function_exists('ldap_parse_virtuallist_control')) // ...or by fetching all records dn and count them
+ $this->vlv_count = $this->_exec_search(true);
+
+ $this->vlv_active = $this->_vlv_set_controls($this->prop, $this->list_page, $this->page_size);
+ }
+
+ // only fetch dn for count (should keep the payload low)
+ $attrs = $count ? array('dn') : array_values($this->fieldmap);
+ if ($this->ldap_result = @$function($this->conn, $this->base_dn, $filter,
+ $attrs, 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit'])
+ ) {
+ // when running on a patched PHP we can use the extended functions to retrieve the total count from the LDAP search result
+ if ($this->vlv_active && function_exists('ldap_parse_virtuallist_control')) {
+ if (ldap_parse_result($this->conn, $this->ldap_result,
+ $errcode, $matcheddn, $errmsg, $referrals, $serverctrls)
+ && $serverctrls // can be null e.g. in case of adm. limit error
+ ) {
+ ldap_parse_virtuallist_control($this->conn, $serverctrls,
+ $last_offset, $this->vlv_count, $vresult);
+ $this->_debug("S: VLV result: last_offset=$last_offset; content_count=$this->vlv_count");
+ }
+ else {
+ $this->_debug("S: ".($errmsg ? $errmsg : ldap_error($this->conn)));
+ }
+ }
+
+ $entries_count = ldap_count_entries($this->conn, $this->ldap_result);
+ $this->_debug("S: $entries_count record(s)");
+
+ return $count ? $entries_count : true;
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Choose the right PHP function according to scope property
+ */
+ private function _scope2func($scope, &$ns_function = null)
+ {
+ switch ($scope) {
+ case 'sub':
+ $function = $ns_function = 'ldap_search';
+ break;
+ case 'base':
+ $function = $ns_function = 'ldap_read';
+ break;
+ default:
+ $function = 'ldap_list';
+ $ns_function = 'ldap_read';
+ break;
+ }
+
+ return $function;
+ }
+
+ /**
+ * Set server controls for Virtual List View (paginated listing)
+ */
+ private function _vlv_set_controls($prop, $list_page, $page_size, $search = null)
+ {
+ $sort_ctrl = array('oid' => "1.2.840.113556.1.4.473", 'value' => $this->_sort_ber_encode((array)$prop['sort']));
+ $vlv_ctrl = array('oid' => "2.16.840.1.113730.3.4.9", 'value' => $this->_vlv_ber_encode(($offset = ($list_page-1) * $page_size + 1), $page_size, $search), 'iscritical' => true);
+
+ $sort = (array)$prop['sort'];
+ $this->_debug("C: set controls sort=" . join(' ', unpack('H'.(strlen($sort_ctrl['value'])*2), $sort_ctrl['value'])) . " ($sort[0]);"
+ . " vlv=" . join(' ', (unpack('H'.(strlen($vlv_ctrl['value'])*2), $vlv_ctrl['value']))) . " ($offset/$page_size)");
+
+ if (!ldap_set_option($this->conn, LDAP_OPT_SERVER_CONTROLS, array($sort_ctrl, $vlv_ctrl))) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SEARCH, 'vlvnotsupported');
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Converts LDAP entry into an array
*/
private function _ldap2result($rec)
{
- $out = array('_type' => 'person');
- $fieldmap = $this->fieldmap;
+ $out = array();
if ($rec['dn'])
$out[$this->primary_key] = self::dn_encode($rec['dn']);
- // determine record type
- if (self::is_group_entry($rec)) {
- $out['_type'] = 'group';
- $out['readonly'] = true;
- $fieldmap['name'] = $this->group_data['name_attr'] ? $this->group_data['name_attr'] : $this->prop['groups']['name_attr'];
- }
-
- foreach ($fieldmap as $rf => $lf)
+ foreach ($this->fieldmap as $rf => $lf)
{
for ($i=0; $i < $rec[$lf]['count']; $i++) {
if (!($value = $rec[$lf][$i]))
@@ -1420,10 +1593,8 @@ class rcube_ldap extends rcube_addressbook
if (is_array($colprop['serialized'])) {
foreach ($colprop['serialized'] as $subtype => $delim) {
$key = $col.':'.$subtype;
- foreach ((array)$save_cols[$key] as $i => $val) {
- $values = array($val['street'], $val['locality'], $val['zipcode'], $val['country']);
- $save_cols[$key][$i] = count(array_filter($values)) ? join($delim, $values) : null;
- }
+ foreach ((array)$save_cols[$key] as $i => $val)
+ $save_cols[$key][$i] = join($delim, array($val['street'], $val['locality'], $val['zipcode'], $val['country']));
}
}
}
@@ -1461,11 +1632,11 @@ class rcube_ldap extends rcube_addressbook
{
// list of known attribute aliases
static $aliases = array(
- 'gn' => 'givenname',
+ 'gn' => 'givenname',
'rfc822mailbox' => 'email',
- 'userid' => 'uid',
- 'emailaddress' => 'email',
- 'pkcs9email' => 'email',
+ 'userid' => 'uid',
+ 'emailaddress' => 'email',
+ 'pkcs9email' => 'email',
);
list($name, $limit) = explode(':', $namev, 2);
@@ -1474,15 +1645,6 @@ class rcube_ldap extends rcube_addressbook
return (isset($aliases[$name]) ? $aliases[$name] : $name) . $suffix;
}
- /**
- * Determines whether the given LDAP entry is a group record
- */
- private static function is_group_entry($entry)
- {
- $classes = array_map('strtolower', (array)$entry['objectclass']);
-
- return count(array_intersect(array_keys(self::$group_types), $classes)) > 0;
- }
/**
* Prints debug info to the log
@@ -1499,27 +1661,55 @@ class rcube_ldap extends rcube_addressbook
* Activate/deactivate debug mode
*
* @param boolean $dbg True if LDAP commands should be logged
+ * @access public
*/
function set_debug($dbg = true)
{
$this->debug = $dbg;
+ }
- if ($this->ldap) {
- $this->ldap->set_debug($dbg);
- }
+
+ /**
+ * Quotes attribute value string
+ *
+ * @param string $str Attribute value
+ * @param bool $dn True if the attribute is a DN
+ *
+ * @return string Quoted string
+ */
+ private static function _quote_string($str, $dn=false)
+ {
+ // take firt entry if array given
+ if (is_array($str))
+ $str = reset($str);
+
+ if ($dn)
+ $replace = array(','=>'\2c', '='=>'\3d', '+'=>'\2b', '<'=>'\3c',
+ '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c', '"'=>'\22', '#'=>'\23');
+ else
+ $replace = array('*'=>'\2a', '('=>'\28', ')'=>'\29', '\\'=>'\5c',
+ '/'=>'\2f');
+
+ return strtr($str, $replace);
}
/**
* Setter for the current group
+ * (empty, has to be re-implemented by extending class)
*/
function set_group($group_id)
{
- if ($group_id) {
+ if ($group_id)
+ {
+ if (($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
+
$this->group_id = $group_id;
- $this->group_data = $this->get_group_entry($group_id);
+ $this->group_data = $group_cache[$group_id];
}
- else {
+ else
+ {
$this->group_id = 0;
$this->group_data = null;
}
@@ -1538,13 +1728,15 @@ class rcube_ldap extends rcube_addressbook
*/
function list_groups($search = null, $mode = 0)
{
- if (!$this->groups) {
+ if (!$this->groups)
return array();
- }
- $group_cache = $this->_fetch_groups();
- $groups = array();
+ // use cached list for searching
+ $this->cache->expunge();
+ if (!$search || ($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
+ $groups = array();
if ($search) {
foreach ($group_cache as $group) {
if ($this->compare_search_value('name', $group['name'], $search, $mode)) {
@@ -1552,9 +1744,8 @@ class rcube_ldap extends rcube_addressbook
}
}
}
- else {
+ else
$groups = $group_cache;
- }
return array_values($groups);
}
@@ -1562,140 +1753,80 @@ class rcube_ldap extends rcube_addressbook
/**
* Fetch groups from server
*/
- private function _fetch_groups($vlv_page = null)
+ private function _fetch_groups($vlv_page = 0)
{
- // special case: list groups from 'group_filters' config
- if ($vlv_page === null && !empty($this->prop['group_filters'])) {
- $groups = array();
-
- // list regular groups configuration as special filter
- if (!empty($this->prop['groups']['filter'])) {
- $id = '__groups__';
- $groups[$id] = array('ID' => $id, 'name' => rcube_label('groups'), 'virtual' => true) + $this->prop['groups'];
- }
-
- foreach ($this->prop['group_filters'] as $id => $prop) {
- $groups[$id] = $prop + array('ID' => $id, 'name' => ucfirst($id), 'virtual' => true, 'base_dn' => $this->base_dn);
- }
-
- return $groups;
- }
-
- if ($this->cache && $vlv_page === null && ($groups = $this->cache->get('groups')) !== null) {
- return $groups;
- }
-
- $base_dn = $this->groups_base_dn;
- $filter = $this->prop['groups']['filter'];
- $scope = $this->prop['groups']['scope'];
- $name_attr = $this->prop['groups']['name_attr'];
+ $base_dn = $this->groups_base_dn;
+ $filter = $this->prop['groups']['filter'];
+ $name_attr = $this->prop['groups']['name_attr'];
$email_attr = $this->prop['groups']['email_attr'] ? $this->prop['groups']['email_attr'] : 'mail';
$sort_attrs = $this->prop['groups']['sort'] ? (array)$this->prop['groups']['sort'] : array($name_attr);
- $sort_attr = $sort_attrs[0];
+ $sort_attr = $sort_attrs[0];
- $ldap = $this->ldap;
+ $this->_debug("C: Search [$filter][dn: $base_dn]");
// use vlv to list groups
if ($this->prop['groups']['vlv']) {
$page_size = 200;
- if (!$this->prop['groups']['sort']) {
+ if (!$this->prop['groups']['sort'])
$this->prop['groups']['sort'] = $sort_attrs;
- }
-
- $ldap = clone $this->ldap;
- $ldap->set_config($this->prop['groups']);
- $ldap->set_vlv_page($vlv_page+1, $page_size);
+ $vlv_active = $this->_vlv_set_controls($this->prop['groups'], $vlv_page+1, $page_size);
}
- $attrs = array_unique(array('dn', 'objectClass', $name_attr, $email_attr, $sort_attr));
- $ldap_data = $ldap->search($base_dn, $filter, $scope, $attrs, $this->prop['groups']);
-
- if ($ldap_data === false) {
+ $function = $this->_scope2func($this->prop['groups']['scope'], $ns_function);
+ $res = @$function($this->conn, $base_dn, $filter, array_unique(array('dn', 'objectClass', $name_attr, $email_attr, $sort_attr)));
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
return array();
}
- $groups = array();
- $group_sortnames = array();
- $group_count = $ldap_data->count();
-
- foreach ($ldap_data as $entry) {
- if (!$entry['dn']) // DN is mandatory
- $entry['dn'] = $ldap_data->get_dn();
+ $ldap_data = ldap_get_entries($this->conn, $res);
+ $this->_debug("S: ".ldap_count_entries($this->conn, $res)." record(s)");
- $group_name = is_array($entry[$name_attr]) ? $entry[$name_attr][0] : $entry[$name_attr];
- $group_id = self::dn_encode($entry['dn']);
+ $groups = array();
+ $group_sortnames = array();
+ $group_count = $ldap_data["count"];
+ for ($i=0; $i < $group_count; $i++)
+ {
+ $group_name = is_array($ldap_data[$i][$name_attr]) ? $ldap_data[$i][$name_attr][0] : $ldap_data[$i][$name_attr];
+ $group_id = self::dn_encode($group_name);
$groups[$group_id]['ID'] = $group_id;
- $groups[$group_id]['dn'] = $entry['dn'];
+ $groups[$group_id]['dn'] = $ldap_data[$i]['dn'];
$groups[$group_id]['name'] = $group_name;
- $groups[$group_id]['member_attr'] = $this->get_group_member_attr($entry['objectclass']);
+ $groups[$group_id]['member_attr'] = $this->get_group_member_attr($ldap_data[$i]['objectclass']);
// list email attributes of a group
- for ($j=0; $entry[$email_attr] && $j < $entry[$email_attr]['count']; $j++) {
- if (strpos($entry[$email_attr][$j], '@') > 0)
- $groups[$group_id]['email'][] = $entry[$email_attr][$j];
+ for ($j=0; $ldap_data[$i][$email_attr] && $j < $ldap_data[$i][$email_attr]['count']; $j++) {
+ if (strpos($ldap_data[$i][$email_attr][$j], '@') > 0)
+ $groups[$group_id]['email'][] = $ldap_data[$i][$email_attr][$j];
}
- $group_sortnames[] = mb_strtolower($entry[$sort_attr][0]);
+ $group_sortnames[] = mb_strtolower($ldap_data[$i][$sort_attr][0]);
}
// recursive call can exit here
- if ($vlv_page > 0) {
+ if ($vlv_page > 0)
return $groups;
- }
// call recursively until we have fetched all groups
- while ($this->prop['groups']['vlv'] && $group_count == $page_size) {
- $next_page = $this->_fetch_groups(++$vlv_page);
- $groups = array_merge($groups, $next_page);
+ while ($vlv_active && $group_count == $page_size)
+ {
+ $next_page = $this->_fetch_groups(++$vlv_page);
+ $groups = array_merge($groups, $next_page);
$group_count = count($next_page);
}
// when using VLV the list of groups is already sorted
- if (!$this->prop['groups']['vlv']) {
+ if (!$this->prop['groups']['vlv'])
array_multisort($group_sortnames, SORT_ASC, SORT_STRING, $groups);
- }
// cache this
- if ($this->cache) {
- $this->cache->set('groups', $groups);
- }
+ $this->cache->set('groups', $groups);
return $groups;
}
/**
- * Fetch a group entry from LDAP and save in local cache
- */
- private function get_group_entry($group_id)
- {
- $group_cache = $this->_fetch_groups();
-
- // add group record to cache if it isn't yet there
- if (!isset($group_cache[$group_id])) {
- $name_attr = $this->prop['groups']['name_attr'];
- $dn = self::dn_decode($group_id);
-
- if ($list = $this->ldap->read_entries($dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL',$name_attr,$this->fieldmap['email']))) {
- $entry = $list[0];
- $group_name = is_array($entry[$name_attr]) ? $entry[$name_attr][0] : $entry[$name_attr];
- $group_cache[$group_id]['ID'] = $group_id;
- $group_cache[$group_id]['dn'] = $dn;
- $group_cache[$group_id]['name'] = $group_name;
- $group_cache[$group_id]['member_attr'] = $this->get_group_member_attr($entry['objectclass']);
- }
- else {
- $group_cache[$group_id] = false;
- }
-
- if ($this->cache) {
- $this->cache->set('groups', $group_cache);
- }
- }
-
- return $group_cache[$group_id];
- }
-
- /**
* Get group properties such as name and email address(es)
*
* @param string Group identifier
@@ -1703,7 +1834,10 @@ class rcube_ldap extends rcube_addressbook
*/
function get_group($group_id)
{
- $group_data = $this->get_group_entry($group_id);
+ if (($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
+
+ $group_data = $group_cache[$group_id];
unset($group_data['dn'], $group_data['member_attr']);
return $group_data;
@@ -1717,24 +1851,24 @@ class rcube_ldap extends rcube_addressbook
*/
function create_group($group_name)
{
- $new_dn = 'cn=' . rcube_ldap_generic::quote_string($group_name, true) . ',' . $this->groups_base_dn;
- $new_gid = self::dn_encode($new_dn);
+ $base_dn = $this->groups_base_dn;
+ $new_dn = "cn=$group_name,$base_dn";
+ $new_gid = self::dn_encode($group_name);
$member_attr = $this->get_group_member_attr();
- $name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn';
- $new_entry = array(
+ $name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn';
+
+ $new_entry = array(
'objectClass' => $this->prop['groups']['object_classes'],
$name_attr => $group_name,
$member_attr => '',
);
- if (!$this->ldap->add($new_dn, $new_entry)) {
+ if (!$this->ldap_add($new_dn, $new_entry)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- if ($this->cache) {
- $this->cache->remove('groups');
- }
+ $this->cache->remove('groups');
return array('id' => $new_gid, 'name' => $group_name);
}
@@ -1747,18 +1881,19 @@ class rcube_ldap extends rcube_addressbook
*/
function delete_group($group_id)
{
- $group_cache = $this->_fetch_groups();
- $del_dn = $group_cache[$group_id]['dn'];
+ if (($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
- if (!$this->ldap->delete($del_dn)) {
+ $base_dn = $this->groups_base_dn;
+ $group_name = $group_cache[$group_id]['name'];
+ $del_dn = "cn=$group_name,$base_dn";
+
+ if (!$this->ldap_delete($del_dn)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- if ($this->cache) {
- unset($group_cache[$group_id]);
- $this->cache->set('groups', $group_cache);
- }
+ $this->cache->remove('groups');
return true;
}
@@ -1773,19 +1908,21 @@ class rcube_ldap extends rcube_addressbook
*/
function rename_group($group_id, $new_name, &$new_gid)
{
- $group_cache = $this->_fetch_groups();
- $old_dn = $group_cache[$group_id]['dn'];
- $new_rdn = "cn=" . rcube_ldap_generic::quote_string($new_name, true);
- $new_gid = self::dn_encode($new_rdn . ',' . $this->groups_base_dn);
+ if (($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
+
+ $base_dn = $this->groups_base_dn;
+ $group_name = $group_cache[$group_id]['name'];
+ $old_dn = "cn=$group_name,$base_dn";
+ $new_rdn = "cn=$new_name";
+ $new_gid = self::dn_encode($new_name);
- if (!$this->ldap->rename($old_dn, $new_rdn, null, true)) {
+ if (!$this->ldap_rename($old_dn, $new_rdn, null, true)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- if ($this->cache) {
- $this->cache->remove('groups');
- }
+ $this->cache->remove('groups');
return $new_name;
}
@@ -1800,27 +1937,27 @@ class rcube_ldap extends rcube_addressbook
*/
function add_to_group($group_id, $contact_ids)
{
- $group_cache = $this->_fetch_groups();
- $member_attr = $group_cache[$group_id]['member_attr'];
- $group_dn = $group_cache[$group_id]['dn'];
- $new_attrs = array();
+ if (($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
- if (!is_array($contact_ids)) {
+ if (!is_array($contact_ids))
$contact_ids = explode(',', $contact_ids);
- }
- foreach ($contact_ids as $id) {
+ $base_dn = $this->groups_base_dn;
+ $group_name = $group_cache[$group_id]['name'];
+ $member_attr = $group_cache[$group_id]['member_attr'];
+ $group_dn = "cn=$group_name,$base_dn";
+ $new_attrs = array();
+
+ foreach ($contact_ids as $id)
$new_attrs[$member_attr][] = self::dn_decode($id);
- }
- if (!$this->ldap->mod_add($group_dn, $new_attrs)) {
+ if (!$this->ldap_mod_add($group_dn, $new_attrs)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return 0;
}
- if ($this->cache) {
- $this->cache->remove('groups');
- }
+ $this->cache->remove('groups');
return count($new_attrs[$member_attr]);
}
@@ -1835,27 +1972,27 @@ class rcube_ldap extends rcube_addressbook
*/
function remove_from_group($group_id, $contact_ids)
{
- $group_cache = $this->_fetch_groups();
- $member_attr = $group_cache[$group_id]['member_attr'];
- $group_dn = $group_cache[$group_id]['dn'];
- $del_attrs = array();
+ if (($group_cache = $this->cache->get('groups')) === null)
+ $group_cache = $this->_fetch_groups();
- if (!is_array($contact_ids)) {
+ if (!is_array($contact_ids))
$contact_ids = explode(',', $contact_ids);
- }
- foreach ($contact_ids as $id) {
+ $base_dn = $this->groups_base_dn;
+ $group_name = $group_cache[$group_id]['name'];
+ $member_attr = $group_cache[$group_id]['member_attr'];
+ $group_dn = "cn=$group_name,$base_dn";
+ $del_attrs = array();
+
+ foreach ($contact_ids as $id)
$del_attrs[$member_attr][] = self::dn_decode($id);
- }
- if (!$this->ldap->mod_del($group_dn, $del_attrs)) {
+ if (!$this->ldap_mod_del($group_dn, $del_attrs)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return 0;
}
- if ($this->cache) {
- $this->cache->remove('groups');
- }
+ $this->cache->remove('groups');
return count($del_attrs[$member_attr]);
}
@@ -1870,63 +2007,206 @@ class rcube_ldap extends rcube_addressbook
*/
function get_record_groups($contact_id)
{
- if (!$this->groups) {
+ if (!$this->groups)
return array();
- }
$base_dn = $this->groups_base_dn;
$contact_dn = self::dn_decode($contact_id);
$name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn';
$member_attr = $this->get_group_member_attr();
$add_filter = '';
-
if ($member_attr != 'member' && $member_attr != 'uniqueMember')
$add_filter = "($member_attr=$contact_dn)";
$filter = strtr("(|(member=$contact_dn)(uniqueMember=$contact_dn)$add_filter)", array('\\' => '\\\\'));
- $ldap_data = $this->ldap->search($base_dn, $filter, 'sub', array('dn', $name_attr));
- if ($res === false) {
+ $this->_debug("C: Search [$filter][dn: $base_dn]");
+
+ $res = @ldap_search($this->conn, $base_dn, $filter, array($name_attr));
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
return array();
}
+ $ldap_data = ldap_get_entries($this->conn, $res);
+ $this->_debug("S: ".ldap_count_entries($this->conn, $res)." record(s)");
$groups = array();
- foreach ($ldap_data as $entry) {
- if (!$entry['dn'])
- $entry['dn'] = $ldap_data->get_dn();
- $group_name = $entry[$name_attr][0];
- $group_id = self::dn_encode($entry['dn']);
- $groups[$group_id] = $group_name;
+ for ($i=0; $i<$ldap_data["count"]; $i++)
+ {
+ $group_name = $ldap_data[$i][$name_attr][0];
+ $group_id = self::dn_encode($group_name);
+ $groups[$group_id] = $group_id;
}
-
return $groups;
}
/**
* Detects group member attribute name
*/
- private function get_group_member_attr($object_classes = array(), $default = 'member')
+ private function get_group_member_attr($object_classes = array())
{
if (empty($object_classes)) {
$object_classes = $this->prop['groups']['object_classes'];
}
-
if (!empty($object_classes)) {
foreach ((array)$object_classes as $oc) {
- if ($attr = self::$group_types[strtolower($oc)]) {
- return $attr;
+ switch (strtolower($oc)) {
+ case 'group':
+ case 'groupofnames':
+ case 'kolabgroupofnames':
+ $member_attr = 'member';
+ break;
+
+ case 'groupofuniquenames':
+ case 'kolabgroupofuniquenames':
+ $member_attr = 'uniqueMember';
+ break;
}
}
}
+ if (!empty($member_attr)) {
+ return $member_attr;
+ }
+
if (!empty($this->prop['groups']['member_attr'])) {
return $this->prop['groups']['member_attr'];
}
- return $default;
+ return 'member';
}
/**
+ * Generate BER encoded string for Virtual List View option
+ *
+ * @param integer List offset (first record)
+ * @param integer Records per page
+ * @return string BER encoded option value
+ */
+ private function _vlv_ber_encode($offset, $rpp, $search = '')
+ {
+ # this string is ber-encoded, php will prefix this value with:
+ # 04 (octet string) and 10 (length of 16 bytes)
+ # the code behind this string is broken down as follows:
+ # 30 = ber sequence with a length of 0e (14) bytes following
+ # 02 = type integer (in two's complement form) with 2 bytes following (beforeCount): 01 00 (ie 0)
+ # 02 = type integer (in two's complement form) with 2 bytes following (afterCount): 01 18 (ie 25-1=24)
+ # a0 = type context-specific/constructed with a length of 06 (6) bytes following
+ # 02 = type integer with 2 bytes following (offset): 01 01 (ie 1)
+ # 02 = type integer with 2 bytes following (contentCount): 01 00
+
+ # whith a search string present:
+ # 81 = type context-specific/constructed with a length of 04 (4) bytes following (the length will change here)
+ # 81 indicates a user string is present where as a a0 indicates just a offset search
+ # 81 = type context-specific/constructed with a length of 06 (6) bytes following
+
+ # the following info was taken from the ISO/IEC 8825-1:2003 x.690 standard re: the
+ # encoding of integer values (note: these values are in
+ # two-complement form so since offset will never be negative bit 8 of the
+ # leftmost octet should never by set to 1):
+ # 8.3.2: If the contents octets of an integer value encoding consist
+ # of more than one octet, then the bits of the first octet (rightmost) and bit 8
+ # of the second (to the left of first octet) octet:
+ # a) shall not all be ones; and
+ # b) shall not all be zero
+
+ if ($search)
+ {
+ $search = preg_replace('/[^-[:alpha:] ,.()0-9]+/', '', $search);
+ $ber_val = self::_string2hex($search);
+ $str = self::_ber_addseq($ber_val, '81');
+ }
+ else
+ {
+ # construct the string from right to left
+ $str = "020100"; # contentCount
+
+ $ber_val = self::_ber_encode_int($offset); // returns encoded integer value in hex format
+
+ // calculate octet length of $ber_val
+ $str = self::_ber_addseq($ber_val, '02') . $str;
+
+ // now compute length over $str
+ $str = self::_ber_addseq($str, 'a0');
+ }
+
+ // now tack on records per page
+ $str = "020100" . self::_ber_addseq(self::_ber_encode_int($rpp-1), '02') . $str;
+
+ // now tack on sequence identifier and length
+ $str = self::_ber_addseq($str, '30');
+
+ return pack('H'.strlen($str), $str);
+ }
+
+
+ /**
+ * create ber encoding for sort control
+ *
+ * @param array List of cols to sort by
+ * @return string BER encoded option value
+ */
+ private function _sort_ber_encode($sortcols)
+ {
+ $str = '';
+ foreach (array_reverse((array)$sortcols) as $col) {
+ $ber_val = self::_string2hex($col);
+
+ # 30 = ber sequence with a length of octet value
+ # 04 = octet string with a length of the ascii value
+ $oct = self::_ber_addseq($ber_val, '04');
+ $str = self::_ber_addseq($oct, '30') . $str;
+ }
+
+ // now tack on sequence identifier and length
+ $str = self::_ber_addseq($str, '30');
+
+ return pack('H'.strlen($str), $str);
+ }
+
+ /**
+ * Add BER sequence with correct length and the given identifier
+ */
+ private static function _ber_addseq($str, $identifier)
+ {
+ $len = dechex(strlen($str)/2);
+ if (strlen($len) % 2 != 0)
+ $len = '0'.$len;
+
+ return $identifier . $len . $str;
+ }
+
+ /**
+ * Returns BER encoded integer value in hex format
+ */
+ private static function _ber_encode_int($offset)
+ {
+ $val = dechex($offset);
+ $prefix = '';
+
+ // check if bit 8 of high byte is 1
+ if (preg_match('/^[89abcdef]/', $val))
+ $prefix = '00';
+
+ if (strlen($val)%2 != 0)
+ $prefix .= '0';
+
+ return $prefix . $val;
+ }
+
+ /**
+ * Returns ascii string encoded in hex
+ */
+ private static function _string2hex($str)
+ {
+ $hex = '';
+ for ($i=0; $i < strlen($str); $i++)
+ $hex .= dechex(ord($str[$i]));
+ return $hex;
+ }
+
+ /**
* HTML-safe DN string encoding
*
* @param string $str DN string
@@ -1953,4 +2233,130 @@ class rcube_ldap extends rcube_addressbook
return base64_decode($str);
}
+ /**
+ * Wrapper for ldap_add()
+ */
+ protected function ldap_add($dn, $entry)
+ {
+ $this->_debug("C: Add [dn: $dn]: ".print_r($entry, true));
+
+ $res = ldap_add($this->conn, $dn, $entry);
+ if ($res === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_delete()
+ */
+ protected function ldap_delete($dn)
+ {
+ $this->_debug("C: Delete [dn: $dn]");
+
+ $res = ldap_delete($this->conn, $dn);
+ if ($res === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_mod_replace()
+ */
+ protected function ldap_mod_replace($dn, $entry)
+ {
+ $this->_debug("C: Replace [dn: $dn]: ".print_r($entry, true));
+
+ if (!ldap_mod_replace($this->conn, $dn, $entry)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_mod_add()
+ */
+ protected function ldap_mod_add($dn, $entry)
+ {
+ $this->_debug("C: Add [dn: $dn]: ".print_r($entry, true));
+
+ if (!ldap_mod_add($this->conn, $dn, $entry)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_mod_del()
+ */
+ protected function ldap_mod_del($dn, $entry)
+ {
+ $this->_debug("C: Delete [dn: $dn]: ".print_r($entry, true));
+
+ if (!ldap_mod_del($this->conn, $dn, $entry)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_rename()
+ */
+ protected function ldap_rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true)
+ {
+ $this->_debug("C: Rename [dn: $dn] [dn: $newrdn]");
+
+ if (!ldap_rename($this->conn, $dn, $newrdn, $newparent, $deleteoldrdn)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_list()
+ */
+ protected function ldap_list($dn, $filter, $attrs = array(''))
+ {
+ $list = array();
+ $this->_debug("C: List [dn: $dn] [{$filter}]");
+
+ if ($result = ldap_list($this->conn, $dn, $filter, $attrs)) {
+ $list = ldap_get_entries($this->conn, $result);
+
+ if ($list === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return array();
+ }
+
+ $count = $list['count'];
+ unset($list['count']);
+
+ $this->_debug("S: $count record(s)");
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+
+ return $list;
+ }
+
}
diff --git a/program/lib/Roundcube/rcube_ldap_generic.php b/program/lib/Roundcube/rcube_ldap_generic.php
index 88378dc22..923a12a41 100644
--- a/program/lib/Roundcube/rcube_ldap_generic.php
+++ b/program/lib/Roundcube/rcube_ldap_generic.php
@@ -696,11 +696,17 @@ class rcube_ldap_generic
* Turn an LDAP entry into a regular PHP array with attributes as keys.
*
* @param array $entry Attributes array as retrieved from ldap_get_attributes() or ldap_get_entries()
+ *
* @return array Hash array with attributes as keys
*/
public static function normalize_entry($entry)
{
+ if (!isset($entry['count'])) {
+ return $entry;
+ }
+
$rec = array();
+
for ($i=0; $i < $entry['count']; $i++) {
$attr = $entry[$i];
if ($entry[$attr]['count'] == 1) {
diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php
index 0d33ea44d..a8bcf6afc 100644
--- a/program/lib/Roundcube/rcube_message.php
+++ b/program/lib/Roundcube/rcube_message.php
@@ -168,11 +168,10 @@ class rcube_message
* @param resource $fp File pointer to save the message part
* @param boolean $skip_charset_conv Disables charset conversion
* @param int $max_bytes Only read this number of bytes
- * @param boolean $formatted Enables formatting of text/* parts bodies
*
* @return string Part content
*/
- public function get_part_content($mime_id, $fp = null, $skip_charset_conv = false, $max_bytes = 0, $formatted = true)
+ public function get_part_content($mime_id, $fp = null, $skip_charset_conv = false, $max_bytes = 0)
{
if ($part = $this->mime_parts[$mime_id]) {
// stored in message structure (winmail/inline-uuencode)
@@ -186,89 +185,47 @@ class rcube_message
// get from IMAP
$this->storage->set_folder($this->folder);
- return $this->storage->get_message_part($this->uid, $mime_id, $part,
- NULL, $fp, $skip_charset_conv, $max_bytes, $formatted);
+ return $this->storage->get_message_part($this->uid, $mime_id, $part, NULL, $fp, $skip_charset_conv, $max_bytes);
}
}
/**
- * Determine if the message contains a HTML part. This must to be
- * a real part not an attachment (or its part)
- * This must to be
- * a real part not an attachment (or its part)
+ * Determine if the message contains a HTML part
*
- * @param bool $enriched Enables checking for text/enriched parts too
+ * @param bool $recursive Enables checking in all levels of the structure
+ * @param bool $enriched Enables checking for text/enriched parts too
*
* @return bool True if a HTML is available, False if not
*/
- function has_html_part($enriched = false)
+ function has_html_part($recursive = true, $enriched = false)
{
// check all message parts
- foreach ($this->mime_parts as $part) {
+ foreach ($this->parts as $part) {
if ($part->mimetype == 'text/html' || ($enriched && $part->mimetype == 'text/enriched')) {
- // Skip if part is an attachment, don't use is_attachment() here
- if ($part->filename) {
- continue;
- }
-
- $level = explode('.', $part->mime_id);
-
- // Check if the part belongs to higher-level's alternative/related
- while (array_pop($level) !== null) {
- if (!count($level)) {
- return true;
- }
+ // Level check, we'll skip e.g. HTML attachments
+ if (!$recursive) {
+ $level = explode('.', $part->mime_id);
- $parent = $this->mime_parts[join('.', $level)];
- if ($parent->mimetype != 'multipart/alternative' && $parent->mimetype != 'multipart/related') {
- continue 2;
+ // Skip if part is an attachment
+ if ($this->is_attachment($part)) {
+ continue;
}
- }
- if ($part->size) {
- return true;
- }
- }
- }
-
- return false;
- }
-
-
- /**
- * Determine if the message contains a text/plain part. This must to be
- * a real part not an attachment (or its part)
- *
- * @return bool True if a plain text part is available, False if not
- */
- function has_text_part()
- {
- // check all message parts
- foreach ($this->mime_parts as $part) {
- if ($part->mimetype == 'text/plain') {
- // Skip if part is an attachment, don't use is_attachment() here
- if ($part->filename) {
- continue;
- }
-
- $level = explode('.', $part->mime_id);
-
- // Check if the part belongs to higher-level's alternative/related
- while (array_pop($level) !== null) {
- if (!count($level)) {
- return true;
- }
+ // Check if the part belongs to higher-level's alternative/related
+ while (array_pop($level) !== null) {
+ if (!count($level)) {
+ return true;
+ }
- $parent = $this->mime_parts[join('.', $level)];
- if ($parent->mimetype != 'multipart/alternative' && $parent->mimetype != 'multipart/related') {
- continue 2;
+ $parent = $this->mime_parts[join('.', $level)];
+ if ($parent->mimetype != 'multipart/alternative' && $parent->mimetype != 'multipart/related') {
+ continue 2;
+ }
}
}
- if ($part->size) {
- return true;
- }
+ return true;
}
}
@@ -363,8 +320,8 @@ class rcube_message
$mimetype = $structure->real_mimetype;
// parse headers from message/rfc822 part
- if (!isset($structure->headers['subject']) && !isset($structure->headers['from'])) {
- list($headers, ) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 32768));
+ if (!isset($structure->headers['subject'])) {
+ list($headers, $dump) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 32768));
$structure->headers = rcube_mime::parse_headers($headers);
}
}
@@ -373,7 +330,7 @@ class rcube_message
// show message headers
if ($recursive && is_array($structure->headers) &&
- (isset($structure->headers['subject']) || $structure->headers['from'] || $structure->headers['to'])) {
+ ($structure->headers['subject'] || $structure->headers['from'] || $structure->headers['to'])) {
$c = new stdClass;
$c->type = 'headers';
$c->headers = $structure->headers;
@@ -487,6 +444,14 @@ class rcube_message
$this->parts[] = $c;
}
+ // add html part as attachment
+ if ($html_part !== null && $structure->parts[$html_part] !== $print_part) {
+ $html_part = $structure->parts[$html_part];
+ $html_part->mimetype = 'text/html';
+
+ $this->attachments[] = $html_part;
+ }
+
// add unsupported/unrecognized parts to attachments list
if ($attach_part) {
$this->attachments[] = $structure->parts[$attach_part];
@@ -571,6 +536,10 @@ class rcube_message
if (!empty($mail_part->filename)) {
$this->attachments[] = $mail_part;
}
+ // list html part as attachment (here the part is most likely inside a multipart/related part)
+ else if ($this->parse_alternative && ($secondary_type == 'html' && !$this->opt['prefer_html'])) {
+ $this->attachments[] = $mail_part;
+ }
}
// part message/*
else if ($primary_type == 'message') {
diff --git a/program/lib/Roundcube/rcube_mime.php b/program/lib/Roundcube/rcube_mime.php
index 96a8eac61..323a5e900 100644
--- a/program/lib/Roundcube/rcube_mime.php
+++ b/program/lib/Roundcube/rcube_mime.php
@@ -637,7 +637,8 @@ class rcube_mime
if ($nextChar === ' ' || $nextChar === $separator) {
$afterNextChar = mb_substr($string, $width + 1, 1);
- if ($afterNextChar === false) {
+ // Note: mb_substr() does never return False
+ if ($afterNextChar === false || $afterNextChar === '') {
$subString .= $nextChar;
}
@@ -650,24 +651,23 @@ class rcube_mime
$subString = mb_substr($subString, 0, $spacePos);
$cutLength = $spacePos + 1;
}
- else if ($cut === false && $breakPos === false) {
- $subString = $string;
- $cutLength = null;
- }
else if ($cut === false) {
$spacePos = mb_strpos($string, ' ', 0);
- if ($spacePos !== false && $spacePos < $breakPos) {
+ if ($spacePos !== false && ($breakPos === false || $spacePos < $breakPos)) {
$subString = mb_substr($string, 0, $spacePos);
$cutLength = $spacePos + 1;
}
+ else if ($breakPos === false) {
+ $subString = $string;
+ $cutLength = null;
+ }
else {
$subString = mb_substr($string, 0, $breakPos);
$cutLength = $breakPos + 1;
}
}
else {
- $subString = mb_substr($subString, 0, $width);
$cutLength = $width;
}
}
@@ -708,20 +708,12 @@ class rcube_mime
*/
public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false, $skip_suffix = false)
{
- static $mime_ext = array();
-
$mime_type = null;
- $config = rcube::get_instance()->config;
- $mime_magic = $config->get('mime_magic');
-
- if (!$skip_suffix && empty($mime_ext)) {
- foreach ($config->resolve_paths('mimetypes.php') as $fpath) {
- $mime_ext = array_merge($mime_ext, (array) @include($fpath));
- }
- }
+ $mime_magic = rcube::get_instance()->config->get('mime_magic');
+ $mime_ext = $skip_suffix ? null : @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
// use file name suffix with hard-coded mime-type map
- if (!$skip_suffix && is_array($mime_ext) && $name) {
+ if (is_array($mime_ext) && $name) {
if ($suffix = substr($name, strrpos($name, '.')+1)) {
$mime_type = $mime_ext[strtolower($suffix)];
}
@@ -826,9 +818,7 @@ class rcube_mime
// fallback to some well-known types most important for daily emails
if (empty($mime_types)) {
- foreach (rcube::get_instance()->config->resolve_paths('mimetypes.php') as $fpath) {
- $mime_extensions = array_merge($mime_extensions, (array) @include($fpath));
- }
+ $mime_extensions = (array) @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
foreach ($mime_extensions as $ext => $mime) {
$mime_types[$mime][] = $ext;
diff --git a/program/lib/Roundcube/rcube_plugin.php b/program/lib/Roundcube/rcube_plugin.php
index 3153a8410..34720cfd7 100644
--- a/program/lib/Roundcube/rcube_plugin.php
+++ b/program/lib/Roundcube/rcube_plugin.php
@@ -92,16 +92,6 @@ abstract class rcube_plugin
abstract function init();
/**
- * Provide information about this
- *
- * @return array Meta information about a plugin or false if not implemented
- */
- public static function info()
- {
- return false;
- }
-
- /**
* Attempt to load the given plugin which is required for the current plugin
*
* @param string Plugin name
@@ -227,7 +217,7 @@ abstract class rcube_plugin
$rcube->load_language($lang, $add);
// add labels to client
- if ($add2client && method_exists($rcube->output, 'add_label')) {
+ if ($add2client) {
if (is_array($add2client)) {
$js_labels = array_map(array($this, 'label_map_callback'), $add2client);
}
@@ -240,24 +230,6 @@ abstract class rcube_plugin
}
/**
- * Wrapper for add_label() adding the plugin ID as domain
- */
- public function add_label()
- {
- $rcube = rcube::get_instance();
-
- if (method_exists($rcube->output, 'add_label')) {
- $args = func_get_args();
- if (count($args) == 1 && is_array($args[0])) {
- $args = $args[0];
- }
-
- $args = array_map(array($this, 'label_map_callback'), $args);
- $rcube->output->add_label($args);
- }
- }
-
- /**
* Wrapper for rcube::gettext() adding the plugin ID as domain
*
* @param string $p Message identifier
@@ -273,7 +245,7 @@ abstract class rcube_plugin
/**
* Register this plugin to be responsible for a specific task
*
- * @param string $task Task name (only characters [a-z0-9_-] are allowed)
+ * @param string $task Task name (only characters [a-z0-9_.-] are allowed)
*/
public function register_task($task)
{
@@ -408,10 +380,6 @@ abstract class rcube_plugin
*/
private function label_map_callback($key)
{
- if (strpos($key, $this->ID.'.') === 0) {
- return $key;
- }
-
return $this->ID.'.'.$key;
}
}
diff --git a/program/lib/Roundcube/rcube_plugin_api.php b/program/lib/Roundcube/rcube_plugin_api.php
index 33f04eaa5..c9602d912 100644
--- a/program/lib/Roundcube/rcube_plugin_api.php
+++ b/program/lib/Roundcube/rcube_plugin_api.php
@@ -35,8 +35,9 @@ class rcube_plugin_api
public $url = 'plugins/';
public $task = '';
public $output;
- public $handlers = array();
- public $allowed_prefs = array();
+ public $handlers = array();
+ public $allowed_prefs = array();
+ public $allowed_session_prefs = array();
protected $plugins = array();
protected $tasks = array();
@@ -228,119 +229,6 @@ class rcube_plugin_api
}
/**
- * Get information about a specific plugin.
- * This is either provided my a plugin's info() method or extracted from a package.xml or a composer.json file
- *
- * @param string Plugin name
- * @return array Meta information about a plugin or False if plugin was not found
- */
- public function get_info($plugin_name)
- {
- static $composer_lock, $license_uris = array(
- 'Apache' => 'http://www.apache.org/licenses/LICENSE-2.0.html',
- 'Apache-2' => 'http://www.apache.org/licenses/LICENSE-2.0.html',
- 'Apache-1' => 'http://www.apache.org/licenses/LICENSE-1.0',
- 'Apache-1.1' => 'http://www.apache.org/licenses/LICENSE-1.1',
- 'GPL' => 'http://www.gnu.org/licenses/gpl.html',
- 'GPLv2' => 'http://www.gnu.org/licenses/gpl-2.0.html',
- 'GPL-2.0' => 'http://www.gnu.org/licenses/gpl-2.0.html',
- 'GPLv3' => 'http://www.gnu.org/licenses/gpl-3.0.html',
- 'GPL-3.0' => 'http://www.gnu.org/licenses/gpl-3.0.html',
- 'GPL-3.0+' => 'http://www.gnu.org/licenses/gpl.html',
- 'GPL-2.0+' => 'http://www.gnu.org/licenses/gpl.html',
- 'LGPL' => 'http://www.gnu.org/licenses/lgpl.html',
- 'LGPLv2' => 'http://www.gnu.org/licenses/lgpl-2.0.html',
- 'LGPLv2.1' => 'http://www.gnu.org/licenses/lgpl-2.1.html',
- 'LGPLv3' => 'http://www.gnu.org/licenses/lgpl.html',
- 'LGPL-2.0' => 'http://www.gnu.org/licenses/lgpl-2.0.html',
- 'LGPL-2.1' => 'http://www.gnu.org/licenses/lgpl-2.1.html',
- 'LGPL-3.0' => 'http://www.gnu.org/licenses/lgpl.html',
- 'LGPL-3.0+' => 'http://www.gnu.org/licenses/lgpl.html',
- 'BSD' => 'http://opensource.org/licenses/bsd-license.html',
- 'BSD-2-Clause' => 'http://opensource.org/licenses/BSD-2-Clause',
- 'BSD-3-Clause' => 'http://opensource.org/licenses/BSD-3-Clause',
- 'FreeBSD' => 'http://opensource.org/licenses/BSD-2-Clause',
- 'MIT' => 'http://www.opensource.org/licenses/mit-license.php',
- 'PHP' => 'http://opensource.org/licenses/PHP-3.0',
- 'PHP-3' => 'http://www.php.net/license/3_01.txt',
- 'PHP-3.0' => 'http://www.php.net/license/3_0.txt',
- 'PHP-3.01' => 'http://www.php.net/license/3_01.txt',
- );
-
- $dir = dir($this->dir);
- $fn = unslashify($dir->path) . DIRECTORY_SEPARATOR . $plugin_name . DIRECTORY_SEPARATOR . $plugin_name . '.php';
- $info = false;
-
- if (!class_exists($plugin_name))
- include($fn);
-
- if (class_exists($plugin_name))
- $info = $plugin_name::info();
-
- // fall back to composer.json file
- if (!$info) {
- $composer = INSTALL_PATH . "/plugins/$plugin_name/composer.json";
- if (file_exists($composer) && ($json = @json_decode(file_get_contents($composer), true))) {
- list($info['vendor'], $info['name']) = explode('/', $json['name']);
- $info['license'] = $json['license'];
- if ($license_uri = $license_uris[$info['license']])
- $info['license_uri'] = $license_uri;
- }
-
- // read local composer.lock file (once)
- if (!isset($composer_lock)) {
- $composer_lock = @json_decode(@file_get_contents(INSTALL_PATH . "/composer.lock"), true);
- if ($composer_lock['packages']) {
- foreach ($composer_lock['packages'] as $i => $package) {
- $composer_lock['installed'][$package['name']] = $package;
- }
- }
- }
-
- // load additional information from local composer.lock file
- if ($lock = $composer_lock['installed'][$json['name']]) {
- $info['version'] = $lock['version'];
- $info['uri'] = $lock['homepage'] ? $lock['homepage'] : $lock['source']['uri'];
- $info['src_uri'] = $lock['dist']['uri'] ? $lock['dist']['uri'] : $lock['source']['uri'];
- }
- }
-
- // fall back to package.xml file
- if (!$info) {
- $package = INSTALL_PATH . "/plugins/$plugin_name/package.xml";
- if (file_exists($package) && ($file = file_get_contents($package))) {
- $doc = new DOMDocument();
- $doc->loadXML($file);
- $xpath = new DOMXPath($doc);
- $xpath->registerNamespace('rc', "http://pear.php.net/dtd/package-2.0");
-
- // XPaths of plugin metadata elements
- $metadata = array(
- 'name' => 'string(//rc:package/rc:name)',
- 'version' => 'string(//rc:package/rc:version/rc:release)',
- 'license' => 'string(//rc:package/rc:license)',
- 'license_uri' => 'string(//rc:package/rc:license/@uri)',
- 'src_uri' => 'string(//rc:package/rc:srcuri)',
- 'uri' => 'string(//rc:package/rc:uri)',
- );
-
- foreach ($metadata as $key => $path) {
- $info[$key] = $xpath->evaluate($path);
- }
-
- // dependent required plugins (can be used, but not included in config)
- $deps = $xpath->evaluate('//rc:package/rc:dependencies/rc:required/rc:package/rc:name');
- for ($i = 0; $i < $deps->length; $i++) {
- $dn = $deps->item($i)->nodeValue;
- $info['requires'][] = $dn;
- }
- }
- }
-
- return $info;
- }
-
- /**
* Allows a plugin object to register a callback for a certain hook
*
* @param string $hook Hook name
@@ -491,7 +379,7 @@ class rcube_plugin_api
/**
* Register this plugin to be responsible for a specific task
*
- * @param string $task Task name (only characters [a-z0-9_-] are allowed)
+ * @param string $task Task name (only characters [a-z0-9_.-] are allowed)
* @param string $owner Plugin name that registers this action
*/
public function register_task($task, $owner)
@@ -501,7 +389,7 @@ class rcube_plugin_api
return true;
}
- if ($task != asciiwords($task, true)) {
+ if ($task != asciiwords($task)) {
rcube::raise_error(array('code' => 526, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Invalid task name: $task."
diff --git a/program/lib/Roundcube/rcube_result_set.php b/program/lib/Roundcube/rcube_result_set.php
index a4b070e28..1391e5e4b 100644
--- a/program/lib/Roundcube/rcube_result_set.php
+++ b/program/lib/Roundcube/rcube_result_set.php
@@ -3,7 +3,7 @@
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 2006-2011, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -17,22 +17,20 @@
*/
/**
- * Roundcube result set class
- *
+ * Roundcube result set class.
* Representing an address directory result set.
- * Implenets Iterator and thus be used in foreach() loops.
*
* @package Framework
* @subpackage Addressbook
*/
-class rcube_result_set implements Iterator
+class rcube_result_set
{
- public $count = 0;
- public $first = 0;
- public $searchonly = false;
- public $records = array();
+ var $count = 0;
+ var $first = 0;
+ var $current = 0;
+ var $searchonly = false;
+ var $records = array();
- private $current = 0;
function __construct($c=0, $f=0)
{
@@ -53,39 +51,18 @@ class rcube_result_set implements Iterator
function first()
{
$this->current = 0;
- return $this->records[$this->current];
- }
-
- function seek($i)
- {
- $this->current = $i;
- }
-
- /*** PHP 5 Iterator interface ***/
-
- function rewind()
- {
- $this->current = 0;
- }
-
- function current()
- {
- return $this->records[$this->current];
- }
-
- function key()
- {
- return $this->current;
+ return $this->records[$this->current++];
}
+ // alias for iterate()
function next()
{
return $this->iterate();
}
- function valid()
+ function seek($i)
{
- return isset($this->records[$this->current]);
+ $this->current = $i;
}
}
diff --git a/program/lib/Roundcube/rcube_session.php b/program/lib/Roundcube/rcube_session.php
index 67072df41..ee4db6e86 100644
--- a/program/lib/Roundcube/rcube_session.php
+++ b/program/lib/Roundcube/rcube_session.php
@@ -32,7 +32,6 @@ class rcube_session
private $ip;
private $start;
private $changed;
- private $time_diff = 0;
private $reloaded = false;
private $unsets = array();
private $gc_handlers = array();
@@ -43,7 +42,6 @@ class rcube_session
private $secret = '';
private $ip_check = false;
private $logging = false;
- private $storage;
private $memcache;
@@ -54,21 +52,18 @@ class rcube_session
{
$this->db = $db;
$this->start = microtime(true);
- $this->ip = rcube_utils::remote_addr();
+ $this->ip = $_SERVER['REMOTE_ADDR'];
$this->logging = $config->get('log_session', false);
$lifetime = $config->get('session_lifetime', 1) * 60;
$this->set_lifetime($lifetime);
// use memcache backend
- $this->storage = $config->get('session_storage', 'db');
- if ($this->storage == 'memcache') {
+ if ($config->get('session_storage', 'db') == 'memcache') {
$this->memcache = rcube::get_instance()->get_memcache();
// set custom functions for PHP session management if memcache is available
if ($this->memcache) {
- ini_set('session.serialize_handler', 'php');
-
session_set_save_handler(
array($this, 'open'),
array($this, 'close'),
@@ -84,9 +79,7 @@ class rcube_session
true, true);
}
}
- else if ($this->storage != 'php') {
- ini_set('session.serialize_handler', 'php');
-
+ else {
// set custom functions for PHP session management
session_set_save_handler(
array($this, 'open'),
@@ -94,23 +87,7 @@ class rcube_session
array($this, 'db_read'),
array($this, 'db_write'),
array($this, 'db_destroy'),
- array($this, 'gc'));
- }
- }
-
-
- /**
- * Wrapper for session_start()
- */
- public function start()
- {
- session_start();
-
- // copy some session properties to object vars
- if ($this->storage == 'php') {
- $this->key = session_id();
- $this->ip = $_SESSION['__IP'];
- $this->changed = $_SESSION['__MTIME'];
+ array($this, 'db_gc'));
}
}
@@ -139,25 +116,6 @@ class rcube_session
/**
- * Wrapper for session_write_close()
- */
- public function write_close()
- {
- if ($this->storage == 'php') {
- $_SESSION['__IP'] = $this->ip;
- $_SESSION['__MTIME'] = time();
- }
-
- session_write_close();
-
- // write_close() is called on script shutdown, see rcube::shutdown()
- // execute cleanup functionality if enabled by session gc handler
- // we do this after closing the session for better performance
- $this->gc_shutdown();
- }
-
-
- /**
* Read session data from database
*
* @param string Session ID
@@ -167,16 +125,14 @@ class rcube_session
public function db_read($key)
{
$sql_result = $this->db->query(
- "SELECT vars, ip, changed, " . $this->db->now() . " AS ts"
- . " FROM " . $this->db->table_name('session')
- . " WHERE sess_id = ?", $key);
+ "SELECT vars, ip, changed FROM ".$this->db->table_name('session')
+ ." WHERE sess_id = ?", $key);
if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
- $this->time_diff = time() - strtotime($sql_arr['ts']);
- $this->changed = strtotime($sql_arr['changed']);
- $this->ip = $sql_arr['ip'];
- $this->vars = base64_decode($sql_arr['vars']);
- $this->key = $key;
+ $this->changed = strtotime($sql_arr['changed']);
+ $this->ip = $sql_arr['ip'];
+ $this->vars = base64_decode($sql_arr['vars']);
+ $this->key = $key;
return !empty($this->vars) ? (string) $this->vars : '';
}
@@ -196,9 +152,8 @@ class rcube_session
*/
public function db_write($key, $vars)
{
- $now = $this->db->now();
- $table = $this->db->table_name('session');
- $ts = microtime(true);
+ $ts = microtime(true);
+ $now = $this->db->fromunixtime((int)$ts);
// no session row in DB (db_read() returns false)
if (!$this->key) {
@@ -216,19 +171,22 @@ class rcube_session
$newvars = $this->_fixvars($vars, $oldvars);
if ($newvars !== $oldvars) {
- $this->db->query("UPDATE $table "
- . "SET changed = $now, vars = ? WHERE sess_id = ?",
- base64_encode($newvars), $key);
+ $this->db->query(
+ sprintf("UPDATE %s SET vars=?, changed=%s WHERE sess_id=?",
+ $this->db->table_name('session'), $now),
+ base64_encode($newvars), $key);
}
- else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
- $this->db->query("UPDATE $table SET changed = $now"
- . " WHERE sess_id = ?", $key);
+ else if ($ts - $this->changed > $this->lifetime / 2) {
+ $this->db->query("UPDATE ".$this->db->table_name('session')
+ ." SET changed=$now WHERE sess_id=?", $key);
}
}
else {
- $this->db->query("INSERT INTO $table (sess_id, vars, ip, created, changed)"
- . " VALUES (?, ?, ?, $now, $now)",
- $key, base64_encode($vars), (string)$this->ip);
+ $this->db->query(
+ sprintf("INSERT INTO %s (sess_id, vars, ip, created, changed) ".
+ "VALUES (?, ?, ?, %s, %s)",
+ $this->db->table_name('session'), $now, $now),
+ $key, base64_encode($vars), (string)$this->ip);
}
return true;
@@ -288,6 +246,25 @@ class rcube_session
/**
+ * Garbage collecting function
+ *
+ * @param string Session lifetime in seconds
+ * @return boolean True on success
+ */
+ public function db_gc($maxlifetime)
+ {
+ // just delete all expired sessions
+ $this->db->query(
+ sprintf("DELETE FROM %s WHERE changed < %s",
+ $this->db->table_name('session'), $this->db->fromunixtime(time() - $maxlifetime)));
+
+ $this->gc();
+
+ return true;
+ }
+
+
+ /**
* Read session data from memcache
*
* @param string Session ID
@@ -363,11 +340,11 @@ class rcube_session
/**
* Execute registered garbage collector routines
*/
- public function gc($maxlifetime)
+ public function gc()
{
- // move gc execution to the script shutdown function
- // see rcube::shutdown() and rcube_session::write_close()
- return $this->gc_enabled = $maxlifetime;
+ foreach ($this->gc_handlers as $fct) {
+ call_user_func($fct);
+ }
}
@@ -389,25 +366,6 @@ class rcube_session
/**
- * Garbage collector handler to run on script shutdown
- */
- protected function gc_shutdown()
- {
- if ($this->gc_enabled) {
- // just delete all expired sessions
- if ($this->storage == 'db') {
- $this->db->query("DELETE FROM " . $this->db->table_name('session')
- . " WHERE changed < " . $this->db->now(-$this->gc_enabled));
- }
-
- foreach ($this->gc_handlers as $fct) {
- call_user_func($fct);
- }
- }
- }
-
-
- /**
* Generate and set new session id
*
* @param boolean $destroy If enabled the current session will be destroyed
@@ -480,7 +438,7 @@ class rcube_session
public function kill()
{
$this->vars = null;
- $this->ip = rcube_utils::remote_addr(); // update IP (might have changed)
+ $this->ip = $_SERVER['REMOTE_ADDR']; // update IP (might have changed)
$this->destroy(session_id());
rcube_utils::setcookie($this->cookiename, '-del-', time() - 60);
}
@@ -694,10 +652,10 @@ class rcube_session
function check_auth()
{
$this->cookie = $_COOKIE[$this->cookiename];
- $result = $this->ip_check ? rcube_utils::remote_addr() == $this->ip : true;
+ $result = $this->ip_check ? $_SERVER['REMOTE_ADDR'] == $this->ip : true;
if (!$result) {
- $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . rcube_utils::remote_addr());
+ $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . $_SERVER['REMOTE_ADDR']);
}
if ($result && $this->_mkcookie($this->now) != $this->cookie) {
diff --git a/program/lib/Roundcube/rcube_smtp.php b/program/lib/Roundcube/rcube_smtp.php
index 60b1389ea..201e8269e 100644
--- a/program/lib/Roundcube/rcube_smtp.php
+++ b/program/lib/Roundcube/rcube_smtp.php
@@ -33,8 +33,6 @@ class rcube_smtp
// define headers delimiter
const SMTP_MIME_CRLF = "\r\n";
- const DEBUG_LINE_LENGTH = 4098; // 4KB + 2B for \r\n
-
/**
* SMTP Connection and authentication
@@ -329,12 +327,6 @@ class rcube_smtp
*/
public function debug_handler(&$smtp, $message)
{
- if (($len = strlen($message)) > self::DEBUG_LINE_LENGTH) {
- $diff = $len - self::DEBUG_LINE_LENGTH;
- $message = substr($message, 0, self::DEBUG_LINE_LENGTH)
- . "... [truncated $diff bytes]";
- }
-
rcube::write_log('smtp', preg_replace('/\r\n$/', '', $message));
}
@@ -441,9 +433,9 @@ class rcube_smtp
$recipients = rcube_utils::explode_quoted_string(',', $recipients);
reset($recipients);
- foreach ($recipients as $recipient) {
+ while (list($k, $recipient) = each($recipients)) {
$a = rcube_utils::explode_quoted_string(' ', $recipient);
- foreach ($a as $word) {
+ while (list($k2, $word) = each($a)) {
if (strpos($word, "@") > 0 && $word[strlen($word)-1] != '"') {
$word = preg_replace('/^<|>$/', '', trim($word));
if (in_array($word, $addresses) === false) {
diff --git a/program/lib/Roundcube/rcube_spellcheck_atd.php b/program/lib/Roundcube/rcube_spellcheck_atd.php
new file mode 100644
index 000000000..9f073f56f
--- /dev/null
+++ b/program/lib/Roundcube/rcube_spellcheck_atd.php
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | |
+ | Copyright (C) 2013, 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: |
+ | Spellchecking backend implementation for afterthedeadline services |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Spellchecking backend implementation to work with an After the Deadline service
+ * See http://www.afterthedeadline.com/ for more information
+ *
+ * @package Framework
+ * @subpackage Utils
+ */
+class rcube_spellcheck_atd extends rcube_spellcheck_engine
+{
+ const SERVICE_HOST = 'service.afterthedeadline.com';
+ const SERVICE_PORT = 80;
+
+ private $matches = array();
+ private $content;
+ private $langhosts = array(
+ 'fr' => 'fr.',
+ 'de' => 'de.',
+ 'pt' => 'pt.',
+ 'es' => 'es.',
+ );
+
+ /**
+ * Return a list of languages supported by this backend
+ *
+ * @see rcube_spellcheck_engine::languages()
+ */
+ function languages()
+ {
+ $langs = array_values($this->langhosts);
+ $langs[] = 'en';
+ return $langs;
+ }
+
+ /**
+ * Set content and check spelling
+ *
+ * @see rcube_spellcheck_engine::check()
+ */
+ function check($text)
+ {
+ $this->content = $text;
+
+ // spell check uri is configured
+ $rcube = rcube::get_instance();
+ $url = $rcube->config->get('spellcheck_uri');
+ $key = $rcube->config->get('spellcheck_atd_key');
+
+ if ($url) {
+ $a_uri = parse_url($url);
+ $ssl = ($a_uri['scheme'] == 'https' || $a_uri['scheme'] == 'ssl');
+ $port = $a_uri['port'] ? $a_uri['port'] : ($ssl ? 443 : 80);
+ $host = ($ssl ? 'ssl://' : '') . $a_uri['host'];
+ $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '') . $this->lang;
+ }
+ else {
+ $host = self::SERVICE_HOST;
+ $port = self::SERVICE_PORT;
+ $path = '/checkDocument';
+
+ // prefix host for other languages than 'en'
+ $lang = substr($this->lang, 0, 2);
+ if ($this->langhosts[$lang])
+ $host = $this->langhosts[$lang] . $host;
+ }
+
+ $postdata = 'data=' . urlencode($text);
+
+ if (!empty($key))
+ $postdata .= '&key=' . urlencode($key);
+
+ $response = $headers = '';
+ $in_header = true;
+ if ($fp = fsockopen($host, $port, $errno, $errstr, 30)) {
+ $out = "POST $path HTTP/1.0\r\n";
+ $out .= "Host: " . str_replace('ssl://', '', $host) . "\r\n";
+ $out .= "Content-Length: " . strlen($postdata) . "\r\n";
+ $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
+ $out .= "Connection: Close\r\n\r\n";
+ $out .= $postdata;
+ fwrite($fp, $out);
+
+ while (!feof($fp)) {
+ if ($in_header) {
+ $line = fgets($fp, 512);
+ $headers .= $line;
+ if (trim($line) == '')
+ $in_header = false;
+ }
+ else {
+ $response .= fgets($fp, 1024);
+ }
+ }
+ fclose($fp);
+ }
+
+ // parse HTTP response headers
+ if (preg_match('!^HTTP/1.\d (\d+)(.+)!', $headers, $m)) {
+ $http_status = $m[1];
+ if ($http_status != '200')
+ $this->error = 'HTTP ' . $m[1] . $m[2];
+ }
+
+ if (!$response) {
+ $this->error = "Empty result from spelling engine";
+ }
+
+ try {
+ $result = new SimpleXMLElement($response);
+ }
+ catch (Exception $e) {
+ $thid->error = "Unexpected response from server: " . $store;
+ return array();
+ }
+
+ foreach ($result->error as $error) {
+ if (strval($error->type) == 'spelling') {
+ $word = strval($error->string);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ continue;
+ }
+
+ $prefix = strval($error->precontext);
+ $start = $prefix ? mb_strpos($text, $prefix) : 0;
+ $pos = mb_strpos($text, $word, $start);
+ $len = mb_strlen($word);
+ $num = 0;
+
+ $match = array($word, $pos, $len, null, array());
+ foreach ($error->suggestions->option as $option) {
+ $match[4][] = strval($option);
+ if (++$num == self::MAX_SUGGESTIONS)
+ break;
+ }
+ $matches[] = $match;
+ }
+ }
+
+ $this->matches = $matches;
+ return $matches;
+ }
+
+ /**
+ * Returns suggestions for the specified word
+ *
+ * @see rcube_spellcheck_engine::get_words()
+ */
+ function get_suggestions($word)
+ {
+ $matches = $word ? $this->check($word) : $this->matches;
+
+ if ($matches[0][4]) {
+ return $matches[0][4];
+ }
+
+ return array();
+ }
+
+ /**
+ * Returns misspelled words
+ *
+ * @see rcube_spellcheck_engine::get_suggestions()
+ */
+ function get_words($text = null)
+ {
+ if ($text) {
+ $matches = $this->check($text);
+ }
+ else {
+ $matches = $this->matches;
+ $text = $this->content;
+ }
+
+ $result = array();
+
+ foreach ($matches as $m) {
+ $result[] = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
+ }
+
+ return $result;
+ }
+
+}
+
diff --git a/program/lib/Roundcube/rcube_spellcheck_enchant.php b/program/lib/Roundcube/rcube_spellcheck_enchant.php
new file mode 100644
index 000000000..14d6fff46
--- /dev/null
+++ b/program/lib/Roundcube/rcube_spellcheck_enchant.php
@@ -0,0 +1,182 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | |
+ | Copyright (C) 2011-2013, Kolab Systems AG |
+ | Copyright (C) 20011-2013, 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: |
+ | Spellchecking backend implementation to work with Enchant |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak@kolabsys.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Spellchecking backend implementation to work with Pspell
+ *
+ * @package Framework
+ * @subpackage Utils
+ */
+class rcube_spellcheck_enchant extends rcube_spellcheck_engine
+{
+ private $enchant_broker;
+ private $enchant_dictionary;
+ private $matches = array();
+
+ /**
+ * Return a list of languages supported by this backend
+ *
+ * @see rcube_spellcheck_engine::languages()
+ */
+ function languages()
+ {
+ $this->init();
+
+ $langs = array();
+ $dicts = enchant_broker_list_dicts($this->enchant_broker);
+ foreach ($dicts as $dict) {
+ $langs[] = preg_replace('/-.*$/', '', $dict['lang_tag']);
+ }
+
+ return array_unique($langs);
+ }
+
+ /**
+ * Initializes Enchant dictionary
+ */
+ private function init()
+ {
+ if (!$this->enchant_broker) {
+ if (!extension_loaded('enchant')) {
+ $this->error = "Enchant extension not available";
+ return;
+ }
+
+ $this->enchant_broker = enchant_broker_init();
+ }
+
+ if (!enchant_broker_dict_exists($this->enchant_broker, $this->lang)) {
+ $this->error = "Unable to load dictionary for selected language using Enchant";
+ return;
+ }
+
+ $this->enchant_dictionary = enchant_broker_request_dict($this->enchant_broker, $this->lang);
+ }
+
+ /**
+ * Set content and check spelling
+ *
+ * @see rcube_spellcheck_engine::check()
+ */
+ function check($text)
+ {
+ $this->init();
+
+ if (!$this->enchant_dictionary) {
+ return array();
+ }
+
+ // tokenize
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ $diff = 0;
+ $matches = array();
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+ $pos = $w[1] - $diff;
+ $len = mb_strlen($word);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ }
+ else if (!enchant_dict_check($this->enchant_dictionary, $word)) {
+ $suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS) {
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+ }
+
+ $matches[] = array($word, $pos, $len, null, $suggestions);
+ }
+
+ $diff += (strlen($word) - $len);
+ }
+
+ $this->matches = $matches;
+ return $matches;
+ }
+
+ /**
+ * Returns suggestions for the specified word
+ *
+ * @see rcube_spellcheck_engine::get_words()
+ */
+ function get_suggestions($word)
+ {
+ $this->init();
+
+ if (!$this->enchant_dictionary) {
+ return array();
+ }
+
+ $suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS)
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+
+ return is_array($suggestions) ? $suggestions : array();
+ }
+
+ /**
+ * Returns misspelled words
+ *
+ * @see rcube_spellcheck_engine::get_suggestions()
+ */
+ function get_words($text = null)
+ {
+ $result = array();
+
+ if ($text) {
+ // init spellchecker
+ $this->init();
+
+ if (!$this->enchant_dictionary) {
+ return array();
+ }
+
+ // With Enchant we don't need to get suggestions to return misspelled words
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ continue;
+ }
+
+ if (!enchant_dict_check($this->enchant_dictionary, $word)) {
+ $result[] = $word;
+ }
+ }
+
+ return $result;
+ }
+
+ foreach ($this->matches as $m) {
+ $result[] = $m[0];
+ }
+
+ return $result;
+ }
+
+}
+
diff --git a/program/lib/Roundcube/rcube_spellcheck_engine.php b/program/lib/Roundcube/rcube_spellcheck_engine.php
new file mode 100644
index 000000000..3cb4ca3de
--- /dev/null
+++ b/program/lib/Roundcube/rcube_spellcheck_engine.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | |
+ | Copyright (C) 2011-2013, Kolab Systems AG |
+ | Copyright (C) 2008-2013, 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: |
+ | Interface class for a spell-checking backend |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Interface class for a spell-checking backend
+ *
+ * @package Framework
+ * @subpackage Utils
+ */
+abstract class rcube_spellcheck_engine
+{
+ const MAX_SUGGESTIONS = 10;
+
+ protected $lang;
+ protected $error;
+ protected $dictionary;
+ protected $separator = '/[\s\r\n\t\(\)\/\[\]{}<>\\"]+|[:;?!,\.](?=\W|$)/';
+
+ /**
+ * Default constructor
+ */
+ public function __construct($dict, $lang)
+ {
+ $this->dictionary = $dict;
+ $this->lang = $lang;
+ }
+
+ /**
+ * Return a list of languages supported by this backend
+ *
+ * @return array Indexed list of language codes
+ */
+ abstract function languages();
+
+ /**
+ * Set content and check spelling
+ *
+ * @param string $text Text content for spellchecking
+ *
+ * @return bool True when no mispelling found, otherwise false
+ */
+ abstract function check($text);
+
+ /**
+ * Returns suggestions for the specified word
+ *
+ * @param string $word The word
+ *
+ * @return array Suggestions list
+ */
+ abstract function get_suggestions($word);
+
+ /**
+ * Returns misspelled words
+ *
+ * @param string $text The content for spellchecking. If empty content
+ * used for check() method will be used.
+ *
+ * @return array List of misspelled words
+ */
+ abstract function get_words($text = null);
+
+ /**
+ * Returns error message
+ *
+ * @return string Error message
+ */
+ public function error()
+ {
+ return $this->error;
+ }
+
+}
+
diff --git a/program/lib/Roundcube/rcube_spellcheck_googie.php b/program/lib/Roundcube/rcube_spellcheck_googie.php
new file mode 100644
index 000000000..3777942a6
--- /dev/null
+++ b/program/lib/Roundcube/rcube_spellcheck_googie.php
@@ -0,0 +1,176 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | |
+ | Copyright (C) 2008-2013, 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: |
+ | Spellchecking backend implementation to work with Googiespell |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak@kolabsys.com> |
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Spellchecking backend implementation to work with a Googiespell service
+ *
+ * @package Framework
+ * @subpackage Utils
+ */
+class rcube_spellcheck_googie extends rcube_spellcheck_engine
+{
+ const GOOGIE_HOST = 'ssl://spell.roundcube.net';
+ const GOOGIE_PORT = 443;
+
+ private $matches = array();
+ private $content;
+
+ /**
+ * Return a list of languages supported by this backend
+ *
+ * @see rcube_spellcheck_engine::languages()
+ */
+ function languages()
+ {
+ return array('am','ar','ar','bg','br','ca','cs','cy','da',
+ 'de_CH','de_DE','el','en_GB','en_US',
+ 'eo','es','et','eu','fa','fi','fr_FR','ga','gl','gl',
+ 'he','hr','hu','hy','is','it','ku','lt','lv','nl',
+ 'pl','pt_BR','pt_PT','ro','ru',
+ 'sk','sl','sv','uk');
+ }
+
+ /**
+ * Set content and check spelling
+ *
+ * @see rcube_spellcheck_engine::check()
+ */
+ function check($text)
+ {
+ $this->content = $text;
+
+ // spell check uri is configured
+ $url = rcube::get_instance()->config->get('spellcheck_uri');
+
+ if ($url) {
+ $a_uri = parse_url($url);
+ $ssl = ($a_uri['scheme'] == 'https' || $a_uri['scheme'] == 'ssl');
+ $port = $a_uri['port'] ? $a_uri['port'] : ($ssl ? 443 : 80);
+ $host = ($ssl ? 'ssl://' : '') . $a_uri['host'];
+ $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '') . $this->lang;
+ }
+ else {
+ $host = self::GOOGIE_HOST;
+ $port = self::GOOGIE_PORT;
+ $path = '/tbproxy/spell?lang=' . $this->lang;
+ }
+
+ $path .= sprintf('&key=%06d', $_SESSION['user_id']);
+
+ $gtext = '<?xml version="1.0" encoding="utf-8" ?>'
+ .'<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
+ .'<text>' . htmlspecialchars($text, ENT_QUOTES, RCUBE_CHARSET) . '</text>'
+ .'</spellrequest>';
+
+ $store = '';
+ if ($fp = fsockopen($host, $port, $errno, $errstr, 30)) {
+ $out = "POST $path HTTP/1.0\r\n";
+ $out .= "Host: " . str_replace('ssl://', '', $host) . "\r\n";
+ $out .= "User-Agent: Roundcube Webmail/" . RCMAIL_VERSION . " (Googiespell Wrapper)\r\n";
+ $out .= "Content-Length: " . strlen($gtext) . "\r\n";
+ $out .= "Content-Type: text/xml\r\n";
+ $out .= "Connection: Close\r\n\r\n";
+ $out .= $gtext;
+ fwrite($fp, $out);
+
+ while (!feof($fp))
+ $store .= fgets($fp, 128);
+ fclose($fp);
+ }
+
+ // parse HTTP response
+ if (preg_match('!^HTTP/1.\d (\d+)(.+)!', $store, $m)) {
+ $http_status = $m[1];
+ if ($http_status != '200') {
+ $this->error = 'HTTP ' . $m[1] . $m[2];
+ $this->error .= "\n" . $store;
+ }
+ }
+
+ if (!$store) {
+ $this->error = "Empty result from spelling engine";
+ }
+ else if (preg_match('/<spellresult error="([^"]+)"/', $store, $m) && $m[1]) {
+ $this->error = "Error code $m[1] returned";
+ $this->error .= preg_match('/<errortext>([^<]+)/', $store, $m) ? ": " . html_entity_decode($m[1]) : '';
+ }
+
+ preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', $store, $matches, PREG_SET_ORDER);
+
+ // skip exceptions (if appropriate options are enabled)
+ foreach ($matches as $idx => $m) {
+ $word = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ unset($matches[$idx]);
+ }
+ }
+
+ $this->matches = $matches;
+ return $matches;
+ }
+
+ /**
+ * Returns suggestions for the specified word
+ *
+ * @see rcube_spellcheck_engine::get_words()
+ */
+ function get_suggestions($word)
+ {
+ $matches = $word ? $this->check($word) : $this->matches;
+
+ if ($matches[0][4]) {
+ $suggestions = explode("\t", $matches[0][4]);
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS) {
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+ }
+
+ return $suggestions;
+ }
+
+ return array();
+ }
+
+ /**
+ * Returns misspelled words
+ *
+ * @see rcube_spellcheck_engine::get_suggestions()
+ */
+ function get_words($text = null)
+ {
+ if ($text) {
+ $matches = $this->check($text);
+ }
+ else {
+ $matches = $this->matches;
+ $text = $this->content;
+ }
+
+ $result = array();
+
+ foreach ($matches as $m) {
+ $result[] = mb_substr($text, $m[1], $m[2], RCUBE_CHARSET);
+ }
+
+ return $result;
+ }
+
+}
+
diff --git a/program/lib/Roundcube/rcube_spellcheck_pspell.php b/program/lib/Roundcube/rcube_spellcheck_pspell.php
new file mode 100644
index 000000000..b12684e43
--- /dev/null
+++ b/program/lib/Roundcube/rcube_spellcheck_pspell.php
@@ -0,0 +1,189 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | |
+ | Copyright (C) 2008-2013, 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: |
+ | Spellchecking backend implementation to work with Pspell |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak@kolabsys.com> |
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Spellchecking backend implementation to work with Pspell
+ *
+ * @package Framework
+ * @subpackage Utils
+ */
+class rcube_spellcheck_pspell extends rcube_spellcheck_engine
+{
+ private $plink;
+ private $matches = array();
+
+ /**
+ * Return a list of languages supported by this backend
+ *
+ * @see rcube_spellcheck_engine::languages()
+ */
+ function languages()
+ {
+ $defaults = array('en');
+ $langs = array();
+
+ // get aspell dictionaries
+ exec('aspell dump dicts', $dicts);
+ if (!empty($dicts)) {
+ $seen = array();
+ foreach ($dicts as $lang) {
+ $lang = preg_replace('/-.*$/', '', $lang);
+ $langc = strlen($lang) == 2 ? $lang.'_'.strtoupper($lang) : $lang;
+ if (!$seen[$langc]++)
+ $langs[] = $lang;
+ }
+ $langs = array_unique($langs);
+ }
+ else {
+ $langs = $defaults;
+ }
+
+ return $langs;
+ }
+
+ /**
+ * Initializes PSpell dictionary
+ */
+ private function init()
+ {
+ if (!$this->plink) {
+ if (!extension_loaded('pspell')) {
+ $this->error = "Pspell extension not available";
+ return;
+ }
+
+ $this->plink = pspell_new($this->lang, null, null, RCUBE_CHARSET, PSPELL_FAST);
+ }
+
+ if (!$this->plink) {
+ $this->error = "Unable to load Pspell engine for selected language";
+ }
+ }
+
+ /**
+ * Set content and check spelling
+ *
+ * @see rcube_spellcheck_engine::check()
+ */
+ function check($text)
+ {
+ $this->init();
+
+ if (!$this->plink) {
+ return array();
+ }
+
+ // tokenize
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ $diff = 0;
+ $matches = array();
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+ $pos = $w[1] - $diff;
+ $len = mb_strlen($word);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ }
+ else if (!pspell_check($this->plink, $word)) {
+ $suggestions = pspell_suggest($this->plink, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS) {
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+ }
+
+ $matches[] = array($word, $pos, $len, null, $suggestions);
+ }
+
+ $diff += (strlen($word) - $len);
+ }
+
+ $this->matches = $matches;
+ return $matches;
+ }
+
+ /**
+ * Returns suggestions for the specified word
+ *
+ * @see rcube_spellcheck_engine::get_words()
+ */
+ function get_suggestions($word)
+ {
+ $this->init();
+
+ if (!$this->plink) {
+ return array();
+ }
+
+ $suggestions = pspell_suggest($this->plink, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS)
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+
+ return is_array($suggestions) ? $suggestions : array();
+ }
+
+ /**
+ * Returns misspelled words
+ *
+ * @see rcube_spellcheck_engine::get_suggestions()
+ */
+ function get_words($text = null)
+ {
+ $result = array();
+
+ if ($text) {
+ // init spellchecker
+ $this->init();
+
+ if (!$this->plink) {
+ return array();
+ }
+
+ // With PSpell we don't need to get suggestions to return misspelled words
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ continue;
+ }
+
+ if (!pspell_check($this->plink, $word)) {
+ $result[] = $word;
+ }
+ }
+
+ return $result;
+ }
+
+ foreach ($this->matches as $m) {
+ $result[] = $m[0];
+ }
+
+ return $result;
+ }
+
+}
+
diff --git a/program/lib/Roundcube/rcube_spellchecker.php b/program/lib/Roundcube/rcube_spellchecker.php
index df4365223..672515204 100644
--- a/program/lib/Roundcube/rcube_spellchecker.php
+++ b/program/lib/Roundcube/rcube_spellchecker.php
@@ -38,7 +38,7 @@ class rcube_spellchecker
// default settings
- const GOOGLE_HOST = 'ssl://www.google.com';
+ const GOOGLE_HOST = 'ssl://spell.roundcube.net';
const GOOGLE_PORT = 443;
const MAX_SUGGESTIONS = 10;
@@ -84,9 +84,6 @@ class rcube_spellchecker
if ($this->engine == 'pspell') {
$this->matches = $this->_pspell_check($this->content);
}
- else if ($this->engine == 'enchant') {
- $this->matches = $this->_enchant_check($this->content);
- }
else {
$this->matches = $this->_googie_check($this->content);
}
@@ -118,9 +115,6 @@ class rcube_spellchecker
if ($this->engine == 'pspell') {
return $this->_pspell_suggestions($word);
}
- else if ($this->engine == 'enchant') {
- return $this->_enchant_suggestions($word);
- }
return $this->_googie_suggestions($word);
}
@@ -139,9 +133,6 @@ class rcube_spellchecker
if ($this->engine == 'pspell') {
return $this->_pspell_words($text, $is_html);
}
- else if ($this->engine == 'enchant') {
- return $this->_enchant_words($text, $is_html);
- }
return $this->_googie_words($text, $is_html);
}
@@ -323,6 +314,11 @@ class rcube_spellchecker
if (!$this->plink) {
if (!extension_loaded('pspell')) {
$this->error = "Pspell extension not available";
+ rcube::raise_error(array(
+ 'code' => 500, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => $this->error), true, false);
+
return;
}
@@ -335,141 +331,6 @@ class rcube_spellchecker
}
- /**
- * Checks the text using enchant
- *
- * @param string $text Text content for spellchecking
- */
- private function _enchant_check($text)
- {
- // init spellchecker
- $this->_enchant_init();
-
- if (!$this->enchant_dictionary) {
- return array();
- }
-
- // tokenize
- $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
-
- $diff = 0;
- $matches = array();
-
- foreach ($text as $w) {
- $word = trim($w[0]);
- $pos = $w[1] - $diff;
- $len = mb_strlen($word);
-
- // skip exceptions
- if ($this->is_exception($word)) {
- }
- else if (!enchant_dict_check($this->enchant_dictionary, $word)) {
- $suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
-
- if (sizeof($suggestions) > self::MAX_SUGGESTIONS) {
- $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
- }
-
- $matches[] = array($word, $pos, $len, null, $suggestions);
- }
-
- $diff += (strlen($word) - $len);
- }
-
- return $matches;
- }
-
-
- /**
- * Returns the misspelled words
- */
- private function _enchant_words($text = null, $is_html=false)
- {
- $result = array();
-
- if ($text) {
- // init spellchecker
- $this->_enchant_init();
-
- if (!$this->enchant_dictionary) {
- return array();
- }
-
- // With Enchant we don't need to get suggestions to return misspelled words
- if ($is_html) {
- $text = $this->html2text($text);
- }
-
- $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
-
- foreach ($text as $w) {
- $word = trim($w[0]);
-
- // skip exceptions
- if ($this->is_exception($word)) {
- continue;
- }
-
- if (!enchant_dict_check($this->enchant_dictionary, $word)) {
- $result[] = $word;
- }
- }
-
- return $result;
- }
-
- foreach ($this->matches as $m) {
- $result[] = $m[0];
- }
-
- return $result;
- }
-
-
- /**
- * Returns suggestions for misspelled word
- */
- private function _enchant_suggestions($word)
- {
- // init spellchecker
- $this->_enchant_init();
-
- if (!$this->enchant_dictionary) {
- return array();
- }
-
- $suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
-
- if (sizeof($suggestions) > self::MAX_SUGGESTIONS)
- $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
-
- return is_array($suggestions) ? $suggestions : array();
- }
-
-
- /**
- * Initializes PSpell dictionary
- */
- private function _enchant_init()
- {
- if (!$this->enchant_broker) {
- if (!extension_loaded('enchant')) {
- $this->error = "Enchant extension not available";
- return;
- }
-
- $this->enchant_broker = enchant_broker_init();
- }
-
- if (!enchant_broker_dict_exists($this->enchant_broker, $this->lang)) {
- $this->error = "Unable to load dictionary for selected language using Enchant";
- return;
- }
-
- $this->enchant_dictionary = enchant_broker_request_dict($this->enchant_broker, $this->lang);
- }
-
-
private function _googie_check($text)
{
// spell check uri is configured
@@ -493,7 +354,7 @@ class rcube_spellchecker
$gtext = '<?xml version="1.0" encoding="utf-8" ?>'
.'<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
- .'<text>' . $gtext . '</text>'
+ .'<text>' . htmlspecialchars($gtext) . '</text>'
.'</spellrequest>';
$store = '';
@@ -511,19 +372,9 @@ class rcube_spellchecker
fclose($fp);
}
- // parse HTTP response
- if (preg_match('!^HTTP/1.\d (\d+)(.+)!', $store, $m)) {
- $http_status = $m[1];
- if ($http_status != '200')
- $this->error = 'HTTP ' . $m[1] . $m[2];
- }
-
if (!$store) {
$this->error = "Empty result from spelling engine";
}
- else if (preg_match('/<spellresult error="([^"]+)"/', $store, $m) && $m[1]) {
- $this->error = "Error code $m[1] returned";
- }
preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', $store, $matches, PREG_SET_ORDER);
diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php
index e697b2c73..8193e540c 100644
--- a/program/lib/Roundcube/rcube_storage.php
+++ b/program/lib/Roundcube/rcube_storage.php
@@ -61,6 +61,8 @@ abstract class rcube_storage
'MAIL-FOLLOWUP-TO',
'MAIL-REPLY-TO',
'RETURN-PATH',
+ 'DELIVERED-TO',
+ 'ENVELOPE-TO',
);
const UNKNOWN = 0;
@@ -538,13 +540,12 @@ abstract class rcube_storage
/**
* Append a mail message (source) to a specific folder.
*
- * @param string $folder Target folder
- * @param string|array $message The message source string or filename
- * or array (of strings and file pointers)
- * @param string $headers Headers string if $message contains only the body
- * @param boolean $is_file True if $message is a filename
- * @param array $flags Message flags
- * @param mixed $date Message internal date
+ * @param string $folder Target folder
+ * @param string $message The message source string or filename
+ * @param string $headers Headers string if $message contains only the body
+ * @param boolean $is_file True if $message is a filename
+ * @param array $flags Message flags
+ * @param mixed $date Message internal date
*
* @return int|bool Appended message UID or True on success, False on error
*/
@@ -806,14 +807,13 @@ abstract class rcube_storage
/**
- * Returns current status of a folder (compared to the last time use)
+ * Returns current status of a folder
*
* @param string $folder Folder name
- * @param array $diff Difference data
*
* @return int Folder status
*/
- abstract function folder_status($folder = null, &$diff = array());
+ abstract function folder_status($folder = null);
/**
@@ -985,6 +985,6 @@ abstract class rcube_storage
/**
* Delete outdated cache entries
*/
- abstract function cache_gc();
+ abstract function expunge_cache();
} // end class rcube_storage
diff --git a/program/lib/Roundcube/rcube_string_replacer.php b/program/lib/Roundcube/rcube_string_replacer.php
index 354b4596d..bd26f8e7d 100644
--- a/program/lib/Roundcube/rcube_string_replacer.php
+++ b/program/lib/Roundcube/rcube_string_replacer.php
@@ -28,10 +28,9 @@ class rcube_string_replacer
public $mailto_pattern;
public $link_pattern;
private $values = array();
- private $options = array();
- function __construct($options = array())
+ function __construct()
{
// Simplified domain expression for UTF8 characters handling
// Support unicode/punycode in top-level domain part
@@ -45,8 +44,6 @@ class rcube_string_replacer
."@$utf_domain" // domain-part
."(\?[$url1$url2]+)?" // e.g. ?subject=test...
.")/";
-
- $this->options = $options;
}
/**
@@ -92,10 +89,10 @@ class rcube_string_replacer
if ($url) {
$suffix = $this->parse_url_brackets($url);
- $attrib = (array)$this->options['link_attribs'];
- $attrib['href'] = $url_prefix . $url;
-
- $i = $this->add(html::a($attrib, rcube::Q($url)) . $suffix);
+ $i = $this->add(html::a(array(
+ 'href' => $url_prefix . $url,
+ 'target' => '_blank'
+ ), rcube::Q($url)) . $suffix);
}
// Return valid link for recognized schemes, otherwise
diff --git a/program/lib/Roundcube/rcube_user.php b/program/lib/Roundcube/rcube_user.php
index 5e9c9af80..505b190d1 100644
--- a/program/lib/Roundcube/rcube_user.php
+++ b/program/lib/Roundcube/rcube_user.php
@@ -495,9 +495,9 @@ class rcube_user
"INSERT INTO ".$dbh->table_name('users').
" (created, last_login, username, mail_host, language)".
" VALUES (".$dbh->now().", ".$dbh->now().", ?, ?, ?)",
- $data['user'],
- $data['host'],
- $data['language']);
+ strip_newlines($data['user']),
+ strip_newlines($data['host']),
+ strip_newlines($data['language']));
if ($user_id = $dbh->insert_id('users')) {
// create rcube_user instance to make plugin hooks work
@@ -517,7 +517,7 @@ class rcube_user
if (empty($user_email)) {
$user_email = strpos($data['user'], '@') ? $user : sprintf('%s@%s', $data['user'], $mail_domain);
}
- $email_list[] = $user_email;
+ $email_list[] = strip_newlines($user_email);
}
// identities_level check
else if (count($email_list) > 1 && $rcube->config->get('identities_level', 0) > 1) {
@@ -547,6 +547,7 @@ class rcube_user
$record['name'] = $user_name != $record['email'] ? $user_name : '';
}
+ $record['name'] = strip_newlines($record['name']);
$record['user_id'] = $user_id;
$record['standard'] = $standard;
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
index 1d76ae508..4dadbb8bd 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -400,7 +400,7 @@ class rcube_utils
$out = array();
$src = $mode == self::INPUT_GET ? $_GET : ($mode == self::INPUT_POST ? $_POST : $_REQUEST);
- foreach (array_keys($src) as $key) {
+ foreach ($src as $key => $value) {
$fname = $key[0] == '_' ? substr($key, 1) : $key;
if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname)) {
$out[$fname] = self::get_input_value($key, $mode);
@@ -476,9 +476,9 @@ class rcube_utils
// remove html comments and add #container to each tag selector.
// also replace body definition because we also stripped off the <body> tag
- $styles = preg_replace(
+ $source = preg_replace(
array(
- '/(^\s*<!--)|(-->\s*$)/',
+ '/(^\s*<\!--)|(-->\s*$)/m',
'/(^\s*|,\s*|\}\s*)([a-z0-9\._#\*][a-z0-9\.\-_]*)/im',
'/'.preg_quote($container_id, '/').'\s+body/i',
),
@@ -490,9 +490,9 @@ class rcube_utils
$source);
// put block contents back in
- $styles = $replacements->resolve($styles);
+ $source = $replacements->resolve($source);
- return $styles;
+ return $source;
}
@@ -506,24 +506,17 @@ class rcube_utils
*/
public static function file2class($mimetype, $filename)
{
- $mimetype = strtolower($mimetype);
- $filename = strtolower($filename);
-
list($primary, $secondary) = explode('/', $mimetype);
$classes = array($primary ? $primary : 'unknown');
-
if ($secondary) {
$classes[] = $secondary;
}
-
- if (preg_match('/\.([a-z0-9]+)$/', $filename, $m)) {
- if (!in_array($m[1], $classes)) {
- $classes[] = $m[1];
- }
+ if (preg_match('/\.([a-z0-9]+)$/i', $filename, $m)) {
+ $classes[] = $m[1];
}
- return join(" ", $classes);
+ return strtolower(join(" ", $classes));
}
@@ -666,21 +659,6 @@ class rcube_utils
/**
- * Returns the real remote IP address
- *
- * @return string Remote IP address
- */
- public static function remote_addr()
- {
- foreach (array('HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP','REMOTE_ADDR') as $prop) {
- if (!empty($_SERVER[$prop]))
- return $_SERVER[$prop];
- }
-
- return '';
- }
-
- /**
* Read a specific HTTP request header.
*
* @param string $name Header name
@@ -761,9 +739,9 @@ class rcube_utils
// Clean malformed data
$date = preg_replace(
array(
- '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal
- '/[^a-z0-9\x20\x09:+-]/i', // remove any invalid characters
- '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names
+ '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal
+ '/[^a-z0-9\x20\x09:+-]/i', // remove any invalid characters
+ '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names
),
array(
'\\1',
@@ -771,8 +749,6 @@ class rcube_utils
'',
), $date);
- $date = trim($date);
-
// if date parsing fails, we have a date in non-rfc format.
// remove token from the end and try again
while ((($ts = @strtotime($date)) === false) || ($ts < 0)) {
@@ -787,44 +763,6 @@ class rcube_utils
return (int) $ts;
}
- /**
- * Date parsing function that turns the given value into a DateTime object
- *
- * @param string $date Date string
- *
- * @return object DateTime instance or false on failure
- */
- public static function anytodatetime($date)
- {
- if (is_object($date) && is_a($date, 'DateTime')) {
- return $date;
- }
-
- $dt = false;
- $date = trim($date);
-
- // try to parse string with DateTime first
- if (!empty($date)) {
- try {
- $dt = new DateTime($date);
- }
- catch (Exception $e) {
- // ignore
- }
- }
-
- // try our advanced strtotime() method
- if (!$dt && ($timestamp = self::strtotime($date))) {
- try {
- $dt = new DateTime("@".$timestamp);
- }
- catch (Exception $e) {
- // ignore
- }
- }
-
- return $dt;
- }
/*
* Idn_to_ascii wrapper.
diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php
index d54dc56ad..f76c4f08d 100644
--- a/program/lib/Roundcube/rcube_vcard.php
+++ b/program/lib/Roundcube/rcube_vcard.php
@@ -47,7 +47,6 @@ class rcube_vcard
'manager' => 'X-MANAGER',
'spouse' => 'X-SPOUSE',
'edit' => 'X-AB-EDIT',
- 'groups' => 'CATEGORIES',
);
private $typemap = array(
'IPHONE' => 'mobile',
@@ -358,8 +357,8 @@ class rcube_vcard
case 'birthday':
case 'anniversary':
- if (($val = rcube_utils::anytodatetime($value)) && ($fn = self::$fieldmap[$field])) {
- $this->raw[$fn][] = array(0 => $val->format('Y-m-d'), 'value' => array('date'));
+ if (($val = rcube_utils::strtotime($value)) && ($fn = self::$fieldmap[$field])) {
+ $this->raw[$fn][] = array(0 => date('Y-m-d', $val), 'value' => array('date'));
}
break;
@@ -482,7 +481,7 @@ class rcube_vcard
$vcard_block = '';
$in_vcard_block = false;
- foreach (preg_split("/[\r\n]+/", $data) as $line) {
+ foreach (preg_split("/[\r\n]+/", $data) as $i => $line) {
if ($in_vcard_block && !empty($line)) {
$vcard_block .= $line . "\n";
}
@@ -612,8 +611,8 @@ class rcube_vcard
$enc = null;
foreach($regs2[1] as $attrid => $attr) {
+ $attr = preg_replace('/[\s\t\n\r\0\x0B]/', '', $attr);
if ((list($key, $value) = explode('=', $attr)) && $value) {
- $value = trim($value);
if ($key == 'ENCODING') {
$value = strtoupper($value);
// add next line(s) to value string if QP line end detected
@@ -757,7 +756,7 @@ class rcube_vcard
*
* @return string Joined and quoted string
*/
- public static function vcard_quote($s, $sep = ';')
+ private static function vcard_quote($s, $sep = ';')
{
if (is_array($s)) {
foreach($s as $part) {
@@ -766,7 +765,7 @@ class rcube_vcard
return(implode($sep, (array)$r));
}
- return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', $sep => '\\'.$sep));
+ return strtr($s, array('\\' => '\\\\', "\r" => '', "\n" => '\n', ',' => '\,', ';' => '\;'));
}
/**
@@ -792,7 +791,7 @@ class rcube_vcard
return $result;
}
- $s = strtr($s, $rep2);
+ $s = trim(strtr($s, $rep2));
}
// some implementations (GMail) use non-standard backslash before colon (#1489085)
diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php
index 8f7fe9749..f964f8b35 100644
--- a/program/lib/Roundcube/rcube_washtml.php
+++ b/program/lib/Roundcube/rcube_washtml.php
@@ -410,25 +410,6 @@ class rcube_washtml
);
$html = preg_replace($html_search, $html_replace, trim($html));
- //-> Replace all of those weird MS Word quotes and other high characters
- $badwordchars=array(
- "\xe2\x80\x98", // left single quote
- "\xe2\x80\x99", // right single quote
- "\xe2\x80\x9c", // left double quote
- "\xe2\x80\x9d", // right double quote
- "\xe2\x80\x94", // em dash
- "\xe2\x80\xa6" // elipses
- );
- $fixedwordchars=array(
- "'",
- "'",
- '"',
- '"',
- '&mdash;',
- '...'
- );
- $html = str_replace($badwordchars,$fixedwordchars, $html);
-
// PCRE errors handling (#1486856), should we use something like for every preg_* use?
if ($html === null && ($preg_error = preg_last_error()) != PREG_NO_ERROR) {
$errstr = "Could not clean up HTML message! PCRE Error: $preg_error.";
@@ -448,7 +429,7 @@ class rcube_washtml
}
// fix (unknown/malformed) HTML tags before "wash"
- $html = preg_replace_callback('/(<[\/]*)([^\s>]+)/', array($this, 'html_tag_callback'), $html);
+ $html = preg_replace_callback('/(<(?!\!)[\/]*)([^\s>]+)/', array($this, 'html_tag_callback'), $html);
// Remove invalid HTML comments (#1487759)
// Don't remove valid conditional comments
diff --git a/program/localization/ar_SA/labels.inc b/program/localization/ar_SA/labels.inc
index bc1764b0f..af08cc301 100644
--- a/program/localization/ar_SA/labels.inc
+++ b/program/localization/ar_SA/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'المسودات';
$labels['sent'] = 'المرسل';
$labels['trash'] = 'المهملات';
$labels['junk'] = 'غير المرغوب';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'الموضوع';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'وضع طريقة السرد';
$labels['folderactions'] = 'إجراءات المجلد...';
$labels['compact'] = 'ضغط';
$labels['empty'] = 'تÙريغ';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'المساحة المستخدمة';
$labels['unknown'] = 'مجهول';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'استعادة البحث للاÙتراضي';
$labels['searchmod'] = 'أماكن البحث';
$labels['msgtext'] = 'كامل الرسالة';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'اÙتح ÙÙŠ ناÙذة جديدة';
$labels['emlsave'] = 'تنزيل (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'عرض المجموعة الأخيرة';
$labels['group'] = 'مجموعة';
$labels['groups'] = 'المجموعات';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'العناوين الشخصية';
$labels['searchsave'] = 'Ø­Ùظ البحث';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'تجاهل الكلمات التي تحتوي
$labels['spellcheckignorecaps'] = 'تجاهل الكلمات التي بها أحر٠كبيرة';
$labels['addtodict'] = 'إضاÙØ© إلى القامس';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ar_SA/messages.inc b/program/localization/ar_SA/messages.inc
index f989867de..9429a3910 100644
--- a/program/localization/ar_SA/messages.inc
+++ b/program/localization/ar_SA/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'إزالة التنسيق من الرسالة...';
$messages['messageopenerror'] = 'تعذرت قراءة الرسالة من الخادم';
$messages['fileuploaderror'] = 'Ùشل رÙع الملÙ';
$messages['filesizeerror'] = 'حجم المل٠الذي تحاول رÙعه أكبر من الحجمالأقصى $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'تم نسخ $nr رسائل بنجاح';
+$messages['copyerror'] = 'لم يمكن نسخ أية عناوين';
$messages['sourceisreadonly'] = 'لا يمكن تعديل مصدر العنوان هذا';
$messages['errorsavingcontact'] = 'تعذر Ø­Ùظ عنوان المراسل';
$messages['movingmessage'] = 'جاري نقل الرسالة...';
$messages['copyingmessage'] = 'جاري نسخ الرسالة...';
$messages['copyingcontact'] = 'جاري نسخ المÙراسلين...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'جاري حذ٠الرسائل...';
$messages['markingmessage'] = 'جاري تحديد الرسائل...';
$messages['addingmember'] = 'جاري إضاÙØ© المÙراسلين إلى المجموعة...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'جاري الاستيراد، رجاء انتظر...'
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>تم استيراد $inserted مراسلين بنجاح، وتجاهل$skipped موجودين مسبقاً</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>تم تجاهل $skipped عناصر موجودة</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'العملية ممنوعة!';
$messages['nofromaddress'] = 'عنوان البريد الالكتروني غير محدد Ùيالهويّة المنتقاة';
$messages['editorwarning'] = 'يتسبب الانتقال إلى محرر النص البسيط بضياع جميع التنسيق. هل تريد الاستمرار؟';
diff --git a/program/localization/ast/labels.inc b/program/localization/ast/labels.inc
index 8c1985eef..49f85689b 100644
--- a/program/localization/ast/labels.inc
+++ b/program/localization/ast/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Unviaos';
$labels['trash'] = 'Papelera';
$labels['junk'] = 'Puxarra';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Asuntu';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compautar';
$labels['empty'] = 'Vaciar';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Espaciu en discu';
$labels['unknown'] = 'desconocíu';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Anovar la búsqueda';
$labels['searchmod'] = 'Guetar modificadores';
$labels['msgtext'] = 'Mensax completu';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir en una ventana nueva';
$labels['emlsave'] = 'Baxar (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Amosar l\'últimu grupu';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupos';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Direiciones personales';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ast/messages.inc b/program/localization/ast/messages.inc
index 512316c18..9e415b8ec 100644
--- a/program/localization/ast/messages.inc
+++ b/program/localization/ast/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Desaniciando\'l formatu del mensaxe...';
$messages['messageopenerror'] = 'Nun soi a baxer el mensaxe del sirvidor';
$messages['fileuploaderror'] = 'Fallu al xubir ficheros';
$messages['filesizeerror'] = 'El ficheru ye más grande de lo permitío ($size)';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Copiaronse $nr direiciones correchamente';
+$messages['copyerror'] = 'Nun fui a copiar nenguna direición';
$messages['sourceisreadonly'] = 'Esta direición ye de namái-llectura';
$messages['errorsavingcontact'] = 'Nun fui a guardar la direición del contautu';
$messages['movingmessage'] = 'Moviendo\'l mensaxe...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importando, dame un minutín...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Importaronse correchamente $inserted contautos, saltáronse $skipped entrase que yá esistíen</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Nun tienes permisu pa facelo.';
$messages['nofromaddress'] = 'Perdiose la direición de corréu de la identidá qu\'escoyisti';
$messages['editorwarning'] = 'Si pases a editor en modu testu vas perder tol estilu aplicáu al mensaxe. ¿Tas seguru de que quies facelo?';
diff --git a/program/localization/az_AZ/labels.inc b/program/localization/az_AZ/labels.inc
index 129315ec0..0cb4b3e82 100644
--- a/program/localization/az_AZ/labels.inc
+++ b/program/localization/az_AZ/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Qaralamalar';
$labels['sent'] = 'Göndərilənlər';
$labels['trash'] = 'Səbət';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Mövzu';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Görünüş rejimi';
$labels['folderactions'] = 'Qovluq işləri...';
$labels['compact'] = 'Sıx';
$labels['empty'] = 'BoÅŸalt';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk istifadəsi';
$labels['unknown'] = 'naməlum';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Axtarışı yenilə';
$labels['searchmod'] = 'Axtarış variantları';
$labels['msgtext'] = 'Bütün məktub';
$labels['body'] = 'Mətn';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Yeni pəncərədə aç';
$labels['emlsave'] = 'Saxla (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Sonuncunu göstər';
$labels['group'] = 'Qrup';
$labels['groups'] = 'Qruplar';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Şəxsi ünvanlar';
$labels['searchsave'] = 'SorÄŸunu saxla';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Rəqəmlər ilə sözləri keç';
$labels['spellcheckignorecaps'] = 'Böyük hərfləri olan sözlərdən keç';
$labels['addtodict'] = 'Lüğətə əlavə et';
$labels['mailtoprotohandler'] = 'mailto: keçid üçün protokol qeyd et';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Məktubların yönəldilməsi';
$labels['inline'] = 'mətndə';
$labels['asattachment'] = 'fayl kimi';
diff --git a/program/localization/az_AZ/messages.inc b/program/localization/az_AZ/messages.inc
index 745836e5f..418f270be 100644
--- a/program/localization/az_AZ/messages.inc
+++ b/program/localization/az_AZ/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Məktubun formatlaşması silinir...';
$messages['messageopenerror'] = 'Məktubu serverdən yükləmək alınmır';
$messages['fileuploaderror'] = 'Fayl yüklənilmədi';
$messages['filesizeerror'] = 'Yüklənilən fayl maksimal ölçüdən çoxdur - $size';
-$messages['copysuccess'] = '$nr kontaktlar uğurlar kopyalanmışdır.';
-$messages['movesuccess'] = '$nr kontaktlar uğurla köçürülmüşdür.';
-$messages['copyerror'] = 'Heç bir kontaktı kopyalamaq olmur.';
-$messages['moveerror'] = 'Heç bir kontaktı köçürmək alınmır.';
+$messages['copysuccess'] = '$nr ünvan kopyalandı';
+$messages['copyerror'] = 'Ünvanları kopyalamaq alınmır';
$messages['sourceisreadonly'] = 'Verilən ünvanlar mənbəyi yalnız oxunmaq üçün';
$messages['errorsavingcontact'] = 'ÆlaqÉ™ni ünvanda saxlamaq mümkün deyil';
$messages['movingmessage'] = 'Məktub köçürülür...';
$messages['copyingmessage'] = 'Məktub kopyalanır...';
$messages['copyingcontact'] = 'Kontakt(lar)ın kopyalanması...';
-$messages['movingcontact'] = 'Kontak(lar)ın köçürülməsi...';
$messages['deletingmessage'] = 'Məktub(lar) silinir...';
$messages['markingmessage'] = 'Məktub(lar) işarələnir...';
$messages['addingmember'] = 'Kontakt(lar)ın qrupa əlavə edilməsi...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'İdxal gedir, lütfən gözləyin...';
$messages['importformaterror'] = 'İdxal xətası. Yüklənilən fayl naməlum məlumat formatına malikdir.';
$messages['importconfirm'] = '<b>$inserted ünvanlar müvəffəqiyyətlə idxal edildi, mövcud $skipped buraxılıb</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Buraxılmış $skipped mövcud daxillər</b>';
-$messages['importmessagesuccess'] = '$nr məktublar uğurla idxal edildi';
-$messages['importmessageerror'] = 'İdxal alınmadı! Yüklənilmiş fayl düzgün məktub və ya poçt faylı deyil';
$messages['opnotpermitted'] = 'ÆmÉ™liyyat qadaÄŸandır!';
$messages['nofromaddress'] = 'Seçilmiş kimlikdə e-poçt ünvanları yoxdur';
$messages['editorwarning'] = 'Adi mətn redaktoruna keçid, bütün mətn formatlarının itkisinə gətirəcək. Davam edilsin?';
diff --git a/program/localization/be_BE/labels.inc b/program/localization/be_BE/labels.inc
index 56339a926..a5489a454 100644
--- a/program/localization/be_BE/labels.inc
+++ b/program/localization/be_BE/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Чарнавікі';
$labels['sent'] = 'ДаÑланыÑ';
$labels['trash'] = 'Сметніца';
$labels['junk'] = 'Спам';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ТÑма';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/be_BE/messages.inc b/program/localization/be_BE/messages.inc
index c4033dad9..73cdb3ed8 100644
--- a/program/localization/be_BE/messages.inc
+++ b/program/localization/be_BE/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'File upload failed.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/bg_BG/labels.inc b/program/localization/bg_BG/labels.inc
index dd5be6e64..6542cfc53 100644
--- a/program/localization/bg_BG/labels.inc
+++ b/program/localization/bg_BG/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Чернови';
$labels['sent'] = 'Изпратени';
$labels['trash'] = 'Кошче';
$labels['junk'] = 'Спам';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Заглавие';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Кратък ÑпиÑък';
$labels['folderactions'] = 'ДейÑÑ‚Ð²Ð¸Ñ Ð·Ð° папки...';
$labels['compact'] = 'Свиване';
$labels['empty'] = 'Изпразни';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Използвано мÑÑто';
$labels['unknown'] = 'нÑма информациÑ';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'ИзчиÑти Ñ‚ÑŠÑ€Ñенето и покажи вÑ
$labels['searchmod'] = 'ТърÑене във';
$labels['msgtext'] = 'ЦÑлото Ñъобщение';
$labels['body'] = 'ОÑновен текÑÑ‚';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори в нов прозорец';
$labels['emlsave'] = 'Изтегли като .eml';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'ПоÑледна Ñтраница';
$labels['group'] = 'Група';
$labels['groups'] = 'Групи';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Лични адреÑи';
$labels['searchsave'] = 'Запази Ñ‚ÑŠÑ€Ñенето';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Игнорирай думи ÑъдържащÐ
$labels['spellcheckignorecaps'] = 'Игнорирай думи Ñъдържащи единÑтвено главни букви';
$labels['addtodict'] = 'Добави в речника';
$labels['mailtoprotohandler'] = 'РегиÑтриран протокол за mailto: връзките';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Препращане на ÑъобщениÑ';
$labels['inline'] = 'вградено';
$labels['asattachment'] = 'като прикачен файл';
diff --git a/program/localization/bg_BG/messages.inc b/program/localization/bg_BG/messages.inc
index 5b6e7a596..219772e74 100644
--- a/program/localization/bg_BG/messages.inc
+++ b/program/localization/bg_BG/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Премахване форматирането на
$messages['messageopenerror'] = 'ПиÑмото не може да бъде заредено от Ñървъра';
$messages['fileuploaderror'] = 'Грешка при прикачването на файла';
$messages['filesizeerror'] = 'ПрикачениÑÑ‚ файл надвишава лимита от $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'УÑпешно копирани $nr адреÑа';
+$messages['copyerror'] = 'Грешка при копирането на адреÑите';
$messages['sourceisreadonly'] = 'Този източник на адреÑи е Ñамо за четене';
$messages['errorsavingcontact'] = 'Грешка при запиÑването на адреÑа';
$messages['movingmessage'] = 'ПремеÑтване на Ñъобщение...';
$messages['copyingmessage'] = 'Копиране на Ñъобщение(Ñ)...';
$messages['copyingcontact'] = 'Копиране на контакт(и)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Изтриване на Ñъобщение(Ñ)...';
$messages['markingmessage'] = 'Маркиране на Ñъобщение(Ñ)...';
$messages['addingmember'] = 'ДобавÑне на контакт(и) в групата...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Импорт, Ð¼Ð¾Ð»Ñ Ð¸Ð·Ñ‡Ð°ÐºÐ°Ð¹Ñ‚Ðµ...';
$messages['importformaterror'] = 'Импорта пропадна! КачениÑÑ‚ файл не е Ñ Ð²Ð°Ð»Ð¸Ð´Ð½Ð¸ данни.';
$messages['importconfirm'] = '<b>УÑпешно Ñа импортирани $inserted контакта, вече ÑъщеÑтвуващите $skipped контакта Ñа пропуÑнати</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = 'b>СъщеÑтвуващите запиÑи $skipped Ñа пропуÑнати</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'ОперациÑта не е позволена!';
$messages['nofromaddress'] = 'ЛипÑва e-mail Ð°Ð´Ñ€ÐµÑ Ð·Ð° избраната ÑамоличноÑÑ‚';
$messages['editorwarning'] = 'Превключването на редактора в текÑтов режим ще доведе до загуба на форматирането на текÑа. Сигурни ли Ñте, че иÑкате да продължите?';
diff --git a/program/localization/bn_BD/labels.inc b/program/localization/bn_BD/labels.inc
index 1273ef192..a0866a3a7 100644
--- a/program/localization/bn_BD/labels.inc
+++ b/program/localization/bn_BD/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'খসড়া';
$labels['sent'] = 'পà§à¦°à§‡à¦°à¦¿à¦¤(পাঠানো মেইল)';
$labels['trash'] = 'ডাসà§à¦Ÿà¦¬à¦¿à¦¨';
$labels['junk'] = 'আজেবাজে মেইল';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'বিষয়';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'টাইটকরà§à¦¨';
$labels['empty'] = 'খালিকরà§à¦¨';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ডিসà§à¦• ঠখালি যায়গা';
$labels['unknown'] = 'অজানা';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'নতà§à¦¨à¦•à¦°à§‡ খà§à¦œà§à¦¨';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'নতà§à¦¨ উইনà§à¦¡à§‹ তে দেখà§à¦¨';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'শেষের গà§à¦²à§‹ দেখান';
$labels['group'] = 'Group';
$labels['groups'] = 'গà§à¦°à§à¦ª';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'নিজের ঠিকানা';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/bn_BD/messages.inc b/program/localization/bn_BD/messages.inc
index 9de6c38de..44d5fcc60 100644
--- a/program/localization/bn_BD/messages.inc
+++ b/program/localization/bn_BD/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'বিনà§à¦¯à¦¾à¦¸ (formatting) সরানো à¦
$messages['messageopenerror'] = 'সারভার থেকে চিঠি আনা গেলোনা';
$messages['fileuploaderror'] = 'ফাইলটা সারভারে উঠানো গেলোনা';
$messages['filesizeerror'] = 'যে ফাইলটা উঠানোর চেষà§à¦Ÿà¦¾ করলেন সেটি সরà§à¦¬à§‹à¦šà§à¦š সাইজ $size à¦à¦° থেকে বেশি';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'ঠিকঠাকমতো $nr ঠিকানা নকল করে নেওয়া গেছে';
+$messages['copyerror'] = 'কোনো ঠিকানা তোলা গেলোনা';
$messages['sourceisreadonly'] = 'à¦à¦‡à¦ à¦¿à¦•à¦¾à¦¨à¦¾à¦Ÿà¦¾ খালি পড়ার জনà§à¦¯à§‡';
$messages['errorsavingcontact'] = 'ঠিকানা জমা রাখা গেলোনা';
$messages['movingmessage'] = 'চিঠি সরানো হচà§à¦›à§‡..';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'আমদানি করা হচà§à¦›à§‡à¥¤ à¦à¦
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>ঠিকমতো $inserted ঠিকানা আমদানি করা গেছে, $skipped ঠিকানা আগের থেকেই ছিলো বলে তাদের টা যা ছিলো তাই রাখা হয়েছে</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'à¦à¦‡ কাজটা করার অনà§à¦®à¦¤à¦¿ নাই আপনার';
$messages['nofromaddress'] = 'বেছে নেওয়া যে পরিচিতিটা, তাতে ই-মেইল নেই';
$messages['editorwarning'] = 'যদি আপনি শà§à¦§à§ লেখার সà§à¦Ÿà¦¾à¦‡à¦²à§‡ যান তাহলে বরà§à¦¤à¦®à¦¾à¦¨à§‡à¦° কোনো বিনà§à¦¯à¦¾à¦¸ হারিয়ে যাবে';
diff --git a/program/localization/br/labels.inc b/program/localization/br/labels.inc
index c88fd92a6..537a887df 100644
--- a/program/localization/br/labels.inc
+++ b/program/localization/br/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Brouilhedoù';
$labels['sent'] = 'Kaset';
$labels['trash'] = 'Pod-lastez';
$labels['junk'] = 'Stroboù';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Sujed';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Stummaat';
$labels['empty'] = 'Skarzhañ';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Implijadur pladenn';
$labels['unknown'] = 'Dianav';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Aderaouekaat ar glask';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Gwelout ar bajenn diwezhañ';
$labels['group'] = 'Group';
$labels['groups'] = 'Strolladoù';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Chomlec\'h personel';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/br/messages.inc b/program/localization/br/messages.inc
index fd1674d80..c1988577d 100644
--- a/program/localization/br/messages.inc
+++ b/program/localization/br/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'O tilemel furmaozañ...';
$messages['messageopenerror'] = 'N\'us ket tu da gargañ ar c\'hemennad adalek ar servijer';
$messages['fileuploaderror'] = 'Fazi o treuzkas ar restr';
$messages['filesizeerror'] = 'Re vras eo ar restr treuzkaset $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Kopiañ mat $nr chomlec\'h';
+$messages['copyerror'] = 'Ne c\'hall ket kopiañ chomlec\'hioù';
$messages['sourceisreadonly'] = 'Lenn hepken eo an tarzh chomlec\'h se';
$messages['errorsavingcontact'] = 'Ne c\'haller ket gwarediñ chomlec\'h darempred';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/bs_BA/labels.inc b/program/localization/bs_BA/labels.inc
index 61989e6b3..5afdcad1f 100644
--- a/program/localization/bs_BA/labels.inc
+++ b/program/localization/bs_BA/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Skice';
$labels['sent'] = 'Poslano';
$labels['trash'] = 'Smeće';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Prikaži prava imena specijalnih foldera';
// message listing
$labels['subject'] = 'Naslov';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'NaÄin prikaza liste';
$labels['folderactions'] = 'Akcije za foldere...';
$labels['compact'] = 'Optimiziraj';
$labels['empty'] = 'Isprazni';
-$labels['importmessages'] = 'Uvezi poruke';
$labels['quota'] = 'Zauzeće diska';
$labels['unknown'] = 'nepoznato';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Resetuj pretragu';
$labels['searchmod'] = 'Modifikacija pretrage';
$labels['msgtext'] = 'Cijela poruka';
$labels['body'] = 'Tijelo';
-$labels['type'] = 'Vrsta';
$labels['openinextwin'] = 'Otvori u novom prozoru';
$labels['emlsave'] = 'Preuzmi (.eml)';
@@ -226,7 +223,7 @@ $labels['mailreplyintro'] = '$date, $sender je napisao/la:';
$labels['originalmessage'] = 'Originalna poruka';
$labels['editidents'] = 'Uredi identitete';
-$labels['spellcheck'] = 'Pravopis';
+$labels['spellcheck'] = 'Spelovanje';
$labels['checkspelling'] = 'Provjera pravopisa';
$labels['resumeediting'] = 'Nastavi uređivanje';
$labels['revertto'] = 'Vrati na';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Prikaži zadnju stranicu';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupe';
-$labels['listgroup'] = 'Izlistaj Älanove grupe';
$labels['personaladrbook'] = 'LiÄne adrese';
$labels['searchsave'] = 'SaÄuvaj pretragu';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Zanemari rijeÄi sa brojevima';
$labels['spellcheckignorecaps'] = 'Zanemari rijeÄi napisane velikim slovima';
$labels['addtodict'] = 'Dodaj u rjeÄnik';
$labels['mailtoprotohandler'] = 'Registruj upravljaÄ protokola za mailto: linkovi';
-$labels['standardwindows'] = 'Tretiraj popup-ove kao standardne prozore';
$labels['forwardmode'] = 'Prosljeđivanje poruka';
$labels['inline'] = 'u istom redu';
$labels['asattachment'] = 'kao prilog';
diff --git a/program/localization/bs_BA/messages.inc b/program/localization/bs_BA/messages.inc
index 09e6df19e..7a1b26168 100644
--- a/program/localization/bs_BA/messages.inc
+++ b/program/localization/bs_BA/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Uklanjam formatiranje...';
$messages['messageopenerror'] = 'Nije moguće uÄitati poruku sa servera.';
$messages['fileuploaderror'] = 'Dodavanje datoteke nije uspjelo.';
$messages['filesizeerror'] = 'Datoteka je prevelika. Maksimalna veliÄina je $size.';
-$messages['copysuccess'] = 'Uspješno kopirano $nr kontakata.';
-$messages['movesuccess'] = 'Uspješno premješteno $nr kontakata.';
-$messages['copyerror'] = 'Nije moguće kopirati kontakte.';
-$messages['moveerror'] = 'Nije moguće premjestiti kontakte.';
+$messages['copysuccess'] = 'Uspješno kopirano $n adresa.';
+$messages['copyerror'] = 'Nije moguće kopirati adrese.';
$messages['sourceisreadonly'] = 'Ovaj izvor adresa je samo za Äitanje.';
$messages['errorsavingcontact'] = 'Nije moguće saÄuvati kontakt adresu.';
$messages['movingmessage'] = 'Premještam poruke...';
$messages['copyingmessage'] = 'Kopiram poruke...';
$messages['copyingcontact'] = 'Kopiram kontakte...';
-$messages['movingcontact'] = 'Premještam kontakte...';
$messages['deletingmessage'] = 'Brišem poruke...';
$messages['markingmessage'] = 'OznaÄavam poruke...';
$messages['addingmember'] = 'Dodajem kontakte u grupu...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Uvoz u toku, molimo saÄekajte...';
$messages['importformaterror'] = 'Uvoz nije uspio! Dodana datoteka nije u ispravnom formatu za uvoz podataka.';
$messages['importconfirm'] = '<b>Uspješno je uvezeno $inserted kontakata</b>';
$messages['importconfirmskipped'] = '<b>PreskoÄeno $skipped postojećih unosa</b>';
-$messages['importmessagesuccess'] = 'Uspješno uvezeno $nr poruka';
-$messages['importmessageerror'] = 'Uvoz nije uspio! Dodana datoteke nije ispravna datoteka sa porukama';
$messages['opnotpermitted'] = 'Operacija nije dozvoljena!';
$messages['nofromaddress'] = 'U odabrani identitet nije upisana email adresa.';
$messages['editorwarning'] = 'Prebacivanje u obiÄni tekstualni ureÄ‘ivaÄ Ä‡e prouzrokovati gubljenje formatiranja teksta. Želite li nastaviti?';
diff --git a/program/localization/ca_ES/labels.inc b/program/localization/ca_ES/labels.inc
index ca0129de4..3be753b68 100644
--- a/program/localization/ca_ES/labels.inc
+++ b/program/localization/ca_ES/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Esborranys';
$labels['sent'] = 'Enviats';
$labels['trash'] = 'Paperera';
$labels['junk'] = 'Correu brossa';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Assumpte';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Mode de vista de llista';
$labels['folderactions'] = 'Accions de carpeta';
$labels['compact'] = 'Compacta';
$labels['empty'] = 'Buida';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ús del disc';
$labels['unknown'] = 'desconegut';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Neteja cerca';
$labels['searchmod'] = 'Cerca modificadors';
$labels['msgtext'] = 'Missatge sencer';
$labels['body'] = 'Cos';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Obre a una nova finestra';
$labels['emlsave'] = 'Descarrega (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Mostra la darrera pàgina';
$labels['group'] = 'Grup';
$labels['groups'] = 'Grups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Llibreta d\'adreces';
$labels['searchsave'] = 'Desa la cerca';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignora paraules amb números';
$labels['spellcheckignorecaps'] = 'Ignora paraules amb lletres capitalitzades';
$labels['addtodict'] = 'Afegeix al diccionari';
$labels['mailtoprotohandler'] = 'Registra controlador de protocol pels enllaços mailto:';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Reenviament de missatges';
$labels['inline'] = 'en línia';
$labels['asattachment'] = 'com adjunt';
diff --git a/program/localization/ca_ES/messages.inc b/program/localization/ca_ES/messages.inc
index 9ee32d54e..70c3fbd0c 100644
--- a/program/localization/ca_ES/messages.inc
+++ b/program/localization/ca_ES/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'S\'està traient el format del missatge...';
$messages['messageopenerror'] = 'No s\'ha pogut carregar el missatge del servidor.';
$messages['fileuploaderror'] = 'La pujada del fitxer ha fallat.';
$messages['filesizeerror'] = 'El fitxer pujat excedeix la mida màxima de $size.';
-$messages['copysuccess'] = 'S\'han copiat $nr contactes correctament.';
-$messages['movesuccess'] = 'S\'han mogut $nr contactes correctament.';
-$messages['copyerror'] = 'No s\'ha pogut copiar cap contacte.';
-$messages['moveerror'] = 'No s\'ha pogut moure cap contacte.';
+$messages['copysuccess'] = 'S\'han copiat $nr adreces correctament.';
+$messages['copyerror'] = 'No s\'ha pogut copiar cap adreça.';
$messages['sourceisreadonly'] = 'Aquesta adreça és només de lectura.';
$messages['errorsavingcontact'] = 'No s\'ha pogut desar l\'adreça de contacte.';
$messages['movingmessage'] = 'S\'està movent missatge(s)...';
$messages['copyingmessage'] = 'S\'està copiant missatge(s)...';
$messages['copyingcontact'] = 'S\'està copiant contacte(s)...';
-$messages['movingcontact'] = 'S\'estan movent els contacte(s)...';
$messages['deletingmessage'] = 'S\'està suprimint missatge(s)...';
$messages['markingmessage'] = 'S\'està marcant missatge(s)...';
$messages['addingmember'] = 'S\'està afegint contacte(s) al grup...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'S\'està important, espereu si us plau...';
$messages['importformaterror'] = 'La importació ha fallat. El fitxer pujat no és un fitxer de dades vàlid.';
$messages['importconfirm'] = '<b>S\'han importat $inserted contactes correctament</b>';
$messages['importconfirmskipped'] = '<b>S\'han descartat $skipped entrades ja existents</b>';
-$messages['importmessagesuccess'] = '<b>S\'han importat $nr missatges correctament</b>';
-$messages['importmessageerror'] = 'La importació ha fallat. El fitxer que heu pujat no és un fitxer de missatges vàlid o no és un fitxer de bústia.';
$messages['opnotpermitted'] = 'Operació no permesa!';
$messages['nofromaddress'] = 'Falta l\'adreça de correu a la identitat seleccionada.';
$messages['editorwarning'] = 'Si canvieu a l\'editor de text pla perdreu tot el format del text. Voleu continuar?';
diff --git a/program/localization/cs_CZ/labels.inc b/program/localization/cs_CZ/labels.inc
index b5cc093d8..8fb7ffade 100644
--- a/program/localization/cs_CZ/labels.inc
+++ b/program/localization/cs_CZ/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Rozepsané';
$labels['sent'] = 'Odeslané';
$labels['trash'] = 'Koš';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Zobrazit skuteÄná jména speciálních složek';
// message listing
$labels['subject'] = 'Předmět';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Režim zobrazení seznamu';
$labels['folderactions'] = 'Akce se složkou...';
$labels['compact'] = 'Zmenšit';
$labels['empty'] = 'Vymazat';
-$labels['importmessages'] = 'Import zpráv';
$labels['quota'] = 'Využití schránky';
$labels['unknown'] = 'neznámý';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Zrušit vyhledávání';
$labels['searchmod'] = 'Parametry hledání';
$labels['msgtext'] = 'Celá zpráva';
$labels['body'] = 'Tělo';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otevřít v novém okně';
$labels['emlsave'] = 'Stáhnout (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Zobrazit poslední zprávy';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupiny';
-$labels['listgroup'] = ' Seznam Älenů skupiny';
$labels['personaladrbook'] = 'Osobní kontakty';
$labels['searchsave'] = 'Uložit hledání';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'Vytvářet HTML zprávy';
$labels['htmlonreply'] = 'jen při odpovědi na HTML zprávy';
$labels['htmlonreplyandforward'] = 'při přeposlání nebo odpovědi na HTML zprávu';
$labels['htmlsignature'] = 'HTML podpis';
-$labels['showemail'] = 'Zobrazit e-mailovou adresu se skuteÄným jménem';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Zobrazit panel náhledu';
$labels['skin'] = 'Vzhled';
$labels['logoutclear'] = 'Vyprázdnit koš při odhlášení';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorovat slova obsahující Äísla';
$labels['spellcheckignorecaps'] = 'Ignorovat slova psaná velkými písmeny';
$labels['addtodict'] = 'Přidat do slovníku';
$labels['mailtoprotohandler'] = 'Zaregistrovat handler pro odkazy „mailto:“';
-$labels['standardwindows'] = 'Zacházet s vyskakovacími okny jako se standardními okny';
$labels['forwardmode'] = 'Přeposlat zprávu';
$labels['inline'] = 'vloženě';
$labels['asattachment'] = 'jako přílohu';
diff --git a/program/localization/cs_CZ/messages.inc b/program/localization/cs_CZ/messages.inc
index 59b2c6bd6..9800b2412 100644
--- a/program/localization/cs_CZ/messages.inc
+++ b/program/localization/cs_CZ/messages.inc
@@ -24,7 +24,7 @@ $messages['sessionerror'] = 'Vaše přihlášení je neplatné nebo vypršelo';
$messages['storageerror'] = 'Připojení na IMAP server selhalo';
$messages['servererror'] = 'Chyba serveru!';
$messages['servererrormsg'] = 'Chyba serveru: $msg';
-$messages['dberror'] = 'Chyba databáze!';
+$messages['dberror'] = 'Chyba v databázi!';
$messages['requesttimedout'] = 'Došlo k vypršení požadavku';
$messages['errorreadonly'] = 'Příkaz nelze provést, složka je urÄena jen ke Ätení.';
$messages['errornoperm'] = 'Příkaz nelze provést, nemáte oprávnění.';
@@ -33,7 +33,7 @@ $messages['erroroverquotadelete'] = 'Není volné místo na disku. Použijte SHI
$messages['invalidrequest'] = 'Nesprávný požadavek. Data nebyla uložena.';
$messages['invalidhost'] = 'Špatné jméno serveru.';
$messages['nomessagesfound'] = 'Ve schránce nebyla nalezena žádná zpráva';
-$messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Na shledanou!';
+$messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Nashledanou!';
$messages['mailboxempty'] = 'Schránka je prázdná';
$messages['refreshing'] = 'Obnovuji...';
$messages['loading'] = 'NaÄítám...';
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Importuji, prosím Äekejte...';
$messages['importformaterror'] = 'Import se nezdařil! Typ souboru není podporován.';
$messages['importconfirm'] = 'ÚspěšnÄ› naimportováno $inserted kontaktů, $skipped existujících záznamů pÅ™eskoÄeno: $names';
$messages['importconfirmskipped'] = '<b>PÅ™eskoÄeno $skipped existujících položek</b>';
-$messages['importmessagesuccess'] = 'Úspěšně naimportováno $nr zpráv';
-$messages['importmessageerror'] = 'Import se nezdařil! Nahraný soubor není platnou zprávou nebo souborem mailboxu';
$messages['opnotpermitted'] = 'Operace není povolena!';
$messages['nofromaddress'] = 'ChybÄ›jící e-mailová adresa v oznaÄeném profilu';
$messages['editorwarning'] = 'PÅ™epnutím do režimu prostého textu ztratíte veÅ¡keré formátování. Chcete pokraÄovat?';
diff --git a/program/localization/cy_GB/labels.inc b/program/localization/cy_GB/labels.inc
index ca1f17426..3e4f136bc 100644
--- a/program/localization/cy_GB/labels.inc
+++ b/program/localization/cy_GB/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Drafftiau';
$labels['sent'] = 'Danfonwyd';
$labels['trash'] = 'Sbwriel';
$labels['junk'] = 'Sothach';
-$labels['show_real_foldernames'] = 'Dangos enwau go-iawn ar gyfer ffolderi arbennig';
// message listing
$labels['subject'] = 'Pwnc';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Golwg rhestr';
$labels['folderactions'] = 'Gweithredoedd ffolder...';
$labels['compact'] = 'Crynhoi';
$labels['empty'] = 'Gwagio';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Defnydd';
$labels['unknown'] = 'anhysbys';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Ail-osod chwiliad';
$labels['searchmod'] = 'Addasyddion chwilio';
$labels['msgtext'] = 'Y neges yn llawn';
$labels['body'] = 'Corff';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Agor mewn ffenest newydd';
$labels['emlsave'] = 'Llwytho lawr (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Dangos y set olaf';
$labels['group'] = 'Grŵp';
$labels['groups'] = 'Grwpiau';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Cyfeiriadau Personol';
$labels['searchsave'] = 'Cadw chwiliad';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'Ysgrifennu negeseuon HTML';
$labels['htmlonreply'] = 'wrth ateb i neges HTML yn unig';
$labels['htmlonreplyandforward'] = 'wrth ddanfon ymlaen neu ymateb i neges HTML';
$labels['htmlsignature'] = 'Llofnod HTML';
-$labels['showemail'] = 'Dangos cyfeiriad ebost gyda\'r enw gweledig';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Dangos ffenest rhagolwg';
$labels['skin'] = 'Croen rhyngwyneb';
$labels['logoutclear'] = 'Clirio\'r Sbwriel wrth allgofnodi';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Anwybyddu geiriau gyda rhifau';
$labels['spellcheckignorecaps'] = 'Anwybyddu geiriau sy\'n briflythrennau yn gyfangwbl';
$labels['addtodict'] = 'Ychwanegu i\'r geiriadur';
$labels['mailtoprotohandler'] = 'Cofrestru trafodwr protocol ar gyfer dolenni mailto:';
-$labels['standardwindows'] = 'Trin ffenestri naid fel ffenestri arferol';
$labels['forwardmode'] = 'Danfon neges ymlaen';
$labels['inline'] = 'mewnlin';
$labels['asattachment'] = 'fel atodiad';
diff --git a/program/localization/cy_GB/messages.inc b/program/localization/cy_GB/messages.inc
index 6323d8c9c..edadc3b45 100644
--- a/program/localization/cy_GB/messages.inc
+++ b/program/localization/cy_GB/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Yn cael gwared a\'r fformatio...';
$messages['messageopenerror'] = 'Methwyd llwytho\'r neges o\'r gweinydd';
$messages['fileuploaderror'] = 'Methwyd llwytho\'r ffeil i fyny';
$messages['filesizeerror'] = 'Mae\'r ffeil a lwythyd fyny yn fwy na\'r maint uchaf ganiateir o $size';
-$messages['copysuccess'] = 'Copïwyd $nr cyswllt yn llwyddiannus';
-$messages['movesuccess'] = 'Symudwyd $nr cyswllt yn llwyddiannus.';
-$messages['copyerror'] = 'Methwyd copïo unrhyw gysylltiadau.';
-$messages['moveerror'] = 'Methwyd symud unrhyw gysylltiadau.';
+$messages['copysuccess'] = 'Copïwyd $nr cyfeiriad yn llwyddiannus';
+$messages['copyerror'] = 'Methwyd copïo unrhyw gyfeiriad';
$messages['sourceisreadonly'] = 'Mae ffynhonnell y cyfeiriadau i\'w ddarllen yn unig';
$messages['errorsavingcontact'] = 'Methwyd cadw cyfeiriad y cyswllt';
$messages['movingmessage'] = 'Yn symud neges...';
$messages['copyingmessage'] = 'Yn copïo\'r neges';
$messages['copyingcontact'] = 'Yn copïo cyswllt/cysylltiadau...';
-$messages['movingcontact'] = 'Yn symud cyswllt/cysylltiadau...';
$messages['deletingmessage'] = 'Yn dileu neges(euon)...';
$messages['markingmessage'] = 'Yn marcio neges(euon)...';
$messages['addingmember'] = 'Yn ychwanegu cyswllt/cysylltiadau i\'r grŵp...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Yn mewnforio, arhoswch os gwelwch yn dda...';
$messages['importformaterror'] = 'Methwyd mewnforio! Nid yw\'r ffeil a lwythwyd yn ffeil ddata dilys.';
$messages['importconfirm'] = '<b>Fe mewnforiwyd $inserted cyswllt yn llwyddiannus, anwybyddwyd $skipped cofnod presennol</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Neidiwyd $skipped cofnod oedd yn bodoli</b>';
-$messages['importmessagesuccess'] = 'Mewnforiwyd $nr neges yn llwyddiannus';
-$messages['importmessageerror'] = 'Methwyd mewnforio! Nid yw\'r ffeil a lwythwyd yn ffeil neges neu blwch ebost dilys';
$messages['opnotpermitted'] = 'Ni chaniateir y weithred!';
$messages['nofromaddress'] = 'Cyfeiriad e-bost ar goll yn y personoliaeth a ddewiswyd';
$messages['editorwarning'] = 'Mi fydd newid i\'r golygydd testun plaen yn golygu byddwch chi\'n colli unrhyw arddulliau yn eich testun. Hoffech chi barhau?';
diff --git a/program/localization/da_DK/labels.inc b/program/localization/da_DK/labels.inc
index a5b9b3bc8..02d7dd9e3 100644
--- a/program/localization/da_DK/labels.inc
+++ b/program/localization/da_DK/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Kladder';
$labels['sent'] = 'Sendt post';
$labels['trash'] = 'Papirkurv';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Emne';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Listevisningsmode';
$labels['folderactions'] = 'Mappehandlinger...';
$labels['compact'] = 'Ryd op';
$labels['empty'] = 'Tøm';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Diskforbrug';
$labels['unknown'] = 'ukendt';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Nulstil søgning';
$labels['searchmod'] = 'Søgeparametre';
$labels['msgtext'] = 'Hele beskeden';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ã…bn i nyt vindue';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Vis sidste side';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Grupper';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlige adresser';
$labels['searchsave'] = 'Gem søgning';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'Skriv HTML-besked';
$labels['htmlonreply'] = 'kun når jeg besvarer HTML-beskeder';
$labels['htmlonreplyandforward'] = 'ved videresendelse eller besvarelse af HTML beskeder';
$labels['htmlsignature'] = 'HTML-signatur';
-$labels['showemail'] = 'Vis email-adresse med vist navn';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Forhåndsvisning';
$labels['skin'] = 'Brugerflade';
$labels['logoutclear'] = 'Tøm Papirkurv når jeg logger af';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorer ord med tal';
$labels['spellcheckignorecaps'] = 'Ignorer ord hvor alle bogstaver er versaler';
$labels['addtodict'] = 'Tilføj til ordbog';
$labels['mailtoprotohandler'] = 'Registrer håndtering af \'mailto:\' links';
-$labels['standardwindows'] = 'Behandl popups som standardvinduer';
$labels['forwardmode'] = 'Videresendelse af besked';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'som vedhæftning';
diff --git a/program/localization/da_DK/messages.inc b/program/localization/da_DK/messages.inc
index 7429fd4e5..9a0b8e4a5 100644
--- a/program/localization/da_DK/messages.inc
+++ b/program/localization/da_DK/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Fjerner formatering fra besked...';
$messages['messageopenerror'] = 'Beskeden kunne ikke hentes fra serveren.';
$messages['fileuploaderror'] = 'Upload mislykkedes.';
$messages['filesizeerror'] = 'Den indsatte fil fylder mere end det maksimale på $size.';
-$messages['copysuccess'] = '$nr blev kopieret.';
-$messages['movesuccess'] = '$nr kontakter blev flyttet.';
-$messages['copyerror'] = 'Kunne ikke kopiere nogen kontakter.';
-$messages['moveerror'] = 'Kunne ikke flytte nogen kontakter.';
+$messages['copysuccess'] = 'Det lykkedes at kopiere $nr adresser.';
+$messages['copyerror'] = 'Kunne ikke kopiere adresserne.';
$messages['sourceisreadonly'] = 'Denne adressekilde er kun til læsning.';
$messages['errorsavingcontact'] = 'Kunne ikke gemme kontaktadressen.';
$messages['movingmessage'] = 'Flytter besked(er)...';
$messages['copyingmessage'] = 'Kopierer besked(er)...';
$messages['copyingcontact'] = 'Kopierer kontakt(er)...';
-$messages['movingcontact'] = 'Flytter kontakt(er)...';
$messages['deletingmessage'] = 'Sletter besked(er)...';
$messages['markingmessage'] = 'Markerer besked(er)...';
$messages['addingmember'] = 'Tilføjer kontakt(er) til gruppen...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importerer, vent venligst...';
$messages['importformaterror'] = 'Importering mislykkedes! Den uploadede fil indeholder ikke gyldige data til importering.';
$messages['importconfirm'] = '<b>Importerede $inserted kontakter</b>';
$messages['importconfirmskipped'] = '<b>Sprang over $skipped eksisterende kontakter</b>';
-$messages['importmessagesuccess'] = 'Importerede $nr beskeder';
-$messages['importmessageerror'] = 'Import mislykkedes! Den uploadede fil er ikke en gyldig besked eller mailbox-fil';
$messages['opnotpermitted'] = 'Handlingen er ikke tilladt!';
$messages['nofromaddress'] = 'Der mangler en e-mailadresse i den valgte identitet.';
$messages['editorwarning'] = 'Al formatering af teksten forsvinder, hvis der skiftes til ren tekst. Vil du fortsætte?';
diff --git a/program/localization/de_CH/labels.inc b/program/localization/de_CH/labels.inc
index 67d42bb05..e64859d2c 100644
--- a/program/localization/de_CH/labels.inc
+++ b/program/localization/de_CH/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Entwürfe';
$labels['sent'] = 'Gesendet';
$labels['trash'] = 'Gelöscht';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Spezialordner nicht übersetzen';
// message listing
$labels['subject'] = 'Betreff';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Anzeigemodus';
$labels['folderactions'] = 'Ordneraktionen...';
$labels['compact'] = 'Packen';
$labels['empty'] = 'Leeren';
-$labels['importmessages'] = 'Nachrichten importieren';
$labels['quota'] = 'Verwendeter Speicherplatz';
$labels['unknown'] = 'unbekannt';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Löschen';
$labels['searchmod'] = 'Suchkriterien ändern';
$labels['msgtext'] = 'Ganze Nachricht';
$labels['body'] = 'Inhalt';
-$labels['type'] = 'Typ';
$labels['openinextwin'] = 'In neuem Fenster öffnen';
$labels['emlsave'] = 'Herunterladen (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Letzte Seite';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppen';
-$labels['listgroup'] = 'Gruppenmitglieder anzeigen';
$labels['personaladrbook'] = 'Persönliches Adressbuch';
$labels['searchsave'] = 'Suche speichern';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Wörter mit Ziffern überspringen';
$labels['spellcheckignorecaps'] = 'Wörter überspringen, die nur aus Grossbuchstaben bestehen';
$labels['addtodict'] = 'Zum Wörterbuch hinzufügen';
$labels['mailtoprotohandler'] = 'Als Empfänger für mailto: Links einrichten';
-$labels['standardwindows'] = 'Popups als normale Browserfenster öffnen';
$labels['forwardmode'] = 'Weiterleiten einer Nachricht';
$labels['inline'] = 'eingebettet';
$labels['asattachment'] = 'als Anhang';
diff --git a/program/localization/de_CH/messages.inc b/program/localization/de_CH/messages.inc
index 27175be9e..f3697a825 100644
--- a/program/localization/de_CH/messages.inc
+++ b/program/localization/de_CH/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Daten werden importiert, bitte warten...';
$messages['importformaterror'] = 'Import fehlgeschlagen! Die hochgeladene Datei enthält keines der unterstützten Datenformate.';
$messages['importconfirm'] = '<b>Es wurden $inserted Adressen erfolgreich importiert</b>';
$messages['importconfirmskipped'] = '<b>$skipped bestehende Einträge wurden übersprungen</b>';
-$messages['importmessagesuccess'] = '$nr Nachricht(n) erfolgreich importiert';
-$messages['importmessageerror'] = 'Import fehlgeschlagen! Die hochgeladene Datei ist keine E-Mail-Nachricht oder Mailbox-Datei.';
$messages['opnotpermitted'] = 'Operation nicht erlaubt!';
$messages['nofromaddress'] = 'Fehlende E-Mail-Adresse in ausgewählter Identität.';
$messages['editorwarning'] = 'Beim Wechseln in den Texteditor gehen alle Textformatierungen verloren. Möchten Sie fortfahren?';
diff --git a/program/localization/de_DE/labels.inc b/program/localization/de_DE/labels.inc
index 662ad2c70..d497a6bc6 100644
--- a/program/localization/de_DE/labels.inc
+++ b/program/localization/de_DE/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Entwürfe';
$labels['sent'] = 'Gesendet';
$labels['trash'] = 'Gelöscht';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Echte Namen für Spezialordner anzeigen';
// message listing
$labels['subject'] = 'Betreff';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Anzeigemodus';
$labels['folderactions'] = 'Ordneraktionen...';
$labels['compact'] = 'Packen';
$labels['empty'] = 'Leeren';
-$labels['importmessages'] = 'Nachrichten importieren';
$labels['quota'] = 'Speicherplatz';
$labels['unknown'] = 'unbekannt';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Suche zurücksetzen';
$labels['searchmod'] = 'Suchkriterien ändern';
$labels['msgtext'] = 'Nachricht';
$labels['body'] = 'Inhalt';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'In neuem Fenster öffnen';
$labels['emlsave'] = 'Lokal speichern (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Letzte Seite';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppen';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persönliches Adressbuch';
$labels['searchsave'] = 'Suchergebnisse speichern';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'HTML-Nachrichten verfassen';
$labels['htmlonreply'] = 'nur Antworten auf HTML-Nachrichten';
$labels['htmlonreplyandforward'] = 'beim Weiterleiten und Beantworten auf HTML-Nachrichten';
$labels['htmlsignature'] = 'HTML-Signatur';
-$labels['showemail'] = 'E-Mail-Adresse mit dem Display Namen anzeigen';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Nachrichtenvorschau anzeigen';
$labels['skin'] = 'Oberflächendesign';
$labels['logoutclear'] = 'Papierkorb beim Abmelden leeren';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Wörter mit Ziffern überspringen';
$labels['spellcheckignorecaps'] = 'Wörter überspringen, die nur aus Großbuchstaben bestehen';
$labels['addtodict'] = 'Zum Wörterbuch hinzufügen';
$labels['mailtoprotohandler'] = 'Als Empfänger für mailto: Links einrichten';
-$labels['standardwindows'] = 'Popups als Standard Windows behandeln';
$labels['forwardmode'] = 'Nachrichtenweiterleitung';
$labels['inline'] = 'eingebettet';
$labels['asattachment'] = 'als Anhang';
diff --git a/program/localization/de_DE/messages.inc b/program/localization/de_DE/messages.inc
index 7b6099924..ba0936d28 100644
--- a/program/localization/de_DE/messages.inc
+++ b/program/localization/de_DE/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Entferne Formatierungen...';
$messages['messageopenerror'] = 'Die Nachricht konnte nicht vom Server geladen werden.';
$messages['fileuploaderror'] = 'Hochladen der Datei fehlgeschlagen.';
$messages['filesizeerror'] = 'Die hochzuladende Datei überschreitet die Maximalgröße von $size.';
-$messages['copysuccess'] = 'Erfolgreich kopiert $ nr Kontakte.';
-$messages['movesuccess'] = 'Erfolgreich verschoben $ nr Kontakte.';
-$messages['copyerror'] = 'Die Kontakte konnten nicht kopiert werden.';
-$messages['moveerror'] = 'Die Kontakte konnten nicht verschoben werden.';
+$messages['copysuccess'] = '$nr Adressen erfolgreich kopiert.';
+$messages['copyerror'] = 'Die Adressen konnten nicht kopiert werden.';
$messages['sourceisreadonly'] = 'Das Adressverzeichnis kann nicht verändert werden.';
$messages['errorsavingcontact'] = 'Die Änderungen konnten nicht gespeichert werden.';
$messages['movingmessage'] = 'Die E-Mail wird verschoben...';
$messages['copyingmessage'] = 'Kopiere Nachrichten...';
$messages['copyingcontact'] = 'Kontakte werden kopiert...';
-$messages['movingcontact'] = 'Kontakt(e) wird verschoben...';
$messages['deletingmessage'] = 'Lösche Nachricht(en)...';
$messages['markingmessage'] = 'Markiere Nachricht(en)...';
$messages['addingmember'] = 'Füge Kontakte der Gruppe hinzu...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Daten werden importiert, bitte warten...';
$messages['importformaterror'] = 'Import fehlgeschlagen! Die hochgeladene Datei ist keine gültige Importdatei.';
$messages['importconfirm'] = '<b>Es wurden $inserted Adressen erfolgreich importiert.</b>';
$messages['importconfirmskipped'] = '<b>$skipped bestehende Einträge wurden übersprungen.</b>';
-$messages['importmessagesuccess'] = 'Nachrichten $nr erfolgreich importiert';
-$messages['importmessageerror'] = 'Import fehlgeschlagen! Die hochgeladene Datei ist keine gültige Importdatei.';
$messages['opnotpermitted'] = 'Operation nicht erlaubt!';
$messages['nofromaddress'] = 'Fehlende E-Mail-Adresse in ausgewählter Identität.';
$messages['editorwarning'] = 'Beim Wechseln in den Texteditor gehen alle Textformatierungen verloren. Möchten Sie fortfahren?';
diff --git a/program/localization/el_GR/labels.inc b/program/localization/el_GR/labels.inc
index d3030e574..9f5d81839 100644
--- a/program/localization/el_GR/labels.inc
+++ b/program/localization/el_GR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'ΠÏόχειÏα';
$labels['sent'] = 'Απεσταλμένα';
$labels['trash'] = 'Κάδος ΑποÏÏιμάτων';
$labels['junk'] = 'ΑνεπιθÏμητα';
-$labels['show_real_foldernames'] = 'Εμφάνιση Ï€Ïαγματικών ονομάτων για ειδικοÏÏ‚ φακέλους';
// message listing
$labels['subject'] = 'Θέμα';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'ΠÏοβολή σε λίστα';
$labels['folderactions'] = 'ΕνέÏγειες στους φακέλους';
$labels['compact'] = 'Συμπίεση';
$labels['empty'] = 'Άδειασμα';
-$labels['importmessages'] = 'Εισαγωγή μηνυμάτων';
$labels['quota'] = 'ΧÏήση δίσκου';
$labels['unknown'] = 'άγνωστο';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'ΕπαναφοÏά Αναζήτησης';
$labels['searchmod'] = 'Aλλαγή αναζήτησης';
$labels['msgtext'] = 'Σε όλο το μήνυμα';
$labels['body'] = 'Σώμα';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Άνοιγμα σε νέο παÏάθυÏο';
$labels['emlsave'] = 'Λήψη αÏχείου (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Εμφάνιση της τελευταίας σελ
$labels['group'] = 'Ομάδα';
$labels['groups'] = 'Ομάδες';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ΠÏοσωπικές ΔιυθÏνσεις';
$labels['searchsave'] = 'Αποθήκευση αναζήτησης';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Οι λέξεις που πεÏιέχουν Î
$labels['spellcheckignorecaps'] = 'Οι λέξεις γÏαμμένες με ΚΕΦΑΛΑΙΑ να αγνοοÏνται';
$labels['addtodict'] = 'ΠÏοσθήκη στο λεξικό';
$labels['mailtoprotohandler'] = 'ΚαταχώÏηση διαχείÏισης Ï€Ïωτοκόλλου δεσμών mailto:';
-$labels['standardwindows'] = 'ΧειÏιστείτε τα αναδυόμενα παÏάθυÏα ως Ï€Ïότυπο των Windows';
$labels['forwardmode'] = 'ΠÏοώθηση μηνυμάτων';
$labels['inline'] = 'με εσνωμάτωση';
$labels['asattachment'] = 'σαν επισÏναψη';
diff --git a/program/localization/el_GR/messages.inc b/program/localization/el_GR/messages.inc
index 504baa674..dc2499d8b 100644
--- a/program/localization/el_GR/messages.inc
+++ b/program/localization/el_GR/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Μετακίνηση διαμοÏφώσεων κειÎ
$messages['messageopenerror'] = 'Η φόÏτωση μηνυμάτων από τον διακομιστή απέτυχε';
$messages['fileuploaderror'] = 'Ανέβασμα αÏχείου απέτυχε';
$messages['filesizeerror'] = 'Το ανεβασμένο αÏχείο ξεπεÏνάει το μέγιστο μέγεθος των $size';
-$messages['copysuccess'] = 'Επιτυχής αντιγÏαφή $ επαφών αÏιθ..';
-$messages['movesuccess'] = 'Με επιτυχία μεταφέÏθηκαν $ αÏιθ. επαφές.';
-$messages['copyerror'] = 'Αποτυχία αντιγÏαφής επαφών.';
-$messages['moveerror'] = 'Δεν μποÏοÏσε να κινηθεί καμία επαφή.';
+$messages['copysuccess'] = 'Επιτυχής αντιγÏαφή $nr διευθÏνσεων';
+$messages['copyerror'] = 'Αποτυχία αντιγÏαφής διευθÏνσεων';
$messages['sourceisreadonly'] = 'Η διεÏθυνση έχει μόνο δικαίωμα ανάγνωσης';
$messages['errorsavingcontact'] = 'Αποθήκευση επαφής απέτυχε';
$messages['movingmessage'] = 'Μετακίνηση μηνÏματος...';
$messages['copyingmessage'] = 'ΑντιγÏαφή μηνυμάτων...';
$messages['copyingcontact'] = 'ΑντιγÏαφή επαφών...';
-$messages['movingcontact'] = 'Μετακίνηση επαφής(ων)...';
$messages['deletingmessage'] = 'ΔιαγÏαφή μηνυμάτων...';
$messages['markingmessage'] = 'Σήμανση μηνυμάτων...';
$messages['addingmember'] = 'ΠÏοσθήκη επαφών στην ομάδα...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Εισαγωγή, παÏακαλώ πεÏιμένετ
$messages['importformaterror'] = 'Η εισαγωγή απέτυχε! Το αÏχείο δεν είναι έγκυÏο εισαγωγής δεδομένων.';
$messages['importconfirm'] = '<b>Εισήχθησαν $inserted επαφές με επιτυχία</b>';
$messages['importconfirmskipped'] = '<b>ΠαÏαλήφθηκαν $skipped υπάÏχοντα αντικείμενα</b>';
-$messages['importmessagesuccess'] = 'Επιτυχής εισαγωγή $nr μηνυμάτων';
-$messages['importmessageerror'] = 'Η εισαγωγή απέτυχε! Το αÏχείο δεν είναι έγκυÏο εισαγωγής δεδομένων.';
$messages['opnotpermitted'] = 'Η λειτουÏγία δεν επιτÏέπεται!';
$messages['nofromaddress'] = 'Στην επιλεγμένη ταυτότητα, λείπει η email διεÏθυνση';
$messages['editorwarning'] = 'Η μετάβαση στην επεξεÏγασία Î±Ï€Î»Î¿Ï ÎºÎµÎ¹Î¼Î­Î½Î¿Ï… θα Ï€Ïοκαλέσει κατάÏγηση της μοÏφοποίησης. Είστε βέβαιοι πως θέλετε να συνεχίσετε;';
diff --git a/program/localization/en_GB/labels.inc b/program/localization/en_GB/labels.inc
index f903b0cf5..275208a98 100644
--- a/program/localization/en_GB/labels.inc
+++ b/program/localization/en_GB/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Drafts';
$labels['sent'] = 'Sent';
$labels['trash'] = 'Deleted Items';
$labels['junk'] = 'Junk';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subject';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Show last set';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalised';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/en_GB/messages.inc b/program/localization/en_GB/messages.inc
index bba70b148..e5c873c94 100644
--- a/program/localization/en_GB/messages.inc
+++ b/program/localization/en_GB/messages.inc
@@ -17,7 +17,7 @@
*/
$messages = array();
-$messages['errortitle'] = 'An error occured.';
+$messages['errortitle'] = 'An error occurred.';
$messages['loginfailed'] = 'Login failed.';
$messages['cookiesdisabled'] = 'Your browser does not accept cookies.';
$messages['sessionerror'] = 'Your session is invalid or has expired.';
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'File upload failed.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address book is read-only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
@@ -144,7 +139,7 @@ $messages['smtperror'] = 'SMTP Error: $msg';
$messages['emailformaterror'] = 'Incorrect e-mail address: $email';
$messages['toomanyrecipients'] = 'Too many recipients. Reduce the number of recipients to $max.';
$messages['maxgroupmembersreached'] = 'The number of group members exceeds the maximum of $max.';
-$messages['internalerror'] = 'An internal error occured. Please try again.';
+$messages['internalerror'] = 'An internal error occurred. Please try again.';
$messages['contactdelerror'] = 'Could not delete contact(s).';
$messages['contactdeleted'] = 'Contact(s) deleted successfully.';
$messages['contactrestoreerror'] = 'Could not restore deleted contact(s).';
diff --git a/program/localization/en_US/csv2vcard.inc b/program/localization/en_US/csv2vcard.inc
index e7b86795b..eb884f59a 100644
--- a/program/localization/en_US/csv2vcard.inc
+++ b/program/localization/en_US/csv2vcard.inc
@@ -5,7 +5,7 @@
| localization/<lang>/csv2vcard.inc |
| |
| Localization file of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | 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. |
@@ -91,20 +91,3 @@ $map['work_phone'] = "Work Phone";
$map['work_address'] = "Work Address";
$map['work_country'] = "Work Country";
$map['work_zipcode'] = "Work ZipCode";
-
-// Atmail
-$map['date_of_birth'] = "Date of Birth";
-$map['email'] = "Email";
-$map['home_mobile'] = "Home Mobile";
-$map['home_zip'] = "Home Zip";
-$map['info'] = "Info";
-$map['user_photo'] = "User Photo";
-$map['url'] = "URL";
-$map['work_city'] = "Work City";
-$map['work_company'] = "Work Company";
-$map['work_dept'] = "Work Dept";
-$map['work_fax'] = "Work Fax";
-$map['work_mobile'] = "Work Mobile";
-$map['work_state'] = "Work State";
-$map['work_title'] = "Work Title";
-$map['work_zip'] = "Work Zip";
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index 840c9358c..1a753ec12 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -5,7 +5,7 @@
| localization/<lang>/labels.inc |
| |
| Localization file of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | 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. |
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Drafts';
$labels['sent'] = 'Sent';
$labels['trash'] = 'Trash';
$labels['junk'] = 'Junk';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subject';
@@ -65,7 +64,6 @@ $labels['copy'] = 'Copy';
$labels['move'] = 'Move';
$labels['moveto'] = 'Move to...';
$labels['download'] = 'Download';
-$labels['open'] = 'Open';
$labels['showattachment'] = 'Show';
$labels['showanyway'] = 'Show it anyway';
@@ -163,7 +161,6 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Unread';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
-$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -194,7 +191,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -205,13 +201,9 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
-$labels['namex'] = 'Name';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
// message compose
$labels['editasnew'] = 'Edit as new';
@@ -343,8 +335,6 @@ $labels['composeto'] = 'Compose mail to';
$labels['contactsfromto'] = 'Contacts $from to $to of $count';
$labels['print'] = 'Print';
$labels['export'] = 'Export';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
$labels['exportvcards'] = 'Export contacts in vCard format';
$labels['newcontactgroup'] = 'Create new contact group';
$labels['grouprename'] = 'Rename group';
@@ -358,7 +348,6 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -367,11 +356,8 @@ $labels['searchdelete'] = 'Delete search';
$labels['import'] = 'Import';
$labels['importcontacts'] = 'Import contacts';
$labels['importfromfile'] = 'Import from file:';
-$labels['importtarget'] = 'Add contacts to';
+$labels['importtarget'] = 'Add new contacts to address book:';
$labels['importreplace'] = 'Replace the entire address book';
-$labels['importgroups'] = 'Import group assignments';
-$labels['importgroupsall'] = 'All (create groups if necessary)';
-$labels['importgroupsexisting'] = 'Only for existing groups';
$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';
@@ -410,7 +396,6 @@ $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['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Show preview pane';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -480,7 +465,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
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/localization/en_US/messages.inc b/program/localization/en_US/messages.inc
index 47b0f797d..a5e3b4ae2 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -5,7 +5,7 @@
| localization/<lang>/messages.inc |
| |
| Localization file of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | 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. |
@@ -28,8 +28,6 @@ $messages['dberror'] = 'Database Error!';
$messages['requesttimedout'] = 'Request timed out';
$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
$messages['errornoperm'] = 'Unable to perform operation. Permission denied.';
-$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
-$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
$messages['invalidrequest'] = 'Invalid request! No data was saved.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'No messages found in this mailbox.';
@@ -56,8 +54,8 @@ $messages['contactnotfound'] = 'The requested contact was not found.';
$messages['contactsearchonly'] = 'Enter some search terms to find contacts';
$messages['sendingfailed'] = 'Failed to send message.';
$messages['senttooquickly'] = 'Please wait $sec sec(s). before sending this message.';
-$messages['errorsavingsent'] = 'An error occured while saving sent message.';
-$messages['errorsaving'] = 'An error occured while saving.';
+$messages['errorsavingsent'] = 'An error occurred while saving sent message.';
+$messages['errorsaving'] = 'An error occurred while saving.';
$messages['errormoving'] = 'Could not move the message(s).';
$messages['errorcopying'] = 'Could not copy the message(s).';
$messages['errordeleting'] = 'Could not delete the message(s).';
@@ -101,16 +99,13 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'File upload failed.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +124,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
@@ -144,7 +137,7 @@ $messages['smtperror'] = 'SMTP Error: $msg';
$messages['emailformaterror'] = 'Invalid e-mail address: $email';
$messages['toomanyrecipients'] = 'Too many recipients. Reduce the number of recipients to $max.';
$messages['maxgroupmembersreached'] = 'The number of group members exceeds the maximum of $max.';
-$messages['internalerror'] = 'An internal error occured. Please try again.';
+$messages['internalerror'] = 'An internal error occurred. Please try again.';
$messages['contactdelerror'] = 'Could not delete contact(s).';
$messages['contactdeleted'] = 'Contact(s) deleted successfully.';
$messages['contactrestoreerror'] = 'Could not restore deleted contact(s).';
diff --git a/program/localization/eo/labels.inc b/program/localization/eo/labels.inc
index 3c2930c89..c088fc50e 100644
--- a/program/localization/eo/labels.inc
+++ b/program/localization/eo/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Malnetujo';
$labels['sent'] = 'Senditujo';
$labels['trash'] = 'Rubujo';
$labels['junk'] = 'Spamujo';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Temo';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Dosierujo-agoj';
$labels['compact'] = 'Kompakta';
$labels['empty'] = 'Malplena';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Diskuzo';
$labels['unknown'] = 'nekonata';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Vakigu serĉon';
$labels['searchmod'] = 'Serĉ-opcioj';
$labels['msgtext'] = 'Tuta mesaÄo';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Malfermu en nova fenestro';
$labels['emlsave'] = 'ElÅutu (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Montru lastan';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupoj';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persona Adresoj';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/eo/messages.inc b/program/localization/eo/messages.inc
index a7765e442..4d72fe54b 100644
--- a/program/localization/eo/messages.inc
+++ b/program/localization/eo/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Foriganta formatan de mesaÄo...';
$messages['messageopenerror'] = 'Ne povis Åargi mesaÄon de servilo';
$messages['fileuploaderror'] = 'Malsukcesis alÅuti dosieron';
$messages['filesizeerror'] = 'La alÅutita dosiero superas la maksimuman grandon de $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Sukcese kopiis $nr adresojn';
+$messages['copyerror'] = 'Ne povis kopii ajn adreson';
$messages['sourceisreadonly'] = 'Ĉi tiu adres-fonto estas nurlegebla';
$messages['errorsavingcontact'] = 'Ne povis savi la kontakt-adreson';
$messages['movingmessage'] = 'Translokanta mesaÄon...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/es_AR/labels.inc b/program/localization/es_AR/labels.inc
index 5bc53f7f0..d9a83be75 100644
--- a/program/localization/es_AR/labels.inc
+++ b/program/localization/es_AR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Papelera';
$labels['junk'] = 'Basura';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Asunto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Acciones de carpeta...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Vaciar';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconocido';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reajustar la búsqueda';
$labels['searchmod'] = 'Opciones de búsqueda';
$labels['msgtext'] = 'Mensaje completo';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir en ventana nueva';
$labels['emlsave'] = 'Guardar (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Mostrar último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Direcciones personales';
$labels['searchsave'] = 'Guardar búsqueda';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/es_AR/messages.inc b/program/localization/es_AR/messages.inc
index 1a0240222..1cec9f01d 100644
--- a/program/localization/es_AR/messages.inc
+++ b/program/localization/es_AR/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removiendo el formato del mensaje...';
$messages['messageopenerror'] = 'No puedo descargar el mensaje del servidor';
$messages['fileuploaderror'] = 'Error al subir archivos';
$messages['filesizeerror'] = 'El archivo excede el tamaño maximo ($size)';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr direcciones copiadas con éxito';
+$messages['copyerror'] = 'No se pudo copiar ninguna dirección';
$messages['sourceisreadonly'] = 'Esta dirección es de sólo-lectura';
$messages['errorsavingcontact'] = 'No se pudo guardar la dirección de contacto';
$messages['movingmessage'] = 'Moviendo mensaje...';
$messages['copyingmessage'] = 'Copiando mensaje...';
$messages['copyingcontact'] = 'Copiando contacto(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Eliminando contacto(s)...';
$messages['markingmessage'] = 'Marcando mensaje(s)...';
$messages['addingmember'] = 'Agregando contacto(s) al grupo...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importando, aguarde por favor...';
$messages['importformaterror'] = 'Importación fallida! El archivo subido no es un archivo de importación de datos válido.';
$messages['importconfirm'] = '<b>Se importaron $inserted contactos correctamente. $skipped ya existentes fueron ignorados</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Se ignoraron $skipped entradas ya existentes</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operación no permitida!';
$messages['nofromaddress'] = 'El contacto seleccionado no tiene dirección de e-mail';
$messages['editorwarning'] = 'Si cambia a texto plano se perderán todas las opciones de formato. ¿Desea continuar?';
diff --git a/program/localization/es_ES/labels.inc b/program/localization/es_ES/labels.inc
index 11d14fa08..03f6b489a 100644
--- a/program/localization/es_ES/labels.inc
+++ b/program/localization/es_ES/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Papelera';
$labels['junk'] = 'SPAM';
-$labels['show_real_foldernames'] = 'Mostrar nombres reales para carpetas especiales';
// message listing
$labels['subject'] = 'Asunto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Modo de vista de lista';
$labels['folderactions'] = 'Acciones de bandeja...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Vaciar';
-$labels['importmessages'] = 'Importar mensajes';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconocido';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reiniciar la búsqueda';
$labels['searchmod'] = 'Opciones de búsqueda';
$labels['msgtext'] = 'Mensaje completo';
$labels['body'] = 'Cuerpo';
-$labels['type'] = 'Tipo';
$labels['openinextwin'] = 'Abrir en nueva ventana';
$labels['emlsave'] = 'Descargar (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Mostrar último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
-$labels['listgroup'] = 'Listar miembros del grupo';
$labels['personaladrbook'] = 'Direcciones personales';
$labels['searchsave'] = 'Guardar búsqueda';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'Componer mensaje en HTML';
$labels['htmlonreply'] = 'sólo en respuesta a un mensaje HTML';
$labels['htmlonreplyandforward'] = 'en reenvío o respuesta al mensaje HTML';
$labels['htmlsignature'] = 'Firma HTML';
-$labels['showemail'] = 'Mostrar dirección de correo electrónico al visualizar el nombre';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Mostrar vista preliminar';
$labels['skin'] = 'Apariencia de la interfaz';
$labels['logoutclear'] = 'Vaciar papelera al cerrar sesión';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorar palabras con números';
$labels['spellcheckignorecaps'] = 'Ignorar palabras con todo mayúsculas';
$labels['addtodict'] = 'Añadir al diccionario';
$labels['mailtoprotohandler'] = 'Registrar controlador de protocolo para enlaces mailto:';
-$labels['standardwindows'] = 'Gestionar ventanas emergentes como ventanas estándar';
$labels['forwardmode'] = 'Reenvío de mensajes';
$labels['inline'] = 'en línea';
$labels['asattachment'] = 'como adjunto';
diff --git a/program/localization/es_ES/messages.inc b/program/localization/es_ES/messages.inc
index d4bd81402..6c031df29 100644
--- a/program/localization/es_ES/messages.inc
+++ b/program/localization/es_ES/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Importando, espere...';
$messages['importformaterror'] = '¡La importación falló! El fichero enviado no es un fichero válido de importación de datos';
$messages['importconfirm'] = '<b>Se han importado $inserted contactos correctamente</b>';
$messages['importconfirmskipped'] = '<b>Ignoradas $skipped entradas existentes</b>';
-$messages['importmessagesuccess'] = '$nr mensajes importados con éxito';
-$messages['importmessageerror'] = '¡Ha fallado la importación! El fichero subido no es un fichero válido de mensaje o buzón de correo';
$messages['opnotpermitted'] = '¡Operación no permitida!';
$messages['nofromaddress'] = 'El contacto seleccionado no tiene dirección de e-mail';
$messages['editorwarning'] = 'Cambiando a texto plano perderá el formato del mensaje. ¿Desea continuar?';
diff --git a/program/localization/et_EE/labels.inc b/program/localization/et_EE/labels.inc
index a8bc28403..5d23d4ded 100644
--- a/program/localization/et_EE/labels.inc
+++ b/program/localization/et_EE/labels.inc
@@ -37,7 +37,7 @@ $labels['drafts'] = 'Mustandid';
$labels['sent'] = 'Saadetud';
$labels['trash'] = 'Prügikast';
$labels['junk'] = 'Rämps';
-$labels['show_real_foldernames'] = 'Näita eriliste kaustade päris nimesid';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Pealkiri';
@@ -194,7 +194,6 @@ $labels['listmode'] = 'Nimekirja vaatamise režiim';
$labels['folderactions'] = 'Kausta tegevused...';
$labels['compact'] = 'Tihenda';
$labels['empty'] = 'Tühjenda';
-$labels['importmessages'] = 'Impordi kirju';
$labels['quota'] = 'Kettakasutus';
$labels['unknown'] = 'teadmata';
@@ -205,7 +204,6 @@ $labels['resetsearch'] = 'Lähtesta otsing';
$labels['searchmod'] = 'Otsingu laiendid';
$labels['msgtext'] = 'Kogu kirjast';
$labels['body'] = 'Keha';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ava uues aknas';
$labels['emlsave'] = 'Salvesta (.eml)';
@@ -357,7 +355,6 @@ $labels['lastpage'] = 'Näita viimast komplekti';
$labels['group'] = 'Grupp';
$labels['groups'] = 'Grupid';
-$labels['listgroup'] = 'Näita grupi liikmeid';
$labels['personaladrbook'] = 'Isiklikud aadressid';
$labels['searchsave'] = 'Salvesta otsing';
diff --git a/program/localization/et_EE/messages.inc b/program/localization/et_EE/messages.inc
index 4d58b0a75..c73d92c48 100644
--- a/program/localization/et_EE/messages.inc
+++ b/program/localization/et_EE/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Impordin, palun oota...';
$messages['importformaterror'] = 'Import nurjus! Laaditud fail ei sisalda sobilikke andmeid.';
$messages['importconfirm'] = '<b>Edukalt imporditud $inserted kontakti, $skipped olemasolevat sissekannet vahele jäetud</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b> $skipped olemasolevat kirjet jäeti vahele</b>';
-$messages['importmessagesuccess'] = '$nr kirja edukalt imporditud';
-$messages['importmessageerror'] = 'Import nurjus! Laaditud fail ei ole kirja ega postkasti fail';
$messages['opnotpermitted'] = 'Tegevus pole lubatud!';
$messages['nofromaddress'] = 'Valitud identiteedil puudub e-posti aadress';
$messages['editorwarning'] = 'Klaarteksti redaktorile lülitamine kaotab kogu teksti vorminduse. Soovid jätkata?';
diff --git a/program/localization/eu_ES/labels.inc b/program/localization/eu_ES/labels.inc
index fedce7de5..8052d69e8 100644
--- a/program/localization/eu_ES/labels.inc
+++ b/program/localization/eu_ES/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Zirriborroak';
$labels['sent'] = 'Bidalitakoak';
$labels['trash'] = 'Zakarrontzia';
$labels['junk'] = 'Zabor-posta';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Gaia';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Trinkotu';
$labels['empty'] = 'Hustu';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disko erabilera';
$labels['unknown'] = 'ezezaguna';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Bilaketa berrabiarazi';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Lehio berrian ireki';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Azken sorta ikusi';
$labels['group'] = 'Group';
$labels['groups'] = 'Taldeak';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Helbide pertsonalak';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/eu_ES/messages.inc b/program/localization/eu_ES/messages.inc
index 6dd781530..a3985b233 100644
--- a/program/localization/eu_ES/messages.inc
+++ b/program/localization/eu_ES/messages.inc
@@ -17,28 +17,28 @@
*/
$messages = array();
-$messages['errortitle'] = 'Errore bat gertatu da!';
-$messages['loginfailed'] = 'Saio hasierak huts egin du.';
-$messages['cookiesdisabled'] = 'Zure nabigatzaileak ez ditu cookie-rik onartzen';
+$messages['errortitle'] = 'An error occurred!';
+$messages['loginfailed'] = 'Saio sarrerak huts egin du';
+$messages['cookiesdisabled'] = 'Zure nabigatzaileak ez ditu cookie-ak onartzen';
$messages['sessionerror'] = 'Zure saioa baliogabea da edo iraungita dago';
-$messages['storageerror'] = 'Huts egin du biltegiratze-zerbitzarira konektatzean';
-$messages['servererror'] = 'Zerbitzari-errorea!';
-$messages['servererrormsg'] = 'Zerbitzari-errorea: $msg';
-$messages['dberror'] = 'Datu-basearen errorea!';
-$messages['requesttimedout'] = 'Eskaera denboraz kanpo.';
-$messages['errorreadonly'] = 'Ezin da ekintza burutu. Karpeta soilik irakurtzekoa da.';
-$messages['errornoperm'] = 'Ezin da ekintza burutu. Baimena ukatua.';
-$messages['erroroverquota'] = 'Ezin da ekintza burutu. Diskoan ez dago tokirik.';
-$messages['erroroverquotadelete'] = 'Diskoan ez dago tokirik. Erabili SHIFT+DEL mezua ezabatzeko.';
-$messages['invalidrequest'] = 'Eskaera ez da baliozkoa! Datuak ez dira gorde.';
-$messages['invalidhost'] = 'Zerbitzari-izena ez da baliozkoa.';
+$messages['storageerror'] = 'Huts IMAP zerbitzarira konektatzean';
+$messages['servererror'] = 'Server Error!';
+$messages['servererrormsg'] = 'Server Error: $msg';
+$messages['dberror'] = 'Database Error!';
+$messages['requesttimedout'] = 'Request timed out';
+$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
+$messages['errornoperm'] = 'Unable to perform operation. Permission denied.';
+$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
+$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
+$messages['invalidrequest'] = 'Invalid request! No data was saved.';
+$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'Ez da mezurik aurkitu posta kutxa honetan';
$messages['loggedout'] = 'Saioa behar bezala amaitu duzu. Agur!';
$messages['mailboxempty'] = 'Posta kutxa hutsik dago';
-$messages['refreshing'] = 'Freskatzen...';
+$messages['refreshing'] = 'Refreshing...';
$messages['loading'] = 'Kargatzen...';
-$messages['uploading'] = 'Fitxategia kargatzen...';
-$messages['uploadingmany'] = 'Fitxategiak kargatzen...';
+$messages['uploading'] = 'Uploading file...';
+$messages['uploadingmany'] = 'Uploading files...';
$messages['loadingdata'] = 'Datuak kargatzen...';
$messages['checkingmail'] = 'Mezu berrien bila arakatzen...';
$messages['sendingmessage'] = 'Mezua bidaltzen...';
@@ -48,129 +48,124 @@ $messages['messagesaved'] = 'Mezua zirriborroetan gordea';
$messages['successfullysaved'] = 'Behar bezala gorde da';
$messages['addedsuccessfully'] = 'Txartela behar bezala gehitu da helbide liburura';
$messages['contactexists'] = 'ePosta honetako txartel bat badago dagoeneko';
-$messages['contactnameexists'] = 'Lehendik badago izen hori duen kontaktua.';
+$messages['contactnameexists'] = 'A contact with the same name already exists.';
$messages['blockedimages'] = 'Zure pribazitatea mantentzeko urruneko irudiak blokeatu egin dira.';
$messages['encryptedmessage'] = 'Hau enkriptaturiko mezu bat da eta ezin da bistarazi. Barkatu!';
$messages['nocontactsfound'] = 'Ez da txartelik aurkitu';
$messages['contactnotfound'] = 'Eskatutako txartela ez da aurkitu';
-$messages['contactsearchonly'] = 'Sartu kontaktua aurkitzeko bilaketa daturen bat.';
+$messages['contactsearchonly'] = 'Enter some search terms to find contacts';
$messages['sendingfailed'] = 'Huts mezua bidaltzerakoan';
-$messages['senttooquickly'] = 'Itxaron $sec segundo mezua bidali aurretik, mesedez.';
+$messages['senttooquickly'] = 'Please wait $sec sec(s). before sending this message.';
$messages['errorsavingsent'] = 'Errorea gertatu da bidalitako mezua gordetzean';
$messages['errorsaving'] = 'Errore bat gertatu da gordetzean';
$messages['errormoving'] = 'Ezin da mezua mugitu';
-$messages['errorcopying'] = 'Ezin d(ir)a kopiatu mezua(k).';
+$messages['errorcopying'] = 'Could not copy the message(s).';
$messages['errordeleting'] = 'Ezin da mezua ezabatu';
-$messages['errormarking'] = 'Ezin d(ir)a markatu mezua(k).';
+$messages['errormarking'] = 'Could not mark the message(s).';
$messages['deletecontactconfirm'] = 'Benetan hautaturiko kontaktuak ezabatu nahi dituzula?';
-$messages['deletegroupconfirm'] = 'Seguru zaude hautatutako taldea ezabatu nahi duzula?';
+$messages['deletegroupconfirm'] = 'Do you really want to delete selected group?';
$messages['deletemessagesconfirm'] = 'Benetan hautaturiko mezuak ezabatu nahi dituzula?';
$messages['deletefolderconfirm'] = 'Benetan Karpeta hau ezabatu nahi duzu?';
$messages['purgefolderconfirm'] = 'Benetan karpeta honetako mezu guziak ezabatu nahi dituzu?';
-$messages['contactdeleting'] = 'Kontaktua(k) ezabatzen...';
-$messages['groupdeleting'] = 'Taldea ezabatzen...';
-$messages['folderdeleting'] = 'Karpeta ezabatzen...';
-$messages['foldermoving'] = 'Karpeta mugitzen...';
-$messages['foldersubscribing'] = 'Karpeta harpidetzen...';
-$messages['folderunsubscribing'] = 'Karpetaren harpidetza kentzen...';
+$messages['contactdeleting'] = 'Deleting contact(s)...';
+$messages['groupdeleting'] = 'Deleting group...';
+$messages['folderdeleting'] = 'Deleting folder...';
+$messages['foldermoving'] = 'Moving folder...';
+$messages['foldersubscribing'] = 'Subscribing folder...';
+$messages['folderunsubscribing'] = 'Unsubscribing folder...';
$messages['formincomplete'] = 'Inprimakia ez guztiz bete';
$messages['noemailwarning'] = 'Mesedez idatzi baliozko eposta helbide bat';
$messages['nonamewarning'] = 'Mesedez izen bat idatzi';
$messages['nopagesizewarning'] = 'Mesedez paper tamaina idatzi';
-$messages['nosenderwarning'] = 'Sartu bidaltzailearen helbide elektronikoa, mesedez.';
+$messages['nosenderwarning'] = 'Please enter sender e-mail address.';
$messages['norecipientwarning'] = 'Mesedez behintzat hartzaile bat idatzi';
$messages['nosubjectwarning'] = '"Gaia" eremua hutsik dago. Bat idatzi nahi al duzu?';
$messages['nobodywarning'] = 'Testu gabeko mezu hau bidali?';
$messages['notsentwarning'] = 'Mezua ez da bidali. Mezua ezeztatu nahi al duzu?';
$messages['noldapserver'] = 'Mesedez hautatu bilaketa egiteko LDAP zerbitzari bat';
$messages['nosearchname'] = 'Mesedez idatzi kontaktu izen bat edo eposta helbide bat';
-$messages['notuploadedwarning'] = 'Oraindik ez dira kargatu eranskin guztiak. Itxaron edo ezeztatu karga.';
+$messages['notuploadedwarning'] = 'Not all attachments have been uploaded yet. Please wait or cancel the upload.';
$messages['searchsuccessful'] = '$nr mezu aurkiturik';
-$messages['contactsearchsuccessful'] = '$nr kontaktu aurkitu dira.';
+$messages['contactsearchsuccessful'] = '$nr contacts found.';
$messages['searchnomatch'] = 'Bilaketak ez du emaitzarik itzuli';
$messages['searching'] = 'Bilatzen...';
$messages['checking'] = 'Arakatzen...';
$messages['nospellerrors'] = 'Ez da ortografia errorerik aurkitu';
$messages['folderdeleted'] = 'Karpeta behar bezala ezabatu da';
-$messages['foldersubscribed'] = 'Karpeta ongi harpidetu da.';
-$messages['folderunsubscribed'] = 'Karpetaren harpidetza ongi kendu da.';
-$messages['folderpurged'] = 'Karpeta ongi hustu da.';
-$messages['folderexpunged'] = 'Karpeta ongi trinkotu da.';
+$messages['foldersubscribed'] = 'Folder successfully subscribed.';
+$messages['folderunsubscribed'] = 'Folder successfully unsubscribed.';
+$messages['folderpurged'] = 'Folder has successfully been emptied.';
+$messages['folderexpunged'] = 'Folder has successfully been compacted.';
$messages['deletedsuccessfully'] = 'Behar bezala ezabatu da';
$messages['converting'] = 'Mezuaren formatua ezabatzen';
$messages['messageopenerror'] = 'Ezin da zerbitzaritik mezua kargatu';
$messages['fileuploaderror'] = 'Huts fitxategia eransterakoan';
$messages['filesizeerror'] = 'Erantsi nahi duzun fitxategian $size tamaina muga gainditzen du';
-$messages['copysuccess'] = '$nr kontaktu ongi kopiatu dira.';
-$messages['movesuccess'] = '$nr kontaktu ongi mugitu dira.';
-$messages['copyerror'] = 'Ezin da kontakturik kopiatu.';
-$messages['moveerror'] = 'Ezin da kontakturik mugitu.';
+$messages['copysuccess'] = 'Ondo kopiatu dira $nr helbideak';
+$messages['copyerror'] = 'Ezin da helbiderik kopiatu';
$messages['sourceisreadonly'] = 'Helbide iturburua irakurtzeko soilik da';
$messages['errorsavingcontact'] = 'Ezin da kontaktuaren helbidea gorde';
$messages['movingmessage'] = 'Mezua mugitzen...';
-$messages['copyingmessage'] = 'Mezuak kopiatzen...';
-$messages['copyingcontact'] = 'Kontaktua(k) kopiatzen...';
-$messages['movingcontact'] = 'Kontaktua(k) mugitzen...';
-$messages['deletingmessage'] = 'Mezua(k) ezabatzen...';
-$messages['markingmessage'] = 'Mezua(k) markatzen...';
-$messages['addingmember'] = 'Kontaktua(k) taldera gehitzen...';
-$messages['removingmember'] = 'Kontaktua(k) taldetik ezabatzen...';
+$messages['copyingmessage'] = 'Copying message(s)...';
+$messages['copyingcontact'] = 'Copying contact(s)...';
+$messages['deletingmessage'] = 'Deleting message(s)...';
+$messages['markingmessage'] = 'Marking message(s)...';
+$messages['addingmember'] = 'Adding contact(s) to the group...';
+$messages['removingmember'] = 'Removing contact(s) from the group...';
$messages['receiptsent'] = 'Ondo bidalia irakurritako agiria';
$messages['errorsendingreceipt'] = 'Ezin da agiria bidali';
-$messages['deleteidentityconfirm'] = 'Seguru zaude identitate hau ezabatu nahi duzula?';
+$messages['deleteidentityconfirm'] = 'Do you really want to delete this identity?';
$messages['nodeletelastidentity'] = 'Ezin da izaera hau ezabatu, zure bakarra da';
$messages['forbiddencharacter'] = 'Karpeta izenak debekatutako karaktereak ditu';
-$messages['selectimportfile'] = 'Hautatu kargatzeko fitxategia.';
-$messages['addresswriterror'] = 'Hautatutako helbide-liburua ezin da editatu.';
-$messages['contactaddedtogroup'] = 'Kontaktuak ongi gehitu dira taldera.';
-$messages['contactremovedfromgroup'] = 'Kontaktuak ongi ezabatu dira taldetik.';
-$messages['nogroupassignmentschanged'] = 'Talde-esleipena ez da aldatu.';
-$messages['importwait'] = 'Inportatzen, itxaron mesedez...';
-$messages['importformaterror'] = 'Huts egin du inportatzean. Kargatu duzun fitxategia ez da inportatzeko fitxategi baliozkoa.';
-$messages['importconfirm'] = '<b>Ongi inportatu dira $inserted kontaktu</b>';
-$messages['importconfirmskipped'] = '<b>Saltatu dira $skipped sarrera</b>';
-$messages['importmessagesuccess'] = '$nr mezu ongi inportatu dira.';
-$messages['importmessageerror'] = 'Inportazio akatsa! Kargatutako fitxategia ez da baliozko mezua edo posta-fitxategia.';
-$messages['opnotpermitted'] = 'Ekintza ez baimendua!';
-$messages['nofromaddress'] = 'Helbide elektronikoa falta da hautatutako identitatean.';
-$messages['editorwarning'] = 'Formaturik gabeko testu-editorera pasatzeak ekar dezake testu-formatu guztien galera. Jarraitu nahi duzu?';
-$messages['httpreceivedencrypterror'] = 'Ezarpen akats larria gertatu da. Jarri harremanetan zure administratzailearekin ahalik eta lasterren. <b>Zure mezua ezin da bidali.</b>';
-$messages['smtpconnerror'] = 'SMTP errorea ($code): Zerbitzariarekiko konexioak huts egin du.';
-$messages['smtpautherror'] = 'SMTP errorea ($code): Egiaztapenak huts egin du.';
-$messages['smtpfromerror'] = 'SMTP errorea ($code): "$from" ($msg) bidaltzailearen ezartzeak huts egin du.';
-$messages['smtptoerror'] = 'SMTP errorea ($code): "$to" ($msg) hartzailea gehitzen huts egin du.';
-$messages['smtprecipientserror'] = 'SMTP errorea: Ezin da hartzaileen zerrenda analizatu.';
-$messages['smtperror'] = 'SMTP errorea: $msg';
-$messages['emailformaterror'] = 'Helbide elektronikoa ez da baliozkoa: $email';
-$messages['toomanyrecipients'] = 'Hartzaile gehiegi. Txikitu hartzaile kopura hona $max.';
-$messages['maxgroupmembersreached'] = 'Taldeko partaideen kopurua $max -ko maximoa gainditzen du:';
-$messages['internalerror'] = 'Barne akatsa. Saiatu berriz, mesedez.';
-$messages['contactdelerror'] = 'Ezin d(ir)a kontaktua(k) ezabatu.';
-$messages['contactdeleted'] = 'Kontaktua(k) ongi ezabatu dira.';
-$messages['contactrestoreerror'] = 'Ezin d(ir)a ezabatutako kontaktua(k) leheneratu.';
-$messages['contactrestored'] = 'Kontaktua(k) ongi leheneratu d(ir)a.';
-$messages['groupdeleted'] = 'Taldea ongi ezabatu da.';
-$messages['grouprenamed'] = 'Taldea ongi berrizendatu da.';
-$messages['groupcreated'] = 'Taldea ongi sortu da.';
-$messages['savedsearchdeleted'] = 'Bilaketaren gordetzea ongi ezabatu da.';
-$messages['savedsearchdeleteerror'] = 'Ezin da ezabatu bilaketaren gordeketa.';
-$messages['savedsearchcreated'] = 'Bilaketaren gordeketa ongi sortu da.';
-$messages['savedsearchcreateerror'] = 'Ezin da sortu bilaketaren gordeketa.';
-$messages['messagedeleted'] = 'Mezua(k) ongi ezabatu dira.';
-$messages['messagemoved'] = 'Mezua(k) ongi mugitu d(ir)a.';
-$messages['messagecopied'] = 'Mezua(k) ongi kopiatu d(ir)a';
-$messages['messagemarked'] = 'Mezua(k) ongi markatu d(ir)a';
-$messages['autocompletechars'] = 'Sartu gutxienez $min karaktere osatze automatikorako';
-$messages['autocompletemore'] = 'Bat datozen sarrera gehiago topatu dira. Idatzi karaktere gehiago.';
-$messages['namecannotbeempty'] = 'Izena ezin da hutsik egon.';
-$messages['nametoolong'] = 'Izena luzeegia da.';
-$messages['folderupdated'] = 'Karpeta ongi eguneratu da.';
-$messages['foldercreated'] = 'Karpeta ongi sortu da.';
-$messages['invalidimageformat'] = 'Irudi formatua ez da baliozkoa.';
-$messages['mispellingsfound'] = 'Ortografia akatsak detektatu dira mezuan.';
-$messages['parentnotwritable'] = 'Ezin da karpeta sortu/mugi hautatutako goragoko karpetan. Sartzeko baimenik ez.';
-$messages['messagetoobig'] = 'Mezu-zatia handiegia da prozesatzeko.';
-$messages['attachmentvalidationerror'] = 'KONTUZ! Eranskin hau susmagarria da zeren bere izaera ez dator bat mezuan deklaratutakoarekin. Bidaltzailearekin fidatzen ez bazara ez zenuke nabigatzailean ireki behar eduki maltzurra izan dezakeelako.<br/><br/><em>Deklaratua: $expected; erreala: $detected</em>';
-$messages['noscriptwarning'] = 'Kontuz: web-posta zerbitzu honek Javascript behar du! Erabili nahi baduzu gaitu Javascript zure nabigatzailearen hobespenetan.';
+$messages['selectimportfile'] = 'Please select a file to upload.';
+$messages['addresswriterror'] = 'The selected address book is not writeable.';
+$messages['contactaddedtogroup'] = 'Successfully added the contacts to this group.';
+$messages['contactremovedfromgroup'] = 'Successfully removed contacts from this group.';
+$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$messages['importwait'] = 'Importing, please wait...';
+$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
+$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
+$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
+$messages['opnotpermitted'] = 'Operation not permitted!';
+$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
+$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
+$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Connection to server failed.';
+$messages['smtpautherror'] = 'SMTP Error ($code): Authentication failed.';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from" ($msg).';
+$messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to" ($msg).';
+$messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list.';
+$messages['smtperror'] = 'SMTP Error: $msg';
+$messages['emailformaterror'] = 'Invalid e-mail address: $email';
+$messages['toomanyrecipients'] = 'Too many recipients. Reduce the number of recipients to $max.';
+$messages['maxgroupmembersreached'] = 'The number of group members exceeds the maximum of $max.';
+$messages['internalerror'] = 'An internal error occured. Please try again.';
+$messages['contactdelerror'] = 'Could not delete contact(s).';
+$messages['contactdeleted'] = 'Contact(s) deleted successfully.';
+$messages['contactrestoreerror'] = 'Could not restore deleted contact(s).';
+$messages['contactrestored'] = 'Contact(s) restored successfully.';
+$messages['groupdeleted'] = 'Group deleted successfully.';
+$messages['grouprenamed'] = 'Group renamed successfully.';
+$messages['groupcreated'] = 'Group created successfully.';
+$messages['savedsearchdeleted'] = 'Saved search deleted successfully.';
+$messages['savedsearchdeleteerror'] = 'Could not delete saved search.';
+$messages['savedsearchcreated'] = 'Saved search created successfully.';
+$messages['savedsearchcreateerror'] = 'Could not create saved search.';
+$messages['messagedeleted'] = 'Message(s) deleted successfully.';
+$messages['messagemoved'] = 'Message(s) moved successfully.';
+$messages['messagecopied'] = 'Message(s) copied successfully.';
+$messages['messagemarked'] = 'Message(s) marked successfully.';
+$messages['autocompletechars'] = 'Enter at least $min characters for autocompletion.';
+$messages['autocompletemore'] = 'More matching entries found. Please type more characters.';
+$messages['namecannotbeempty'] = 'Name cannot be empty.';
+$messages['nametoolong'] = 'Name is too long.';
+$messages['folderupdated'] = 'Folder updated successfully.';
+$messages['foldercreated'] = 'Folder created successfully.';
+$messages['invalidimageformat'] = 'Not a valid image format.';
+$messages['mispellingsfound'] = 'Spelling errors detected in the message.';
+$messages['parentnotwritable'] = 'Unable to create/move folder into selected parent folder. No access rights.';
+$messages['messagetoobig'] = 'The message part is too big to process it.';
+$messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.<br/><br/><em>Expected: $expected; found: $detected</em>';
+$messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.';
?>
diff --git a/program/localization/fa_AF/labels.inc b/program/localization/fa_AF/labels.inc
index 38154c23c..70113bc49 100644
--- a/program/localization/fa_AF/labels.inc
+++ b/program/localization/fa_AF/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'نامه های ناتکمیل';
$labels['sent'] = 'ارسال شده';
$labels['trash'] = 'اشغال دانی';
$labels['junk'] = 'بیکاره';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'مضمون';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'خلاصه';
$labels['empty'] = 'خالي';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = '‌طريقه استعمال ديسک';
$labels['unknown'] = 'نامعلوم';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'بازنشاندن جستجو';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'در پینجره ای جدید باز کنید';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'بسته اخير را نشان دهيد';
$labels['group'] = 'Group';
$labels['groups'] = 'گروه ها';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ادرس های شخصي';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/fa_AF/messages.inc b/program/localization/fa_AF/messages.inc
index 51ad5b717..4f3d4be55 100644
--- a/program/localization/fa_AF/messages.inc
+++ b/program/localization/fa_AF/messages.inc
@@ -17,33 +17,33 @@
*/
$messages = array();
-$messages['errortitle'] = 'خطا رخ داد';
-$messages['loginfailed'] = 'خطا در ورود به سیستم';
+$messages['errortitle'] = 'An error occurred!';
+$messages['loginfailed'] = 'داخل شدن به سيستم موÙÙ‚ نه شد';
$messages['cookiesdisabled'] = 'جستجوگر شما cookies را قبول نميکند';
$messages['sessionerror'] = 'جلسه شما وجود ندارد و يا هم از زمان معين آن گذشته است';
$messages['storageerror'] = 'وصل شدن به آیمیپ سرور موÙÙ‚ نشد';
$messages['servererror'] = 'Server Error!';
-$messages['servererrormsg'] = 'خطای سرور: $msg';
-$messages['dberror'] = 'خطای پایگاه داده';
-$messages['requesttimedout'] = 'عدم پاسخگویی در زمان مقرر';
+$messages['servererrormsg'] = 'Server Error: $msg';
+$messages['dberror'] = 'Database Error!';
+$messages['requesttimedout'] = 'Request timed out';
$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
$messages['errornoperm'] = 'Unable to perform operation. Permission denied.';
$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
$messages['invalidrequest'] = 'Invalid request! No data was saved.';
-$messages['invalidhost'] = 'نام سرور نامعتبر است';
+$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'هيچ پيغامی در اين صندوق پستي درياÙت نه شد';
$messages['loggedout'] = 'جلسه شما بصورت مکمل Ùسخ شده است خدا حاÙظ';
$messages['mailboxempty'] = 'صندوق پستي خالي است';
-$messages['refreshing'] = 'دوباره سازی....';
-$messages['loading'] = 'در حال بارگزاری...';
-$messages['uploading'] = 'در حال بارگزاری Ùایل...';
-$messages['uploadingmany'] = 'در حال بارگزاری Ùایل ها...';
-$messages['loadingdata'] = 'در حال بارگزاری داده';
+$messages['refreshing'] = 'Refreshing...';
+$messages['loading'] = 'در حال باز شدن ...';
+$messages['uploading'] = 'Uploading file...';
+$messages['uploadingmany'] = 'Uploading files...';
+$messages['loadingdata'] = 'در حال بار کردن دیتا';
$messages['checkingmail'] = 'پيغام های جديد را بررسي ميکند';
$messages['sendingmessage'] = 'پيغام ها را ارسال ميکند';
$messages['messagesent'] = 'پیام موÙقانه ارسال گردید';
-$messages['savingmessage'] = 'در حال ذخیره کردن پیام';
+$messages['savingmessage'] = 'در حال Ø­Ùظ کردن پیام';
$messages['messagesaved'] = 'پيغام را به پیش نويس Ø­Ùظ کرد';
$messages['successfullysaved'] = 'Ø­Ùظ پیام موÙقانه صورت گرÙت';
$messages['addedsuccessfully'] = 'آدرس بصورت مکمل در کتاب ادرس علاوه شد';
@@ -59,23 +59,23 @@ $messages['senttooquickly'] = 'ثانیه منتظر باشید$secلطÙا مد
$messages['errorsavingsent'] = 'در جريان Ø­Ùظ کردن پیام ارسال شده يکاشتباه به وجود امد';
$messages['errorsaving'] = 'در جريان Ø­Ùظ کردن يکاشتباه به وجود امد';
$messages['errormoving'] = 'پيغام نقل مکان شده نتوانست';
-$messages['errorcopying'] = 'امکان کپی پیام (ها) وجود ندارد';
+$messages['errorcopying'] = 'Could not copy the message(s).';
$messages['errordeleting'] = 'پيغام حذ٠شده نتوانست';
-$messages['errormarking'] = 'امکان انتخاب پیام (ها) وجود ندارد';
+$messages['errormarking'] = 'Could not mark the message(s).';
$messages['deletecontactconfirm'] = 'آيا واقعاً شما ميخواهيد که آدرس های انتخاب شده را حذ٠کنيد؟';
$messages['deletegroupconfirm'] = 'Do you really want to delete selected group?';
$messages['deletemessagesconfirm'] = 'آيا واقعاً شما ميخواهيد که پيغام هاي انتخاب شده را حذ٠کنيد؟';
$messages['deletefolderconfirm'] = 'آيا واقعاً شما ميخواهيد که اين پوشه را حذ٠کنيد؟';
$messages['purgefolderconfirm'] = 'آيا واقعاً شما ميخواهيد تمام پيغام های که در اين پوشه وجود دارد حذ٠کنيد؟';
$messages['contactdeleting'] = 'Deleting contact(s)...';
-$messages['groupdeleting'] = 'در حال حذ٠گروه...';
+$messages['groupdeleting'] = 'Deleting group...';
$messages['folderdeleting'] = 'در حال حذ٠پوشه';
$messages['foldermoving'] = 'در حال انتقال پوشه';
$messages['foldersubscribing'] = 'Subscribing folder...';
$messages['folderunsubscribing'] = 'Unsubscribing folder...';
$messages['formincomplete'] = 'Ùورمه بصورت مکمل خانه پري نه شده است';
$messages['noemailwarning'] = 'لطÙاً ÙŠÚ© ايميل ادرس موجود را داخل کنيد';
-$messages['nonamewarning'] = 'لطÙاً ÙŠÚ© نام وارد کنيد';
+$messages['nonamewarning'] = 'لطÙاً ÙŠÚ© نام را داخل کنيد';
$messages['nopagesizewarning'] = 'لطÙاً اندازه ÙŠÚ© صÙحه را داخل کنيد';
$messages['nosenderwarning'] = 'لطÙاً ایمیل آدرس ارسال کننده را داخل کنید';
$messages['norecipientwarning'] = 'لطÙاً Ú©Ù… از Ú©Ù… ÙŠÚ© آدرس گيرينده را نوشته / داخل کنيد';
@@ -85,32 +85,29 @@ $messages['notsentwarning'] = 'پيغام ارسال نه شده است آیا
$messages['noldapserver'] = 'لطÙاً ÙŠÚ© ايل دپ سرور را بخاطر جستجو انتخاب کنيد';
$messages['nosearchname'] = 'لطÙاً ÙŠÚ© نام تماس Ùˆ يا هم ÙŠÚ© ايميل ادرس را داخل کنيد';
$messages['notuploadedwarning'] = 'Not all attachments have been uploaded yet. Please wait or cancel the upload.';
-$messages['searchsuccessful'] = '$nr پیام یاÙت شد';
-$messages['contactsearchsuccessful'] = '$nr حساب کاربری یاÙت شد';
+$messages['searchsuccessful'] = '$nr پیام دریاÙت شد';
+$messages['contactsearchsuccessful'] = '$nr contacts found.';
$messages['searchnomatch'] = 'جستجو گر موÙÙ‚ به دریاÙت هیچ گونه اثری نشد';
-$messages['searching'] = 'در حال جستجو..';
+$messages['searching'] = 'در حال جستجو';
$messages['checking'] = 'در حال بررسی';
$messages['nospellerrors'] = 'هيچ اشتباه املايي را درياÙت نه کرد';
$messages['folderdeleted'] = 'پوشه موÙقانه از بين رÙت/ حذ٠گرديد';
$messages['foldersubscribed'] = 'Folder successfully subscribed.';
$messages['folderunsubscribed'] = 'Folder successfully unsubscribed.';
-$messages['folderpurged'] = 'محتوای پوشه ها با موÙقیت پاک شدند';
+$messages['folderpurged'] = 'Folder has successfully been emptied.';
$messages['folderexpunged'] = 'Folder has successfully been compacted.';
-$messages['deletedsuccessfully'] = 'با موÙقیت حذ٠شد';
-$messages['converting'] = 'در حال پاک کردن ساختار';
+$messages['deletedsuccessfully'] = 'موÙقانه حذ٠شد';
+$messages['converting'] = 'در حال از بین بردن Ø´Ú©Ù„ دهی Ùˆ ساختار (Ùرمت)';
$messages['messageopenerror'] = 'پيغام از سرور جريان کرده نتوانست';
-$messages['fileuploaderror'] = 'بارگزاری Ùايل با خطا مواجه شد.';
+$messages['fileuploaderror'] = 'اپلود کردن Ùايل موÙÙ‚ نه شد.';
$messages['filesizeerror'] = 'تثبیت شده میباشد$size حجم Ùایل آپلود شده بیشتر از حجم Ú©Ù„ÛŒ';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'آدرس ها کاپی شد. $nrموÙقانه بع تعداد';
+$messages['copyerror'] = 'هيچ يک از تماس ها را کاپي کرده نتوانست';
$messages['sourceisreadonly'] = 'اجازه نمامه کود / منبع این آدرس Ù‚ÙØ· خواندنی است';
$messages['errorsavingcontact'] = 'ادرس این پیام را Ø­Ùظکرده نتوانست';
$messages['movingmessage'] = 'ذر حال انتقال پیام...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'در حال وارد کردن لطÙا صبر Ú©Ù†ÛŒØ
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts, $skipped existing entries skipped</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'اجازه این عملکرد را ندارید';
$messages['nofromaddress'] = 'بخش ایمیل آدرس در شناخت نامه انتخاب شده Ù…Ùقود است.';
$messages['editorwarning'] = 'استÙاده از تصحیح کننده متن ساده تمام Ùرمت Ùˆ ساختار داده شده را از بین خواهد برد. آیا میخواهید Ú©Ù‡ ادامه بدهید.';
diff --git a/program/localization/fa_IR/labels.inc b/program/localization/fa_IR/labels.inc
index 79bfbbe9d..221e4b891 100644
--- a/program/localization/fa_IR/labels.inc
+++ b/program/localization/fa_IR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'پیش‌نویس‌ها';
$labels['sent'] = 'Ùرستاده شده';
$labels['trash'] = 'سطل آشغال';
$labels['junk'] = 'بنجل';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'موضوع';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'نوع مشاهده Ùهرست';
$labels['folderactions'] = 'اعمال پوشه...';
$labels['compact'] = 'Ùشرده';
$labels['empty'] = 'خالی';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ùضای استÙاده شده';
$labels['unknown'] = 'ناشناخته';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'جستجوی دوباره';
$labels['searchmod'] = 'اصلاحات جستجو';
$labels['msgtext'] = 'کل پیغام';
$labels['body'] = 'بدنه';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'باز کردن در پنجره‌ی جدید';
$labels['emlsave'] = 'بارگیری (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'نمایش صÙحه آخر';
$labels['group'] = 'گروه';
$labels['groups'] = 'گروه‌ها';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'نشانی‌های شخصی';
$labels['searchsave'] = 'ذخیره جستجو';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'نادیده گرÙتن کلمات دارای
$labels['spellcheckignorecaps'] = 'نادیده گرÙتن کلمات با حرو٠بزرگ';
$labels['addtodict'] = 'اضاÙÙ‡ کردن به واژه‌نامه';
$labels['mailtoprotohandler'] = 'ثبت نگه‌دارنده پروتوکل برای mailto: پیوندها';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'بازگردانی پیغام';
$labels['inline'] = 'خطی';
$labels['asattachment'] = 'به عنوان پیوست';
diff --git a/program/localization/fa_IR/messages.inc b/program/localization/fa_IR/messages.inc
index 3f3f861d6..ff53c650e 100644
--- a/program/localization/fa_IR/messages.inc
+++ b/program/localization/fa_IR/messages.inc
@@ -21,19 +21,19 @@ $messages['errortitle'] = 'خطایی رخ داد!';
$messages['loginfailed'] = 'ورود ناموÙÙ‚ بود.';
$messages['cookiesdisabled'] = 'مرورگر شما کوکی‌ها را قبول نمی‌کند.';
$messages['sessionerror'] = 'نشست شما معتبر نیست، یا منقضی شده است.';
-$messages['storageerror'] = 'اتصال به سرور مخزن ناموÙÙ‚ بود.';
+$messages['storageerror'] = 'اتصال به سرور انباره ناموÙÙ‚ بود.';
$messages['servererror'] = 'خطای سرور!';
$messages['servererrormsg'] = 'خطای سرور: $msg';
-$messages['dberror'] = 'خطای پایگاه داده';
+$messages['dberror'] = 'خطای پایگاه‌داده';
$messages['requesttimedout'] = 'زمان درخواست تمام شد';
-$messages['errorreadonly'] = ' عمل مورد نظر انجام نشد. پوشه Ùقط خواندنی است.';
-$messages['errornoperm'] = ' عمل مورد نظر انجام نشد. دسترسی وجود ندارد.';
-$messages['erroroverquota'] = 'عملیات انجام نشد. دیسک Ùضای خالی ندارد.';
-$messages['erroroverquotadelete'] = 'دیسک Ùضای خالی ندارد. برای حذ٠پیغام از SHIFT+DEL استÙاده کنید.';
+$messages['errorreadonly'] = 'ناتوانی در انجام عملیات. پوشه Ùقط خواندنی است.';
+$messages['errornoperm'] = 'ناتوانی در انجام عملیات. دسترسی وجود ندارد.';
+$messages['erroroverquota'] = 'ناتوانی در انجام عملیات. Ùضای دیسک خالی نیست.';
+$messages['erroroverquotadelete'] = 'Ùضای دیسک خالی نیست. برای حذ٠پیغام از SHIFT+DEL استÙاده کنید.';
$messages['invalidrequest'] = 'درخواست نامعتبر! هیچ داده‌ای ذخیره نشد.';
$messages['invalidhost'] = 'نام سرور غیرمعتبر.';
-$messages['nomessagesfound'] = 'هیچ پیغامی در این صندوق‌پستی پیدا نشد.';
-$messages['loggedout'] = 'شما با موÙقیت نشست را پایان دادید. خدانگهدار!';
+$messages['nomessagesfound'] = 'هیچ پیغامی در این صندوق پیدا نشد.';
+$messages['loggedout'] = 'شما با موÙقیت نشست را پایان دادید. خدا نگه‌دار!';
$messages['mailboxempty'] = 'صندوق‌پستی خالی است.';
$messages['refreshing'] = 'نوسازی...';
$messages['loading'] = 'در حال بارگذاری...';
@@ -46,131 +46,126 @@ $messages['messagesent'] = 'پیغام با موÙقیت Ùرستاده شد.';
$messages['savingmessage'] = 'درحال ذخیره‌ی پیغام...';
$messages['messagesaved'] = 'پیغام در پیش‌نویس‌ها ذخیره شد';
$messages['successfullysaved'] = 'با موÙقیت ذخیره شد.';
-$messages['addedsuccessfully'] = 'مخاطب با موÙقیت به دÙتر نشانی‌ها اضاÙÙ‡ شد.';
-$messages['contactexists'] = 'یک مخاطب با این ایمیل از قبل وجود دارد.';
-$messages['contactnameexists'] = 'یک مخاطب با این نام از قبل وجود دارد.';
-$messages['blockedimages'] = 'برای Ø­Ùاظت از حریم شخصی شما، عکس‌های با آدرس خارجی در این پیغام مسدود شده‌اند.';
+$messages['addedsuccessfully'] = 'تماس با موÙقیت به دÙتر نشانی‌ها اضاÙÙ‡ شد';
+$messages['contactexists'] = 'یک تماس با این نشانی ایمیل از قبل وجود دارد.';
+$messages['contactnameexists'] = 'یک تماس با این نام از قبل وجود دارد.';
+$messages['blockedimages'] = 'برای Ø­Ùاظت از حریم شخصی شما، عکس‌های دوردست از پیغام حذ٠شد.';
$messages['encryptedmessage'] = '!این یک پیغام رمزنگاری شده است و قابل نمایش نیست. ببخشید';
-$messages['nocontactsfound'] = 'هیج مخاطبی پیدا نشد.';
-$messages['contactnotfound'] = 'مخاطب درخواست شده پیدا نشد.';
-$messages['contactsearchonly'] = 'برای یاÙتن مخاطب عبارتی را جستجو کنید';
-$messages['sendingfailed'] = 'ارسال پیغام ناموÙÙ‚ بود.';
-$messages['senttooquickly'] = 'لطÙا قبل از ارسال این پیغام $sec ثانیه صبر کنید.';
-$messages['errorsavingsent'] = 'در لحظه ذخیره پیغام ارسال شده، مشکلی رخ داد.';
-$messages['errorsaving'] = 'هنگام ذخیره‌سازی، مشکلی رخ داد.';
-$messages['errormoving'] = 'پیغام(ها) منتقل نشدند.';
-$messages['errorcopying'] = 'پیغام(ها) کپی نشدند.';
-$messages['errordeleting'] = 'پیغام(ها) حذ٠نشدند.';
-$messages['errormarking'] = 'پیغام(ها) نشانه‌گذاری نشدند.';
-$messages['deletecontactconfirm'] = 'آیا واقعاً می‌خواهید مخاطب(های) انتخاب شده را حذ٠کنید؟';
+$messages['nocontactsfound'] = 'هیج تماسی پیدا نشد.';
+$messages['contactnotfound'] = 'تماس درخواست شده پیدا نشد.';
+$messages['contactsearchonly'] = 'چند عبارات جستجو برای یاÙتن تماس ها وارد نمایید';
+$messages['sendingfailed'] = 'ناموÙÙ‚ در Ùرستادن پیغام.';
+$messages['senttooquickly'] = 'لطÙا قبل از ارسال این پیغام $sec صبر کنید.';
+$messages['errorsavingsent'] = 'در لحظه ذخیره پیغام ارسال شده، مشکل به وجود آمد.';
+$messages['errorsaving'] = 'هنگام ذخیره‌سازی، اشکالی پیش آمد.';
+$messages['errormoving'] = 'ناتوان در انتقال پیغام(ها).';
+$messages['errorcopying'] = 'ناتوان در رونوشت پیغام(ها).';
+$messages['errordeleting'] = 'ناتوان در حذ٠پیغام(ها).';
+$messages['errormarking'] = 'ناتوان در نشانه گذاری پیغام(ها).';
+$messages['deletecontactconfirm'] = 'آیا واقعاً می‌خواهید تماس(های) انتخاب شده را حذ٠کنید؟';
$messages['deletegroupconfirm'] = 'آیا واقعا می‌خواهید گروه انتخاب شده را حذ٠کنید؟';
$messages['deletemessagesconfirm'] = 'آیا واقعاً می‌خواهید پیغام(های) انتخاب شده را حذ٠کنید؟';
$messages['deletefolderconfirm'] = 'آیا واقعاً می‌خواهید این پوشه را حذ٠کنید؟';
$messages['purgefolderconfirm'] = 'آیا واقعاً می‌خواهید همه‌ی پیغام‌های داخل این پوشه را حذ٠کنید؟';
-$messages['contactdeleting'] = 'حذ٠مخاطب(ها)...';
+$messages['contactdeleting'] = 'حذ٠تماس(ها)...';
$messages['groupdeleting'] = 'حذ٠گروه...';
$messages['folderdeleting'] = 'حذ٠پوشه...';
$messages['foldermoving'] = 'انتقال پوشه...';
$messages['foldersubscribing'] = 'اشتراک پوشه...';
$messages['folderunsubscribing'] = 'لغو اشتراک پوشه...';
-$messages['formincomplete'] = 'Ùرم کامل پر نشده بود.';
-$messages['noemailwarning'] = 'لطÙا یک پست الکترونیکی معتبر وارد کنید.';
+$messages['formincomplete'] = 'Ùرم کاملاً پر نشده بود.';
+$messages['noemailwarning'] = 'لطÙا یک نشانی پست الکترونیکی معتبر وارد کنید.';
$messages['nonamewarning'] = 'لطÙا یک نام وارد کنید.';
-$messages['nopagesizewarning'] = 'لطÙا اندازه‌ی صÙحه را وارد کنید.';
-$messages['nosenderwarning'] = 'لطÙا پست الکترونیکی Ùرستنده را وارد کنید.';
+$messages['nopagesizewarning'] = 'لطÙا اندازه ÛŒ صÙحه را وارد کنید.';
+$messages['nosenderwarning'] = 'لطÙا آدرس پست الکترونیکی Ùرستنده را وارد کنید.';
$messages['norecipientwarning'] = 'لطÙاً حداقل یک گیرنده وارد کنید.';
-$messages['nosubjectwarning'] = 'قسمت "موضوع" خالی است. می‌خواهید اکنون وارد کنید؟';
+$messages['nosubjectwarning'] = 'قسمت "موضوع" خالی است. آیا می‌خواهید اکنون وارد کنید؟';
$messages['nobodywarning'] = 'این پیغام بدون متن ارسال شود؟';
$messages['notsentwarning'] = 'پیغام ارسال نشده است. آیا می‌خواهید پیغام را از بین ببرید؟';
-$messages['noldapserver'] = 'لطÙا یک سرور LDAP برای جست‌و‌جو انتخاب کنید.';
-$messages['nosearchname'] = 'لطÙا نام یک مخاطب یا یک نشانی ایمیل وارد کنید.';
-$messages['notuploadedwarning'] = 'همه پیوست ها هنوز بارگذاری نشده‌اند. لطÙا صبر کرده یا بارگذاری را لغو کنید.';
-$messages['searchsuccessful'] = '$nr پیغام پیدا شد.';
-$messages['contactsearchsuccessful'] = '$nr مخاطب ییدا شد.';
-$messages['searchnomatch'] = 'جست‌و‌جو هیچ نتیجه‌ای نداشت.';
-$messages['searching'] = 'در حال جست‌و‌جو...';
+$messages['noldapserver'] = 'برای جست Ùˆ جو انتخاب کنید LDAP لطÙا یک سرور.';
+$messages['nosearchname'] = 'لطÙا نام یک تماس Ùˆ یا یک نشانی ایمیل وارد کنید.';
+$messages['notuploadedwarning'] = 'همه پیوست ها هنوز بارگذاری نشده اند. لطÙا صبر کنید یا بارگذاری را لغو کنید.';
+$messages['searchsuccessful'] = '$nr پیغام پیدا شد';
+$messages['contactsearchsuccessful'] = '$nr تماس ییدا شد.';
+$messages['searchnomatch'] = 'جست و جو هیچ نتیجه‌ای نداشت.';
+$messages['searching'] = 'در حال جست و جو...';
$messages['checking'] = 'در حال بررسی...';
$messages['nospellerrors'] = 'هیچ اشکال املایی پیدا نشد.';
$messages['folderdeleted'] = 'پوشه با موÙقیت حذ٠شد.';
-$messages['foldersubscribed'] = 'اشتراک پوشه با موÙقیت انجام شد.';
+$messages['foldersubscribed'] = 'پوشه با موÙقیت اشتراک شد.';
$messages['folderunsubscribed'] = 'اشتراک پوشه با موÙقیت لغو شد.';
$messages['folderpurged'] = 'پوشه با موÙقیت خالی شد.';
$messages['folderexpunged'] = 'پوشه با موÙقیت Ùشرده شد.';
$messages['deletedsuccessfully'] = 'با موÙقیت حذ٠شد.';
$messages['converting'] = 'در حال حذ٠قالب‌بندی...';
-$messages['messageopenerror'] = 'بارگذاری پیغام از روی سرور انجام نشد.';
+$messages['messageopenerror'] = 'ناتوان در بارگذاری پیغام از روی سرور.';
$messages['fileuploaderror'] = 'بارگذاری پرونده ناموÙÙ‚ بود.';
$messages['filesizeerror'] = 'اندازه‌ی پرونده‌ی بارگذاری شده از بیشینه اندازه‌ی $size بیشتر است.';
-$messages['copysuccess'] = '$nr مخاطب با موÙقیت Ú©Ù¾ÛŒ شد.';
-$messages['movesuccess'] = '$nr مخاطب با موÙقیت جابجا شد.';
-$messages['copyerror'] = 'مخاطب‌ها کپی نشدند.';
-$messages['moveerror'] = 'مخاطب‌ها جابجا نشدند.';
-$messages['sourceisreadonly'] = 'این منبع نشانی Ùقط خواندنی است.';
-$messages['errorsavingcontact'] = 'ذخیره‌ی نشانی مخاطب ناموÙÙ‚ بود.';
+$messages['copysuccess'] = '$nr نشانی با موÙقیت رونوشت‌برداری شدند.';
+$messages['copyerror'] = 'رونوشت‌برداری از نشانی‌ها ناموÙÙ‚ بود.';
+$messages['sourceisreadonly'] = 'این منبع نشانی Ùقط‌خواندنی است.';
+$messages['errorsavingcontact'] = 'ذخیره‌ی نشانی تماس ناموÙÙ‚ بود.';
$messages['movingmessage'] = 'در حال انتقال پیغام(ها)...';
-$messages['copyingmessage'] = 'در حال کپی‌برداری از پیغام(ها)...';
-$messages['copyingcontact'] = 'در حال کپی‌برداری مخاطب(ها)...';
-$messages['movingcontact'] = 'در حال جابجایی مخاطب(ها)...';
+$messages['copyingmessage'] = 'در حال رونوشت پیغام(ها)...';
+$messages['copyingcontact'] = 'در حال رونوشت تماس(ها)...';
$messages['deletingmessage'] = 'در حال حذ٠پیغام(ها)...';
$messages['markingmessage'] = 'در حال نشانه‌گذاری پیغام(ها)...';
-$messages['addingmember'] = 'در حال اÙزودن مخاطب(ها) به گروه...';
-$messages['removingmember'] = 'در حال حذ٠مخاطب(ها) از گروه...';
+$messages['addingmember'] = 'در حال اÙزودن تماس(ها) به گروه...';
+$messages['removingmember'] = 'در حال انتقال تماس(ها) از گروه...';
$messages['receiptsent'] = 'رسید خواندن با موÙقیت ارسال شد.';
-$messages['errorsendingreceipt'] = 'ارسال رسید انجام نشد.';
-$messages['deleteidentityconfirm'] = 'آیا از حذ٠این شناسه مطمئن هستید؟';
-$messages['nodeletelastidentity'] = 'این شناسه را نمی‌توانید حذ٠کنید، زیرا آخرین شناسه شما است.';
-$messages['forbiddencharacter'] = 'نام پوشه شامل یک کاراکتر غیر مجاز است.';
-$messages['selectimportfile'] = 'لطÙاً پرونده‌ای را برای بارگذاری انتخاب کنید.';
+$messages['errorsendingreceipt'] = 'ناتوان در ارسال رسید.';
+$messages['deleteidentityconfirm'] = 'آیا شما مطمئن به حذ٠این شناسه هستید.';
+$messages['nodeletelastidentity'] = 'نمی‌توانید این شناسه را حذ٠کنید، زیرا آخرین شناسه شما است.';
+$messages['forbiddencharacter'] = 'نام پوشه شامل یک حر٠غیر مجاز است.';
+$messages['selectimportfile'] = 'لطÙاً پرونده ای را برای بارگیری انتخاب کنید.';
$messages['addresswriterror'] = 'دÙترچه آدرس انتخابی قابل نوشتن نیست.';
-$messages['contactaddedtogroup'] = 'مخاطب‌ها با موÙقیت به این گروه اضاÙÙ‡ شدند.';
-$messages['contactremovedfromgroup'] = 'مخاطب‌ها با موÙقیت از این گروه حذ٠شدند.';
+$messages['contactaddedtogroup'] = 'تماس ها با موÙقیت به این گروه اضاÙÙ‡ شدند.';
+$messages['contactremovedfromgroup'] = 'تماس ها با موÙقیت از این گروه حذ٠شدند.';
$messages['nogroupassignmentschanged'] = 'هیچ تکلی٠گروهی تغییر نکرده است.';
$messages['importwait'] = 'در حال وارد کردن، لطÙا صبر کنید...';
$messages['importformaterror'] = 'وارد کردن ناموÙÙ‚! Ùایل بارگذاری شده یک Ùایل اطلاعات معتبر نیست.';
-$messages['importconfirm'] = '<b>$inserted مخاطب با موÙقیت وارد شدند</b>';
-$messages['importconfirmskipped'] = '<b>$skipped ورودی موجود نادیده گرÙته شدند</b>';
-$messages['importmessagesuccess'] = 'با موÙقیت $nr پیغام وارد شد.';
-$messages['importmessageerror'] = 'وارد کردن ناموÙÙ‚! Ùایل بارگذاری شده یک پیغام یا صندوق‌پستی معتبر نیست.';
+$messages['importconfirm'] = '<b>تماس های $inserted با موÙقیت وارد شدند</b>';
+$messages['importconfirmskipped'] = '<b>ورودی های موجود $skipped نادیده گرÙته شدند</b>';
$messages['opnotpermitted'] = 'عملیات مجاز نیست!';
-$messages['nofromaddress'] = 'شناسه انتخاب شده پست الکترونیکی ندارد.';
+$messages['nofromaddress'] = 'آدرس پست الکترونیکی های Ù…Ùقود در شناسه انتخاب شده.';
$messages['editorwarning'] = 'تعویض به ویرایشگر متن ساده باعث از دست رÙتن قالب‌بندی همه متن‌ها می‌شود، آیا می‌خواهید عملیات را ادامه بدهید؟';
-$messages['httpreceivedencrypterror'] = 'یک خطای پیکربندی خطرناک رخ داده است. سریعا با سرپرست یا مسئول خود تماس بگیرید. <b>امکان ارسال پیغام شما وجود ندارد.</b>';
+$messages['httpreceivedencrypterror'] = 'یک خطای تنظیم وخیم رخ داده است. سریعا با سرپرست یا مدیر خود تماس بگیرید. <b>امکان ارسال پیغام شما وجود ندارد.</b>';
$messages['smtpconnerror'] = 'خطای SMTP (%code): اتصال به سرور ناموÙÙ‚ بود.';
$messages['smtpautherror'] = 'خطای SMTP (%code): تصدیق هویت ناموÙÙ‚ بود.';
$messages['smtpfromerror'] = 'خطای SMTP (%code): ناموÙÙ‚ در تنظیم Ùرستنده "$from" ($msg).';
$messages['smtptoerror'] = 'خطای SMTP (%code): نام موÙÙ‚ در اÙزودن گیرنده "$to" ($msg).';
$messages['smtprecipientserror'] = 'خطای SMTP: ناتوان در تجزیه Ùهرست گیرنده‌ها.';
$messages['smtperror'] = 'خطای SMTP: $msg';
-$messages['emailformaterror'] = 'پست الکترونیکی نامعتبر: $email';
-$messages['toomanyrecipients'] = 'گیرنده‌های بیش از اندازه: تعداد گیرنده ها را به $max کاهش دهید.';
-$messages['maxgroupmembersreached'] = 'تعداد اعضای گروه بیشتر از $max است.';
+$messages['emailformaterror'] = 'آدرس پیت الکترونیکی نامعتبر: $email';
+$messages['toomanyrecipients'] = 'گیرنده های خیلی زیاد: تعداد گیرنده ها را به تعداد $max کاهش دهید.';
+$messages['maxgroupmembersreached'] = 'تعداد اعضاء گروه از مقدار بیشینه $max بیشتر است.';
$messages['internalerror'] = 'خطای داخلی رخ داد. لطÙا دوباره امتحان کنید.';
-$messages['contactdelerror'] = 'حذ٠مخاطب(ها) انجام شد.';
-$messages['contactdeleted'] = 'مخاطب(ها) با موÙقیت حذ٠شدند.';
-$messages['contactrestoreerror'] = 'مخاطب(های) حذ٠شده بازگردانی نخواهند شد.';
-$messages['contactrestored'] = 'مخاطب(ها) با موÙقیت بازگردانده شدند.';
+$messages['contactdelerror'] = 'تماس(ها) حذ٠نخواهند شد.';
+$messages['contactdeleted'] = 'تماس(ها) با موÙقیت حذ٠شدند.';
+$messages['contactrestoreerror'] = 'تماس(های) حذ٠شده بازگردانی نخواهند شد.';
+$messages['contactrestored'] = 'تماس(ها) با موÙقیت بازگردانده شدند.';
$messages['groupdeleted'] = 'گروه با موÙقیت حذ٠شد.';
-$messages['grouprenamed'] = 'نام گروه با موÙقیت تغییر داده شد.';
+$messages['grouprenamed'] = 'گروه با موÙقیت تغییر نام داده شد.';
$messages['groupcreated'] = 'گروه با موÙقیت ایجاد شد.';
-$messages['savedsearchdeleted'] = 'جستجوی ذخیره شده با موÙقیت حذ٠شد.';
-$messages['savedsearchdeleteerror'] = 'حذ٠جستجوی ذخیره شده انجام نشد.';
-$messages['savedsearchcreated'] = 'جستجوی حذ٠شده با موÙقیت ایجاد شد.';
-$messages['savedsearchcreateerror'] = 'ساخت جستجوی ذخیره شده انجام نشد.';
+$messages['savedsearchdeleted'] = 'جستجوی ذخیره شد با موÙقیت حذ٠شد.';
+$messages['savedsearchdeleteerror'] = 'جستجوی ذخیره شد حذ٠نخواهد شد.';
+$messages['savedsearchcreated'] = 'جستجوی حذ٠شده با موÙقیت حذ٠شد.';
+$messages['savedsearchcreateerror'] = 'جستجوی ذخیره شده اÙزوده نخواهد شد.';
$messages['messagedeleted'] = 'پیغام(ها) با موÙقیت حذ٠شدند.';
$messages['messagemoved'] = 'پیغام(ها) با موÙقیت منتقل شدند.';
-$messages['messagecopied'] = 'پیغام(ها) با موÙقیت Ú©Ù¾ÛŒ شدند.';
-$messages['messagemarked'] = 'پیغام(ها) با موÙقیت نشانه‌گذاری شدند.';
+$messages['messagecopied'] = 'پیغام(ها) با موÙقیت رونوشت شدند.';
+$messages['messagemarked'] = 'پیغام(ها) با موÙقیت نشانه گذاری شدند.';
$messages['autocompletechars'] = 'حداقل $min حر٠برای تکمیل خودکار وارد نمایید.';
-$messages['autocompletemore'] = 'نتایج زیادی یاÙت شد. لطÙا حرو٠بیشتری وارد نمایید.';
+$messages['autocompletemore'] = 'تعداد ورودی های هماهنگ زیادی یاÙت شد. لطÙا حرو٠بیشتری وارد نمایید.';
$messages['namecannotbeempty'] = 'نام نمی‌تواند خالی باشد.';
$messages['nametoolong'] = 'نام خیلی طولانی است.';
-$messages['folderupdated'] = 'پوشه با موÙقیت به‌روز شد.';
+$messages['folderupdated'] = 'پوشه با موÙقیت بارگذاری شد.';
$messages['foldercreated'] = 'پوشه با موÙقیت اÙزوده شد.';
-$messages['invalidimageformat'] = 'Ùرمت تصویر نامعتبر است.';
+$messages['invalidimageformat'] = 'Ùرمت تصویر نامعتبر.';
$messages['mispellingsfound'] = 'خطای املایی در پیغام شناسایی شد.';
-$messages['parentnotwritable'] = 'به دلیل نداشتن حق دسترسی، ایجاد/انتقال پوشه به پوشه والد انتخاب شده، انجام نشد.';
-$messages['messagetoobig'] = 'بخش پیغام برای پردازش آن خیلی بزرگ است.';
-$messages['attachmentvalidationerror'] = 'هشدار! این پیوست مشکوک است زیرا نوع آن با نوعی Ú©Ù‡ در پیغام اشاره شده مطابقت ندارد. اگر شما به Ùرستنده اطمینان ندارید، نباید آن را در مرورگر باز نمایید زیرا ممکن است Ú©Ù‡ شامل محتوای مخرب باشد.<br><br><em>مورد انتظار: $expected; یاÙت شده: $detected</em>';
-$messages['noscriptwarning'] = 'هشدار: این برنامه به جاوااسکریپت نیاز دارد! برای استÙاده از این برنامه لطÙا جاوااسکریپت را در تنظیمات مرورگر خود Ùعال نمایید.';
+$messages['parentnotwritable'] = 'ناتوانی در ایجاد/انتقال پوشه به پوشه والد انتخاب شده. بدون حق دسترسی.';
+$messages['messagetoobig'] = 'بخش پیغام برای اجرای آن خیلی بزرگ است.';
+$messages['attachmentvalidationerror'] = 'هشدار! این پیوست مشکوک است زیرا نوع آن با نوعی Ú©Ù‡ در پیغام اشاره شده مطابقت ندارد. اگر شما Ùرستنده را تایید نمی‌کنید، شما نباید آن را در مرورگر باز نمایید زیرا ممکن است Ú©Ù‡ شامل محتوای مخرب باشد.<br/><br/><em>مورد انتظار: $expected; یاÙت شده: $detected</em>';
+$messages['noscriptwarning'] = 'هشدار: این برنامه به جاوااسکریپت نیاز دارد! برای استÙاده از این لطÙا جاوااسکریپت را در تنظیمات مرورگر خود Ùعال نمایید.';
?>
diff --git a/program/localization/fi_FI/labels.inc b/program/localization/fi_FI/labels.inc
index ef0f0bff0..ea856b389 100644
--- a/program/localization/fi_FI/labels.inc
+++ b/program/localization/fi_FI/labels.inc
@@ -194,7 +194,6 @@ $labels['listmode'] = 'Listausnäkymä';
$labels['folderactions'] = 'Kansiotoiminnot...';
$labels['compact'] = 'Tiivistä';
$labels['empty'] = 'Tyhjennä';
-$labels['importmessages'] = 'Tuo viestejä';
$labels['quota'] = 'Levytila';
$labels['unknown'] = 'tuntematon';
@@ -205,7 +204,6 @@ $labels['resetsearch'] = 'Nollaa haku';
$labels['searchmod'] = 'Hakukriteerit';
$labels['msgtext'] = 'Koko viesti';
$labels['body'] = 'Runko';
-$labels['type'] = 'Tyyppi';
$labels['openinextwin'] = 'Avaa uudessa ikkunassa';
$labels['emlsave'] = 'Tallenna (.eml)';
@@ -357,7 +355,6 @@ $labels['lastpage'] = 'Näytä viimeinen luettelo';
$labels['group'] = 'Ryhmä';
$labels['groups'] = 'Ryhmät';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Henkilökohtaiset osoitteet';
$labels['searchsave'] = 'Tallenna haku';
diff --git a/program/localization/fi_FI/messages.inc b/program/localization/fi_FI/messages.inc
index adcb36607..3a8c393d6 100644
--- a/program/localization/fi_FI/messages.inc
+++ b/program/localization/fi_FI/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Tietokantavirhe!';
$messages['requesttimedout'] = 'Pyyntö aikakatkaistiin';
$messages['errorreadonly'] = 'Toiminnon suoritus ei onnistu, koska hakemisto on vain lukutilassa.';
$messages['errornoperm'] = 'Toimintoa ei voitu suorittaa. Ei oikeuksia.';
+$messages['erroroverquota'] = 'Toiminnon suoritus epäonnistui. Levytila on loppu.';
+$messages['erroroverquotadelete'] = 'Levytila on loppu. Paina SHIFT+DEL poistaaksesi viestin.';
$messages['invalidrequest'] = 'Virheellinen pyyntö! Tietoa ei tallennettu.';
$messages['invalidhost'] = 'Virheellinen palvelinnimi.';
$messages['nomessagesfound'] = 'Kansiossa ei ole sähköpostiviestejä';
@@ -163,7 +165,7 @@ $messages['invalidimageformat'] = 'Virheellinen kuvamuoto.';
$messages['mispellingsfound'] = 'Viestissä havaittiin kielioppivirheitä.';
$messages['parentnotwritable'] = 'Kansiota ei voitu siirtää tai luoda valittuun yläkansioon. Ei käyttöoikeutta.';
$messages['messagetoobig'] = 'Viestiosa on liian suuri prosessoitavaksi.';
-$messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.<br/><br/><em>Expected: $expected; found: $detected</em>';
+$messages['attachmentvalidationerror'] = 'Varoitus! Tämä liitetiedosto on epäilyttävä, koska se ei vastaa ilmoitettua tiedostotyyppiä. Jos et luoda lähettäjään, älä avaa liitetiedostoa välttääksesi mahdollista vahingollista aineistoa.<br/><br/><em>Odotettu: $expected; löydetty: $detected</em>';
$messages['noscriptwarning'] = 'Varoitus: Tämä verkkopohjainen sähköpostipalvelu vaatii Javascriptin toimiakseen. Ota Javascript käyttöön selaimesi asetuksista.';
?>
diff --git a/program/localization/fr_FR/labels.inc b/program/localization/fr_FR/labels.inc
index 2a4f3a169..8331bbb54 100644
--- a/program/localization/fr_FR/labels.inc
+++ b/program/localization/fr_FR/labels.inc
@@ -194,7 +194,6 @@ $labels['listmode'] = 'Mode d\'affichage de la liste';
$labels['folderactions'] = 'Actions du dossier...';
$labels['compact'] = 'Compacter';
$labels['empty'] = 'Vider';
-$labels['importmessages'] = 'Importer des messages';
$labels['quota'] = 'Occupation disque';
$labels['unknown'] = 'inconnue';
@@ -205,7 +204,6 @@ $labels['resetsearch'] = 'Réinitialiser la recherche';
$labels['searchmod'] = 'Portée de la recherche';
$labels['msgtext'] = 'Message entier';
$labels['body'] = 'Corps';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ouvrir dans une nouvelle fenêtre';
$labels['emlsave'] = 'Télécharger (.eml)';
@@ -357,7 +355,6 @@ $labels['lastpage'] = 'Voir la dernière page';
$labels['group'] = 'Groupe';
$labels['groups'] = 'Groupes';
-$labels['listgroup'] = 'Liste des membres du groupe';
$labels['personaladrbook'] = 'Adresses personnelles';
$labels['searchsave'] = 'Enregistrer la recherche';
@@ -406,7 +403,7 @@ $labels['htmleditor'] = 'Composer un message au format HTML';
$labels['htmlonreply'] = 'en réponse aux messages HTML uniquement';
$labels['htmlonreplyandforward'] = 'Transférer ou répondre au message HTML';
$labels['htmlsignature'] = 'Signature HTML';
-$labels['showemail'] = 'Montrer l\'adresse de courriel avec le nom complet';
+$labels['showemail'] = 'Montrer l\'adresse mail avec le nom complet';
$labels['previewpane'] = 'Afficher le panneau d\'aperçu';
$labels['skin'] = 'Thème de l\'interface';
$labels['logoutclear'] = 'Vider la corbeille à la déconnexion';
@@ -467,9 +464,9 @@ $labels['reqmdn'] = 'Toujours demander un avis de réception';
$labels['reqdsn'] = 'Toujours demander une notification d\'état de distribution';
$labels['replysamefolder'] = 'Placer les réponses dans le dossier du message auquel il est répondu';
$labels['defaultabook'] = 'Carnet d\'adresses par défaut';
-$labels['autocompletesingle'] = 'Ne pas tenir compte des adresses de courriel alternatives dans l\'autoremplissage';
+$labels['autocompletesingle'] = 'Ne pas tenir compte des adresses emails alternatives dans l\'autoremplissage';
$labels['listnamedisplay'] = 'Lister les contacts comme';
-$labels['spellcheckbeforesend'] = 'Vérifier l’orthographe avant l’envoi d’un message';
+$labels['spellcheckbeforesend'] = 'Vérifier l’orthographe avant l’envoie d’un message';
$labels['spellcheckoptions'] = 'Options du vérificateur d\'orthographe';
$labels['spellcheckignoresyms'] = 'Ignorer les mots avec des symboles';
$labels['spellcheckignorenums'] = 'Ignorer les mots avec des nombres';
diff --git a/program/localization/fr_FR/messages.inc b/program/localization/fr_FR/messages.inc
index a736e103e..8de50e9e5 100644
--- a/program/localization/fr_FR/messages.inc
+++ b/program/localization/fr_FR/messages.inc
@@ -18,150 +18,150 @@
$messages = array();
$messages['errortitle'] = 'Une erreur est survenue !';
-$messages['loginfailed'] = 'L\'authentification a échoué';
-$messages['cookiesdisabled'] = 'Votre navigateur n\'accepte pas les cookies';
-$messages['sessionerror'] = 'Votre session est invalide ou a expiré';
-$messages['storageerror'] = 'Erreur de connexion au serveur IMAP';
+$messages['loginfailed'] = 'L\'authentification a échoué.';
+$messages['cookiesdisabled'] = 'Votre navigateur n\'accepte pas les cookies.';
+$messages['sessionerror'] = 'Votre session est invalide ou a expiré.';
+$messages['storageerror'] = 'Erreur de connexion au serveur IMAP.';
$messages['servererror'] = 'Erreur Serveur !';
-$messages['servererrormsg'] = 'Erreur du serveur: $msg';
-$messages['dberror'] = 'Erreur avec la base de donnée!';
+$messages['servererrormsg'] = 'Erreur du serveur : $msg';
+$messages['dberror'] = 'Erreur avec la base de données !';
$messages['requesttimedout'] = 'Délai de la requête expiré';
-$messages['errorreadonly'] = 'Impossible d\'effectuer cette opération. Le dossier est en lecture seule';
-$messages['errornoperm'] = 'Impossible d\'effectuer cette opération. Permission refusée';
+$messages['errorreadonly'] = 'Impossible d\'effectuer cette opération. Le dossier est en lecture seule.';
+$messages['errornoperm'] = 'Impossible d\'effectuer cette opération. Permission refusée.';
$messages['erroroverquota'] = 'Impossible d\'effectuer cette opération. Plus d\'espace libre.';
$messages['erroroverquotadelete'] = 'Plus d\'espace libre. Utilisez SHIFT+DEL pour supprimer un message.';
$messages['invalidrequest'] = 'Requête invalide ! Aucune donnée n\'a été sauvegardée.';
$messages['invalidhost'] = 'Nom du serveur invalide.';
$messages['nomessagesfound'] = 'Cette boîte aux lettres ne contient aucun message.';
-$messages['loggedout'] = 'Vous venez de vous déconnecter avec succès. Au revoir !';
+$messages['loggedout'] = 'Vous vous êtes correctement déconnecté. Au revoir !';
$messages['mailboxempty'] = 'La boîte aux lettres est vide.';
$messages['refreshing'] = 'Rafraîchissement en cours...';
-$messages['loading'] = 'Chargement...';
-$messages['uploading'] = 'Envoi du fichier...';
-$messages['uploadingmany'] = 'Envoi des fichiers ...';
-$messages['loadingdata'] = 'Chargement des données...';
+$messages['loading'] = 'Chargement en cours...';
+$messages['uploading'] = 'Transfert du fichier en cours...';
+$messages['uploadingmany'] = 'Transfert des fichiers en cours...';
+$messages['loadingdata'] = 'Chargement des données en cours...';
$messages['checkingmail'] = 'Vérification des nouveaux messages...';
-$messages['sendingmessage'] = 'Expédition du message...';
-$messages['messagesent'] = 'Message expédié.';
-$messages['savingmessage'] = 'Sauvegarde du message...';
-$messages['messagesaved'] = 'Message sauvegardé dans Brouillons';
-$messages['successfullysaved'] = 'Sauvegarde effectuée';
-$messages['addedsuccessfully'] = 'Contact ajouté dans le carnet d\'adresses';
-$messages['contactexists'] = 'Cette adresse courriel est utilisée par un autre contact';
+$messages['sendingmessage'] = 'Envoi du message en cours...';
+$messages['messagesent'] = 'Le message a bien été expédié.';
+$messages['savingmessage'] = 'Sauvegarde du message en cours...';
+$messages['messagesaved'] = 'Message sauvegardé dans Brouillons.';
+$messages['successfullysaved'] = 'La sauvegarde a bien été effectuée.';
+$messages['addedsuccessfully'] = 'Le contact a bien été ajouté dans le carnet d\'adresses.';
+$messages['contactexists'] = 'Cette adresse courriel est utilisée par un autre contact.';
$messages['contactnameexists'] = 'Il existe déjà un contact nommé ainsi.';
$messages['blockedimages'] = 'Les images distantes sont bloquées pour protéger votre vie privée.';
$messages['encryptedmessage'] = 'Désolé, ce message est chiffré et ne peut être affiché.';
-$messages['nocontactsfound'] = 'Aucun contact n\'a pu être trouvé';
+$messages['nocontactsfound'] = 'Aucun contact n\'a pu être trouvé.';
$messages['contactnotfound'] = 'Le contact demandé n\'a pas été trouvé.';
-$messages['contactsearchonly'] = 'Entrez un ou plusieurs mots clés pour trouver des contacts';
-$messages['sendingfailed'] = 'L\'envoi du message a échoué';
-$messages['senttooquickly'] = 'Vous devez attendre $sec s. pour envoyer le message';
-$messages['errorsavingsent'] = 'Une erreur est survenue pendant la sauvegarde du message envoyé';
-$messages['errorsaving'] = 'Une erreur a empêché la sauvegarde';
-$messages['errormoving'] = 'Impossible de déplacer le message';
-$messages['errorcopying'] = 'La copie de ce(s) message(s) a échoué.';
-$messages['errordeleting'] = 'Impossible d\'effacer le message';
-$messages['errormarking'] = 'Impossible de marquer le message';
+$messages['contactsearchonly'] = 'Entrez un ou plusieurs mots clés pour trouver des contacts.';
+$messages['sendingfailed'] = 'L\'envoi du message a échoué.';
+$messages['senttooquickly'] = 'Veuillez patienter $sec s. pour envoyer ce message.';
+$messages['errorsavingsent'] = 'Une erreur est survenue pendant la sauvegarde du message envoyé.';
+$messages['errorsaving'] = 'Une erreur est survenue pendant la sauvegarde.';
+$messages['errormoving'] = 'Impossible de déplacer le(s) message(s).';
+$messages['errorcopying'] = 'Impossible de copier le(s) message(s).';
+$messages['errordeleting'] = 'Impossible de supprimer le(s) message(s).';
+$messages['errormarking'] = 'Impossible de marquer le(s) message(s).';
$messages['deletecontactconfirm'] = 'Êtes-vous sûr de vouloir supprimer le(s) contact(s) sélectionné(s) ?';
$messages['deletegroupconfirm'] = 'Êtes-vous sûr de vouloir supprimer le groupe sélectionné ?';
$messages['deletemessagesconfirm'] = 'Êtes-vous sûr de vouloir supprimer le(s) message(s) sélectionné(s) ?';
$messages['deletefolderconfirm'] = 'Êtes-vous sûr de vouloir supprimer ce dossier ?';
$messages['purgefolderconfirm'] = 'Êtes-vous sûr de vouloir supprimer tous les messages de ce dossier ?';
-$messages['contactdeleting'] = 'Suppression de contact(s)...';
-$messages['groupdeleting'] = 'Suppression du groupe ...';
+$messages['contactdeleting'] = 'Suppression de contact(s) en cours...';
+$messages['groupdeleting'] = 'Suppression du groupe...';
$messages['folderdeleting'] = 'Suppression du dossier...';
$messages['foldermoving'] = 'Déplacement du dossier...';
$messages['foldersubscribing'] = 'Inscription du dossier...';
$messages['folderunsubscribing'] = 'Désinscription du dossier...';
-$messages['formincomplete'] = 'Le formulaire n\'a pas été entièrement rempli';
-$messages['noemailwarning'] = 'Veuillez spécifier un courriel valide';
-$messages['nonamewarning'] = 'Veuillez fournir un nom';
-$messages['nopagesizewarning'] = 'Veuillez indiquer une taille de page';
-$messages['nosenderwarning'] = 'Veuillez renseigner l\'adresse d\'expéditeur';
-$messages['norecipientwarning'] = 'Veuillez ajouter au moins un destinataire';
+$messages['formincomplete'] = 'Le formulaire n\'a pas été entièrement rempli.';
+$messages['noemailwarning'] = 'Veuillez spécifier un courriel valide.';
+$messages['nonamewarning'] = 'Veuillez fournir un nom.';
+$messages['nopagesizewarning'] = 'Veuillez indiquer une taille de page.';
+$messages['nosenderwarning'] = 'Veuillez renseigner l\'adresse d\'expéditeur.';
+$messages['norecipientwarning'] = 'Veuillez ajouter au moins un destinataire.';
$messages['nosubjectwarning'] = 'Le champ «Objet» est vide. Souhaitez-vous le renseigner maintenant ?';
$messages['nobodywarning'] = 'Envoyer ce message sans texte ?';
$messages['notsentwarning'] = 'Le message n\'a pas été envoyé. Voulez-vous abandonner ce message ?';
-$messages['noldapserver'] = 'Choisissez un serveur LDAP pour la recherche';
-$messages['nosearchname'] = 'Entrez un nom de contact ou un courriel';
-$messages['notuploadedwarning'] = 'Certaines pièces jointes sont en cours d\'expédition : attendez ou annulez l\'envoi.';
-$messages['searchsuccessful'] = '$nr messages trouvés';
+$messages['noldapserver'] = 'Choisissez un serveur LDAP pour la recherche.';
+$messages['nosearchname'] = 'Entrez un nom de contact ou un courriel.';
+$messages['notuploadedwarning'] = 'Toutes les pièces jointes n\'ont pas encore été transférées. Veuillez patienter ou annuler cette opération.';
+$messages['searchsuccessful'] = '$nr message(s) trouvé(s).';
$messages['contactsearchsuccessful'] = '$nr contact(s) trouvé(s).';
-$messages['searchnomatch'] = 'La recherche ne donne aucun résultat';
-$messages['searching'] = 'En cours de recherche...';
-$messages['checking'] = 'Vérification...';
-$messages['nospellerrors'] = 'Aucune faute trouvée';
-$messages['folderdeleted'] = 'Dossier effacé';
-$messages['foldersubscribed'] = 'Le dossier a bien été inscrit';
-$messages['folderunsubscribed'] = 'Le dossier a bien été désinscrit';
-$messages['folderpurged'] = 'Le dossier a bien été vidé';
-$messages['folderexpunged'] = 'Le dossier a bien été compacté';
-$messages['deletedsuccessfully'] = 'Supprimé(s) avec succès';
+$messages['searchnomatch'] = 'La recherche n\'a donné aucun résultat.';
+$messages['searching'] = 'Recherche en cours...';
+$messages['checking'] = 'Vérification en cours...';
+$messages['nospellerrors'] = 'Aucune faute d\'orthographe trouvée.';
+$messages['folderdeleted'] = 'Le dossier a bien été effacé.';
+$messages['foldersubscribed'] = 'Le dossier a bien été inscrit.';
+$messages['folderunsubscribed'] = 'Le dossier a bien été désinscrit.';
+$messages['folderpurged'] = 'Le dossier a bien été vidé.';
+$messages['folderexpunged'] = 'Le dossier a bien été compacté.';
+$messages['deletedsuccessfully'] = 'Correctement supprimé(s).';
$messages['converting'] = 'Suppression de la mise en forme...';
-$messages['messageopenerror'] = 'Impossible de charger le message depuis serveur';
+$messages['messageopenerror'] = 'Impossible de charger le message depuis serveur.';
$messages['fileuploaderror'] = 'Transfert du fichier échoué';
-$messages['filesizeerror'] = 'Le fichier transféré dépasse la taille maximale de $size';
-$messages['copysuccess'] = 'Succès de la copie des $nr adresses';
-$messages['copyerror'] = 'Ne peut pas copier les adresses';
-$messages['sourceisreadonly'] = 'Cette source d\'adresse est en lecture seule';
-$messages['errorsavingcontact'] = 'Ne peut pas enregistrer l\'adresse du contact';
-$messages['movingmessage'] = 'Déplacement du message...';
-$messages['copyingmessage'] = 'Copie du message ...';
-$messages['copyingcontact'] = 'Copie des contacts ...';
-$messages['deletingmessage'] = 'Suppression des messages...';
-$messages['markingmessage'] = 'Marquage des messages...';
-$messages['addingmember'] = 'Ajout des contacts dans le groupe ...';
-$messages['removingmember'] = 'Suppression des contacts du groupe ...';
-$messages['receiptsent'] = 'L\'accusé de réception a bien été envoyé';
-$messages['errorsendingreceipt'] = 'L\'accusé de réception n\'a pas pu être envoyé';
-$messages['deleteidentityconfirm'] = 'Voulez vous vraiment supprimer cette identités ?';
+$messages['filesizeerror'] = 'Le fichier transféré dépasse la taille maximale de $size.';
+$messages['copysuccess'] = 'Les $nr adresses ont bien été copiées.';
+$messages['copyerror'] = 'Impossible de copier des adresses.';
+$messages['sourceisreadonly'] = 'Cette source d\'adresse est en lecture seule.';
+$messages['errorsavingcontact'] = 'Impossible de sauvegarder l\'adresse du contact.';
+$messages['movingmessage'] = 'Message(s) en cours de déplacement...';
+$messages['copyingmessage'] = 'Message(s) en cours de copie...';
+$messages['copyingcontact'] = 'Contact(s) en cours de copie...';
+$messages['deletingmessage'] = 'Message(s) en cours de suppression...';
+$messages['markingmessage'] = 'Message(s) en cours de marquage...';
+$messages['addingmember'] = 'Contact(s) en cours d\'ajout dans le groupe...';
+$messages['removingmember'] = 'Contact(s) en cours de suppression du groupe...';
+$messages['receiptsent'] = 'L\'accusé de réception a bien été envoyé.';
+$messages['errorsendingreceipt'] = 'Impossible d\'envoyer l\'accusé de réception.';
+$messages['deleteidentityconfirm'] = 'Voulez vous vraiment supprimer cette identité ?';
$messages['nodeletelastidentity'] = 'Vous ne pouvez pas effacer votre seule identité.';
-$messages['forbiddencharacter'] = 'Le nom du dossier contient un caractère interdit';
-$messages['selectimportfile'] = 'Veuillez sélectionner un fichier à envoyer';
-$messages['addresswriterror'] = 'Impossible d\'écrire dans le carnet d\'adresse sélectionné';
-$messages['contactaddedtogroup'] = 'Les contacts ont bien été ajoutés à ce groupe';
-$messages['contactremovedfromgroup'] = 'Les contacts ont bien été supprimés de ce groupe';
+$messages['forbiddencharacter'] = 'Le nom du dossier contient un caractère interdit.';
+$messages['selectimportfile'] = 'Veuillez sélectionner un fichier à transférer.';
+$messages['addresswriterror'] = 'Impossible d\'écrire dans le carnet d\'adresse sélectionné.';
+$messages['contactaddedtogroup'] = 'Les contacts ont bien été ajoutés à ce groupe.';
+$messages['contactremovedfromgroup'] = 'Les contacts ont bien été supprimés de ce groupe.';
$messages['nogroupassignmentschanged'] = 'Appartenance aux groupes inchangée.';
-$messages['importwait'] = 'Importation, veuillez patienter...';
-$messages['importformaterror'] = 'Echec de l\'import ! Le fichier n\'est pas un fichier d\'import de données valide.';
-$messages['importconfirm'] = '<b>$inserted contacts importés avec succès, $skipped entrées existantes ignorées</b>:<p><em>$names</em></p>';
+$messages['importwait'] = 'Import en cours, veuillez patienter...';
+$messages['importformaterror'] = 'L\'import a échoué ! Le fichier transféré n\'est pas un fichier d\'import de données valide.';
+$messages['importconfirm'] = '<b>Les $inserted contacts ont bien été importés</b>';
$messages['importconfirmskipped'] = '<b>$skipped entrée(s) déjà existante(s)</b>';
$messages['opnotpermitted'] = 'Cette opération n\'est pas permise !';
-$messages['nofromaddress'] = 'Il manque une adresse e-mail dans l\'identité sélectionnée';
-$messages['editorwarning'] = 'Passer à l\'éditeur texte seul causera la perte du formatage du texte. Voulez-vous continuer ?';
+$messages['nofromaddress'] = 'Courriel manquant dans l\'identité sélectionnée.';
+$messages['editorwarning'] = 'Passer à l\'éditeur de texte brut causera la perte du formatage du texte. Souhaitez-vous continuer ?';
$messages['httpreceivedencrypterror'] = 'Une erreur fatale de configuration est survenue. Veuillez contacter votre administrateur immédiatement. <b>Votre message n\'a pas pu être envoyé.</b>';
-$messages['smtpconnerror'] = 'Erreur SMTP ($code): Echec de la connexion au serveur';
-$messages['smtpautherror'] = 'Erreur SMTP ($code): Echec de l\'authentification';
-$messages['smtpfromerror'] = 'Erreur SMTP ($code): Impossible de définir l\'expéditeur "$from" ($msg)';
-$messages['smtptoerror'] = 'Erreur SMTP ($code): Impossible d\'ajouter le destinataire "$to" ($msg)';
-$messages['smtprecipientserror'] = 'Erreur SMTP: Impossible de lire la liste des destinataires';
-$messages['smtperror'] = 'Erreur SMTP: $msg';
-$messages['emailformaterror'] = 'Adresse email incorrecte: $email';
+$messages['smtpconnerror'] = 'Erreur SMTP ($code) : Échec de la connexion au serveur.';
+$messages['smtpautherror'] = 'Erreur SMTP ($code) : Échec de l\'authentification.';
+$messages['smtpfromerror'] = 'Erreur SMTP ($code) : Impossible de définir l\'expéditeur "$from" ($msg)';
+$messages['smtptoerror'] = 'Erreur SMTP ($code) : Impossible d\'ajouter le destinataire "$to" ($msg)';
+$messages['smtprecipientserror'] = 'Erreur SMTP : Impossible de lire la liste des destinataires.';
+$messages['smtperror'] = 'Erreur SMTP : $msg';
+$messages['emailformaterror'] = 'Courriel incorrect : $email';
$messages['toomanyrecipients'] = 'Trop de destinataires. Réduisez leur nombre à $max maximum.';
$messages['maxgroupmembersreached'] = 'Le nombre de membres du groupe dépasse le maximum de $max.';
-$messages['internalerror'] = 'Une erreur interne est survenue. Merci de réessayer';
-$messages['contactdelerror'] = 'Les contacts n\'ont pas pu être supprimés';
-$messages['contactdeleted'] = 'Les contacts ont bien été supprimés';
-$messages['contactrestoreerror'] = 'Impossible de restaurer les contacts supprimés.';
-$messages['contactrestored'] = 'Les contacts ont bien été restaurés.';
-$messages['groupdeleted'] = 'Le groupe a bien été supprimé';
-$messages['grouprenamed'] = 'Le groupe a bien été renommé';
-$messages['groupcreated'] = 'Le groupe a bien été créé';
+$messages['internalerror'] = 'Une erreur interne est survenue. Veuillez réessayer.';
+$messages['contactdelerror'] = 'Impossible de supprimer le(s) contact(s).';
+$messages['contactdeleted'] = 'Contact(s) correctement supprimé(s).';
+$messages['contactrestoreerror'] = 'Impossible de restaurer le(s) contact(s) supprimé(s).';
+$messages['contactrestored'] = 'Contact(s) correctement restauré(s).';
+$messages['groupdeleted'] = 'Le groupe a bien été supprimé.';
+$messages['grouprenamed'] = 'Le groupe a bien été renommé.';
+$messages['groupcreated'] = 'Le groupe a bien été créé.';
$messages['savedsearchdeleted'] = 'La recherche enregistrée a bien été supprimée.';
$messages['savedsearchdeleteerror'] = 'Impossible de supprimer la recherche enregistrée.';
-$messages['savedsearchcreated'] = 'La recherche enregistrée a bien été crée.';
+$messages['savedsearchcreated'] = 'La recherche enregistrée a bien été créée.';
$messages['savedsearchcreateerror'] = 'Impossible de créer la recherche enregistrée.';
-$messages['messagedeleted'] = 'Les messages ont bien été supprimés';
-$messages['messagemoved'] = 'Les messages ont bien été déplacés';
-$messages['messagecopied'] = 'Les messages ont bien été copiés';
-$messages['messagemarked'] = 'Les messages ont bien été marqués';
-$messages['autocompletechars'] = 'Entrez au moins $min caractères pour l\'auto-complétion';
-$messages['autocompletemore'] = 'Plusieurs entrées trouvées. Tapez plus de caractères.';
-$messages['namecannotbeempty'] = 'Le nom ne peut pas être vide';
-$messages['nametoolong'] = 'Le nom est trop long';
-$messages['folderupdated'] = 'Le dossier a bien été mis à jour';
-$messages['foldercreated'] = 'Le dossier a bien été créé';
-$messages['invalidimageformat'] = 'Format d\'image invalide';
+$messages['messagedeleted'] = 'Message(s) correctement supprimé(s).';
+$messages['messagemoved'] = 'Message(s) correctement déplacé(s).';
+$messages['messagecopied'] = 'Message(s) correctement copié(s).';
+$messages['messagemarked'] = 'Message(s) correctement marqué(s).';
+$messages['autocompletechars'] = 'Entrez au moins $min caractères pour l\'auto-complétion.';
+$messages['autocompletemore'] = 'Plusieurs entrées trouvées. Veuillez taper plus de caractères.';
+$messages['namecannotbeempty'] = 'Le nom ne peut pas être vide.';
+$messages['nametoolong'] = 'Le nom est trop long.';
+$messages['folderupdated'] = 'Le dossier a bien été mis à jour.';
+$messages['foldercreated'] = 'Le dossier a bien été créé.';
+$messages['invalidimageformat'] = 'Format d\'image invalide.';
$messages['mispellingsfound'] = 'Des fautes d\'orthographe ont été détectées dans le message.';
$messages['parentnotwritable'] = 'Impossible de créer/déplacer le dossier dans le dossier parent sélectionné. Aucun droit d\'accès.';
$messages['messagetoobig'] = 'Le message est trop gros pour être traité.';
diff --git a/program/localization/fy_NL/labels.inc b/program/localization/fy_NL/labels.inc
index 5ffd906eb..891371f58 100644
--- a/program/localization/fy_NL/labels.inc
+++ b/program/localization/fy_NL/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Konsepten';
$labels['sent'] = 'Stjoerd';
$labels['trash'] = 'Jiskefet';
$labels['junk'] = 'Junk';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Ûnderwerp';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/fy_NL/messages.inc b/program/localization/fy_NL/messages.inc
index 16f4c67bf..1dacf4adc 100644
--- a/program/localization/fy_NL/messages.inc
+++ b/program/localization/fy_NL/messages.inc
@@ -2,172 +2,15 @@
/*
+-----------------------------------------------------------------------+
- | localization/<lang>/messages.inc |
+ | localization/fy_NL/messages.inc |
| |
- | Localization file of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, 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. |
+ | Language file of the Roundcube Webmail client |
+ | Copyright (C) 2012, The Roundcube Dev Team |
+ | Licensed under the GNU General Public License |
| |
+-----------------------------------------------------------------------+
-
- For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/messages/
+ | Author: unknown |
+ +-----------------------------------------------------------------------+
*/
-$messages = array();
-$messages['errortitle'] = 'An error occurred!';
-$messages['loginfailed'] = 'Login failed.';
-$messages['cookiesdisabled'] = 'Your browser does not accept cookies.';
-$messages['sessionerror'] = 'Your session is invalid or expired.';
-$messages['storageerror'] = 'Connection to storage server failed.';
-$messages['servererror'] = 'Server Error!';
-$messages['servererrormsg'] = 'Server Error: $msg';
-$messages['dberror'] = 'Database Error!';
-$messages['requesttimedout'] = 'Request timed out';
-$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
-$messages['errornoperm'] = 'Unable to perform operation. Permission denied.';
-$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
-$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
-$messages['invalidrequest'] = 'Invalid request! No data was saved.';
-$messages['invalidhost'] = 'Invalid server name.';
-$messages['nomessagesfound'] = 'No messages found in this mailbox.';
-$messages['loggedout'] = 'You have successfully terminated the session. Good bye!';
-$messages['mailboxempty'] = 'Mailbox is empty.';
-$messages['refreshing'] = 'Refreshing...';
-$messages['loading'] = 'Loading...';
-$messages['uploading'] = 'Uploading file...';
-$messages['uploadingmany'] = 'Uploading files...';
-$messages['loadingdata'] = 'Loading data...';
-$messages['checkingmail'] = 'Checking for new messages...';
-$messages['sendingmessage'] = 'Sending message...';
-$messages['messagesent'] = 'Message sent successfully.';
-$messages['savingmessage'] = 'Saving message...';
-$messages['messagesaved'] = 'Message saved to Drafts.';
-$messages['successfullysaved'] = 'Successfully saved.';
-$messages['addedsuccessfully'] = 'Contact added successfully to address book.';
-$messages['contactexists'] = 'A contact with the same e-mail address already exists.';
-$messages['contactnameexists'] = 'A contact with the same name already exists.';
-$messages['blockedimages'] = 'To protect your privacy, remote images are blocked in this message.';
-$messages['encryptedmessage'] = 'This is an encrypted message and can not be displayed. Sorry!';
-$messages['nocontactsfound'] = 'No contacts found.';
-$messages['contactnotfound'] = 'The requested contact was not found.';
-$messages['contactsearchonly'] = 'Enter some search terms to find contacts';
-$messages['sendingfailed'] = 'Failed to send message.';
-$messages['senttooquickly'] = 'Please wait $sec sec(s). before sending this message.';
-$messages['errorsavingsent'] = 'An error occured while saving sent message.';
-$messages['errorsaving'] = 'An error occured while saving.';
-$messages['errormoving'] = 'Could not move the message(s).';
-$messages['errorcopying'] = 'Could not copy the message(s).';
-$messages['errordeleting'] = 'Could not delete the message(s).';
-$messages['errormarking'] = 'Could not mark the message(s).';
-$messages['deletecontactconfirm'] = 'Do you really want to delete selected contact(s)?';
-$messages['deletegroupconfirm'] = 'Do you really want to delete selected group?';
-$messages['deletemessagesconfirm'] = 'Do you really want to delete selected message(s)?';
-$messages['deletefolderconfirm'] = 'Do you really want to delete this folder?';
-$messages['purgefolderconfirm'] = 'Do you really want to delete all messages in this folder?';
-$messages['contactdeleting'] = 'Deleting contact(s)...';
-$messages['groupdeleting'] = 'Deleting group...';
-$messages['folderdeleting'] = 'Deleting folder...';
-$messages['foldermoving'] = 'Moving folder...';
-$messages['foldersubscribing'] = 'Subscribing folder...';
-$messages['folderunsubscribing'] = 'Unsubscribing folder...';
-$messages['formincomplete'] = 'The form was not completely filled out.';
-$messages['noemailwarning'] = 'Please enter a valid email address.';
-$messages['nonamewarning'] = 'Please enter a name.';
-$messages['nopagesizewarning'] = 'Please enter a page size.';
-$messages['nosenderwarning'] = 'Please enter sender e-mail address.';
-$messages['norecipientwarning'] = 'Please enter at least one recipient.';
-$messages['nosubjectwarning'] = 'The "Subject" field is empty. Would you like to enter one now?';
-$messages['nobodywarning'] = 'Send this message without text?';
-$messages['notsentwarning'] = 'Message has not been sent. Do you want to discard your message?';
-$messages['noldapserver'] = 'Please select an ldap server to search.';
-$messages['nosearchname'] = 'Please enter a contact name or email address.';
-$messages['notuploadedwarning'] = 'Not all attachments have been uploaded yet. Please wait or cancel the upload.';
-$messages['searchsuccessful'] = '$nr messages found.';
-$messages['contactsearchsuccessful'] = '$nr contacts found.';
-$messages['searchnomatch'] = 'Search returned no matches.';
-$messages['searching'] = 'Searching...';
-$messages['checking'] = 'Checking...';
-$messages['nospellerrors'] = 'No spelling errors found.';
-$messages['folderdeleted'] = 'Folder successfully deleted.';
-$messages['foldersubscribed'] = 'Folder successfully subscribed.';
-$messages['folderunsubscribed'] = 'Folder successfully unsubscribed.';
-$messages['folderpurged'] = 'Folder has successfully been emptied.';
-$messages['folderexpunged'] = 'Folder has successfully been compacted.';
-$messages['deletedsuccessfully'] = 'Successfully deleted.';
-$messages['converting'] = 'Removing formatting...';
-$messages['messageopenerror'] = 'Could not load message from server.';
-$messages['fileuploaderror'] = 'File upload failed.';
-$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr addresses.';
-$messages['copyerror'] = 'Could not copy any addresses.';
-$messages['sourceisreadonly'] = 'This address source is read only.';
-$messages['errorsavingcontact'] = 'Could not save the contact address.';
-$messages['movingmessage'] = 'Moving message(s)...';
-$messages['copyingmessage'] = 'Copying message(s)...';
-$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['deletingmessage'] = 'Deleting message(s)...';
-$messages['markingmessage'] = 'Marking message(s)...';
-$messages['addingmember'] = 'Adding contact(s) to the group...';
-$messages['removingmember'] = 'Removing contact(s) from the group...';
-$messages['receiptsent'] = 'Successfully sent a read receipt.';
-$messages['errorsendingreceipt'] = 'Could not send the receipt.';
-$messages['deleteidentityconfirm'] = 'Do you really want to delete this identity?';
-$messages['nodeletelastidentity'] = 'You cannot delete this identity, it\'s your last one.';
-$messages['forbiddencharacter'] = 'Folder name contains a forbidden character.';
-$messages['selectimportfile'] = 'Please select a file to upload.';
-$messages['addresswriterror'] = 'The selected address book is not writeable.';
-$messages['contactaddedtogroup'] = 'Successfully added the contacts to this group.';
-$messages['contactremovedfromgroup'] = 'Successfully removed contacts from this group.';
-$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
-$messages['importwait'] = 'Importing, please wait...';
-$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
-$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
-$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
-$messages['opnotpermitted'] = 'Operation not permitted!';
-$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
-$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
-$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>';
-$messages['smtpconnerror'] = 'SMTP Error ($code): Connection to server failed.';
-$messages['smtpautherror'] = 'SMTP Error ($code): Authentication failed.';
-$messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from" ($msg).';
-$messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to" ($msg).';
-$messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list.';
-$messages['smtperror'] = 'SMTP Error: $msg';
-$messages['emailformaterror'] = 'Invalid e-mail address: $email';
-$messages['toomanyrecipients'] = 'Too many recipients. Reduce the number of recipients to $max.';
-$messages['maxgroupmembersreached'] = 'The number of group members exceeds the maximum of $max.';
-$messages['internalerror'] = 'An internal error occured. Please try again.';
-$messages['contactdelerror'] = 'Could not delete contact(s).';
-$messages['contactdeleted'] = 'Contact(s) deleted successfully.';
-$messages['contactrestoreerror'] = 'Could not restore deleted contact(s).';
-$messages['contactrestored'] = 'Contact(s) restored successfully.';
-$messages['groupdeleted'] = 'Group deleted successfully.';
-$messages['grouprenamed'] = 'Group renamed successfully.';
-$messages['groupcreated'] = 'Group created successfully.';
-$messages['savedsearchdeleted'] = 'Saved search deleted successfully.';
-$messages['savedsearchdeleteerror'] = 'Could not delete saved search.';
-$messages['savedsearchcreated'] = 'Saved search created successfully.';
-$messages['savedsearchcreateerror'] = 'Could not create saved search.';
-$messages['messagedeleted'] = 'Message(s) deleted successfully.';
-$messages['messagemoved'] = 'Message(s) moved successfully.';
-$messages['messagecopied'] = 'Message(s) copied successfully.';
-$messages['messagemarked'] = 'Message(s) marked successfully.';
-$messages['autocompletechars'] = 'Enter at least $min characters for autocompletion.';
-$messages['autocompletemore'] = 'More matching entries found. Please type more characters.';
-$messages['namecannotbeempty'] = 'Name cannot be empty.';
-$messages['nametoolong'] = 'Name is too long.';
-$messages['folderupdated'] = 'Folder updated successfully.';
-$messages['foldercreated'] = 'Folder created successfully.';
-$messages['invalidimageformat'] = 'Not a valid image format.';
-$messages['mispellingsfound'] = 'Spelling errors detected in the message.';
-$messages['parentnotwritable'] = 'Unable to create/move folder into selected parent folder. No access rights.';
-$messages['messagetoobig'] = 'The message part is too big to process it.';
-$messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.<br/><br/><em>Expected: $expected; found: $detected</em>';
-$messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.';
-
-?>
+$messages = array(); \ No newline at end of file
diff --git a/program/localization/ga_IE/labels.inc b/program/localization/ga_IE/labels.inc
index 9fffaf42a..9f0da6550 100755..100644
--- a/program/localization/ga_IE/labels.inc
+++ b/program/localization/ga_IE/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Dréachtaí';
$labels['sent'] = 'Amach';
$labels['trash'] = 'Bosca bruscair';
$labels['junk'] = 'Dramhaíl';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Ãbhair';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Comhbhrúigh';
$labels['empty'] = 'Folmhaigh';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Toilleadh diosca atá athláimhe';
$labels['unknown'] = 'gan aithne';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Athshocraigh an cuardach';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Taispeáin an foireann deireanach';
$labels['group'] = 'Group';
$labels['groups'] = 'Grúpaí';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Seoltaí Pearsanta';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ga_IE/messages.inc b/program/localization/ga_IE/messages.inc
index b837c9d16..70aa28a36 100755..100644
--- a/program/localization/ga_IE/messages.inc
+++ b/program/localization/ga_IE/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Scrios mé formáidithe as an teachtaireacht seo';
$messages['messageopenerror'] = 'Theip orm chun an teachtaireacht seo a tarrtháil as an freastalaí';
$messages['fileuploaderror'] = 'Theip an suas-luchtú';
$messages['filesizeerror'] = 'Beigh an comhad ró-mhor. Is ea $size uas-saghas chun admháil léite';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'D\'éirigh mé agus chuir mé $nr seolagh i do Leabhair Seoltaí';
+$messages['copyerror'] = 'Theip mé agus níor dfhag mé aon seolagh';
$messages['sourceisreadonly'] = 'Tá an foinse seolaigh seo inléite amháin';
$messages['errorsavingcontact'] = 'Theip mé, Níl an cumas agam an seolagh seo a sábháil';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/gl_ES/labels.inc b/program/localization/gl_ES/labels.inc
index c624c462e..5905ea4b9 100644
--- a/program/localization/gl_ES/labels.inc
+++ b/program/localization/gl_ES/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Cubo do lixo';
$labels['junk'] = 'Correo lixo';
-$labels['show_real_foldernames'] = 'Amosar nomes reáis para cartafois especiáis';
// message listing
$labels['subject'] = 'Asunto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Modo de vista da lista';
$labels['folderactions'] = 'Accións cos cartafoles';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Baleirar';
-$labels['importmessages'] = 'Importar mensaxes';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'descoñecido';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Restablecer a busca';
$labels['searchmod'] = 'Modificadores de busca';
$labels['msgtext'] = 'Mensaxe enteira';
$labels['body'] = 'Corpo';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir nunha nova fiestra';
$labels['emlsave'] = 'Gardar (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Amosar o último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Enderezos persoais';
$labels['searchsave'] = 'Gardar procura';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'Redactar mensaxes HTML';
$labels['htmlonreply'] = 'só cando se resposte a unha mensaxe HTML';
$labels['htmlonreplyandforward'] = 'ao reenviar ou respostar a unha mensaxe HTML';
$labels['htmlsignature'] = 'Sinatura HTML';
-$labels['showemail'] = 'Amosar enderezo de correo co nome en pantalla';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Amosar previsualización';
$labels['skin'] = 'Aspecto da interface';
$labels['logoutclear'] = 'Baleirar o cubo do lixo ao saír';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorar as palabras con números';
$labels['spellcheckignorecaps'] = 'Ignorar as palabras escritas en maiúsculas';
$labels['addtodict'] = 'Engadir ao diccionario';
$labels['mailtoprotohandler'] = 'Rexistrar o manexador de protocolo para as ligazóns "mailto:"';
-$labels['standardwindows'] = 'Manexar avisos emerxentes como xanelas estándar';
$labels['forwardmode'] = 'Reenvio de mensaxes';
$labels['inline'] = 'inserido';
$labels['asattachment'] = 'coma anexo';
diff --git a/program/localization/gl_ES/messages.inc b/program/localization/gl_ES/messages.inc
index 8fc2cb424..207a016a1 100644
--- a/program/localization/gl_ES/messages.inc
+++ b/program/localization/gl_ES/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'A importar. Por favor, agarde...';
$messages['importformaterror'] = 'Fallou a importación! O ficheiro cargado non contén datos válidos.';
$messages['importconfirm'] = '<b>Importáronse correctamente $inserted contactos. Ignoráronse $skipped contactos que xa existían</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Ignoráronse $skipped existing entradas</b>';
-$messages['importmessagesuccess'] = 'Importados $nr mensaxes con éxito';
-$messages['importmessageerror'] = 'Fallou a importación! O arquivo subido non é unha mensaxe válida ou un ficheiro de caixa de correo';
$messages['opnotpermitted'] = 'Operación non permitida!';
$messages['nofromaddress'] = 'Falta o enderezo de correo electrónico na identidade que escolleu.';
$messages['editorwarning'] = 'Se troca neste intre ao editor de texto plano, vai perder todo o formato do texto. Quere continuar?';
diff --git a/program/localization/he_IL/labels.inc b/program/localization/he_IL/labels.inc
index 7ad04ab4a..bfb9e2fef 100644
--- a/program/localization/he_IL/labels.inc
+++ b/program/localization/he_IL/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'טיוטות';
$labels['sent'] = 'נשלח';
$labels['trash'] = '×שפה';
$labels['junk'] = 'זבל';
-$labels['show_real_foldernames'] = 'הצגת שמות ××ž×™×ª×™×™× ×©×œ תיקיות מיוחדות';
// message listing
$labels['subject'] = 'נוש×';
@@ -194,7 +193,6 @@ $labels['listmode'] = '×ופן הצגת רשימה';
$labels['folderactions'] = 'פעולות על תיקי×';
$labels['compact'] = 'פינוי שטח ×œ× ×ž× ×•×¦×œ';
$labels['empty'] = 'ריקון';
-$labels['importmessages'] = '×™×™×‘×•× ×”×•×“×¢×•×ª';
$labels['quota'] = 'ניצול קיבולת';
$labels['unknown'] = '×œ× ×™×“×•×¢';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'ניקוי תיבת החיפוש';
$labels['searchmod'] = 'מ×פייני חיפוש';
$labels['msgtext'] = 'כל ההודעה';
$labels['body'] = 'גוף ההודעה';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'פתיחה בחלון חדש';
$labels['emlsave'] = 'הורדת הודעה בפורמט EML';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'הצגת הקבוצה ×”×חרונה';
$labels['group'] = 'קבוצה';
$labels['groups'] = 'קבוצות';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'כתובות פרטיות';
$labels['searchsave'] = 'שמירת החיפוש';
@@ -478,7 +474,6 @@ $labels['spellcheckignorenums'] = 'התעלמות ×ž×ž×™×œ×™× ×”×ž×›×™×œ×•×ª מ
$labels['spellcheckignorecaps'] = 'התעלמות ×ž×ž×™×œ×™× ×¢× ×ותציות ר×שיות';
$labels['addtodict'] = 'הוספה למילון';
$labels['mailtoprotohandler'] = 'קביעת הפרוטוקול לטיפול בקישור מסוג mailto:links';
-$labels['standardwindows'] = 'חלונות ×§×•×¤×¦×™× ×™×˜×•×¤×œ×• כחלונות רגילי×';
$labels['forwardmode'] = 'הפנית הודעות';
$labels['inline'] = 'חלק מההודעה';
$labels['asattachment'] = 'כצרופה';
diff --git a/program/localization/he_IL/messages.inc b/program/localization/he_IL/messages.inc
index 37ebcea01..7d9b87c06 100644
--- a/program/localization/he_IL/messages.inc
+++ b/program/localization/he_IL/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'ייבו×, × × ×œ×”×ž×ª×™×Ÿ..';
$messages['importformaterror'] = '×”×™×‘×•× × ×›×©×œ ! הקובץ שהועלה ×ינו מת××™×.';
$messages['importconfirm'] = '<b>יוב×ו $inserted ×נשי קשר, $skipped היו ×§×™×™×ž×™× </b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b> דילוג של $skipped × ×ª×•× ×™× ×§×™×™×ž×™× <b>';
-$messages['importmessagesuccess'] = 'יוב×ו בהצלחה $nr הודעות ';
-$messages['importmessageerror'] = '×”×™×‘×•× × ×›×©×œ ! הקובץ שהועלה ×ינו הודעה ×ו קובץ הודעות במבנה מת××™×';
$messages['opnotpermitted'] = 'פעולה ×סורה!';
$messages['nofromaddress'] = 'לזהות שנבחרה חסרה כתובת דו×ר';
$messages['editorwarning'] = 'המעבר לעורך רגיל ×™×’×¨×•× ×œ×יבוד ×ת העריכה הקיימת. ×”×× ×œ×”×ž×©×™×š?';
diff --git a/program/localization/hi_IN/labels.inc b/program/localization/hi_IN/labels.inc
index 303e0b5fb..3b8279f71 100644
--- a/program/localization/hi_IN/labels.inc
+++ b/program/localization/hi_IN/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'डà¥à¤°à¤¾à¤«à¤¼à¤Ÿ';
$labels['sent'] = 'भेजा गया';
$labels['trash'] = 'रदà¥à¤¦à¥€';
$labels['junk'] = 'सà¥à¤ªà¥ˆà¤®';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विशय';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'छोटा करें';
$labels['empty'] = 'मेल रदà¥à¤¦à¥€ में डालें';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤• उपयोग';
$labels['unknown'] = 'अजà¥à¤žà¤¾à¤¤';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'खोज खाली करें';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'आखिरी बनà¥à¤¡à¤² दिखाà¤à¤‚'
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/hi_IN/messages.inc b/program/localization/hi_IN/messages.inc
index ffbc6f436..1d55f5c48 100644
--- a/program/localization/hi_IN/messages.inc
+++ b/program/localization/hi_IN/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'मेल से फ़ॉरà¥à¤®à¥ˆà¤Ÿà¤¿à¤‚ग à¤
$messages['messageopenerror'] = 'सरà¥à¤µà¤° से मेल लोड नहीं हो पाया';
$messages['fileuploaderror'] = 'फ़ाईल अपलोड नहीं हो पाया';
$messages['filesizeerror'] = 'अपलोड के लिये फ़ाईल हद $size से बड़ा है';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/hr_HR/labels.inc b/program/localization/hr_HR/labels.inc
index 4578fed2b..506d50f1f 100644
--- a/program/localization/hr_HR/labels.inc
+++ b/program/localization/hr_HR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Predlošci';
$labels['sent'] = 'Poslano';
$labels['trash'] = 'Smeće';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Naslov';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Model pregleda listi';
$labels['folderactions'] = 'Akcije mapa';
$labels['compact'] = 'Kompresiranje';
$labels['empty'] = 'Isprazni';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Kvota';
$labels['unknown'] = 'nepoznato';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Prikaži sve poruke';
$labels['searchmod'] = 'Postavke pretrage';
$labels['msgtext'] = 'Cijela poruka';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otvori u novom prozoru';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Zadnja strana';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupe';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Privatna adresa';
$labels['searchsave'] = 'Pohrani pretragu';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignoriraj rijeÄi koje sadrže brojeve';
$labels['spellcheckignorecaps'] = 'Ignoriraj rijeÄi sa sa svim velikim slovima';
$labels['addtodict'] = 'Dodaj u rjeÄnik';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/hr_HR/messages.inc b/program/localization/hr_HR/messages.inc
index 0b96c97f2..3e6cc6daf 100644
--- a/program/localization/hr_HR/messages.inc
+++ b/program/localization/hr_HR/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Formatiranje poruke';
$messages['messageopenerror'] = 'UÄitavanje poruke nije uspjelo';
$messages['fileuploaderror'] = 'Prijenos datoteke nije uspio';
$messages['filesizeerror'] = 'Datoteka je prevelika. Maksimalna veliÄina je $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Uspješno kopirano $n adresa';
+$messages['copyerror'] = 'Nije uspjelo kopiranje adresa';
$messages['sourceisreadonly'] = 'Ovaj resurs adresa je samo za Äitanje';
$messages['errorsavingcontact'] = 'Nije uspjelo spremanje adrese kontakta';
$messages['movingmessage'] = 'Premještanje poruke...';
$messages['copyingmessage'] = 'Kopiranje poruke...';
$messages['copyingcontact'] = 'Kopiram kontakt(e)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Brisanje poruke...';
$messages['markingmessage'] = 'OznaÄavanje poruke...';
$messages['addingmember'] = 'Dodajem kontakt(e) u grupu...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Uvozim, molimo saÄekajte...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>UspjeÅ¡no je uvezeno $inserted kontakt(a), preskoÄeno $skipped već postojećih</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>PreskoÄeno $skipped postojećih unosa</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operacija nije dozvoljena!';
$messages['nofromaddress'] = 'Nije upisana e-mail adresa u odabrani identitet';
$messages['editorwarning'] = 'Prebacivanje u Äisti tekstualni ureÄ‘ivaÄ Ä‡e prouzrokovati gubljenje formatiranje teksta. Želite li nastaviti?';
diff --git a/program/localization/hu_HU/labels.inc b/program/localization/hu_HU/labels.inc
index abdc7e891..3cc5da1aa 100644
--- a/program/localization/hu_HU/labels.inc
+++ b/program/localization/hu_HU/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Piszkozatok';
$labels['sent'] = 'Küldött levelek';
$labels['trash'] = 'Törölt elemek';
$labels['junk'] = 'Kéretlen levelek';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tárgy';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Megjelenítési mód';
$labels['folderactions'] = 'Mappaműveletek...';
$labels['compact'] = 'Tömörítés';
$labels['empty'] = 'Kiürítés';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Helyfoglalás';
$labels['unknown'] = 'ismeretlen';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Alapállapot';
$labels['searchmod'] = 'Keresési opciók';
$labels['msgtext'] = 'Teljes üzenet';
$labels['body'] = 'Törzs';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Megnyitás új ablakban';
$labels['emlsave'] = 'Letöltés (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Utolsó oldal';
$labels['group'] = 'Csoport';
$labels['groups'] = 'Csoportok';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Személyes címjegyzék';
$labels['searchsave'] = 'Keresés mentése';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Számot tartalmazó szavak kihagyása';
$labels['spellcheckignorecaps'] = 'Csak nagybetűt tartalmazó szavak kihagyása';
$labels['addtodict'] = 'Hozzáadás a szótárhoz';
$labels['mailtoprotohandler'] = 'Beállítás a mailto: linkek kezelőjeként';
-$labels['standardwindows'] = 'A felugró ablakok használata szokásos ablakként';
$labels['forwardmode'] = 'Üzenet továbbítás';
$labels['inline'] = 'beágyazott';
$labels['asattachment'] = 'csatolmányként';
diff --git a/program/localization/hu_HU/messages.inc b/program/localization/hu_HU/messages.inc
index d54589f42..6528602a4 100644
--- a/program/localization/hu_HU/messages.inc
+++ b/program/localization/hu_HU/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Formázás eltávolítása az üzenetből...';
$messages['messageopenerror'] = 'A levelek a szerverről nem tölthetők le';
$messages['fileuploaderror'] = 'Feltöltés sikertelen';
$messages['filesizeerror'] = 'A feltöltött fájl mérete meghaladja a maximális $size méretet';
-$messages['copysuccess'] = 'Sikeresen átmásolva $nr kapcsolat.';
-$messages['movesuccess'] = 'Sikeresen átmozgatva $nr kapcsolat.';
-$messages['copyerror'] = 'Nem lehet másolni a kapcsolatokat.';
-$messages['moveerror'] = 'Nem lehet átmozgatni a kapcsolatokat.';
+$messages['copysuccess'] = '$nr cím sikeresen másolva';
+$messages['copyerror'] = 'Egyetlen cím sem másolható';
$messages['sourceisreadonly'] = 'Ez a címforrás csak olvasható';
$messages['errorsavingcontact'] = 'A kapcsolat címe nem menthető';
$messages['movingmessage'] = 'Üzenet(ek) mozgatása...';
$messages['copyingmessage'] = 'Üzenet(ek) másolása...';
$messages['copyingcontact'] = 'Kapcsolat(ok) másolása...';
-$messages['movingcontact'] = 'Kapcsolat(ok) átmozgatása ...';
$messages['deletingmessage'] = 'Üzenet(ek) törlése....';
$messages['markingmessage'] = 'Üzenet(ek) megjelölése...';
$messages['addingmember'] = 'Kapcsolat(ok) hozzáadása a csoporthoz...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importálás folyamatban, kérem várjon...';
$messages['importformaterror'] = 'Az importálás sikertelen! A feltöltött fájl ismeretlen formátumú.';
$messages['importconfirm'] = '<b>Sikeresen importálásra került $inserted kapcsolat, kihagyva $skipped már létező bejegyzés</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Kihagyva $skipped már létező bejegyzés</b>';
-$messages['importmessagesuccess'] = 'Sikeresen importálva $nr üzenet';
-$messages['importmessageerror'] = 'Sikertelen az importálás. A feltőltött file nem értelmezhető üzenetként vagy postafiók (mailbox) fileként.';
$messages['opnotpermitted'] = 'A művelet nem megengedett!';
$messages['nofromaddress'] = 'A kiválasztott azonosítónál nincs email beállítva.';
$messages['editorwarning'] = 'Az egyszerű szöveges formátumra való váltás az összes formázás elvesztésével jár. Biztosan folytatja?';
diff --git a/program/localization/hy_AM/labels.inc b/program/localization/hy_AM/labels.inc
index 8ee9316c4..99cee4ab9 100644
--- a/program/localization/hy_AM/labels.inc
+++ b/program/localization/hy_AM/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'ÕÖ‡Õ¡Õ£Ö€Õ¥Ö€';
$labels['sent'] = 'ÕˆÖ‚Õ²Õ¡Ö€Õ¯Õ¾Õ¡Õ®';
$labels['trash'] = 'Ô±Õ²Õ¢Õ¡Ö€Õ¯Õ²';
$labels['junk'] = 'Ô¹Õ¡ÖƒÕ¸Õ¶';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÕŽÕ¥Ö€Õ¶Õ¡Õ£Õ«Ö€';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¯Õ¸Õ¾ Õ¿Õ¥Õ½Ö„Õ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨';
$labels['folderactions'] = 'Պանակի գործողություններ…';
$labels['compact'] = 'ÕÕ¥Õ²Õ´Õ¥Õ¬';
$labels['empty'] = 'Ô´Õ¡Õ¿Õ¡Ö€Õ¯Õ¥Õ¬';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ô´Õ«Õ½Õ¯Õ¡ÕµÕ«Õ¶ Õ¿Õ¡Ö€Õ¡Õ®Ö„';
$labels['unknown'] = 'Õ¡Õ¶Õ°Õ¡ÕµÕ¿';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'ÕŽÕ¥Ö€Õ½Õ¯Õ½Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ¸Ö‚Õ´Õ¨';
$labels['searchmod'] = 'ÕˆÖ€Õ¸Õ¶Õ´Õ¡Õ¶ ÖƒÕ¸ÖƒÕ¸Õ­Õ«Õ¹Õ¶Õ¥Ö€';
$labels['msgtext'] = 'ÕˆÕ²Õ» Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ô²Õ¡ÖÕ¥Õ¬ Õ¶Õ¸Ö€ ÕºÕ¡Õ¿Õ¸Ö‚Õ°Õ¡Õ¶Õ¸Ö‚Õ´';
$labels['emlsave'] = 'Õ†Õ¥Ö€Õ¢Õ¥Õ¼Õ¶Õ¥Õ¬ (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»Õ¨';
$labels['group'] = 'Ô½Õ¸Ö‚Õ´Õ¢';
$labels['groups'] = 'Ô½Õ´Õ¢Õ¥Ö€';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Ô±Õ¶Õ±Õ¶Õ¡Õ¯Õ¡Õ¶ Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€';
$labels['searchsave'] = 'ÕŠÕ¡Õ°ÕºÕ¡Õ¶Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ¸Ö‚Õ´Õ¨';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ô±Õ¶Õ¿Õ¥Õ½Õ¥Õ¬ Õ©Õ¾Õ¥Ö€Õ¸Õ¾ Õ¢Õ¡Õ¼Õ¥Ö€Õ¨';
$labels['spellcheckignorecaps'] = 'Ô±Õ¶Õ¿Õ¥Õ½Õ¥Õ¬ Õ¬Ö€Õ«Õ¾ Õ´Õ¥Õ®Õ¡Õ¿Õ¡Õ¼ Õ¢Õ¡Õ¼Õ¥Ö€Õ¨';
$labels['addtodict'] = 'Ô±Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ¢Õ¡Õ¼Õ¡Ö€Õ¡Õ¶Õ¸Ö‚Õ´';
$labels['mailtoprotohandler'] = 'mailto: Õ°Õ²Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ« Õ½ÕºÕ¡Õ½Õ¡Ö€Õ¯Õ¸Õ²';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/hy_AM/messages.inc b/program/localization/hy_AM/messages.inc
index 2128a188c..6b3f4ebe9 100644
--- a/program/localization/hy_AM/messages.inc
+++ b/program/localization/hy_AM/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Õ†Õ¡Õ´Õ¡Õ¯Õ« Õ±Ö‡Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ Õ°Õ¥Õ¼Õ¡Öում…';
$messages['messageopenerror'] = 'Õ†Õ¡Õ´Õ¡Õ¯Õ« Õ¢Õ¥Õ¼Õ¶Õ¾Õ¸Ö‚Õ´Õ¨ Õ½Õ¥Ö€Õ¾Õ¥Ö€Õ«Ö Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥Ö';
$messages['fileuploaderror'] = 'Õ–Õ¡ÕµÕ¬Õ« Õ¯ÖÕ¸Ö‚Õ´Õ¶ Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥Ö';
$messages['filesizeerror'] = 'Õ–Õ¡ÕµÕ¬Õ« Õ¹Õ¡ÖƒÕ¨ Õ£Õ¥Ö€Õ¡Õ¦Õ¡Õ¶ÖÕ¸Ö‚Õ´ Õ§ Õ´Õ¡Ö„Õ½Õ«Õ´Õ¡Õ¬Õ¨Õ $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€Õ« Õ¯Ö€Õ¯Õ¶Ö…Ö€Õ«Õ¶Õ¡Õ¯Õ¸Ö‚Õ´Õ¨ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¡Õ® Õ§';
+$messages['copyerror'] = 'Õ€Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€Õ« Õ¯Ö€Õ¯Õ¶Ö…Ö€Õ«Õ¶Õ¡Õ¯Õ¸Ö‚Õ´Õ¨ Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥Ö';
$messages['sourceisreadonly'] = 'Ô±ÕµÕ½ Õ°Õ¡Õ½ÖÕ¥Õ¶ ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶Õ¾Õ¡Õ® Õ§';
$messages['errorsavingcontact'] = 'Õ€Õ¡Õ½ÖÕ¥Õ« Õ£Ö€Õ¡Õ¶ÖÕ¸Ö‚Õ´Õ¶ Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥Ö';
$messages['movingmessage'] = 'Նամակը տեղափոխվում է…';
$messages['copyingmessage'] = 'Հաղորդագրությունների պատճենում…';
$messages['copyingcontact'] = 'Ô±Õ¶Õ±Õ¡Õ¶Ö ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ¸Ö‚Õ´â€¦';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Հաղորդագրությունների ջնջում…';
$messages['markingmessage'] = 'Հաղորդագրությունների նշում…';
$messages['addingmember'] = 'Ô±Õ¶Õ±Õ¡Õ¶Ö Õ¡Õ¾Õ¥Õ¬Õ¡ÖÕ¸Ö‚Õ´ խմբին…';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Õ†Õ¥Ö€Õ¯Ö€Õ¸Ö‚Õ´Õ¶ Õ¨Õ¶Õ©Õ¡ÖÖ„Õ« Õ´Õ¥Õ» Õ§...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '$inserted Õ¶Õ¸Ö€ Õ¶Õ¥Ö€Õ¯Ö€Õ¾Õ¡Õ® Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€, $skipped Õ¡Ö€Õ¤Õ¥Õ¶ Õ¡Õ¼Õ¯Õ¡ Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€Õ <p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Ô²Õ¡Ö Õ©Õ¸Õ²Õ¶Õ¾Õ¥Ö $skipped Õ¡Õ¼Õ¯Õ¡ Õ£Ö€Õ¡Õ¼Õ¸Ö‚Õ´</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Ô³Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¡Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ§Ö‰';
$messages['nofromaddress'] = 'Õ†Õ·Õ¾Õ¡Õ® Õ¡Õ¶Õ±Õ¨ Õ°Õ¡Õ½ÖÕ¥ Õ¹Õ¸Ö‚Õ¶Õ«Ö‰';
$messages['editorwarning'] = 'Ô´Õ¥ÕºÕ« ÕºÕ¡Ö€Õ¦ Õ¿Õ¥Ö„Õ½Õ¿Õ« Õ­Õ´Õ¢Õ¡Õ£Ö€Õ«Õ¹ Õ¡Õ¶ÖÕ´Õ¡Õ¶ Õ¤Õ¥ÕºÖ„Õ¸Ö‚Õ´ Õ¯Õ¯Õ¸Ö€Õ« Õ¿Õ¥Ö„Õ½Õ¿Õ« Õ±Ö‡Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´Õ¨Ö‰ Õ‡Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥ÕžÕ¬Ö‰';
diff --git a/program/localization/ia/labels.inc b/program/localization/ia/labels.inc
index 1cd614d35..2a9501168 100644
--- a/program/localization/ia/labels.inc
+++ b/program/localization/ia/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Drafts';
$labels['sent'] = 'Inviate';
$labels['trash'] = 'Trash';
$labels['junk'] = 'Junk';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subjecto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Actiones de dossier...';
$labels['compact'] = 'Compacte';
$labels['empty'] = 'Vacue';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'incognite';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reinitialisar cerca';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Message complete';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Aperir in nove fenestra';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Gruppo';
$labels['groups'] = 'Gruppos';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adresses personal';
$labels['searchsave'] = 'Salveguardar cerca';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Adder al dictionario';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ia/messages.inc b/program/localization/ia/messages.inc
index d6fbba87d..ebc6953d2 100644
--- a/program/localization/ia/messages.inc
+++ b/program/localization/ia/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'Incargamento de file falleva.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/id_ID/labels.inc b/program/localization/id_ID/labels.inc
index a8d5f4c5b..eea3132cd 100644
--- a/program/localization/id_ID/labels.inc
+++ b/program/localization/id_ID/labels.inc
@@ -33,11 +33,10 @@ $labels['addressbook'] = 'Buku Alamat';
// mailbox names
$labels['inbox'] = 'Kotak Masuk';
-$labels['drafts'] = 'Konsep';
+$labels['drafts'] = 'Daftar tunggu';
$labels['sent'] = 'Terkirim';
$labels['trash'] = 'Surat Terhapus';
$labels['junk'] = 'Sampah';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Judul';
@@ -65,7 +64,7 @@ $labels['copy'] = 'Salin';
$labels['move'] = 'Pindahkan';
$labels['moveto'] = 'Pindahkan ke...';
$labels['download'] = 'Unduh';
-$labels['open'] = 'Buka';
+$labels['open'] = 'Open';
$labels['showattachment'] = 'Tampilkan';
$labels['showanyway'] = 'Tampilkan saja';
@@ -163,7 +162,7 @@ $labels['currpage'] = 'Halaman sekarang';
$labels['unread'] = 'Belum terbaca';
$labels['flagged'] = 'Ditandai';
$labels['unanswered'] = 'Belum terjawab';
-$labels['withattachment'] = 'Dengan lampiran';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Terhapus';
$labels['undeleted'] = 'Tidak terhapus';
$labels['invert'] = 'Sebaliknya';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Perlihatkan mode tinjauan';
$labels['folderactions'] = 'Tindakan pada folder...';
$labels['compact'] = 'Rampingkan';
$labels['empty'] = 'Kosong';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Penggunaan ruang';
$labels['unknown'] = 'Tidak dikenal';
@@ -205,13 +203,11 @@ $labels['resetsearch'] = 'Atur ulang pencarian';
$labels['searchmod'] = 'Peubah pencarian';
$labels['msgtext'] = 'Seluruh pesan';
$labels['body'] = 'Badan';
-$labels['type'] = 'Tipe';
-$labels['namex'] = 'Nama';
$labels['openinextwin'] = 'Buka dalam jendela baru';
$labels['emlsave'] = 'Unduh (.eml)';
-$labels['changeformattext'] = 'Tampilkan dalam format text biasa';
-$labels['changeformathtml'] = 'Tampilkan dalam format HTML';
+$labels['changeformattext'] = 'Display in plain text format';
+$labels['changeformathtml'] = 'Display in HTML format';
// message compose
$labels['editasnew'] = 'Sunting sebagai pesan baru';
@@ -358,7 +354,6 @@ $labels['lastpage'] = 'Perlihatkan himpunan terakhir';
$labels['group'] = 'Kelompok';
$labels['groups'] = 'Kelompok';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Alamat pribadi';
$labels['searchsave'] = 'Simpan pencarian';
@@ -430,7 +425,7 @@ $labels['showremoteimages'] = 'Tampilkan remote inline images';
$labels['fromknownsenders'] = 'dari pengirim yang dikenal';
$labels['always'] = 'selalu';
$labels['showinlineimages'] = 'Tampilkan gambar terlampir dibawah pesan';
-$labels['autosavedraft'] = 'Otomatis menyimpan konsep';
+$labels['autosavedraft'] = 'Otomatis menyimpan pesan tertunda';
$labels['everynminutes'] = 'setiap $n menit';
$labels['refreshinterval'] = 'Refresh (memeriksa pesan baru, dsb)';
$labels['never'] = 'tidak pernah';
@@ -477,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Abaikan kata-kata yang bernomor';
$labels['spellcheckignorecaps'] = 'Abaikan kata-kata dengan huruf besar semua';
$labels['addtodict'] = 'Tambahkan ke kamus';
$labels['mailtoprotohandler'] = 'Daftarkan pengampu protokol untuk link mailto:';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Meneruskan pesan';
$labels['inline'] = 'dalam surat';
$labels['asattachment'] = 'sebagai sisipan';
diff --git a/program/localization/id_ID/messages.inc b/program/localization/id_ID/messages.inc
index a81b2ab01..04d8242ad 100644
--- a/program/localization/id_ID/messages.inc
+++ b/program/localization/id_ID/messages.inc
@@ -44,7 +44,7 @@ $messages['checkingmail'] = 'Memeriksa pesan baru...';
$messages['sendingmessage'] = 'Mengirim pesan...';
$messages['messagesent'] = 'Pesan berhasil dikirim.';
$messages['savingmessage'] = 'Menyimpan pesan...';
-$messages['messagesaved'] = 'Pesan tersimpan kedalam Konsep';
+$messages['messagesaved'] = 'Menyimpan pesan ke daftar tunggu';
$messages['successfullysaved'] = 'Berhasil disimpan';
$messages['addedsuccessfully'] = 'Kontak berhasil ditambahkan ke buku alamat';
$messages['contactexists'] = 'Kontak dengan alamat e-mail ini sudah ada.';
@@ -101,16 +101,13 @@ $messages['converting'] = 'Mengembalikan pesan ke format awal...';
$messages['messageopenerror'] = 'Tidak dapat mengambil pesan dari server';
$messages['fileuploaderror'] = 'Gagal mengunggah berkas';
$messages['filesizeerror'] = 'Berkas terunggah mencapai ukuran maksimal dari $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Berhasil menyalin $nr alamat';
+$messages['copyerror'] = 'Tidak bisa menyalin alamat manapun';
$messages['sourceisreadonly'] = 'Sumber dari alamat ini hanya dapat dibaca';
$messages['errorsavingcontact'] = 'Tidak bisa menyimpan alamat kontak';
$messages['movingmessage'] = 'Memindahkan pesan...';
$messages['copyingmessage'] = 'Menyalin pesan...';
$messages['copyingcontact'] = 'Menyalin kontak...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Menghapus pesan...';
$messages['markingmessage'] = 'Menandai Pesan...';
$messages['addingmember'] = 'Menambahkan kontak ke grup...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Sedang mengimpor, harap menunggu...';
$messages['importformaterror'] = 'Proses import gagal. File yang di upload bukan file import yang valid.';
$messages['importconfirm'] = '<b>Berhasil mengimpor $inserted kontak</b>';
$messages['importconfirmskipped'] = '<b>$skipped entri yang sudah ada dilewatkan</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operasi tidak diperbolehkan!';
$messages['nofromaddress'] = 'kekurangan alamat e-mail pada identitas terpilih';
$messages['editorwarning'] = 'Beralih pada editor teks murni akan mengakibatkan semua pemformatan teks hilang. Lanjutkan?';
diff --git a/program/localization/index.inc b/program/localization/index.inc
index 4b848dc49..bfb770cac 100644
--- a/program/localization/index.inc
+++ b/program/localization/index.inc
@@ -70,7 +70,6 @@ $rcube_languages = array(
'ku' => 'Kurdish (Kurmancî)',
'lv_LV' => 'Latvian (Latviešu)',
'lt_LT' => 'Lithuanian (Lietuviškai)',
- 'lb_LU' => 'Luxembourgish (Lëtzebuergesch)',
'mk_MK' => 'Macedonian (МакедонÑки)',
'ms_MY' => 'Malay (Bahasa Melayu)',
'ml_IN' => 'Malayalam (മലയാളം)',
@@ -134,7 +133,6 @@ $rcube_language_aliases = array(
'kh' => 'km_KH',
'kh_KH' => 'km_KH',
'km' => 'km_KH',
- 'lb' => 'lb_LU',
'ne' => 'ne_NP',
'no' => 'nn_NO',
'ms' => 'ms_MY',
diff --git a/program/localization/is_IS/labels.inc b/program/localization/is_IS/labels.inc
index c2859ce75..80443dd3a 100644
--- a/program/localization/is_IS/labels.inc
+++ b/program/localization/is_IS/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Drög';
$labels['sent'] = 'Sent';
$labels['trash'] = 'Rusl';
$labels['junk'] = 'Ruslpóstur';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Titill';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Listayfirlit';
$labels['folderactions'] = 'Möppuaðgerðir...';
$labels['compact'] = 'Pakka';
$labels['empty'] = 'Tæma';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Gagnamagn';
$labels['unknown'] = 'óþekkt';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Tæma leit';
$labels['searchmod'] = 'Leitarskilyrði';
$labels['msgtext'] = 'Allt skeytið';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Opna í nýjum glugga';
$labels['emlsave'] = 'Niðurhlaða (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Sýna síðustu síðu';
$labels['group'] = 'Hópur';
$labels['groups'] = 'Hópar';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persónuleg heimilisföng';
$labels['searchsave'] = 'Vista leit';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Hunsa orð með tölum';
$labels['spellcheckignorecaps'] = 'Hunsa orð sem eru í hástöfum';
$labels['addtodict'] = 'Bæta við orðalista';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/is_IS/messages.inc b/program/localization/is_IS/messages.inc
index 731a19791..6e9f35af3 100644
--- a/program/localization/is_IS/messages.inc
+++ b/program/localization/is_IS/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'File upload failed.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/it_IT/labels.inc b/program/localization/it_IT/labels.inc
index 55cd432f7..75a24c5fd 100644
--- a/program/localization/it_IT/labels.inc
+++ b/program/localization/it_IT/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Bozze';
$labels['sent'] = 'Inviata';
$labels['trash'] = 'Cestino';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Oggetto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Modalità di visualizzazione';
$labels['folderactions'] = 'Operazioni cartella';
$labels['compact'] = 'Compatta';
$labels['empty'] = 'Svuota';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Spazio utilizzato';
$labels['unknown'] = 'sconosciuto';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Annulla ricerca';
$labels['searchmod'] = 'Ambito di ricerca';
$labels['msgtext'] = 'Intero messaggio';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Apri in una nuova finestra';
$labels['emlsave'] = 'Scarica (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Ultima pagina';
$labels['group'] = 'Gruppo';
$labels['groups'] = 'Gruppi';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Rubrica Personale';
$labels['searchsave'] = 'Salva ricerca';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignora le parole contenenti numeri';
$labels['spellcheckignorecaps'] = 'Ignora le parole con tutte le lettere maiuscole';
$labels['addtodict'] = 'Aggiungi al dizionario';
$labels['mailtoprotohandler'] = 'Registra gestore per mailto:';
-$labels['standardwindows'] = 'Gestisci i popup come finestre standard';
$labels['forwardmode'] = 'Inoltro messaggi';
$labels['inline'] = 'In linea';
$labels['asattachment'] = 'come allegato';
diff --git a/program/localization/it_IT/messages.inc b/program/localization/it_IT/messages.inc
index 502ecba25..80395b551 100644
--- a/program/localization/it_IT/messages.inc
+++ b/program/localization/it_IT/messages.inc
@@ -17,7 +17,7 @@
*/
$messages = array();
-$messages['errortitle'] = 'Si è verificato un errore!';
+$messages['errortitle'] = 'C\'è stato qualche errore';
$messages['loginfailed'] = 'Impossibile accedere. Utente o password non corretti';
$messages['cookiesdisabled'] = 'Il tuo browser non accetta i cookies';
$messages['sessionerror'] = 'Sessione non valida o scaduta';
@@ -101,16 +101,13 @@ $messages['converting'] = 'Rimozione della formattazione dal messaggio...';
$messages['messageopenerror'] = 'Impossibile caricare il messaggio dal server';
$messages['fileuploaderror'] = 'Errore durante il caricamento del file';
$messages['filesizeerror'] = 'Il file da caricare supera il limite massimo di $size';
-$messages['copysuccess'] = 'Copiati correttamente $nr contatti.';
-$messages['movesuccess'] = '$nr contatti spostati correttamente.';
-$messages['copyerror'] = 'Impossibile copiare i contatti.';
-$messages['moveerror'] = 'Impossibile spostare i contatti.';
+$messages['copysuccess'] = 'Copiati $nr indirizzi';
+$messages['copyerror'] = 'Impossibile copiare gli indirizzi';
$messages['sourceisreadonly'] = 'La rubrica è in sola lettura';
$messages['errorsavingcontact'] = 'Impossibile salvare il contatto';
$messages['movingmessage'] = 'Spostamento del messaggio...';
$messages['copyingmessage'] = 'Copia del messaggio...';
$messages['copyingcontact'] = 'Copia del contatto...';
-$messages['movingcontact'] = 'Spostamento contatto(i)';
$messages['deletingmessage'] = 'Cancellazione messaggio...';
$messages['markingmessage'] = 'Marca messaggio...';
$messages['addingmember'] = 'Aggiunta contatto al gruppo...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importazione in corso, attendere...';
$messages['importformaterror'] = 'Importazione fallita! Il file caricato non è un file valido per l\'importazione.';
$messages['importconfirm'] = '<b>$inserted contatti importati con successo</p>';
$messages['importconfirmskipped'] = '<b>$skipped ignorati perché esistono già</b>';
-$messages['importmessagesuccess'] = 'Importati correttamente $nr messaggi';
-$messages['importmessageerror'] = 'Importazione fallita! Il file caricato non è un messaggio o una casella postale valida.';
$messages['opnotpermitted'] = 'Operazione non consentita!';
$messages['nofromaddress'] = 'Indirizzo e-mail mancante nell\'identità selezionata';
$messages['editorwarning'] = 'Passare all\'editor testuale farà perdere tutte le informazioni di formattazione. Sicuro di voler continuare?';
diff --git a/program/localization/ja_JP/labels.inc b/program/localization/ja_JP/labels.inc
index 767aff23a..6998f0623 100644
--- a/program/localization/ja_JP/labels.inc
+++ b/program/localization/ja_JP/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = '下書ã';
$labels['sent'] = 'é€ä¿¡æ¸ˆã¿';
$labels['trash'] = 'ã”ã¿ç®±';
$labels['junk'] = '迷惑メール';
-$labels['show_real_foldernames'] = '特殊フォルダーã®å®Ÿéš›ã®åå‰ã‚’表示';
// message listing
$labels['subject'] = '件å';
@@ -194,7 +193,6 @@ $labels['listmode'] = '一覧表示モード';
$labels['folderactions'] = 'フォルダーã®æ“作...';
$labels['compact'] = '圧縮';
$labels['empty'] = '空';
-$labels['importmessages'] = 'メッセージをインãƒãƒ¼ãƒˆ';
$labels['quota'] = 'ディスクã®ä½¿ç”¨çŠ¶æ³';
$labels['unknown'] = 'ä¸æ˜Ž';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = '検索を解除';
$labels['searchmod'] = '検索ã®æ¡ä»¶';
$labels['msgtext'] = 'メッセージ全体';
$labels['body'] = '本文';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'æ–°ã—ã„ウィンドウã§é–‹ã';
$labels['emlsave'] = 'ダウンロード(.emlå½¢å¼)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = '最後ã®ãƒšãƒ¼ã‚¸ã‚’表示';
$labels['group'] = 'グループ';
$labels['groups'] = 'グループ';
-$labels['listgroup'] = 'グループã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’一覧';
$labels['personaladrbook'] = '個人ã®ä½æ‰€';
$labels['searchsave'] = '検索情報をä¿å­˜';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'æ•°å­—ã‚’å«ã‚€å˜èªžã‚’無視';
$labels['spellcheckignorecaps'] = 'ã™ã¹ã¦å¤§æ–‡å­—ã®å˜èªžã‚’無視';
$labels['addtodict'] = '辞書ã«è¿½åŠ ';
$labels['mailtoprotohandler'] = 'mailto: ã®ãƒªãƒ³ã‚¯ã‚’扱ã†ãƒ—ロトコル処ç†ã®ç™»éŒ²';
-$labels['standardwindows'] = 'ãƒãƒƒãƒ—アップを通常ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¨ã—ã¦å‡¦ç†';
$labels['forwardmode'] = 'メッセージã®è»¢é€å½¢å¼';
$labels['inline'] = 'インライン';
$labels['asattachment'] = '添付ファイル';
diff --git a/program/localization/ja_JP/messages.inc b/program/localization/ja_JP/messages.inc
index 820b52d96..f4dd0fceb 100644
--- a/program/localization/ja_JP/messages.inc
+++ b/program/localization/ja_JP/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'メールã‹ã‚‰æ›¸å¼ã‚’削除中...';
$messages['messageopenerror'] = 'サーãƒãƒ¼ã‹ã‚‰ãƒ¡ãƒ¼ãƒ«ã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“。';
$messages['fileuploaderror'] = 'ファイルをアップロードã§ãã¾ã›ã‚“ã§ã—ãŸã€‚';
$messages['filesizeerror'] = 'アップロードã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚µã‚¤ã‚ºãŒä¸Šé™($size)を超ãˆã¾ã—ãŸã€‚';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr件ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’コピーã—ã¾ã—ãŸã€‚';
+$messages['copyerror'] = 'ã©ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚‚コピーã§ãã¾ã›ã‚“ã§ã—ãŸã€‚';
$messages['sourceisreadonly'] = 'ã“ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚½ãƒ¼ã‚¹ã¯èª­ã¿è¾¼ã¿å°‚用ã§ã™ã€‚';
$messages['errorsavingcontact'] = '連絡先ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’ä¿å­˜ã§ãã¾ã›ã‚“。';
$messages['movingmessage'] = 'メッセージを移動中...';
$messages['copyingmessage'] = 'メッセージをコピー中...';
$messages['copyingcontact'] = '連絡先をコピー中...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'メッセージを削除中...';
$messages['markingmessage'] = 'メッセージã«ãƒžãƒ¼ã‚¯ã‚’設定中...';
$messages['addingmember'] = 'グループã«é€£çµ¡å…ˆã‚’コピー中...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'インãƒãƒ¼ãƒˆä¸­ã§ã™ã€‚ã—ã°ã‚‰ããŠå¾…ã¡ãã
$messages['importformaterror'] = 'インãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ! アップロードã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã¯æ­£ã—ã„データをインãƒãƒ¼ãƒˆã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã§ã¯ã‚ã‚Šã¾ã›ã‚“。';
$messages['importconfirm'] = '<b>$inserted件ã®é€£çµ¡å…ˆã‚’インãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚</b>';
$messages['importconfirmskipped'] = '<b>$skipped件ã®æ—¢å­˜ã™ã‚‹é …目を飛ã°ã—ãŸã€‚</b>';
-$messages['importmessagesuccess'] = '$nr件ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’インãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚';
-$messages['importmessageerror'] = 'インãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ! アップロードã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã¯æœ‰åŠ¹ãªãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚„メールボックスã®ãƒ•ã‚¡ã‚¤ãƒ«ã§ã¯ã‚ã‚Šã¾ã›ã‚“。';
$messages['opnotpermitted'] = '許å¯ã•ã‚Œã¦ã„ãªã„æ“作ã§ã™ã€‚';
$messages['nofromaddress'] = 'é¸æŠžã—ã¦ã„る識別情報ã«é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒæŠœã‘ã¦ã„ã¾ã™ã€‚';
$messages['editorwarning'] = 'テキストエディターã«åˆ‡ã‚Šæ›¿ãˆã‚‹ã¨ã€ã™ã¹ã¦ã®æ›¸å¼ã¯ãªããªã‚Šã¾ã™ã€‚本当ã«ç¶šã‘ã¾ã™ã‹?';
diff --git a/program/localization/ka_GE/labels.inc b/program/localization/ka_GE/labels.inc
index b0126c44e..3ab3b6e63 100755..100644
--- a/program/localization/ka_GE/labels.inc
+++ b/program/localization/ka_GE/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'დრáƒáƒ”ბითი';
$labels['sent'] = 'გáƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜';
$labels['trash'] = 'წáƒáƒ¨áƒšáƒ˜áƒšáƒ˜';
$labels['junk'] = 'სპáƒáƒ›áƒ˜';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'სáƒáƒ—áƒáƒ£áƒ áƒ˜';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'შეკუმშვáƒ';
$labels['empty'] = 'გáƒáƒªáƒáƒ áƒ˜áƒ”ლებáƒ';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'შეზღუდვáƒ';
$labels['unknown'] = 'უცნáƒáƒ‘ი';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'ძიების გáƒáƒ¡áƒ£áƒ¤áƒ—áƒáƒ•áƒ”ბáƒ'
$labels['searchmod'] = 'ძებნის ვáƒáƒ áƒ˜áƒáƒœáƒ¢áƒ”ბი';
$labels['msgtext'] = 'ყველრშეტყáƒáƒ‘ინებáƒ';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'გáƒáƒ®áƒ¡áƒœáƒ áƒáƒ®áƒáƒš ფáƒáƒœáƒ¯áƒáƒ áƒáƒ¨áƒ˜';
$labels['emlsave'] = 'გáƒáƒ“მáƒáƒ¬áƒ”რრ(.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'ბáƒáƒšáƒáƒ¡ ჩვენებáƒ';
$labels['group'] = 'ჯგუფი';
$labels['groups'] = 'ჯგუფები';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'პერსáƒáƒœáƒáƒšáƒ£áƒ áƒ˜ მისáƒáƒ›áƒáƒ áƒ—ები';
$labels['searchsave'] = 'ძებნის შენáƒáƒ®áƒ•áƒ';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'ლექსიკáƒáƒœáƒ¨áƒ˜ დáƒáƒ›áƒáƒ¢áƒ”ბáƒ';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ka_GE/messages.inc b/program/localization/ka_GE/messages.inc
index c0cdd98f0..754343fac 100755..100644
--- a/program/localization/ka_GE/messages.inc
+++ b/program/localization/ka_GE/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'შეტყáƒáƒ‘ინების ფáƒáƒ áƒ›áƒá
$messages['messageopenerror'] = 'შეტყáƒáƒ‘ინებრვერ ჩáƒáƒ˜áƒ¢áƒ•áƒ˜áƒ áƒ—რსერვერიდáƒáƒœ';
$messages['fileuploaderror'] = 'ფáƒáƒ˜áƒšáƒ˜ ვერ áƒáƒ˜áƒ¢áƒ•áƒ˜áƒ áƒ—áƒ';
$messages['filesizeerror'] = 'áƒáƒ¢áƒ•áƒ˜áƒ áƒ—ული ფáƒáƒ˜áƒšáƒ˜áƒ¡ ზáƒáƒ›áƒ მეტირდáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბ ფáƒáƒ˜áƒšáƒ˜áƒ¡ მáƒáƒ¥áƒ¡áƒ˜áƒ›áƒáƒšáƒ£áƒ  ზáƒáƒ›áƒáƒ–ე ($size)';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'წáƒáƒ áƒ›áƒáƒ¢áƒ”ბით დáƒáƒ™áƒáƒžáƒ˜áƒ áƒ“რ$nr მისáƒáƒ›áƒáƒ áƒ—ი';
+$messages['copyerror'] = 'ვერცერთი მისáƒáƒ›áƒáƒ áƒ—ი ვერ დáƒáƒ™áƒáƒžáƒ˜áƒ áƒ“áƒ';
$messages['sourceisreadonly'] = 'áƒáƒ¦áƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ მისáƒáƒ›áƒáƒ áƒ—ის მხáƒáƒšáƒáƒ“ წáƒáƒ™áƒ˜áƒ—ხვáƒáƒ შესáƒáƒ«áƒšáƒ”ბელი';
$messages['errorsavingcontact'] = 'სáƒáƒ™áƒáƒœáƒ¢áƒáƒ¥áƒ¢áƒ მისáƒáƒ›áƒáƒ áƒ—ის შენáƒáƒ®áƒ•áƒ შეუძლებელიáƒ';
$messages['movingmessage'] = 'შეტყáƒáƒ‘ინების გáƒáƒ“áƒáƒ¢áƒáƒœáƒ...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'გთხáƒáƒ•áƒ— მáƒáƒ˜áƒªáƒáƒ“áƒáƒ—, მიáƒ
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>წáƒáƒ áƒ›áƒáƒ¢áƒ”ბით დáƒáƒ¡áƒ áƒ£áƒšáƒ“რ$inserted კáƒáƒœáƒ¢áƒáƒ¥áƒ¢áƒ”ბის შემáƒáƒ¢áƒáƒœáƒ, $skipped áƒáƒ áƒ¡áƒ”ბულის გáƒáƒ›áƒáƒ¢áƒáƒ•áƒ”ბáƒ</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'áƒáƒžáƒ”რáƒáƒªáƒ˜áƒ შეზღუდულიáƒ';
$messages['nofromaddress'] = 'ელ–ფáƒáƒ¡áƒ¢áƒ˜áƒ¡ მისáƒáƒ›áƒáƒ áƒ—ი გáƒáƒ›áƒáƒ¢áƒáƒ•áƒ”ბულიáƒ';
$messages['editorwarning'] = 'რედáƒáƒ¥áƒ¢áƒáƒ áƒ˜áƒ¡ გáƒáƒ“áƒáƒ áƒ—ვრტექსტურ რეჟიმში გáƒáƒ›áƒáƒ˜áƒ¬áƒ•áƒ”ვს áƒáƒ áƒ¡áƒ”ბული ტექსტის ფáƒáƒ áƒ›áƒáƒ¢áƒ˜áƒ¡ დáƒáƒ™áƒáƒ áƒ’ვáƒáƒ¡. გსურთ გáƒáƒ’რძელებáƒ?';
diff --git a/program/localization/km_KH/labels.inc b/program/localization/km_KH/labels.inc
index bc2836a53..7b10b5f7f 100644
--- a/program/localization/km_KH/labels.inc
+++ b/program/localization/km_KH/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'សំបុážáŸ’រពង្រៀង';
$labels['sent'] = 'សំបុážáŸ’រដែលបានបញ្ជូន';
$labels['trash'] = 'ធុងសំរាម';
$labels['junk'] = 'សំបុážáŸ’រមិនល្អ';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ចំណងជើង';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'បង្ហាញជាážáž¶ážšáž¶áž„';
$labels['folderactions'] = 'មុážáž„ារážáž';
$labels['compact'] = 'បង្រួម';
$labels['empty'] = 'áž‘áž‘áŸážš';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ទំហំសំបុážáŸ’រទាំងអស់ដែលមាន';
$labels['unknown'] = 'មិនស្គាល់';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'កំណážáŸ‹áž›áž€áŸ’ážážáŸážŽáŸ’ឌស្វáŸ
$labels['searchmod'] = 'កែសំរួលលក្ážážáŸážŽáŸ’ឌស្វែងរក';
$labels['msgtext'] = 'សំបុážáŸ’រទាំងមូល';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'បើកក្នុងវីនដូវážáŸ’មី';
$labels['emlsave'] = 'រក្សាទុកទិន្ននáŸáž™áž‡áž¶áž¯áž€ážŸáž¶ážšáž”្រភáŸáž‘(.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'ទំពáŸážšáž…ុងក្រោយ';
$labels['group'] = 'ក្រុម';
$labels['groups'] = 'ក្រុម';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'អាសយដ្ឋានផ្ទាល់ážáŸ’លួន';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/km_KH/messages.inc b/program/localization/km_KH/messages.inc
index 35bb10244..1f629fa6c 100644
--- a/program/localization/km_KH/messages.inc
+++ b/program/localization/km_KH/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'កំពុងលុបការរចនាចោáž
$messages['messageopenerror'] = 'មិនអាចទាញយកសំបុážáŸ’រពីម៉ាស៊ីនមáŸáž”ានទáŸ';
$messages['fileuploaderror'] = 'មិនអាចបញ្ជូលភ្ជាប់ឯកសារ';
$messages['filesizeerror'] = 'ទំហំឯកសារážáŸ’រូវបញ្ជូនលើសចំណុះទំហំធំបំផុážáž‚ឺ $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'បានចំលងអាសយដ្ឋានចំនួន $nrដោយជោគជáŸáž™';
+$messages['copyerror'] = 'មិនអាចចំលងអាសយដ្ឋានណាមួយឡើយ';
$messages['sourceisreadonly'] = 'លោកអ្នកមានសិទ្ធážáŸ’រឹមážáŸ‚មើលប្រភពនៃអាសយដ្ឋាននáŸáŸ‡';
$messages['errorsavingcontact'] = 'មិនអាចរក្សាអាសយដ្ឋានបានទáŸ';
$messages['movingmessage'] = 'កំពុកផ្ážáŸážšážŸáŸ†áž”áž»ážáŸ’ážš...';
$messages['copyingmessage'] = 'កំពុងចំលងសំបុážáŸ’ážš...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'កំពុងលុបសំបុážáŸ’ážš...';
$messages['markingmessage'] = 'កំពុងកំណážáŸ‹ážŸáŸ†áž‚ាល់សំបុážáŸ’ážš...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'សូមមáŸážáŸ’ážáž¶ážšáž„់ចាំកំáž
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>áž–áŸážáŸŒáž˜áž¶áž“ទំនាក់ទំនង $insertedបានបញ្ចូលដោយជោគជáŸáž™,ហើយបានរំលងចោលពážáŸŒáž˜áž¶áž“ដែលមានស្រាប់$skipped </b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'ប្រážáž·áŸ’ážáž”ážáŸ’ážáž·áž€áž¶ážšážáŸ’រូវបានគáŸáž áž¶áž˜ážƒáž¶ážáŸ‹!';
$messages['nofromaddress'] = 'ážáŸ’វះអាសយដ្ឋានអ៊ីមែលក្នុងអážáŸ’ážážŸáž‰áŸ’ណាណមួយនáŸáŸ‡';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/ko_KR/labels.inc b/program/localization/ko_KR/labels.inc
index 60a9275ac..950928767 100644
--- a/program/localization/ko_KR/labels.inc
+++ b/program/localization/ko_KR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = '임시 보관함';
$labels['sent'] = '보낸 편지함';
$labels['trash'] = '휴지통';
$labels['junk'] = '스팸 편지함';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '제목';
@@ -194,7 +193,6 @@ $labels['listmode'] = '화면 모드 ëª©ë¡ ë³´ê¸°';
$labels['folderactions'] = 'í´ë” 명령';
$labels['compact'] = '간단하게';
$labels['empty'] = '비어 있ìŒ';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ë””ìŠ¤í¬ ì‚¬ìš©ëŸ‰';
$labels['unknown'] = 'ì•Œ 수 ì—†ìŒ';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = '검색 재설정';
$labels['searchmod'] = 'ìˆ˜ì •ìž ê²€ìƒ‰';
$labels['msgtext'] = '전체 메시지';
$labels['body'] = '본문';
-$labels['type'] = 'Type';
$labels['openinextwin'] = '새 ì°½ì—ì„œ 열기';
$labels['emlsave'] = '다운로드(.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = '마지막 페ì´ì§€ 보기';
$labels['group'] = '그룹';
$labels['groups'] = '그룹';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ê°œì¸ ì£¼ì†Œ';
$labels['searchsave'] = '검색 저장';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = '숫ìžê°€ í¬í•¨ëœ 단어 무시';
$labels['spellcheckignorecaps'] = 'ëª¨ë‘ ëŒ€ë¬¸ìžë¡œ í‘œê¸°ëœ ë‹¨ì–´ 무시';
$labels['addtodict'] = 'ì‚¬ì „ì— ì¶”ê°€';
$labels['mailtoprotohandler'] = 'mailto: ë§í¬ì˜ 프로토콜 ì²˜ë¦¬ìž ë“±ë¡';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = '메시지 전달';
$labels['inline'] = '본문 내용으로';
$labels['asattachment'] = '첨부파ì¼ë¡œ';
diff --git a/program/localization/ko_KR/messages.inc b/program/localization/ko_KR/messages.inc
index ace6dc8d7..bf42c9c89 100644
--- a/program/localization/ko_KR/messages.inc
+++ b/program/localization/ko_KR/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'ì„œì‹ ì„¤ì • ì‚­ì œ 중...';
$messages['messageopenerror'] = '서버ì—ì„œ 메시지를 불러올 수 ì—†ìŒ.';
$messages['fileuploaderror'] = 'íŒŒì¼ ì—…ë¡œë“œë¥¼ 실패함.';
$messages['filesizeerror'] = 'ì—…ë¡œë“œëœ íŒŒì¼ì´ 최대 í¬ê¸°ì¸ $size를 초과하였습니다.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nrê°œì˜ ì£¼ì†Œë¥¼ 성공ì ìœ¼ë¡œ 복사함.';
+$messages['copyerror'] = '모든 주소를 복사할 수 ì—†ìŒ.';
$messages['sourceisreadonly'] = 'ì´ ì£¼ì†Œì˜ ì†ŒìŠ¤ëŠ” ì½ê¸° 전용입니다.';
$messages['errorsavingcontact'] = 'ì—°ë½ì²˜ì˜ 주소를 저장할 수 ì—†ìŒ.';
$messages['movingmessage'] = '메시지를 ì´ë™í•˜ëŠ” 중...';
$messages['copyingmessage'] = '메시지 복사하는 중...';
$messages['copyingcontact'] = 'ì—°ë½ì²˜ 복사하는 중...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = '메시지 삭제하는 중...';
$messages['markingmessage'] = 'ë©”ì‹œì§€ì— í‘œì‹œí•˜ëŠ” 중...';
$messages['addingmember'] = 'ê·¸ë£¹ì— ì—°ë½ì²˜ë¥¼ 추가하는 중...';
@@ -129,8 +126,6 @@ $messages['importwait'] = '가져오는 중, 기다려주시기 ë°”ëžë‹ˆë‹¤...'
$messages['importformaterror'] = '가져오기를 실패함! ì—…ë¡œë“œëœ íŒŒì¼ì€ 유효하지 ì•Šì€ ê°€ì ¸ì˜¤ê¸° ë°ì´í„° 파ì¼ìž…니다.';
$messages['importconfirm'] = '<b>$inserted ì—°ë½ì²˜ë¥¼ 성공ì ìœ¼ë¡œ 가져옴<b>';
$messages['importconfirmskipped'] = '<b>기존 ê¸°ìž¬ì‚¬í•­ì¸ $skippedì„(를) 건너뜀</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'ìž‘ì—…ì´ í—ˆê°€ë˜ì§€ ì•ŠìŒ!';
$messages['nofromaddress'] = 'ì„ íƒëœ ì‹ ì›ì— ì´ë©”ì¼ ì£¼ì†Œ ê°€ 누ë½ë¨.';
$messages['editorwarning'] = 'ì¼ë°˜ í…스트 편집기로 바꾸면 모든 í…스트 ì„œì‹ì´ 사ë¼ì§‘니다. 계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?';
diff --git a/program/localization/ku/labels.inc b/program/localization/ku/labels.inc
index 6a3c16a5f..a4f6cb568 100644
--- a/program/localization/ku/labels.inc
+++ b/program/localization/ku/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Hilanînî';
$labels['sent'] = 'Şandî';
$labels['trash'] = 'Çop';
$labels['junk'] = 'Biikêrnehatî';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Mijar';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Kompakt';
$labels['empty'] = 'Vala Bike';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Bikaranîna dîskê';
$labels['unknown'] = 'nayê zanîn';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Lêgerînê reset bike';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Seta dawî nîşan bide';
$labels['group'] = 'Group';
$labels['groups'] = 'Kom';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Navnîşanên Takekesî';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ku/messages.inc b/program/localization/ku/messages.inc
index b3c716466..9d219cbf5 100644
--- a/program/localization/ku/messages.inc
+++ b/program/localization/ku/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Formatkirin ji peyamê tê birin...';
$messages['messageopenerror'] = 'Peyam ji pêşkêşkar nehat barkirin';
$messages['fileuploaderror'] = 'Barkirina pelê têk çû';
$messages['filesizeerror'] = 'Pel pir mezin e. Herî zêde divê $size be';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr navnîşan hat(in) jibergirtin';
+$messages['copyerror'] = 'Tu navnîşan nehat jibergirtin';
$messages['sourceisreadonly'] = 'Çavkaniya vê navnîşanê tenê-xwendin e';
$messages['errorsavingcontact'] = 'Navnîşana têkiliyê nehat barkirin';
$messages['movingmessage'] = 'Ciyê peyamê tê guhertin...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/lb_LU/labels.inc b/program/localization/lb_LU/labels.inc
index 1dff3a9e7..cbd5a12a8 100644
--- a/program/localization/lb_LU/labels.inc
+++ b/program/localization/lb_LU/labels.inc
@@ -15,31 +15,21 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/labels/
*/
-
-$labels = array();
-
-// login page
$labels['welcome'] = 'Wëllkomm bei $product';
$labels['username'] = 'Benotzernumm';
$labels['password'] = 'Passwuert';
$labels['server'] = 'Server';
$labels['login'] = 'Aloggen';
-
-// taskbar
$labels['logout'] = 'Ausloggen';
$labels['mail'] = 'Mailen';
$labels['settings'] = 'Astellungen';
$labels['addressbook'] = 'Adressbuch';
-
-// mailbox names
$labels['inbox'] = 'Mailbox';
$labels['drafts'] = 'Brouillonen';
$labels['sent'] = 'Verschéckt';
$labels['trash'] = 'Poubelle';
$labels['junk'] = 'Spam';
$labels['show_real_foldernames'] = 'Richteg Nimm vu de speziellen Dossieren uweisen';
-
-// message listing
$labels['subject'] = 'Sujet';
$labels['from'] = 'Vun';
$labels['sender'] = 'Geschéckt vun';
@@ -54,13 +44,11 @@ $labels['priority'] = 'Prioritéit';
$labels['organization'] = 'Organisatioun';
$labels['readstatus'] = 'Lies-Status';
$labels['listoptions'] = 'Optiounen oplëschten';
-
$labels['mailboxlist'] = 'Dossieren';
$labels['messagesfromto'] = 'Messagen $from bis $to vun $count';
$labels['threadsfromto'] = 'Diskussiounen $from bis $to vun $count';
$labels['messagenrof'] = 'Message $nr vun $count';
$labels['fromtoshort'] = '$from bis $to vun $count';
-
$labels['copy'] = 'Kopéieren';
$labels['move'] = 'Réckelen';
$labels['moveto'] = 'Réckelen an...';
@@ -68,13 +56,9 @@ $labels['download'] = 'Eroflueden';
$labels['open'] = 'Opmaachen';
$labels['showattachment'] = 'Weisen';
$labels['showanyway'] = 'Trotzdeem weisen';
-
$labels['filename'] = 'Numm vum Fichier';
$labels['filesize'] = 'Gréisst vum Fichier';
-
$labels['addtoaddressbook'] = 'An d\'Adressbuch setzen';
-
-// weekdays short
$labels['sun'] = 'Son';
$labels['mon'] = 'Méi';
$labels['tue'] = 'Dën';
@@ -82,8 +66,6 @@ $labels['wed'] = 'Don';
$labels['thu'] = 'Fre';
$labels['fri'] = 'Sam';
$labels['sat'] = 'Son';
-
-// weekdays long
$labels['sunday'] = 'Sonndeg';
$labels['monday'] = 'Méindeg';
$labels['tuesday'] = 'Dënschdeg';
@@ -91,8 +73,6 @@ $labels['wednesday'] = 'Mëttwoch';
$labels['thursday'] = 'Donneschdeg';
$labels['friday'] = 'Freideg';
$labels['saturday'] = 'Samschdeg';
-
-// months short
$labels['jan'] = 'Jan';
$labels['feb'] = 'Feb';
$labels['mar'] = 'Mäe';
@@ -105,8 +85,6 @@ $labels['sep'] = 'Sep';
$labels['oct'] = 'Okt';
$labels['nov'] = 'Nov';
$labels['dec'] = 'Dez';
-
-// months long
$labels['longjan'] = 'Januar';
$labels['longfeb'] = 'Februar';
$labels['longmar'] = 'Mäerz';
@@ -119,10 +97,7 @@ $labels['longsep'] = 'September';
$labels['longoct'] = 'Oktober';
$labels['longnov'] = 'November';
$labels['longdec'] = 'Dezember';
-
$labels['today'] = 'Haut';
-
-// toolbar buttons
$labels['refresh'] = 'Nei lueden';
$labels['checkmail'] = 'Nei Messagen ofruffen';
$labels['compose'] = 'Schreiwen';
@@ -155,7 +130,6 @@ $labels['moreactions'] = 'Mei Aktiounen...';
$labels['more'] = 'Méi';
$labels['back'] = 'Zréck';
$labels['options'] = 'Optiounen';
-
$labels['select'] = 'Auswielen';
$labels['all'] = 'All';
$labels['none'] = 'Keng';
@@ -174,7 +148,6 @@ $labels['expand-all'] = 'All opfächeren';
$labels['expand-unread'] = 'Ongelies opfächeren';
$labels['collapse-all'] = 'All zesummefächeren';
$labels['threaded'] = 'Diskussiounen zesummefaassen';
-
$labels['autoexpand_threads'] = 'Diskussiounen auserneefächeren';
$labels['do_expand'] = 'All d\'Diskussiounen';
$labels['expand_only_unread'] = 'just ongeliese Messagen';
@@ -190,16 +163,13 @@ $labels['listcolumns'] = 'Kolonnen oplëschten';
$labels['listsorting'] = 'Kolonne sortéieren';
$labels['listorder'] = 'Sortéier-Reiefolleg';
$labels['listmode'] = 'Oplëschtungs-Modus';
-
$labels['folderactions'] = 'Dossiers-Aktiounen...';
$labels['compact'] = 'Kompaktéieren';
$labels['empty'] = 'Eidel';
$labels['importmessages'] = 'Messagen importéieren';
-
$labels['quota'] = 'Plazverbrauch';
$labels['unknown'] = 'onbekannt';
$labels['unlimited'] = 'onlimitéiert';
-
$labels['quicksearch'] = 'Séier Sich';
$labels['resetsearch'] = 'Sich zerécksetzen';
$labels['searchmod'] = 'Sich-Parameter';
@@ -207,13 +177,10 @@ $labels['msgtext'] = 'Ganze Message';
$labels['body'] = 'Kierper';
$labels['type'] = 'Typ';
$labels['namex'] = 'Numm';
-
$labels['openinextwin'] = 'An enger neier Fënster opmaachen';
$labels['emlsave'] = 'Eroflueden (.eml)';
$labels['changeformattext'] = 'Als Text ouni Formatéierungen uweisen';
$labels['changeformathtml'] = 'Als formatéierten Text uweisen';
-
-// message compose
$labels['editasnew'] = 'Als nei editéieren';
$labels['send'] = 'Schécken';
$labels['sendmessage'] = 'Message schécken';
@@ -225,26 +192,30 @@ $labels['returnreceipt'] = 'Empfanksbestätegung';
$labels['dsn'] = 'Empfanks-Status-Meldung';
$labels['mailreplyintro'] = 'Den $date, $sender schreift:';
$labels['originalmessage'] = 'Original-Message';
-
$labels['editidents'] = 'Identitéiten editéieren';
$labels['spellcheck'] = 'Orthographie';
$labels['checkspelling'] = 'Orthographie kontrolléieren';
$labels['resumeediting'] = 'Weider editéieren';
$labels['revertto'] = 'Zréck bei';
-
+$labels['responses'] = 'Äntwerten';
+$labels['insertresponse'] = 'Äntwert afügen';
+$labels['manageresponses'] = 'Äntwerte geréieren';
+$labels['savenewresponse'] = 'Nei Äntwert späicheren';
+$labels['editresponses'] = 'Äntwerten Editéieren';
+$labels['editresponse'] = 'Äntwert editéieren';
+$labels['responsename'] = 'Numm';
+$labels['responsetext'] = 'Äntwert-Text';
$labels['attach'] = 'Drunhänken';
$labels['attachments'] = 'Unhäng';
$labels['upload'] = 'Eroplueden';
$labels['uploadprogress'] = '$percent ($current vun $total)';
$labels['close'] = 'Zoumaachen';
$labels['messageoptions'] = 'Message-Optiounen...';
-
$labels['low'] = 'Niddreg';
$labels['lowest'] = 'Am niddregsten';
$labels['normal'] = 'Normal';
$labels['high'] = 'Héich';
$labels['highest'] = 'Am héchsten';
-
$labels['nosubject'] = '(kee Sujet)';
$labels['showimages'] = 'Biller uweisen';
$labels['alwaysshow'] = 'Biller vun $sender ëmmer uweisen';
@@ -252,25 +223,19 @@ $labels['isdraft'] = 'Dëst ass e Brouillon.';
$labels['andnmore'] = '$nr more...';
$labels['togglemoreheaders'] = 'Méi Message-Headeren uweisen';
$labels['togglefullheaders'] = 'Réi Message-Headeren an-/ausblenden';
-
$labels['htmltoggle'] = 'Text mat Formatéierungen';
$labels['plaintoggle'] = 'Text ouni Formatéierungen';
$labels['savesentmessagein'] = 'Dee verschéckte Message späicheren an';
$labels['dontsave'] = 'net späicheren';
$labels['maxuploadsize'] = 'Déi maximal erlaabte Fichiers-Gréisst ass $size';
-
$labels['addcc'] = 'CC dobäisetzen';
$labels['addbcc'] = 'BCC dobäisetzen';
$labels['addreplyto'] = '"Äntwert un" dobäisetzen';
$labels['addfollowupto'] = '"Noverfollgung un" dobäisetzen';
-
-// mdn
$labels['mdnrequest'] = 'De Sender vun dësem Message huet gefrot fir informéiert ze gi wann de Message gelies gëtt. Wëlls du de Sender informéieren?';
$labels['receiptread'] = 'Empfanksbestätegung (gelies)';
$labels['yourmessage'] = 'Dëst ass eng Empfanksbestätegung fir Äre Message.';
$labels['receiptnote'] = 'Bemierkung: Dës Bestätegung bezeit just datt de Message beim Empfänger ugewise ginn ass. Et gëtt keng Garantie dass den Empfänger den Inhalt vum Message gelies oder verstanen huet.';
-
-// address boook
$labels['name'] = 'Ganzen Numm';
$labels['firstname'] = 'Virnumm';
$labels['surname'] = 'Nonumm';
@@ -305,7 +270,6 @@ $labels['search'] = 'Sichen';
$labels['advsearch'] = 'Avancéiert Sich';
$labels['advanced'] = 'Avancéiert';
$labels['other'] = 'Aneres';
-
$labels['typehome'] = 'Doheem';
$labels['typework'] = 'Aarbecht';
$labels['typeother'] = 'Aneres';
@@ -320,14 +284,12 @@ $labels['typeassistant'] = 'Assistent';
$labels['typehomepage'] = 'Websäit';
$labels['typeblog'] = 'Blog';
$labels['typeprofile'] = 'Profil';
-
$labels['addfield'] = 'Feld dobäisetzen...';
$labels['addcontact'] = 'Neie Kontakt dobäisetzen';
$labels['editcontact'] = 'Kontakt editéieren';
$labels['contacts'] = 'Kontakter';
$labels['contactproperties'] = 'Kontakt-Eegeschaften';
$labels['personalinfo'] = 'Perséinlech Informatioun';
-
$labels['edit'] = 'Änneren';
$labels['cancel'] = 'Ofbriechen';
$labels['save'] = 'Späicheren';
@@ -336,7 +298,6 @@ $labels['rename'] = 'Ëmbenennen';
$labels['addphoto'] = 'Dobäisetzen';
$labels['replacephoto'] = 'Ersetzen';
$labels['uploadphoto'] = 'Foto eroplueden';
-
$labels['newcontact'] = 'Nei Kontakt-Kaart erstellen';
$labels['deletecontact'] = 'Déi ausgewielte Kontakter läschen';
$labels['composeto'] = 'Mail schreiwen un';
@@ -350,42 +311,36 @@ $labels['newcontactgroup'] = 'Nei Kontakt-Grupp erstellen';
$labels['grouprename'] = 'Grupp ëmbenennen';
$labels['groupdelete'] = 'Grupp läschen';
$labels['groupremoveselected'] = 'Ausgewielte Kontakter aus Grupp eraushuele';
-
$labels['previouspage'] = 'Säit virdru weisen';
$labels['firstpage'] = 'Éischt Säit weisen';
$labels['nextpage'] = 'Nächst Säit weisen';
$labels['lastpage'] = 'Lescht Säit weisen';
-
$labels['group'] = 'Grup';
$labels['groups'] = 'Gruppen';
$labels['listgroup'] = 'Gruppe-Memberen oplëschten';
$labels['personaladrbook'] = 'Perséinlech Adressen';
-
$labels['searchsave'] = 'Sich späicheren';
$labels['searchdelete'] = 'Sich läschen';
-
$labels['import'] = 'Importéieren';
$labels['importcontacts'] = 'Kontakter importéieren';
$labels['importfromfile'] = 'Aus Fichier importéieren:';
-$labels['importtarget'] = 'Nei Kontakter an d\'Adressbuch setzen:';
+$labels['importtarget'] = 'Kontakter dobäisetze bei';
$labels['importreplace'] = 'Dat ganzt Adressbuch ersetzen';
+$labels['importgroups'] = 'Gruppen-Zouweisung importéieren';
+$labels['importgroupsall'] = 'All (nei Gruppen uleeën falls néideg)';
+$labels['importgroupsexisting'] = 'Just fir Gruppen déi schon existéieren';
$labels['importdesc'] = 'Du kanns Kontakter aus engem existéierenden Adressbuch eroplueden.<br/>Mir ënnerstëtze momentan en Adress-Import vum <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>- oder CSV (mat Komma getrennt)-Date-Format.';
$labels['done'] = 'Erleedegt';
-
-// settings
$labels['settingsfor'] = 'Astellunge fir';
$labels['about'] = 'Iwwert';
$labels['preferences'] = 'Astellungen';
$labels['userpreferences'] = 'Benotzer-Astellungen';
$labels['editpreferences'] = 'Benotzer-Astellungen änneren';
-
$labels['identities'] = 'Identitéiten';
$labels['manageidentities'] = 'Identitéite fir dësen Account geréieren';
$labels['newidentity'] = 'Nei Identitéit';
-
$labels['newitem'] = 'Neit Element';
$labels['edititem'] = 'Element änneren';
-
$labels['preferhtml'] = 'HTML uweisen';
$labels['defaultcharset'] = 'Standard Zeechesaz';
$labels['htmlmessage'] = 'HTML-Message';
@@ -481,7 +436,6 @@ $labels['standardwindows'] = 'Popup-Fënstere wéi normal Fënstere behandelen';
$labels['forwardmode'] = 'Messagë-Weiderleedung';
$labels['inline'] = 'am Message';
$labels['asattachment'] = 'als Unhank';
-
$labels['folder'] = 'Dossier';
$labels['folders'] = 'Dossieren';
$labels['foldername'] = 'Dossiersnumm';
@@ -502,26 +456,20 @@ $labels['foldertype'] = 'Dossiers-Typ';
$labels['personalfolder'] = 'Privaten Dossier';
$labels['otherfolder'] = 'Dossier vun anerem Benotzer';
$labels['sharedfolder'] = 'Ëffentlechen Dossier';
-
$labels['sortby'] = 'Sortéieren no';
$labels['sortasc'] = 'Opsteigend sortéieren';
$labels['sortdesc'] = 'Ofsteigend sortéieren';
$labels['undo'] = 'Réckgängeg maachen';
-
$labels['installedplugins'] = 'Installéiert Plugins';
$labels['plugin'] = 'Plugin';
$labels['version'] = 'Versioun';
$labels['source'] = 'Source';
$labels['license'] = 'Lizenz';
$labels['support'] = 'Support ufroen';
-
-// units
$labels['B'] = 'B';
$labels['KB'] = 'kB';
$labels['MB'] = 'MB';
$labels['GB'] = 'GB';
-
-// character sets
$labels['unicode'] = 'Unicode';
$labels['english'] = 'Englesch';
$labels['westerneuropean'] = 'West-Europäesch';
@@ -540,5 +488,4 @@ $labels['vietnamese'] = 'Vietnamesesch';
$labels['japanese'] = 'Japanesch';
$labels['korean'] = 'Koreanesch';
$labels['chinese'] = 'Chinesesch';
-
?>
diff --git a/program/localization/lb_LU/messages.inc b/program/localization/lb_LU/messages.inc
index 5599f227b..fc053b59e 100644
--- a/program/localization/lb_LU/messages.inc
+++ b/program/localization/lb_LU/messages.inc
@@ -15,8 +15,6 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/messages/
*/
-
-$messages = array();
$messages['errortitle'] = 'Ee Feeler ass opgetrueden!';
$messages['loginfailed'] = 'Login feelgeschloen.';
$messages['cookiesdisabled'] = 'Däi Browser acceptéiert keng Cookien.';
@@ -46,6 +44,8 @@ $messages['messagesent'] = 'Message erfollegräich verschéckt.';
$messages['savingmessage'] = 'Message gëtt gespäichert...';
$messages['messagesaved'] = 'Message als Brouillon gespäichert.';
$messages['successfullysaved'] = 'Erfollegräich gespäichert.';
+$messages['savingresponse'] = 'Äntwert-Text gëtt gespäichert...';
+$messages['deleteresponseconfirm'] = 'Wëlls du dësen Äntwert-Text wierklech läschen?';
$messages['addedsuccessfully'] = 'Kontakt erfollegräich an d\'Adressbuch gesat.';
$messages['contactexists'] = 'Et existéiert schon e Kontakt mat der selweschter E-Mail-Adress.';
$messages['contactnameexists'] = 'Et existéiert schon e Kontakt mam selweschten Numm.';
@@ -56,7 +56,7 @@ $messages['contactnotfound'] = 'Den ugefrotene Kontakt gouf net fonnt.';
$messages['contactsearchonly'] = 'Gëff e puer Sichbegrëffer a fir Kontakter ze fannen';
$messages['sendingfailed'] = 'De Message konnt net verschéckt ginn.';
$messages['senttooquickly'] = 'Waart wann ech gelift $sec Sekonn(en) bevir s du de Message verschécks. ';
-$messages['errorsavingsent'] = 'Beim Späichere vum verschéckte Message ass e Feeler opgetrueden';
+$messages['errorsavingsent'] = 'Beim Späichere vum geschéckte Message ass e Feeler opgetruden.';
$messages['errorsaving'] = 'Beim Späicheren ass e Feeler opgetrueden.';
$messages['errormoving'] = 'D\'Messagë konnten net verréckelt ginn.';
$messages['errorcopying'] = 'D\'Messagë konnten net kopéiert ginn.';
@@ -172,5 +172,4 @@ $messages['parentnotwritable'] = 'Den Dossier konnt net am ausgewielten Dossier
$messages['messagetoobig'] = 'Den Messagen-Deel ass ze grouss fir verschafft ze ginn.';
$messages['attachmentvalidationerror'] = 'WARNUNG! Dësen Unhank ass verdächteg well den tatsächlechen Typ vum Fichier net mam Typ deen am Message deklaréiert ass iwwertenee stëmmt. Falls du dem Ofsender net traus sollts du den Unhank net am Browser opmaache well e béisaartegen Inhalt enthaale kéint.<br/><br/><em>Erwaart: $expected; fonnt: $detected</em>';
$messages['noscriptwarning'] = 'Warnung: Dëse Webmail brauch JavaScript! Fir de Service benotzen ze kënnen, aktivéier w.e.gl JavaScript an denge Browser-Astellungen.';
-
?>
diff --git a/program/localization/lt_LT/labels.inc b/program/localization/lt_LT/labels.inc
index 31cb44d27..6398a3683 100644
--- a/program/localization/lt_LT/labels.inc
+++ b/program/localization/lt_LT/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'JuodraÅ¡Äiai';
$labels['sent'] = 'Išsiųsti laiškai';
$labels['trash'] = 'Šiukšlinė';
$labels['junk'] = 'Brukalas';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tema';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Sąrašo rodymo veiksena';
$labels['folderactions'] = 'Veiksmai su aplankais…';
$labels['compact'] = 'Suglaudinti';
$labels['empty'] = 'Ištuštinti';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disko naudojimas';
$labels['unknown'] = 'nežinomas';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Atšaukti paiešką';
$labels['searchmod'] = 'Paieškos modifikatoriai';
$labels['msgtext'] = 'Visas laiškas';
$labels['body'] = 'Laiško tekstas';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Atverti naujame lange';
$labels['emlsave'] = 'Parsisiųsti (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Rodyti paskutinį puslapį';
$labels['group'] = 'GrupÄ—';
$labels['groups'] = 'GrupÄ—s';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Asmeniniai adresai';
$labels['searchsave'] = 'Įrašyti kaip radinių aplanką';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Nepaisyti žodžių su skaitmenimis';
$labels['spellcheckignorecaps'] = 'Nepaisyti žodžių vien iš didžiųjų raidžių';
$labels['addtodict'] = 'Įtraukti į žodyną';
$labels['mailtoprotohandler'] = 'Užregistruoti svetainÄ™ kaip dirbanÄiÄ… su „mailto:“ saitais';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Laiškų persiuntimo būdas';
$labels['inline'] = 'kaip citatÄ…';
$labels['asattachment'] = 'kaip priedas';
diff --git a/program/localization/lt_LT/messages.inc b/program/localization/lt_LT/messages.inc
index 7eb31ec3f..df19c291b 100644
--- a/program/localization/lt_LT/messages.inc
+++ b/program/localization/lt_LT/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Šalinamas laiško formatavimas…';
$messages['messageopenerror'] = 'Nepavyko įkelti laiško iš serverio.';
$messages['fileuploaderror'] = 'Nepavyko įkelti failo.';
$messages['filesizeerror'] = 'Įkeltas failas viršija maksimalų leistiną dydį – $size.';
-$messages['copysuccess'] = 'Nukopijuota adresatų: $nr.';
-$messages['movesuccess'] = 'Perkelta adresatų: $nr.';
-$messages['copyerror'] = 'Adresatų nukopijuoti nepavyko.';
-$messages['moveerror'] = 'Adresatų perkelti nepavyko.';
+$messages['copysuccess'] = 'Nukopijuota adresų: $nr.';
+$messages['copyerror'] = 'Adresų nukopijuoti nepavyko.';
$messages['sourceisreadonly'] = 'Šis adresų šaltinis prieinamas tik skaitymui.';
$messages['errorsavingcontact'] = 'Asmens adreso įrašyti nepavyko.';
$messages['movingmessage'] = 'Laiškas(-ai) perkeliamas(-i)…';
$messages['copyingmessage'] = 'Laiškas(-ai) kopijuojamas(-i)…';
$messages['copyingcontact'] = 'Adresatas(-ai) kopijuojamas(-i)…';
-$messages['movingcontact'] = 'Adresatas(-ai) perkeliamas(-i)…';
$messages['deletingmessage'] = 'Laiškas(-ai) šalinamas(-i)…';
$messages['markingmessage'] = 'Laiškas(-ai) žymimas(-i)…';
$messages['addingmember'] = 'Adresatas(-ai) įtraukiamas(-i) į grupę…';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importuojama, prašome palaukti…';
$messages['importformaterror'] = 'Importas nepavyko! Įkeltasis failas nėra tinkamas importavimui duomenų failas.';
$messages['importconfirm'] = '<b>Sėkmingai importuoti $inserted adresatai(-ų)</b>';
$messages['importconfirmskipped'] = '<b>Praleisti $skipped jau egzistuojantys adresatai(-ų)</b>';
-$messages['importmessagesuccess'] = 'Importuota laiškų: $nr';
-$messages['importmessageerror'] = 'Importas nepavyko! Įkeltasis failas nėra tinkamas importavimui laiško arba pašto dėžutės failas';
$messages['opnotpermitted'] = 'Veiksmas neleistinas!';
$messages['nofromaddress'] = 'Nenurodytas pasirinktosios tapatybės el. pašto adresas.';
$messages['editorwarning'] = 'Pereinant į grynojo teksto redagavimą, visas laiško formatavimas bus prarastas. Ar tęsti?';
diff --git a/program/localization/lv_LV/labels.inc b/program/localization/lv_LV/labels.inc
index 0fe5b0faf..7d4de2564 100644
--- a/program/localization/lv_LV/labels.inc
+++ b/program/localization/lv_LV/labels.inc
@@ -23,51 +23,50 @@ $labels['welcome'] = 'Esiet laipni lūgti $product';
$labels['username'] = 'LietotÄjvÄrds';
$labels['password'] = 'Parole';
$labels['server'] = 'Serveris';
-$labels['login'] = 'Autorizēties';
+$labels['login'] = 'Pieslēgties';
// taskbar
-$labels['logout'] = 'Iziet';
+$labels['logout'] = 'Atslēgties';
$labels['mail'] = 'E-pasts';
-$labels['settings'] = 'Iestatījumi';
+$labels['settings'] = 'Personīgie iestatījumi';
$labels['addressbook'] = 'AdreÅ¡u grÄmata';
// mailbox names
$labels['inbox'] = 'IenÄkoÅ¡Äs';
$labels['drafts'] = 'Uzmetumi';
$labels['sent'] = 'NosÅ«tÄ«tÄs';
-$labels['trash'] = 'Papīrgrozs';
+$labels['trash'] = 'Miskaste';
$labels['junk'] = 'MÄ“stules';
-$labels['show_real_foldernames'] = 'SistÄ“mas mapÄ“m rÄdÄ«t Ä«stos nosaukumus';
// message listing
$labels['subject'] = 'Temats';
$labels['from'] = 'No';
-$labels['sender'] = 'SÅ«tÄ«tÄjs';
+$labels['sender'] = 'Sender';
$labels['to'] = 'Kam';
$labels['cc'] = 'Cc';
$labels['bcc'] = 'Bcc';
-$labels['replyto'] = 'Atbildēt-Uz';
-$labels['followupto'] = 'Sekot-Uz';
+$labels['replyto'] = 'Reply-To';
+$labels['followupto'] = 'Followup-To';
$labels['date'] = 'Datums';
$labels['size'] = 'Izmērs';
$labels['priority'] = 'PrioritÄte';
$labels['organization'] = 'Uzņēmums';
$labels['readstatus'] = 'Izlasīšanas statuss';
-$labels['listoptions'] = 'Vēstuļu saraksta attēlošanas iestatījumi...';
+$labels['listoptions'] = 'List options...';
$labels['mailboxlist'] = 'Mapes';
$labels['messagesfromto'] = 'Vēstules $from līdz $to no $count';
$labels['threadsfromto'] = 'Vijumi $from līdz $to no $count';
-$labels['messagenrof'] = '$nr. vēstule no $count';
-$labels['fromtoshort'] = '$from – $to no $count';
+$labels['messagenrof'] = '$nr. vēstule no $count';
+$labels['fromtoshort'] = '$from – $to of $count';
$labels['copy'] = 'Kopēt';
$labels['move'] = 'PÄrvietot';
-$labels['moveto'] = 'PÄrvietot uz...';
+$labels['moveto'] = 'pÄrvietot uz...';
$labels['download'] = 'lejupielÄdÄ“t';
-$labels['open'] = 'Atvērt';
-$labels['showattachment'] = 'RÄdÄ«t';
-$labels['showanyway'] = 'Vienalga rÄdÄ«t';
+$labels['open'] = 'Open';
+$labels['showattachment'] = 'Show';
+$labels['showanyway'] = 'Show it anyway';
$labels['filename'] = 'Faila nosaukums';
$labels['filesize'] = 'Faila izmērs';
@@ -123,78 +122,77 @@ $labels['longdec'] = 'Decembris';
$labels['today'] = 'Å odien';
// toolbar buttons
-$labels['refresh'] = 'Atjaunot';
-$labels['checkmail'] = 'PÄrbaudÄ«t e-pastu';
+$labels['refresh'] = 'Refresh';
+$labels['checkmail'] = 'PÄrbaudÄ«t pastu';
$labels['compose'] = 'Rakstīt vēstuli';
$labels['writenewmessage'] = 'Rakstīt jaunu vēstuli';
-$labels['reply'] = 'Atbildēt';
-$labels['replytomessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam';
-$labels['replytoallmessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam vai listei un visiem adresÄtiem';
+$labels['reply'] = 'Reply';
+$labels['replytomessage'] = 'Atbildēt';
+$labels['replytoallmessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam un visiem saņēmÄ“jiem';
$labels['replyall'] = 'Atbildēt visiem';
$labels['replylist'] = 'Atbildēt listei';
-$labels['forward'] = 'PÄrsÅ«tÄ«t';
+$labels['forward'] = 'Forward';
$labels['forwardinline'] = 'PÄrsÅ«tÄ«t iekļaujot vÄ“stulÄ“';
$labels['forwardattachment'] = 'PÄrsÅ«tÄ«t kÄ pielikumu';
$labels['forwardmessage'] = 'PÄrsÅ«tÄ«t vÄ“stuli';
$labels['deletemessage'] = 'Dzēst vēstuli';
-$labels['movemessagetotrash'] = 'PÄrvietot vÄ“stuli uz papÄ«rgrozu';
-$labels['printmessage'] = 'IzdrukÄt Å¡o vÄ“stuli';
+$labels['movemessagetotrash'] = 'PÄrvietot vÄ“stuli uz miskasti';
+$labels['printmessage'] = 'izdrukÄt';
$labels['previousmessage'] = 'ParÄdÄ«t iepriekÅ¡Ä“jo vÄ“stuli';
$labels['firstmessage'] = 'ParÄdÄ«t pirmo vÄ“stuli';
$labels['nextmessage'] = 'ParÄdÄ«t nÄkamo vÄ“stuli';
$labels['lastmessage'] = 'ParÄdÄ«t pÄ“dÄ“jo vÄ“stuli';
$labels['backtolist'] = 'Atpakaļ uz vēstuļu sarakstu';
-$labels['viewsource'] = 'ParÄdÄ«t pirmtekstu';
-$labels['mark'] = 'Atzīmēt';
-$labels['markmessages'] = 'AtzÄ«mÄ“t vÄ“stules kÄ:';
-$labels['markread'] = 'KÄ lasÄ«tas';
-$labels['markunread'] = 'KÄ nelasÄ«tas';
-$labels['markflagged'] = 'KÄ atÄ«mÄ“tas';
-$labels['markunflagged'] = 'KÄ neatzÄ«mÄ“tas';
-$labels['moreactions'] = 'Papildus darbības...';
-$labels['more'] = 'VairÄk';
-$labels['back'] = 'Atpakaļ';
-$labels['options'] = 'Opcijas';
-
-$labels['select'] = 'Atzīmēt';
-$labels['all'] = 'Visas';
-$labels['none'] = 'Nevienu';
+$labels['viewsource'] = 'parÄdÄ«t pirmtekstu';
+$labels['mark'] = 'Mark';
+$labels['markmessages'] = 'MarÄ·Ä“t vÄ“stules kÄ:';
+$labels['markread'] = 'lasītas';
+$labels['markunread'] = 'nelasītas';
+$labels['markflagged'] = 'iezīmētas';
+$labels['markunflagged'] = 'neiezīmētas';
+$labels['moreactions'] = 'Citas darbības...';
+$labels['more'] = 'More';
+$labels['back'] = 'Back';
+$labels['options'] = 'Options';
+
+$labels['select'] = 'Iezīmēt';
+$labels['all'] = 'visas';
+$labels['none'] = 'Neviens';
$labels['currpage'] = 'PaÅ¡reizÄ“jÄ lapa';
-$labels['unread'] = 'NelasÄ«tÄs';
-$labels['flagged'] = 'AtzÄ«mÄ“tÄs';
-$labels['unanswered'] = 'NeatbildÄ“tÄs';
-$labels['withattachment'] = 'Ar pielikumu';
-$labels['deleted'] = 'DzÄ“stÄs';
-$labels['undeleted'] = 'Nav izdzēstas';
-$labels['invert'] = 'Pretēji';
+$labels['unread'] = 'nelasÄ«tÄs';
+$labels['flagged'] = 'iezÄ«mÄ“tÄs';
+$labels['unanswered'] = 'neatbildÄ“tÄs';
+$labels['withattachment'] = 'With attachment';
+$labels['deleted'] = 'dzÄ“stÄs';
+$labels['undeleted'] = 'Not deleted';
+$labels['invert'] = 'invertēt';
$labels['filter'] = 'Filtrēt';
-$labels['list'] = 'RÄdÄ«t kÄ sarakstu';
-$labels['threads'] = 'RÄdÄ«t kÄ vijumus';
+$labels['list'] = 'Saraksts';
+$labels['threads'] = 'Vijumi';
$labels['expand-all'] = 'Izvērst visus';
-$labels['expand-unread'] = 'IzvÄ“rst neizlasÄ«tÄs';
-$labels['collapse-all'] = 'Sakļaut visas';
-$labels['threaded'] = 'RÄdÄ«t vijumus';
+$labels['expand-unread'] = 'Izvērst neizlasītos';
+$labels['collapse-all'] = 'Savērst visu';
+$labels['threaded'] = 'Savīts';
$labels['autoexpand_threads'] = 'Izvērst vēstuļu vijumus';
-$labels['do_expand'] = 'visus vijumus';
-$labels['expand_only_unread'] = 'tikai ar neizlasÄ«tÄm vÄ“stulÄ“m';
-$labels['fromto'] = 'No/Kam';
-$labels['flag'] = 'Atzīmēt';
+$labels['do_expand'] = 'visiem vijumiem';
+$labels['expand_only_unread'] = 'tikai tad, ja ir neizlasītas vēstules';
+$labels['fromto'] = 'SÅ«tÄ«tÄjs/SaņēmÄ“js';
+$labels['flag'] = 'Iezīmēts';
$labels['attachment'] = 'Pielikums';
-$labels['nonesort'] = 'Neviena';
+$labels['nonesort'] = 'Neviens';
$labels['sentdate'] = 'Nosūtīšanas datums';
$labels['arrival'] = 'PienÄkÅ¡anas datums';
$labels['asc'] = 'augoša';
$labels['desc'] = 'dilstoša';
$labels['listcolumns'] = 'Saraksta kolonnas';
-$labels['listsorting'] = 'KÄrtoÅ¡anas kolonnas';
+$labels['listsorting'] = 'KÄrtot pÄ“c kolonnas';
$labels['listorder'] = 'KÄrtoÅ¡anas secÄ«ba';
-$labels['listmode'] = 'Attēlošanas veids';
+$labels['listmode'] = 'Saraksta režīms';
$labels['folderactions'] = 'Darbības ar mapēm...';
-$labels['compact'] = 'Saspiest';
-$labels['empty'] = 'Iztukšot';
-$labels['importmessages'] = 'Importēt vēstules';
+$labels['compact'] = 'saspiest';
+$labels['empty'] = 'iztukšot';
$labels['quota'] = 'Kvota';
$labels['unknown'] = 'nezinÄms';
@@ -202,36 +200,35 @@ $labels['unlimited'] = 'neierobežots';
$labels['quicksearch'] = 'Ä€rtÄ meklÄ“Å¡ana';
$labels['resetsearch'] = 'Atstatīt meklēšanu';
-$labels['searchmod'] = 'Meklēšanas modifikatori:';
-$labels['msgtext'] = 'VisÄ vÄ“stulÄ“';
-$labels['body'] = 'Pamatteksts';
-$labels['type'] = 'Tips';
+$labels['searchmod'] = 'Meklēt laukos:';
+$labels['msgtext'] = 'VÄ“stules tekstÄ';
+$labels['body'] = 'Body';
-$labels['openinextwin'] = 'AtvÄ“rt jaunÄ logÄ';
+$labels['openinextwin'] = 'atvÄ“rt jaunÄ logÄ';
$labels['emlsave'] = 'lejupielÄdÄ“t (.eml)';
-$labels['changeformattext'] = 'RÄdÄ«t kÄ neformatÄ“tu tekstu';
-$labels['changeformathtml'] = 'RÄdÄ«t kÄ HTML formatÄ“tu';
+$labels['changeformattext'] = 'Display in plain text format';
+$labels['changeformathtml'] = 'Display in HTML format';
// message compose
-$labels['editasnew'] = 'Rediģēt kÄ jaunu';
-$labels['send'] = 'Sūtīt';
+$labels['editasnew'] = 'rediģēt kÄ jaunu';
+$labels['send'] = 'Send';
$labels['sendmessage'] = 'Sūtīt vēstuli';
-$labels['savemessage'] = 'SaglabÄt kÄ uzmetumu';
+$labels['savemessage'] = 'SaglabÄt uzmetumu';
$labels['addattachment'] = 'Pievienot failu';
$labels['charset'] = 'Rakstzīmju kopa';
$labels['editortype'] = 'Redaktora tips';
$labels['returnreceipt'] = 'SaņemÅ¡anas apstiprinÄjums';
-$labels['dsn'] = 'PiegÄdes atskaite';
+$labels['dsn'] = 'Atskaite par piegÄdi';
$labels['mailreplyintro'] = '$sender @ $date rakstīja:';
$labels['originalmessage'] = 'SÄkotnÄ“jÄ vÄ“stule';
$labels['editidents'] = 'Rediģēt identitÄtes';
-$labels['spellcheck'] = 'IzrunÄt';
+$labels['spellcheck'] = 'Spell';
$labels['checkspelling'] = 'PÄrbaudÄ«t pareizrakstÄ«bu';
$labels['resumeediting'] = 'TurpinÄt rediģēšanu';
$labels['revertto'] = 'Atgriezt uz';
-$labels['attach'] = 'Pievienot';
+$labels['attach'] = 'Attach';
$labels['attachments'] = 'Pielikumi';
$labels['upload'] = 'AugÅ¡upielÄdÄ“t';
$labels['uploadprogress'] = '$percent ($current no $total)';
@@ -244,13 +241,13 @@ $labels['normal'] = 'NormÄla';
$labels['high'] = 'Augsta';
$labels['highest'] = 'AugstÄkÄ';
-$labels['nosubject'] = '(bez tēmas)';
+$labels['nosubject'] = '(no subject)';
$labels['showimages'] = 'RÄdÄ«t attÄ“lus';
-$labels['alwaysshow'] = 'VienmÄ“r rÄdÄ«t attÄ“lus vÄ“stulÄ“s, kuras sÅ«tÄ«jis $sender';
+$labels['alwaysshow'] = 'VienmÄ“r rÄdÄ«t attÄ“lus no $sender';
$labels['isdraft'] = 'Å is ir melnraksts.';
-$labels['andnmore'] = '$nr vairÄk...';
-$labels['togglemoreheaders'] = 'RÄdÄ«t galvenes papildus informÄciju';
-$labels['togglefullheaders'] = 'SlÄ“pt galvenes papildus informÄciju';
+$labels['andnmore'] = '$nr more...';
+$labels['togglemoreheaders'] = 'Show more message headers';
+$labels['togglefullheaders'] = 'Toggle raw message headers';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'VienkÄrÅ¡s teksts';
@@ -260,14 +257,14 @@ $labels['maxuploadsize'] = 'MaksimÄlais atļautais faila izmÄ“rs ir $size';
$labels['addcc'] = 'Pievienot Cc';
$labels['addbcc'] = 'Pievienot Bcc';
-$labels['addreplyto'] = 'Pievienot Atbildēt-Uz';
+$labels['addreplyto'] = 'Pievienot Reply-To';
$labels['addfollowupto'] = 'Pievienot Followup-To';
// mdn
-$labels['mdnrequest'] = 'Å Ä«s vÄ“stules sÅ«tÄ«tÄjs vÄ“las redzÄ“t vÄ“stules saņemÅ¡anas apstiprinÄjumu. Vai JÅ«s vÄ“laties nosÅ«tÄ«t Å¡o apstiprinÄjumu?';
+$labels['mdnrequest'] = 'Å Ä«s vÄ“stules sÅ«tÄ«tÄjs vÄ“las redzÄ“t vÄ“stules saņemÅ¡anas apstiprinÄjumu. Vai jÅ«s vÄ“laties nosÅ«tÄ«t apstiprinÄjumu?';
$labels['receiptread'] = 'SaņemÅ¡anas apstiprinÄjums';
-$labels['yourmessage'] = 'Å is ir JÅ«su nosÅ«tÄ«tÄs vÄ“stules saņemÅ¡anas apstiprinÄjums';
-$labels['receiptnote'] = 'PiezÄ«me: Å is apsiprinÄjums nozÄ«mÄ“ tikai to, ka vÄ“stule tika parÄdÄ«ta uz saņēmÄja datora. Tas nenozÄ«mÄ“, ka saņēmÄ“js ir izlasÄ«jis vai sapratis vÄ“stules saturu.';
+$labels['yourmessage'] = 'Å Ä«s ir jÅ«su vÄ“stules saņemÅ¡anas apstiprinÄjums';
+$labels['receiptnote'] = 'PiezÄ«me: Å Ä«s apsiprinÄjums nozÄ«mÄ“ tikai to, ka vÄ“stule tika parÄdÄ«ta uz saņēmÄja datora. Tas nenozÄ«mÄ“, ka saņēmÄ“js ir izlasÄ«jis vai izpratis vÄ“stules saturu.';
// address boook
$labels['name'] = 'UzrÄdÄ«tais vÄrds';
@@ -276,33 +273,33 @@ $labels['surname'] = 'UzvÄrds';
$labels['middlename'] = 'Otrais vÄrds';
$labels['nameprefix'] = 'Prefikss';
$labels['namesuffix'] = 'Sufikss';
-$labels['nickname'] = 'SegvÄrds';
+$labels['nickname'] = 'Iesauka (nick)';
$labels['jobtitle'] = 'Amats';
$labels['department'] = 'Nodaļa';
$labels['gender'] = 'Dzimums';
-$labels['maidenname'] = 'PirmslaulÄ«bas uzvÄrds';
+$labels['maidenname'] = 'PirmslaulÄ«bu uzvÄrds';
$labels['email'] = 'E-pasts';
$labels['phone'] = 'TÄlrunis';
$labels['address'] = 'Adrese';
$labels['street'] = 'Iela';
$labels['locality'] = 'Pilsēta';
-$labels['zipcode'] = 'Pasta indekss';
+$labels['zipcode'] = 'Pasta kods';
$labels['region'] = 'Novads';
$labels['country'] = 'Pilsēta';
$labels['birthday'] = 'Dzimšanas diena';
$labels['anniversary'] = 'Gadadiena';
-$labels['website'] = 'MÄjaslapa';
+$labels['website'] = 'Web lapa';
$labels['instantmessenger'] = 'IM';
$labels['notes'] = 'Piezīmes';
$labels['male'] = 'vīrietis';
$labels['female'] = 'sieviete';
$labels['manager'] = 'Menedžeris';
$labels['assistant'] = 'Asistents';
-$labels['spouse'] = 'LaulÄtais';
+$labels['spouse'] = 'LaulÄtais draugs';
$labels['allfields'] = 'Visi lauki';
$labels['search'] = 'Meklēt';
$labels['advsearch'] = 'PaplaÅ¡inÄtÄ meklÄ“Å¡ana';
-$labels['advanced'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
+$labels['advanced'] = 'Advanced';
$labels['other'] = 'Cits';
$labels['typehome'] = 'MÄjas';
@@ -310,22 +307,22 @@ $labels['typework'] = 'Darbs';
$labels['typeother'] = 'Cits';
$labels['typemobile'] = 'Mobilais tÄlrunis';
$labels['typemain'] = 'Galvenais';
-$labels['typehomefax'] = 'Fakss mÄjÄs';
-$labels['typeworkfax'] = 'Fakss darbÄ';
+$labels['typehomefax'] = 'MÄjas Fax';
+$labels['typeworkfax'] = 'Darba Fax';
$labels['typecar'] = 'Auto';
$labels['typepager'] = 'Peidžeris';
$labels['typevideo'] = 'Video';
$labels['typeassistant'] = 'Asistents';
-$labels['typehomepage'] = 'MÄjaslapa';
+$labels['typehomepage'] = 'Web lapa';
$labels['typeblog'] = 'Blogs';
$labels['typeprofile'] = 'Profils';
$labels['addfield'] = 'Pievienot lauku...';
-$labels['addcontact'] = 'Pievienot jaunu kontaktu';
-$labels['editcontact'] = 'Rediģēt kontaktu';
+$labels['addcontact'] = 'Pievienot iezÄ«mÄ“to ierakstu adreÅ¡u grÄmatai';
+$labels['editcontact'] = 'Rediģēt adreÅ¡u grÄmatas ierakstu';
$labels['contacts'] = 'Kontakti';
$labels['contactproperties'] = 'Kontakta īpašības';
-$labels['personalinfo'] = 'PersonÄ«gÄ informÄcija';
+$labels['personalinfo'] = 'PersoniskÄ informÄcija';
$labels['edit'] = 'Rediģēt';
$labels['cancel'] = 'Atcelt';
@@ -334,30 +331,29 @@ $labels['delete'] = 'Dzēst';
$labels['rename'] = 'PÄrdÄ“vÄ“t';
$labels['addphoto'] = 'Pievienot';
$labels['replacephoto'] = 'Aizvietot';
-$labels['uploadphoto'] = 'AugÅ¡upielÄdÄ“t fotogrÄfiju';
+$labels['uploadphoto'] = 'Upload photo';
-$labels['newcontact'] = 'Izveidot jaunu kontaktu';
-$labels['deletecontact'] = 'Dzēst atzīmētos kontaktus';
+$labels['newcontact'] = 'Izveidot jaunu ierakstu';
+$labels['deletecontact'] = 'Dzēst iezīmētos ierakstus';
$labels['composeto'] = 'Rakstīt vēstuli';
-$labels['contactsfromto'] = 'Ieraksti no $from lÄ«dz $to - kopÄ $count';
+$labels['contactsfromto'] = 'Ieraksti $from līdz $to no $count';
$labels['print'] = 'DrukÄt';
$labels['export'] = 'Eksportēt';
-$labels['exportall'] = 'Eksportēt visu';
-$labels['exportsel'] = 'Eksportēt atzīmēto';
+$labels['exportall'] = 'Export all';
+$labels['exportsel'] = 'Export selected';
$labels['exportvcards'] = 'EksportÄ“t kontaktus vCard formÄtÄ';
$labels['newcontactgroup'] = 'Izveidot jaunu kontaktu grupu';
$labels['grouprename'] = 'PÄrdÄ“vÄ“t grupu';
$labels['groupdelete'] = 'Izdzēst grupu';
-$labels['groupremoveselected'] = 'Dzēst atzīmētos kontaktus no grupas';
+$labels['groupremoveselected'] = 'Remove selected contacts from group';
-$labels['previouspage'] = 'ParÄdÄ«t iepriekÅ¡Ä“jo lapu';
-$labels['firstpage'] = 'ParÄdÄ«t pirmo lapu';
-$labels['nextpage'] = 'ParÄdÄ«t nÄkamo lapu';
-$labels['lastpage'] = 'ParÄdÄ«t pÄ“dÄ“jo lapu';
+$labels['previouspage'] = 'ParÄdÄ«t iepriekÅ¡Ä“jo kopu';
+$labels['firstpage'] = 'ParÄdÄ«t pirmo kopu';
+$labels['nextpage'] = 'ParÄdÄ«t nÄkamo kopu';
+$labels['lastpage'] = 'ParÄdÄ«t pÄ“dÄ“jo kopu';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupas';
-$labels['listgroup'] = 'RÄdÄ«t grupas kontaktus';
$labels['personaladrbook'] = 'PersonÄ«gÄs adreses';
$labels['searchsave'] = 'SaglabÄt meklÄ“Å¡anas pieprasÄ«jumu';
@@ -366,72 +362,72 @@ $labels['searchdelete'] = 'DzÄ“st saglabÄto meklÄ“Å¡anas pieprasÄ«jumu';
$labels['import'] = 'Importēt';
$labels['importcontacts'] = 'Importēt kontaktus';
$labels['importfromfile'] = 'Importēt no faila:';
-$labels['importtarget'] = 'Pievienot jaunus kontaktus adreÅ¡u grÄmatai:';
+$labels['importtarget'] = 'Pievienot jaunus kontaktus adreÅ¡u grÄmatai';
$labels['importreplace'] = 'Aizvietot visu adreÅ¡u grÄmatu';
-$labels['importdesc'] = 'JÅ«s varat ieimportÄ“t kontaktus no jau esoÅ¡as adreÅ¡u grÄmatas.<br/>Uz doto brÄ«di tiek atbalstÄ«ti <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> vai CSV (ar komatu atdalÄ«tie) datu formÄti.';
+$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'] = 'Pabeigts';
// settings
$labels['settingsfor'] = 'Iestatījumi';
$labels['about'] = 'Par';
$labels['preferences'] = 'Iestatījumi';
-$labels['userpreferences'] = 'LietotÄja iestatÄ«jumi';
-$labels['editpreferences'] = 'Rediģēt iestatījumus';
+$labels['userpreferences'] = 'LietotÄja preferences';
+$labels['editpreferences'] = 'Rediģēt lietotÄja preferences';
$labels['identities'] = 'IdentitÄtes';
-$labels['manageidentities'] = 'Rediģēt identitÄtes';
+$labels['manageidentities'] = 'Rediģēt Å¡Ä« konta identitÄtes';
$labels['newidentity'] = 'Jauna identitÄte';
$labels['newitem'] = 'Jauns';
$labels['edititem'] = 'Rediģēt';
-$labels['preferhtml'] = 'RÄdÄ«t HTML formatÄ“tÄs vÄ“stules';
+$labels['preferhtml'] = 'Dot priekÅ¡roku HTML formatÄ“tÄm vÄ“stulÄ“m';
$labels['defaultcharset'] = 'NoklusÄ“tÄ rakstzÄ«mju kopa';
-$labels['htmlmessage'] = 'HTML formatēta vēstule';
-$labels['messagepart'] = 'Daļa';
-$labels['digitalsig'] = 'DigitÄlais paraksts';
+$labels['htmlmessage'] = 'HTML vēstule';
+$labels['messagepart'] = 'Part';
+$labels['digitalsig'] = 'Digital Signature';
$labels['dateformat'] = 'Datuma formÄts';
$labels['timeformat'] = 'Laika formÄts';
-$labels['prettydate'] = 'RÄdÄ«t Ä«sos datumus';
+$labels['prettydate'] = 'Formatēt datumus';
$labels['setdefault'] = 'Uzlikt kÄ noklusÄ“to';
-$labels['autodetect'] = 'AutomÄtiska';
+$labels['autodetect'] = 'AutomÄtiski';
$labels['language'] = 'Valoda';
$labels['timezone'] = 'Laika zona';
$labels['pagesize'] = 'Rindas lapÄ';
$labels['signature'] = 'Paraksts';
$labels['dstactive'] = 'Vasaras/ziemas laiks';
-$labels['showinextwin'] = 'VÄ“stules atvÄ“rt jaunÄ logÄ';
-$labels['composeextwin'] = 'VÄ“stuli rakstÄ«t jaunÄ logÄ';
-$labels['htmleditor'] = 'Rakstīt HTML formatētas vēstules';
+$labels['showinextwin'] = 'Open message in a new window';
+$labels['composeextwin'] = 'Compose in a new window';
+$labels['htmleditor'] = 'Rakstīt HTML vēstules';
$labels['htmlonreply'] = 'tikai atbildot uz HTML formatÄ“tÄm vÄ“stulÄ“m';
-$labels['htmlonreplyandforward'] = 'tikai pÄrsÅ«tot vai atbildot uz HTML formatÄ“tu vÄ“stuli';
-$labels['htmlsignature'] = 'HTML formatēts paraksts';
-$labels['showemail'] = 'Pie vÄrda rÄdÄ«t arÄ« e-pasta adresi';
+$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
+$labels['htmlsignature'] = 'HTML paraksts';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'RÄdÄ«t priekÅ¡skatÄ«juma paneli';
-$labels['skin'] = 'Saskarnes izskats';
-$labels['logoutclear'] = 'Izejot no e-pasta, iztīrīt papīrgrozu';
-$labels['logoutcompact'] = 'Izejot no e-pasta, saspiest iesūtni';
+$labels['skin'] = 'Interfeisa izskats';
+$labels['logoutclear'] = 'Izejot no sistēmas, iztīrīt miskasti';
+$labels['logoutcompact'] = 'Izejot no sistēmas, saspiest iesūtni';
$labels['uisettings'] = 'LietotÄja saskarne';
$labels['serversettings'] = 'Servera iestatījumi';
$labels['mailboxview'] = 'Pastkastes skats';
$labels['mdnrequests'] = 'Vēstules izlasīšanas atskaites sūtīšana';
-$labels['askuser'] = 'jautÄt man vai sÅ«tÄ«t';
+$labels['askuser'] = 'jautÄt lietotÄjam';
$labels['autosend'] = 'sÅ«tÄ«t automÄtiski';
-$labels['autosendknown'] = 'automÄtiski sÅ«tÄ«t ja pieprasÄ«tÄjs ir manos kontaktos, par citiem jautÄt';
-$labels['autosendknownignore'] = 'automÄtiski sÅ«tÄ«t ja pieprasÄ«tÄjs ir manos kontaktos, citiem ignorÄ“t un nesÅ«tÄ«t';
-$labels['ignore'] = 'ignorēt un nesūtīt';
-$labels['readwhendeleted'] = 'DzÄ“Å¡ot vÄ“stules tÄs atzÄ«mÄ“t kÄ izlasÄ«tas';
-$labels['flagfordeletion'] = 'DzÄ“Å¡ot vÄ“stules tÄs nedzÄ“st, bet marÄ·Ä“t kÄ dzÄ“Å¡amas';
+$labels['autosendknown'] = 'automÄtiski sÅ«tÄ«t maniem kontaktiem, par citiem jautÄt';
+$labels['autosendknownignore'] = 'automÄtiski sÅ«tÄ«t maniem kontaktiem, citiem nesÅ«tÄ«t';
+$labels['ignore'] = 'ignorēt';
+$labels['readwhendeleted'] = 'AtzÄ«mÄ“t dzÄ“stÄs vÄ“stules kÄ izlasÄ«tas';
+$labels['flagfordeletion'] = 'DzÄ“Å¡ot marÄ·Ä“t vÄ“stules kÄ dzÄ“stas, bet nedzÄ“st';
$labels['skipdeleted'] = 'NerÄdÄ«t dzÄ“stÄs vÄ“stules';
-$labels['deletealways'] = 'IzdzÄ“st vÄ“stules, ja tÄs neizdodas pÄrvietot uz papÄ«rgrozu';
-$labels['deletejunk'] = 'AutomÄtiski dzÄ“st vÄ“stules no mÄ“stuļu mapÄ«tes';
-$labels['showremoteimages'] = 'RÄdÄ«t vÄ“stulÄ“s attÄ“lus, kuri atrodas uz cita servera';
-$labels['fromknownsenders'] = 'tikai no zinÄmiem sÅ«tÄ«tÄjiem';
+$labels['deletealways'] = 'IzdzÄ“st vÄ“stules, ja tÄs neizdodas pÄrvietot uz miskasti';
+$labels['deletejunk'] = 'Directly delete messages in Junk';
+$labels['showremoteimages'] = 'RÄdÄ«t attÄ“lus, kas atrodas uz cita servera';
+$labels['fromknownsenders'] = 'no zinÄmiem sÅ«tÄ«tÄjiem';
$labels['always'] = 'vienmēr';
$labels['showinlineimages'] = 'RÄdÄ«t pielikuma attÄ“lus zem vÄ“stules';
-$labels['autosavedraft'] = 'AutomÄtiski saglabÄt vÄ“stules uzmetumu';
-$labels['everynminutes'] = 'ik pēc $n minūtes(ēm)';
-$labels['refreshinterval'] = 'PÄrbaudÄ«t jaunÄs vÄ“stules';
+$labels['autosavedraft'] = 'AutomÄtiski saglabÄt uzmetumu';
+$labels['everynminutes'] = 'ik pa $n minūti(ēm)';
+$labels['refreshinterval'] = 'Refresh (check for new messages, etc.)';
$labels['never'] = 'nekad';
$labels['immediately'] = 'nekavējoties';
$labels['messagesdisplaying'] = 'Vēstuļu attēlošana';
@@ -441,45 +437,44 @@ $labels['2231folding'] = 'Pilns RFC 2231 (Thunderbird)';
$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
$labels['2047folding'] = 'Pilns RFC 2047 (citi)';
$labels['force7bit'] = 'Izmantot MIME kodējumu 8-bitu simboliem';
-$labels['advancedoptions'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
-$labels['focusonnewmessage'] = 'UzstÄdÄ«t pÄrlÅ«ka fokusu uz jaunu vÄ“stuli';
-$labels['checkallfolders'] = 'MeklÄ“t visÄs mapÄ“s jaunÄs vÄ“stules';
-$labels['displaynext'] = 'PÄ“c vÄ“stules dzÄ“Å¡anas/pÄrvietoÅ¡anas rÄdÄ«t nÄkamo vÄ“stuli';
-$labels['defaultfont'] = 'NoklusÄ“tais fonts vÄ“stulÄ“m HTML formÄtÄ';
+$labels['advancedoptions'] = 'PaplaÅ¡inÄti iestatÄ«jumi';
+$labels['focusonnewmessage'] = 'UztÄdÄ«t pÄrlÅ«ka fokusu uz jaunu vÄ“stuli';
+$labels['checkallfolders'] = 'PÄrbaudÄ«t visas mapes pÄ“c jaunÄm vÄ“stulÄ“m';
+$labels['displaynext'] = 'RÄdÄ«t nÄkamo vÄ“stuli pÄ“c dzÄ“Å¡anas/pÄrvietoÅ¡anas';
+$labels['defaultfont'] = 'NoklusÄ“tais fonts vÄ“stulei HTML formÄtÄ';
$labels['mainoptions'] = 'Galvenie iestatījumi';
-$labels['browseroptions'] = 'PÄrlÅ«ka iestatÄ«jumi';
-$labels['section'] = 'Sadaļa';
+$labels['browseroptions'] = 'Browser Options';
+$labels['section'] = 'Kategorija';
$labels['maintenance'] = 'Uzturēšana';
$labels['newmessage'] = 'VÄ“stuļu pienÄkÅ¡ana';
$labels['signatureoptions'] = 'Paraksta iestatījumi';
$labels['whenreplying'] = 'Atbildot';
-$labels['replyempty'] = 'neiekļaut vÄ“stules sÄkotnÄ“jo tekstu';
+$labels['replyempty'] = 'do not quote the original message';
$labels['replytopposting'] = 'sÄkt jaunu vÄ“stuli virs oriÄ£inÄla';
$labels['replybottomposting'] = 'sÄkt jaunu vÄ“stuli zem oriÄ£inÄla';
$labels['replyremovesignature'] = 'Atbildot izņemt oriÄ£inÄlo parakstu no vÄ“stules';
$labels['autoaddsignature'] = 'AutomÄtiski pievienot parakstu';
-$labels['newmessageonly'] = 'tikai jaunÄm vÄ“stulÄ“m';
-$labels['replyandforwardonly'] = 'tikai atbildÄ“m un pÄrsÅ«tÄ«jumiem';
+$labels['newmessageonly'] = 'tikai jaunas vēstules';
+$labels['replyandforwardonly'] = 'tikai atbildes un pÄrsÅ«tÄ«jumi';
$labels['insertsignature'] = 'Ievietot parakstu';
$labels['previewpanemarkread'] = 'AtzÄ«mÄ“t priekÅ¡skatÄ«tÄs vÄ“stules kÄ lasÄ«tas';
$labels['afternseconds'] = 'pēc $n sekundēm';
-$labels['reqmdn'] = 'VienmÄ“r pieprasÄ«t saņemÅ¡anas apstiprinÄjumu';
-$labels['reqdsn'] = 'VienmÄ“r pieprasÄ«t atskati par piegÄdi';
+$labels['reqmdn'] = 'Vienmēr pieprasīt atskati par vēstules izlasīšanu';
+$labels['reqdsn'] = 'VienmÄ“r pieprasÄ«t atskati par vÄ“stules piegÄdÄÅ¡anu saņēmÄ“ja serverim';
$labels['replysamefolder'] = 'GlabÄt atbildes tajÄ paÅ¡Ä mapÄ“, kurÄ ir vÄ“stule, uz kuru tika atbildÄ“ts';
-$labels['defaultabook'] = 'NoklusÄ“tÄ adreÅ¡u grÄmata';
-$labels['autocompletesingle'] = 'AutomÄtiski aizpildot, nerÄdÄ«t alternatÄ«vÄs e-pasta adreses';
-$labels['listnamedisplay'] = 'RÄdÄ«t kontaktus kÄ';
-$labels['spellcheckbeforesend'] = 'Pirms vÄ“stules nosÅ«tÄ«Å¡anas pÄrbaudÄ«t pareizrakstÄ«bu';
+$labels['defaultabook'] = 'Default address book';
+$labels['autocompletesingle'] = 'AutomÄtiski aizpildot, izlaist alternatÄ«vÄs e-pasta adreses';
+$labels['listnamedisplay'] = 'List contacts as';
+$labels['spellcheckbeforesend'] = 'PÄrbaudÄ«t pareizrakstÄ«bu pirms vÄ“stules nosÅ«tÄ«Å¡anas';
$labels['spellcheckoptions'] = 'Pareizrakstības iestatījumi';
$labels['spellcheckignoresyms'] = 'IgnorÄ“t vÄrdus, kuri satur simbolus';
$labels['spellcheckignorenums'] = 'IgnorÄ“t vÄrdus, kuri satur skaitļus';
$labels['spellcheckignorecaps'] = 'IgnorÄ“t vÄrdus, kuri rakstÄ«ti ar lielajiem burtiem';
$labels['addtodict'] = 'Pievienot vÄrdnÄ«cai';
-$labels['mailtoprotohandler'] = 'Atverot mailto: saites, lietot Å¡o e-pasta programmu';
-$labels['standardwindows'] = 'IzlÄ“coÅ¡ie logi kÄ parasti logi';
-$labels['forwardmode'] = 'VÄ“stuļu pÄrsÅ«tÄ«Å¡ana';
-$labels['inline'] = 'iekļaujot';
-$labels['asattachment'] = 'kÄ pielikumu';
+$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['forwardmode'] = 'Messages forwarding';
+$labels['inline'] = 'inline';
+$labels['asattachment'] = 'as attachment';
$labels['folder'] = 'Mapi';
$labels['folders'] = 'Mapes';
@@ -496,8 +491,8 @@ $labels['parentfolder'] = 'Virsmape';
$labels['location'] = 'AtraÅ¡anÄs vieta';
$labels['info'] = 'InformÄcija';
$labels['getfoldersize'] = 'UzklikÅ¡Ä·iniet, lai uzzinÄtu mapes izmÄ“ru';
-$labels['changesubscription'] = 'Uzklikšķiniet, lai mainītu abonēšanas iestatījumus';
-$labels['foldertype'] = 'Mapes tips';
+$labels['changesubscription'] = 'Uzklikšķiniet, lai mainītu abonēšanu';
+$labels['foldertype'] = 'Mapes veids';
$labels['personalfolder'] = 'PrivÄta mape';
$labels['otherfolder'] = 'Cita lietotÄja mape';
$labels['sharedfolder'] = 'Publiska mape';
@@ -507,7 +502,7 @@ $labels['sortasc'] = 'KÄrtot augoÅ¡Ä secÄ«bÄ';
$labels['sortdesc'] = 'KÄrtot dilstoÅ¡Ä secÄ«bÄ';
$labels['undo'] = 'Atsaukt';
-$labels['installedplugins'] = 'UzstÄdÄ«tie spraudņi';
+$labels['installedplugins'] = 'Installed plugins';
$labels['plugin'] = 'Spraudnis';
$labels['version'] = 'Versija';
$labels['source'] = 'OriÄ£inÄls';
@@ -521,7 +516,7 @@ $labels['MB'] = 'MB';
$labels['GB'] = 'GB';
// character sets
-$labels['unicode'] = 'Unikods';
+$labels['unicode'] = 'Unikoda';
$labels['english'] = 'Angļu';
$labels['westerneuropean'] = 'Rietumeiropas';
$labels['easterneuropean'] = 'Austrumeiropas';
diff --git a/program/localization/lv_LV/messages.inc b/program/localization/lv_LV/messages.inc
index 37ceb0463..b69a73e2b 100644
--- a/program/localization/lv_LV/messages.inc
+++ b/program/localization/lv_LV/messages.inc
@@ -28,7 +28,7 @@ $messages['dberror'] = 'DatubÄzes kļūda!';
$messages['requesttimedout'] = 'PieprasÄ«jumam iestÄjÄs noilgums';
$messages['errorreadonly'] = 'NeizdevÄs veikt darbÄ«bu: mape ir tikai lasÄma (read only)';
$messages['errornoperm'] = 'NeizdevÄs veikt darbÄ«bu: piekļuve liegta';
-$messages['erroroverquota'] = 'OperÄciju veikt nav iespÄ“jams. Uz diska nav brÄ«vas veitas.';
+$messages['erroroverquota'] = 'OperÄciju nav iespÄ“jams veikt. Uz diska nav brÄ«vas veitas.';
$messages['erroroverquotadelete'] = 'Uz diska nav brīvas vietas. Lai dzēstu vēstuli, lietojiet SHIFT+DEL.';
$messages['invalidrequest'] = 'NederÄ«gs pieprasÄ«jums! Dati netika saglabÄti ...';
$messages['invalidhost'] = 'Nederīgs servera nosaukums';
@@ -45,7 +45,7 @@ $messages['sendingmessage'] = 'Tiek sūtīta vēstule ...';
$messages['messagesent'] = 'Vēstule nosūtīta veiksmīgi';
$messages['savingmessage'] = 'VÄ“stule tiek saglabÄta ...';
$messages['messagesaved'] = 'VÄ“stule saglabÄta Uzmetumos';
-$messages['successfullysaved'] = 'VeiksmÄ«gi saglabÄts.';
+$messages['successfullysaved'] = 'VÄ“stule veiksmÄ«gi saglabÄta';
$messages['addedsuccessfully'] = 'Kontakts veiksmÄ«gi pievienots adreÅ¡u grÄmatai';
$messages['contactexists'] = 'Kontakts ar Å¡Ädu e-pasta adresi jau eksistÄ“';
$messages['contactnameexists'] = 'Kontakts ar Å¡Ädu vÄrdu jau eksistÄ“.';
@@ -100,74 +100,72 @@ $messages['deletedsuccessfully'] = 'Veiksmīgi izdzēsts';
$messages['converting'] = 'Tiek noņemts vēstules formatējums...';
$messages['messageopenerror'] = 'NevarÄ“ja ielÄdÄ“t vÄ“stuli no servera';
$messages['fileuploaderror'] = 'Faila augÅ¡upielÄde neveiksmÄ«ga';
-$messages['filesizeerror'] = 'AugÅ¡upielÄdÄ“tais fails pÄrsniedz pieļaujamo $size izmÄ“ru.';
-$messages['copysuccess'] = 'Veiksmīgi nokopētas $nr adreses.';
-$messages['copyerror'] = 'Nevarēja nokopēt nevienu adresi.';
+$messages['filesizeerror'] = 'IelÄdÄ“tais fails pÄrsniedz pieļaujamo $size apjomu';
+$messages['copysuccess'] = 'Veiksmīgi nokopētas $nr vēstules';
+$messages['copyerror'] = 'Nevarēja nokopēt nevienu adresi';
$messages['sourceisreadonly'] = 'Adreses avots ir lasÄ«Å¡anas režīmÄ tikai';
-$messages['errorsavingcontact'] = 'Kontakta adresi nevarÄ“ja saglabÄt.';
-$messages['movingmessage'] = 'PÄrvieto vÄ“stules...';
+$messages['errorsavingcontact'] = 'NevarÄ“ja saglabÄt kontakta adreses';
+$messages['movingmessage'] = 'PÄrvietoju vÄ“stules...';
$messages['copyingmessage'] = 'Kopē vēstules...';
$messages['copyingcontact'] = 'Kopē kontaktus...';
$messages['deletingmessage'] = 'Dzēš vēstules...';
$messages['markingmessage'] = 'Atzīmē vēstules...';
-$messages['addingmember'] = 'Kontaktus pievieno grupai...';
-$messages['removingmember'] = 'Kontaktus atvieno no grupas...';
-$messages['receiptsent'] = 'SaņemÅ¡anas apstiprinÄjums nosÅ«tÄ«ts veiksmÄ«gi.';
-$messages['errorsendingreceipt'] = 'NeizdevÄs nosÅ«tÄ«t saņemÅ¡anas apstiprinÄjumu.';
-$messages['deleteidentityconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st Å¡o identitÄti?';
-$messages['nodeletelastidentity'] = 'Å o identitÄti nav iespÄ“jams izdzÄ“st, jo tÄ ir pati pÄ“dÄ“jÄ.';
-$messages['forbiddencharacter'] = 'Mapes nosaukums satur aizliegtus simbolus.';
-$messages['selectimportfile'] = 'LÅ«dzu norÄdiet failu, kuru vÄ“laties augÅ¡upielÄdÄ“t.';
-$messages['addresswriterror'] = 'IzvÄ“lÄ“tÄs adreÅ¡u grÄmatas datus nav iespÄ“jams rediģēt.';
+$messages['addingmember'] = 'Pievieno kontaktu(s) grupai...';
+$messages['removingmember'] = 'Atvieno kontaktu(s) no grupas...';
+$messages['receiptsent'] = 'SaņemÅ¡anas apstiprinÄjums nosÅ«tÄ«ts';
+$messages['errorsendingreceipt'] = 'NeizdevÄs nosÅ«tÄ«t apstiprinÄjumu';
+$messages['deleteidentityconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡o identitÄti?';
+$messages['nodeletelastidentity'] = 'Å o identitÄti nevar izdzÄ“st, tÄ ir pati pÄ“dÄ“jÄ.';
+$messages['forbiddencharacter'] = 'Mapes nosaukums satur aizliegtus simbolus';
+$messages['selectimportfile'] = 'LÅ«dzu izvÄ“lieties failu, ko vÄ“laties augÅ¡upielÄdÄ“t';
+$messages['addresswriterror'] = 'IzvÄ“lÄ“tÄs adreÅ¡u grÄmatas datus nevar labot';
$messages['contactaddedtogroup'] = 'Kontakti tika veiksmīgi pievienoti šai grupai.';
$messages['contactremovedfromgroup'] = 'Kontakti tika veiksmīgi atvienoti no šīs grupas.';
$messages['nogroupassignmentschanged'] = 'GrupÄ nekas netika mainÄ«ts.';
$messages['importwait'] = 'Importēju, lūdzu uzgaidiet...';
$messages['importformaterror'] = 'Imports neizdevÄs! AugÅ¡upielÄdÄ“tais fails nav derÄ«gs importam.';
-$messages['importconfirm'] = '<b>Veiksmīgi ieimportēti $inserted kontakti</b>';
+$messages['importconfirm'] = '<b>Veiksmīgi ieimportēti $inserted kontakti, netika importēti $skipped esoši ieraksti</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Izlaida $skipped jau eksistējošus ierakstus</b>';
-$messages['importmessagesuccess'] = 'Veiksmīgi ieimportētas $nr vēstules';
-$messages['importmessageerror'] = 'ImportÄ“Å¡anas kļūda! AugÅ¡upielÄdÄ“tÄ datne satur nekorektus datus';
$messages['opnotpermitted'] = 'Darbība nav atļauta!';
-$messages['nofromaddress'] = 'IzvÄ“lÄ“tajai identitÄtei nav norÄdÄ«ta e-pasta adrese.';
-$messages['editorwarning'] = 'PÄrslÄ“dzoties uz vienkÄrÅ¡otu teksta redaktoru, tiks pazaudÄ“ts esoÅ¡ais teksta formatÄ“jums. Vai tieÅ¡Äm vÄ“laties turpinÄt?';
-$messages['httpreceivedencrypterror'] = 'Notika kritiska kļūme. Lūdzu nekavējoties sazinieties ar Jūsu administratoru. <b>Jūsu vēstuli nosūtīt nav iespējams.</b>';
+$messages['nofromaddress'] = 'IzvÄ“lÄ“tajai identitÄtei nav norÄdÄ«ta e-pasta adrese';
+$messages['editorwarning'] = 'PÄrslÄ“dzoties uz vienkÄrÅ¡otu teksta redaktoru, tiks pazaudÄ“ts esoÅ¡ais teksta formatÄ“jums. Vai vÄ“laties turpinÄt?';
+$messages['httpreceivedencrypterror'] = 'Kļūme. Lūdzu sazinieties ar administratoru. <b>Nav iespējams nosūtīt vēstuli.</b>';
$messages['smtpconnerror'] = 'SMTP kļūme ($code): NeizdevÄs pieslÄ“gties serverim';
-$messages['smtpautherror'] = 'SMTP kļūda ($code): NeizdevÄs autorizÄ“ties.';
-$messages['smtpfromerror'] = 'SMTP kļūda ($code): NeizdevÄs iestatÄ«t sÅ«tÄ«tÄju "$from" ($msg).';
-$messages['smtptoerror'] = 'SMTP kļūda ($code): NeizdevÄs pievienot saņēmÄ“ju "$to" ($msg).';
-$messages['smtprecipientserror'] = 'SMTP kļūda: Nav iespÄ“jams aptrÄdÄt saņēmÄ“ju sarakstu.';
-$messages['smtperror'] = 'SMTP kļūda: $msg';
+$messages['smtpautherror'] = 'SMTP kļūme ($code): NeizdevÄs autentificÄ“ties';
+$messages['smtpfromerror'] = 'SMTP kļūme ($code): NeizdevÄs iestatÄ«t sÅ«tÄ«tÄju "$from" ($msg)';
+$messages['smtptoerror'] = 'SMTP kļūme ($code): NeizdevÄs pievienot saņēmÄ“ju "$to" ($msg)';
+$messages['smtprecipientserror'] = 'SMTP kļūme: Nav iespējams parsēt saņēmēju sarakstu';
+$messages['smtperror'] = 'SMTP kļūme: $msg';
$messages['emailformaterror'] = 'Nepareiza e-pasta adrese: $email';
$messages['toomanyrecipients'] = 'PÄrÄk daudz saņēmÄ“ju. Samaziniet skaitu lÄ«dz $max.';
$messages['maxgroupmembersreached'] = 'Grupas dalÄ«bnieku skaits pÄrsniedz limitu $max.';
-$messages['internalerror'] = 'Notika servera iekÅ¡Ä“jÄ kļūda. LÅ«dzu mÄ“Ä£iniet vÄ“lreiz.';
-$messages['contactdelerror'] = 'Kontaktus izdzÄ“st neizdevÄs.';
-$messages['contactdeleted'] = 'Kontakti izdzēsti veiksmīgi.';
-$messages['contactrestoreerror'] = 'IzdzÄ“stos kontaktus atjaunot neizdevÄs.';
-$messages['contactrestored'] = 'Kontakti atjaunoti veiksmīgi.';
-$messages['groupdeleted'] = 'Grupa izdzēsta veiksmīgi.';
-$messages['grouprenamed'] = 'Grupa pÄrdÄ“vÄ“ta veiksmÄ«gi.';
-$messages['groupcreated'] = 'Grupa izveidota veiksmīgi.';
-$messages['savedsearchdeleted'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums izdzÄ“sts veiksmÄ«gi.';
-$messages['savedsearchdeleteerror'] = 'SaglabÄto meklÄ“Å¡anas pieprasÄ«jumu izdzÄ“st neizdevÄs.';
-$messages['savedsearchcreated'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums saglabÄts veiksmÄ«gi.';
-$messages['savedsearchcreateerror'] = 'MeklÄ“Å¡anas pieprasÄ«jumu izveidot neizdevÄs.';
+$messages['internalerror'] = 'Servera iekÅ¡Ä“jÄ kļūda. LÅ«dzu mÄ“Ä£iniet vÄ“lreiz.';
+$messages['contactdelerror'] = 'NeizdevÄs izdzÄ“st kontaktu(s).';
+$messages['contactdeleted'] = 'Kontakti veiksmīgi izdzēsti.';
+$messages['contactrestoreerror'] = 'NeizdevÄs atjaunot izdzÄ“stos kontaktus.';
+$messages['contactrestored'] = 'Kontakti veiksmīgi atjaunoti.';
+$messages['groupdeleted'] = 'Grupa veiksmīgi izdzēsta.';
+$messages['grouprenamed'] = 'Grupa veiksmÄ«gi pÄrdÄ“vÄ“ta.';
+$messages['groupcreated'] = 'Grupa veiksmīgi izveidota.';
+$messages['savedsearchdeleted'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums veiksmÄ«gi dzÄ“sts.';
+$messages['savedsearchdeleteerror'] = 'NeizdevÄs nodzÄ“st saglabÄto meklÄ“Å¡anas pieprasÄ«jumu.';
+$messages['savedsearchcreated'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums veiksmÄ«gi saglabÄts.';
+$messages['savedsearchcreateerror'] = 'NeizdevÄs saglabÄt meklÄ“Å¡anas pieprasÄ«jumu.';
$messages['messagedeleted'] = 'Vēstule(s) veiksmīgi izdzēsta(s).';
$messages['messagemoved'] = 'VÄ“stule(s) veiksmÄ«gi pÄrvietota(s).';
$messages['messagecopied'] = 'VÄ“stule(s) veiksmÄ«gi pÄrkopÄ“ta(s).';
-$messages['messagemarked'] = 'Vēstule(s) veiksmīgi atzīmēta(s).';
-$messages['autocompletechars'] = 'Lai automÄtiski meklÄ“tu, ievadiet vismaz $min burtus.';
-$messages['autocompletemore'] = 'Atrasti vairÄki ieraksti. Papildiniet meklÄ“Å¡anas kritÄ“riju ar vairÄk burtiem.';
+$messages['messagemarked'] = 'Vēstule(s) veiksmīgi iezīmēta(s).';
+$messages['autocompletechars'] = 'Ievadiet vismaz $min burtus, lai meklÄ“tu automÄtiski.';
+$messages['autocompletemore'] = 'Atrasti vairÄki ieraksti. Papildiniet meklÄ“Å¡anas kritÄ“riju.';
$messages['namecannotbeempty'] = 'LÅ«dzu ievadiet vÄrdu.';
-$messages['nametoolong'] = 'VÄrds ir pÄrÄk garÅ¡.';
+$messages['nametoolong'] = 'VÄrds ir par garu.';
$messages['folderupdated'] = 'Mape vieksmīgi atjaunota.';
$messages['foldercreated'] = 'Mape veiksmīgi izveidota.';
$messages['invalidimageformat'] = 'NederÄ«gs attÄ“la formÄts.';
$messages['mispellingsfound'] = 'Vēstulē atrastas pareizrakstības kļūdas.';
-$messages['parentnotwritable'] = 'NeizdevÄs izveidot/pÄrvietot mapi atzÄ«mÄ“tajÄ virsmapÄ“. Nav piekļuves tiesÄ«bu.';
-$messages['messagetoobig'] = 'VÄ“stule daļa ir pÄrÄk liela, lai to varÄ“tu apstrÄdÄt.';
+$messages['parentnotwritable'] = 'NeizdevÄs izveidot/pÄrvietot mapi uz atzÄ«mÄ“to virsmapi. Nav piekļuves tiesÄ«bu.';
+$messages['messagetoobig'] = 'VÄ“stule ir pÄrÄk liela, lai to varÄ“tu apstrÄdÄt.';
$messages['attachmentvalidationerror'] = 'BRĪDINÄ€JUMS! Å is pielikums ir aizdomÄ«gs, jo tÄ tips neatbilst tipam, kurÅ¡ ir uzrÄdÄ«ts e-pasta ziņojumÄ. Ja jÅ«s neuzticaties sÅ«tÄ«tÄjam, Å¡o failu Jums vaÄ¼Ä vÄ“rt nevajadzÄ“tu, jo tas var saturÄ“t ļaunprÄtÄ«gu saturu. <br/><br/><em>BÅ«tu jÄbÅ«t: $expected; Bet ir: $detected</em>';
-$messages['noscriptwarning'] = 'UzmanÄ«bu: lai lasÄ«tu e-pastus, JÅ«su pÄrlÅ«kprogrammÄ jÄbÅ«t ieslÄ“gtiem JavaScript.';
+$messages['noscriptwarning'] = 'UzmanÄ«bu: lai lasÄ«tu e-pastus, JÅ«su tÄ«mekļa pÄrlÅ«kÄ jÄbÅ«t iespÄ“jotiem JavaScript.';
?>
diff --git a/program/localization/mk_MK/labels.inc b/program/localization/mk_MK/labels.inc
index 519df5823..bb9606e6a 100755..100644
--- a/program/localization/mk_MK/labels.inc
+++ b/program/localization/mk_MK/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Ðепратени';
$labels['sent'] = 'Пратени';
$labels['trash'] = 'Корпа';
$labels['junk'] = 'Ѓубре';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÐаÑлов';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Компактно';
$labels['empty'] = 'ИÑпразни';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ИÑкориÑтен проÑтор';
$labels['unknown'] = 'непознато';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Ðово пребарување';
$labels['searchmod'] = 'Модификатори на пребарувањето';
$labels['msgtext'] = 'Цело пиÑмо';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори во нов прозорец';
$labels['emlsave'] = 'Преземи (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Прикажи ја поÑледната Ñтран
$labels['group'] = 'Group';
$labels['groups'] = 'Групи';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Лични адреÑи';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/mk_MK/messages.inc b/program/localization/mk_MK/messages.inc
index 7a7548ce0..f7a8d9a12 100755..100644
--- a/program/localization/mk_MK/messages.inc
+++ b/program/localization/mk_MK/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Форматирањето на пиÑмото е оÑ
$messages['messageopenerror'] = 'Ðе можев да го вчитам пиÑното од Ñерверот';
$messages['fileuploaderror'] = 'Прикачувањето е неуÑпешно';
$messages['filesizeerror'] = 'Подигнатата податотека го надминува ограничувањето од $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'УÑпешно Ñе копирани $nr имиња';
+$messages['copyerror'] = 'Ðе можам да ги копирам адреÑите';
$messages['sourceisreadonly'] = 'Изворот на оваа адреÑа неможе да Ñе промени';
$messages['errorsavingcontact'] = 'Името неможе да Ñе Ñними';
$messages['movingmessage'] = 'Пораката Ñе премеÑтува...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Убезувам,, почекајте...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>УÑпешно Ñе увезени $inserted имиња, $skipped веќе поÑтојат и Ñе преÑкокнати</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Операцијата не е дозволена';
$messages['nofromaddress'] = 'Ðе е внеÑена е-пошта во одберениот идентитет';
$messages['editorwarning'] = 'Префрлањето на уредникот на обичен текÑÑ‚ ќе резултира Ñо губење на целото форматирање на текÑтот. Дали Ñакате да продолжите?';
diff --git a/program/localization/ml_IN/labels.inc b/program/localization/ml_IN/labels.inc
index 7d3fdc501..ed0e7402a 100644
--- a/program/localization/ml_IN/labels.inc
+++ b/program/localization/ml_IN/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'പൂരàµâ€à´¤àµà´¤à´¿à´¯à´¾à´•à´¾à´¤àµà´¤à´µ';
$labels['sent'] = 'അയചàµà´šà´µ';
$labels['trash'] = 'ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿ';
$labels['junk'] = 'ആവശàµà´¯à´®à´¿à´²àµà´²à´¾à´¤àµà´¤à´µ';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'വിഷയം';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'à´šàµà´°àµà´•àµà´•àµ';
$labels['empty'] = 'ശൂനàµà´¯à´‚';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'à´¡à´¿à´¸àµà´•àµà´•àµ ഉപയോഗം';
$labels['unknown'] = 'അറിയാതàµà´¤';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'à´®àµà´´àµà´µà´¨àµâ€ സനàµà´¦àµ‡à´¶à´µàµà´‚';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'à´ªàµà´¤à´¿à´¯ വിനàµâ€à´¡àµ‹à´¯à´¿à´²àµâ€ à´¤àµà´±à´•àµà´•àµà´•';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'കൂടàµà´Ÿà´‚';
$labels['groups'] = 'കൂടàµà´Ÿà´™àµà´™à´³àµâ€';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'à´¸àµà´µà´•à´¾à´°àµà´¯ വിലാസങàµà´™à´³àµâ€';
$labels['searchsave'] = 'തിരയലàµâ€ സൂകàµà´·à´¿à´•àµà´•àµà´•';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'à´…à´•àµà´•à´™àµà´™à´³àµâ€ ഉളàµà´³ à
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'നിഘണàµà´Ÿàµà´µà´¿à´²àµâ€ ചേരàµâ€à´•àµà´•àµà´•';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ml_IN/messages.inc b/program/localization/ml_IN/messages.inc
index cc189a17d..28eb22be2 100644
--- a/program/localization/ml_IN/messages.inc
+++ b/program/localization/ml_IN/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'File upload failed.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/mr_IN/labels.inc b/program/localization/mr_IN/labels.inc
index d26583d4d..02b129e0b 100755..100644
--- a/program/localization/mr_IN/labels.inc
+++ b/program/localization/mr_IN/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'मसà¥à¤¦à¤¾';
$labels['sent'] = 'पाठवलेले';
$labels['trash'] = 'कचरा पेटी';
$labels['junk'] = 'नको असलेले कचरा संदेश';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विषय';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'यादी दरà¥à¤¶à¤• पधà¥â€à¤¦à¤¤';
$labels['folderactions'] = 'फोलà¥à¤¡à¤° कृती..';
$labels['compact'] = 'छोटा';
$labels['empty'] = 'रिकामा';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤•à¤šà¤¾ वापर';
$labels['unknown'] = 'माहित नसलेला';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'परत शोध';
$labels['searchmod'] = 'बदलकरà¥à¤¤à¥â€à¤¯à¤¾à¤‚ना शोधा';
$labels['msgtext'] = 'संपूरà¥à¤£ संदेश';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'नवीन खिडकी उघडा';
$labels['emlsave'] = 'इà¤à¤®à¤à¤² सà¥â€à¤µà¤°à¥‚पात उतरवून घà¥à¤¯à¤¾';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'शेवटचा संच दाखवा';
$labels['group'] = 'गट';
$labels['groups'] = 'अनेक गट';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'वैयकà¥à¤¤à¤¿à¤• पतà¥à¤¤à¥‡';
$labels['searchsave'] = 'शोध जतन करा';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/mr_IN/messages.inc b/program/localization/mr_IN/messages.inc
index 2b1bd3f33..bc4097fb5 100755..100644
--- a/program/localization/mr_IN/messages.inc
+++ b/program/localization/mr_IN/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'दृषà¥à¤¯ सà¥à¤µà¤°à¥à¤ª काढून à¤
$messages['messageopenerror'] = 'सरà¥à¤µà¥à¤¹à¤°à¤µà¤°à¥à¤¨ संदेश आणता आला नाही.';
$messages['fileuploaderror'] = 'फाईल चढवता आली नाही';
$messages['filesizeerror'] = 'तà¥à¤®à¥à¤¹à¥€ चढवलेली फाईल कà¥à¤·à¤®à¤¤à¥‡à¤ªà¥‡à¤•à¥à¤·à¤¾ जासà¥à¤¤ मोठी आहे.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr पतà¥à¤¤à¥à¤¯à¤¾à¤‚ची यशसà¥à¤µà¥€à¤°à¤¿à¤¤à¥à¤¯à¤¾ पà¥à¤°à¤¤ केली.';
+$messages['copyerror'] = 'कोणतà¥à¤¯à¤¾à¤¹à¥€ पतà¥à¤¤à¥à¤¯à¤¾à¤šà¥€ पà¥à¤°à¤¤ बनवता आली नाही.';
$messages['sourceisreadonly'] = 'पतà¥à¤¤à¤¾ फकà¥à¤¤ वाचणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आहे.';
$messages['errorsavingcontact'] = 'पतà¥à¤¤à¤¾ नोंदवहीत ठेवता आला नाही.';
$messages['movingmessage'] = 'संदेश हलवत आहे..';
$messages['copyingmessage'] = 'संदेशाची नकà¥â€à¤•à¤² करत आहे...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'आयात करत आहे, कृपया व
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>$inserted पतà¥à¤¤à¥‡ यशसà¥à¤µà¥€à¤°à¤¿à¤¤à¥à¤¯à¤¾ आयात केल, $skipped आधिच असलेलà¥à¤¯à¤¾ नोंदी केलà¥à¤¯à¤¾ नाहीत</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'ही कà¥à¤°à¤¿à¤¯à¤¾ करणà¥à¤¯à¤¾à¤¸ परवानगी नाही.';
$messages['nofromaddress'] = 'निवडलेलà¥à¤¯à¤¾ खातà¥à¤¯à¤¾à¤¤ इमेल पतà¥à¤¤à¤¾ दिलेला नाही.';
$messages['editorwarning'] = 'टेकà¥à¤¸à¥à¤Ÿ संपादन निवडलà¥à¤¯à¤¾à¤¸ संदेशाचे दृषà¥à¤¯ सà¥à¤µà¤°à¥à¤ª बदलून जाईल. तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ असेच करायचे आहे ना?';
diff --git a/program/localization/ms_MY/labels.inc b/program/localization/ms_MY/labels.inc
index a6bdfbfa0..318af05ad 100644
--- a/program/localization/ms_MY/labels.inc
+++ b/program/localization/ms_MY/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Draf';
$labels['sent'] = 'Hantar';
$labels['trash'] = 'Tong Sampah';
$labels['junk'] = 'Junk';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subjek';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Mod senarai paparan';
$labels['folderactions'] = 'Aksi folder';
$labels['compact'] = 'Kompak';
$labels['empty'] = 'Kosong';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Penggunaan cakera';
$labels['unknown'] = 'tidak diketahui';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Set semula carian';
$labels['searchmod'] = 'Pengubah carian';
$labels['msgtext'] = 'Keseluruhan mesej';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Buka dalam tetingkap baru';
$labels['emlsave'] = 'Muat-turun (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Papar set akhir';
$labels['group'] = 'Group';
$labels['groups'] = 'Kumpulan';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Alamat-alamat Peribadi';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ms_MY/messages.inc b/program/localization/ms_MY/messages.inc
index 50f10af13..72d2e3075 100644
--- a/program/localization/ms_MY/messages.inc
+++ b/program/localization/ms_MY/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Singkir format dari mesej...';
$messages['messageopenerror'] = 'Tidak boleh muat mesej dari server';
$messages['fileuploaderror'] = 'Muatnaik fail gagal';
$messages['filesizeerror'] = 'Fail yang dimuatnaik melampaui saiz maksima $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Berjaya salin alamat-alamat $nr';
+$messages['copyerror'] = 'Tidak boleh salin apa-apa alamat';
$messages['sourceisreadonly'] = 'Sumber alamat ini adalah untuk bacaan sahaja';
$messages['errorsavingcontact'] = 'Tidak boleh simmpan alamat kontek';
$messages['movingmessage'] = 'Memindah mesej...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/nb_NO/labels.inc b/program/localization/nb_NO/labels.inc
index b5c8ce4c6..cba58dc9c 100644
--- a/program/localization/nb_NO/labels.inc
+++ b/program/localization/nb_NO/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Kladd';
$labels['sent'] = 'Sendt';
$labels['trash'] = 'Slettet';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Emne';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Listevisningsmodus';
$labels['folderactions'] = 'Mappehandlinger...';
$labels['compact'] = 'Rydd opp';
$labels['empty'] = 'Tøm';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Plassforbruk';
$labels['unknown'] = 'ukjent';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Nullstill søk';
$labels['searchmod'] = 'Søke felt';
$labels['msgtext'] = 'Hele meldingen';
$labels['body'] = 'Meldingstekst';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ã…pne i nytt vindu';
$labels['emlsave'] = 'Last ned (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Vis siste sett';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Grupper';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Egne adresser';
$labels['searchsave'] = 'Lagre søk';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorer ord med tall';
$labels['spellcheckignorecaps'] = 'Ignorer ord med kun store bokstaver';
$labels['addtodict'] = 'Legg til i ordbok';
$labels['mailtoprotohandler'] = 'Registrer protokollhåndtering for mailto-lenker';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Meldinger videresendes';
$labels['inline'] = 'i teksten';
$labels['asattachment'] = 'som vedlegg';
diff --git a/program/localization/nb_NO/messages.inc b/program/localization/nb_NO/messages.inc
index 6138b9379..7785f474a 100644
--- a/program/localization/nb_NO/messages.inc
+++ b/program/localization/nb_NO/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Fjerner formatering fra meldingen ...';
$messages['messageopenerror'] = 'Kunne ikke hente meldingen fra server';
$messages['fileuploaderror'] = 'Feil under opplastning.';
$messages['filesizeerror'] = 'Filen overstiger maksimum tillatt filstørrelse ($size)';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Kopierte $nr adresser.';
+$messages['copyerror'] = 'Kunne ikke kopiere adresser.';
$messages['sourceisreadonly'] = 'Denne adressekilden er skrivebeskyttet';
$messages['errorsavingcontact'] = 'Kunne ikke lagre kontaktadressen.';
$messages['movingmessage'] = 'Flytter e-post ...';
$messages['copyingmessage'] = 'Kopierer e-post...';
$messages['copyingcontact'] = 'Kopierer kontakt(er) …';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Sletter melding(er) …';
$messages['markingmessage'] = 'Markerer melding(er) ...';
$messages['addingmember'] = 'Legger til kontakt(er) i gruppa ...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importerer, vennligst vent...';
$messages['importformaterror'] = 'Import feilet! Den opplastede filen er i feil format.';
$messages['importconfirm'] = '<b>Importerte $inserted kontakter</b>';
$messages['importconfirmskipped'] = '<b>Hoppet over $skipped eksisterende oppføringer</b>';
-$messages['importmessagesuccess'] = 'Kopierte $nr meldinger';
-$messages['importmessageerror'] = 'Importeringen var mislykket! Den opplastede filen er ikke en gyldig melding, eller er ikke kompatibel med meldingssystemet.';
$messages['opnotpermitted'] = 'Handling ikke tillatt!';
$messages['nofromaddress'] = 'E-postadresse mangler i valgt identitet';
$messages['editorwarning'] = 'Ved å bytte format til ren tekst vil all tekstformatering gå tapt. Ønsker du å fortsette?';
diff --git a/program/localization/ne_NP/labels.inc b/program/localization/ne_NP/labels.inc
index 5f69e1916..29d43ef9c 100644
--- a/program/localization/ne_NP/labels.inc
+++ b/program/localization/ne_NP/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'डà¥à¤°à¤¾à¤«à¥à¤Ÿà¤¹à¤°à¥‚';
$labels['sent'] = 'पठईà¤à¤•à¤¾ मेलहरà¥';
$labels['trash'] = 'रदà¥à¤¦à¥€ टोकरी';
$labels['junk'] = 'सà¥à¤ªà¤¾à¤®';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विषय';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'छोटो गरà¥à¤¨à¥à¤¹à¥‹à¤¸';
$labels['empty'] = 'खाली गरà¥à¤¨à¥‡';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤•à¤•à¥‹ उपभोग';
$labels['unknown'] = 'अजà¥à¤žà¤¾à¤¤';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'पन: खोज';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'अनà¥à¤¤à¤¿à¤® सेट देखाउनà¥à
$labels['group'] = 'Group';
$labels['groups'] = 'समूहहरà¥';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त ठेगानाहरà¥';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ne_NP/messages.inc b/program/localization/ne_NP/messages.inc
index bedf41d8d..c5214bb0f 100644
--- a/program/localization/ne_NP/messages.inc
+++ b/program/localization/ne_NP/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'मेलबाट फोरà¥à¤®à¤¾à¤Ÿà¤¿à¤™ हट
$messages['messageopenerror'] = 'सरà¥à¤µà¤°à¤¬à¤¾à¤Ÿ मेल लोड हà¥à¤¨ सकेन';
$messages['fileuploaderror'] = 'फाईल अपलोड हà¥à¤¨ असफल';
$messages['filesizeerror'] = 'अपलोड गरिà¤à¤•à¥‹ फाईल हद $size भनà¥à¤¦à¤¾ ठूलो छ';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'सफलà¥à¤¤à¤¾à¤ªà¥‚रà¥à¤µà¤• $nr ठेगानाहरॠउतारियो';
+$messages['copyerror'] = 'कà¥à¤¨à¥ˆ पनि ठेगानाहरॠउतारà¥à¤¨ सकिà¤à¤¨';
$messages['sourceisreadonly'] = 'यो ठेगाना को शà¥à¤°à¥‹à¤¤ पढà¥à¤¨à¤•à¥‹ लागि मातà¥à¤° उपलबà¥à¤§ छ';
$messages['errorsavingcontact'] = 'सà¥à¤®à¤ªà¤°à¥à¤•à¤•à¥‹ ठेगाना जोगाउन सकिà¤à¤¨';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/nl_BE/labels.inc b/program/localization/nl_BE/labels.inc
index 1e6bb2d2f..eb44eefc0 100644
--- a/program/localization/nl_BE/labels.inc
+++ b/program/localization/nl_BE/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Concepten';
$labels['sent'] = 'Verzonden berichten';
$labels['trash'] = 'Prullenbak';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Onderwerp';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Lijstweergave mode';
$labels['folderactions'] = 'Acties voor map...';
$labels['compact'] = 'Comprimeren';
$labels['empty'] = 'Legen';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Gebruikte schijfruimte';
$labels['unknown'] = 'onbekend';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Zoek opnieuw';
$labels['searchmod'] = 'Zoekopties';
$labels['msgtext'] = 'Volledig bericht';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Openen in een nieuw venster';
$labels['emlsave'] = 'Opslaan (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Toon laatste';
$labels['group'] = 'Groep';
$labels['groups'] = 'Groepen';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlijke adressen';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/nl_BE/messages.inc b/program/localization/nl_BE/messages.inc
index f7ed8e8d4..d87329dc3 100644
--- a/program/localization/nl_BE/messages.inc
+++ b/program/localization/nl_BE/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Opmaak van het bericht wordt gewist...';
$messages['messageopenerror'] = 'Kon het bericht niet ophalen van de server.';
$messages['fileuploaderror'] = 'Bestandsupload mislukt.';
$messages['filesizeerror'] = 'Het bestand overschrijdt de maximum grootte van $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr adressen met succes gekopieerd.';
+$messages['copyerror'] = 'Kon de adressen niet kopiëren.';
$messages['sourceisreadonly'] = 'Het adres kan niet worden opgeslagen.';
$messages['errorsavingcontact'] = 'Kon de contactpersoon niet bewaren.';
$messages['movingmessage'] = 'Bericht wordt verplaatst...';
$messages['copyingmessage'] = 'Bericht wordt gekopieerd...';
$messages['copyingcontact'] = 'Kopiëren contactpersonen...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Bericht wordt verwijderd...';
$messages['markingmessage'] = 'Bericht wordt gemarkeerd...';
$messages['addingmember'] = 'Contactpersonen worden toegevoegd aan de groep...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Bezig met importeren, even geduld...';
$messages['importformaterror'] = 'Importeren mislukt! Het geüploade bestand is geen importeerbaar bestand.';
$messages['importconfirm'] = '<b>Er zijn $inserted contactpersonen succesvol geïmporteerd</b>';
$messages['importconfirmskipped'] = '<b>$skipped bestaande contactpersonen overgeslagen</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Deze actie is niet toegestaan!';
$messages['nofromaddress'] = 'De geselecteerde identiteit bevat geen emailadres.';
$messages['editorwarning'] = 'Door het overschakelen naar de platte tekst editor gaat alle opmaak verloren. Weet u zeker dat u verder wilt gaan?';
diff --git a/program/localization/nl_NL/labels.inc b/program/localization/nl_NL/labels.inc
index 8a6f994fa..7bd48bd4a 100644
--- a/program/localization/nl_NL/labels.inc
+++ b/program/localization/nl_NL/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Concepten';
$labels['sent'] = 'Verzonden';
$labels['trash'] = 'Prullenbak';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Toon echte namen voor speciale mappen';
// message listing
$labels['subject'] = 'Onderwerp';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Lijstweergave';
$labels['folderactions'] = 'Mapacties...';
$labels['compact'] = 'Opschonen';
$labels['empty'] = 'Legen';
-$labels['importmessages'] = 'Berichten importeren';
$labels['quota'] = 'Opslagverbruik';
$labels['unknown'] = 'onbekend';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Wis zoekopdracht';
$labels['searchmod'] = 'Zoekopties';
$labels['msgtext'] = 'Gehele bericht';
$labels['body'] = 'Inhoud';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Openen in een nieuw venster';
$labels['emlsave'] = 'Opslaan (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Laatste pagina';
$labels['group'] = 'Groep';
$labels['groups'] = 'Groepen';
-$labels['listgroup'] = 'Toon groepsleden';
$labels['personaladrbook'] = 'Persoonlijk adresboek';
$labels['searchsave'] = 'Zoekopdracht opslaan';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Negeer woorden met cijfers';
$labels['spellcheckignorecaps'] = 'Negeer woorden welke volledig uit hoofdletters bestaan';
$labels['addtodict'] = 'Voeg toe aan woordenboek';
$labels['mailtoprotohandler'] = 'Registreer protocolhandler voor mailto: links';
-$labels['standardwindows'] = 'Behandel pop-ups als normale vensters';
$labels['forwardmode'] = 'Berichten doorsturen';
$labels['inline'] = 'invoegen';
$labels['asattachment'] = 'als bijlage';
diff --git a/program/localization/nl_NL/messages.inc b/program/localization/nl_NL/messages.inc
index 01c43b243..4a67e1590 100644
--- a/program/localization/nl_NL/messages.inc
+++ b/program/localization/nl_NL/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Opmaak van bericht verwijderen...';
$messages['messageopenerror'] = 'Kan het bericht niet van de server laden.';
$messages['fileuploaderror'] = 'Bestand uploaden mislukt.';
$messages['filesizeerror'] = 'Het bestand overschrijdt de maximale grootte van $size.';
-$messages['copysuccess'] = '$nr contactpersonen succesvol gekopieerd.';
-$messages['movesuccess'] = '$nr contactpersonen succesvol verplaatst.';
-$messages['copyerror'] = 'Kon geen contactpersoon kopieren.';
-$messages['moveerror'] = 'Kon geen contactpersoon verplaatsen.';
+$messages['copysuccess'] = '$nr adressen succesvol gekopieerd.';
+$messages['copyerror'] = 'Kan geen adressen kopiëren.';
$messages['sourceisreadonly'] = 'Deze adresbron is alleen-lezen.';
$messages['errorsavingcontact'] = 'Kan contactpersoon niet opslaan.';
$messages['movingmessage'] = 'Bericht(en) verplaatsen...';
$messages['copyingmessage'] = 'Bericht(en) kopiëren...';
$messages['copyingcontact'] = 'Contact(en) kopiëren...';
-$messages['movingcontact'] = 'Contact(en) verplaatsen...';
$messages['deletingmessage'] = 'Bericht(en) verwijderen...';
$messages['markingmessage'] = 'Bericht(en) markeren...';
$messages['addingmember'] = 'Contactpersonen worden toegevoegd aan groep...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importeren, even geduld...';
$messages['importformaterror'] = 'Importeren mislukt! Het geüploade bestand is geen geldig importbestand.';
$messages['importconfirm'] = '<b>$inserted contactpersonen succesvol geïmporteerd</b>';
$messages['importconfirmskipped'] = '<b>$skipped bestaande contactpersonen overgeslagen</b>';
-$messages['importmessagesuccess'] = '$nr berichten succesvol geïmporteerd';
-$messages['importmessageerror'] = 'Importeren mislukt! Het verstuurde bestand is geen geldig bericht of mailboxbestand';
$messages['opnotpermitted'] = 'Deze bewerking is niet toegestaan!';
$messages['nofromaddress'] = 'Het e-mailadres ontbreekt in de geselecteerde identiteit.';
$messages['editorwarning'] = 'Door het overschakelen naar de platte-tekstverwerker gaat alle opmaak verloren. Weet u zeker dat u verder wilt gaan?';
diff --git a/program/localization/nn_NO/labels.inc b/program/localization/nn_NO/labels.inc
index 5934a01d9..d1a1c5700 100644
--- a/program/localization/nn_NO/labels.inc
+++ b/program/localization/nn_NO/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Kladd';
$labels['sent'] = 'Sendt';
$labels['trash'] = 'Sletta';
$labels['junk'] = 'Søppel';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Emne';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Listevisningmodus';
$labels['folderactions'] = 'Mappehandlingar';
$labels['compact'] = 'Kompakt';
$labels['empty'] = 'Tom';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Plassbruk';
$labels['unknown'] = 'ukjend';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Tilbakestill søk';
$labels['searchmod'] = 'Søkeutsagn';
$labels['msgtext'] = 'Heile eposten';
$labels['body'] = 'Meldingstekst';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Opna i nytt vindauga';
$labels['emlsave'] = 'Last ned (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Siste side';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppar';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlege adresser';
$labels['searchsave'] = 'Lagre søk';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorer ord med tal';
$labels['spellcheckignorecaps'] = 'Ignorer ord med berre store bokstavar';
$labels['addtodict'] = 'Legg til i ordliste';
$labels['mailtoprotohandler'] = 'Registrer protokollhandsaming for mailto-lenkjer';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Meldingar vidaresendast';
$labels['inline'] = 'i teksten';
$labels['asattachment'] = 'som vedlegg';
diff --git a/program/localization/nn_NO/messages.inc b/program/localization/nn_NO/messages.inc
index 741b4cb20..3dce30b98 100644
--- a/program/localization/nn_NO/messages.inc
+++ b/program/localization/nn_NO/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Fjernar formatering frå meldinga …';
$messages['messageopenerror'] = 'Klarte ikkje lasta meldinga frå tenaren.';
$messages['fileuploaderror'] = 'Filopplasting feila.';
$messages['filesizeerror'] = 'Fila du lasta opp, er større enn største tillatne filstorleik, $size.';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Kopierte $nr adresser.';
+$messages['copyerror'] = 'Klarte ikkje kopiera nokon adresser.';
$messages['sourceisreadonly'] = 'Denne adressekjelda er berre lesbar.';
$messages['errorsavingcontact'] = 'Klarte ikkje lagra kontaktadressa.';
$messages['movingmessage'] = 'Flyttar melding(ar) …';
$messages['copyingmessage'] = 'Kopierer melding(ar) …';
$messages['copyingcontact'] = 'Kopierer kontakt(ar) …';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Slettar melding(ar) …';
$messages['markingmessage'] = 'Merkar melding(ar) …';
$messages['addingmember'] = 'Legg til kontakt(ar) i gruppa …';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importerer, vent …';
$messages['importformaterror'] = 'Importering feila. Den opplasta fila er i feil format.';
$messages['importconfirm'] = '<b>Importerte $inserted kontaktar</b>';
$messages['importconfirmskipped'] = '<b>Hoppa over $skipped oppføringar som fanst frå før</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Ulovleg operasjon.';
$messages['nofromaddress'] = 'Manglar e-postadresse i denne identiteten.';
$messages['editorwarning'] = 'Ã… byta til rein tekst vil fjerna all tekstformateringa. Vil du halda fram?';
diff --git a/program/localization/pl_PL/labels.inc b/program/localization/pl_PL/labels.inc
index d7b9cd2d4..426ac381e 100644
--- a/program/localization/pl_PL/labels.inc
+++ b/program/localization/pl_PL/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Kopie robocze';
$labels['sent'] = 'Wysłane';
$labels['trash'] = 'Kosz';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Pokaż prawdziwe nazwy dla folderów specjalnych';
// message listing
$labels['subject'] = 'Temat';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Typ listy';
$labels['folderactions'] = 'Działania na folderach...';
$labels['compact'] = 'PorzÄ…dkuj';
$labels['empty'] = 'Opróżnij';
-$labels['importmessages'] = 'Import wiadomości';
$labels['quota'] = 'Użyte miejsce';
$labels['unknown'] = 'nieznane';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Wyczyść filtr';
$labels['searchmod'] = 'Parametry wyszukiwania';
$labels['msgtext'] = 'Cała wiadomość';
$labels['body'] = 'Treść';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otwórz w nowym oknie';
$labels['emlsave'] = 'Pobierz (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Ostatnia strona';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupy';
-$labels['listgroup'] = 'Członkowie grupy';
$labels['personaladrbook'] = 'Kontakty osobiste';
$labels['searchsave'] = 'Zapisz wyszukiwanie';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignoruj słowa zawierające cyfry';
$labels['spellcheckignorecaps'] = 'Ignoruj słowa pisane wielkimi literami';
$labels['addtodict'] = 'Dodaj do słownika';
$labels['mailtoprotohandler'] = 'Zainstaluj obsługę linków mailto:';
-$labels['standardwindows'] = 'Traktuj okna wyskakujÄ…ce jako standardowe okna';
$labels['forwardmode'] = 'Przekazywanie wiadomości';
$labels['inline'] = 'w treści';
$labels['asattachment'] = 'jako załącznik';
diff --git a/program/localization/pl_PL/messages.inc b/program/localization/pl_PL/messages.inc
index 3cac0c426..fb7ad6c97 100644
--- a/program/localization/pl_PL/messages.inc
+++ b/program/localization/pl_PL/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Importowanie, proszę czekać...';
$messages['importformaterror'] = 'Import nieudany! Użyty plik nie jest poprawnym plikiem importu danych.';
$messages['importconfirm'] = '<b>Pomyślnie dodano $inserted kontaktów, pominięto $skipped istniejących wpisów</b>:<p><em>$names</em></p>.';
$messages['importconfirmskipped'] = '<b>Pominięto $skipped istniejących wpisów.</b>';
-$messages['importmessagesuccess'] = 'Pomyślnie zaimportowano następującą liczbę wiadomości: $nr';
-$messages['importmessageerror'] = 'Import nieudany! Wgrywany plik nie jest poprawną wiadomością lub plikiem skrzynki pocztowej';
$messages['opnotpermitted'] = 'Niedozwolona operacja!';
$messages['nofromaddress'] = 'Brak adresu e-mail w wybranej tożsamości.';
$messages['editorwarning'] = 'Zmiana edytora spowoduje utratę formatowania tekstu. Czy jesteś pewien, że chcesz to zrobić?';
diff --git a/program/localization/ps/labels.inc b/program/localization/ps/labels.inc
index d5e513419..262e3d490 100755..100644
--- a/program/localization/ps/labels.inc
+++ b/program/localization/ps/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'بارليک';
$labels['sent'] = 'Ù„ÛÚ–Ù„ شوي ليکونه';
$labels['trash'] = 'کثاÙت دانÛ';
$labels['junk'] = 'جنک';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'مضمون';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Ú©ÛÚšÚ©Ù„ÛŒ';
$labels['empty'] = 'تش';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ټيکلي لارښود';
$labels['unknown'] = 'نامعلوم';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'د Ù¾Ù„Ù¼Ù†Û Ø¨ÙŠØ§Ø³Ù…ÙˆÙ†';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'په نوي Ú©Ú“Ú©Û Ú©Û Ù¾Ø±Ø§Ù†ÙŠØ²Ù‡';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'پای غونډ وښيه';
$labels['group'] = 'Group';
$labels['groups'] = 'Ú‰Ù„Û';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Úاني پتÛ';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ps/messages.inc b/program/localization/ps/messages.inc
index 50c1849bd..d3a8483ee 100755..100644
--- a/program/localization/ps/messages.inc
+++ b/program/localization/ps/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'له استوزي څخه Ø¨Ú¼Û Ú“Ù†Ú«ÛÚ–ÙŠ';
$messages['messageopenerror'] = 'له سرور څخه استوزي پرمخ نه شي تلی';
$messages['fileuploaderror'] = 'دÙايل پورته کول په بري سره سرته ونه رسيده';
$messages['filesizeerror'] = 'د پورته شوي Ùايل Ú©Ú†Ù‡ بايد لږترلږه له $څخه تيری ونه Ú©Ú“ÙŠ';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'په بشپړه توګه $Ù¾ØªÛ Ú©Ø§Ù¾ÙŠ شوÛ';
+$messages['copyerror'] = 'Ù‡ÛÚ… يوه پته ÙŠÛ Ú©Ø§Ù¾ÙŠâ€ŒÙ†Ù‡ شوای کړای';
$messages['sourceisreadonly'] = 'Ø¯Ø¯Û Ù¾ØªÛ ÙŠÙˆØ§Ø²Û Ø³Ø±Ú†ÙŠÙ†Ù‡ لوستل Ú©ÛÚ–ÙŠ';
$messages['errorsavingcontact'] = 'د Ù¾ØªÛ Ø§Ú“ÙŠÚ©Ù„ÙˆØ±ÛŒ ÙŠÛ Ø®ÙˆÙ†Ø¯ÙŠâ€ŒÙ†Ù‡ شو کړای';
$messages['movingmessage'] = 'استوزه خوÚوي';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'نقلوي...صبر وکړئ';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>په بشپړه توګه نقل شو $اړيکلوري داخل شول, $شته تيرشوي انټاير څخه تيرشول</b>:<p><em>$نومونه</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'چار اجازه نه لري';
$messages['nofromaddress'] = 'په ټاکل شوي پيژندنه Ú©Û Ø¨Ø±Ûښناليک Ù¾ØªÛ Ù„Ù‡ لاسه ورکړي';
$messages['editorwarning'] = 'Ú©Ù‡ د متن بڼو له منÚÙ‡ تللو ګواښ وي نو د متن سمون پرانيزئ. غواړئ Ú†Û Ø¯ÙˆØ§Ù… ورکړئ';
diff --git a/program/localization/pt_BR/labels.inc b/program/localization/pt_BR/labels.inc
index e70ae35b9..9a1946eee 100644
--- a/program/localization/pt_BR/labels.inc
+++ b/program/localization/pt_BR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Rascunhos';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Lixeira';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Exibir o nome real das pastas de sistema';
// message listing
$labels['subject'] = 'Assunto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Visualização em lista';
$labels['folderactions'] = 'Ações para as pastas...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Esvaziar';
-$labels['importmessages'] = 'Importar mensagens';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconhecido';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Limpar pesquisa';
$labels['searchmod'] = 'Opções da pesquisa';
$labels['msgtext'] = 'Mensagem inteira';
$labels['body'] = 'Conteúdo';
-$labels['type'] = 'Tipo';
$labels['openinextwin'] = 'Abrir em nova janela';
$labels['emlsave'] = 'Baixar (formato .eml)';
@@ -270,7 +267,7 @@ $labels['yourmessage'] = 'Esta é uma confirmação de leitura da sua mensagem';
$labels['receiptnote'] = 'Nota: Esta confirmação de leitura somente informa que a mensagem foi aberta no computador do destinatário. Não há garantia que o destinatário tenha lido ou compreendido o conteúdo da mensagem.';
// address boook
-$labels['name'] = 'Nome';
+$labels['name'] = 'Nome de exibição';
$labels['firstname'] = 'Primeiro Nome';
$labels['surname'] = 'Sobrenome';
$labels['middlename'] = 'Segundo Nome';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Última Página';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
-$labels['listgroup'] = 'Listar membros do grupo';
$labels['personaladrbook'] = 'Endereços pessoais';
$labels['searchsave'] = 'Salvar pesquisa';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorar palavras com números';
$labels['spellcheckignorecaps'] = 'Ignorar palavras com todas letras maiúsculas';
$labels['addtodict'] = 'Adicionar ao dicionário';
$labels['mailtoprotohandler'] = 'Associar links de e-mail (mailto:) para envio de mensagem através do webmail';
-$labels['standardwindows'] = 'Usar popups como janelas do navegador';
$labels['forwardmode'] = 'Encaminhamento de mensagens';
$labels['inline'] = 'Em linha (no corpo da mensagem)';
$labels['asattachment'] = 'como anexo';
@@ -489,7 +484,7 @@ $labels['messagecount'] = 'Mensagens';
$labels['create'] = 'Criar';
$labels['createfolder'] = 'Criar nova pasta';
$labels['managefolders'] = 'Gerenciar pastas';
-$labels['specialfolders'] = 'Pastas de sistema';
+$labels['specialfolders'] = 'Pastas especiais';
$labels['properties'] = 'Propriedades';
$labels['folderproperties'] = 'Propriedades da pasta';
$labels['parentfolder'] = 'Pasta pai';
diff --git a/program/localization/pt_BR/messages.inc b/program/localization/pt_BR/messages.inc
index 45b835d44..6ec481b8f 100644
--- a/program/localization/pt_BR/messages.inc
+++ b/program/localization/pt_BR/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Removendo formatação...';
$messages['messageopenerror'] = 'Não foi possível carregar a mensagem do servidor';
$messages['fileuploaderror'] = 'Falha ao enviar o arquivo';
$messages['filesizeerror'] = 'O arquivo enviado excede o tamanho máximo de $size';
-$messages['copysuccess'] = '$nr contato(s) copiado(s) com sucesso.';
-$messages['movesuccess'] = '$nr contato(s) movido(s) com sucesso.';
-$messages['copyerror'] = 'Não foi possível copiar os contatos.';
-$messages['moveerror'] = 'Não foi possível mover os contatos.';
+$messages['copysuccess'] = '$nr endereço(s) copiado(s) com sucesso';
+$messages['copyerror'] = 'Não foi possível copiar os endereços';
$messages['sourceisreadonly'] = 'Esta fonte de endereço é somente leitura';
$messages['errorsavingcontact'] = 'Não foi possível salvar o endereço de contato';
$messages['movingmessage'] = 'Movendo mensagem(ns)...';
$messages['copyingmessage'] = 'Copiando mensagem(ns)...';
$messages['copyingcontact'] = 'Copiando contato(s)...';
-$messages['movingcontact'] = 'Movendo contato(s)...';
$messages['deletingmessage'] = 'Excluindo mensagem(ns)...';
$messages['markingmessage'] = 'Marcando mensagem(ns)...';
$messages['addingmember'] = 'Adicionando contato(s) para o grupo...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importando, aguarde por favor...';
$messages['importformaterror'] = 'Falha na importação! O arquivo enviado não está em um formato válido.';
$messages['importconfirm'] = '<b>Foram importados com sucesso $inserted contatos</b>';
$messages['importconfirmskipped'] = '<b>Ignorado(s) $skipped registro(s) já existente(s)</b>';
-$messages['importmessagesuccess'] = 'Importação de $nr mensagens com sucesso';
-$messages['importmessageerror'] = 'Falha na importação! O arquivo enviado não é uma mensagem ou caixa postal válida';
$messages['opnotpermitted'] = 'Operação não permitida!';
$messages['nofromaddress'] = 'Falta o e-mail na identidade selecionada.';
$messages['editorwarning'] = 'Mudar para o editor de texto simples elimina toda a formatação de texto. Deseja continuar?';
diff --git a/program/localization/pt_PT/labels.inc b/program/localization/pt_PT/labels.inc
index cc4c534e0..316255e5e 100644
--- a/program/localization/pt_PT/labels.inc
+++ b/program/localization/pt_PT/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Rascunhos';
$labels['sent'] = 'Itens Enviados';
$labels['trash'] = 'Reciclagem';
$labels['junk'] = 'Spam';
-$labels['show_real_foldernames'] = 'Mostrar nomes reais para as pastas especiais';
// message listing
$labels['subject'] = 'Assunto';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Modo de visualização';
$labels['folderactions'] = 'Acções para pastas...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Esvaziar';
-$labels['importmessages'] = 'Importar mensagens';
$labels['quota'] = 'Espaço utilizado';
$labels['unknown'] = 'desconhecido';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Limpar pesquisa';
$labels['searchmod'] = 'Pesquisar em';
$labels['msgtext'] = 'Mensagem completa';
$labels['body'] = 'Corpo';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir numa nova janela';
$labels['emlsave'] = 'Guardar como (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Última página';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
-$labels['listgroup'] = 'Lista de membros do grupo';
$labels['personaladrbook'] = 'Endereços pessoais';
$labels['searchsave'] = 'Guardar pesquisa';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorar palavras com números';
$labels['spellcheckignorecaps'] = 'Ignorar palavras em maiúsculas';
$labels['addtodict'] = 'Adicionar ao dicionário';
$labels['mailtoprotohandler'] = 'Registar manipulador de protocolo para mailto: links';
-$labels['standardwindows'] = 'Lidar com popups como janelas padrão';
$labels['forwardmode'] = 'Reencaminhamento de mensagens';
$labels['inline'] = 'em linha';
$labels['asattachment'] = 'como anexo';
diff --git a/program/localization/pt_PT/messages.inc b/program/localization/pt_PT/messages.inc
index f0855096e..88b96e60e 100644
--- a/program/localization/pt_PT/messages.inc
+++ b/program/localization/pt_PT/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'A remover a formatação...';
$messages['messageopenerror'] = 'Não foi possível carregar a mensagem.';
$messages['fileuploaderror'] = 'Falha ao carregar o ficheiro';
$messages['filesizeerror'] = 'O ficheiro excede o tamanho máximo permitido de $size';
-$messages['copysuccess'] = '$nr contacto(s) copiado(s) com sucesso.';
-$messages['movesuccess'] = '$nr contacto(s) movido(s) com sucesso.';
-$messages['copyerror'] = 'Não foi possível copiar o(s) contacto(s).';
-$messages['moveerror'] = 'Não foi possível mover o(s) contacto(s).';
+$messages['copysuccess'] = 'Foram copiados $nr endereços com sucesso';
+$messages['copyerror'] = 'Não foi possível copiar os endereços';
$messages['sourceisreadonly'] = 'Esta origem de endereços é só de leitura';
$messages['errorsavingcontact'] = 'Não foi possível guardar o endereço deste contacto';
$messages['movingmessage'] = 'A mover mensagem(ns)...';
$messages['copyingmessage'] = 'A copiar mensagem(ns)...';
$messages['copyingcontact'] = 'A copiar contacto(s)...';
-$messages['movingcontact'] = 'A mover contacto(s)...';
$messages['deletingmessage'] = 'A eliminar mensagem(ns)...';
$messages['markingmessage'] = 'A marcar mensagem(ns)...';
$messages['addingmember'] = 'A adicionar contacto(s) ao grupo...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'A importar, por favor aguarde...';
$messages['importformaterror'] = 'A importação falhou! O ficheiro enviado não é um ficheiro de dados válido.';
$messages['importconfirm'] = '<b>$inserted contactos importados com sucesso, $skipped contactos já existentes foram ignorados</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = 'Ignoradas $skipped entradas já existentes.';
-$messages['importmessagesuccess'] = '$nr mensagens importadas com sucesso';
-$messages['importmessageerror'] = 'A importação falhou! O ficheiro carregado não é um arquivo de caixa de correio ou ficheiro de mensagem válido.';
$messages['opnotpermitted'] = 'Operação não permitida';
$messages['nofromaddress'] = 'Falta o endereço de e-mail na identidade seleccionada';
$messages['editorwarning'] = 'Ao mudar para o editor Plain Text vai perder toda a formação de texto. Deseja continuar?';
diff --git a/program/localization/ro_RO/labels.inc b/program/localization/ro_RO/labels.inc
index 4f6ddb1fa..9b76d7175 100644
--- a/program/localization/ro_RO/labels.inc
+++ b/program/localization/ro_RO/labels.inc
@@ -194,7 +194,6 @@ $labels['listmode'] = 'Mod de vizualizare';
$labels['folderactions'] = 'Acțiuni dosar...';
$labels['compact'] = 'Compactează';
$labels['empty'] = 'GoleÅŸte';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Spaţiu folosit';
$labels['unknown'] = 'necunoscut';
@@ -205,7 +204,6 @@ $labels['resetsearch'] = 'Anulează căutarea';
$labels['searchmod'] = 'Parametrii de căutare';
$labels['msgtext'] = 'Tot mesajul';
$labels['body'] = 'Corp';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Deschide în fereastră nouă';
$labels['emlsave'] = 'Salvează în format .eml';
@@ -357,7 +355,6 @@ $labels['lastpage'] = 'Ultima pagină';
$labels['group'] = 'Grup';
$labels['groups'] = 'Grupuri';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adrese personale';
$labels['searchsave'] = 'Salvează căutarea';
diff --git a/program/localization/ro_RO/messages.inc b/program/localization/ro_RO/messages.inc
index 96b9de593..78e0fcb65 100644
--- a/program/localization/ro_RO/messages.inc
+++ b/program/localization/ro_RO/messages.inc
@@ -25,13 +25,13 @@ $messages['storageerror'] = 'Conectarea la serverul IMAP a eÅŸuat';
$messages['servererror'] = 'Eroare de server!';
$messages['servererrormsg'] = 'Eroare Server: $msg';
$messages['dberror'] = 'Eroare bază de date!';
-$messages['requesttimedout'] = 'Timpul alocat cereri a expirat';
-$messages['errorreadonly'] = 'Nu se poate efectua operaţia. Dosarul este doar-citire.';
-$messages['errornoperm'] = 'Nu se poate efectua operaţia. Acces interzis.';
-$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
-$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
+$messages['requesttimedout'] = 'Timpul alocat cererii a expirat';
+$messages['errorreadonly'] = 'Nu se poate efectua operaţiunea. Dosarul este disponibil doar pentru citire.';
+$messages['errornoperm'] = 'Nu se poate efectua operaţiunea. Acces interzis.';
+$messages['erroroverquota'] = 'Nu se poate efectua operația. Nu există spațiu liber.';
+$messages['erroroverquotadelete'] = 'Nu există spațiu liber. Folosiți SHIFT+DEL pentru a șterge un mesaj.';
$messages['invalidrequest'] = 'Solicitare invalidă! Datele nu au fost salvate.';
-$messages['invalidhost'] = 'Hosname invalid';
+$messages['invalidhost'] = 'Nume server invalid.';
$messages['nomessagesfound'] = 'Nu a fost găsit nici un mesaj în această căsuţă poştală';
$messages['loggedout'] = 'Sesiune încheiată cu succes. La revedere!';
$messages['mailboxempty'] = 'Căsuţa poştală este goală';
@@ -40,34 +40,34 @@ $messages['loading'] = 'Se încarcă...';
$messages['uploading'] = 'Fişierul se încarcă...';
$messages['uploadingmany'] = 'ÃŽncarc fiÅŸierele...';
$messages['loadingdata'] = 'Se încarcă informaţiile...';
-$messages['checkingmail'] = 'Se caută mesaje noi...';
+$messages['checkingmail'] = 'Se verifică pentru mesaje noi...';
$messages['sendingmessage'] = 'Trimitere mesaj...';
$messages['messagesent'] = 'Mesajul a fost trimis cu succes!';
$messages['savingmessage'] = 'Salvare mesaj...';
$messages['messagesaved'] = 'Mesajul a fost salvat în Ciorne';
-$messages['successfullysaved'] = 'Salvarea s-a efectuat cu succes';
+$messages['successfullysaved'] = 'Salvat cu succes.';
$messages['addedsuccessfully'] = 'Contactul a fost adăugat cu succes în agendă';
-$messages['contactexists'] = 'Mai există un contact cu această adresă de e-mail';
+$messages['contactexists'] = 'Un contact cu această adresă de e-mail există deja.';
$messages['contactnameexists'] = 'Există deja un contact cu acelaşi nume.';
$messages['blockedimages'] = 'Pentru a vă proteja intimitatea, imaginile externe au fost blocate.';
$messages['encryptedmessage'] = 'Acesta este un mesaj criptat şi nu poate fi afişat. Ne pare rău.';
$messages['nocontactsfound'] = 'Nu s-a găsit nici un contact';
$messages['contactnotfound'] = 'Contactul solicitat nu a fost găsit.';
-$messages['contactsearchonly'] = 'Introdu nişte termeni decăutare pentru a găsi contactele';
+$messages['contactsearchonly'] = 'Introdu nişte termeni de căutare pentru a găsi contactele';
$messages['sendingfailed'] = 'Nu s-a reuÅŸit trimiterea mesajului';
$messages['senttooquickly'] = 'Vă rugăm aşteptaţi $sec sec. înainte de a trimite acest mesaj';
$messages['errorsavingsent'] = 'A intervenit o eroare în timp ce se efectua salvarea mesajului trimis';
$messages['errorsaving'] = 'A intervenit o eroare în timp ce se efectua salvarea';
-$messages['errormoving'] = 'Mesajul(e) nu a(u) putut fi mutat(e)';
-$messages['errorcopying'] = 'Mesajul(e) nu a(u) putut fi copiat(e)';
-$messages['errordeleting'] = 'Mesajul(e) nu a(u) putut fi ÅŸters(e)';
-$messages['errormarking'] = 'Mesajul(e) nu a(u) putut fi marcat(e)';
-$messages['deletecontactconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi contactul(ele) selectate?';
-$messages['deletegroupconfirm'] = 'Chiar vrei să ştergi grupul selectat?';
-$messages['deletemessagesconfirm'] = 'Chiar doriţi să ştergeţi mesajele selectate ?';
+$messages['errormoving'] = 'Nu am putut muta mesajul (mesajele).';
+$messages['errorcopying'] = 'Nu am putut copia mesajul (mesajele).';
+$messages['errordeleting'] = 'Nu am putut ÅŸterge mesajul (mesajele).';
+$messages['errormarking'] = 'Nu am putut marca mesajul (mesajele)';
+$messages['deletecontactconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi contactul/ele selectat(e)?';
+$messages['deletegroupconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi grupul selectat?';
+$messages['deletemessagesconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi mesajul (mesajele) selectate ?';
$messages['deletefolderconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi acest dosar?';
$messages['purgefolderconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi toate mesajele din acest dosar?';
-$messages['contactdeleting'] = 'Åžterg contactul(ele)...';
+$messages['contactdeleting'] = 'Åžterg contactul (ele)...';
$messages['groupdeleting'] = 'Åžterg grupul...';
$messages['folderdeleting'] = 'Se ÅŸterge dosarul...';
$messages['foldermoving'] = 'Se mută dosarul...';
@@ -100,10 +100,10 @@ $messages['deletedsuccessfully'] = 'Mesaj ÅŸters cu succes !';
$messages['converting'] = 'Resetez mesajul la parametrii iniţiali...';
$messages['messageopenerror'] = 'Nu s-a putut încărca mesajul din server';
$messages['fileuploaderror'] = 'Încărcarea pe server a eşuat';
-$messages['filesizeerror'] = 'Fişierul încărcat depăşeşte mărimea de $size';
-$messages['copysuccess'] = '$nr adrese s-au copiat cu succes';
+$messages['filesizeerror'] = 'Fişierul încărcat depăşeşte dimensiunea de $size';
+$messages['copysuccess'] = '$nr adrese copiat(e) cu succes';
$messages['copyerror'] = 'Nu s-a putut copia nicio adresă';
-$messages['sourceisreadonly'] = 'Sursa acestei adrese este "read-only"(se poate doar citi)';
+$messages['sourceisreadonly'] = 'Sursa acestei adrese este "read-only" (se poate doar citi)';
$messages['errorsavingcontact'] = 'Nu s-a putut salva adresa de contact';
$messages['movingmessage'] = 'Mutare mesaj....';
$messages['copyingmessage'] = 'Copiere mesaj...';
@@ -118,18 +118,18 @@ $messages['deleteidentityconfirm'] = 'Chiar vrei să ştergi aceasă identitate?
$messages['nodeletelastidentity'] = 'Nu puteţi şterge această identitate, este ultima.';
$messages['forbiddencharacter'] = 'Numele dosarului conţine un caracter nepermis.';
$messages['selectimportfile'] = 'Va rugăm să selectaţi fişierul pentru încărcare';
-$messages['addresswriterror'] = 'Agenda selectată nu poate fi actualizată';
+$messages['addresswriterror'] = 'Agenda selectată nu poate fi actualizată, aceasta fiind disponibila doar pentru citire.';
$messages['contactaddedtogroup'] = 'Contactele au fost adăugate cu succes la acest grup';
$messages['contactremovedfromgroup'] = 'Contactele au fost ÅŸterse cu succes din acest grup';
$messages['nogroupassignmentschanged'] = 'Atribuirile la grupuri nu au fost modificate.';
$messages['importwait'] = 'Datele sunt importate, vă rugăm să aşteptaţi...';
$messages['importformaterror'] = 'Importul a eșuat! Fișierul încărcat nu este un fișier valid pentru import de date.';
-$messages['importconfirm'] = 'Contactele $inserted au fost importate cu succes, $skipped intrări au fost ignorate deoarece ele există deja:$names';
+$messages['importconfirm'] = '<b>$inserted contacte au fost importate cu succes, $skipped intrări au fost ignorate deoarece ele există deja: $names</b>';
$messages['importconfirmskipped'] = '<b>Am sărit peste $skipped înregistrări</b>';
-$messages['opnotpermitted'] = 'Operaţia nu este permisă!';
+$messages['opnotpermitted'] = 'Operaţiunea nu este permisă!';
$messages['nofromaddress'] = 'Nu există o adresă de e-mail în identitatea selectată';
$messages['editorwarning'] = 'Trecerea în mod text a editorului va cauza pierderea formatării textului. Doriţi să continuaţi?';
-$messages['httpreceivedencrypterror'] = 'Vă rugăm să luaţi legătura cu administratorul serverului de mail, deoarece există o eroare în configuraţia acestuia. Mesajul d-voastră nu a fost trimis.';
+$messages['httpreceivedencrypterror'] = 'Vă rugăm să luaţi legătura cu administratorul serverului de mail, deoarece există o eroare în configuraţia acestuia. <b>Mesajul d-voastră nu a fost trimis.</b>';
$messages['smtpconnerror'] = 'Eroare SMTP ($code): Conexiunea cu serverul a eÅŸuat';
$messages['smtpautherror'] = 'Eroare SMTP ($code): Autentificare eşuată';
$messages['smtpfromerror'] = 'Eroare SMTP ($code): Nu s-a putut seta expeditorul "$from" ($msg)';
@@ -148,13 +148,13 @@ $messages['groupdeleted'] = 'Grupul a fost ÅŸters cu succes.';
$messages['grouprenamed'] = 'Grupul a fost redenumit cu succes.';
$messages['groupcreated'] = 'Grupul a fost creat cu succes.';
$messages['savedsearchdeleted'] = 'Căutarea salvată a fost ştearsă cu succes.';
-$messages['savedsearchdeleteerror'] = 'Nu a putut şterge căutarea salvată.';
+$messages['savedsearchdeleteerror'] = 'Nu am putut şterge căutarea salvată.';
$messages['savedsearchcreated'] = 'Căutarea a fost salvată cu succes.';
$messages['savedsearchcreateerror'] = 'Nu am putut salva căutarea.';
-$messages['messagedeleted'] = 'Mesaj(ele) a(u) fost ÅŸters(e) cu succes.';
-$messages['messagemoved'] = 'Mesaj(ele) a(u) fost mutat(e) cu succes.';
-$messages['messagecopied'] = 'Mesaj(ele) a(u) fost copiat(e) cu succes.';
-$messages['messagemarked'] = 'Mesaj(ele) a(u) fost marcat(e) cu succes.';
+$messages['messagedeleted'] = 'Mesajul (ele) a (u) fost ÅŸters (e) cu succes.';
+$messages['messagemoved'] = 'Mesajul (ele) a (u) fost mutat (e) cu succes.';
+$messages['messagecopied'] = 'Mesajul (ele) a (u) fost copiat (e) cu succes.';
+$messages['messagemarked'] = 'Mesajul (ele) a (u) fost marcat (e) cu succes.';
$messages['autocompletechars'] = 'Introdu măcar $min caractere pentru autocompletare.';
$messages['autocompletemore'] = 'Au fost găsite mai multe înregistrări. Introdu mai multe caractere.';
$messages['namecannotbeempty'] = '"Nume" nu poate fi gol.';
@@ -166,6 +166,6 @@ $messages['mispellingsfound'] = 'Au fost găsite greşeli de ortografie în mesa
$messages['parentnotwritable'] = 'Nu pot crea/muta dosarul în dosarul părinte selectat. Fără drepturi de acces.';
$messages['messagetoobig'] = 'Partea de mesaj este prea mare pentru a o procesa.';
$messages['attachmentvalidationerror'] = 'ATENȚIE! Acest atașament este suspect, fiindcă tipul lui nu coincide cu tipul declarat în mesaj. Dacă nu aveți încredere în expeditor, nu vă recomandăm să deschideți fișierul, fiindcă poate avea conținut malițios. <br/><br/><em>Așteptat: $expected; găsit: $detected</em>';
-$messages['noscriptwarning'] = 'Atenție: Serviciul de webmail necesită Javascript! Pentru al utiliza vă rugăm activați Javascript în navigator.';
+$messages['noscriptwarning'] = 'Atenție: Serviciul de webmail necesită Javascript! Pentru a-l utiliza vă rugăm activați Javascript în setările browserului.';
?>
diff --git a/program/localization/ru_RU/labels.inc b/program/localization/ru_RU/labels.inc
index 6b2b4ebca..8a136aa77 100644
--- a/program/localization/ru_RU/labels.inc
+++ b/program/localization/ru_RU/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Черновики';
$labels['sent'] = 'Отправленные';
$labels['trash'] = 'Корзина';
$labels['junk'] = 'СПÐÐœ';
-$labels['show_real_foldernames'] = 'Показывать наÑтоÑщие Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñпециальных папок';
// message listing
$labels['subject'] = 'Тема';
@@ -146,7 +145,7 @@ $labels['lastmessage'] = 'Показать поÑледнее ÑообщеÐ
$labels['backtolist'] = 'К ÑпиÑку Ñообщений';
$labels['viewsource'] = 'ИÑходный текÑÑ‚';
$labels['mark'] = 'Пометить';
-$labels['markmessages'] = 'Пометить ÑообщениÑ';
+$labels['markmessages'] = 'Пометить Ñообщение';
$labels['markread'] = 'Как прочитанное';
$labels['markunread'] = 'Как непрочитанное';
$labels['markflagged'] = 'УÑтановить флаг';
@@ -164,9 +163,9 @@ $labels['unread'] = 'Ðепрочитанные';
$labels['flagged'] = 'Помеченные';
$labels['unanswered'] = 'Ðеотвеченные';
$labels['withattachment'] = 'С вложением';
-$labels['deleted'] = 'Удаленные';
-$labels['undeleted'] = 'Ðе удаленные';
-$labels['invert'] = 'Инвертировать';
+$labels['deleted'] = 'Удаленное';
+$labels['undeleted'] = 'Ðе удалено';
+$labels['invert'] = 'Инвертное';
$labels['filter'] = 'Фильтр';
$labels['list'] = 'СпиÑок';
$labels['threads'] = 'ОбÑуждениÑ';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Режим проÑмотра';
$labels['folderactions'] = 'Операции над папкой...';
$labels['compact'] = 'Сжать';
$labels['empty'] = 'ОпуÑтошить';
-$labels['importmessages'] = 'Импорт Ñообщений';
$labels['quota'] = 'Квота';
$labels['unknown'] = 'неизвеÑтно';
@@ -205,8 +203,6 @@ $labels['resetsearch'] = 'СброÑ';
$labels['searchmod'] = 'Варианты поиÑка';
$labels['msgtext'] = 'Ð’ÑÑ‘ Ñообщение';
$labels['body'] = 'Тело пиÑьма';
-$labels['type'] = 'Тип';
-$labels['namex'] = 'ИмÑ';
$labels['openinextwin'] = 'Открыть в новом окне';
$labels['emlsave'] = 'Сохранить (.eml)';
@@ -240,7 +236,7 @@ $labels['close'] = 'Закрыть';
$labels['messageoptions'] = 'ÐаÑтройки Ñообщений...';
$labels['low'] = 'Ðизкий';
-$labels['lowest'] = 'Ðизший';
+$labels['lowest'] = 'Ðижайш.';
$labels['normal'] = 'Ðорм.';
$labels['high'] = 'Ð’Ñ‹Ñокий';
$labels['highest'] = 'Ð’Ñ‹Ñоч.';
@@ -322,7 +318,7 @@ $labels['typeblog'] = 'Блог';
$labels['typeprofile'] = 'Профиль';
$labels['addfield'] = 'Добавить поле...';
-$labels['addcontact'] = 'Добавить новый контакт';
+$labels['addcontact'] = 'Добавить выбранные контакты в ÑпиÑок контактов';
$labels['editcontact'] = 'Редактировать контакт';
$labels['contacts'] = 'Контакты';
$labels['contactproperties'] = 'СвойÑтва контакта';
@@ -351,14 +347,13 @@ $labels['grouprename'] = 'Переименовать группу';
$labels['groupdelete'] = 'Удалить группу';
$labels['groupremoveselected'] = 'Удалить выбранные контакты из группы';
-$labels['previouspage'] = 'Показать предыдущую Ñтраницу';
+$labels['previouspage'] = 'Показать предыдущий';
$labels['firstpage'] = 'Показать первую Ñтраницу';
$labels['nextpage'] = 'Показать Ñледующую Ñтраницу';
$labels['lastpage'] = 'Показать поÑледнюю Ñтраницу';
$labels['group'] = 'Группа';
$labels['groups'] = 'Группы';
-$labels['listgroup'] = 'СпиÑок членов группы';
$labels['personaladrbook'] = 'ПерÑональные адреÑа';
$labels['searchsave'] = 'Сохранить запроÑ';
@@ -477,7 +472,6 @@ $labels['spellcheckignorenums'] = 'ПропуÑкать Ñлова Ñ Ñ†Ð¸Ñ„Ñ€Ð°
$labels['spellcheckignorecaps'] = 'ПропуÑкать Ñлова из пропиÑных букв';
$labels['addtodict'] = 'Добавить в Ñловарь';
$labels['mailtoprotohandler'] = 'ЗарегиÑтрировать обработчик Ð´Ð»Ñ ÑÑылок mailto:';
-$labels['standardwindows'] = 'Обрабатывать вÑплывающие окна как обычные';
$labels['forwardmode'] = 'ПереÑылка Ñообщений';
$labels['inline'] = 'в текÑте';
$labels['asattachment'] = 'как вложение';
diff --git a/program/localization/ru_RU/messages.inc b/program/localization/ru_RU/messages.inc
index e7dd36298..f9c8c433a 100644
--- a/program/localization/ru_RU/messages.inc
+++ b/program/localization/ru_RU/messages.inc
@@ -18,23 +18,23 @@
$messages = array();
$messages['errortitle'] = 'Произошла ошибка!';
-$messages['loginfailed'] = 'ÐÐµÑƒÐ´Ð°Ñ‡Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° входа.';
-$messages['cookiesdisabled'] = 'Ваш браузер не принимает cookie.';
-$messages['sessionerror'] = 'Ваша ÑеÑÑÐ¸Ñ ÑƒÑтарела.';
+$messages['loginfailed'] = 'ÐÐµÑƒÐ´Ð°Ñ‡Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° входа';
+$messages['cookiesdisabled'] = 'Ваш броузер не принимает cookie';
+$messages['sessionerror'] = 'Ваша ÑеÑÑÐ¸Ñ ÑƒÑтарела';
$messages['storageerror'] = 'Ðеудачное Ñоединение Ñ IMAP Ñервером';
$messages['servererror'] = 'Ошибка Ñервера!';
$messages['servererrormsg'] = 'Ошибка Ñервера: $msg';
$messages['dberror'] = 'Ошибка базы данных!';
$messages['requesttimedout'] = 'Превышено Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа';
-$messages['errorreadonly'] = 'Ðевозможно выполнить операцию. Папка доÑтупна только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ.';
-$messages['errornoperm'] = 'Ðевозможно выполнить операцию. ДоÑтуп запрещён.';
+$messages['errorreadonly'] = 'Ðевозможно выполнить операцию. Папка доÑтупна только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ';
+$messages['errornoperm'] = 'Ðевозможно выполнить операцию. ДоÑтуп запрещён';
$messages['erroroverquota'] = 'Ðевозможно выполнить операцию. Ðет Ñвободного меÑта на диÑке.';
$messages['erroroverquotadelete'] = 'Ðет Ñвободного меÑта на диÑке. ИÑпользуйте SHIFT+DEL Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑообщениÑ.';
$messages['invalidrequest'] = 'Ðеверный запроÑ! Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ðµ Ñохранена.';
$messages['invalidhost'] = 'Ðеверное Ð¸Ð¼Ñ Ñервера.';
$messages['nomessagesfound'] = 'Сообщений не найдено';
$messages['loggedout'] = 'Ваша ÑеÑÑÐ¸Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð°. Ð’Ñего доброго!';
-$messages['mailboxempty'] = 'Почтовый Ñщик пуÑÑ‚.';
+$messages['mailboxempty'] = 'Почтовый Ñщик пуÑÑ‚';
$messages['refreshing'] = 'Обновление...';
$messages['loading'] = 'Загрузка...';
$messages['uploading'] = 'Файл загружаетÑÑ…';
@@ -42,28 +42,28 @@ $messages['uploadingmany'] = 'Загрузка файлов...';
$messages['loadingdata'] = 'Загрузка данных...';
$messages['checkingmail'] = 'Проверка новых Ñообщений...';
$messages['sendingmessage'] = 'Отправка ÑообщениÑ...';
-$messages['messagesent'] = 'Сообщение отправлено.';
+$messages['messagesent'] = 'Сообщение отправлено';
$messages['savingmessage'] = 'Сохранение ÑообщениÑ...';
-$messages['messagesaved'] = 'Сохранено в Черновиках.';
-$messages['successfullysaved'] = 'Сохранено.';
-$messages['addedsuccessfully'] = 'Контакт добавлен в адреÑную книгу.';
-$messages['contactexists'] = 'Контакт Ñ Ñтим адреÑом e-mail уже ÑущеÑтвует.';
+$messages['messagesaved'] = 'Сохранено в Черновиках';
+$messages['successfullysaved'] = 'Сохранено';
+$messages['addedsuccessfully'] = 'Контакт добавлен в ÑпиÑок контактов';
+$messages['contactexists'] = 'Контакт Ñ Ñтим адреÑом e-mail уже ÑущеÑтвует';
$messages['contactnameexists'] = 'Контакт Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует.';
$messages['blockedimages'] = 'Ð’ целÑÑ… безопаÑноÑти загрузка изображений заблокирована.';
$messages['encryptedmessage'] = 'Сообщение зашифровано и не может быть показано. ОбратитеÑÑŒ к админиÑтратору Ñервера.';
-$messages['nocontactsfound'] = 'Контакты не найдены.';
-$messages['contactnotfound'] = 'Требуемый контакт не найден.';
+$messages['nocontactsfound'] = 'Контакты не найдены';
+$messages['contactnotfound'] = 'Требуемый контакт не найден';
$messages['contactsearchonly'] = 'Введите уÑÐ»Ð¾Ð²Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка контактов';
-$messages['sendingfailed'] = 'Ðе удалоÑÑŒ отправить Ñообщение.';
-$messages['senttooquickly'] = 'Ð’Ñ‹ должны подождать $sec Ñек. Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ ÑообщениÑ.';
-$messages['errorsavingsent'] = 'Произошла ошибка при Ñохранении отправленного ÑообщениÑ.';
-$messages['errorsaving'] = 'Ð’ процеÑÑе ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° ошибка.';
-$messages['errormoving'] = 'Ðе удалоÑÑŒ перемеÑтить Ñообщение(Ñ).';
-$messages['errorcopying'] = 'Ðе удалоÑÑŒ Ñкопировать Ñообщение(Ñ).';
-$messages['errordeleting'] = 'Ðе удалоÑÑŒ удалить Ñообщение(Ñ).';
-$messages['errormarking'] = 'Ðе удалоÑÑŒ пометить Ñообщение(Ñ).';
+$messages['sendingfailed'] = 'Ðе удалоÑÑŒ отправить Ñообщение';
+$messages['senttooquickly'] = 'Ð’Ñ‹ должны подождать $sec Ñек. Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ ÑообщениÑ';
+$messages['errorsavingsent'] = 'Произошла ошибка при Ñохранении отправленного ÑообщениÑ';
+$messages['errorsaving'] = 'Ð’ процеÑÑе ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° ошибка';
+$messages['errormoving'] = 'Ðе удалоÑÑŒ перемеÑтить Ñообщение';
+$messages['errorcopying'] = 'Ðе удалоÑÑŒ Ñкопировать Ñообщение';
+$messages['errordeleting'] = 'Ðе удалоÑÑŒ удалить Ñообщение';
+$messages['errormarking'] = 'Ðевозможно пометить Ñообщение';
$messages['deletecontactconfirm'] = 'Ð’Ñ‹ дейÑтвительно хотите удалить выделенные контакты?';
-$messages['deletegroupconfirm'] = 'Ð’Ñ‹ дейÑтвительно хотите удалить выделенную группу?';
+$messages['deletegroupconfirm'] = 'Ð’Ñ‹ дейÑтвительно хотите удалить группу?';
$messages['deletemessagesconfirm'] = 'Ð’Ñ‹ дейÑтвительно хотите удалить выбранные ÑообщениÑ?';
$messages['deletefolderconfirm'] = 'Ð’Ñ‹ дейÑтвительно хотите удалить Ñту папку?';
$messages['purgefolderconfirm'] = 'Ð’Ñ‹ дейÑтвительно хотите удалить вÑе ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² Ñтой папке?';
@@ -73,104 +73,99 @@ $messages['folderdeleting'] = 'Удаление папки...';
$messages['foldermoving'] = 'Перемещение папки...';
$messages['foldersubscribing'] = 'ПодпиÑать папку...';
$messages['folderunsubscribing'] = 'ОтпиÑать папку...';
-$messages['formincomplete'] = 'Заполнены не вÑе Ð¿Ð¾Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ñ‹.';
-$messages['noemailwarning'] = 'ПожалуйÑта, введите корректный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты.';
-$messages['nonamewarning'] = 'ПожалуйÑта, введите имÑ.';
-$messages['nopagesizewarning'] = 'ПожалуйÑта, введите размер Ñтраницы.';
-$messages['nosenderwarning'] = 'ПожалуйÑта, введите Ð°Ð´Ñ€ÐµÑ Ñлектронной почты отправителÑ.';
-$messages['norecipientwarning'] = 'ПожалуйÑта, введите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одного получателÑ.';
+$messages['formincomplete'] = 'Заполнены не вÑе полÑ';
+$messages['noemailwarning'] = 'ПожалуйÑта, введите корректный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты';
+$messages['nonamewarning'] = 'ПожалуйÑта, введите имÑ';
+$messages['nopagesizewarning'] = 'ПожалуйÑта, введите размер Ñтраницы';
+$messages['nosenderwarning'] = 'ПожалуйÑта, введите Ð°Ð´Ñ€ÐµÑ Ñлектронной почты отправителÑ';
+$messages['norecipientwarning'] = 'ПожалуйÑта, введите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ';
$messages['nosubjectwarning'] = 'Поле Тема не заполнено. Хотите заполнить его ÑейчаÑ?';
$messages['nobodywarning'] = 'Отправить Ñообщение без текÑта?';
$messages['notsentwarning'] = 'Сообщение не было отправлено. Ð’Ñ‹ хотите отказатьÑÑ Ð¾Ñ‚ отправки?';
-$messages['noldapserver'] = 'ПожалуйÑта, выберите LDAP Ñервер Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка.';
+$messages['noldapserver'] = 'ПожалуйÑта, выберите LDAP Ñервер Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка';
$messages['nosearchname'] = 'ПожалуйÑта, введите Ð¸Ð¼Ñ Ð¸Ð»Ð¸ Ð°Ð´Ñ€ÐµÑ E-Mail';
$messages['notuploadedwarning'] = 'Ð’Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ñ‹ не полноÑтью. Подождите или отмените загрузку.';
$messages['searchsuccessful'] = 'Ðайденных Ñообщений - $nr';
$messages['contactsearchsuccessful'] = '$nr контактов найдено.';
-$messages['searchnomatch'] = 'Ðичего не найдено.';
+$messages['searchnomatch'] = 'Сообщений не найдено';
$messages['searching'] = 'ПоиÑк...';
$messages['checking'] = 'Проверка...';
-$messages['nospellerrors'] = 'ОрфографичеÑких ошибок не найдено.';
-$messages['folderdeleted'] = 'Папка удалена.';
+$messages['nospellerrors'] = 'ОрфографичеÑких ошибок не найдено';
+$messages['folderdeleted'] = 'Папка удалена';
$messages['foldersubscribed'] = 'Папка подпиÑана';
$messages['folderunsubscribed'] = 'Папка отпиÑана';
-$messages['folderpurged'] = 'Папка очищена.';
-$messages['folderexpunged'] = 'Папка Ñжата.';
-$messages['deletedsuccessfully'] = 'Удалено.';
+$messages['folderpurged'] = 'Папка удалена';
+$messages['folderexpunged'] = 'Папка очищена';
+$messages['deletedsuccessfully'] = 'Удалено';
$messages['converting'] = 'Удаление Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑообщениÑ...';
-$messages['messageopenerror'] = 'Ðевозможно загрузить Ñообщение Ñ Ñервера.';
-$messages['fileuploaderror'] = 'Ошибка загрузки файла.';
-$messages['filesizeerror'] = 'Загруженный файл больше макÑимального размера в $size.';
-$messages['copysuccess'] = 'УÑпешно Ñкопировано $nr контактов.';
-$messages['movesuccess'] = 'УÑпешно перемещено $nr контактов.';
-$messages['copyerror'] = 'Контакты не Ñкопированы.';
-$messages['moveerror'] = 'Контакты не перемещены.';
-$messages['sourceisreadonly'] = 'Данный иÑточник адреÑов только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ.';
-$messages['errorsavingcontact'] = 'Ðевозможно Ñохранить Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°.';
-$messages['movingmessage'] = 'Перемещение ÑообщениÑ(й)…';
-$messages['copyingmessage'] = 'Копирование ÑообщениÑ(й)...';
+$messages['messageopenerror'] = 'Ðевозможно загрузить Ñообщение Ñ Ñервера';
+$messages['fileuploaderror'] = 'Ðевозможно загрузить файл';
+$messages['filesizeerror'] = 'Загруженный файл больше макÑимального размера в $size';
+$messages['copysuccess'] = 'Скопировано $nr адреÑов';
+$messages['copyerror'] = 'Ðевозможно Ñкопировать адреÑа';
+$messages['sourceisreadonly'] = 'Данный иÑточник адреÑов только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ';
+$messages['errorsavingcontact'] = 'Ðевозможно Ñохранить Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°';
+$messages['movingmessage'] = 'Перемещение Ñообщений…';
+$messages['copyingmessage'] = 'Копирование Ñообщений...';
$messages['copyingcontact'] = 'Копирование контакта(ов)...';
-$messages['movingcontact'] = 'Перемещение контакта(ов)...';
-$messages['deletingmessage'] = 'Удаление ÑообщениÑ(й)...';
-$messages['markingmessage'] = 'Выделение ÑообщениÑ(й)...';
+$messages['deletingmessage'] = 'Удаление Ñообщений...';
+$messages['markingmessage'] = 'Выделение Ñообщений...';
$messages['addingmember'] = 'Добавление контакта(ов) в группу...';
$messages['removingmember'] = 'Удаление контакта(ов) из группы...';
-$messages['receiptsent'] = 'Уведомление о прочтении отправлено.';
-$messages['errorsendingreceipt'] = 'Уведомление о прочтении не отправлено.';
+$messages['receiptsent'] = 'Уведомление о прочтении отправлено';
+$messages['errorsendingreceipt'] = 'Уведомление о прочтении не отправлено';
$messages['deleteidentityconfirm'] = 'Ð’Ñ‹ на Ñамом деле хотите удалить Ñту ÑущноÑÑ‚ÑŒ?';
-$messages['nodeletelastidentity'] = 'Ð’Ñ‹ не можете удалить Ñтот профиль, он у Ð²Ð°Ñ Ð¿Ð¾Ñледний.';
-$messages['forbiddencharacter'] = 'Ð˜Ð¼Ñ Ð¿Ð°Ð¿ÐºÐ¸ Ñодержит недопуÑтимые Ñимволы.';
-$messages['selectimportfile'] = 'Выберите файл Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸.';
-$messages['addresswriterror'] = 'Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð°Ð´Ñ€ÐµÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° недоÑтупна Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи.';
-$messages['contactaddedtogroup'] = 'Контакты добавлены в Ñту группу.';
-$messages['contactremovedfromgroup'] = 'Контакты удалены из Ñтой группы.';
+$messages['nodeletelastidentity'] = 'Ð’Ñ‹ не можете удалить Ñтот профиль, он у Ð²Ð°Ñ Ð¿Ð¾Ñледний';
+$messages['forbiddencharacter'] = 'Ð˜Ð¼Ñ Ð¿Ð°Ð¿ÐºÐ¸ Ñодержит недопуÑтимые Ñимволы';
+$messages['selectimportfile'] = 'Выберите файл Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸';
+$messages['addresswriterror'] = 'Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð°Ð´Ñ€ÐµÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° недоÑтупна Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи';
+$messages['contactaddedtogroup'] = 'Контакты добавлены в группу';
+$messages['contactremovedfromgroup'] = 'Контакты удалены из группы';
$messages['nogroupassignmentschanged'] = 'РаÑпределение по группам не изменено.';
$messages['importwait'] = 'Импортирование, пожалуйÑта, подождите...';
$messages['importformaterror'] = 'Ошибка импорта! Загруженный файл имеет неизвеÑтный формат данных.';
-$messages['importconfirm'] = '<b>УÑпешно импортировано $inserted контактов</b>';
-$messages['importconfirmskipped'] = '<b>Пропущено $skipped ÑущеÑтвующих запиÑей</b>';
-$messages['importmessagesuccess'] = '$nr Ñообщений уÑпешно импортировано.';
-$messages['importmessageerror'] = 'Сбой импорта! Загруженный файл не ÑвлÑетÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ почтового Ñщика';
+$messages['importconfirm'] = '<b>УÑпешно импортировано $inserted контакт(ов), пропущено $skipped ÑущеÑтвующих</b>:<p><em>$names</em></p>';
+$messages['importconfirmskipped'] = '<b>Пропущенные $skipped ÑущеÑтвующие запиÑи</b>';
$messages['opnotpermitted'] = 'ДейÑтвие запрещено!';
-$messages['nofromaddress'] = 'Ð’ выбранном профиле не хватает адреÑа Ñлектронной почты.';
+$messages['nofromaddress'] = 'Ð’ выбранном профиле не хватает адреÑа Ñлектронной почты';
$messages['editorwarning'] = 'При переключении в редактор проÑтого текÑта вÑе форматирование будет потерÑно. Продолжить?';
-$messages['httpreceivedencrypterror'] = 'Ðа Ñервере возникла Ð½ÐµÐ¸Ð·Ð±ÐµÐ¶Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Срочно ÑвÑжитеÑÑŒ Ñ Ð’Ð°ÑˆÐ¸Ð¼ админиÑтратором. <b>Ваше Ñообщение не может быть отправлено.</b>';
-$messages['smtpconnerror'] = 'SMTP ошибка ($code): Сбой ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ñервером.';
-$messages['smtpautherror'] = 'SMTP ошибка ($code): Ошибка авторизации.';
-$messages['smtpfromerror'] = 'SMTP ошибка ($code): Ðевозможно уÑтановить Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÐµÐ»Ñ "$from" ($msg)';
-$messages['smtptoerror'] = 'SMTP ошибка ($code): Ðевозможно добавить Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ "$to" ($msg)';
-$messages['smtprecipientserror'] = 'SMTP ошибка: Ðевозможно обработать ÑпиÑок получателей.';
-$messages['smtperror'] = 'SMTP ошибка: $msg';
+$messages['httpreceivedencrypterror'] = 'Ðа Ñервере возникла Ð½ÐµÐ¸Ð·Ð±ÐµÐ¶Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Срочно ÑвÑжитеÑÑŒ Ñ Ð’Ð°ÑˆÐ¸Ð¼ админиÑтратором. <b>Ваше Ñообщение может быть не отправлено.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Соединение Ñ Ñервером Ñброшено';
+$messages['smtpautherror'] = 'SMTP Error ($code): Ошибка авторизации';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Ðевозможно уÑтановить Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÐµÐ»Ñ "$from" ($msg)';
+$messages['smtptoerror'] = 'SMTP Error ($code): Ðевозможно добавить Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ "$to" ($msg)';
+$messages['smtprecipientserror'] = 'SMTP Error: Ðевозможно обработать ÑпиÑок получателей';
+$messages['smtperror'] = 'SMTP Error ($code): $msg';
$messages['emailformaterror'] = 'Ðеверный адреÑ: $email';
-$messages['toomanyrecipients'] = 'Слишком много получателей. Уменьшите их количеÑтво до $max.';
-$messages['maxgroupmembersreached'] = 'Размер группы больше макÑимально разрешенного - $max.';
-$messages['internalerror'] = 'Произошла внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Попробуйте ещё раз.';
-$messages['contactdelerror'] = 'Ðе возможно удалить контакт(Ñ‹).';
-$messages['contactdeleted'] = 'Контакт(Ñ‹) уÑпешно удален(Ñ‹).';
+$messages['toomanyrecipients'] = 'Слишком много получателей, уменьшите их количеÑтво до $max.';
+$messages['maxgroupmembersreached'] = 'Размер группы больше макÑимально разрешенного - $max';
+$messages['internalerror'] = 'Произошла внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Попробуйте ещё раз';
+$messages['contactdelerror'] = 'Ðе могу удалить контакт(Ñ‹)';
+$messages['contactdeleted'] = 'Контакт(Ñ‹) уÑпешно удален(Ñ‹)';
$messages['contactrestoreerror'] = 'Ðе удалоÑÑŒ воÑÑтановить удалённый(е) контакт(Ñ‹).';
-$messages['contactrestored'] = 'Контакт(Ñ‹) уÑпешно воÑÑтановлен(Ñ‹).';
-$messages['groupdeleted'] = 'Группа уÑпешно удалена.';
-$messages['grouprenamed'] = 'Группа уÑпешно переименована.';
-$messages['groupcreated'] = 'Группа уÑпешно Ñоздана.';
+$messages['contactrestored'] = 'Контакт(Ñ‹) уÑпешно воÑÑтановлены.';
+$messages['groupdeleted'] = 'Группа уÑпешно удалена';
+$messages['grouprenamed'] = 'Группа уÑпешно переименована';
+$messages['groupcreated'] = 'Группа уÑпешно Ñоздана';
$messages['savedsearchdeleted'] = 'Сохранённый Ð·Ð°Ð¿Ñ€Ð¾Ñ ÑƒÑпешно удалён.';
$messages['savedsearchdeleteerror'] = 'Ðе удалоÑÑŒ удалить Ñохранённый запроÑ.';
$messages['savedsearchcreated'] = 'Сохранённый Ð·Ð°Ð¿Ñ€Ð¾Ñ ÑƒÑпешно Ñоздан.';
$messages['savedsearchcreateerror'] = 'Ðе удалоÑÑŒ Ñоздать Ñохранённый запроÑ.';
-$messages['messagedeleted'] = 'Сообщение(Ñ) уÑпешно удалено(Ñ‹).';
-$messages['messagemoved'] = 'Сообщение(Ñ) уÑпешно перемещено(Ñ‹).';
-$messages['messagecopied'] = 'Сообщение(Ñ) уÑпешно Ñкопировано(Ñ‹).';
-$messages['messagemarked'] = 'Сообщение(Ñ) уÑпешно выделено(Ñ‹).';
-$messages['autocompletechars'] = 'Введите, как минимум, $min Ñимволов Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ.';
+$messages['messagedeleted'] = 'Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÑƒÑпешно удалены';
+$messages['messagemoved'] = 'Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÑƒÑпешно перемещены';
+$messages['messagecopied'] = 'Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÑƒÑпешно Ñкопированы';
+$messages['messagemarked'] = 'Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÑƒÑпешно выделены';
+$messages['autocompletechars'] = 'Введите, как минимум, $min Ñимволов Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ';
$messages['autocompletemore'] = 'ПоиÑк возвратил Ñлишком много результатов. ПожалуйÑта, уточните.';
-$messages['namecannotbeempty'] = 'Ð˜Ð¼Ñ Ð½Ðµ может быть пуÑтым.';
-$messages['nametoolong'] = 'Слишком длинное имÑ.';
-$messages['folderupdated'] = 'Папка обновлена.';
-$messages['foldercreated'] = 'Папка Ñоздана.';
-$messages['invalidimageformat'] = 'Ðеверный формат изображениÑ.';
-$messages['mispellingsfound'] = 'Ð’ Ñообщении обнаружены орфографичеÑкие ошибки.';
+$messages['namecannotbeempty'] = 'Ð˜Ð¼Ñ Ð½Ðµ может быть пуÑтым';
+$messages['nametoolong'] = 'Слишком длинное имÑ';
+$messages['folderupdated'] = 'Папка обновлена';
+$messages['foldercreated'] = 'Папка Ñоздана';
+$messages['invalidimageformat'] = 'Ðеверный формат изображениÑ';
+$messages['mispellingsfound'] = 'Ð’ Ñообщении обнаружены орфографичеÑкие ошибки';
$messages['parentnotwritable'] = 'Ðе удаетÑÑ Ñоздать/перемеÑтить папку в выбранную родительÑкую папку. Ðет прав доÑтупа.';
$messages['messagetoobig'] = 'ЧаÑÑ‚ÑŒ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñлишком велика Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸.';
-$messages['attachmentvalidationerror'] = 'Ð’ÐИМÐÐИЕ! Это вложение ÑвлÑетÑÑ Ð¿Ð¾Ð´Ð¾Ð·Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¼, потому что его тип не Ñовпадает Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼, объÑвленным в Ñообщении. ЕÑли Ð’Ñ‹ не доверÑете отправителю, не открывайте его в браузере, поÑкольку оно может заключать в Ñебе вредоноÑное Ñодержимое.<br/><br/><em>Expected: $expected; found: $detected</em>';
+$messages['attachmentvalidationerror'] = 'Ð’ÐИМÐÐИЕ! Это приложение ÑвлÑетÑÑ Ð¿Ð¾Ð´Ð¾Ð·Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹, потому что его тип не Ñовпадает Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼, объÑвленным в Ñообщении. ЕÑли вы не доверÑете отправителю, вы не должны открывать его в браузере, поÑкольку он может Ñодержать вредоноÑный Ñодержание.<br/><br/><em>Expected: $expected; found: $detected</em>';
$messages['noscriptwarning'] = 'Внимание: Данному ÑервиÑу веб-почты требуетÑÑ Javascript! Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы его иÑпользовать необходимо включить поддержку Javascript в наÑтройках вашего браузера.';
?>
diff --git a/program/localization/si_LK/labels.inc b/program/localization/si_LK/labels.inc
index 92d33d3b7..d8cd71662 100644
--- a/program/localization/si_LK/labels.inc
+++ b/program/localization/si_LK/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'කටු සටහන්';
$labels['sent'] = 'යà·à·€à·–';
$labels['trash'] = 'ඉවතලන බඳුන';
$labels['junk'] = 'සුන්බුන්';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'මà·à¶­à·˜à¶šà·à·€';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'බහà·à¶½à·”ම් ක්â€à¶»à·’යà·...';
$labels['compact'] = 'සංයුක්ත';
$labels['empty'] = 'හිස්';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'නොදනී';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'සෙවුම යලි පිහිටවීම';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'සම්පූර්ණ පණිවිඩය';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'නව කවුළුවක විවෘත කරන්න';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'අවසà·à¶± පිටුව පෙන්වනà
$labels['group'] = 'කණ්ඩà·à¶ºà¶¸';
$labels['groups'] = 'කණ්ඩà·à¶ºà¶¸à·Š';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'පුද්ගලික ලිපිනය';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'අංක සහිත වචන නොසල
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'à·à¶¶à·Šà¶¯ කà·à·‚යට එක් කරන්න';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/si_LK/messages.inc b/program/localization/si_LK/messages.inc
index dd020b928..c3828bc64 100644
--- a/program/localization/si_LK/messages.inc
+++ b/program/localization/si_LK/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'පනිවුඩයෙන් ආකෘතීකරà
$messages['messageopenerror'] = 'පනිවුඩය පූරනය කිරීමට නොහà·à¶š';
$messages['fileuploaderror'] = 'ගොනුව ඇතුලත් කිරීමට නොහà·à¶š';
$messages['filesizeerror'] = 'ඇතුලත් කල ගොනුවෙ ප්රමà·à¶«à¶º උපරිම අගය $size ඉක්මව෠ඇත';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '$nr ලිපිනය à·ƒà·à¶»à·Šà¶®à¶šà·€ පිටපත් කරන ලදී';
+$messages['copyerror'] = 'Could not copy any addresses.';
$messages['sourceisreadonly'] = 'මෙම ලිපින මූලà·à·à·Šà¶»à¶º කියවීම සඳහ෠පමනි';
$messages['errorsavingcontact'] = 'ලිපිනය තà·à¶±à·Šà¶´à¶­à·Š කීරීමට නොහà·à¶š';
$messages['movingmessage'] = 'පණිවිඩ(ය) ගෙනයමින්...';
$messages['copyingmessage'] = 'පණිවිඩ(ය) පිටපත් කරමින්...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'පණිවිඩ(ය) මක෠දමමින්...';
$messages['markingmessage'] = 'පණිවිඩ(ය) සලකුණු කරමින්...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'ආනයනය කරමින්, කරුණà·à¶
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/sk_SK/labels.inc b/program/localization/sk_SK/labels.inc
index 465252409..10673382a 100644
--- a/program/localization/sk_SK/labels.inc
+++ b/program/localization/sk_SK/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Rozpísané';
$labels['sent'] = 'Odoslané';
$labels['trash'] = 'Kôš';
$labels['junk'] = 'Nevyžiadaná pošta';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Predmet';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Režim zobrazenia zoznamu';
$labels['folderactions'] = 'Akcie so zložkou...';
$labels['compact'] = 'ZhustiÅ¥ prieÄinok';
$labels['empty'] = 'Vyprázdniť';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Zaplnenie schránky';
$labels['unknown'] = 'neznáme';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'VyÄistiÅ¥ vyhľadávanie';
$labels['searchmod'] = 'Parametre hľadanie';
$labels['msgtext'] = 'Celá správa';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otvoriť v novom okne';
$labels['emlsave'] = 'Stiahnuť';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Posledná stránka';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupiny';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Osobné adresy';
$labels['searchsave'] = 'Uložiť vyhľadávanie';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'IgnorovaÅ¥ slová s Äíslami';
$labels['spellcheckignorecaps'] = 'Ignorovať slová písané veľkými písmenami';
$labels['addtodict'] = 'Pridať do slovníka';
$labels['mailtoprotohandler'] = 'Zaregistrovať handler pre odkazy „mailto:“';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Preposielanie správ';
$labels['inline'] = 'v tele spávy';
$labels['asattachment'] = 'ako príloha';
diff --git a/program/localization/sk_SK/messages.inc b/program/localization/sk_SK/messages.inc
index 17aaa3a53..a6f319db6 100644
--- a/program/localization/sk_SK/messages.inc
+++ b/program/localization/sk_SK/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Odstraňuje sa formátovanie správy...';
$messages['messageopenerror'] = 'Nedá sa naÄítaÅ¥ správa zo servera';
$messages['fileuploaderror'] = 'NaÄítanie súboru nebolo úspeÅ¡né';
$messages['filesizeerror'] = 'NaÄítavaný súbor prekroÄil maximálnu veľkosÅ¥ $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Úspešne sa skopírovalo $nr adries';
+$messages['copyerror'] = 'Nedá sa kopírovať žiadna adresa';
$messages['sourceisreadonly'] = 'Tento zdroj adries je len na Äítanie';
$messages['errorsavingcontact'] = 'Nedá sa uložiť adresa kontaktu';
$messages['movingmessage'] = 'Správa sa presúva...';
$messages['copyingmessage'] = 'Správa sa kopíruje...';
$messages['copyingcontact'] = 'Kopírujem kontakt(y)';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Mažem správu(y)...';
$messages['markingmessage'] = 'OznaÄujem správu(y)...';
$messages['addingmember'] = 'Pridávam kontakt(y) do skupiny...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Prebieha import, poÄkajte ...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>ÚspeÅ¡ne sa naÄítalo $inserted kontaktov, preskoÄilo sa $skipped existujúcich záznamov</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>PreskoÄených $skipped existujúcich záznamov</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operácia nie je povolená!';
$messages['nofromaddress'] = 'Zvolená identita neobsahuje e-mailovú adresu';
$messages['editorwarning'] = 'Prepnutie na editor obyÄajného textu spôsobí stratu formátovania. Chcete napriek tomu pokraÄovaÅ¥?';
diff --git a/program/localization/sl_SI/labels.inc b/program/localization/sl_SI/labels.inc
index c33ea479c..6b9ba2d41 100644
--- a/program/localization/sl_SI/labels.inc
+++ b/program/localization/sl_SI/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Osnutki';
$labels['sent'] = 'Poslano';
$labels['trash'] = 'Smeti';
$labels['junk'] = 'Nezaželena sporoÄila';
-$labels['show_real_foldernames'] = 'Prikaži prava imena za posebne mape';
// message listing
$labels['subject'] = 'Zadeva';
@@ -163,7 +162,7 @@ $labels['currpage'] = 'Trenutna stran';
$labels['unread'] = 'Neprebrano';
$labels['flagged'] = 'OznaÄeno';
$labels['unanswered'] = 'NeoznaÄeno';
-$labels['withattachment'] = 'S priponko';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Izbrisano';
$labels['undeleted'] = 'Ni izbrisano';
$labels['invert'] = 'Zamenjaj';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'NaÄin prikaza seznama';
$labels['folderactions'] = 'Upravljanje map...';
$labels['compact'] = 'Stisni';
$labels['empty'] = 'Izprazni';
-$labels['importmessages'] = 'Uvozi sporoÄila';
$labels['quota'] = 'Poraba prostora';
$labels['unknown'] = 'neznana';
@@ -205,12 +203,11 @@ $labels['resetsearch'] = 'PrekliÄi iskanje';
$labels['searchmod'] = 'Spremembe iskanja';
$labels['msgtext'] = 'Celotno sporoÄilo';
$labels['body'] = 'Vsebina sporoÄila';
-$labels['type'] = 'Tip';
$labels['openinextwin'] = 'Odpri v novem oknu';
$labels['emlsave'] = 'Prenos datoteke (.eml)';
-$labels['changeformattext'] = 'Prikaži kot golo besedilo';
-$labels['changeformathtml'] = 'Prikaži v formatu HTML';
+$labels['changeformattext'] = 'Display in plain text format';
+$labels['changeformathtml'] = 'Display in HTML format';
// message compose
$labels['editasnew'] = 'Uredi kot novo';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Zadnja stran';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupine';
-$labels['listgroup'] = 'IzpiÅ¡i seznam Älanov skupine';
$labels['personaladrbook'] = 'Stiki';
$labels['searchsave'] = 'Shrani iskanje';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'Sestavi sporoÄila z obogatenim besedilom';
$labels['htmlonreply'] = 'le pri odgovoru na sporoÄila z obogatenim besedilom';
$labels['htmlonreplyandforward'] = 'le pri posredovanju ali odgovoru na sporoÄila z obogatenim besedilom';
$labels['htmlsignature'] = 'Podpis z obogatenim besedilom';
-$labels['showemail'] = 'Prikaži e-naslove poleg imen';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Prikaži predogled';
$labels['skin'] = 'Tema uporabniškega vmesnika';
$labels['logoutclear'] = 'Izprazni mapo Smeti ob odjavi';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ne upoštevaj besed, ki vsebujejo številke';
$labels['spellcheckignorecaps'] = 'Ne upoÅ¡tevaj besed, ki vsebujejo samo velike Ärke';
$labels['addtodict'] = 'Dodaj v slovar';
$labels['mailtoprotohandler'] = 'Registriraj upravljavca protokola za e-naslov: povezave';
-$labels['standardwindows'] = 'Prikaži pojavna okna kot obiÄajna';
$labels['forwardmode'] = 'Posredovanje sporoÄil';
$labels['inline'] = 'medvrstiÄno';
$labels['asattachment'] = 'Kot priponka';
diff --git a/program/localization/sl_SI/messages.inc b/program/localization/sl_SI/messages.inc
index dc731d01b..081d912c1 100644
--- a/program/localization/sl_SI/messages.inc
+++ b/program/localization/sl_SI/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Uvažanje poteka...';
$messages['importformaterror'] = 'Uvoz ni uspel! Uvožena datoteka ni pravega formata.';
$messages['importconfirm'] = '<b>Uspešno uvoženi $inserted stiki, $skipped stikov že obstaja v imeniku</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>PreskoÄeni že obstojeÄi vnosi $skipped </b>';
-$messages['importmessagesuccess'] = 'UpeÅ¡no ste uvozili $nr sporoÄil.';
-$messages['importmessageerror'] = 'Uvoz je spodletel. Naložena datoteka ni veljavno sporoÄilo ali poÅ¡tna datoteka';
$messages['opnotpermitted'] = 'Operacija ni dovoljena.';
$messages['nofromaddress'] = 'V izbrani identiteti manjka elektronski naslov.';
$messages['editorwarning'] = 'Preklop v sploÅ¡en urejevalnik onemogoÄa uporabo izbranih nastavitev oblikovanja. Želite nadaljevati?';
diff --git a/program/localization/sq_AL/labels.inc b/program/localization/sq_AL/labels.inc
index e2cb6791b..ba9b559d8 100644
--- a/program/localization/sq_AL/labels.inc
+++ b/program/localization/sq_AL/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Drafte';
$labels['sent'] = 'Dërguar';
$labels['trash'] = 'Fshirë';
$labels['junk'] = 'Reklama';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tema';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Zvogëlo';
$labels['empty'] = 'Boshatis';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Përdorimi i diskut';
$labels['unknown'] = 'i panjohur';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Pastro kërkimin';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Shfaq grupin e fundit';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupet';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adresat Personale';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/sq_AL/messages.inc b/program/localization/sq_AL/messages.inc
index 5a18aafca..56bb9feb2 100644
--- a/program/localization/sq_AL/messages.inc
+++ b/program/localization/sq_AL/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Po i heq formatimin mesazhit...';
$messages['messageopenerror'] = 'Nuk marr dot mesazhe nga serveri';
$messages['fileuploaderror'] = 'Ngarkimi i skedarit dështoi';
$messages['filesizeerror'] = 'Skedari i ngarkuar e kalon madhësinë kufi prej $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'U kopjuan me sukses $nr adresa';
+$messages['copyerror'] = 'Nuk munda të kopjoj adresat';
$messages['sourceisreadonly'] = 'Ky burim adrese është vetëm i lexueshëm';
$messages['errorsavingcontact'] = 'Nuk e ruajta dot adresën e kontaktit';
$messages['movingmessage'] = 'Po lëviz mesazhin...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/sr_CS/labels.inc b/program/localization/sr_CS/labels.inc
index 4bdf25020..130d3a7a6 100644
--- a/program/localization/sr_CS/labels.inc
+++ b/program/localization/sr_CS/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'U pripremi';
$labels['sent'] = 'ПоÑлате';
$labels['trash'] = 'Канта';
$labels['junk'] = 'Смеће';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÐаÑлов';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'ЛиÑÑ‚ режим приказивања';
$labels['folderactions'] = 'ПоÑтавке фаÑцикле';
$labels['compact'] = 'Компакција';
$labels['empty'] = 'ИÑпразни';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Квота';
$labels['unknown'] = 'непозната';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Прикажи Ñве поруке';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Цела порука';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори у новом прозору';
$labels['emlsave'] = 'Довнлоад (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Прикажи поÑледњи Ñкуп';
$labels['group'] = 'Група';
$labels['groups'] = 'Групе';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Личне адреÑе';
$labels['searchsave'] = 'Сачувај претрагу';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'игнориши речи Ñа бројевÐ
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Додај у речник';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/sr_CS/messages.inc b/program/localization/sr_CS/messages.inc
index 016cef163..32007e6f2 100644
--- a/program/localization/sr_CS/messages.inc
+++ b/program/localization/sr_CS/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Уклањање форматирања из пору
$messages['messageopenerror'] = 'Порука Ñе не може учитати Ñа Ñервера';
$messages['fileuploaderror'] = 'Слање датотеке неуÑпешно';
$messages['filesizeerror'] = 'ПоÑлата датотека не може да прекорачи величину од $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'УÑпешно копирано $nr адреÑа';
+$messages['copyerror'] = 'Ðемогуће је иÑкопирати иједну адреÑу';
$messages['sourceisreadonly'] = 'Овај извор адреÑе је Ñамо за читање';
$messages['errorsavingcontact'] = 'ÐеуÑпело Ñнимање адреÑе контакта';
$messages['movingmessage'] = 'Премештам поруку...';
$messages['copyingmessage'] = 'Копирам поруке...';
$messages['copyingcontact'] = 'Умножава контакте...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'бришем поруке...';
$messages['markingmessage'] = 'Означавам поруке...';
$messages['addingmember'] = 'Додаје контакте у групу...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Увоз података, молимо ÑачекаÑ
$messages['importformaterror'] = 'Увоз је неуÑпешан! ПоÑлата датотека није допуштена за увоз.';
$messages['importconfirm'] = '<b>УÑпешно увезжени $inserted контакти </b>';
$messages['importconfirmskipped'] = '<b>ПреÑкочени $skipped поÑтојећи уноÑи </b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Операција није дозвољена!';
$messages['nofromaddress'] = 'ÐедоÑтаје имејл адреÑа у изабраном налогу';
$messages['editorwarning'] = 'Пребацивање на обичан текÑÑ‚ едитор ће изазвати губитак целог форматирања. Да ли желите да наÑтавите?';
diff --git a/program/localization/sv_SE/labels.inc b/program/localization/sv_SE/labels.inc
index 7169aeba8..f61433527 100644
--- a/program/localization/sv_SE/labels.inc
+++ b/program/localization/sv_SE/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Utkast';
$labels['sent'] = 'Skickat';
$labels['trash'] = 'Papperskorg';
$labels['junk'] = 'Skräp';
-$labels['show_real_foldernames'] = 'Visa verkliga namn på särskilda kataloger';
// message listing
$labels['subject'] = 'Ämne';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Visningsläge';
$labels['folderactions'] = 'Hantera kataloger';
$labels['compact'] = 'Packa';
$labels['empty'] = 'Töm';
-$labels['importmessages'] = 'Importera meddelanden';
$labels['quota'] = 'Diskutrymme';
$labels['unknown'] = 'okänt';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Återställ sökning';
$labels['searchmod'] = 'Sökalternativ';
$labels['msgtext'] = 'Hela meddelandet';
$labels['body'] = 'Innehåll';
-$labels['type'] = 'Typ';
$labels['openinextwin'] = 'Öppna i nytt fönster';
$labels['emlsave'] = 'Spara (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Visa sista sidan';
$labels['group'] = 'Grupp';
$labels['groups'] = 'Kontaktgrupper';
-$labels['listgroup'] = 'Visa gruppmedlemmar';
$labels['personaladrbook'] = 'Personliga adresser';
$labels['searchsave'] = 'Lägg till sökning';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'Ignorera ord med siffror';
$labels['spellcheckignorecaps'] = 'Ignorera ord med enbart stora bokstäver';
$labels['addtodict'] = 'Lägg till i ordlista';
$labels['mailtoprotohandler'] = 'Ange program för hantering av mailto-länkar';
-$labels['standardwindows'] = 'Hantera popup-rutor som standardfönster';
$labels['forwardmode'] = 'Vidarebefordra meddelande';
$labels['inline'] = 'Infogat';
$labels['asattachment'] = 'Bilaga';
diff --git a/program/localization/sv_SE/messages.inc b/program/localization/sv_SE/messages.inc
index d0c58a97d..63dddc548 100644
--- a/program/localization/sv_SE/messages.inc
+++ b/program/localization/sv_SE/messages.inc
@@ -42,11 +42,11 @@ $messages['uploadingmany'] = 'Överför filer...';
$messages['loadingdata'] = 'Laddar data...';
$messages['checkingmail'] = 'Hämtar nya meddelanden...';
$messages['sendingmessage'] = 'Skickar meddelande...';
-$messages['messagesent'] = 'Meddelandet har skickats.';
+$messages['messagesent'] = 'Meddelandet har skickats';
$messages['savingmessage'] = 'Sparar meddelande...';
$messages['messagesaved'] = 'Meddelandet har sparats i Utkast';
-$messages['successfullysaved'] = 'Informationen har sparats.';
-$messages['addedsuccessfully'] = 'Kontakten har lagts till i adressboken.';
+$messages['successfullysaved'] = 'Informationen har sparats';
+$messages['addedsuccessfully'] = 'Kontakten har lagts till i adressboken';
$messages['contactexists'] = 'En kontakt med den här adressen finns redan';
$messages['contactnameexists'] = 'En kontakt med det här namnet finns redan';
$messages['blockedimages'] = 'Externt länkade bilder i meddelandet har blockerats.';
@@ -85,52 +85,47 @@ $messages['notsentwarning'] = 'Meddelandet har inte skickats. Vill du avbryta me
$messages['noldapserver'] = 'Ange en LDAP-server för att söka';
$messages['nosearchname'] = 'Ange ett kontaktnamn eller en adress';
$messages['notuploadedwarning'] = 'Alla bilagor har inte överförts ännu. Vänta eller avbryt överföringen.';
-$messages['searchsuccessful'] = '$nr meddelanden hittades.';
-$messages['contactsearchsuccessful'] = '$nr kontakter hittades.';
+$messages['searchsuccessful'] = '$nr meddelanden hittades';
+$messages['contactsearchsuccessful'] = '$nr kontakter hittades';
$messages['searchnomatch'] = 'Sökningen gav inget resultat';
$messages['searching'] = 'Söker...';
$messages['checking'] = 'Kontrollerar...';
$messages['nospellerrors'] = 'Inget stavfel hittades';
-$messages['folderdeleted'] = 'Katalogen togs bort.';
-$messages['foldersubscribed'] = 'Prenumeration på katalog startad.';
-$messages['folderunsubscribed'] = 'Prenumeration på katalog avslutad.';
-$messages['folderpurged'] = 'Katalog rensad.';
-$messages['folderexpunged'] = 'Katalog tömd.';
-$messages['deletedsuccessfully'] = 'Lyckad borttagning.';
+$messages['folderdeleted'] = 'Katalogen togs bort';
+$messages['foldersubscribed'] = 'Prenumeration på katalog startad';
+$messages['folderunsubscribed'] = 'Prenumeration på katalog avslutad';
+$messages['folderpurged'] = 'Katalog rensad';
+$messages['folderexpunged'] = 'Katalog tömd';
+$messages['deletedsuccessfully'] = 'Lyckad borttagning';
$messages['converting'] = 'Tar bort formatering från meddelande...';
$messages['messageopenerror'] = 'Meddelandet kunde inte hämtas från servern';
$messages['fileuploaderror'] = 'Filuppladdning misslyckades';
$messages['filesizeerror'] = 'Den uppladdade filens storlek överstiger högsta tillåtna $size';
-$messages['copysuccess'] = '$nr kontakter har kopierats.';
-$messages['movesuccess'] = '$nr kontakter har flyttats.';
-$messages['copyerror'] = 'NÃ¥gra kontakter kunde inte kopieras.';
-$messages['moveerror'] = 'NÃ¥gra kontakter kunde inte flyttas.';
+$messages['copysuccess'] = '$nr adresser har kopierats';
+$messages['copyerror'] = 'NÃ¥gra adresser kunde inte kopieras';
$messages['sourceisreadonly'] = 'Denna adresskälla är skrivskyddad';
$messages['errorsavingcontact'] = 'Kontaktadressen kunde inte sparas';
$messages['movingmessage'] = 'Flyttar meddelande...';
$messages['copyingmessage'] = 'Kopierar meddelande...';
$messages['copyingcontact'] = 'Kopierar kontakter...';
-$messages['movingcontact'] = 'Flyttar kontakter...';
$messages['deletingmessage'] = 'Tar bort meddelande...';
$messages['markingmessage'] = 'Markerar meddelande...';
$messages['addingmember'] = 'Lägger till kontakter i gruppen...';
$messages['removingmember'] = 'Tar bort kontakter från gruppen...';
-$messages['receiptsent'] = 'Mottagarkvitto har skickats.';
+$messages['receiptsent'] = 'Mottagarkvitto har skickats';
$messages['errorsendingreceipt'] = 'Mottagarkvitto kunde inte skickas';
$messages['deleteidentityconfirm'] = 'Vill du verkligen ta bort denna identitet?';
$messages['nodeletelastidentity'] = 'Du kan inte ta bort identiteten, den är din sista.';
$messages['forbiddencharacter'] = 'Katalognamnet innehåller otillåtna tecken';
$messages['selectimportfile'] = 'Välj en fil att ladda upp';
$messages['addresswriterror'] = 'Angiven adressbok är skrivskyddad';
-$messages['contactaddedtogroup'] = 'Kontakterna har lagts till i gruppen.';
-$messages['contactremovedfromgroup'] = 'Kontakterna har tagits bort från gruppen.';
+$messages['contactaddedtogroup'] = 'Kontakterna har lagts till i gruppen';
+$messages['contactremovedfromgroup'] = 'Kontakterna har tagits bort från gruppen';
$messages['nogroupassignmentschanged'] = 'Ingen grupptillhörighet ändrades.';
$messages['importwait'] = 'Importerar, var god vänta...';
$messages['importformaterror'] = 'Importen misslyckades! Filen har inte korrekt dataformat.';
$messages['importconfirm'] = '<b>Lyckad import av $inserted kontakter</b>';
$messages['importconfirmskipped'] = '<b>Hoppade över $skipped befintliga poster</b>';
-$messages['importmessagesuccess'] = '$nr meddelanden har importerats.';
-$messages['importmessageerror'] = 'Importen misslyckades! Filen innehåller inte något meddelande eller någon brevlåda';
$messages['opnotpermitted'] = 'Otillåten operation!';
$messages['nofromaddress'] = 'Adress saknas i den valda identiteten';
$messages['editorwarning'] = 'Genom att växla till text-läge går formateringen förlorad. Vill du fortsätta?';
@@ -146,26 +141,26 @@ $messages['toomanyrecipients'] = 'Förmånga mottagare. Minska antalet till hög
$messages['maxgroupmembersreached'] = 'Antalet gruppmedlemmar får inte överstiga $max';
$messages['internalerror'] = 'Ett internt fel uppstod. Försök igen.';
$messages['contactdelerror'] = 'Kontakt kunde inte tas bort';
-$messages['contactdeleted'] = 'Kontakt borttagen.';
+$messages['contactdeleted'] = 'Kontakt borttagen';
$messages['contactrestoreerror'] = 'Borttagna kontakter kunde inte återskapas';
-$messages['contactrestored'] = 'Kontakter återskapade.';
-$messages['groupdeleted'] = 'Grupp borttagen.';
-$messages['grouprenamed'] = 'Gruppnamn ändrat.';
-$messages['groupcreated'] = 'Grupp skapad.';
-$messages['savedsearchdeleted'] = 'Sparad sökning borttagen.';
+$messages['contactrestored'] = 'Kontakter återskapade';
+$messages['groupdeleted'] = 'Grupp borttagen';
+$messages['grouprenamed'] = 'Gruppnamn ändrat';
+$messages['groupcreated'] = 'Grupp skapad';
+$messages['savedsearchdeleted'] = 'Sparad sökning borttagen';
$messages['savedsearchdeleteerror'] = 'Kunde inte ta bort sparad sökning';
-$messages['savedsearchcreated'] = 'Sparad sökning tillagd.';
+$messages['savedsearchcreated'] = 'Sparad sökning tillagd';
$messages['savedsearchcreateerror'] = 'Kunde inte lägga till sparad sökning';
-$messages['messagedeleted'] = 'Meddelande borttaget.';
-$messages['messagemoved'] = 'Meddelande flyttat.';
-$messages['messagecopied'] = 'Meddelande kopierat.';
-$messages['messagemarked'] = 'Meddelande markerat.';
+$messages['messagedeleted'] = 'Meddelande borttaget';
+$messages['messagemoved'] = 'Meddelande flyttat';
+$messages['messagecopied'] = 'Meddelande kopierat';
+$messages['messagemarked'] = 'Meddelande markerat';
$messages['autocompletechars'] = 'Ange minst $min tecken för automatisk komplettering';
$messages['autocompletemore'] = 'Flera passande informationsposter funna. Skriv fler tecken.';
$messages['namecannotbeempty'] = 'Namnet får inte vara tomt';
$messages['nametoolong'] = 'Namnet är för långt';
-$messages['folderupdated'] = 'Katalog uppdaterad.';
-$messages['foldercreated'] = 'Katalog skapad.';
+$messages['folderupdated'] = 'Katalog uppdaterad';
+$messages['foldercreated'] = 'Katalog skapad';
$messages['invalidimageformat'] = 'Ogiltigt bildfilsformat';
$messages['mispellingsfound'] = 'Stavfel hittades i meddelandet';
$messages['parentnotwritable'] = 'Katalogen kunde inte skapas eller flyttas. Åtkomsträttighet saknas.';
diff --git a/program/localization/ta_IN/labels.inc b/program/localization/ta_IN/labels.inc
index 197e80606..bc1db7d00 100644
--- a/program/localization/ta_IN/labels.inc
+++ b/program/localization/ta_IN/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'வரைவà¯à®•à®³à¯';
$labels['sent'] = 'அனà¯à®ªà¯à®ªà®¿à®¯ அஞà¯à®šà®²à¯';
$labels['trash'] = 'கà¯à®ªà¯à®ªà¯ˆ';
$labels['junk'] = 'எரிதமà¯';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'தலைபà¯à®ªà¯';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'கà¯à®±à¯à®•à®¿à®¯';
$labels['empty'] = 'காலி';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ அளவà¯';
$labels['unknown'] = 'தெரியாத';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'தேடலை மறà¯à®…மை';
$labels['searchmod'] = 'மாறà¯à®±à®¿à®•à®³à¯ˆ தேடà¯';
$labels['msgtext'] = 'à®®à¯à®´à¯ செயà¯à®¤à®¿';
$labels['body'] = 'Body';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'பà¯à®¤à¯ சாளரதà¯à®¤à®¿à®²à¯ திற';
$labels['emlsave'] = 'பதிவிறகà¯à®•à¯ (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'கடைசி கà¯à®´à¯à®µà¯ˆ காடà¯à®Ÿà
$labels['group'] = 'Group';
$labels['groups'] = 'கà¯à®´à¯à®•à¯à®•à®³à¯';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'சà¯à®¯ à®®à¯à®•à®µà®°à®¿';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ta_IN/messages.inc b/program/localization/ta_IN/messages.inc
index 22466351a..65e611f88 100644
--- a/program/localization/ta_IN/messages.inc
+++ b/program/localization/ta_IN/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'வடிவதà¯à®¤à¯ˆ நீகà¯à®•à¯à®•à®¿à®±à
$messages['messageopenerror'] = 'சேவையகதà¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ செயà¯à®¤à®¿à®¯à¯ˆ à®à®±à¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ';
$messages['fileuploaderror'] = 'கோபà¯à®ªà¯ à®à®±à¯à®±à®®à¯ தோலà¯à®µà®¿à®¯à®Ÿà®¾à®¨à¯à®¤à®¤à¯';
$messages['filesizeerror'] = 'à®à®±à¯à®±à®¿à®¯ கோபà¯à®ªà¯ அதிகபடà¯à®š அளவான $size-஠மீறியதà¯';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'வெறà¯à®±à®¿à®•à®°à®®à®¾à®• $nr à®®à¯à®•à®µà®°à®¿à®•à¯à®•à®³à¯ˆ நகலெடà¯à®¤à¯à®¤à®¤à¯';
+$messages['copyerror'] = 'எநà¯à®¤ à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®¯à¯à®®à¯ நகலெடà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ';
$messages['sourceisreadonly'] = 'இநà¯à®¤ à®®à¯à®•à®µà®°à®¿à®¯à®¿à®©à¯ மூலதà¯à®¤à¯ˆ படிகà¯à®• மடà¯à®Ÿà¯à®®à¯à®¤à®¾à®©à¯ à®®à¯à®Ÿà®¿à®¯à¯à®®à¯';
$messages['errorsavingcontact'] = 'தொடரà¯à®ªà¯ à®®à¯à®•à®µà®°à®¿à®¯à¯ˆ சேமிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ';
$messages['movingmessage'] = 'செயà¯à®¤à®¿à®¯à¯ˆ நகரà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'à®à®±à¯à®±à¯à®•à®¿à®±à®¤à¯, தயவ௠செà®
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>வெறà¯à®±à®¿à®•à®°à®®à®¾à®• $inserted தொடரà¯à®ªà¯à®•à®³à¯ à®à®±à¯à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯, à®à®±à¯à®•à®©à®µà¯‡ உளà¯à®³ $skipped தொடரà¯à®ªà¯à®•à®³à¯ தவிரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</b>: <p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'பணி அனà¯à®®à®¤à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ!';
$messages['nofromaddress'] = 'நீஙà¯à®•à®³à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®¤à¯à®¤ அடையாளதà¯à®¤à®¿à®²à¯ மினà¯à®©à®žà¯à®šà®²à¯ இலà¯à®²à¯ˆ';
$messages['editorwarning'] = 'எளிய உரை திரà¯à®¤à¯à®¤à®¿à®•à¯à®•à¯ மாறà¯à®µà®¤à®©à¯ மூலம௠எலà¯à®²à®¾ உரை வடிவஙà¯à®•à®³à¯à®®à¯ தொலைநà¯à®¤à¯ போகக௠கூடà¯à®®à¯. தொடர விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾ ?';
diff --git a/program/localization/th_TH/labels.inc b/program/localization/th_TH/labels.inc
index 85b091e5b..03b4161fb 100644
--- a/program/localization/th_TH/labels.inc
+++ b/program/localization/th_TH/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายร่าง';
$labels['sent'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸‚าออà¸';
$labels['trash'] = 'ถังขยะ';
$labels['junk'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายขยะ';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'หัวจดหมาย';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'à¹à¸šà¸šà¸¢à¹ˆà¸­';
$labels['empty'] = 'ว่างเปล่า';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'พื้นที่ใช้งาน';
$labels['unknown'] = 'ไม่ทราบ';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'ล้างà¸à¸²à¸£à¸„้นหา';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'เนื้อหา';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -476,7 +472,6 @@ $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['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'เป็นไฟล์à¹à¸™à¸š';
diff --git a/program/localization/th_TH/messages.inc b/program/localization/th_TH/messages.inc
index cf9a1cde8..826930c0e 100644
--- a/program/localization/th_TH/messages.inc
+++ b/program/localization/th_TH/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'นำเอาหารจัดรูปà¹à¸šà¸šà¹
$messages['messageopenerror'] = 'ไม่สามารถอ่านจดหมายจาภServer ได้';
$messages['fileuploaderror'] = 'à¸à¸²à¸£à¸­à¸±à¸žà¹‚หลดล้มเหลว';
$messages['filesizeerror'] = 'ไฟล์มีขนาดใหà¸à¹ˆà¹€à¸à¸´à¸™ $size';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'คัดลอà¸à¸ˆà¸”หมายจำนวน $nr ฉบับเรียบร้อย';
+$messages['copyerror'] = 'ไม่สามารถคัดลอà¸à¹„ด้';
$messages['sourceisreadonly'] = 'จดหมายนี้เป็นà¹à¸šà¸šà¸­à¹ˆà¸²à¸™à¸­à¸¢à¹ˆà¸²à¸‡à¹€à¸”ียว';
$messages['errorsavingcontact'] = 'ไม่สามารถบันทึà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¹„ด้';
$messages['movingmessage'] = 'à¸à¸³à¸¥à¸±à¸‡à¸¢à¹‰à¸²à¸¢à¸‚้อความ...';
$messages['copyingmessage'] = 'à¸à¸³à¸¥à¸±à¸‡à¸„ัดลอà¸à¸‚้อความ...';
$messages['copyingcontact'] = 'à¸à¸³à¸¥à¸±à¸‡à¸„ัดลอà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¸•à¸´à¸”ต่อ...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'à¸à¸³à¸¥à¸±à¸‡à¸¥à¸šà¸‚้อความ...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'à¸à¸³à¸¥à¸±à¸‡à¸™à¸³à¹€à¸‚้าข้อมูล,
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/tr_TR/labels.inc b/program/localization/tr_TR/labels.inc
index c62c5c079..9e78ea3fa 100644
--- a/program/localization/tr_TR/labels.inc
+++ b/program/localization/tr_TR/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Taslaklar';
$labels['sent'] = 'Giden';
$labels['trash'] = 'Çöp';
$labels['junk'] = 'Ä°stenmeyen';
-$labels['show_real_foldernames'] = 'Özel klasörler için gerçek isimleri göster';
// message listing
$labels['subject'] = 'Konu';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Liste görünümü';
$labels['folderactions'] = 'Klasör eylemleri...';
$labels['compact'] = 'Sıklaştır';
$labels['empty'] = 'BoÅŸalt';
-$labels['importmessages'] = 'Mesajları içe aktar';
$labels['quota'] = 'Disk kullanımı';
$labels['unknown'] = 'bilinmeyen';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Aramayı bitir';
$labels['searchmod'] = 'Arama detayları';
$labels['msgtext'] = 'Tüm posta gövdesi';
$labels['body'] = 'Gövde';
-$labels['type'] = 'Tip';
$labels['openinextwin'] = 'Yeni pencerede aç';
$labels['emlsave'] = 'Ä°ndir (.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Sonuncuyu göster';
$labels['group'] = 'Grup';
$labels['groups'] = 'Gruplar';
-$labels['listgroup'] = 'Grup üyelerini listele';
$labels['personaladrbook'] = 'Adresler';
$labels['searchsave'] = 'Aramayı kaydet';
@@ -406,7 +402,7 @@ $labels['htmleditor'] = 'HTML postaları oluştur';
$labels['htmlonreply'] = 'sadece HTML postaları yanıtlarken';
$labels['htmlonreplyandforward'] = 'HTML biçimindeki posta yanıtlandığında veye iletildiğinde';
$labels['htmlsignature'] = 'HTML imza';
-$labels['showemail'] = 'Eposta adresini görünüm ismi ile görüntüle';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Önizleme panelini göster';
$labels['skin'] = 'Arayüz görünümü';
$labels['logoutclear'] = 'Oturumu kapatınca Çöpü temizle';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'İçinde rakam geçen kelimleri göz ardı et
$labels['spellcheckignorecaps'] = 'Tümü büyük harf olan kelimleri göz ardı et';
$labels['addtodict'] = 'Sözlüğe Ekle';
$labels['mailtoprotohandler'] = 'mailto: bağlantıları için protokol işleyici kayıt et';
-$labels['standardwindows'] = 'Popup pencerelerini standart pencere olarak yönet';
$labels['forwardmode'] = 'Posta yönlendirme';
$labels['inline'] = 'postanın içinde';
$labels['asattachment'] = 'ek olarak';
diff --git a/program/localization/tr_TR/messages.inc b/program/localization/tr_TR/messages.inc
index 3f728b523..3b451d556 100644
--- a/program/localization/tr_TR/messages.inc
+++ b/program/localization/tr_TR/messages.inc
@@ -126,8 +126,6 @@ $messages['importwait'] = 'Aktarılıyor, lütfen bekleyin...';
$messages['importformaterror'] = 'İçe aktarım başarısız. Yüklenen dosya geçerli bir içe aktarım dosyası değil.';
$messages['importconfirm'] = '<b>$inserted kişi başarıyla aktarıldı</b>';
$messages['importconfirmskipped'] = '<b>Var olan $skipped girdi atlandı</b>';
-$messages['importmessagesuccess'] = '$nr adet mesaj başarıyla içe aktarıldı';
-$messages['importmessageerror'] = 'İçe aktarım başarısız. Yüklenen dosya geçerli bir içe aktarım dosyası değil.';
$messages['opnotpermitted'] = 'Bu iÅŸleme izin verilmedi!';
$messages['nofromaddress'] = 'Seçili kimlikte e-posta adresi yok';
$messages['editorwarning'] = 'Düz metin düzenleyiciye geçmek, metin üzerindeki bütün biçimlendirmeleri kaldıracak. Devam etmek istiyor musunuz?';
diff --git a/program/localization/uk_UA/labels.inc b/program/localization/uk_UA/labels.inc
index 6ff37ee21..6675e177e 100644
--- a/program/localization/uk_UA/labels.inc
+++ b/program/localization/uk_UA/labels.inc
@@ -19,11 +19,11 @@
$labels = array();
// login page
-$labels['welcome'] = 'ЛаÑкаво проÑимо до $product';
-$labels['username'] = 'Ім\'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача';
-$labels['password'] = 'Пароль';
-$labels['server'] = 'Сервер';
-$labels['login'] = 'Увійти';
+$labels['welcome'] = 'ЛаÑкаво проÑимо!';
+$labels['username'] = 'Ім\'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача';
+$labels['password'] = 'Пароль';
+$labels['server'] = 'Сервер';
+$labels['login'] = 'Увійти';
// taskbar
$labels['logout'] = 'Вийти';
@@ -35,37 +35,36 @@ $labels['addressbook'] = 'Контакти';
$labels['inbox'] = 'Вхідні';
$labels['drafts'] = 'Чернетки';
$labels['sent'] = 'ÐадіÑлані';
-$labels['trash'] = 'Кошик';
+$labels['trash'] = 'Видалені';
$labels['junk'] = 'Спам';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
-$labels['subject'] = 'Тема';
-$labels['from'] = 'Відправник';
-$labels['sender'] = 'Відправник';
-$labels['to'] = 'Кому';
-$labels['cc'] = 'КопіÑ';
-$labels['bcc'] = 'Прихована';
-$labels['replyto'] = 'Ð—Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ñ Ð°Ð´Ñ€ÐµÑа';
-$labels['followupto'] = 'Followup-To';
-$labels['date'] = 'Дата';
-$labels['size'] = 'Розмір';
+$labels['subject'] = 'Тема';
+$labels['from'] = 'Від';
+$labels['sender'] = 'Відправник';
+$labels['to'] = 'Кому';
+$labels['cc'] = 'КопіÑ';
+$labels['bcc'] = 'Прихована';
+$labels['replyto'] = 'Ð—Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ñ Ð°Ð´Ñ€ÐµÑа';
+$labels['followupto'] = 'У відповідь';
+$labels['date'] = 'Дата';
+$labels['size'] = 'Розмір';
$labels['priority'] = 'Пріоритет';
$labels['organization'] = 'ОрганізаціÑ';
$labels['readstatus'] = 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ';
-$labels['listoptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑпиÑку...';
+$labels['listoptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð³Ð»Ñду...';
$labels['mailboxlist'] = 'Папки';
-$labels['messagesfromto'] = 'ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· $from по $to із $count';
+$labels['messagesfromto'] = 'ЛиÑÑ‚ з $from по $to із $count';
$labels['threadsfromto'] = 'ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· $from по $to із $count';
$labels['messagenrof'] = 'ЛиÑÑ‚ $nr із $count';
$labels['fromtoshort'] = '$from – $to з $count';
$labels['copy'] = 'Копіювати';
$labels['move'] = 'ПереміÑтити';
-$labels['moveto'] = 'ПереміÑтити до...';
+$labels['moveto'] = 'ПереміÑтити лиÑÑ‚ у...';
$labels['download'] = 'Завантажити';
-$labels['open'] = 'Open';
+$labels['open'] = 'Відкрити';
$labels['showattachment'] = 'Показати';
$labels['showanyway'] = 'Ð’Ñе одно показати';
@@ -93,238 +92,236 @@ $labels['friday'] = 'П\'ÑтницÑ';
$labels['saturday'] = 'Субота';
// months short
-$labels['jan'] = 'Ñіч';
-$labels['feb'] = 'лют';
-$labels['mar'] = 'бер';
-$labels['apr'] = 'квіт';
-$labels['may'] = 'Травень';
-$labels['jun'] = 'чер';
-$labels['jul'] = 'лип';
-$labels['aug'] = 'Ñер';
-$labels['sep'] = 'вер';
-$labels['oct'] = 'жов';
-$labels['nov'] = 'лиÑ';
-$labels['dec'] = 'гр';
+$labels['jan'] = 'Ñіч';
+$labels['feb'] = 'лют';
+$labels['mar'] = 'бер';
+$labels['apr'] = 'кві';
+$labels['may'] = 'тра';
+$labels['jun'] = 'чер';
+$labels['jul'] = 'лип';
+$labels['aug'] = 'Ñер';
+$labels['sep'] = 'вер';
+$labels['oct'] = 'жов';
+$labels['nov'] = 'лиÑ';
+$labels['dec'] = 'гру';
// months long
-$labels['longjan'] = 'Січень';
-$labels['longfeb'] = 'Лютий';
-$labels['longmar'] = 'Березень';
-$labels['longapr'] = 'Квітень';
-$labels['longmay'] = 'Травень';
-$labels['longjun'] = 'Червень';
-$labels['longjul'] = 'Липень';
-$labels['longaug'] = 'Серпень';
-$labels['longsep'] = 'ВереÑень';
-$labels['longoct'] = 'Жовтень';
-$labels['longnov'] = 'ЛиÑтопад';
-$labels['longdec'] = 'Грудень';
+$labels['longjan'] = 'Січень';
+$labels['longfeb'] = 'Лютий';
+$labels['longmar'] = 'Березень';
+$labels['longapr'] = 'Квітень';
+$labels['longmay'] = 'Травень';
+$labels['longjun'] = 'Червень';
+$labels['longjul'] = 'Липень';
+$labels['longaug'] = 'Серпень';
+$labels['longsep'] = 'ВереÑень';
+$labels['longoct'] = 'Жовтень';
+$labels['longnov'] = 'ЛиÑтопад';
+$labels['longdec'] = 'Грудень';
$labels['today'] = 'Сьогодні';
// toolbar buttons
-$labels['refresh'] = 'Оновити';
-$labels['checkmail'] = 'Перевірити пошту';
-$labels['compose'] = 'ÐапиÑати лиÑта';
-$labels['writenewmessage'] = 'ÐапиÑати лиÑта';
-$labels['reply'] = 'ВідповіÑти';
-$labels['replytomessage'] = 'ВідповіÑти відправнику';
-$labels['replytoallmessage'] = 'ВідповіÑти до лиÑта або відправнику та уÑім отримувачам';
-$labels['replyall'] = 'ВідповіÑти уÑім';
-$labels['replylist'] = 'ВідповіÑти до лиÑта';
-$labels['forward'] = 'ПереÑлати';
-$labels['forwardinline'] = 'ПереÑлати у тілі лиÑта';
-$labels['forwardattachment'] = 'ПереÑлати Ñк прикріпленнÑ';
-$labels['forwardmessage'] = 'ПереÑлати повідомленнÑ';
-$labels['deletemessage'] = 'У кошик';
-$labels['movemessagetotrash'] = 'ПереміÑтити лиÑÑ‚ у кошик';
-$labels['printmessage'] = 'Друкувати';
-$labels['previousmessage'] = 'Показати попередній лиÑÑ‚';
-$labels['firstmessage'] = 'Показати перший лиÑÑ‚';
-$labels['nextmessage'] = 'Показати наÑтупний лиÑÑ‚';
-$labels['lastmessage'] = 'Показати оÑтанній лиÑÑ‚';
-$labels['backtolist'] = 'До переліку лиÑтів';
-$labels['viewsource'] = 'Вихідний текÑÑ‚';
-$labels['mark'] = 'Помітити';
-$labels['markmessages'] = 'Позначити лиÑти';
-$labels['markread'] = 'Позначити Ñк прочитане';
-$labels['markunread'] = 'Позначити Ñк непрочитане';
-$labels['markflagged'] = 'Додати зірочку';
-$labels['markunflagged'] = 'ЗнÑти зірочку';
-$labels['moreactions'] = 'Інші дії...';
-$labels['more'] = 'Ще';
-$labels['back'] = 'Ðазад';
-$labels['options'] = 'Параметри';
-
-$labels['select'] = 'Вибрати';
-$labels['all'] = 'Ð’ÑÑ–';
-$labels['none'] = 'Ðе Ñортувати';
-$labels['currpage'] = 'Поточна Ñторінка';
-$labels['unread'] = 'Ðепрочитані';
-$labels['flagged'] = 'Із зірочкою';
+$labels['refresh'] = 'Оновити';
+$labels['checkmail'] = 'Перевірити пошту';
+$labels['compose'] = 'ÐапиÑати лиÑта';
+$labels['writenewmessage'] = 'ÐапиÑати лиÑта';
+$labels['reply'] = 'ВідповіÑти';
+$labels['replytomessage'] = 'ВідповіÑти відправнику';
+$labels['replytoallmessage'] = 'ВідповіÑти відправнику та уÑім отримувачам';
+$labels['replyall'] = 'ВідповіÑти уÑім';
+$labels['replylist'] = 'ВідповіÑти уÑім отримувачам';
+$labels['forward'] = 'ПереÑлати';
+$labels['forwardinline'] = 'ПереÑлати у тілі лиÑта';
+$labels['forwardattachment'] = 'ПереÑлати Ñк додаток';
+$labels['forwardmessage'] = 'ПереÑлати лиÑÑ‚';
+$labels['deletemessage'] = 'Видалити';
+$labels['movemessagetotrash'] = 'ПереміÑтити у Видалені';
+$labels['printmessage'] = 'Друкувати';
+$labels['previousmessage'] = 'Показати попередній лиÑÑ‚';
+$labels['firstmessage'] = 'Показати перший лиÑÑ‚';
+$labels['nextmessage'] = 'Показати наÑтупний лиÑÑ‚';
+$labels['lastmessage'] = 'Показати оÑтанній лиÑÑ‚';
+$labels['backtolist'] = 'До переліку лиÑтів';
+$labels['viewsource'] = 'Вихідний текÑÑ‚';
+$labels['mark'] = 'Позначити';
+$labels['markmessages'] = 'Позначити лиÑти';
+$labels['markread'] = 'Позначити Ñк прочитаний';
+$labels['markunread'] = 'Позначити Ñк непрочитаний';
+$labels['markflagged'] = 'ПоÑтавити позначку';
+$labels['markunflagged'] = 'ЗнÑти позначку';
+$labels['moreactions'] = 'Інші дії...';
+$labels['more'] = 'Ще';
+$labels['back'] = 'Ðазад';
+$labels['options'] = 'Параметри';
+
+$labels['select'] = 'Вибрати';
+$labels['all'] = 'УÑÑ–';
+$labels['none'] = 'Ðе Ñортувати';
+$labels['currpage'] = 'Поточна Ñторінка';
+$labels['unread'] = 'Ðепрочитані';
+$labels['flagged'] = 'З позначкою';
$labels['unanswered'] = 'Без відповіді';
-$labels['withattachment'] = 'With attachment';
-$labels['deleted'] = 'Видалені';
-$labels['undeleted'] = 'Ðе видалено';
-$labels['invert'] = 'Інвертувати виділеннÑ';
-$labels['filter'] = 'Фільтр';
-$labels['list'] = 'СпиÑком';
-$labels['threads'] = 'Гілки';
-$labels['expand-all'] = 'Розкрити вÑÑ–';
-$labels['expand-unread'] = 'Розкрити непрочитані';
-$labels['collapse-all'] = 'Згорнути вÑÑ–';
-$labels['threaded'] = 'Гілками';
-
-$labels['autoexpand_threads'] = 'Розкривати гілки';
+$labels['withattachment'] = 'З додатком';
+$labels['deleted'] = 'Видалені';
+$labels['undeleted'] = 'Ðе видалені';
+$labels['invert'] = 'Інвертувати вибір';
+$labels['filter'] = 'Фільтр';
+$labels['list'] = 'СпиÑок';
+$labels['threads'] = 'Гілки';
+$labels['expand-all'] = 'Розгорнути уÑÑ–';
+$labels['expand-unread'] = 'Розгорнути непрочитані';
+$labels['collapse-all'] = 'Згорнути уÑÑ–';
+$labels['threaded'] = 'Гілками';
+
+$labels['autoexpand_threads'] = 'Ðвтоматично розгортати гілки';
$labels['do_expand'] = 'уÑÑ– гілки';
$labels['expand_only_unread'] = 'тільки з непрочитаними лиÑтами';
-$labels['fromto'] = 'Відправник/Одержувач';
-$labels['flag'] = 'Позначка';
-$labels['attachment'] = 'ВкладеннÑ';
-$labels['nonesort'] = 'Ðе Ñортувати';
-$labels['sentdate'] = 'Дата відправленнÑ';
-$labels['arrival'] = 'Дата ориманнÑ';
-$labels['asc'] = 'за зроÑтаннÑм';
-$labels['desc'] = 'за ÑпаданнÑм';
+$labels['fromto'] = 'Відправник/Одержувач';
+$labels['flag'] = 'Позначка';
+$labels['attachment'] = 'Додаток';
+$labels['nonesort'] = 'Ðе Ñортувати';
+$labels['sentdate'] = 'Дата відправленнÑ';
+$labels['arrival'] = 'Дата отриманнÑ';
+$labels['asc'] = 'За зроÑтаннÑм';
+$labels['desc'] = 'За ÑпаданнÑм';
$labels['listcolumns'] = 'Ðтрибути Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ';
$labels['listsorting'] = 'Сортувати за атрибутом';
$labels['listorder'] = 'ПорÑдок ÑортуваннÑ';
-$labels['listmode'] = 'Режим переглÑду';
+$labels['listmode'] = 'Режим переглÑду';
$labels['folderactions'] = 'Операції з папкою...';
$labels['compact'] = 'СтиÑнути';
$labels['empty'] = 'Спорожнити';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ВикориÑтано';
-$labels['unknown'] = 'невідомо';
-$labels['unlimited'] = 'без обмеженнÑ';
+$labels['unknown'] = 'невідомо';
+$labels['unlimited'] = 'без обмеженнÑ';
-$labels['quicksearch'] = 'Швидкий пошук';
-$labels['resetsearch'] = 'ОчиÑтити пошук';
-$labels['searchmod'] = 'Де шукати';
-$labels['msgtext'] = 'Ð’ уÑьому лиÑÑ‚Ñ–';
-$labels['body'] = 'Тіло повідомленнÑ';
-$labels['type'] = 'Type';
+$labels['quicksearch'] = 'Швидкий пошук';
+$labels['resetsearch'] = 'ОчиÑтити пошук';
+$labels['searchmod'] = 'Де шукати';
+$labels['msgtext'] = 'ВеÑÑŒ лиÑÑ‚';
+$labels['body'] = 'ТекÑÑ‚ лиÑта';
-$labels['openinextwin'] = 'Відкрити в новому вікні';
+$labels['openinextwin'] = 'Відкрити у новому вікні';
$labels['emlsave'] = 'Зберегти (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Показати Ñк звичайний текÑÑ‚';
+$labels['changeformathtml'] = 'Показати Ñк HTML';
// message compose
-$labels['editasnew'] = 'Редагувати Ñк новий';
-$labels['send'] = 'Відправлено';
-$labels['sendmessage'] = 'ÐадіÑлати зараз';
-$labels['savemessage'] = 'Зберегти чернетку';
-$labels['addattachment'] = 'ВклаÑти файл';
-$labels['charset'] = 'КодуваннÑ';
-$labels['editortype'] = 'Редактор';
-$labels['returnreceipt'] = 'Запит відповіді';
-$labels['dsn'] = 'ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ доÑтавку';
+$labels['editasnew'] = 'Редагувати Ñк новий';
+$labels['send'] = 'Відправлено';
+$labels['sendmessage'] = 'ÐадіÑлати зараз';
+$labels['savemessage'] = 'Зберегти чернетку';
+$labels['addattachment'] = 'Додати файл';
+$labels['charset'] = 'КодуваннÑ';
+$labels['editortype'] = 'Редактор';
+$labels['returnreceipt'] = 'Повідомити про прочитаннÑ';
+$labels['dsn'] = 'Повідомити про доÑтавку';
$labels['mailreplyintro'] = '$date, $sender напиÑав:';
-$labels['originalmessage'] = 'Оригінальне повідомленнÑ';
+$labels['originalmessage'] = 'Оригінальний лиÑÑ‚';
-$labels['editidents'] = 'Змінити данні';
-$labels['spellcheck'] = 'ОрфографіÑ';
+$labels['editidents'] = 'Змінити дані';
+$labels['spellcheck'] = 'ОрфографіÑ';
$labels['checkspelling'] = 'Перевірити орфографію';
$labels['resumeediting'] = 'Продовжити редагуваннÑ';
-$labels['revertto'] = 'Відмінити редагуваннÑ';
+$labels['revertto'] = 'Відмінити редагуваннÑ';
-$labels['attach'] = 'ВклаÑти';
-$labels['attachments'] = 'Вкладені файли';
-$labels['upload'] = 'ВклаÑти';
+$labels['attach'] = 'Додати';
+$labels['attachments'] = 'Додані файли';
+$labels['upload'] = 'Завантажити';
$labels['uploadprogress'] = '$percent ($current з $total)';
-$labels['close'] = 'Закрити';
-$labels['messageoptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð»Ð¸Ñтів';
+$labels['close'] = 'Закрити';
+$labels['messageoptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð»Ð¸Ñта';
-$labels['low'] = 'Ðизький';
-$labels['lowest'] = 'Ðайнижчий';
-$labels['normal'] = 'Ðормальний';
-$labels['high'] = 'ВиÑокий';
-$labels['highest'] = 'Ðайвищий';
+$labels['low'] = 'низький';
+$labels['lowest'] = 'найнижчий';
+$labels['normal'] = 'нормальний';
+$labels['high'] = 'виÑокий';
+$labels['highest'] = 'найвищий';
$labels['nosubject'] = '(без теми)';
$labels['showimages'] = 'Показувати зображеннÑ';
$labels['alwaysshow'] = 'Завжди показувати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ $sender';
$labels['isdraft'] = 'Це чернетка.';
$labels['andnmore'] = 'ще $nr...';
-$labels['togglemoreheaders'] = 'Завантажити ще заголовки повідомлень';
-$labels['togglefullheaders'] = 'Показати оригінальні заголовки повідомленнÑ';
+$labels['togglemoreheaders'] = 'Показати більше заголовків лиÑта';
+$labels['togglefullheaders'] = 'Показати уÑÑ– заголовки лиÑта';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Звичайний текÑÑ‚';
-$labels['savesentmessagein'] = 'зберегти надіÑланого лиÑта в';
+$labels['savesentmessagein'] = 'Зберегти надіÑланого лиÑта у';
$labels['dontsave'] = 'не зберігати';
$labels['maxuploadsize'] = 'МакÑимальний розмір файлу $size';
$labels['addcc'] = 'Додати копію';
$labels['addbcc'] = 'Додати приховану копію';
$labels['addreplyto'] = 'Додати зворотню адреÑу';
-$labels['addfollowupto'] = 'Додати Followup-To';
+$labels['addfollowupto'] = 'Додати у відповідь';
// mdn
-$labels['mdnrequest'] = 'Відправник цього лиÑта запитав про прочитаннÑ. Повідомити відправника?';
+$labels['mdnrequest'] = 'Відправник цього лиÑта запитує про його прочитаннÑ. Повідомити відправника?';
$labels['receiptread'] = 'ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ прочитаннÑ';
$labels['yourmessage'] = 'ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð’Ð°ÑˆÐ¾Ð³Ð¾ лиÑта';
-$labels['receiptnote'] = 'ЗауваженнÑ: Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¾Ð·Ð½Ð°Ñ‡Ð°Ñ” лише, що лиÑта було відкрито одержувачем, Ñ– не гарантує того, що його було прочитано.';
+$labels['receiptnote'] = 'ЗауваженнÑ: Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¾Ð·Ð½Ð°Ñ‡Ð°Ñ” лише те, що лиÑта було відкрито одержувачем, Ñ– не гарантує того, що його було прочитано.';
// address boook
-$labels['name'] = 'Ім`Ñ Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ';
-$labels['firstname'] = 'Ім`Ñ';
-$labels['surname'] = 'Прізвище';
-$labels['middlename'] = 'По-батькові';
-$labels['nameprefix'] = 'ПрефікÑ';
-$labels['namesuffix'] = 'СуфікÑ';
-$labels['nickname'] = 'Ðікнейм';
-$labels['jobtitle'] = 'ПоÑада';
-$labels['department'] = 'Відділ';
-$labels['gender'] = 'Стать';
-$labels['maidenname'] = 'Дівоче прізвище';
-$labels['email'] = 'Електронна адреÑа';
-$labels['phone'] = 'Телефон';
-$labels['address'] = 'ÐдреÑа';
-$labels['street'] = 'ВулицÑ';
-$labels['locality'] = 'МіÑто';
-$labels['zipcode'] = 'ІндекÑ';
-$labels['region'] = 'ОблаÑÑ‚ÑŒ';
-$labels['country'] = 'Страна';
-$labels['birthday'] = 'Дата народженнÑ';
-$labels['anniversary'] = 'Ювілей';
-$labels['website'] = 'Веб-Ñайт';
+$labels['name'] = 'Ім\'Ñ Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ';
+$labels['firstname'] = 'Ім\'Ñ';
+$labels['surname'] = 'Прізвище';
+$labels['middlename'] = 'По-батькові';
+$labels['nameprefix'] = 'ПрефікÑ';
+$labels['namesuffix'] = 'СуфікÑ';
+$labels['nickname'] = 'ПрізвиÑько';
+$labels['jobtitle'] = 'ПоÑада';
+$labels['department'] = 'Відділ';
+$labels['gender'] = 'Стать';
+$labels['maidenname'] = 'Дівоче прізвище';
+$labels['email'] = 'Електронна адреÑа';
+$labels['phone'] = 'Телефон';
+$labels['address'] = 'ÐдреÑа';
+$labels['street'] = 'ВулицÑ';
+$labels['locality'] = 'МіÑто';
+$labels['zipcode'] = 'ІндекÑ';
+$labels['region'] = 'ОблаÑÑ‚ÑŒ';
+$labels['country'] = 'Країна';
+$labels['birthday'] = 'День народженнÑ';
+$labels['anniversary'] = 'Ювілей';
+$labels['website'] = 'Веб-Ñайт';
$labels['instantmessenger'] = 'IM';
-$labels['notes'] = 'Примітки';
-$labels['male'] = 'чоловічий';
-$labels['female'] = 'жіночий';
-$labels['manager'] = 'Менеждер';
-$labels['assistant'] = 'Помічник';
-$labels['spouse'] = 'Шлюбний партнер';
-$labels['allfields'] = 'УÑÑ– полÑ';
-$labels['search'] = 'Пошук';
-$labels['advsearch'] = 'Розширений пошук';
-$labels['advanced'] = 'Додатково';
-$labels['other'] = 'Інше';
+$labels['notes'] = 'Примітки';
+$labels['male'] = 'чоловіча';
+$labels['female'] = 'жіноча';
+$labels['manager'] = 'Менеджер';
+$labels['assistant'] = 'Помічник';
+$labels['spouse'] = 'У шлюбі з';
+$labels['allfields'] = 'УÑÑ– полÑ';
+$labels['search'] = 'Пошук';
+$labels['advsearch'] = 'Розширений пошук';
+$labels['advanced'] = 'Додатково';
+$labels['other'] = 'Інше';
$labels['typehome'] = 'Дім';
$labels['typework'] = 'Робота';
$labels['typeother'] = 'Інше';
-$labels['typemobile'] = 'Мобільний';
-$labels['typemain'] = 'ОÑновний';
-$labels['typehomefax'] = 'Домашній факÑ';
-$labels['typeworkfax'] = 'Робочий факÑ';
-$labels['typecar'] = 'Ðвтомобіль';
+$labels['typemobile'] = 'Мобільний';
+$labels['typemain'] = 'ОÑновний';
+$labels['typehomefax'] = 'Домашній факÑ';
+$labels['typeworkfax'] = 'Робочий факÑ';
+$labels['typecar'] = 'Ðвтомобіль';
$labels['typepager'] = 'Пейджер';
$labels['typevideo'] = 'Відео';
-$labels['typeassistant'] = 'Помічник';
-$labels['typehomepage'] = 'Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка';
-$labels['typeblog'] = 'Блог';
+$labels['typeassistant'] = 'Помічник';
+$labels['typehomepage'] = 'Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка';
+$labels['typeblog'] = 'Блог';
$labels['typeprofile'] = 'Профіль';
$labels['addfield'] = 'Додати поле...';
-$labels['addcontact'] = 'Додати вибрані контакти до ÑпиÑку контактів';
+$labels['addcontact'] = 'Додати обрані контакти до ÑпиÑку контактів';
$labels['editcontact'] = 'Редагувати контакт';
$labels['contacts'] = 'Контакти';
-$labels['contactproperties'] = 'ВлаÑтивоÑÑ‚Ñ– контакта';
+$labels['contactproperties'] = 'ВлаÑтивоÑÑ‚Ñ– контакту';
$labels['personalinfo'] = 'ОÑобова інформаціÑ';
$labels['edit'] = 'Правка';
@@ -336,39 +333,38 @@ $labels['addphoto'] = 'Додати';
$labels['replacephoto'] = 'Замінити';
$labels['uploadphoto'] = 'Завантажити фотографію';
-$labels['newcontact'] = 'Створити новий контакт';
-$labels['deletecontact'] = 'Видалити вибрані контакти';
-$labels['composeto'] = 'Створити лиÑта Ð´Ð»Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð½Ð¸Ñ… контактів';
+$labels['newcontact'] = 'Створити новий контакт';
+$labels['deletecontact'] = 'Видалити обрані контакти';
+$labels['composeto'] = 'ÐапиÑати лиÑта до обраних контактів';
$labels['contactsfromto'] = 'Контакти $from - $to / $count';
-$labels['print'] = 'Друкувати';
-$labels['export'] = 'ЕкÑпортувати';
-$labels['exportall'] = 'ЕкÑпортувати вÑе';
-$labels['exportsel'] = 'ЕкÑпортувати виділені';
-$labels['exportvcards'] = 'ЕкÑпортувати контакти у формат vCard';
+$labels['print'] = 'Друкувати';
+$labels['export'] = 'ЕкÑпортувати';
+$labels['exportall'] = 'ЕкÑпортувати вÑе';
+$labels['exportsel'] = 'ЕкÑпортувати обрані';
+$labels['exportvcards'] = 'ЕкÑпортувати контакти у формат vCard';
$labels['newcontactgroup'] = 'Створити нову групу контактів';
-$labels['grouprename'] = 'Перейменувати групу';
-$labels['groupdelete'] = 'Видалити групу';
+$labels['grouprename'] = 'Перейменувати групу';
+$labels['groupdelete'] = 'Видалити групу';
$labels['groupremoveselected'] = 'Видалити обрані контакти з групи';
-$labels['previouspage'] = 'ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñторінка';
-$labels['firstpage'] = 'Перша Ñторінка';
-$labels['nextpage'] = 'ÐаÑтупна Ñторінка';
-$labels['lastpage'] = 'ОÑÑ‚Ð°Ð½Ð½Ñ Ñторінка';
+$labels['previouspage'] = 'ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñторінка';
+$labels['firstpage'] = 'Перша Ñторінка';
+$labels['nextpage'] = 'ÐаÑтупна Ñторінка';
+$labels['lastpage'] = 'ОÑÑ‚Ð°Ð½Ð½Ñ Ñторінка';
$labels['group'] = 'Група';
$labels['groups'] = 'Групи';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ПерÑональні адреÑи';
-$labels['searchsave'] = 'Зберегти пошук';
-$labels['searchdelete'] = 'Видалити пошук';
+$labels['searchsave'] = 'Зберегти пошуковий запит';
+$labels['searchdelete'] = 'Видалити пошуковий запит';
$labels['import'] = 'Імпорт';
$labels['importcontacts'] = 'Імпортувати контакти';
$labels['importfromfile'] = 'Імпортувати з файлу:';
$labels['importtarget'] = 'Додати нові контакти до адреÑної книги';
$labels['importreplace'] = 'Замінити вÑÑŽ адреÑну книгу';
-$labels['importdesc'] = 'Ви можете завантажити контакти з Ñ–Ñнуючої адреÑної книги.<br/>Ð’ даний Ñ‡Ð°Ñ Ð¼Ð¸ підтримуємо імпорт Ð°Ð´Ñ€ÐµÑ Ð² форматі візитної картки <a href="http://en.wikipedia.org/wiki/VCard"> vCard</ a> або CSV (дані розділені комами).';
+$labels['importdesc'] = 'Ви можете завантажити контакти з Ñ–Ñнуючої адреÑної книги.<br/>Ð’ даний Ñ‡Ð°Ñ Ð¼Ð¸ підтримуємо імпорт Ð°Ð´Ñ€ÐµÑ Ñƒ форматі візитної картки <a href="http://en.wikipedia.org/wiki/VCard"> vCard</ a> або CSV (дані розділені комами).';
$labels['done'] = 'Готово';
// settings
@@ -385,31 +381,31 @@ $labels['newidentity'] = 'Ðовий профіль';
$labels['newitem'] = 'Ðовий';
$labels['edititem'] = 'Редагувати';
-$labels['preferhtml'] = 'Показувати в HTML';
-$labels['defaultcharset'] = 'ÐšÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° замовчуванннÑм';
+$labels['preferhtml'] = 'Показувати у HTML';
+$labels['defaultcharset'] = 'ÐšÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° замовчуваннÑм';
$labels['htmlmessage'] = 'ЛиÑÑ‚ у HTML';
$labels['messagepart'] = 'ЧаÑтина';
$labels['digitalsig'] = 'Цифровий підпиÑ';
$labels['dateformat'] = 'Формат дати';
$labels['timeformat'] = 'Формат чаÑу';
$labels['prettydate'] = 'Дати у зручному форматі';
-$labels['setdefault'] = 'Ð’Ñтановити за замовчуваннÑм';
-$labels['autodetect'] = 'Визначати автоматично';
-$labels['language'] = 'Мова';
-$labels['timezone'] = 'ЧаÑовий поÑÑ';
-$labels['pagesize'] = 'РÑдків на Ñторінці';
+$labels['setdefault'] = 'Ð’Ñтановити за замовчуваннÑм';
+$labels['autodetect'] = 'визначити автоматично';
+$labels['language'] = 'Мова';
+$labels['timezone'] = 'ЧаÑовий поÑÑ';
+$labels['pagesize'] = 'РÑдків на Ñторінці';
$labels['signature'] = 'ПідпиÑ';
-$labels['dstactive'] = 'Літній/зимовий чаÑ';
-$labels['showinextwin'] = 'Відкрити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð² новому вікні';
-$labels['composeextwin'] = 'Створити в новому вікні';
-$labels['htmleditor'] = 'Створювати лиÑти в HTML';
-$labels['htmlonreply'] = 'тільки у відповідь на HTML повідомленнÑ';
-$labels['htmlonreplyandforward'] = 'під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ відповіді на Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ HTML';
-$labels['htmlsignature'] = 'ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð² HTML';
-$labels['showemail'] = 'Show email address with display name';
+$labels['dstactive'] = 'Літній/зимовий чаÑ';
+$labels['showinextwin'] = 'Відкрити лиÑÑ‚ у новому вікні';
+$labels['composeextwin'] = 'Створити у новому вікні';
+$labels['htmleditor'] = 'Створювати лиÑти у HTML';
+$labels['htmlonreply'] = 'тільки у відповідь на лиÑÑ‚ у HTML';
+$labels['htmlonreplyandforward'] = 'під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ відповіді на лиÑÑ‚ у HTML';
+$labels['htmlsignature'] = 'ÐŸÑ–Ð´Ð¿Ð¸Ñ Ñƒ HTML';
+$labels['showemail'] = 'Показати адреÑу з ім\'Ñм Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ';
$labels['previewpane'] = 'Показати панель переглÑду';
$labels['skin'] = 'Тема';
-$labels['logoutclear'] = 'Очищати кошик при виході';
+$labels['logoutclear'] = 'Очищати папку Видалені при виході';
$labels['logoutcompact'] = 'СтиÑкати папку Вхідні при завершенні';
$labels['uisettings'] = 'Ð†Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ñ€Ð¸Ñтувача';
$labels['serversettings'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñервера';
@@ -417,43 +413,43 @@ $labels['mailboxview'] = 'Вид інтерфейÑу';
$labels['mdnrequests'] = 'ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ прочитаннÑ';
$labels['askuser'] = 'запитати кориÑтувача';
$labels['autosend'] = 'відправлÑти автоматично';
-$labels['autosendknown'] = 'відправити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¸Ð¼ контактам, в іншому випадку запитати мене';
-$labels['autosendknownignore'] = 'відправити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¸Ð¼ контактам, в іншому випадку ігнорувати';
+$labels['autosendknown'] = 'відправити лиÑÑ‚ моїм контактам, у іншому випадку запитати мене';
+$labels['autosendknownignore'] = 'відправити лиÑÑ‚ моїм контактам, у іншому випадку ігнорувати';
$labels['ignore'] = 'ігнорувати';
$labels['readwhendeleted'] = 'Позначати Ñк прочитане при видаленні';
$labels['flagfordeletion'] = 'Позначати Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¼Ñ–ÑÑ‚ÑŒ видаленнÑ';
$labels['skipdeleted'] = 'Ðе показувати видалені лиÑти';
-$labels['deletealways'] = 'ВидалÑти лиÑти при невдалому переміщенні до кошика';
-$labels['deletejunk'] = 'ВидалÑти Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· папки СПÐÐœ минаючи Корзину';
+$labels['deletealways'] = 'ВидалÑти лиÑти при невдалому переміщенні у Видалені';
+$labels['deletejunk'] = 'ВидалÑти лиÑти з папки СПÐÐœ минаючи Видалені';
$labels['showremoteimages'] = 'Показувати віддалені зображеннÑ';
$labels['fromknownsenders'] = 'від відомих відправників';
$labels['always'] = 'завжди';
-$labels['showinlineimages'] = 'Показувати вкладені Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð½Ð¸Ð·Ñƒ лиÑта';
-$labels['autosavedraft'] = 'ÐÐ²Ñ‚Ð¾Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð½ÐµÑ‚ÐºÐ¸';
-$labels['everynminutes'] = 'кожні $n хвилин';
-$labels['refreshinterval'] = 'Оновити (перевірити нові повідомленнÑ, тощо)';
-$labels['never'] = 'ніколи';
-$labels['immediately'] = 'одразу';
+$labels['showinlineimages'] = 'Показувати додані Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð½Ð¸Ð·Ñƒ лиÑта';
+$labels['autosavedraft'] = 'ÐÐ²Ñ‚Ð¾Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð½ÐµÑ‚ÐºÐ¸';
+$labels['everynminutes'] = 'кожні $n хвилин';
+$labels['refreshinterval'] = 'Оновити (перевірити нові лиÑти, тощо)';
+$labels['never'] = 'ніколи';
+$labels['immediately'] = 'одразу';
$labels['messagesdisplaying'] = 'Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð»Ð¸Ñтів';
$labels['messagescomposition'] = 'Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð»Ð¸Ñтів';
-$labels['mimeparamfolding'] = 'Імена вкладень';
-$labels['2231folding'] = 'Повний RFC 2231 (Thunderbird)';
+$labels['mimeparamfolding'] = 'Імена додатків';
+$labels['2231folding'] = 'повний RFC 2231 (Thunderbird)';
$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
$labels['2047folding'] = 'RFC 2047 (інші поштові клієнти)';
$labels['force7bit'] = 'ВикориÑтовувати MIME ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ 8-бітних Ñимволів';
$labels['advancedoptions'] = 'Додаткові параметри';
-$labels['focusonnewmessage'] = 'ФокуÑувати вікно браузера при новому лиÑÑ‚Ñ–';
+$labels['focusonnewmessage'] = 'ФокуÑувати вікно переглÑдача при новому лиÑÑ‚Ñ–';
$labels['checkallfolders'] = 'ПеревірÑти нові лиÑти у вÑÑ–Ñ… папках';
$labels['displaynext'] = 'ПіÑÐ»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ/Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð»Ð¸Ñта відображати наÑтупний';
-$labels['defaultfont'] = 'Шрифт за замовчуваннÑм HTML повідомленнÑ';
+$labels['defaultfont'] = 'Шрифт Ð´Ð»Ñ HTML за замовчуваннÑм';
$labels['mainoptions'] = 'ОÑновні налаштуваннÑ';
-$labels['browseroptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€Ð°';
+$labels['browseroptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñдача';
$labels['section'] = 'Розділ';
$labels['maintenance'] = 'Додатково';
$labels['newmessage'] = 'Ðовий лиÑÑ‚';
$labels['signatureoptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñу';
$labels['whenreplying'] = 'При відповіді';
-$labels['replyempty'] = 'не цитувати оригінальне повідомленнÑ';
+$labels['replyempty'] = 'не цитувати оригінальний лиÑÑ‚';
$labels['replytopposting'] = 'починати новий лиÑÑ‚ перед цитованим';
$labels['replybottomposting'] = 'починати новий лиÑÑ‚ піÑÐ»Ñ Ñ†Ð¸Ñ‚Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾';
$labels['replyremovesignature'] = 'При відповіді видалÑти первинний Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð· лиÑта';
@@ -461,34 +457,33 @@ $labels['autoaddsignature'] = 'Ðвтоматично додавати підпÐ
$labels['newmessageonly'] = 'тільки до нових лиÑтів';
$labels['replyandforwardonly'] = 'тільки при відповідÑÑ… та переÑилках';
$labels['insertsignature'] = 'Додати підпиÑ';
-$labels['previewpanemarkread'] = 'Позначити переглÑнуті лиÑти Ñк прочитані';
-$labels['afternseconds'] = 'через $n Ñекунд';
-$labels['reqmdn'] = 'Завжди вимагати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ доÑтавку';
-$labels['reqdsn'] = 'Завжди вимагати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð´Ð¾Ñтавки';
-$labels['replysamefolder'] = 'РозміÑтити відповіді у тій же папці, де знаходитьÑÑ Ð¾Ñ€Ð¸Ð³Ñ–Ð½Ð°Ð»';
+$labels['previewpanemarkread'] = 'Позначити переглÑнуті лиÑти Ñк прочитані';
+$labels['afternseconds'] = 'через $n Ñекунд';
+$labels['reqmdn'] = 'Завжди повідомлÑти про прочитаннÑ';
+$labels['reqdsn'] = 'Завжди повідомлÑти про доÑтавку';
+$labels['replysamefolder'] = 'Розміщувати відповіді у папці вихідного лиÑта';
$labels['defaultabook'] = 'ÐдреÑна книга за замовчуваннÑм';
-$labels['autocompletesingle'] = 'ПропуÑкати додаткові адреÑи в автозавершенні';
+$labels['autocompletesingle'] = 'ПропуÑкати додаткові адреÑи у автозавершенні';
$labels['listnamedisplay'] = 'Виводити ÑпиÑок контактів Ñк';
-$labels['spellcheckbeforesend'] = 'Перевірити орфографію перед відправкою повідомленнÑ';
+$labels['spellcheckbeforesend'] = 'ПеревірÑти орфографію перед відправкою';
$labels['spellcheckoptions'] = 'ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ орфографії';
-$labels['spellcheckignoresyms'] = 'Ігнорувати Ñлова із Ñимволами';
-$labels['spellcheckignorenums'] = 'Ігнорувати Ñлова із чиÑлами';
-$labels['spellcheckignorecaps'] = 'Ігнорувати Ñлова із великими буквами';
+$labels['spellcheckignoresyms'] = 'Ігнорувати Ñлова з Ñимволами';
+$labels['spellcheckignorenums'] = 'Ігнорувати Ñлова з чиÑлами';
+$labels['spellcheckignorecaps'] = 'Ігнорувати Ñлова з великими літерами';
$labels['addtodict'] = 'Додати до Ñловника';
-$labels['mailtoprotohandler'] = 'ЗареєÑтрувати обробник Ð´Ð»Ñ Ð¿Ð¾Ñилань mailto';
-$labels['standardwindows'] = 'Handle popups as standard windows';
-$labels['forwardmode'] = 'ПереÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ';
+$labels['mailtoprotohandler'] = 'ЗареєÑтрувати цей Ñервер Ñк обробник поÑилань mailto:';
+$labels['forwardmode'] = 'ПереÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð»Ð¸Ñтів';
$labels['inline'] = 'у текÑÑ‚Ñ–';
-$labels['asattachment'] = 'Ñк вкладеннÑ';
+$labels['asattachment'] = 'Ñк додаток';
-$labels['folder'] = 'Папка';
-$labels['folders'] = 'Папки';
-$labels['foldername'] = 'Ðазва папки';
-$labels['subscribed'] = 'ПідпиÑані';
+$labels['folder'] = 'Папка';
+$labels['folders'] = 'Папки';
+$labels['foldername'] = 'Ðазва папки';
+$labels['subscribed'] = 'ПідпиÑані';
$labels['messagecount'] = 'ЛиÑти';
-$labels['create'] = 'Створити';
-$labels['createfolder'] = 'Створити нову папку';
-$labels['managefolders'] = 'ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°Ð¿ÐºÐ°Ð¼Ð¸';
+$labels['create'] = 'Створити';
+$labels['createfolder'] = 'Створити нову папку';
+$labels['managefolders'] = 'ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°Ð¿ÐºÐ°Ð¼Ð¸';
$labels['specialfolders'] = 'ОÑобливі папки';
$labels['properties'] = 'ВлаÑтивоÑÑ‚Ñ–';
$labels['folderproperties'] = 'ВлаÑтивоÑÑ‚Ñ– папки';
@@ -498,12 +493,12 @@ $labels['info'] = 'ІнформаціÑ';
$labels['getfoldersize'] = 'Показати розмір папки';
$labels['changesubscription'] = 'Змінити підпиÑку';
$labels['foldertype'] = 'Тип каталогу';
-$labels['personalfolder'] = 'Приватний каталог';
-$labels['otherfolder'] = 'Каталог іншого кориÑтувача';
-$labels['sharedfolder'] = 'Публічний каталог';
+$labels['personalfolder'] = 'Приватний каталог';
+$labels['otherfolder'] = 'Каталог іншого кориÑтувача';
+$labels['sharedfolder'] = 'Публічний каталог';
$labels['sortby'] = 'ВідÑортувати за';
-$labels['sortasc'] = 'Сортувати за зроÑтаннÑм';
+$labels['sortasc'] = 'Сортувати за зроÑтаннÑм';
$labels['sortdesc'] = 'Сортувати за ÑпаданнÑм';
$labels['undo'] = 'Відмінити';
@@ -515,10 +510,10 @@ $labels['license'] = 'ЛіцензіÑ';
$labels['support'] = 'Отримати підтримку';
// units
-$labels['B'] = 'б';
-$labels['KB'] = 'Кб';
-$labels['MB'] = 'Мб';
-$labels['GB'] = 'Гб';
+$labels['B'] = 'Б';
+$labels['KB'] = 'кБ';
+$labels['MB'] = 'МБ';
+$labels['GB'] = 'ГБ';
// character sets
$labels['unicode'] = 'Юнікод';
diff --git a/program/localization/uk_UA/messages.inc b/program/localization/uk_UA/messages.inc
index 2a114803f..0b52e4d6c 100644
--- a/program/localization/uk_UA/messages.inc
+++ b/program/localization/uk_UA/messages.inc
@@ -17,23 +17,23 @@
*/
$messages = array();
-$messages['errortitle'] = 'Виникла помилка!';
-$messages['loginfailed'] = 'Ðевдала Ñпроба входу';
+$messages['errortitle'] = 'Виникла помилка!';
+$messages['loginfailed'] = 'Ðевдала Ñпроба входу';
$messages['cookiesdisabled'] = 'Ваш переглÑдач не приймає cookie';
$messages['sessionerror'] = 'Ваша ÑеÑÑ–Ñ Ð·Ð°Ñтаріла';
-$messages['storageerror'] = 'Ðевдале з`Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· IMAP Ñервером';
+$messages['storageerror'] = 'Ðевдале з\'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· IMAP Ñервером';
$messages['servererror'] = 'Помилка Ñервера!';
$messages['servererrormsg'] = 'Помилка Ñервера: $msg';
$messages['dberror'] = 'Помилка бази даних!';
$messages['requesttimedout'] = 'Тайм-аут запиту';
-$messages['errorreadonly'] = 'Ðеможливо виконати операцію. Папка доÑтупна тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ.';
-$messages['errornoperm'] = 'Ðеможливо виконати операцію. ДоÑтуп заборонено';
-$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
-$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
+$messages['errorreadonly'] = 'Ðеможливо виконати операцію - папка доÑтупна тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ';
+$messages['errornoperm'] = 'Ðеможливо виконати операцію - доÑтуп заборонено';
+$messages['erroroverquota'] = 'Ðеможливо виконати операцію - немає вільного міÑÑ†Ñ Ð½Ð° диÑку';
+$messages['erroroverquotadelete'] = 'Ðемає вільного міÑÑ†Ñ Ð½Ð° диÑку - натиÑніть SHIFT+DEL Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð»Ð¸Ñта';
$messages['invalidrequest'] = 'Ðевірний запит! Дані не збережено.';
-$messages['invalidhost'] = 'Ðевірне ім\'Ñ Ñерверу.';
+$messages['invalidhost'] = 'Ðевірне ім\'Ñ Ñервера';
$messages['nomessagesfound'] = 'ЛиÑтів не знайдено';
-$messages['loggedout'] = 'Вашу ÑеÑÑ–ÑŽ завершено. Ð’Ñього найкращого!';
+$messages['loggedout'] = 'Вашу ÑеÑÑ–ÑŽ завершено. УÑього найкращого!';
$messages['mailboxempty'] = 'Поштова Ñкринька порожнÑ';
$messages['refreshing'] = 'ОновленнÑ...';
$messages['loading'] = 'ЗавантаженнÑ...';
@@ -44,16 +44,16 @@ $messages['checkingmail'] = 'Перевірка нових лиÑтів...';
$messages['sendingmessage'] = 'Відправка лиÑта...';
$messages['messagesent'] = 'ЛиÑÑ‚ уÑпішно відправлено';
$messages['savingmessage'] = 'Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð»Ð¸Ñта...';
-$messages['messagesaved'] = 'Збережено в Чернетках';
+$messages['messagesaved'] = 'Збережено у Чернетках';
$messages['successfullysaved'] = 'Збережено';
$messages['addedsuccessfully'] = 'Контакт уÑпішно доданий до ÑпиÑку контактів';
$messages['contactexists'] = 'Контакт з такою електронною адреÑою вже Ñ–Ñнує';
-$messages['contactnameexists'] = 'Контакт з таким Ñамим іменем вже Ñ–Ñнує.';
-$messages['blockedimages'] = 'З метою безпеки Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð· зовнішніх джерел заблоковано у цьому лиÑÑ‚Ñ–.';
-$messages['encryptedmessage'] = 'ЛиÑÑ‚ зашифровано Ñ– не може бути відображено.';
+$messages['contactnameexists'] = 'Контакт з таким ім\'Ñм вже Ñ–Ñнує';
+$messages['blockedimages'] = 'З метою безпеки у цьому лиÑÑ‚Ñ– заблоковано Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð· зовнішніх джерел';
+$messages['encryptedmessage'] = 'ЛиÑÑ‚ зашифровано Ñ– не може бути відображено';
$messages['nocontactsfound'] = 'Контакти не знайдені';
$messages['contactnotfound'] = 'Запитаний контакт не знайдений';
-$messages['contactsearchonly'] = 'Введіть деÑкі критерії пошуку, щоб знайти контакти';
+$messages['contactsearchonly'] = 'Щоб знайти контакти введіть критерії пошуку';
$messages['sendingfailed'] = 'Ðе вдалоÑÑ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ лиÑта';
$messages['senttooquickly'] = 'Будь лаÑка, зачекайте $sec Ñекунд Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²ÐºÐ¸ лиÑта';
$messages['errorsavingsent'] = 'Помилка при збереженні відправленого лиÑта';
@@ -62,20 +62,20 @@ $messages['errormoving'] = 'Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити лиÑÑ‚Ð
$messages['errorcopying'] = 'Ðе вдалоÑÑ Ð·ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ñ‚Ð¸ лиÑти';
$messages['errordeleting'] = 'Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ лиÑти';
$messages['errormarking'] = 'Ðе вдалоÑÑ Ð¿Ð¾Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ лиÑти';
-$messages['deletecontactconfirm'] = 'Ви дійÑно бажаєте видалити вибрані контакти?';
+$messages['deletecontactconfirm'] = 'Ви дійÑно бажаєте видалити обрані контакти?';
$messages['deletegroupconfirm'] = 'Ви дійÑно хочете видалити обрану групу?';
-$messages['deletemessagesconfirm'] = 'Ви дійÑно бажаєте видалити вибрані лиÑти?';
+$messages['deletemessagesconfirm'] = 'Ви дійÑно бажаєте видалити обрані лиÑти?';
$messages['deletefolderconfirm'] = 'Ви дійÑно бажаєте видалити цю папку?';
-$messages['purgefolderconfirm'] = 'Ви дійÑно бажаєте видалити вÑÑ– лиÑти у цій папці?';
+$messages['purgefolderconfirm'] = 'Ви дійÑно бажаєте видалити уÑÑ– лиÑти у цій папці?';
$messages['contactdeleting'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñƒ(ів)...';
$messages['groupdeleting'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð¸...';
$messages['folderdeleting'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ð¿ÐºÐ¸...';
$messages['foldermoving'] = 'ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð°Ð¿ÐºÐ¸...';
$messages['foldersubscribing'] = 'ПідпиÑати папку...';
$messages['folderunsubscribing'] = 'ВідпиÑати папку...';
-$messages['formincomplete'] = 'Заповнено не вÑÑ– полÑ';
+$messages['formincomplete'] = 'Заповнено не уÑÑ– полÑ';
$messages['noemailwarning'] = 'Будь лаÑка, введіть коректну адреÑу електронної пошти';
-$messages['nonamewarning'] = 'Будь лаÑка, введіть ім`Ñ';
+$messages['nonamewarning'] = 'Будь лаÑка, введіть ім\'Ñ';
$messages['nopagesizewarning'] = 'Будь лаÑка, введіть розмір Ñторінки';
$messages['nosenderwarning'] = 'Будь лаÑка, введіть адреÑу електронної пошти відправника';
$messages['norecipientwarning'] = 'Будь лаÑка, вкажіть принаймні одного отримувача';
@@ -83,10 +83,10 @@ $messages['nosubjectwarning'] = 'Ðе вказано тему лиÑта. БаÐ
$messages['nobodywarning'] = 'Відправити лиÑта без текÑту?';
$messages['notsentwarning'] = 'ЛиÑÑ‚ не було відправлено. Ви бажаєте відхилити відправку?';
$messages['noldapserver'] = 'Будь лаÑка, виберіть LDAP Ñервер Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ';
-$messages['nosearchname'] = 'Будь лаÑка, введіть ім`Ñ Ñ‡Ð¸ електронну адреÑу';
-$messages['notuploadedwarning'] = 'ДеÑкі Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð½Ñ Ð½Ðµ було завантажено. Будь лаÑка, почекайте або відмініть завантаженнÑ.';
-$messages['searchsuccessful'] = 'Зайдено $nr лиÑтів';
-$messages['contactsearchsuccessful'] = '$nr контактів знайдено.';
+$messages['nosearchname'] = 'Будь лаÑка, введіть ім\'Ñ Ñ‡Ð¸ електронну адреÑу';
+$messages['notuploadedwarning'] = 'ДеÑкі додатки не було завантажено. Будь лаÑка, почекайте або відмініть завантаженнÑ.';
+$messages['searchsuccessful'] = 'Знайдено $nr лиÑтів';
+$messages['contactsearchsuccessful'] = '$nr контактів знайдено';
$messages['searchnomatch'] = 'ЛиÑтів не знайдено';
$messages['searching'] = 'Пошук...';
$messages['checking'] = 'Перевірка...';
@@ -98,43 +98,38 @@ $messages['folderpurged'] = 'Папка видалена';
$messages['folderexpunged'] = 'Папка очищена';
$messages['deletedsuccessfully'] = 'Видалено уÑпішно';
$messages['converting'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ...';
-$messages['messageopenerror'] = 'Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· Ñервера';
+$messages['messageopenerror'] = 'Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ лиÑÑ‚ з Ñервера';
$messages['fileuploaderror'] = 'Ðе вдалоÑÑ Ð²ÐºÐ»Ð°Ñти файл';
-$messages['filesizeerror'] = 'Розмір вибраного файлу перевищує макÑимально дозволений ($size)';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['filesizeerror'] = 'Розмір обраного файлу перевищує макÑимально дозволений ($size)';
+$messages['copysuccess'] = 'Скопійовано $nr адреÑ';
+$messages['copyerror'] = 'Ðе вдалоÑÑ Ñкопіювати жодну адреÑу';
$messages['sourceisreadonly'] = 'Дане джерело Ð°Ð´Ñ€ÐµÑ Ð´Ð¾Ñтупне лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ';
$messages['errorsavingcontact'] = 'Ðеможливо зберегти адреÑу контакту';
$messages['movingmessage'] = 'ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð»Ð¸Ñта...';
$messages['copyingmessage'] = 'ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð»Ð¸Ñта...';
$messages['copyingcontact'] = 'ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñƒ(ів)...';
-$messages['movingcontact'] = 'Moving contact(s)...';
-$messages['deletingmessage'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð»Ð¸Ñта (ів)';
-$messages['markingmessage'] = 'ÐŸÐ¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ð¸Ñта (ів)';
+$messages['deletingmessage'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð»Ð¸Ñта(ів)';
+$messages['markingmessage'] = 'ÐŸÐ¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ð¸Ñта(ів)';
$messages['addingmember'] = 'Ð”Ð¾Ð´Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñƒ(ів) до групи...';
$messages['removingmember'] = 'Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñƒ(ів) з групи...';
$messages['receiptsent'] = 'ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾';
$messages['errorsendingreceipt'] = 'Ðе вдалоÑÑ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ прочитаннÑ';
$messages['deleteidentityconfirm'] = 'Ви дійÑно бажаєте видалити цей профіль?';
-$messages['nodeletelastidentity'] = 'Ви не можете видалити цей профіль, він у Ð’Ð°Ñ Ð¾Ñтанній.';
-$messages['forbiddencharacter'] = 'Ім\'Ñ Ð¿Ð°Ð¿ÐºÐ¸ міÑтить заборонені Ñимволи';
+$messages['nodeletelastidentity'] = 'Ви не можете видалити оÑтанній профіль';
+$messages['forbiddencharacter'] = 'Ім\'Ñ Ð¿Ð°Ð¿ÐºÐ¸ міÑтить неприпуÑтимі Ñимволи';
$messages['selectimportfile'] = 'Виберіть файл Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ';
$messages['addresswriterror'] = 'Обрана адреÑна книга недоÑтупна Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу';
$messages['contactaddedtogroup'] = 'Контакти уÑпішно додано до цієї групи';
-$messages['contactremovedfromgroup'] = 'УКонтакти уÑпішно видалено з цієї групи';
-$messages['nogroupassignmentschanged'] = 'Розподіл за групами не змінено.';
-$messages['importwait'] = 'ІмпортуваннÑ, будь лаÑка, зачекайте...';
+$messages['contactremovedfromgroup'] = 'Контакти уÑпішно видалено з цієї групи';
+$messages['nogroupassignmentschanged'] = 'Розподіл за групами не змінено';
+$messages['importwait'] = 'Зачекайте, будь лаÑка, відбуваєтьÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ...';
$messages['importformaterror'] = 'Помилка імпорту! Завантажений файл має невідомий формат даних.';
$messages['importconfirm'] = '<b>УÑпішно імпортовано $inserted контактів, пропущено $skipped Ñ–Ñнуючих</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Пропущені $skipped наÑвні запиÑи</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Ð”Ñ–Ñ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ð°!';
-$messages['nofromaddress'] = 'Ð’ обраному профілі не виÑтачає адреÑи електронної пошти';
-$messages['editorwarning'] = 'ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð² режим звичайного текÑту Ñпричинить втрату вÑього форматуваннÑ. Продовжити?';
-$messages['httpreceivedencrypterror'] = 'Помилка конфігурації. Ðегайно звернітьÑÑ Ð´Ð¾ адмініÑтратора. <b>Ваше Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ðµ буде відправлено.</b>';
+$messages['nofromaddress'] = 'У обраному профілі не виÑтачає адреÑи електронної пошти';
+$messages['editorwarning'] = 'ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ñƒ режим звичайного текÑту Ñпричинить втрату вÑього форматуваннÑ. Продовжити?';
+$messages['httpreceivedencrypterror'] = 'Помилка конфігурації. Ðегайно звернітьÑÑ Ð´Ð¾ адмініÑтратора. <b>Ваш лиÑÑ‚ не буде відправлено.</b>';
$messages['smtpconnerror'] = 'Помилка SMTP-Ñервера ($code): Ðе вдалоÑÑ Ð·\'єднатиÑÑ Ð· Ñервером';
$messages['smtpautherror'] = 'Помилка SMTP-Ñервера ($code): Ðевдала Ñпроба автентифікації';
$messages['smtpfromerror'] = 'Помилка SMTP-Ñервера ($code): Ðе вдалоÑÑ Ð²ÐºÐ°Ð·Ð°Ñ‚Ð¸ відправника "$from" ($msg)';
@@ -142,35 +137,35 @@ $messages['smtptoerror'] = 'Помилка SMTP-Ñервера ($code): Ðе вÐ
$messages['smtprecipientserror'] = 'Помилка SMTP: Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ ÑпиÑок отримувачів';
$messages['smtperror'] = 'Помилка SMTP: $msg';
$messages['emailformaterror'] = 'Ðевірна електронна адреÑа: $email';
-$messages['toomanyrecipients'] = 'Занадто багато отримувачів. Зменшіть Ñ—Ñ… чиÑло до $max.';
-$messages['maxgroupmembersreached'] = 'ЧиÑло Ð°Ð´Ñ€ÐµÑ Ñƒ групі перевищило макÑимум у $max.';
-$messages['internalerror'] = 'Виникла Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Будь лаÑка, Ñпробуйте ще раз';
+$messages['toomanyrecipients'] = 'Занадто багато отримувачів. Зменшіть Ñ—Ñ… чиÑло до $max';
+$messages['maxgroupmembersreached'] = 'ЧиÑло Ð°Ð´Ñ€ÐµÑ Ñƒ групі перевищило макÑимум у $max';
+$messages['internalerror'] = 'Виникла Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Будь лаÑка, Ñпробуйте ще раз.';
$messages['contactdelerror'] = 'Ðеможливо видалити контакт(и)';
$messages['contactdeleted'] = 'Контакт(и) видалено уÑпішно';
-$messages['contactrestoreerror'] = 'Ðеможливо відновити видалений(Ñ–) контакт(и).';
-$messages['contactrestored'] = 'Контакт(и) вдало відновлено.';
+$messages['contactrestoreerror'] = 'Ðеможливо відновити видалений(Ñ–) контакт(и)';
+$messages['contactrestored'] = 'Контакт(и) уÑпішно відновлено';
$messages['groupdeleted'] = 'Група видалена уÑпішно';
$messages['grouprenamed'] = 'Група перейменована уÑпішно';
$messages['groupcreated'] = 'Група Ñтворена уÑпішно';
-$messages['savedsearchdeleted'] = 'Збережений пошук вдало видалено.';
-$messages['savedsearchdeleteerror'] = 'Ðеможливо видалити збережений пошук.';
-$messages['savedsearchcreated'] = 'Збережений пошук вдало Ñтворено.';
-$messages['savedsearchcreateerror'] = 'Ðе вдалоÑÑŒ Ñтворити збережений пошук.';
+$messages['savedsearchdeleted'] = 'Збережений пошуковий запит уÑпішно видалено';
+$messages['savedsearchdeleteerror'] = 'Ðеможливо видалити збережений пошуковий запит';
+$messages['savedsearchcreated'] = 'Пошуковий запит уÑпішно збережено';
+$messages['savedsearchcreateerror'] = 'Ðе вдалоÑÑŒ зберегти пошуковий запит';
$messages['messagedeleted'] = 'ЛиÑÑ‚(и) видалено уÑпішно';
$messages['messagemoved'] = 'ЛиÑÑ‚(и) переміщено уÑпішно';
$messages['messagecopied'] = 'ЛиÑÑ‚(и) Ñкопійовано уÑпішно';
-$messages['messagemarked'] = 'ЛиÑÑ‚(и) помічено уÑпішно';
-$messages['autocompletechars'] = 'Введіть щонайменьше $min Ñимволів Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ';
+$messages['messagemarked'] = 'ЛиÑÑ‚(и) позначено уÑпішно';
+$messages['autocompletechars'] = 'Введіть щонайменше $min Ñимволів Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ';
$messages['autocompletemore'] = 'Знайдено багато відповідних запиÑів. Будь лаÑка введіть більше Ñимволів.';
-$messages['namecannotbeempty'] = 'Ð†Ð¼â€™Ñ Ð½Ðµ може бути пуÑтим';
-$messages['nametoolong'] = 'Занадто довге ім’Ñ';
+$messages['namecannotbeempty'] = 'Ім\'Ñ Ð½Ðµ може бути пуÑтим';
+$messages['nametoolong'] = 'Занадто довге ім\'Ñ';
$messages['folderupdated'] = 'Папка відновлена';
$messages['foldercreated'] = 'Папка Ñтворена';
$messages['invalidimageformat'] = 'Ðевірний формат зображеннÑ';
-$messages['mispellingsfound'] = 'Знайдено орфографічні помилки у повідомленні.';
-$messages['parentnotwritable'] = 'Ðеможливо Ñтворити/переміÑтити папку до обраної батьківÑької папки. Ðема прав доÑтупу.';
-$messages['messagetoobig'] = 'ЧаÑтина Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð½Ð°Ð´Ñ‚Ð¾ велика Ð´Ð»Ñ Ð¾Ð¿Ñ€Ð°Ñ†ÑŽÐ²Ð°Ð½Ð½Ñ.';
-$messages['attachmentvalidationerror'] = 'УВÐГÐ! Це Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð½Ñ Ñ” підозрілим, тому що його тип не збігаєтьÑÑ Ð· типом, оголошеним у повідомленні. Якщо ви не довірÑєте відправнику, ви не повинні відкривати його в браузері, оÑкільки його вміÑÑ‚ може бути шкідливим.<br/><br/><em>Очікуване: $expected; знайдене: $detected </em>';
-$messages['noscriptwarning'] = 'Увага: Даний клієнт електронної пошти потрібує Javascript! Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб викориÑтовувати його необхідно включити підтримку Javascript в налаштуваннÑÑ… вашого браузера.';
+$messages['mispellingsfound'] = 'У лиÑÑ‚Ñ– знайдено орфографічні помилки';
+$messages['parentnotwritable'] = 'Ðеможливо Ñтворити/переміÑтити папку до обраної батьківÑької папки - немає прав доÑтупу';
+$messages['messagetoobig'] = 'ЧаÑтина лиÑта занадто велика Ð´Ð»Ñ Ð¾Ð¿Ñ€Ð°Ñ†ÑŽÐ²Ð°Ð½Ð½Ñ';
+$messages['attachmentvalidationerror'] = 'УВÐГÐ! Цей додаток Ñ” підозрілим бо його тип (визначений Ñк <em>$detected</em>) не збігаєтьÑÑ Ð· оголошеним у лиÑÑ‚Ñ– типом (<em>$expected</em>). Ðе відкривайте цей додаток Ñкщо Ñ” Ñумніви - його вміÑÑ‚ може бути шкідливим!<br/><br/>';
+$messages['noscriptwarning'] = 'Увага: Цей клієнт електронної пошти потрібує JavaScript. Ð”Ð»Ñ Ð¹Ð¾Ð³Ð¾ викориÑÑ‚Ð°Ð½Ð½Ñ Ð½ÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð¾ включити підтримку JavaScript у налаштуваннÑÑ… переглÑдача.';
?>
diff --git a/program/localization/ur_PK/labels.inc b/program/localization/ur_PK/labels.inc
new file mode 100644
index 000000000..797c98f11
--- /dev/null
+++ b/program/localization/ur_PK/labels.inc
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/<lang>/labels.inc |
+ | |
+ | Localization file of the Roundcube Webmail client |
+ | Copyright (C) 2005-2013, 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['welcome'] = ' $product میں خوش آمدید';
+$labels['server'] = 'سَروَر';
+$labels['mail'] = 'میل';
+$labels['settings'] = 'ترتیبات';
+$labels['download'] = 'ڈاؤن لوڈ';
+$labels['showanyway'] = 'جیسا بھی ÛÛ’ ظاÛر کر دیں';
+$labels['markread'] = 'جیسے Ù¾Ú‘Ú¾ لیا ÛÙˆ';
+$labels['markunread'] = 'جیسے ابھی Ù†Û Ù¾Ú‘Ú¾Ø§ ÛÙˆ';
+$labels['more'] = 'مزید';
+$labels['back'] = 'واپس';
+$labels['select'] = 'مۃنتخب کریں';
+$labels['all'] = 'تمام';
+$labels['none'] = 'کوئی Ù†Ûیں';
+$labels['currpage'] = 'Ù…ÙˆØ¬ÙˆØ¯Û Ø­ÙØ­Û';
+$labels['unread'] = 'Ù†Ûیں پڑھا';
+$labels['deleted'] = 'ختم ÛÙˆ گیا';
+$labels['undeleted'] = 'ختم Ù†Ûیں ÛÙوا';
+$labels['invert'] = 'شکل تبدیل کریں';
+$labels['list'] = 'Ù„Ùسٹ';
+$labels['expand-all'] = 'تمام کھولیں';
+$labels['attachment'] = 'Ù…Ùنسلَک Ø´ÙدÛ';
+$labels['nonesort'] = 'کوئی Ù†Ûیں';
+?>
diff --git a/program/localization/ur_PK/messages.inc b/program/localization/ur_PK/messages.inc
new file mode 100644
index 000000000..da4e39679
--- /dev/null
+++ b/program/localization/ur_PK/messages.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/<lang>/messages.inc |
+ | |
+ | Localization file of the Roundcube Webmail client |
+ | Copyright (C) 2005-2013, 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/messages/
+*/
+?>
diff --git a/program/localization/vi_VN/labels.inc b/program/localization/vi_VN/labels.inc
index aad0dafe6..f1cf95149 100644
--- a/program/localization/vi_VN/labels.inc
+++ b/program/localization/vi_VN/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'Thư nháp';
$labels['sent'] = 'Äã gá»­i';
$labels['trash'] = 'Sá»t rác';
$labels['junk'] = 'Thư rác';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tiêu Ä‘á»';
@@ -194,7 +193,6 @@ $labels['listmode'] = 'Xem dạng danh sách';
$labels['folderactions'] = 'Thao tác với thư mục';
$labels['compact'] = 'Nén';
$labels['empty'] = 'Trống';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Lượng đĩa sử dụng';
$labels['unknown'] = 'Không rõ';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'Thiết lập lại tìm kiếm';
$labels['searchmod'] = 'Tìm kiếm với từ khóa và ký tự đặc biệt [() : " - ]';
$labels['msgtext'] = 'Toàn bộ thư';
$labels['body'] = 'Ná»™i dung thÆ°';
-$labels['type'] = 'Type';
$labels['openinextwin'] = 'Mở trong khung cửa mới';
$labels['emlsave'] = 'Tải vỠtheo định dạng .eml';
@@ -357,7 +354,6 @@ $labels['lastpage'] = 'Hiển thị trang cuối';
$labels['group'] = 'Nhóm';
$labels['groups'] = 'Các nhóm';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Các địa chỉ cá nhân';
$labels['searchsave'] = 'Lưu tìm kiếm';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = 'BỠqua các từ kèm số';
$labels['spellcheckignorecaps'] = 'BỠqua các từ được viết hoa';
$labels['addtodict'] = 'Thêm vào từ điển';
$labels['mailtoprotohandler'] = 'Xác định cách xử lý giao thức mailto: liên kết';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Chuyển tiếp thư';
$labels['inline'] = 'nội tuyến';
$labels['asattachment'] = 'dạng gửi kèm';
diff --git a/program/localization/vi_VN/messages.inc b/program/localization/vi_VN/messages.inc
index 769a21afd..50bf71846 100644
--- a/program/localization/vi_VN/messages.inc
+++ b/program/localization/vi_VN/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = 'Loại bỠđịnh dạng...';
$messages['messageopenerror'] = 'Không thể tải thư từ máy chủ';
$messages['fileuploaderror'] = 'Tải tập tin lên thất bại';
$messages['filesizeerror'] = 'Tập tin được tải lên vượt quá dung lượng tối đa....';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = 'Sao chép thành công $nr địa chỉ.';
+$messages['copyerror'] = 'Không thể sao chép đỉa chỉ nào.';
$messages['sourceisreadonly'] = 'Nguồn địa chỉ này chỉ cho Ä‘á»c';
$messages['errorsavingcontact'] = 'Không thể lưu địa chỉ liên lạc';
$messages['movingmessage'] = 'Äang chuyển thÆ°...';
$messages['copyingmessage'] = 'Äang sao chép thÆ°...';
$messages['copyingcontact'] = 'Äang sao chép liên lạc...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Äang xóa thÆ°...';
$messages['markingmessage'] = 'Äánh dấu thÆ°...';
$messages['addingmember'] = 'Äang thêm liên lạc vào nhóm...';
@@ -129,8 +126,6 @@ $messages['importwait'] = 'Äang nhập, xin chá»...';
$messages['importformaterror'] = 'Nhập dữ liệu lỗi. Tệp tin vừa tải lên không phải tệp dữ liệu chính xác.';
$messages['importconfirm'] = 'Äã nhập $inserted liên hệ đã chèn vào thành công.';
$messages['importconfirmskipped'] = 'Äã bá» qua được $skipped mục tồn tại.';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Thao tác không được cho phép!';
$messages['nofromaddress'] = 'Äịa chỉ email mất ở trong nhận dạng đã chá»n';
$messages['editorwarning'] = 'Việc chuyển soạn thảo text gốc sẽ gây ra toàn bộ định dạng text đã có bị mất. Bạn có muốn tiếp tục không?';
diff --git a/program/localization/zh_CN/labels.inc b/program/localization/zh_CN/labels.inc
index b568a7008..23a42b96d 100644
--- a/program/localization/zh_CN/labels.inc
+++ b/program/localization/zh_CN/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'è‰ç¨¿ç®±';
$labels['sent'] = 'å·²å‘é€é‚®ä»¶';
$labels['trash'] = '已删除邮件';
$labels['junk'] = '垃圾邮件';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '主题';
@@ -194,7 +193,6 @@ $labels['listmode'] = '列表视图样å¼';
$labels['folderactions'] = '文件夹æ“作...';
$labels['compact'] = '压缩';
$labels['empty'] = '清空';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = '邮箱容é‡';
$labels['unknown'] = '未知';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = '清空';
$labels['searchmod'] = '修改æœç´¢';
$labels['msgtext'] = 'æ•´å°é‚®ä»¶';
$labels['body'] = '正文';
-$labels['type'] = 'Type';
$labels['openinextwin'] = '在新窗å£ä¸­æ‰“å¼€';
$labels['emlsave'] = '下载(.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = '最åŽä¸€é¡µ';
$labels['group'] = '分组';
$labels['groups'] = '分组';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = '个人通讯录';
$labels['searchsave'] = 'ä¿å­˜æœç´¢';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = '忽略带数字的å•è¯';
$labels['spellcheckignorecaps'] = '忽略所有大写字æ¯çš„å•è¯';
$labels['addtodict'] = '添加到字典中';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = '邮件转å‘æ–¹å¼';
$labels['inline'] = '内嵌';
$labels['asattachment'] = '作为附件';
diff --git a/program/localization/zh_CN/messages.inc b/program/localization/zh_CN/messages.inc
index 4c47f833e..43703e311 100644
--- a/program/localization/zh_CN/messages.inc
+++ b/program/localization/zh_CN/messages.inc
@@ -19,115 +19,117 @@
$messages = array();
$messages['errortitle'] = 'å‘生错误ï¼';
$messages['loginfailed'] = '登录失败。';
-$messages['cookiesdisabled'] = '您的æµè§ˆå™¨ä¸æŽ¥å— cookies。';
-$messages['sessionerror'] = '会è¯å·²è¿‡æœŸã€‚';
-$messages['storageerror'] = '连接到邮件æœåŠ¡å™¨å¤±è´¥ã€‚';
+$messages['cookiesdisabled'] = '您的æµè§ˆå™¨ä¸æ”¯æŒ Cookies。';
+$messages['sessionerror'] = '会è¯æ— æ•ˆæˆ–已过期。';
+$messages['storageerror'] = '连接至 IMAP æœåŠ¡å™¨å¤±è´¥ã€‚';
$messages['servererror'] = 'æœåŠ¡å™¨é”™è¯¯ï¼';
-$messages['servererrormsg'] = 'æœåŠ¡å™¨é”™è¯¯: $msg';
+$messages['servererrormsg'] = 'æœåŠ¡å™¨é”™è¯¯ï¼š$msg';
$messages['dberror'] = 'æ•°æ®åº“错误ï¼';
$messages['requesttimedout'] = '请求超时';
-$messages['errorreadonly'] = 'ä¸å¯å¯¹åªè¯»æ–‡ä»¶å¤¹è¿›è¡Œæ“作。';
-$messages['errornoperm'] = 'æ— æƒé™æ“作';
-$messages['invalidrequest'] = '无效的请求ï¼æ•°æ®ä¿å­˜å¤±è´¥ã€‚';
-$messages['invalidhost'] = 'éžæ³•ä¸»æœºå。';
+$messages['errorreadonly'] = '无法完æˆæ“作。文件夹为åªè¯»ã€‚';
+$messages['errornoperm'] = '无法完æˆæ“作。没有æƒé™ã€‚';
+$messages['erroroverquota'] = '无法完æˆæ“作。没有足够的ç£ç›˜ç©ºé—´ã€‚';
+$messages['erroroverquotadelete'] = '没有足够的ç£ç›˜ç©ºé—´ã€‚请使用 SHIFT+DEL 删除一部分邮件。';
+$messages['invalidrequest'] = '请求无效ï¼æœªä¿å­˜æ•°æ®ã€‚';
+$messages['invalidhost'] = '无效的主机å。';
$messages['nomessagesfound'] = '此邮件夹内无邮件。';
$messages['loggedout'] = '您已æˆåŠŸæ³¨é”€ï¼Œå†è§ï¼';
-$messages['mailboxempty'] = '邮件夹为空';
-$messages['refreshing'] = '刷新中...';
-$messages['loading'] = '正在载入...';
+$messages['mailboxempty'] = '邮件夹为空。';
+$messages['refreshing'] = '正在刷新...';
+$messages['loading'] = '正在登录...';
$messages['uploading'] = '正在上传文件...';
$messages['uploadingmany'] = '正在上传文件...';
$messages['loadingdata'] = '正在载入数æ®...';
$messages['checkingmail'] = '正在检查新邮件...';
-$messages['sendingmessage'] = '正在å‘é€é‚®ä»¶...';
-$messages['messagesent'] = '邮件å‘é€æˆåŠŸã€‚';
+$messages['sendingmessage'] = '正在å‘é€...';
+$messages['messagesent'] = '邮件已å‘é€ã€‚';
$messages['savingmessage'] = '正在ä¿å­˜é‚®ä»¶...';
-$messages['messagesaved'] = '邮件已暂存到è‰ç¨¿ç®±ã€‚';
+$messages['messagesaved'] = '邮件已暂存至è‰ç¨¿ç®±ã€‚';
$messages['successfullysaved'] = 'ä¿å­˜æˆåŠŸã€‚';
-$messages['addedsuccessfully'] = 'æˆåŠŸæ·»åŠ è”系人。';
+$messages['addedsuccessfully'] = 'è”系人已添加。';
$messages['contactexists'] = '当å‰è”系人的电å­é‚®ä»¶åœ°å€å·²å­˜åœ¨ã€‚';
-$messages['contactnameexists'] = '已存在åŒåçš„è”系人。';
-$messages['blockedimages'] = '为ä¿æŠ¤éšç§ï¼Œæ­¤é‚®ä»¶ä¸­çš„远程图片未显示。';
+$messages['contactnameexists'] = '已存在åŒåè”系人。';
+$messages['blockedimages'] = '由于ä¿æŠ¤éšç§ï¼Œæ­¤é‚®ä»¶ä¸­çš„远程图片未予显示。';
$messages['encryptedmessage'] = '抱歉ï¼è¯¥é‚®ä»¶å·²è¢«åŠ å¯†ï¼Œæ— æ³•æ˜¾ç¤ºã€‚';
$messages['nocontactsfound'] = '未找到è”系人。';
$messages['contactnotfound'] = '未找到指定的è”系人。';
$messages['contactsearchonly'] = '请输入è”系人的æœç´¢æ¡ä»¶';
$messages['sendingfailed'] = 'å‘é€å¤±è´¥ã€‚';
-$messages['senttooquickly'] = '您需è¦ç­‰å¾… $sec 秒æ‰èƒ½å‘é€é‚®ä»¶ã€‚';
+$messages['senttooquickly'] = '您需è¦ç­‰å¾…$sec秒æ‰èƒ½å‘é€é‚®ä»¶ã€‚';
$messages['errorsavingsent'] = 'ä¿å­˜å·²å‘é€é‚®ä»¶æ—¶å‘生错误。';
$messages['errorsaving'] = 'ä¿å­˜æ—¶å‘生错误。';
$messages['errormoving'] = '无法移动邮件。';
$messages['errorcopying'] = '无法å¤åˆ¶é‚®ä»¶ã€‚';
$messages['errordeleting'] = '无法删除邮件。';
$messages['errormarking'] = '无法标记邮件。';
-$messages['deletecontactconfirm'] = '确定è¦åˆ é™¤å·²é€‰ä¸­çš„è”系人?';
-$messages['deletegroupconfirm'] = '确定è¦åˆ é™¤ä»¥é€‰ä¸­çš„组?';
-$messages['deletemessagesconfirm'] = '确定è¦åˆ é™¤å·²é€‰ä¸­çš„邮件?';
-$messages['deletefolderconfirm'] = '确定è¦åˆ é™¤å·²é€‰ä¸­çš„邮件夹?';
-$messages['purgefolderconfirm'] = '是å¦ç¡®è®¤è¦åˆ é™¤å½“å‰é‚®ä»¶å¤¹ä¸­çš„所有邮件?';
+$messages['deletecontactconfirm'] = '是å¦åˆ é™¤é€‰ä¸­çš„è”系人?';
+$messages['deletegroupconfirm'] = '是å¦åˆ é™¤é€‰ä¸­çš„群组?';
+$messages['deletemessagesconfirm'] = '是å¦åˆ é™¤é€‰ä¸­çš„邮件?';
+$messages['deletefolderconfirm'] = '是å¦åˆ é™¤é€‰ä¸­çš„邮件夹?';
+$messages['purgefolderconfirm'] = '是å¦åˆ é™¤å½“å‰é‚®ä»¶å¤¹ä¸­çš„全部邮件?';
$messages['contactdeleting'] = '正在删除è”系人...';
-$messages['groupdeleting'] = '正在删除组...';
+$messages['groupdeleting'] = '正在删除群组...';
$messages['folderdeleting'] = '正在删除文件夹...';
$messages['foldermoving'] = '正在移动文件夹...';
$messages['foldersubscribing'] = '订阅文件夹中...';
$messages['folderunsubscribing'] = '退订中...';
-$messages['formincomplete'] = '当å‰è¡¨å•æœªå¡«å†™å®Œæ•´ï¼Œè¯·å®Œæ•´å¡«å†™ã€‚';
+$messages['formincomplete'] = '表å•æœªå¡«å†™å®Œæ•´ã€‚';
$messages['noemailwarning'] = '请输入一个有效的邮件地å€ã€‚';
-$messages['nonamewarning'] = '请输入å字。';
-$messages['nopagesizewarning'] = '请输入æ¯é¡µæ˜¾ç¤ºçš„邮件数é‡';
+$messages['nonamewarning'] = '请输入å称。';
+$messages['nopagesizewarning'] = '请输入æ¯é¡µæ˜¾ç¤ºçš„邮件数é‡ã€‚';
$messages['nosenderwarning'] = '请输入å‘件人地å€ã€‚';
-$messages['norecipientwarning'] = '至少需è¦ä¸€ä¸ªæ”¶ä»¶äººã€‚';
+$messages['norecipientwarning'] = '至少输入一个收件人。';
$messages['nosubjectwarning'] = '主题为空。您è¦è¾“入一个主题å—?';
-$messages['nobodywarning'] = 'è¦å‘é€æ— æ­£æ–‡çš„邮件å—?';
+$messages['nobodywarning'] = 'è¦å‘é€æ²¡æœ‰æ­£æ–‡çš„邮件å—?';
$messages['notsentwarning'] = '邮件未å‘é€ã€‚您确定è¦ç¦»å¼€å¹¶èˆå¼ƒå½“å‰é‚®ä»¶å—?';
-$messages['noldapserver'] = '请选择一个LDAPæœåŠ¡å™¨è¿›è¡ŒæŸ¥æ‰¾ã€‚';
-$messages['nosearchname'] = '请输入一个è”系人姓å或电å­é‚®ä»¶åœ°å€ã€‚';
-$messages['notuploadedwarning'] = '附件还没有全部上传,请等待或者å–消上传。';
+$messages['noldapserver'] = '请选择一个用æ¥æŸ¥æ‰¾çš„ LDAP æœåŠ¡å™¨ã€‚';
+$messages['nosearchname'] = '请输入è”系人姓å或电å­é‚®ä»¶åœ°å€ã€‚';
+$messages['notuploadedwarning'] = '附件尚未全部上传,请è€å¿ƒç­‰å¾…或者å–消上传。';
$messages['searchsuccessful'] = '共找到 $nr å°é‚®ä»¶ã€‚';
$messages['contactsearchsuccessful'] = '共找到 $nr ä½è”系人。';
-$messages['searchnomatch'] = '未找到任何符åˆæ¡ä»¶çš„邮件';
+$messages['searchnomatch'] = '未找到任何符åˆæ¡ä»¶çš„邮件。';
$messages['searching'] = '正在æœç´¢...';
$messages['checking'] = '正在检查...';
-$messages['nospellerrors'] = '未å‘现拼写错误';
-$messages['folderdeleted'] = '文件夹已被æˆåŠŸåˆ é™¤ã€‚';
-$messages['foldersubscribed'] = 'æˆåŠŸè®¢é˜…文件夹。';
-$messages['folderunsubscribed'] = 'æˆåŠŸé€€è®¢çš„文件夹。';
-$messages['folderpurged'] = 'æˆåŠŸæ¸…空文件夹。';
+$messages['nospellerrors'] = '未å‘现拼写错误。';
+$messages['folderdeleted'] = '删除文件夹æˆåŠŸã€‚';
+$messages['foldersubscribed'] = '订阅文件夹æˆåŠŸã€‚';
+$messages['folderunsubscribed'] = '退订文件夹æˆåŠŸã€‚';
+$messages['folderpurged'] = '清空文件夹æˆåŠŸã€‚';
$messages['folderexpunged'] = '文件夹已清空。';
$messages['deletedsuccessfully'] = '删除æˆåŠŸã€‚';
$messages['converting'] = 'æ ¼å¼è½¬æ¢ä¸­...';
-$messages['messageopenerror'] = '无法从æœåŠ¡å™¨ä¸ŠåŠ è½½é‚®ä»¶å†…容。';
+$messages['messageopenerror'] = '无法从æœåŠ¡å™¨åŠ è½½é‚®ä»¶å†…容。';
$messages['fileuploaderror'] = '文件上传失败。';
$messages['filesizeerror'] = '上传的文件超过了 $size 的大å°é™åˆ¶ã€‚';
$messages['copysuccess'] = 'æˆåŠŸå¤åˆ¶ $nr 个地å€ã€‚';
$messages['copyerror'] = '无法å¤åˆ¶åœ°å€ã€‚';
$messages['sourceisreadonly'] = 'æºåœ°å€ä¸ºåªè¯»ã€‚';
-$messages['errorsavingcontact'] = '无法ä¿å­˜è”系人的地å€ã€‚';
-$messages['movingmessage'] = '移动邮件到...';
-$messages['copyingmessage'] = 'å¤åˆ¶é‚®ä»¶åˆ°...';
-$messages['copyingcontact'] = 'å¤åˆ¶è”系人...';
+$messages['errorsavingcontact'] = '无法ä¿å­˜è”系人地å€ã€‚';
+$messages['movingmessage'] = '正在移动邮件...';
+$messages['copyingmessage'] = '正在å¤åˆ¶é‚®ä»¶...';
+$messages['copyingcontact'] = '正在å¤åˆ¶è”系人...';
$messages['deletingmessage'] = '正在删除邮件...';
$messages['markingmessage'] = '正在标记邮件...';
-$messages['addingmember'] = '正在添加è”系人到组...';
-$messages['removingmember'] = '正在从组中删除è”系人...';
-$messages['receiptsent'] = 'æˆåŠŸå‘é€äº†ä¸€ä¸ªå·²è¯»å›žæ‰§ã€‚';
-$messages['errorsendingreceipt'] = '无法å‘é€å›žæ‰§ã€‚';
-$messages['deleteidentityconfirm'] = '您真的想删除这个验è¯ä¿¡æ¯å—?';
-$messages['nodeletelastidentity'] = '无法删除这个身份,这是最åŽä¸€ä¸ªã€‚';
-$messages['forbiddencharacter'] = '目录å包å«éšè—字符。';
+$messages['addingmember'] = '正在添加è”系人至群组...';
+$messages['removingmember'] = '正在从群组中删除è”系人...';
+$messages['receiptsent'] = 'æˆåŠŸå‘é€ä¸€ä¸ªå·²è¯»å›žæ‰§ã€‚';
+$messages['errorsendingreceipt'] = '无法å‘é€å·²è¯»å›žæ‰§ã€‚';
+$messages['deleteidentityconfirm'] = '是å¦åˆ é™¤è¯¥èº«ä»½ï¼Ÿ';
+$messages['nodeletelastidentity'] = '无法删除该身份,这是最åŽä¸€ä¸ªã€‚';
+$messages['forbiddencharacter'] = '目录å包å«ç¦æ­¢å­—符。';
$messages['selectimportfile'] = '请选择è¦ä¸Šä¼ çš„文件。';
-$messages['addresswriterror'] = '已选择的地å€ç°¿ä¸å¯å†™ã€‚';
-$messages['contactaddedtogroup'] = 'æˆåŠŸæ·»åŠ è”系人至该分组。';
-$messages['contactremovedfromgroup'] = 'æˆåŠŸä»Žè¯¥åˆ†ç»„移除è”系人。';
-$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$messages['addresswriterror'] = '选中的通讯录ä¸å¯å†™ã€‚';
+$messages['contactaddedtogroup'] = '添加è”系人至该群组æˆåŠŸã€‚';
+$messages['contactremovedfromgroup'] = '从该群组移除è”系人æˆåŠŸã€‚';
+$messages['nogroupassignmentschanged'] = '群组资料没有å˜æ›´ã€‚';
$messages['importwait'] = '正在导入,请ç¨åŽ...';
-$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
+$messages['importformaterror'] = '导入失败ï¼æ–‡ä»¶æ— æ•ˆã€‚';
$messages['importconfirm'] = '<b>æˆåŠŸå¯¼å…¥ $inserted è”系人</b>';
$messages['importconfirmskipped'] = '<b>跳过已存在的 $skipped 项目</b>';
$messages['opnotpermitted'] = 'ä¸å…许的æ“作!';
-$messages['nofromaddress'] = '选中的身份中没有邮件地å€ã€‚';
-$messages['editorwarning'] = '切æ¢åˆ°çº¯æ–‡æœ¬ç¼–辑器将导致邮件正文中的所有文本格å¼å¤±æ•ˆï¼Œæ‚¨ç¡®å®šè¦è¿™æ ·åšå—?';
-$messages['httpreceivedencrypterror'] = 'å‘生了一个致命的é…置错误,请立å³è”系管ç†å‘˜ã€‚<b>您的邮件无法å‘é€ã€‚</b>';
+$messages['nofromaddress'] = '选中的身份没有邮件地å€ã€‚';
+$messages['editorwarning'] = '切æ¢è‡³çº¯æ–‡æœ¬ç¼–辑器将导致邮件正文中的所有文本格å¼å¤±æ•ˆï¼Œæ‚¨ç¡®å®šè¦è¿™æ ·åšå—?';
+$messages['httpreceivedencrypterror'] = '<b>您的邮件无法å‘é€</b>,因为å‘生了一个严é‡çš„é…置错误,请立å³è”系管ç†å‘˜ã€‚';
$messages['smtpconnerror'] = 'SMTP 错误 ($code):连接æœåŠ¡å™¨å¤±è´¥ã€‚';
$messages['smtpautherror'] = 'SMTP 错误 ($code): 认è¯å¤±è´¥ã€‚';
$messages['smtpfromerror'] = 'SMTP 错误 ($code):添加å‘件人失败 "$from" ($msg)。';
@@ -137,17 +139,17 @@ $messages['smtperror'] = 'SMTP 错误: $msg';
$messages['emailformaterror'] = '无效的邮件地å€ï¼š$email';
$messages['toomanyrecipients'] = '收件人太多,请å‡å°‘人数至 $max。';
$messages['maxgroupmembersreached'] = '组员数é‡è¶…过最大值 $max。';
-$messages['internalerror'] = 'é‡åˆ°ä¸€ä¸ªå†…部错误,请é‡è¯•ã€‚';
+$messages['internalerror'] = 'å‘生一个内部错误,请é‡è¯•ã€‚';
$messages['contactdelerror'] = '无法删除è”系人。';
$messages['contactdeleted'] = '删除è”系人æˆåŠŸã€‚';
$messages['contactrestoreerror'] = '无法æ¢å¤å·²åˆ é™¤çš„è”系人。';
$messages['contactrestored'] = 'è”系人æ¢å¤æˆåŠŸã€‚';
-$messages['groupdeleted'] = 'æˆåŠŸåˆ é™¤ç»„。';
-$messages['grouprenamed'] = '组改åæˆåŠŸã€‚';
-$messages['groupcreated'] = 'æˆåŠŸåˆ›å»ºç»„';
+$messages['groupdeleted'] = '删除群组æˆåŠŸã€‚';
+$messages['grouprenamed'] = '群组改åæˆåŠŸã€‚';
+$messages['groupcreated'] = 'æˆåŠŸåˆ›å»ºç¾¤ç»„';
$messages['savedsearchdeleted'] = 'æˆåŠŸåˆ é™¤ä¿å­˜çš„æœç´¢';
$messages['savedsearchdeleteerror'] = '无法删除ä¿å­˜çš„æœç´¢';
-$messages['savedsearchcreated'] = 'æˆåŠŸå»ºç«‹ä¿å­˜çš„æœç´¢';
+$messages['savedsearchcreated'] = 'æˆåŠŸåˆ›å»ºä¿å­˜çš„æœç´¢';
$messages['savedsearchcreateerror'] = '无法创建ä¿å­˜çš„æœç´¢ã€‚';
$messages['messagedeleted'] = '删除邮件æˆåŠŸã€‚';
$messages['messagemoved'] = '移动邮件æˆåŠŸã€‚';
@@ -161,9 +163,9 @@ $messages['folderupdated'] = 'æˆåŠŸæ›´æ–°æ–‡ä»¶å¤¹';
$messages['foldercreated'] = 'æˆåŠŸåˆ›å»ºæ–‡ä»¶å¤¹';
$messages['invalidimageformat'] = 'éžæ³•çš„图åƒç±»åž‹ã€‚';
$messages['mispellingsfound'] = '检查到拼写错误。';
-$messages['parentnotwritable'] = '无法创建和转移到所选的目录,æƒé™ä¸è¶³ã€‚';
-$messages['messagetoobig'] = '由于邮件部分过大无法处ç†ã€‚';
-$messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.<br/><br/><em>Expected: $expected; found: $detected</em>';
-$messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.';
+$messages['parentnotwritable'] = '无法创建/转移文件夹至指定的上级目录,æƒé™ä¸è¶³ã€‚';
+$messages['messagetoobig'] = '邮件过大无法处ç†ã€‚';
+$messages['attachmentvalidationerror'] = '警告ï¼è¯¥é™„件很å¯ç–‘,因为其自身的格å¼ä¸Žé‚®ä»¶ä¸­å£°æ˜Žçš„æ ¼å¼ä¸ç¬¦ã€‚如果您ä¸ä¿¡ä»»å‘é€äººï¼Œåˆ™ä¸åº”该在æµè§ˆå™¨ä¸­æ‰“开该附件。<br/><br/><em>声明格å¼ï¼š$expected;实际格å¼ï¼š$detected</em>';
+$messages['noscriptwarning'] = '警告:本程åºéœ€è¦ Javascript 支æŒï¼è¯·åœ¨æµè§ˆå™¨è®¾ç½®ä¸­å¯ç”¨ Javascript。';
?>
diff --git a/program/localization/zh_TW/labels.inc b/program/localization/zh_TW/labels.inc
index 7726da5dd..a545f2f81 100644
--- a/program/localization/zh_TW/labels.inc
+++ b/program/localization/zh_TW/labels.inc
@@ -37,7 +37,6 @@ $labels['drafts'] = 'è‰ç¨¿åŒ£';
$labels['sent'] = '寄件備份';
$labels['trash'] = '垃圾桶';
$labels['junk'] = '垃圾郵件';
-$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '主旨';
@@ -194,7 +193,6 @@ $labels['listmode'] = '清單檢視模å¼';
$labels['folderactions'] = '資料夾動作...';
$labels['compact'] = '壓縮';
$labels['empty'] = '清空';
-$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ç£ç¢Ÿä½¿ç”¨é‡';
$labels['unknown'] = '未知';
@@ -205,7 +203,6 @@ $labels['resetsearch'] = 'é‡è¨­æœå°‹';
$labels['searchmod'] = '修改æœå°‹';
$labels['msgtext'] = 'æ•´å°éƒµä»¶';
$labels['body'] = '內文';
-$labels['type'] = 'Type';
$labels['openinextwin'] = '在新視窗開啟';
$labels['emlsave'] = '下載(.eml)';
@@ -357,7 +354,6 @@ $labels['lastpage'] = '顯示最後一é ';
$labels['group'] = '群組';
$labels['groups'] = '群組';
-$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = '個人通訊錄';
$labels['searchsave'] = '儲存æœå°‹çµæžœ';
@@ -476,7 +472,6 @@ $labels['spellcheckignorenums'] = '忽略數字';
$labels['spellcheckignorecaps'] = '忽略大寫字æ¯';
$labels['addtodict'] = '加入詞典';
$labels['mailtoprotohandler'] = '註冊mailto:å”定處ç†ç¨‹å¼';
-$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = '郵件轉寄方å¼';
$labels['inline'] = '放入內文';
$labels['asattachment'] = '當æˆé™„件';
diff --git a/program/localization/zh_TW/messages.inc b/program/localization/zh_TW/messages.inc
index b6fdcccae..5605ba815 100644
--- a/program/localization/zh_TW/messages.inc
+++ b/program/localization/zh_TW/messages.inc
@@ -101,16 +101,13 @@ $messages['converting'] = '移除郵件格å¼ä¸­...';
$messages['messageopenerror'] = '無法從伺æœå™¨è¼‰å…¥éƒµä»¶';
$messages['fileuploaderror'] = '檔案上傳失敗';
$messages['filesizeerror'] = '上傳的檔案超éŽäº† $size 的大å°é™åˆ¶';
-$messages['copysuccess'] = 'Successfully copied $nr contacts.';
-$messages['movesuccess'] = 'Successfully moved $nr contacts.';
-$messages['copyerror'] = 'Could not copy any contacts.';
-$messages['moveerror'] = 'Could not move any contacts.';
+$messages['copysuccess'] = '複製 $nr 個ä½å€æˆåŠŸ';
+$messages['copyerror'] = '無法複製任何ä½å€';
$messages['sourceisreadonly'] = '此來æºä½å€æ˜¯å”¯è®€çš„';
$messages['errorsavingcontact'] = '無法儲存連絡人的ä½å€';
$messages['movingmessage'] = '移動郵件中...';
$messages['copyingmessage'] = '複製訊æ¯...';
$messages['copyingcontact'] = '複製群組...';
-$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = '刪除訊æ¯...';
$messages['markingmessage'] = '標示訊æ¯...';
$messages['addingmember'] = '新增連絡人至群組';
@@ -129,8 +126,6 @@ $messages['importwait'] = '匯入中,請ç¨å€™...';
$messages['importformaterror'] = '匯入失敗ï¼ä¸Šè¼‰çš„檔案格å¼ä¸æ”¯æ´';
$messages['importconfirm'] = '<b>æˆåŠŸåŒ¯å…¥ $inserted ç­†è³‡æ–™ï¼Œç•¥éŽ $skipped 筆已存在的資料</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>ç•¥éŽ $skipped 個已存在的項目</b>';
-$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
-$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'ä¸å…許的æ“作';
$messages['nofromaddress'] = '在é¸æ“‡çš„身分中éºå¤±äº†é›»å­éƒµä»¶ä½å€';
$messages['editorwarning'] = '切æ›åˆ°ç´”文字編輯模å¼å°‡æœƒéºå¤±æ‰€æœ‰è¨­å®šçš„樣å¼ã€‚您確定è¦ç¹¼çºŒå—Žï¼Ÿ';
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc
index d4387194a..480a9b52e 100644
--- a/program/steps/addressbook/copy.inc
+++ b/program/steps/addressbook/copy.inc
@@ -57,16 +57,10 @@ foreach ($cids as $source => $cid)
foreach ($cid as $cid) {
$a_record = $CONTACTS->get_record($cid, true);
- // avoid copying groups
- if ($a_record['_type'] == 'group')
- continue;
-
// Check if contact exists, if so, we'll need it's ID
// Note: Some addressbooks allows empty email address field
- // @TODO: should we check all email addresses?
- $email = $CONTACTS->get_col_values('email', $a_record, true);
- if (!empty($email))
- $result = $TARGET->search('email', $email[0], 1, true, true);
+ if (!empty($a_record['email']))
+ $result = $TARGET->search('email', $a_record['email'], 1, true, true);
else if (!empty($a_record['name']))
$result = $TARGET->search('name', $a_record['name'], 1, true, true);
else
@@ -120,7 +114,7 @@ foreach ($cids as $source => $cid)
}
}
-if (!$success)
+if ($success == 0)
$OUTPUT->show_message($errormsg, 'error');
else
$OUTPUT->show_message('copysuccess', 'notice', array('nr' => $success));
diff --git a/program/steps/addressbook/delete.inc b/program/steps/addressbook/delete.inc
index 3bb2ef500..56118583c 100644
--- a/program/steps/addressbook/delete.inc
+++ b/program/steps/addressbook/delete.inc
@@ -68,14 +68,48 @@ foreach ($cids as $source => $cid)
$page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
// update saved search after data changed
-if (($records = rcmail_search_update(true)) !== false) {
+if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
+ $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+ $afields = $RCMAIL->config->get('contactlist_fields');
+ $search = (array)$_SESSION['search'][$search_request];
+ $records = array();
+
+ // Get records from all sources (refresh search)
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records($afields);
+
+ if (!$result->count) {
+ unset($search[$s]);
+ continue;
+ }
+
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
+ }
+ unset($result);
+
+ $search[$s] = $source->get_search_set();
+ }
+
+ $_SESSION['search'][$search_request] = $search;
+
// create resultset object
$count = count($records);
$first = ($page-1) * $PAGE_SIZE;
$result = new rcube_result_set($count, $first);
- $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
// get records from the next page to add to the list
+ $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
// sort the records
ksort($records, SORT_LOCALE_STRING);
diff --git a/program/steps/addressbook/export.inc b/program/steps/addressbook/export.inc
index 1e988feab..11c9ca493 100644
--- a/program/steps/addressbook/export.inc
+++ b/program/steps/addressbook/export.inc
@@ -5,7 +5,7 @@
| program/steps/addressbook/export.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2008-2013, The Roundcube Dev Team |
+ | Copyright (C) 2008-2011, The Roundcube Dev Team |
| Copyright (C) 2011, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
@@ -21,46 +21,6 @@
+-----------------------------------------------------------------------+
*/
-
-/**
- * Copy contact record properties into a vcard object
- */
-function prepare_for_export(&$record, $source = null)
-{
- $groups = $source && $source->groups && $source->export_groups ? $source->get_record_groups($record['ID']) : null;
-
- if (empty($record['vcard'])) {
- $vcard = new rcube_vcard();
- if ($source) {
- $vcard->extend_fieldmap($source->vcard_map);
- }
- $vcard->load($record['vcard']);
- $vcard->reset();
-
- foreach ($record as $key => $values) {
- list($field, $section) = explode(':', $key);
- foreach ((array)$values as $value) {
- if (is_array($value) || @strlen($value)) {
- $vcard->set($field, $value, strtoupper($section));
- }
- }
- }
-
- // append group names
- if ($groups) {
- $vcard->set('groups', join(',', $groups), null);
- }
-
- $record['vcard'] = $vcard->export(true);
- }
- // patch categories to alread existing vcard block
- else if ($record['vcard'] && !empty($groups) && !strpos($record['vcard'], 'CATEGORIES:')) {
- $vgroups = 'CATEGORIES:' . rcube_vcard::vcard_quote(join(',', $groups));
- $record['vcard'] = str_replace('END:VCARD', $vgroups . rcube_vcard::$eol . 'END:VCARD', $record['vcard']);
- }
-}
-
-
// Use search result
if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']]))
{
@@ -80,15 +40,11 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
// get records
$result = $source->list_records();
- while ($record = $result->next()) {
- // because vcard_map is per-source we need to create vcard here
- prepare_for_export($record, $source);
-
- $record['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($record, $sort_col);
- $records[$key] = $record;
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
}
-
unset($result);
}
@@ -100,35 +56,6 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
$result = new rcube_result_set($count);
$result->records = array_values($records);
}
-// selected contacts
-else if (!empty($_REQUEST['_cid'])) {
- $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
- $records = array();
-
- // Selected contact IDs (with multi-source support)
- $cids = rcmail_get_cids();
-
- foreach ($cids as $s => $ids) {
- $source = $RCMAIL->get_address_book($s);
- $result = $source->search('ID', $ids, 1, true, true);
-
- while ($record = $result->next()) {
- // because vcard_map is per-source we need to create vcard here
- prepare_for_export($record, $source);
-
- $record['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($record, $sort_col);
- $records[$key] = $record;
- }
- }
-
- ksort($records, SORT_LOCALE_STRING);
-
- // create resultset object
- $count = count($records);
- $result = new rcube_result_set($count);
- $result->records = array_values($records);
-}
// selected directory/group
else {
$CONTACTS = rcmail_contact_source(null, true);
@@ -141,15 +68,33 @@ else {
// send downlaod headers
header('Content-Type: text/x-vcard; charset='.RCMAIL_CHARSET);
-header('Content-Disposition: attachment; filename="contacts.vcf"');
+header('Content-Disposition: attachment; filename="rcube_contacts.vcf"');
while ($result && ($row = $result->next())) {
- prepare_for_export($row, $CONTACTS);
+ // we already have a vcard record
+ if ($row['vcard'] && $row['name']) {
+ // fix folding and end-of-line chars
+ $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']);
+ $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']);
+ echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol;
+ }
+ // copy values into vcard object
+ else {
+ $vcard = new rcube_vcard();
+ $vcard->extend_fieldmap($CONTACTS->vcard_map);
+ $vcard->load($row['vcard']);
+ $vcard->reset();
+
+ foreach ($row as $key => $values) {
+ list($field, $section) = explode(':', $key);
+ foreach ((array)$values as $value) {
+ if (is_array($value) || @strlen($value))
+ $vcard->set($field, $value, strtoupper($section));
+ }
+ }
- // fix folding and end-of-line chars
- $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']);
- $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']);
- echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol;
+ echo $vcard->export(true) . rcube_vcard::$eol;
+ }
}
exit;
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index f94d15338..989b7c1c4 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -183,10 +183,11 @@ function rcmail_directory_list($attrib)
$attrib['id'] = 'rcmdirectorylist';
$out = '';
+ $local_id = '0';
$jsdata = array();
$line_templ = html::tag('li', array(
- 'id' => 'rcmli%s', 'class' => '%s', 'noclose' => true),
+ 'id' => 'rcmli%s', 'class' => '%s'),
html::a(array('href' => '%s',
'rel' => '%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('list','%s',this)"), '%s'));
@@ -212,7 +213,7 @@ function rcmail_directory_list($attrib)
$name = !empty($source['name']) ? $source['name'] : $id;
$out .= sprintf($line_templ,
- rcube_utils::html_identifier($id, true),
+ html_identifier($id),
$class_name,
Q(rcmail_url(null, array('_source' => $id))),
$source['id'],
@@ -223,11 +224,10 @@ function rcmail_directory_list($attrib)
$groupdata = rcmail_contact_groups($groupdata);
$jsdata = $groupdata['jsdata'];
$out = $groupdata['out'];
- $out .= '</li>';
}
$line_templ = html::tag('li', array(
- 'id' => 'rcmli%s', 'class' => '%s'),
+ 'id' => 'rcmliS%s', 'class' => '%s'),
html::a(array('href' => '#', 'rel' => 'S%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('listsearch', '%s', this)"), '%s'));
@@ -245,17 +245,14 @@ function rcmail_directory_list($attrib)
$class_name .= ' ' . $source['class_name'];
$out .= sprintf($line_templ,
- rcube_utils::html_identifier('S'.$id, true),
+ html_identifier($id),
$class_name,
$id,
$js_id, (!empty($source['name']) ? Q($source['name']) : Q($id)));
}
$OUTPUT->set_env('contactgroups', $jsdata);
- $OUTPUT->set_env('collapsed_abooks', (string)$RCMAIL->config->get('collapsed_abooks',''));
$OUTPUT->add_gui_object('folderlist', $attrib['id']);
- $OUTPUT->include_script('treelist.js');
-
// add some labels to client
$OUTPUT->add_label('deletegroupconfirm', 'groupdeleting', 'addingmember', 'removingmember');
@@ -267,23 +264,19 @@ function rcmail_contact_groups($args)
{
global $RCMAIL;
- $groups_html = '';
$groups = $RCMAIL->get_address_book($args['source'])->list_groups();
if (!empty($groups)) {
$line_templ = html::tag('li', array(
- 'id' => 'rcmli%s', 'class' => 'contactgroup'),
+ 'id' => 'rcmliG%s', 'class' => 'contactgroup'),
html::a(array('href' => '#',
'rel' => '%s:%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('listgroup',{'source':'%s','id':'%s'},this)"), '%s'));
- // append collapse/expand toggle and open a new <ul>
- $is_collapsed = strpos($RCMAIL->config->get('collapsed_abooks',''), '&'.rawurlencode($args['source']).'&') !== false;
- $args['out'] .= html::div('treetoggle ' . ($is_collapsed ? 'collapsed' : 'expanded'), '&nbsp;');
-
+ $jsdata = array();
foreach ($groups as $group) {
- $groups_html .= sprintf($line_templ,
- rcube_utils::html_identifier('G' . $args['source'] . $group['ID'], true),
+ $args['out'] .= sprintf($line_templ,
+ html_identifier($args['source'] . $group['ID']),
$args['source'], $group['ID'],
$args['source'], $group['ID'], Q($group['name'])
);
@@ -293,10 +286,6 @@ function rcmail_contact_groups($args)
}
}
- $args['out'] .= html::tag('ul',
- array('class' => 'groups', 'style' => ($is_collapsed || empty($groups) ? "display:none;" : null)),
- $groups_html);
-
return $args;
}
@@ -307,7 +296,7 @@ function rcmail_contacts_list($attrib)
global $CONTACTS, $OUTPUT;
// define list of cols to be displayed
- $a_show_cols = array('name','action');
+ $a_show_cols = array('name');
// add id to message list table if not specified
if (!strlen($attrib['id']))
@@ -322,7 +311,7 @@ function rcmail_contacts_list($attrib)
$OUTPUT->include_script('list.js');
// add some labels to client
- $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'movingcontact', 'contactdeleting');
+ $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'contactdeleting');
return $out;
}
@@ -336,73 +325,31 @@ function rcmail_js_contacts_list($result, $prefix='')
return;
// define list of cols to be displayed
- $a_show_cols = array('name','action');
+ $a_show_cols = array('name');
while ($row = $result->next()) {
- $row['CID'] = $row['ID'];
- $row['email'] = reset(rcube_addressbook::get_col_values('email', $row, true));
-
- $source_id = $OUTPUT->get_env('source');
$a_row_cols = array();
- $classes = array($row['_type'] ? $row['_type'] : 'person');
+ $classes = array('person'); // org records will follow some day
// build contact ID with source ID
if (isset($row['sourceid'])) {
$row['ID'] = $row['ID'].'-'.$row['sourceid'];
- $source_id = $row['sourceid'];
}
// format each col
foreach ($a_show_cols as $col) {
- $val = '';
- switch ($col) {
- case 'name':
- $val = Q(rcube_addressbook::compose_list_name($row));
- break;
-
- case 'action':
- if ($row['_type'] == 'group') {
- $val = html::a(array(
- 'href' => '#list',
- 'rel' => $row['ID'],
- 'title' => rcube_label('listgroup'),
- 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source_id, $row['CID']),
- ), '&raquo;');
- }
- else
- $val = '&nbsp;';
- break;
-
- default:
- $val = Q($row[$col]);
- break;
- }
-
- $a_row_cols[$col] = $val;
+ $val = $col == 'name' ? rcube_addressbook::compose_list_name($row) : $row[$col];
+ $a_row_cols[$col] = Q($val);
}
if ($row['readonly'])
$classes[] = 'readonly';
- $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes), array_intersect_key($row, array('ID'=>1,'readonly'=>1,'_type'=>1,'email'=>1,'name'=>1)));
+ $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes));
}
}
-function rcmail_contacts_list_title($attrib)
-{
- global $OUTPUT;
-
- $attrib += array('label' => 'contacts', 'id' => 'rcmabooklisttitle', 'tag' => 'span');
- unset($attrib['name']);
-
- $OUTPUT->add_gui_object('addresslist_title', $attrib['id']);
- $OUTPUT->add_label('contacts');
-
- return html::tag($attrib['tag'], $attrib, rcube_label($attrib['label']), html::$common_attrib);
-}
-
-
// similar function as /steps/settings/identities.inc::rcmail_identity_frame()
function rcmail_contact_frame($attrib)
{
@@ -471,7 +418,7 @@ function rcmail_get_type_label($type)
function rcmail_contact_form($form, $record, $attrib = null)
{
- global $RCMAIL;
+ global $RCMAIL, $CONFIG;
// Allow plugins to modify contact form content
$plugin = $RCMAIL->plugins->exec_hook('contact_form', array(
@@ -480,7 +427,7 @@ function rcmail_contact_form($form, $record, $attrib = null)
$form = $plugin['form'];
$record = $plugin['record'];
$edit_mode = $RCMAIL->action != 'show';
- $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => rcube_label('delete'))) : rcube_label('delete');
+ $del_button = $attrib['deleteicon'] ? html::img(array('src' => $CONFIG['skin_path'] . $attrib['deleteicon'], 'alt' => rcube_label('delete'))) : rcube_label('delete');
unset($attrib['deleteicon']);
$out = '';
@@ -593,13 +540,22 @@ function rcmail_contact_form($form, $record, $attrib = null)
// iterate over possible subtypes and collect values with their subtype
if (is_array($colprop['subtypes'])) {
$values = $subtypes = array();
- foreach (rcube_addressbook::get_col_values($field, $record) as $st => $vals) {
- foreach((array)$vals as $value) {
- $i = count($values);
- $subtypes[$i] = $st;
- $values[$i] = $value;
+ foreach ($colprop['subtypes'] as $i => $st) {
+ $newval = false;
+ if ($record[$field.':'.$st]) {
+ $subtypes[count($values)] = $st;
+ $newval = $record[$field.':'.$st];
+ }
+ else if ($i == 0 && $record[$field]) {
+ $subtypes[count($values)] = $st;
+ $newval = $record[$field];
+ }
+ if ($newval !== false) {
+ if (is_array($newval) && isset($newval[0]))
+ $values = array_merge($values, $newval);
+ else
+ $values[] = $newval;
}
- // TODO: add $st to $select_subtype if missing ?
}
}
else {
@@ -737,42 +693,23 @@ function rcmail_contact_form($form, $record, $attrib = null)
function rcmail_contact_photo($attrib)
{
- global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL;
+ global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL, $CONFIG;
if ($result = $CONTACTS->get_result())
$record = $result->first();
- $photo_img = $attrib['placeholder'] ? $RCMAIL->output->get_skin_file($attrib['placeholder']) : 'program/resources/blank.gif';
- if ($record['_type'] == 'group' && $attrib['placeholdergroup'])
- $photo_img = $RCMAIL->output->get_skin_file($attrib['placeholdergroup']);
-
+ $photo_img = $attrib['placeholder'] ? $CONFIG['skin_path'] . $attrib['placeholder'] : 'program/resources/blank.gif';
$RCMAIL->output->set_env('photo_placeholder', $photo_img);
unset($attrib['placeholder']);
$plugin = $RCMAIL->plugins->exec_hook('contact_photo', array('record' => $record, 'data' => $record['photo']));
- // check if we have photo data from contact form
- if ($GLOBALS['EDIT_RECORD']) {
- $rec = $GLOBALS['EDIT_RECORD'];
- if ($rec['photo'] == '-del-') {
- $record['photo'] = '';
- }
- else if ($_SESSION['contacts']['files'][$rec['photo']]) {
- $record['photo'] = $file_id = $rec['photo'];
- }
- }
-
if ($plugin['url'])
$photo_img = $plugin['url'];
else if (preg_match('!^https?://!i', $record['photo']))
$photo_img = $record['photo'];
- else if ($record['photo']) {
- $url = array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID);
- if ($file_id) {
- $url['_photo'] = $ff_value = $file_id;
- }
- $photo_img = $RCMAIL->url($url);
- }
+ else if ($record['photo'])
+ $photo_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID));
else
$ff_value = '-del-'; // will disable delete-photo action
@@ -795,54 +732,6 @@ function rcmail_format_date_col($val)
return format_date($val, $RCMAIL->config->get('date_format', 'Y-m-d'), false);
}
-/**
- * Updates saved search after data changed
- */
-function rcmail_search_update($return = false)
-{
- global $RCMAIL;
-
- if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
- $search = (array)$_SESSION['search'][$search_request];
- $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
- $afields = $return ? $RCMAIL->config->get('contactlist_fields') : array('name', 'email');
- $records = array();
-
- foreach ($search as $s => $set) {
- $source = $RCMAIL->get_address_book($s);
-
- // reset page
- $source->set_page(1);
- $source->set_pagesize(9999);
- $source->set_search_set($set);
-
- // get records
- $result = $source->list_records($afields);
-
- if (!$result->count) {
- unset($search[$s]);
- continue;
- }
-
- if ($return) {
- while ($row = $result->next()) {
- $row['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
- $records[$key] = $row;
- }
- unset($result);
- }
-
- $search[$s] = $source->get_search_set();
- }
-
- $_SESSION['search'][$search_request] = $search;
-
- return $records;
- }
-
- return false;
-}
/**
* Returns contact ID(s) and source(s) from GET/POST data
@@ -900,7 +789,6 @@ $OUTPUT->add_handlers(array(
'directorylist' => 'rcmail_directory_list',
// 'groupslist' => 'rcmail_contact_groups',
'addresslist' => 'rcmail_contacts_list',
- 'addresslisttitle' => 'rcmail_contacts_list_title',
'addressframe' => 'rcmail_contact_frame',
'recordscountdisplay' => 'rcmail_rowcount_display',
'searchform' => array($OUTPUT, 'search_form')
@@ -909,6 +797,7 @@ $OUTPUT->add_handlers(array(
// register action aliases
$RCMAIL->register_action_map(array(
'add' => 'edit.inc',
+ 'photo' => 'show.inc',
'group-create' => 'groups.inc',
'group-rename' => 'groups.inc',
'group-delete' => 'groups.inc',
diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc
index 60f5d7b61..915aac884 100644
--- a/program/steps/addressbook/import.inc
+++ b/program/steps/addressbook/import.inc
@@ -40,7 +40,6 @@ function rcmail_import_form($attrib)
'multiple' => 'multiple',
));
$form = html::p(null, html::label('rcmimportfile', rcube_label('importfromfile')) . $upload->show());
- $table = new html_table(array('cols' => 2));
// addressbook selector
if (count($writable_books) > 1) {
@@ -49,31 +48,17 @@ function rcmail_import_form($attrib)
foreach ($writable_books as $book)
$select->add($book['name'], $book['id']);
- $table->add('title', html::label('rcmimporttarget', rcube_label('importtarget')));
- $table->add(null, $select->show($target));
+ $form .= html::p(null, html::label('rcmimporttarget', rcube_label('importtarget'))
+ . $select->show($target));
}
else {
$abook = new html_hiddenfield(array('name' => '_target', 'value' => key($writable_books)));
$form .= $abook->show();
}
- // selector for group import options
- if (count($writable_books) >= 1 || $writable_books[0]->groups) {
- $select = new html_select(array('name' => '_groups', 'id' => 'rcmimportgroups', 'is_escaped' => true));
- $select->add(rcube_label('none'), '0');
- $select->add(rcube_label('importgroupsall'), '1');
- $select->add(rcube_label('importgroupsexisting'), '2');
-
- $table->add('title', html::label('rcmimportgroups', rcube_label('importgroups')));
- $table->add(null, $select->show(get_input_value('_groups', RCUBE_INPUT_GPC)));
- }
-
- // checkbox to replace the entire address book
$check_replace = new html_checkbox(array('name' => '_replace', 'value' => 1, 'id' => 'rcmimportreplace'));
- $table->add('title', html::label('rcmimportreplace', rcube_label('importreplace')));
- $table->add(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC)));
-
- $form .= $table->show(array('id' => null) + $attrib);
+ $form .= html::p(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC)) .
+ html::label('rcmimportreplace', rcube_label('importreplace')));
$OUTPUT->set_env('writable_source', !empty($writable_books));
$OUTPUT->add_label('selectimportfile','importwait');
@@ -149,50 +134,19 @@ function rcmail_import_buttons($attrib)
}
-/**
- * Returns the matching group id. If group doesn't exist, it'll be created if allowed.
- */
-function rcmail_import_group_id($group_name, $CONTACTS, $create, &$import_groups)
-{
- $group_id = 0;
- foreach ($import_groups as $key => $group) {
- if (strtolower($group['name']) == strtolower($group_name)) {
- $group_id = $group['ID'];
- break;
- }
- }
-
- // create a new group
- if (!$group_id && $create) {
- $new_group = $CONTACTS->create_group($group_name);
- if (!$new_group['ID'])
- $new_group['ID'] = $new_group['id'];
- $import_groups[] = $new_group;
- $group_id = $new_group['ID'];
- }
-
- return $group_id;
-}
-
-
/** The import process **/
$importstep = 'rcmail_import_form';
if (is_array($_FILES['_file'])) {
- $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC);
- $target = get_input_value('_target', RCUBE_INPUT_GPC);
- $with_groups = intval(get_input_value('_groups', RCUBE_INPUT_GPC));
+ $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC);
+ $target = get_input_value('_target', RCUBE_INPUT_GPC);
$vcards = array();
$upload_error = null;
$CONTACTS = $RCMAIL->get_address_book($target, true);
- if (!$CONTACTS->groups) {
- $with_groups = false;
- }
-
if ($CONTACTS->readonly) {
$OUTPUT->show_message('addresswriterror', 'error');
}
@@ -252,10 +206,6 @@ if (is_array($_FILES['_file'])) {
$CONTACTS->delete_all();
}
- if ($with_groups) {
- $import_groups = $CONTACTS->list_groups();
- }
-
foreach ($vcards as $vcard) {
$a_record = $vcard->get_assoc();
@@ -308,15 +258,6 @@ if (is_array($_FILES['_file'])) {
$success = $plugin['result'];
if ($success) {
- // assign groups for this contact (if enabled)
- if ($with_groups && !empty($a_record['groups'])) {
- foreach (explode(',', $a_record['groups'][0]) as $group_name) {
- if ($group_id = rcmail_import_group_id($group_name, $CONTACTS, $with_groups == 1, $import_groups)) {
- $CONTACTS->add_to_group($group_id, $success);
- }
- }
- }
-
$IMPORT_STATS->inserted++;
$IMPORT_STATS->names[] = $a_record['name'] ? $a_record['name'] : $email;
}
diff --git a/program/steps/addressbook/list.inc b/program/steps/addressbook/list.inc
index aca58d279..1bb28658b 100644
--- a/program/steps/addressbook/list.inc
+++ b/program/steps/addressbook/list.inc
@@ -19,20 +19,47 @@
+-----------------------------------------------------------------------+
*/
-if (!empty($_GET['_page']))
- $page = intval($_GET['_page']);
-else
- $page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1;
-
-$_SESSION['page'] = $page;
+$afields = $RCMAIL->config->get('contactlist_fields');
// Use search result
-if (($records = rcmail_search_update(true)) !== false) {
+if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']]))
+{
+ $search = (array)$_SESSION['search'][$_REQUEST['_search']];
+ $records = array();
+
+ if (!empty($_GET['_page']))
+ $page = intval($_GET['_page']);
+ else
+ $page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
+
+ $_SESSION['page'] = $page;
+ $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+
+ // Get records from all sources
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records($afields);
+
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
+ }
+ unset($result);
+ }
+
// sort the records
ksort($records, SORT_LOCALE_STRING);
// create resultset object
- $count = count($records);
+ $count = count($records);
$first = ($page-1) * $PAGE_SIZE;
$result = new rcube_result_set($count, $first);
@@ -45,7 +72,6 @@ if (($records = rcmail_search_update(true)) !== false) {
}
// List selected directory
else {
- $afields = $RCMAIL->config->get('contactlist_fields');
$CONTACTS = rcmail_contact_source(null, true);
// get contacts for this user
@@ -55,11 +81,6 @@ else {
$OUTPUT->show_message('contactsearchonly', 'notice');
$OUTPUT->command('command', 'advanced-search');
}
-
- if ($CONTACTS->group_id) {
- $OUTPUT->command('set_group_prop', array('ID' => $CONTACTS->group_id)
- + array_intersect_key((array)$CONTACTS->get_group($CONTACTS->group_id), array('name'=>1,'email'=>1)));
- }
}
// update message count display
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 2adc53bcf..25bfbd48b 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -59,34 +59,15 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
}
// assign values and subtypes
else if (is_array($_POST[$fname])) {
- $values = get_input_value($fname, RCUBE_INPUT_POST, true);
+ $values = get_input_value($fname, RCUBE_INPUT_POST, true);
$subtypes = get_input_value('_subtype_' . $col, RCUBE_INPUT_POST);
-
foreach ($values as $i => $val) {
- if ($col == 'email') {
- // extract email from full address specification, e.g. "Name" <addr@domain.tld>
- $addr = rcube_mime::decode_address_list($val, 1, false);
- if (!empty($addr) && ($addr = array_pop($addr)) && $addr['mailto']) {
- $val = $addr['mailto'];
- }
- }
-
$subtype = $subtypes[$i] ? ':'.$subtypes[$i] : '';
$a_record[$col.$subtype][] = $val;
}
}
else if (isset($_POST[$fname])) {
$a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST, true);
-
- // normalize the submitted date strings
- if ($colprop['type'] == 'date') {
- if ($timestamp = rcube_utils::strtotime($a_record[$col])) {
- $a_record[$col] = date('Y-m-d', $timestamp);
- }
- else {
- unset($a_record[$col]);
- }
- }
}
}
@@ -94,10 +75,8 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
if (empty($a_record['name'])) {
$a_record['name'] = rcube_addressbook::compose_display_name($a_record, true);
// Reset it if equals to email address (from compose_display_name())
- $email = rcube_addressbook::get_col_values('email', $a_record, true);
- if ($a_record['name'] == $email[0]) {
+ if ($a_record['name'] == $a_record['email'][0])
$a_record['name'] = '';
- }
}
// do input checks (delegated to $CONTACTS instance)
@@ -155,11 +134,11 @@ if (!empty($cid))
$record['email'] = reset($CONTACTS->get_col_values('email', $record, true));
$record['name'] = rcube_addressbook::compose_list_name($record);
- foreach (array('name') as $col)
+ foreach (array('name', 'email') as $col)
$a_js_cols[] = Q((string)$record[$col]);
// update the changed col in list
- $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record);
+ $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source);
// show confirmation
$OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc
index efab5e9e5..d583a6d36 100644
--- a/program/steps/addressbook/show.inc
+++ b/program/steps/addressbook/show.inc
@@ -38,6 +38,58 @@ if ($cid && ($record = $CONTACTS->get_record($cid, true))) {
// get address book name (for display)
rcmail_set_sourcename($CONTACTS);
+// return raw photo of the given contact
+if ($RCMAIL->action == 'photo') {
+ // search for contact first
+ if (!$record && ($email = get_input_value('_email', RCUBE_INPUT_GPC))) {
+ foreach ($RCMAIL->get_address_sources() as $s) {
+ $abook = $RCMAIL->get_address_book($s['id']);
+ $result = $abook->search(array('email'), $email, 1, true, true, 'photo');
+ while ($result && ($record = $result->iterate())) {
+ if ($record['photo'])
+ break 2;
+ }
+ }
+ }
+
+ // read the referenced file
+ if (($file_id = get_input_value('_photo', RCUBE_INPUT_GPC)) && ($tempfile = $_SESSION['contacts']['files'][$file_id])) {
+ $tempfile = $RCMAIL->plugins->exec_hook('attachment_display', $tempfile);
+ if ($tempfile['status']) {
+ if ($tempfile['data'])
+ $data = $tempfile['data'];
+ else if ($tempfile['path'])
+ $data = file_get_contents($tempfile['path']);
+ }
+ }
+ else if ($record['photo']) {
+ $data = is_array($record['photo']) ? $record['photo'][0] : $record['photo'];
+ if (!preg_match('![^a-z0-9/=+-]!i', $data))
+ $data = base64_decode($data, true);
+ }
+
+ // let plugins do fancy things with contact photos
+ $plugin = $RCMAIL->plugins->exec_hook('contact_photo', array('record' => $record, 'email' => $email, 'data' => $data));
+
+ // redirect to url provided by a plugin
+ if ($plugin['url'])
+ $RCMAIL->output->redirect($plugin['url']);
+ else
+ $data = $plugin['data'];
+
+ // deliver alt image
+ if (!$data && ($alt_img = get_input_value('_alt', RCUBE_INPUT_GPC)) && is_file($alt_img))
+ $data = file_get_contents($alt_img);
+
+ // cache for one day if requested by email
+ if (!$cid && $email)
+ $RCMAIL->output->future_expire_header(86400);
+
+ header('Content-Type: ' . rc_image_content_type($data));
+ echo $data ? $data : file_get_contents('program/resources/blank.gif');
+ exit;
+}
+
function rcmail_contact_head($attrib)
{
@@ -49,6 +101,8 @@ function rcmail_contact_head($attrib)
return false;
}
+ $microformats = array('name' => 'fn', 'email' => 'email');
+
$form = array(
'head' => array( // section 'head' is magic!
'content' => array(
@@ -123,7 +177,7 @@ function rcmail_contact_details($attrib)
}
-function rcmail_render_email_value($email)
+function rcmail_render_email_value($email, $col)
{
return html::a(array(
'href' => 'mailto:' . $email,
@@ -134,7 +188,7 @@ function rcmail_render_email_value($email)
}
-function rcmail_render_url_value($url)
+function rcmail_render_url_value($url, $col)
{
$prefix = preg_match('!^(http|ftp)s?://!', $url) ? '' : 'http://';
return html::a(array(
@@ -155,8 +209,9 @@ function rcmail_contact_record_groups($contact_id)
return '';
}
- $members = $CONTACTS->get_record_groups($contact_id);
- $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
+ $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
+
+ $members = $CONTACTS->get_record_groups($contact_id);
$checkbox = new html_checkbox(array('name' => '_gid[]',
'class' => 'groupmember', 'disabled' => $CONTACTS->readonly));
diff --git a/program/steps/addressbook/undo.inc b/program/steps/addressbook/undo.inc
index c23bd1cb6..9c171143c 100644
--- a/program/steps/addressbook/undo.inc
+++ b/program/steps/addressbook/undo.inc
@@ -46,7 +46,30 @@ foreach ((array)$undo['data'] as $source => $cid)
}
// update saved search after data changed
-rcmail_search_update();
+if ($delcnt && ($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
+ $search = (array)$_SESSION['search'][$search_request];
+
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records(array('name', 'email'));
+
+ if (!$result->count) {
+ unset($search[$s]);
+ continue;
+ }
+
+ $search[$s] = $source->get_search_set();
+ }
+
+ $_SESSION['search'][$search_request] = $search;
+}
$RCMAIL->session->remove('contact_undo');
diff --git a/program/steps/mail/attachments.inc b/program/steps/mail/attachments.inc
index f83f6892e..85aa9542b 100644
--- a/program/steps/mail/attachments.inc
+++ b/program/steps/mail/attachments.inc
@@ -118,9 +118,12 @@ if (is_array($_FILES['_attachments']['tmp_name'])) {
'alt' => rcube_label('delete')
));
}
- else {
+ else if ($COMPOSE['textbuttons']) {
$button = Q(rcube_label('delete'));
}
+ else {
+ $button = '';
+ }
$content = html::a(array(
'href' => "#delete",
diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc
index 8c0b1ffc0..d3c14a38d 100644
--- a/program/steps/mail/check_recent.inc
+++ b/program/steps/mail/check_recent.inc
@@ -52,12 +52,12 @@ foreach ($a_mailboxes as $mbox_name) {
}
// Get mailbox status
- $status = $RCMAIL->storage->folder_status($mbox_name, $diff);
+ $status = $RCMAIL->storage->folder_status($mbox_name);
if ($status & 1) {
// trigger plugin hook
$RCMAIL->plugins->exec_hook('new_messages',
- array('mailbox' => $mbox_name, 'is_current' => $is_current, 'diff' => $diff));
+ array('mailbox' => $mbox_name, 'is_current' => $is_current));
}
rcmail_send_unread_count($mbox_name, true, null,
@@ -81,10 +81,9 @@ foreach ($a_mailboxes as $mbox_name) {
if (empty($_GET['_list']))
continue;
- // get overall message count; allow caching because rcube_storage::folder_status()
- // did a refresh but only in list mode
+ // get overall message count; allow caching because rcube_storage::folder_status() did a refresh
$list_mode = $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL';
- $all_count = $RCMAIL->storage->count($mbox_name, $list_mode, $list_mode == 'THREADS', false);
+ $all_count = $RCMAIL->storage->count($mbox_name, $list_mode, false, false);
$page = $RCMAIL->storage->get_page();
$page_size = $RCMAIL->storage->get_pagesize();
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index e9f638cb1..0130b1c55 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -165,8 +165,6 @@ else if ($msg_uid = $COMPOSE['param']['forward_uid']) {
else if ($msg_uid = $COMPOSE['param']['uid']) {
$compose_mode = RCUBE_COMPOSE_EDIT;
}
-
-$COMPOSE['mode'] = $compose_mode;
$OUTPUT->set_env('compose_mode', $compose_mode);
$config_show_sig = $RCMAIL->config->get('show_sig', 1);
@@ -188,18 +186,9 @@ $LINE_LENGTH = $RCMAIL->config->get('line_length', 72);
if (!empty($msg_uid) && empty($COMPOSE['as_attachment']))
{
- $mbox_name = $RCMAIL->storage->get_folder();
-
- // set format before rcube_message construction
- // use the same format as for the message view
- if (isset($_SESSION['msg_formats'][$mbox_name.':'.$msg_uid])) {
- $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$msg_uid]);
- }
- else {
- $prefer_html = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT;
- $RCMAIL->config->set('prefer_html', $prefer_html);
- }
-
+ // similar as in program/steps/mail/show.inc
+ // re-set 'prefer_html' to have possibility to use html part for compose
+ $CONFIG['prefer_html'] = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT;
$MESSAGE = new rcube_message($msg_uid);
// make sure message is marked as read
@@ -324,8 +313,8 @@ foreach ($parts as $header) {
else if (!empty($MESSAGE->headers->from))
$fvalue = $MESSAGE->headers->from;
- // Reply to message sent by yourself (#1487074, #1489230)
- if (!empty($ident) && in_array($ident['ident'], array($fvalue, $MESSAGE->headers->from))) {
+ // Reply to message sent by yourself (#1487074)
+ if (!empty($ident) && $fvalue == $ident['ident']) {
$fvalue = $MESSAGE->headers->to;
}
}
@@ -413,7 +402,7 @@ function rcmail_compose_headers($attrib)
{
global $MESSAGE;
- list($form_start,) = get_form_tags($attrib);
+ list($form_start, $form_end) = get_form_tags($attrib);
$out = '';
$part = strtolower($attrib['part']);
@@ -477,7 +466,7 @@ function rcmail_compose_headers($attrib)
function rcmail_compose_header_from($attrib)
{
- global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode;
+ global $MESSAGE, $OUTPUT, $RCMAIL, $compose_mode;
// pass the following attributes to the form class
$field_attrib = array('name' => '_from');
@@ -488,7 +477,6 @@ function rcmail_compose_header_from($attrib)
if (count($MESSAGE->identities))
{
$a_signatures = array();
- $identities = array();
$separator = intval($RCMAIL->config->get('reply_mode')) > 0
&& ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- ';
@@ -526,21 +514,12 @@ function rcmail_compose_header_from($attrib)
$a_signatures[$identity_id]['text'] = $text;
$a_signatures[$identity_id]['html'] = $html;
}
-
- // add bcc and reply-to
- if (!empty($sql_arr['reply-to'])) {
- $identities[$identity_id]['replyto'] = $sql_arr['reply-to'];
- }
- if (!empty($sql_arr['bcc'])) {
- $identities[$identity_id]['bcc'] = $sql_arr['bcc'];
- }
}
$out = $select_from->show($MESSAGE->compose['from']);
// add signatures to client
$OUTPUT->set_env('signatures', $a_signatures);
- $OUTPUT->set_env('identities', $identities);
}
// no identities, display text input field
else {
@@ -584,13 +563,13 @@ function rcmail_compose_editor_mode()
function rcmail_message_is_html()
{
- global $RCMAIL, $MESSAGE;
- return $RCMAIL->config->get('prefer_html') && ($MESSAGE instanceof rcube_message) && $MESSAGE->has_html_part(true);
+ global $MESSAGE;
+ return ($MESSAGE instanceof rcube_message) && $MESSAGE->has_html_part(false, true);
}
function rcmail_prepare_message_body()
{
- global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE;
+ global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $LINE_LENGTH, $HTML_MODE;
// use posted message body
if (!empty($_POST['_message'])) {
@@ -717,11 +696,6 @@ function rcmail_compose_part_body($part, $isHtml = false)
$body = rcmail_remove_signature($body);
}
}
-
- if ($part->ctype_parameters['format'] == 'flowed') {
- $body = rcube_mime::unfold_flowed($body);
- }
-
// add HTML formatting
$body = rcmail_plain_body($body);
if ($body) {
@@ -742,6 +716,9 @@ function rcmail_compose_part_body($part, $isHtml = false)
$txt = new rcube_html2text($body, false, true, $len);
$body = $txt->get_text();
}
+ else if ($part->ctype_secondary == 'enriched') {
+ $body = rcube_enriched::to_html($body);
+ }
else {
if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') {
$body = rcube_mime::unfold_flowed($body);
@@ -761,7 +738,7 @@ function rcmail_compose_part_body($part, $isHtml = false)
function rcmail_compose_body($attrib)
{
- global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $HTML_MODE, $MESSAGE_BODY;
+ global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $LINE_LENGTH, $HTML_MODE, $MESSAGE_BODY;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
@@ -945,7 +922,8 @@ function rcmail_create_forward_body($body, $bodyIsHtml)
if (!isset($COMPOSE['forward_attachments']) && is_array($MESSAGE->mime_parts))
$cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml);
- $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long'));
+ $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long'));
+ $charset = $RCMAIL->output->get_charset();
if (!$bodyIsHtml) {
$prefix = "\n\n\n-------- " . rcube_label('originalmessage') . " --------\n";
@@ -997,7 +975,7 @@ function rcmail_create_forward_body($body, $bodyIsHtml)
function rcmail_create_draft_body($body, $bodyIsHtml)
{
- global $MESSAGE, $COMPOSE;
+ global $MESSAGE, $OUTPUT, $COMPOSE;
/**
* add attachments
@@ -1053,14 +1031,7 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
{
global $RCMAIL, $COMPOSE, $compose_mode;
- $loaded_attachments = array();
- foreach ((array)$COMPOSE['attachments'] as $attachment) {
- $loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
- }
-
- $cid_map = array();
- $messages = array();
-
+ $cid_map = $messages = array();
foreach ((array)$message->mime_parts as $pid => $part)
{
if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) {
@@ -1096,8 +1067,7 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
}
}
- if (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype])
- || ($attachment = rcmail_save_attachment($message, $pid))) {
+ if ($attachment = rcmail_save_attachment($message, $pid)) {
$COMPOSE['attachments'][$attachment['id']] = $attachment;
if ($bodyIsHtml && ($part->content_id || $part->content_location)) {
$url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s',
@@ -1150,7 +1120,7 @@ function rcmail_write_forward_attachments()
$names = array();
$loaded_attachments = array();
- foreach ((array)$COMPOSE['attachments'] as $attachment) {
+ foreach ((array)$COMPOSE['attachments'] as $id => $attachment) {
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
}
@@ -1370,8 +1340,9 @@ function rcmail_compose_attachment_list($attrib)
if (!$attrib['id'])
$attrib['id'] = 'rcmAttachmentList';
- $out = "\n";
+ $out = "\n";
$jslist = array();
+ $button = '';
if (is_array($COMPOSE['attachments'])) {
if ($attrib['deleteicon']) {
@@ -1380,27 +1351,38 @@ function rcmail_compose_attachment_list($attrib)
'alt' => rcube_label('delete')
));
}
- else
+ else if (rcube_utils::get_boolean($attrib['textbuttons'])) {
$button = Q(rcube_label('delete'));
+ }
foreach ($COMPOSE['attachments'] as $id => $a_prop) {
if (empty($a_prop))
continue;
- $out .= html::tag('li', array('id' => 'rcmfile'.$id, 'class' => rcmail_filetype2classname($a_prop['mimetype'], $a_prop['name'])),
+ $out .= html::tag('li',
+ array(
+ 'id' => 'rcmfile'.$id,
+ 'class' => rcmail_filetype2classname($a_prop['mimetype'], $a_prop['name']),
+ 'onmouseover' => "rcube_webmail.long_subject_title_ex(this, 0)",
+ ),
html::a(array(
'href' => "#delete",
'title' => rcube_label('delete'),
'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id),
- 'class' => 'delete'),
- $button) . Q($a_prop['name']));
+ 'class' => 'delete'
+ ),
+ $button
+ ) . Q($a_prop['name'])
+ );
- $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']);
+ $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']);
}
}
if ($attrib['deleteicon'])
$COMPOSE['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon'];
+ else if (rcube_utils::get_boolean($attrib['textbuttons']))
+ $COMPOSE['textbuttons'] = true;
if ($attrib['cancelicon'])
$OUTPUT->set_env('cancelicon', $CONFIG['skin_path'] . $attrib['cancelicon']);
if ($attrib['loadingicon'])
@@ -1427,7 +1409,7 @@ function rcmail_compose_attachment_form($attrib)
$out = html::div($attrib,
$OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'),
- html::div(null, rcmail_compose_attachment_field()) .
+ html::div(null, rcmail_compose_attachment_field(array('size' => $attrib['attachmentfieldsize']))) .
html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
(get_boolean($attrib['buttons']) ? html::div('buttons',
$button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' .
@@ -1441,7 +1423,7 @@ function rcmail_compose_attachment_form($attrib)
}
-function rcmail_compose_attachment_field($attrib = array())
+function rcmail_compose_attachment_field($attrib)
{
$attrib['type'] = 'file';
$attrib['name'] = '_attachments[]';
@@ -1559,7 +1541,7 @@ function rcmail_editor_selector($attrib)
$select->add(Q(rcube_label('plaintoggle')), 'plain');
return $select->show($useHtml ? 'html' : 'plain');
-/*
+
foreach ($choices as $value => $text) {
$attrib['id'] = '_' . $value;
$attrib['value'] = $value;
@@ -1567,7 +1549,6 @@ function rcmail_editor_selector($attrib)
}
return $selector;
-*/
}
@@ -1661,7 +1642,7 @@ function rcmail_addressbook_list($attrib = array())
$class_name .= ' ' . $source['class_name'];
$out .= sprintf($line_templ,
- html_identifier($id,true),
+ html_identifier($id),
$class_name,
$source['id'],
$js_id, (!empty($source['name']) ? $source['name'] : $id));
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index a7d9ca240..2938e91e1 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -89,12 +89,11 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
}
$threading = (bool) $RCMAIL->storage->get_threading();
- $delimiter = $RCMAIL->storage->get_hierarchy_delimiter();
// 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', $delimiter);
+ $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));
@@ -120,48 +119,11 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
if (!$OUTPUT->ajax_call)
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
- 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait');
+ 'copy', 'move', 'quota');
- $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
- $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
-
- $OUTPUT->set_pagetitle($pagetitle);
+ $OUTPUT->set_pagetitle(rcmail_localize_foldername($RCMAIL->storage->mod_folder($mbox_name)));
}
-// 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',
- 'messageimportform' => 'rcmail_message_import_form',
- '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',
- 'move' => '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',
-));
-
-
-
/**
* Returns 'to' if current folder is configured Sent or Drafts
* or their subfolders, otherwise returns 'from'.
@@ -177,9 +139,7 @@ function rcmail_message_list_smart_column_name()
$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)
- && strtoupper($mbox) != 'INBOX'
- ) {
+ if (strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) {
return 'to';
}
@@ -260,7 +220,7 @@ function rcmail_message_list($attrib)
if (!in_array('threads', $a_show_cols))
array_unshift($a_show_cols, 'threads');
- $_SESSION['skin_path'] = $CONFIG['skin_path'];
+ $skin_path = $_SESSION['skin_path'] = $CONFIG['skin_path'];
// set client env
$OUTPUT->add_gui_object('messagelist', $attrib['id']);
@@ -272,13 +232,15 @@ function rcmail_message_list($attrib)
$OUTPUT->include_script('list.js');
- $table = new html_table($attrib);
- if (!$attrib['noheader']) {
- foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell)
- $table->add_header(array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
- }
+ $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 $table->show();
+ 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'));
}
@@ -325,7 +287,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
$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 (array_search('fromto', $a_show_cols) !== false) {
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
$smart_col = rcmail_message_list_smart_column_name();
}
@@ -341,7 +303,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
}
// loop through message headers
- foreach ($a_headers as $header) {
+ foreach ($a_headers as $n => $header) {
if (empty($header))
continue;
@@ -415,6 +377,7 @@ 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'];
@@ -450,7 +413,7 @@ function rcmail_message_list_head($attrib, $a_show_cols)
$cells = array();
// get name of smart From/To column in folder context
- if (array_search('fromto', $a_show_cols) !== false) {
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
$smart_col = rcmail_message_list_smart_column_name();
}
@@ -641,8 +604,6 @@ function rcmail_check_safe(&$message)
$message->set_safe(true);
}
}
-
- $RCMAIL->plugins->exec_hook('message_check_safe', array('message' => $message));
break;
case 2: // always
@@ -742,10 +703,7 @@ function rcmail_print_body($part, $p = array())
+ $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
// convert html to text/plain
- if ($data['plain'] && ($data['type'] == 'html' || $data['type'] == 'enriched')) {
- if ($data['type'] == 'enriched') {
- $data['body'] = rcube_enriched::to_html($data['body']);
- }
+ if ($data['type'] == 'html' && $data['plain']) {
$txt = new rcube_html2text($data['body'], false, true);
$body = $txt->get_text();
$part->ctype_secondary = 'plain';
@@ -771,13 +729,8 @@ function rcmail_print_body($part, $p = array())
unset($data['body']);
// plaintext postprocessing
- if ($part->ctype_secondary == 'plain') {
- if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') {
- $body = rcube_mime::unfold_flowed($body);
- }
-
- $body = rcmail_plain_body($body);
- }
+ 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',
@@ -791,16 +744,16 @@ function rcmail_print_body($part, $p = array())
* 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)
+function rcmail_plain_body($body, $flowed=false)
{
global $RCMAIL;
// make links and email-addresses clickable
- $attribs = array('link_attribs' => array('rel' => 'noreferrer', 'target' => '_blank'));
- $replacer = new rcmail_string_replacer($attribs);
+ $replacer = new rcmail_string_replacer;
// search for patterns like links and e-mail addresses and replace with tokens
$body = $replacer->replace($body);
@@ -826,10 +779,48 @@ function rcmail_plain_body($body)
str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
$last = $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 ($quote_level > 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];
}
@@ -900,7 +891,7 @@ function rcmail_washtml_callback($tagname, $attrib, $content, $washtml)
*/
function rcmail_message_headers($attrib, $headers=null)
{
- global $MESSAGE, $PRINT_MODE, $RCMAIL;
+ global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
static $sa_attrib;
// keep header table attrib
@@ -1085,7 +1076,7 @@ function rcmail_message_body($attrib)
$header_attrib[$regs[1]] = $value;
if (!empty($MESSAGE->parts)) {
- foreach ($MESSAGE->parts as $part) {
+ 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));
}
@@ -1189,9 +1180,10 @@ function rcmail_message_body($attrib)
$show_link = array(
'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
'onclick' => sprintf(
- 'return %s.command(\'load-attachment\',\'%s\',this)',
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
JS_OBJECT_NAME,
- $attach_prop->mime_id)
+ $attach_prop->mime_id,
+ $mimetype)
);
$out .= html::p('image-attachment',
html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)),
@@ -1377,7 +1369,7 @@ function rcmail_html4inline($body, $container_id, $body_id='', &$attributes=null
/**
- * parse link (a, link, area) attributes and set correct target
+ * parse link attributes and set correct target
*/
function rcmail_alter_html_link($matches)
{
@@ -1386,9 +1378,9 @@ function rcmail_alter_html_link($matches)
// 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 = strtolower($matches[1]);
+ $tag = $matches[1];
$attrib = parse_attrib_string($matches[2]);
- $end = '>';
+ $end = '>';
// Remove non-printable characters in URL (#1487805)
if ($attrib['href'])
@@ -1415,11 +1407,6 @@ function rcmail_alter_html_link($matches)
$attrib['target'] = '_blank';
}
- // Better security by adding rel="noreferrer" (#1484686)
- if (($tag == 'a' || $tag == 'area') && $attrib['href'] && $attrib['href'][0] != '#') {
- $attrib['rel'] = 'noreferrer';
- }
-
// 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');
@@ -1443,8 +1430,7 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
$c = count($a_parts);
$j = 0;
$out = '';
- $allvalues = array();
- $show_email = $RCMAIL->config->get('message_show_email');
+ $allvalues = array();
if ($addicon && !isset($_SESSION['writeable_abook'])) {
$_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false;
@@ -1458,7 +1444,7 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
$valid = check_email($mailto, false);
// phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>"
- if (!$show_email && $valid && $name && $name != $mailto && strpos($name, '@')) {
+ if ($name && $valid && $name != $mailto && strpos($name, '@')) {
$name = '';
}
@@ -1476,21 +1462,13 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
}
else if ($valid) {
if ($linked) {
- $attrs = array(
- 'href' => 'mailto:' . $mailto,
- 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)),
- 'class' => "rcmContactAddress",
- );
-
- if ($show_email && $name && $mailto) {
- $content = Q($name ? sprintf('%s <%s>', $name, $mailto) : $mailto);
- }
- else {
- $content = Q($name ? $name : $mailto);
- $attrs['title'] = $mailto;
- }
-
- $address = html::a($attrs, $content);
+ $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"),
@@ -1617,6 +1595,45 @@ function rcmail_draftinfo_decode($str)
}
+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 = rcmail_attachment_name($part);
+
+ 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
*/
@@ -1704,7 +1721,8 @@ function rcmail_send_mdn($message, &$smtp_error)
$sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options);
- if ($sent) {
+ if ($sent)
+ {
$RCMAIL->storage->set_flag($message->uid, 'MDNSENT');
return true;
}
@@ -1784,15 +1802,19 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
// Try Return-Path
if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
+ $return_path = array_map('strtolower', (array) $return_path);
+
foreach ($identities as $idx => $ident) {
// Return-Path header contains an email address, but on some mailing list
// it can be e.g. <pear-dev-return-55250-local=domain.tld@lists.php.net>
// where local@domain.tld is the address we're looking for (#1489241)
- $ident1 = $ident['email_ascii'];
+ $ident1 = strtolower($ident['email_ascii']);
$ident2 = str_replace('@', '=', $ident1);
+ $ident1 = '<' . $ident1 . '>';
+ $ident2 = '-' . $ident2 . '@';
- foreach ((array)$return_path as $path) {
- if (stripos($path, $ident1) !== false || stripos($path, $ident2)) {
+ foreach ($return_path as $path) {
+ if ($path == $ident1 || stripos($path, $ident2)) {
$from_idx = $idx;
break 2;
}
@@ -1800,13 +1822,27 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
}
}
- // See identity_select plugin for example usage of this hook
- $plugin = rcmail::get_instance()->plugins->exec_hook('identity_select',
- array('message' => $MESSAGE, 'identities' => $identities, 'selected' => $from_idx));
+ // 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;
+ }
+ }
+ }
- $selected = $plugin['selected'];
+ // 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[$selected !== null ? $selected : $default_identity];
+ return $identities[$from_idx !== null ? $from_idx : $default_identity];
}
// Fixes some content-type names
@@ -1863,15 +1899,13 @@ function rcmail_search_filter($attrib)
$attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)';
- // Content-Type values of messages with attachments
- // the same as in app.js:add_message_row()
- $ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report');
-
- // Build search string of "with attachment" filter
- $attachment = str_repeat(' OR', count($ctypes)-1);
- foreach ($ctypes as $type) {
- $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type);
- }
+ /*
+ 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');
@@ -1882,7 +1916,6 @@ function rcmail_search_filter($attrib)
$select_filter->add(rcube_label('deleted'), 'DELETED');
$select_filter->add(rcube_label('undeleted'), 'UNDELETED');
}
- $select_filter->add(rcube_label('withattachment'), $attachment);
$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');
@@ -1912,36 +1945,35 @@ function rcmail_message_error($uid=null)
$RCMAIL->output->send('messageerror');
}
-function rcmail_message_import_form($attrib = array())
-{
- global $OUTPUT;
-
- // set defaults
- $attrib += array('id' => 'rcmImportform', 'buttons' => 'yes');
-
- // Get filesize, enable upload progress bar
- $max_filesize = rcube_upload_init();
-
- $button = new html_inputfield(array('type' => 'button'));
- $fileinput = new html_inputfield(array(
- 'type' => 'file',
- 'name' => '_file[]',
- 'multiple' => 'multiple',
- 'accept' => ".eml, .mbox, message/rfc822, text/*",
- ));
-
- $out = html::div($attrib,
- $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'method' => 'post', 'enctype' => 'multipart/form-data'),
- html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) .
- html::div(null, $fileinput->show()) .
- html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
- (get_boolean($attrib['buttons']) ? html::div('buttons',
- $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' .
- $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('import-messages', this.form)"))
- ) : '')
- )
- );
+// 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'),
+));
- $OUTPUT->add_gui_object('importform', $attrib['id'].'Frm');
- return $out;
-}
+// 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/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/get.inc b/program/steps/mail/get.inc
index e0c4e2911..372757720 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -38,34 +38,19 @@ ob_end_clean();
// similar code as in program/steps/mail/show.inc
if (!empty($_GET['_uid'])) {
- $uid = get_input_value('_uid', RCUBE_INPUT_GET);
$RCMAIL->config->set('prefer_html', true);
- $MESSAGE = new rcube_message($uid);
+ $MESSAGE = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET));
}
// check connection status
check_storage_status();
-$part_id = get_input_value('_part', RCUBE_INPUT_GPC);
-
// show part page
if (!empty($_GET['_frame'])) {
- if ($part_id && ($part = $MESSAGE->mime_parts[$part_id])) {
- $filename = rcmail_attachment_name($part);
- $OUTPUT->set_pagetitle($filename);
+ if (($part_id = get_input_value('_part', RCUBE_INPUT_GPC)) && ($part = $MESSAGE->mime_parts[$part_id])) {
+ $OUTPUT->set_pagetitle(rcmail_attachment_name($part));
}
- // register UI objects
- $OUTPUT->add_handlers(array(
- 'messagepartframe' => 'rcmail_message_part_frame',
- 'messagepartcontrols' => 'rcmail_message_part_controls',
- ));
-
- $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder());
- $OUTPUT->set_env('uid', $uid);
- $OUTPUT->set_env('part', $part_id);
- $OUTPUT->set_env('filename', $filename);
-
$OUTPUT->send('messagepart');
exit;
}
@@ -107,8 +92,9 @@ else if ($_GET['_thumb']) {
exit;
}
-else if (strlen($part_id)) {
- if ($part = $MESSAGE->mime_parts[$part_id]) {
+else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
+
+ if ($part = $MESSAGE->mime_parts[$pid]) {
$mimetype = rcmail_fix_mimetype($part->mimetype);
// allow post-processing of the message body
@@ -134,7 +120,7 @@ else if (strlen($part_id)) {
$valid = $file_extension && in_array($file_extension, (array)$extensions) || !empty($_REQUEST['_mimeclass']);
// 2. detect the real mimetype of the attachment part and compare it with the stated mimetype and filename extension
- if ($valid || !$file_extension || $mimetype == 'application/octet-stream' || stripos($mimetype, 'text/') === 0) {
+ if ($valid || !$file_extension || $mimetype == 'application/octet-stream' || $mimetype == 'text/plain') {
if ($part->body) // part body is already loaded
$body = $part->body;
else if ($part->size && $part->size < 1024*1024) // load the entire part if it's small enough
@@ -189,8 +175,8 @@ else if (strlen($part_id)) {
rcube_label(array(
'name' => 'attachmentvalidationerror',
'vars' => array(
- 'expected' => $mimetype . ($file_extension ? " (.$file_extension)" : ''),
- 'detected' => $real_mimetype . ($extensions[0] ? " (.$extensions[0])" : ''),
+ 'expected' => $mimetype . ($file_extension ? "(.$file_extension)" : ''),
+ 'detected' => $real_mimetype . ($extensions[0] ? "(.$extensions[0])" : ''),
)
)) .
html::p(array('class' => 'rcmail-inline-buttons'),
@@ -233,6 +219,7 @@ else if (strlen($part_id)) {
header("Content-Transfer-Encoding: binary");
}
+
// deliver part content
if ($ctype_primary == 'text' && $ctype_secondary == 'html' && empty($plugin['download'])) {
// Check if we have enough memory to handle the message in it
@@ -357,8 +344,7 @@ else if (strlen($part_id)) {
header("Content-Length: $size");
}
- // 8th argument disables re-formatting of text/* parts (#1489267)
- $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, true, null, false, 0, false);
+ $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, true);
}
}
@@ -392,9 +378,7 @@ else {
header('HTTP/1.1 404 Not Found');
exit;
-/**
- * Handles nicely storage connection errors
- */
+
function check_storage_status()
{
$error = rcmail::get_instance()->storage->get_error_code();
@@ -426,49 +410,3 @@ function check_storage_status()
exit;
}
}
-
-/**
- * Attachment properties table
- */
-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' => 2));
-
- $table->add('title', Q(rcube_label('namex')).':');
- $table->add('header', Q(rcmail_attachment_name($part)));
-
- $table->add('title', Q(rcube_label('type')).':');
- $table->add('header', Q($part->mimetype));
-
- $table->add('title', Q(rcube_label('size')).':');
- $table->add('header', Q($RCMAIL->message_part_size($part)));
-
- return $table->show($attrib);
-}
-
-/**
- * Attachment preview frame
- */
-function rcmail_message_part_frame($attrib)
-{
- global $MESSAGE, $RCMAIL;
-
- $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']);
-
- $RCMAIL->output->add_gui_object('messagepartframe', $attrib['id']);
-
- return html::iframe($attrib);
-}
diff --git a/program/steps/mail/list.inc b/program/steps/mail/list.inc
index a2380131a..b8c3ee021 100644
--- a/program/steps/mail/list.inc
+++ b/program/steps/mail/list.inc
@@ -97,6 +97,7 @@ $OUTPUT->set_env('threading', $threading);
$OUTPUT->set_env('current_page', $count ? $RCMAIL->storage->get_page() : 1);
$OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS'));
$OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($count), $mbox_name);
+$OUTPUT->command('set_mailboxname', rcmail_get_mailbox_name_text());
// add message rows
rcmail_js_message_list($a_headers, FALSE, $cols);
diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc
index dab146431..479c21422 100644
--- a/program/steps/mail/list_contacts.inc
+++ b/program/steps/mail/list_contacts.inc
@@ -73,11 +73,8 @@ else {
$CONTACTS->set_pagesize($page_size);
$CONTACTS->set_page($list_page);
- if ($group_id = get_input_value('_gid', RCUBE_INPUT_GPC)) {
- $CONTACTS->set_group($group_id);
- }
// list groups of this source (on page one)
- else if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
+ if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
foreach ($CONTACTS->list_groups() as $group) {
$CONTACTS->reset();
$CONTACTS->set_group($group['ID']);
@@ -92,19 +89,6 @@ else {
'contactgroup' => html::span(array('title' => $email), Q($group['name']))), 'group');
}
}
- // make virtual groups clickable to list their members
- else if ($group_prop['virtual']) {
- $row_id = 'G'.$group['ID'];
- $OUTPUT->command('add_contact_row', $row_id, array(
- 'contactgroup' => html::a(array(
- 'href' => '#list',
- 'rel' => $row['ID'],
- 'title' => rcube_label('listgroup'),
- 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source, $group['ID']),
- ), Q($group['name']) . '&nbsp;' . html::span('action', '&raquo;'))),
- 'group',
- array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true));
- }
// show group with count
else if (($result = $CONTACTS->count()) && $result->count) {
$row_id = 'E'.$group['ID'];
@@ -113,12 +97,10 @@ else {
'contactgroup' => Q($group['name'] . ' (' . intval($result->count) . ')')), 'group');
}
}
-
- $CONTACTS->reset();
- $CONTACTS->set_group(0);
}
// get contacts for this user
+ $CONTACTS->set_group(0);
$result = $CONTACTS->list_records($afields);
}
}
@@ -136,13 +118,10 @@ else if (!empty($result) && $result->count > 0) {
foreach ($emails as $i => $email) {
$row_id = $row['ID'].$i;
$jsresult[$row_id] = format_email_recipient($email, $name);
- $classname = $row['_type'] == 'group' ? 'group' : 'person';
- $keyname = $row['_type'] == 'group' ? 'contactgroup' : 'contact';
-
$OUTPUT->command('add_contact_row', $row_id, array(
- $keyname => html::span(array('title' => $email), Q($name ? $name : $email) .
+ 'contact' => html::span(array('title' => $email), Q($name ? $name : $email) .
($name && count($emails) > 1 ? '&nbsp;' . html::span('email', Q($email)) : '')
- )), $classname);
+ )), 'person');
}
}
}
diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc
index f15cd2460..37157b71f 100644
--- a/program/steps/mail/move_del.inc
+++ b/program/steps/mail/move_del.inc
@@ -29,11 +29,10 @@ $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL');
$old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize());
// move messages
-if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
- $count = sizeof(explode(',', ($uids = get_input_value('_uid', RCUBE_INPUT_POST))));
+if ($RCMAIL->action=='moveto' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
+ $count = sizeof(explode(',', ($uids = get_input_value('_uid', RCUBE_INPUT_POST))));
$target = get_input_value('_target_mbox', RCUBE_INPUT_POST, true);
- $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true);
- $trash = $RCMAIL->config->get('trash_mbox');
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true);
$moved = $RCMAIL->storage->move_message($uids, $target, $mbox);
@@ -41,7 +40,7 @@ if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_targe
// send error message
if ($_POST['_from'] != 'show')
$OUTPUT->command('list_mailbox');
- rcmail_display_server_error('errormoving', null, $target == $trash ? 'delete' : '');
+ rcmail_display_server_error('errormoving');
$OUTPUT->send();
exit;
}
@@ -126,7 +125,7 @@ else
rcmail_set_unseen_count($mbox, $unseen_count);
}
- if ($RCMAIL->action == 'move' && strlen($target)) {
+ if ($RCMAIL->action == 'moveto' && strlen($target)) {
rcmail_send_unread_count($target, true);
}
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 779fb87cd..c1c257127 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -123,7 +123,7 @@ function rcmail_fix_emoticon_paths($mime_message)
// sanitize image name so resulting attachment doesn't leave images dir
$image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i', '', $image_name);
- $img_file = INSTALL_PATH . '/' . $searchstr . $image_name;
+ $img_file = '/usr/share/tinymce/www/plugins/emotions/img/' . $image_name;
if (! in_array($image_name, $included_images)) {
// add the image to the MIME message
@@ -391,6 +391,10 @@ if (!empty($mailcc)) {
if (!empty($mailbcc)) {
$headers['Bcc'] = $mailbcc;
}
+if (!empty($identity_arr['bcc']) && stripos($headers['Bcc'], $identity_arr['bcc']) === false) {
+ $headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc'];
+ $RECIPIENT_COUNT ++;
+}
if (($max_recipients = (int) $RCMAIL->config->get('max_recipients')) > 0) {
if ($RECIPIENT_COUNT > $max_recipients) {
@@ -408,6 +412,9 @@ if (!empty($identity_arr['organization'])) {
if (!empty($_POST['_replyto'])) {
$headers['Reply-To'] = rcmail_email_input_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset));
}
+else if (!empty($identity_arr['reply-to'])) {
+ $headers['Reply-To'] = rcmail_email_input_format($identity_arr['reply-to'], false, true);
+}
if (!empty($headers['Reply-To'])) {
$headers['Mail-Reply-To'] = $headers['Reply-To'];
}
@@ -823,24 +830,15 @@ if ($savedraft) {
// start the auto-save timer again
$OUTPUT->command('auto_save_start');
+
+ $OUTPUT->send('iframe');
}
else {
- $folders = array();
-
- if ($COMPOSE['mode'] == 'reply' || $COMPOSE['mode'] == 'forward')
- $folders[] = $COMPOSE['mailbox'];
-
rcmail_compose_cleanup($COMPOSE_ID);
if ($store_folder && !$saved)
- $OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'), $folders);
- else {
- if ($store_folder) {
- $folders[] = $store_target;
- }
-
- $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'), $folders);
- }
+ $OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'));
+ else
+ $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'), $store_target);
+ $OUTPUT->send('iframe');
}
-
-$OUTPUT->send('iframe');
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 59f4d55e1..c1726bbdf 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -19,7 +19,7 @@
+-----------------------------------------------------------------------+
*/
-$PRINT_MODE = $RCMAIL->action == 'print' ? TRUE : FALSE;
+$PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE;
// Read browser capabilities and store them in session
if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) {
@@ -31,21 +31,8 @@ if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) {
$_SESSION['browser_caps'] = $browser_caps;
}
-$uid = get_input_value('_uid', RCUBE_INPUT_GET);
-$mbox_name = $RCMAIL->storage->get_folder();
-
// similar code as in program/steps/mail/get.inc
-if ($uid) {
- // set message format (need to be done before rcube_message construction)
- if (!empty($_GET['_format'])) {
- $prefer_html = $_GET['_format'] == 'html';
- $RCMAIL->config->set('prefer_html', $prefer_html);
- $_SESSION['msg_formats'][$mbox_name.':'.$uid] = $prefer_html;
- }
- else if (isset($_SESSION['msg_formats'][$mbox_name.':'.$uid])) {
- $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$uid]);
- }
-
+if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
$MESSAGE = new rcube_message($uid);
// if message not found (wrong UID)...
@@ -53,6 +40,7 @@ if ($uid) {
rcmail_message_error($uid);
}
+ $mbox_name = $RCMAIL->storage->get_folder();
// show images?
rcmail_check_safe($MESSAGE);
@@ -116,12 +104,7 @@ if ($uid) {
if (!$OUTPUT->ajax_call)
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
- 'movingmessage', 'deletingmessage', 'markingmessage', 'replyall', 'replylist');
-
- $prefer_html = $RCMAIL->config->get('prefer_html');
- if ($MESSAGE->has_html_part()) {
- $OUTPUT->set_env('optional_format', $prefer_html ? 'text' : 'html');
- }
+ 'movingmessage', 'deletingmessage', 'markingmessage');
// check for unset disposition notification
if ($MESSAGE->headers->mdn_to
@@ -164,7 +147,6 @@ function rcmail_message_attachments($attrib)
global $PRINT_MODE, $MESSAGE, $RCMAIL;
$out = $ol = '';
- $attachments = array();
if (sizeof($MESSAGE->attachments)) {
foreach ($MESSAGE->attachments as $attach_prop) {
@@ -175,31 +157,30 @@ function rcmail_message_attachments($attrib)
$ol .= html::tag('li', null, Q(sprintf("%s (%s)", $filename, $size)));
}
else {
- if (mb_strlen($filename) > 50) {
+ if ($attrib['maxlength'] && mb_strlen($filename) > $attrib['maxlength']) {
$title = $filename;
- $filename = abbreviate_string($filename, 50);
+ $filename = abbreviate_string($filename, $attrib['maxlength']);
}
else {
$title = '';
}
- $mimetype = rcmail_fix_mimetype($attach_prop->mimetype);
- $class = rcmail_filetype2classname($mimetype, $filename);
- $id = 'attach' . $attach_prop->mime_id;
- $link = html::a(array(
+ $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\',\'%s\',this)',
- JS_OBJECT_NAME, $attach_prop->mime_id),
- 'title' => Q($title),
- ), Q($filename));
- $ol .= html::tag('li', array('class' => $class, 'id' => $id), $link);
-
- $attachments[$attach_prop->mime_id] = $mimetype;
+ '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)),
+ 'onmouseover' => $title ? '' : 'rcube_webmail.long_subject_title_ex(this, 0)',
+ 'title' => Q($title),
+ ),
+ Q($filename)));
}
}
$out = html::tag('ul', $attrib, $ol, html::$common_attrib);
- $RCMAIL->output->set_env('attachments', $attachments);
}
return $out;
@@ -228,11 +209,11 @@ function rcmail_remote_objects_msg()
function rcmail_message_buttons()
{
- global $RCMAIL;
+ global $MESSAGE, $RCMAIL, $CONFIG;
$mbox = $RCMAIL->storage->get_folder();
$delim = $RCMAIL->storage->get_hierarchy_delimiter();
- $dbox = $RCMAIL->config->get('drafts_mbox');
+ $dbox = $CONFIG['drafts_mbox'];
// the message is not a draft
if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) {
@@ -309,9 +290,9 @@ $OUTPUT->add_handlers(array(
));
-if ($RCMAIL->action == 'print' && $OUTPUT->template_exists('messageprint'))
+if ($RCMAIL->action=='print' && $OUTPUT->template_exists('messageprint'))
$OUTPUT->send('messageprint', false);
-else if ($RCMAIL->action == 'preview' && $OUTPUT->template_exists('messagepreview'))
+else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
$OUTPUT->send('messagepreview', false);
else
$OUTPUT->send('message', false);
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;
+
diff --git a/program/steps/settings/about.inc b/program/steps/settings/about.inc
index 0fdefddda..9b13402f1 100644
--- a/program/steps/settings/about.inc
+++ b/program/steps/settings/about.inc
@@ -40,28 +40,17 @@ function rcmail_plugins_list($attrib)
$attrib['id'] = 'rcmpluginlist';
$plugins = array_filter((array) $RCMAIL->config->get('plugins'));
- $plugin_info = array();
+ $plugins = array_flip($plugins);
- foreach ($plugins as $name) {
- if ($info = $RCMAIL->plugins->get_info($name))
- $plugin_info[$name] = $info;
+ foreach ($plugins as $name => $plugin) {
+ rcube_plugin_data($name, $plugins);
}
- // load info from required plugins, too
- foreach ($plugin_info as $name => $info) {
- if (is_array($info['required']) && !empty($info['required'])) {
- foreach ($info['required'] as $req_name) {
- if (!isset($plugin_info[$req_name]) && ($req_info = $RCMAIL->plugins->get_info($req_name)))
- $plugin_info[$req_name] = $req_info;
- }
- }
- }
-
- if (empty($plugin_info)) {
+ if (empty($plugins)) {
return '';
}
- ksort($plugin_info, SORT_LOCALE_STRING);
+ ksort($plugins, SORT_LOCALE_STRING);
$table = new html_table($attrib);
@@ -71,8 +60,8 @@ function rcmail_plugins_list($attrib)
$table->add_header('license', rcube_label('license'));
$table->add_header('source', rcube_label('source'));
- foreach ($plugin_info as $name => $data) {
- $uri = $data['src_uri'] ? $data['src_uri'] : $data['uri'];
+ foreach ($plugins as $name => $data) {
+ $uri = $data['srcuri'] ? $data['srcuri'] : $data['uri'];
if ($uri && stripos($uri, 'http') !== 0) {
$uri = 'http://' . $uri;
}
@@ -89,6 +78,48 @@ function rcmail_plugins_list($attrib)
return $table->show();
}
+function rcube_plugin_data($name, &$plugins = array())
+{
+ // XPaths of plugin metadata elements
+ $metadata = array(
+ 'name' => 'string(//rc:package/rc:name)',
+ 'version' => 'string(//rc:package/rc:version/rc:release)',
+ 'license' => 'string(//rc:package/rc:license)',
+ 'license_uri' => 'string(//rc:package/rc:license/@uri)',
+ 'srcuri' => 'string(//rc:package/rc:srcuri)',
+ 'uri' => 'string(//rc:package/rc:uri)',
+ );
+
+ $package = INSTALL_PATH . "/plugins/$name/package.xml";
+ if (file_exists($package) && ($file = file_get_contents($package))) {
+ $doc = new DOMDocument();
+ $doc->loadXML($file);
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('rc', "http://pear.php.net/dtd/package-2.0");
+ $data = array();
+
+ foreach ($metadata as $key => $path) {
+ $data[$key] = $xpath->evaluate($path);
+ }
+
+ $plugins[$name] = $data;
+
+ // dependent required plugins (can be used, but not included in config)
+ $deps = $xpath->evaluate('//rc:package/rc:dependencies/rc:required/rc:package/rc:name');
+ $cnt = $deps->length;
+
+ for ($i=0; $i<$cnt; $i++) {
+ $dn = $deps->item($i)->nodeValue;
+ if (!array_key_exists($dn, $plugins)) {
+ rcube_plugin_data($dn, $plugins);
+ }
+ }
+ }
+ else {
+ unset($plugins[$name]);
+ }
+}
+
$OUTPUT->set_pagetitle(rcube_label('about'));
diff --git a/program/steps/settings/edit_folder.inc b/program/steps/settings/edit_folder.inc
index f19e2177b..fdb38e602 100644
--- a/program/steps/settings/edit_folder.inc
+++ b/program/steps/settings/edit_folder.inc
@@ -264,12 +264,9 @@ function rcmail_folder_form($attrib)
$content = rcmail_get_form_part($tab, $attrib);
}
- if ($content && sizeof($form) > 1) {
+ if ($content) {
$out .= html::tag('fieldset', null, html::tag('legend', null, Q($tab['name'])) . $content) ."\n";
}
- else {
- $out .= $content ."\n";
- }
}
$out .= "\n$form_end";
diff --git a/program/steps/settings/edit_prefs.inc b/program/steps/settings/edit_prefs.inc
index 468e4994d..971ed60b6 100644
--- a/program/steps/settings/edit_prefs.inc
+++ b/program/steps/settings/edit_prefs.inc
@@ -40,7 +40,7 @@ function rcmail_user_prefs_form($attrib)
$out = $form_start;
- foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $block) {
+ foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $idx => $block) {
if (!empty($block['options'])) {
$table = new html_table(array('cols' => 2));
diff --git a/program/steps/settings/edit_response.inc b/program/steps/settings/edit_response.inc
new file mode 100644
index 000000000..49856775a
--- /dev/null
+++ b/program/steps/settings/edit_response.inc
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_response.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, 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: |
+ | Show edit form for a canned response record or to add a new one |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$responses = $RCMAIL->get_compose_responses();
+
+// edit-response
+if (($key = get_input_value('_key', RCUBE_INPUT_GPC))) {
+ foreach ($responses as $i => $response) {
+ if ($response['key'] == $key) {
+ $RESPONSE_RECORD = $response;
+ $RESPONSE_RECORD['index'] = $i;
+ break;
+ }
+ }
+}
+
+// save response
+if ($RCMAIL->action == 'save-response' && isset($_POST['_name']) && !$RESPONSE_RECORD['static']) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+ $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
+
+ if (!empty($name) && !empty($text)) {
+ $dupes = 0;
+ foreach ($responses as $i => $resp) {
+ if ($RESPONSE_RECORD && $RESPONSE_RECORD['index'] === $i)
+ continue;
+ if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
+ $dupes++;
+ }
+ if ($dupes) { // require a unique name
+ $name .= ' (' . ++$dupes . ')';
+ }
+
+ $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16));
+ if ($RESPONSE_RECORD && $responses[$RESPONSE_RECORD['index']]) {
+ $responses[$RESPONSE_RECORD['index']] = $response;
+ }
+ else {
+ $responses[] = $response;
+ }
+
+ $responses = array_filter($responses, function($item){ return empty($item['static']); });
+ if ($RCMAIL->user->save_prefs(array('compose_responses' => array_values($responses)))) {
+ $RCMAIL->output->show_message('successfullysaved', 'confirmation');
+ $RCMAIL->output->command('parent.update_response_row', $response, $key);
+ $RCMAIL->overwrite_action('edit-response');
+ $RESPONSE_RECORD = $response;
+ }
+ }
+ else {
+ $RCMAIL->output->show_message('formincomplete', 'error');
+ }
+}
+
+
+function rcube_response_form($attrib)
+{
+ global $RCMAIL, $OUTPUT, $RESPONSE_RECORD;
+
+ // Set form tags and hidden fields
+ $disabled = !empty($RESPONSE_RECORD['static']);
+ $key = $RESPONSE_RECORD['key'];
+ list($form_start, $form_end) = get_form_tags($attrib, 'save-response', $key, array('name' => '_key', 'value' => $key));
+ unset($attrib['form'], $attrib['id']);
+
+ // return the complete edit form as table
+ $out = "$form_start\n";
+
+ $table = new html_table(array('cols' => 2));
+ $label = rcube_label('responsename');
+
+ $table->add('title', html::label('ffname', Q(rcube_label('responsename'))));
+ $table->add(null, rcube_output::get_edit_field('name', $RESPONSE_RECORD['name'], array('id' => 'ffname', 'size' => $attrib['size'], 'disabled' => $disabled), 'text'));
+
+ $table->add('title', html::label('fftext', Q(rcube_label('responsetext'))));
+ $table->add(null, rcube_output::get_edit_field('text', $RESPONSE_RECORD['text'], array('id' => 'fftext', 'size' => $attrib['textareacols'], 'rows' => $attrib['textarearows'], 'disabled' => $disabled), 'textarea'));
+
+ $out .= $table->show($attrib);
+ $out .= $form_end;
+
+ return $out;
+}
+
+$OUTPUT->set_env('readonly', !empty($RESPONSE_RECORD['static']));
+$OUTPUT->add_handler('responseform', 'rcube_response_form');
+$OUTPUT->set_pagetitle(rcube_label(($RCMAIL->action=='add-response' ? 'savenewresponse' : 'editresponse')));
+
+$OUTPUT->send('responseedit');
+
diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc
index 64af18d62..778d93c03 100644
--- a/program/steps/settings/folders.inc
+++ b/program/steps/settings/folders.inc
@@ -232,16 +232,16 @@ function rcube_subscription_form($attrib)
// add any necessary "virtual" parent folders
if ($parent_folder && !isset($seen[$parent_folder])) {
for ($i=1; $i<=$level; $i++) {
- $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
- if ($ancestor_folder && !$seen[$ancestor_folder]++) {
- $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP');
- $list_folders[] = array(
+ $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
+ if ($ancestor_folder && !$seen[$ancestor_folder]++) {
+ $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP');
+ $list_folders[] = array(
'id' => $ancestor_folder,
'name' => $ancestor_name,
'level' => $i-1,
'virtual' => true,
);
- }
+ }
}
}
@@ -283,6 +283,7 @@ function rcube_subscription_form($attrib)
$noselect = false;
$classes = array($i%2 ? 'even' : 'odd');
+ $folder_js = Q($folder['id']);
$folder_utf8 = rcube_charset_convert($folder['id'], 'UTF7-IMAP');
$display_folder = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $folder['level'])
. Q($protected ? rcmail_localize_foldername($folder['id']) : $folder['name']);
@@ -291,8 +292,7 @@ function rcube_subscription_form($attrib)
$classes[] = 'virtual';
}
- // Check \Noselect flag (of existing folder)
- if (!$protected && in_array($folder['id'], $a_unsubscribed)) {
+ if (!$protected) {
$attrs = $STORAGE->folder_attributes($folder['id']);
$noselect = in_array('\\Noselect', $attrs);
}
@@ -394,7 +394,7 @@ function rcmail_rename_folder($oldname, $newname)
$a_threaded = (array) $RCMAIL->config->get('message_threading', array());
$oldprefix = '/^' . preg_quote($oldname . $delimiter, '/') . '/';
- foreach (array_keys($a_threaded) as $key) {
+ foreach ($a_threaded as $key => $val) {
if ($key == $oldname) {
unset($a_threaded[$key]);
$a_threaded[$newname] = true;
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index fdc07be9e..981d4e406 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -19,1176 +19,915 @@
+-----------------------------------------------------------------------+
*/
-if (!$OUTPUT->ajax_call) {
- $OUTPUT->set_pagetitle(rcube_label('preferences'));
-}
+if (!$OUTPUT->ajax_call)
+ $OUTPUT->set_pagetitle(rcube_label('preferences'));
+
// similar function as /steps/settings/identities.inc::rcmail_identity_frame()
function rcmail_preferences_frame($attrib)
{
- global $OUTPUT;
+ global $OUTPUT;
- if (!$attrib['id']) {
- $attrib['id'] = 'rcmprefsframe';
- }
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmprefsframe';
- return $OUTPUT->frame($attrib, true);
+ return $OUTPUT->frame($attrib, true);
}
function rcmail_sections_list($attrib)
{
- global $RCMAIL;
+ global $RCMAIL;
- // add id to message list table if not specified
- if (!strlen($attrib['id'])) {
- $attrib['id'] = 'rcmsectionslist';
- }
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmsectionslist';
- list($list, $cols) = rcmail_user_prefs();
+ list($list, $cols) = rcmail_user_prefs();
- // create XHTML table
- $out = rcube_table_output($attrib, $list, $cols, 'id');
+ // create XHTML table
+ $out = rcube_table_output($attrib, $list, $cols, 'id');
- // set client env
- $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']);
- $RCMAIL->output->include_script('list.js');
+ // set client env
+ $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']);
+ $RCMAIL->output->include_script('list.js');
- return $out;
+ return $out;
}
function rcmail_identities_list($attrib)
{
- global $OUTPUT, $RCMAIL;
+ global $OUTPUT, $RCMAIL;
- // add id to message list table if not specified
- if (!strlen($attrib['id'])) {
- $attrib['id'] = 'rcmIdentitiesList';
- }
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmIdentitiesList';
- // get identities list and define 'mail' column
- $list = $RCMAIL->user->list_identities();
- foreach ($list as $idx => $row) {
- $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_idn_to_utf8($row['email']) .'>');
- }
+ // get identities list and define 'mail' column
+ $list = $RCMAIL->user->list_identities();
+ foreach ($list as $idx => $row)
+ $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_idn_to_utf8($row['email']) .'>');
- // get all identites from DB and define list of cols to be displayed
- $plugin = $RCMAIL->plugins->exec_hook('identities_list', array(
- 'list' => $list,
- 'cols' => array('mail')
- ));
+ // get all identites from DB and define list of cols to be displayed
+ $plugin = $RCMAIL->plugins->exec_hook('identities_list', array(
+ 'list' => $list,
+ 'cols' => array('mail')));
- // @TODO: use <UL> instead of <TABLE> for identities list
- // create XHTML table
- $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id');
+ // @TODO: use <UL> instead of <TABLE> for identities list
+ // create XHTML table
+ $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id');
- // set client env
- $OUTPUT->add_gui_object('identitieslist', $attrib['id']);
+ // set client env
+ $OUTPUT->add_gui_object('identitieslist', $attrib['id']);
- return $out;
+ return $out;
}
// similar function as in /steps/addressbook/edit.inc
function get_form_tags($attrib, $action, $id = null, $hidden = null)
{
- global $EDIT_FORM, $RCMAIL;
-
- $form_start = $form_end = '';
-
- if (empty($EDIT_FORM)) {
- $request_key = $action . (isset($id) ? '.'.$id : '');
- $form_start = $RCMAIL->output->request_form(array(
- 'name' => 'form',
- 'method' => 'post',
- 'task' => $RCMAIL->task,
- 'action' => $action,
- 'request' => $request_key,
- 'noclose' => true
- ) + $attrib);
-
- if (is_array($hidden)) {
- $hiddenfields = new html_hiddenfield($hidden);
- $form_start .= $hiddenfields->show();
- }
+ global $EDIT_FORM, $RCMAIL;
+
+ $form_start = $form_end = '';
+
+ if (empty($EDIT_FORM)) {
+ $request_key = $action . (isset($id) ? '.'.$id : '');
+ $form_start = $RCMAIL->output->request_form(array(
+ 'name' => 'form',
+ 'method' => 'post',
+ 'task' => $RCMAIL->task,
+ 'action' => $action,
+ 'request' => $request_key,
+ 'noclose' => true
+ ) + $attrib);
+
+ if (is_array($hidden)) {
+ $hiddenfields = new html_hiddenfield($hidden);
+ $form_start .= $hiddenfields->show();
+ }
- $form_end = !strlen($attrib['form']) ? '</form>' : '';
+ $form_end = !strlen($attrib['form']) ? '</form>' : '';
- $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
- $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
- }
+ $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
+ $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
+ }
- return array($form_start, $form_end);
+ return array($form_start, $form_end);
}
-function rcmail_user_prefs($current = null)
+function rcmail_user_prefs($current=null)
{
- global $RCMAIL;
+ global $RCMAIL;
+
+ $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
+ $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
+ $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
+ $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
+ $sections['addressbook'] = array('id' => 'addressbook','section' => rcube_label('addressbook'));
+ $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
+ $sections['server'] = array('id' => 'server', 'section' => rcube_label('serversettings'));
+
+ // hook + define list cols
+ $plugin = $RCMAIL->plugins->exec_hook('preferences_sections_list',
+ array('list' => $sections, 'cols' => array('section')));
- $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
- $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
- $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
- $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
- $sections['addressbook'] = array('id' => 'addressbook','section' => rcube_label('addressbook'));
- $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
- $sections['server'] = array('id' => 'server', 'section' => rcube_label('serversettings'));
+ $sections = $plugin['list'];
- // hook + define list cols
- $plugin = $RCMAIL->plugins->exec_hook('preferences_sections_list',
- array('list' => $sections, 'cols' => array('section')));
+ $config = $RCMAIL->config->all();
+ $no_override = array_flip($RCMAIL->config->get('dont_override', array()));
+
+ foreach ($sections as $idx => $sect) {
+
+ if ($current && $sect['id'] != $current)
+ continue;
+
+ $blocks = array();
- $sections = $plugin['list'];
- $config = $RCMAIL->config->all();
- $no_override = array_flip((array)$RCMAIL->config->get('dont_override'));
+ switch ($sect['id']) {
+ // general
+ case 'general':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ // language selection
+ if (!isset($no_override['language'])) {
+ $a_lang = $RCMAIL->list_languages();
+ asort($a_lang);
+
+ $field_id = 'rcmfd_lang';
+ $select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
+ $select_lang->add(array_values($a_lang), array_keys($a_lang));
+
+ $blocks['main']['options']['language'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('language'))),
+ 'content' => $select_lang->show($RCMAIL->user->language),
+ );
+ }
- foreach ($sections as $idx => $sect) {
- if ($current && $sect['id'] != $current) {
- continue;
+ // timezone selection
+ if (!isset($no_override['timezone'])) {
+ $field_id = 'rcmfd_timezone';
+ $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id));
+ $select_timezone->add(rcube_label('autodetect'), 'auto');
+
+ $zones = array();
+ foreach (DateTimeZone::listIdentifiers() as $i => $tzs) {
+ try {
+ $tz = new DateTimeZone($tzs);
+ $date = new DateTime('2012-12-21', $tz);
+ $offset = $date->format('Z') + 45000;
+ $sortkey = sprintf('%06d.%s', $offset, $tzs);
+ $zones[$sortkey] = array($tzs, $date->format('P'));
}
+ catch (Exception $e) {}
+ }
+
+ ksort($zones);
+ foreach ($zones as $zone) {
+ list($tzs, $offset) = $zone;
+ $select_timezone->add('(GMT ' . $offset . ') ' . strtr($tzs, '_', ' '), $tzs);
+ }
+
+ $blocks['main']['options']['timezone'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('timezone'))),
+ 'content' => $select_timezone->show((string)$config['timezone']),
+ );
+ }
+
+ // date/time formatting
+ if (!isset($no_override['time_format'])) {
+ $reftime = mktime(7,30,0);
+ $field_id = 'rcmfd_time_format';
+ $select_time = new html_select(array('name' => '_time_format', 'id' => $field_id));
+ foreach ((array)$RCMAIL->config->get('time_formats', array('G:i', 'H:i', 'g:i a', 'h:i A')) as $choice)
+ $select_time->add(date($choice, $reftime), $choice);
+
+ $blocks['main']['options']['time_format'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('timeformat'))),
+ 'content' => $select_time->show($RCMAIL->config->get('time_format')),
+ );
+ }
+
+ if (!isset($no_override['date_format'])) {
+ $refdate = mktime(12,30,0,7,24);
+ $field_id = 'rcmfd_date_format';
+ $select_date = new html_select(array('name' => '_date_format', 'id' => $field_id));
+ foreach ((array)$RCMAIL->config->get('date_formats', array('Y-m-d','d-m-Y','Y/m/d','m/d/Y','d/m/Y','d.m.Y','j.n.Y')) as $choice)
+ $select_date->add(date($choice, $refdate), $choice);
+
+ $blocks['main']['options']['date_format'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('dateformat'))),
+ 'content' => $select_date->show($config['date_format']),
+ );
+ }
+
+ // MM: Show checkbox for toggling 'pretty dates'
+ if (!isset($no_override['prettydate'])) {
+ $field_id = 'rcmfd_prettydate';
+ $input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
- $blocks = array();
-
- switch ($sect['id']) {
-
- // general
- case 'general':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'skin' => array('name' => Q(rcube_label('skin'))),
- 'browser' => array('name' => Q(rcube_label('browseroptions'))),
- );
-
- // language selection
- if (!isset($no_override['language'])) {
- if (!$current) {
- continue 2;
- }
-
- $a_lang = $RCMAIL->list_languages();
- asort($a_lang);
-
- $field_id = 'rcmfd_lang';
- $select = new html_select(array('name' => '_language', 'id' => $field_id));
- $select->add(array_values($a_lang), array_keys($a_lang));
-
- $blocks['main']['options']['language'] = array(
- 'title' => html::label($field_id, Q(rcube_label('language'))),
- 'content' => $select->show($RCMAIL->user->language),
- );
- }
-
- // timezone selection
- if (!isset($no_override['timezone'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_timezone';
- $select = new html_select(array('name' => '_timezone', 'id' => $field_id));
- $select->add(rcube_label('autodetect'), 'auto');
-
- $zones = array();
- foreach (DateTimeZone::listIdentifiers() as $i => $tzs) {
- try {
- $tz = new DateTimeZone($tzs);
- $date = new DateTime('2012-12-21', $tz);
- $offset = $date->format('Z') + 45000;
- $sortkey = sprintf('%06d.%s', $offset, $tzs);
- $zones[$sortkey] = array($tzs, $date->format('P'));
- }
- catch (Exception $e) {}
- }
-
- ksort($zones);
-
- foreach ($zones as $zone) {
- list($tzs, $offset) = $zone;
- $select->add('(GMT ' . $offset . ') ' . strtr($tzs, '_', ' '), $tzs);
- }
-
- $blocks['main']['options']['timezone'] = array(
- 'title' => html::label($field_id, Q(rcube_label('timezone'))),
- 'content' => $select->show((string)$config['timezone']),
- );
- }
-
- // date/time formatting
- if (!isset($no_override['time_format'])) {
- if (!$current) {
- continue 2;
- }
-
- $reftime = mktime(7,30,0);
- $defaults = array('G:i', 'H:i', 'g:i a', 'h:i A');
- $formats = (array)$RCMAIL->config->get('time_formats', $defaults);
- $field_id = 'rcmfd_time_format';
- $select = new html_select(array('name' => '_time_format', 'id' => $field_id));
-
- foreach ($formats as $choice) {
- $select->add(date($choice, $reftime), $choice);
- }
-
- $blocks['main']['options']['time_format'] = array(
- 'title' => html::label($field_id, Q(rcube_label('timeformat'))),
- 'content' => $select->show($RCMAIL->config->get('time_format')),
- );
- }
-
- if (!isset($no_override['date_format'])) {
- if (!$current) {
- continue 2;
- }
-
- $refdate = mktime(12,30,0,7,24);
- $defaults = array('Y-m-d','d-m-Y','Y/m/d','m/d/Y','d/m/Y','d.m.Y','j.n.Y');
- $formats = (array)$RCMAIL->config->get('date_formats', $defaults);
- $field_id = 'rcmfd_date_format';
- $select = new html_select(array('name' => '_date_format', 'id' => $field_id));
-
- foreach ($formats as $choice) {
- $select->add(date($choice, $refdate), $choice);
- }
-
- $blocks['main']['options']['date_format'] = array(
- 'title' => html::label($field_id, Q(rcube_label('dateformat'))),
- 'content' => $select->show($config['date_format']),
- );
- }
-
- // Show checkbox for toggling 'pretty dates'
- if (!isset($no_override['prettydate'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_prettydate';
- $input = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['prettydate'] = array(
- 'title' => html::label($field_id, Q(rcube_label('prettydate'))),
- 'content' => $input->show($config['prettydate']?1:0),
- );
- }
-
- if (!isset($no_override['refresh_interval'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_refresh_interval';
- $select = new html_select(array('name' => '_refresh_interval', 'id' => $field_id));
-
- $select->add(rcube_label('never'), 0);
- foreach (array(1, 3, 5, 10, 15, 30, 60) as $min) {
- if (!$config['min_refresh_interval'] || $config['min_refresh_interval'] <= $min * 60) {
- $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
- $select->add($label, $min);
- }
- }
-
- $blocks['main']['options']['refresh_interval'] = array(
- 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
- 'content' => $select->show($config['refresh_interval']/60),
- );
- }
-
- // show drop-down for available skins
- if (!isset($no_override['skin'])) {
- if (!$current) {
- continue 2;
- }
-
- $skins = rcmail_get_skins();
-
- if (count($skins) > 1) {
- $field_id = 'rcmfd_skin';
- $input = new html_radiobutton(array('name'=>'_skin'));
-
- foreach ($skins as $skin) {
- $thumbnail = "./skins/$skin/thumbnail.png";
- if (!is_file($thumbnail))
- $thumbnail = './program/resources/blank.gif';
-
- $skinname = ucfirst($skin);
- $author_link = $license_link = '';
- $meta = @json_decode(@file_get_contents("./skins/$skin/meta.json"), true);
-
- if (is_array($meta) && $meta['name']) {
- $skinname = $meta['name'];
- $author_link = $meta['url'] ? html::a(array('href' => $meta['url'], 'target' => '_blank'), Q($meta['author'])) : Q($meta['author']);
- $license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), Q($meta['license'])) : Q($meta['license']);
- }
-
- $blocks['skin']['options'][$skin]['content'] = html::label(array('class' => 'skinselection'),
- html::span('skinitem', $input->show($config['skin'], array('value' => $skin, 'id' => $field_id.$skin))) .
- html::span('skinitem', html::img(array('src' => $thumbnail, 'class' => 'skinthumbnail', 'alt' => $skin, 'width' => 64, 'height' => 64))) .
- html::span('skinitem', html::span('skinname', Q($skinname)) . html::br() .
- html::span('skinauthor', $author_link ? 'by ' . $author_link : '') . html::br() .
- html::span('skinlicense', $license_link ? rcube_label('license').':&nbsp;' . $license_link : ''))
- );
- }
- }
- }
-
- // standard_windows option decides if new windows should be
- // opened as popups or standard windows (which can be handled by browsers as tabs)
- if (!isset($no_override['standard_windows'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_standard_windows';
- $checkbox = new html_checkbox(array('name' => '_standard_windows', 'id' => $field_id, 'value' => 1));
-
- $blocks['browser']['options']['standard_windows'] = array(
- 'title' => html::label($field_id, Q(rcube_label('standardwindows'))),
- 'content' => $checkbox->show($config['standard_windows']?1:0),
- );
- }
-
- if ($current) {
- $product_name = $RCMAIL->config->get('product_name', 'Roundcube Webmail');
- $RCMAIL->output->add_script(sprintf("%s.check_protocol_handler('%s', '#mailtoprotohandler');",
- JS_OBJECT_NAME, JQ($product_name)), 'foot');
- }
-
- $blocks['browser']['options']['mailtoprotohandler'] = array(
- 'content' => html::a(array(
- 'href' => '#',
- 'id' => 'mailtoprotohandler'), Q(rcube_label('mailtoprotohandler'))),
- );
-
- break;
-
- // Mailbox view (mail screen)
- case 'mailbox':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'new_message' => array('name' => Q(rcube_label('newmessage'))),
- );
-
- // show config parameter for preview pane
- if (!isset($no_override['preview_pane'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_preview';
- $input = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1,
- 'onchange' => "$('#rcmfd_preview_pane_mark_read').prop('disabled', !this.checked)"));
-
- $blocks['main']['options']['preview_pane'] = array(
- 'title' => html::label($field_id, Q(rcube_label('previewpane'))),
- 'content' => $input->show($config['preview_pane']?1:0),
- );
- }
-
- // show config parameter for preview pane auto mark as read delay
- if (!isset($no_override['preview_pane_mark_read'])) {
- if (!$current) {
- continue 2;
- }
-
- // apply default if config option is not set at all
- $config['preview_pane_mark_read'] = $RCMAIL->config->get('preview_pane_mark_read', 0);
-
- $field_id = 'rcmfd_preview_pane_mark_read';
- $select = new html_select(array('name' => '_preview_pane_mark_read', 'id' => $field_id,
- 'disabled' => $config['preview_pane']?0:1));
-
- $select->add(rcube_label('never'), '-1');
- $select->add(rcube_label('immediately'), 0);
-
- foreach (array(5, 10, 20, 30) as $sec) {
- $label = rcube_label(array('name' => 'afternseconds', 'vars' => array('n' => $sec)));
- $select->add($label, $sec);
- }
-
- $blocks['main']['options']['preview_pane_mark_read'] = array(
- 'title' => html::label($field_id, Q(rcube_label('previewpanemarkread'))),
- 'content' => $select->show(intval($config['preview_pane_mark_read'])),
- );
- }
-
- if (!isset($no_override['mdn_requests'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_mdn_requests';
- $select = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
- $select->add(rcube_label('askuser'), 0);
- $select->add(rcube_label('autosend'), 1);
- $select->add(rcube_label('autosendknown'), 3);
- $select->add(rcube_label('autosendknownignore'), 4);
- $select->add(rcube_label('ignore'), 2);
-
- $blocks['main']['options']['mdn_requests'] = array(
- 'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
- 'content' => $select->show($config['mdn_requests']),
- );
- }
-
- if (!isset($no_override['autoexpand_threads'])) {
- if (!$current) {
- continue 2;
- }
-
- $storage = $RCMAIL->get_storage();
- $supported = $storage->get_capability('THREAD');
-
- if ($supported) {
- $field_id = 'rcmfd_autoexpand_threads';
- $select = new html_select(array('name' => '_autoexpand_threads', 'id' => $field_id));
- $select->add(rcube_label('never'), 0);
- $select->add(rcube_label('do_expand'), 1);
- $select->add(rcube_label('expand_only_unread'), 2);
-
- $blocks['main']['options']['autoexpand_threads'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autoexpand_threads'))),
- 'content' => $select->show($config['autoexpand_threads']),
- );
- }
- }
-
- // show page size selection
- if (!isset($no_override['mail_pagesize'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_mail_pagesize';
- $input = new html_inputfield(array('name' => '_mail_pagesize', 'id' => $field_id, 'size' => 5));
- $size = intval($config['mail_pagesize'] ? $config['mail_pagesize'] : $config['pagesize']);
-
- $blocks['main']['options']['pagesize'] = array(
- 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
- 'content' => $input->show($size ? $size : 50),
- );
- }
-
- if (!isset($no_override['check_all_folders'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_check_all_folders';
- $input = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
-
- $blocks['new_message']['options']['check_all_folders'] = array(
- 'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
- 'content' => $input->show($config['check_all_folders']?1:0),
- );
- }
- break;
-
- // Message viewing
- case 'mailview':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- );
-
- // show checkbox to open message view in new window
- if (!isset($no_override['message_extwin'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_message_extwin';
- $input = new html_checkbox(array('name' => '_message_extwin', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['message_extwin'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showinextwin'))),
- 'content' => $input->show($config['message_extwin']?1:0),
- );
- }
-
- // show checkbox to show email instead of name
- if (!isset($no_override['message_show_email'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_message_show_email';
- $input = new html_checkbox(array('name' => '_message_show_email', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['message_show_email'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showemail'))),
- 'content' => $input->show($config['message_show_email']?1:0),
- );
- }
-
- // show checkbox for HTML/plaintext messages
- if (!isset($no_override['prefer_html'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_htmlmsg';
- $input = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
- 'onchange' => "$('#rcmfd_show_images').prop('disabled', !this.checked).val(0)"));
-
- $blocks['main']['options']['prefer_html'] = array(
- 'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
- 'content' => $input->show($config['prefer_html']?1:0),
- );
- }
-
- if (!isset($no_override['default_charset'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_default_charset';
-
- $blocks['main']['options']['default_charset'] = array(
- 'title' => html::label($field_id, Q(rcube_label('defaultcharset'))),
- 'content' => $RCMAIL->output->charset_selector(array(
- 'id' => $field_id, 'name' => '_default_charset', 'selected' => $config['default_charset']
- )));
- }
-
- if (!isset($no_override['show_images'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_show_images';
- $input = new html_select(array('name' => '_show_images', 'id' => $field_id,
- 'disabled' => !$config['prefer_html']));
-
- $input->add(rcube_label('never'), 0);
- $input->add(rcube_label('fromknownsenders'), 1);
- $input->add(rcube_label('always'), 2);
-
- $blocks['main']['options']['show_images'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
- 'content' => $input->show($config['prefer_html'] ? $config['show_images'] : 0),
- );
- }
-
- if (!isset($no_override['inline_images'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_inline_images';
- $input = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['inline_images'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
- 'content' => $input->show($config['inline_images']?1:0),
- );
- }
-
- // "display after delete" checkbox
- if (!isset($no_override['display_next'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_displaynext';
- $input = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['display_next'] = array(
- 'title' => html::label($field_id, Q(rcube_label('displaynext'))),
- 'content' => $input->show($config['display_next']?1:0),
- );
- }
- break;
-
- // Mail composition
- case 'compose':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'sig' => array('name' => Q(rcube_label('signatureoptions'))),
- 'spellcheck' => array('name' => Q(rcube_label('spellcheckoptions'))),
- );
-
- // show checkbox to compose messages in a new window
- if (!isset($no_override['compose_extwin'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfdcompose_extwin';
- $input = new html_checkbox(array('name' => '_compose_extwin', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['compose_extwin'] = array(
- 'title' => html::label($field_id, Q(rcube_label('composeextwin'))),
- 'content' => $input->show($config['compose_extwin']?1:0),
- );
- }
-
- if (!isset($no_override['htmleditor'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_htmleditor';
- $select = new html_select(array('name' => '_htmleditor', 'id' => $field_id));
-
- $select->add(rcube_label('never'), 0);
- $select->add(rcube_label('always'), 1);
- $select->add(rcube_label('htmlonreply'), 2);
- $select->add(rcube_label('htmlonreplyandforward'), 3);
-
- $blocks['main']['options']['htmleditor'] = array(
- 'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
- 'content' => $select->show(intval($config['htmleditor'])),
- );
- }
-
- if (!isset($no_override['draft_autosave'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_autosave';
- $select = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
-
- $select->add(rcube_label('never'), 0);
- foreach (array(1, 3, 5, 10) as $i => $min) {
- $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
- $select->add($label, $min*60);
- }
-
- $blocks['main']['options']['draft_autosave'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
- 'content' => $select->show($config['draft_autosave']),
- );
- }
-
- if (!isset($no_override['mime_param_folding'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_param_folding';
- $select = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
-
- $select->add(rcube_label('2231folding'), 0);
- $select->add(rcube_label('miscfolding'), 1);
- $select->add(rcube_label('2047folding'), 2);
-
- $blocks['main']['options']['mime_param_folding'] = array(
- 'advanced' => true,
- 'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
- 'content' => $select->show($config['mime_param_folding']),
- );
- }
-
- if (!isset($no_override['force_7bit'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_force_7bit';
- $input = new html_checkbox(array('name' => '_force_7bit', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['force_7bit'] = array(
- 'advanced' => true,
- 'title' => html::label($field_id, Q(rcube_label('force7bit'))),
- 'content' => $input->show($config['force_7bit']?1:0),
- );
- }
-
- if (!isset($no_override['mdn_default'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_mdn_default';
- $input = new html_checkbox(array('name' => '_mdn_default', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['mdn_default'] = array(
- 'title' => html::label($field_id, Q(rcube_label('reqmdn'))),
- 'content' => $input->show($config['mdn_default']?1:0),
- );
- }
-
- if (!isset($no_override['dsn_default'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_dsn_default';
- $input = new html_checkbox(array('name' => '_dsn_default', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['dsn_default'] = array(
- 'title' => html::label($field_id, Q(rcube_label('reqdsn'))),
- 'content' => $input->show($config['dsn_default']?1:0),
- );
- }
-
- if (!isset($no_override['reply_same_folder'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_reply_same_folder';
- $input = new html_checkbox(array('name' => '_reply_same_folder', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['reply_same_folder'] = array(
- 'title' => html::label($field_id, Q(rcube_label('replysamefolder'))),
- 'content' => $input->show($config['reply_same_folder']?1:0),
- );
- }
-
- if (!isset($no_override['reply_mode'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_reply_mode';
- $select = new html_select(array('name' => '_reply_mode', 'id' => $field_id));
-
- $select->add(rcube_label('replyempty'), -1);
- $select->add(rcube_label('replybottomposting'), 0);
- $select->add(rcube_label('replytopposting'), 1);
-
- $blocks['main']['options']['reply_mode'] = array(
- 'title' => html::label($field_id, Q(rcube_label('whenreplying'))),
- 'content' => $select->show(intval($config['reply_mode'])),
- );
- }
-
- if (!isset($no_override['spellcheck_before_send']) && $config['enable_spellcheck']) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_spellcheck_before_send';
- $input = new html_checkbox(array('name' => '_spellcheck_before_send', 'id' => $field_id, 'value' => 1));
-
- $blocks['spellcheck']['options']['spellcheck_before_send'] = array(
- 'title' => html::label($field_id, Q(rcube_label('spellcheckbeforesend'))),
- 'content' => $input->show($config['spellcheck_before_send']?1:0),
- );
- }
-
- if ($config['enable_spellcheck']) {
- if (!$current) {
- continue 2;
- }
-
- foreach (array('syms', 'nums', 'caps') as $key) {
- $key = 'spellcheck_ignore_'.$key;
- if (!isset($no_override[$key])) {
- $input = new html_checkbox(array('name' => '_'.$key, 'id' => 'rcmfd_'.$key, 'value' => 1));
-
- $blocks['spellcheck']['options'][$key] = array(
- 'title' => html::label($field_id, Q(rcube_label(str_replace('_', '', $key)))),
- 'content' => $input->show($config[$key]?1:0),
- );
- }
- }
- }
-
- if (!isset($no_override['show_sig'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_show_sig';
- $select = new html_select(array('name' => '_show_sig', 'id' => $field_id));
-
- $select->add(rcube_label('never'), 0);
- $select->add(rcube_label('always'), 1);
- $select->add(rcube_label('newmessageonly'), 2);
- $select->add(rcube_label('replyandforwardonly'), 3);
-
- $blocks['sig']['options']['show_sig'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autoaddsignature'))),
- 'content' => $select->show($RCMAIL->config->get('show_sig', 1)),
- );
- }
-
- if (!isset($no_override['strip_existing_sig'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_strip_existing_sig';
- $input = new html_checkbox(array('name' => '_strip_existing_sig', 'id' => $field_id, 'value' => 1));
-
- $blocks['sig']['options']['strip_existing_sig'] = array(
- 'title' => html::label($field_id, Q(rcube_label('replyremovesignature'))),
- 'content' => $input->show($config['strip_existing_sig']?1:0),
- );
- }
-
- if (!isset($no_override['forward_attachment'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_forward_attachment';
- $select = new html_select(array('name' => '_forward_attachment', 'id' => $field_id));
-
- $select->add(rcube_label('inline'), 0);
- $select->add(rcube_label('asattachment'), 1);
-
- $blocks['main']['options']['forward_attachment'] = array(
- 'title' => html::label($field_id, Q(rcube_label('forwardmode'))),
- 'content' => $select->show(intval($config['forward_attachment'])),
- );
- }
-
- if (!isset($no_override['default_font'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_default_font';
- $fonts = rcube_fontdefs();
- $selected = $config['default_font'];
-
- $select = '<select name="_default_font" id="'.$field_id.'">';
- $select .= '<option value=""' . (!$selected ? ' selected="selected"' : '') . '>---</option>';
- foreach ($fonts as $fname => $font) {
- $select .= '<option value="'.$fname.'"'
- . ($fname == $selected ? ' selected="selected"' : '')
- . ' style=\'font-family: ' . $font . '\'>'
- . Q($fname) . '</option>';
- }
- $select .= '</select>';
-
- $blocks['main']['options']['default_font'] = array(
- 'title' => html::label($field_id, Q(rcube_label('defaultfont'))),
- 'content' => $select
- );
- }
- break;
-
- // Addressbook config
- case 'addressbook':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- );
-
- if (!isset($no_override['default_addressbook'])
- && (!$current || ($books = $RCMAIL->get_address_sources(true, true)))
- ) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_default_addressbook';
- $select = new html_select(array('name' => '_default_addressbook', 'id' => $field_id));
-
- foreach ($books as $book) {
- $select->add(html_entity_decode($book['name'], ENT_COMPAT, 'UTF-8'), $book['id']);
- }
-
- $blocks['main']['options']['default_addressbook'] = array(
- 'title' => html::label($field_id, Q(rcube_label('defaultabook'))),
- 'content' => $select->show($config['default_addressbook']),
- );
- }
-
- // show addressbook listing mode selection
- if (!isset($no_override['addressbook_name_listing'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_addressbook_name_listing';
- $select = new html_select(array('name' => '_addressbook_name_listing', 'id' => $field_id));
-
- $select->add(rcube_label('name'), 0);
- $select->add(rcube_label('firstname') . ' ' . rcube_label('surname'), 1);
- $select->add(rcube_label('surname') . ' ' . rcube_label('firstname'), 2);
- $select->add(rcube_label('surname') . ', ' . rcube_label('firstname'), 3);
-
- $blocks['main']['options']['list_name_listing'] = array(
- 'title' => html::label($field_id, Q(rcube_label('listnamedisplay'))),
- 'content' => $select->show($config['addressbook_name_listing']),
- );
- }
-
- // show addressbook sort column
- if (!isset($no_override['addressbook_sort_col'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_addressbook_sort_col';
- $select = new html_select(array('name' => '_addressbook_sort_col', 'id' => $field_id));
-
- $select->add(rcube_label('name'), 'name');
- $select->add(rcube_label('firstname'), 'firstname');
- $select->add(rcube_label('surname'), 'surname');
-
- $blocks['main']['options']['sort_col'] = array(
- 'title' => html::label($field_id, Q(rcube_label('listsorting'))),
- 'content' => $select->show($config['addressbook_sort_col']),
- );
- }
-
- // show addressbook page size selection
- if (!isset($no_override['addressbook_pagesize'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_addressbook_pagesize';
- $input = new html_inputfield(array('name' => '_addressbook_pagesize', 'id' => $field_id, 'size' => 5));
- $size = intval($config['addressbook_pagesize'] ? $config['addressbook_pagesize'] : $config['pagesize']);
-
- $blocks['main']['options']['pagesize'] = array(
- 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
- 'content' => $input->show($size ? $size : 50),
- );
- }
-
- if (!isset($no_override['autocomplete_single'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_autocomplete_single';
- $checkbox = new html_checkbox(array('name' => '_autocomplete_single', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['autocomplete_single'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autocompletesingle'))),
- 'content' => $checkbox->show($config['autocomplete_single']?1:0),
- );
- }
- break;
-
- // Special IMAP folders
- case 'folders':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- );
-
- if (!isset($no_override['show_real_foldernames'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'show_real_foldernames';
- $input = new html_checkbox(array('name' => '_show_real_foldernames', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['show_real_foldernames'] = array(
- 'title' => html::label($field_id, Q(rcube_label('show_real_foldernames'))),
- 'content' => $input->show($config['show_real_foldernames']?1:0),
- );
- }
-
- // Configure special folders
- if (!isset($no_override['default_folders']) && $current) {
- $select = rcmail_mailbox_select(array(
- 'noselection' => '---',
- 'realnames' => true,
- 'maxlength' => 30,
- 'folder_filter' => 'mail',
- 'folder_rights' => 'w',
- ));
- }
-
- // #1486114, #1488279, #1489219
- $onchange = "if ($(this).val() == 'INBOX') $(this).val('')";
-
- if (!isset($no_override['drafts_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['drafts_mbox'] = array(
- 'title' => Q(rcube_label('drafts')),
- 'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox", 'onchange' => $onchange)),
- );
- }
-
- if (!isset($no_override['sent_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['sent_mbox'] = array(
- 'title' => Q(rcube_label('sent')),
- 'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox", 'onchange' => '')),
- );
- }
-
- if (!isset($no_override['junk_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['junk_mbox'] = array(
- 'title' => Q(rcube_label('junk')),
- 'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox", 'onchange' => $onchange)),
- );
- }
-
- if (!isset($no_override['trash_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['trash_mbox'] = array(
- 'title' => Q(rcube_label('trash')),
- 'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox", 'onchange' => $onchange)),
- );
- }
- break;
-
- // Server settings
- case 'server':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'maintenance' => array('name' => Q(rcube_label('maintenance'))),
- );
-
- if (!isset($no_override['read_when_deleted'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_read_deleted';
- $input = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['read_when_deleted'] = array(
- 'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
- 'content' => $input->show($config['read_when_deleted']?1:0),
- );
- }
-
- if (!isset($no_override['flag_for_deletion'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_flag_for_deletion';
- $input = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['flag_for_deletion'] = array(
- 'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
- 'content' => $input->show($config['flag_for_deletion']?1:0),
- );
- }
-
- // don't show deleted messages
- if (!isset($no_override['skip_deleted'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_skip_deleted';
- $input = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['skip_deleted'] = array(
- 'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
- 'content' => $input->show($config['skip_deleted']?1:0),
- );
- }
-
- if (!isset($no_override['delete_always'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_delete_always';
- $input = new html_checkbox(array('name' => '_delete_always', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['delete_always'] = array(
- 'title' => html::label($field_id, Q(rcube_label('deletealways'))),
- 'content' => $input->show($config['delete_always']?1:0),
- );
- }
-
- if (!isset($no_override['delete_junk'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_delete_junk';
- $input = new html_checkbox(array('name' => '_delete_junk', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['delete_junk'] = array(
- 'title' => html::label($field_id, Q(rcube_label('deletejunk'))),
- 'content' => $input->show($config['delete_junk']?1:0),
- );
- }
-
- // Trash purging on logout
- if (!isset($no_override['logout_purge'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_logout_purge';
- $input = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
-
- $blocks['maintenance']['options']['logout_purge'] = array(
- 'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
- 'content' => $input->show($config['logout_purge']?1:0),
- );
- }
-
- // INBOX compacting on logout
- if (!isset($no_override['logout_expunge'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_logout_expunge';
- $input = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
-
- $blocks['maintenance']['options']['logout_expunge'] = array(
- 'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
- 'content' => $input->show($config['logout_expunge']?1:0),
- );
- }
+ $blocks['main']['options']['prettydate'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('prettydate'))),
+ 'content' => $input_prettydate->show($config['prettydate']?1:0),
+ );
+ }
+
+ if (!isset($no_override['refresh_interval'])) {
+ $field_id = 'rcmfd_refresh_interval';
+ $select_refresh_interval = new html_select(array('name' => '_refresh_interval', 'id' => $field_id));
+
+ $select_refresh_interval->add(rcube_label('never'), 0);
+ foreach (array(1, 3, 5, 10, 15, 30, 60) as $min) {
+ if (!$config['min_refresh_interval'] || $config['min_refresh_interval'] <= $min * 60) {
+ $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
+ $select_refresh_interval->add($label, $min);
}
+ }
- $found = false;
- $data = $RCMAIL->plugins->exec_hook('preferences_list',
- array('section' => $sect['id'], 'blocks' => $blocks, 'current' => $current));
+ $blocks['main']['options']['refresh_interval'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
+ 'content' => $select_refresh_interval->show($config['refresh_interval']/60),
+ );
+ }
- // create output
- foreach ($data['blocks'] as $block) {
- if (!empty($block['content']) || !empty($block['options'])) {
- $found = true;
- break;
- }
+ // show drop-down for available skins
+ if (!isset($no_override['skin'])) {
+ $skins = rcmail_get_skins();
+
+ if (count($skins) > 1) {
+ $field_id = 'rcmfd_skin';
+ $input_skin = new html_radiobutton(array('name'=>'_skin'));
+
+ $blocks['skin'] = array('name' => Q(rcube_label('skin')),);
+
+ foreach($skins as $skin) {
+ $thumbnail = "./skins/$skin/thumbnail.png";
+ if (!is_file($thumbnail))
+ $thumbnail = './program/resources/blank.gif';
+
+ $skinname = ucfirst($skin);
+ $author_link = $license_link = '';
+ $meta = @json_decode(@file_get_contents("./skins/$skin/meta.json"), true);
+ if (is_array($meta) && $meta['name']) {
+ $skinname = $meta['name'];
+ $author_link = $meta['url'] ? html::a(array('href' => $meta['url'], 'target' => '_blank'), Q($meta['author'])) : Q($meta['author']);
+ $license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), Q($meta['license'])) : Q($meta['license']);
+ }
+
+ $blocks['skin']['options'][$skin]['content'] = html::label(array('class' => 'skinselection'),
+ html::span('skinitem', $input_skin->show($config['skin'], array('value' => $skin, 'id' => $field_id.$skin))) .
+ html::span('skinitem', html::img(array('src' => $thumbnail, 'class' => 'skinthumbnail', 'alt' => $skin, 'width' => 64, 'height' => 64))) .
+ html::span('skinitem', html::span('skinname', Q($skinname)) . html::br() .
+ html::span('skinauthor', $author_link ? 'by ' . $author_link : '') . html::br() .
+ html::span('skinlicense', $license_link ? rcube_label('license').':&nbsp;' . $license_link : ''))
+ );
}
+ }
+ }
- if (!$found)
- unset($sections[$idx]);
- else
- $sections[$idx]['blocks'] = $data['blocks'];
+ $product_name = $RCMAIL->config->get('product_name', 'Roundcube Webmail');
+ $RCMAIL->output->add_script(sprintf("%s.check_protocol_handler('%s', '#mailtoprotohandler');",
+ JS_OBJECT_NAME, JQ($product_name)), 'foot');
+
+ $blocks['browser'] = array(
+ 'name' => Q(rcube_label('browseroptions')),
+ 'options' => array('mailtoprotohandler' => array(
+ 'content' => html::a(array(
+ 'href' => '#',
+ 'id' => 'mailtoprotohandler'), Q(rcube_label('mailtoprotohandler'))),
+ )),
+ );
+
+ break;
+
+ // Mailbox view (mail screen)
+ case 'mailbox':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ 'new_message' => array('name' => Q(rcube_label('newmessage'))),
+ );
+
+ // show config parameter for preview pane
+ if (!isset($no_override['preview_pane'])) {
+ $field_id = 'rcmfd_preview';
+ $input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1,
+ 'onchange' => "$('#rcmfd_preview_pane_mark_read').prop('disabled', !this.checked)"));
+
+ $blocks['main']['options']['preview_pane'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('previewpane'))),
+ 'content' => $input_preview->show($config['preview_pane']?1:0),
+ );
}
- return array($sections, $plugin['cols']);
-}
+ // show config parameter for preview pane auto mark as read delay
+ if (!isset($no_override['preview_pane_mark_read'])) {
+ // apply default if config option is not set at all
+ $config['preview_pane_mark_read'] = $RCMAIL->config->get('preview_pane_mark_read', 0);
+ $field_id = 'rcmfd_preview_pane_mark_read';
+ $select_delay = new html_select(array('name' => '_preview_pane_mark_read', 'id' => $field_id,
+ 'disabled' => $config['preview_pane']?0:1));
-function rcmail_get_skins()
-{
- $path = RCUBE_INSTALL_PATH . 'skins';
- $skins = array();
- $dir = opendir($path);
+ $select_delay->add(rcube_label('never'), '-1');
+ $select_delay->add(rcube_label('immediately'), 0);
+ foreach(array(5, 10, 20, 30) as $sec)
+ $select_delay->add(rcube_label(array('name' => 'afternseconds', 'vars' => array('n' => $sec))), $sec);
+
+ $blocks['main']['options']['preview_pane_mark_read'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('previewpanemarkread'))),
+ 'content' => $select_delay->show(intval($config['preview_pane_mark_read'])),
+ );
+ }
+
+ if (!isset($no_override['mdn_requests'])) {
+ $field_id = 'rcmfd_mdn_requests';
+ $select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
+ $select_mdn_requests->add(rcube_label('askuser'), 0);
+ $select_mdn_requests->add(rcube_label('autosend'), 1);
+ $select_mdn_requests->add(rcube_label('autosendknown'), 3);
+ $select_mdn_requests->add(rcube_label('autosendknownignore'), 4);
+ $select_mdn_requests->add(rcube_label('ignore'), 2);
+
+ $blocks['main']['options']['mdn_requests'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
+ 'content' => $select_mdn_requests->show($config['mdn_requests']),
+ );
+ }
+
+ $storage = $RCMAIL->get_storage();
+ $threading_supported = $storage->get_capability('THREAD');
+
+ if (!isset($no_override['autoexpand_threads']) && $threading_supported) {
+ $field_id = 'rcmfd_autoexpand_threads';
+ $select_autoexpand_threads = new html_select(array('name' => '_autoexpand_threads', 'id' => $field_id));
+ $select_autoexpand_threads->add(rcube_label('never'), 0);
+ $select_autoexpand_threads->add(rcube_label('do_expand'), 1);
+ $select_autoexpand_threads->add(rcube_label('expand_only_unread'), 2);
+
+ $blocks['main']['options']['autoexpand_threads'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autoexpand_threads'))),
+ 'content' => $select_autoexpand_threads->show($config['autoexpand_threads']),
+ );
+ }
+
+ // show page size selection
+ if (!isset($no_override['mail_pagesize'])) {
+ $field_id = 'rcmfd_mail_pagesize';
+ $input_pagesize = new html_inputfield(array('name' => '_mail_pagesize', 'id' => $field_id, 'size' => 5));
+
+ $size = intval($config['mail_pagesize'] ? $config['mail_pagesize'] : $config['pagesize']);
+
+ $blocks['main']['options']['pagesize'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
+ 'content' => $input_pagesize->show($size ? $size : 50),
+ );
+ }
+ if (!isset($no_override['check_all_folders'])) {
+ $field_id = 'rcmfd_check_all_folders';
+ $input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
+
+ $blocks['new_message']['options']['check_all_folders'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
+ 'content' => $input_check_all->show($config['check_all_folders']?1:0),
+ );
+ }
+
+ break;
+
+ // Message viewing
+ case 'mailview':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ // show checkbox to open message view in new window
+ if (!isset($no_override['message_extwin'])) {
+ $field_id = 'rcmfd_message_extwin';
+ $input_msgextwin = new html_checkbox(array('name' => '_message_extwin', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['message_extwin'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('showinextwin'))),
+ 'content' => $input_msgextwin->show($config['message_extwin']?1:0),
+ );
+ }
+
+ // show checkbox for HTML/plaintext messages
+ if (!isset($no_override['prefer_html'])) {
+ $field_id = 'rcmfd_htmlmsg';
+ $input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
+ 'onchange' => "$('#rcmfd_show_images').prop('disabled', !this.checked).val(0)"));
+
+ $blocks['main']['options']['prefer_html'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
+ 'content' => $input_preferhtml->show($config['prefer_html']?1:0),
+ );
+ }
+
+ if (!isset($no_override['default_charset'])) {
+ $field_id = 'rcmfd_default_charset';
+
+ $blocks['main']['options']['default_charset'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('defaultcharset'))),
+ 'content' => $RCMAIL->output->charset_selector(array(
+ 'name' => '_default_charset', 'selected' => $config['default_charset']
+ ))
+ );
+ }
+
+ if (!isset($no_override['show_images'])) {
+ $field_id = 'rcmfd_show_images';
+ $input_show_images = new html_select(array('name' => '_show_images', 'id' => $field_id,
+ 'disabled' => !$config['prefer_html']));
+ $input_show_images->add(rcube_label('never'), 0);
+ $input_show_images->add(rcube_label('fromknownsenders'), 1);
+ $input_show_images->add(rcube_label('always'), 2);
+
+ $blocks['main']['options']['show_images'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
+ 'content' => $input_show_images->show($config['prefer_html'] ? $config['show_images'] : 0),
+ );
+ }
+
+ if (!isset($no_override['inline_images'])) {
+ $field_id = 'rcmfd_inline_images';
+ $input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['inline_images'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
+ 'content' => $input_inline_images->show($config['inline_images']?1:0),
+ );
+ }
+
+ // "display after delete" checkbox
+ if (!isset($no_override['display_next'])) {
+ $field_id = 'rcmfd_displaynext';
+ $input_displaynext = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['display_next'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('displaynext'))),
+ 'content' => $input_displaynext->show($config['display_next']?1:0),
+ );
+ }
+
+ break;
+
+ // Mail composition
+ case 'compose':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ 'sig' => array('name' => Q(rcube_label('signatureoptions'))),
+ 'spellcheck' => array('name' => Q(rcube_label('spellcheckoptions'))),
+ );
+
+ // show checkbox to compose messages in a new window
+ if (!isset($no_override['compose_extwin'])) {
+ $field_id = 'rcmfdcompose_extwin';
+ $input_compextwin = new html_checkbox(array('name' => '_compose_extwin', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['compose_extwin'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('composeextwin'))),
+ 'content' => $input_compextwin->show($config['compose_extwin']?1:0),
+ );
+ }
+
+ if (!isset($no_override['htmleditor'])) {
+ $field_id = 'rcmfd_htmleditor';
+ $select_htmleditor = new html_select(array('name' => '_htmleditor', 'id' => $field_id));
+ $select_htmleditor->add(rcube_label('never'), 0);
+ $select_htmleditor->add(rcube_label('always'), 1);
+ $select_htmleditor->add(rcube_label('htmlonreply'), 2);
+ $select_htmleditor->add(rcube_label('htmlonreplyandforward'), 3);
+
+ $blocks['main']['options']['htmleditor'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
+ 'content' => $select_htmleditor->show(intval($config['htmleditor'])),
+ );
+ }
+
+ if (!isset($no_override['draft_autosave'])) {
+ $field_id = 'rcmfd_autosave';
+ $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
+ $select_autosave->add(rcube_label('never'), 0);
+ foreach (array(1, 3, 5, 10) as $i => $min)
+ $select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
+
+ $blocks['main']['options']['draft_autosave'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
+ 'content' => $select_autosave->show($config['draft_autosave']),
+ );
+ }
+
+ if (!isset($no_override['mime_param_folding'])) {
+ $field_id = 'rcmfd_param_folding';
+ $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
+ $select_param_folding->add(rcube_label('2231folding'), 0);
+ $select_param_folding->add(rcube_label('miscfolding'), 1);
+ $select_param_folding->add(rcube_label('2047folding'), 2);
+
+ $blocks['main']['options']['mime_param_folding'] = array(
+ 'advanced' => true,
+ 'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
+ 'content' => $select_param_folding->show($config['mime_param_folding']),
+ );
+ }
+
+ if (!isset($no_override['force_7bit'])) {
+ $field_id = 'rcmfd_force_7bit';
+ $input_7bit = new html_checkbox(array('name' => '_force_7bit', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['force_7bit'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('force7bit'))),
+ 'content' => $input_7bit->show($config['force_7bit']?1:0),
+ );
+ }
+
+ if (!isset($no_override['mdn_default'])) {
+ $field_id = 'rcmfd_mdn_default';
+ $input_mdn = new html_checkbox(array('name' => '_mdn_default', 'id' => $field_id, 'value' => 1));
- if (!$dir) {
- return false;
+ $blocks['main']['options']['mdn_default'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('reqmdn'))),
+ 'content' => $input_mdn->show($config['mdn_default']?1:0),
+ );
}
- while (($file = readdir($dir)) !== false) {
- $filename = $path.'/'.$file;
- if (!preg_match('/^\./', $file) && is_dir($filename) && is_readable($filename)) {
- $skins[] = $file;
+ if (!isset($no_override['dsn_default'])) {
+ $field_id = 'rcmfd_dsn_default';
+ $input_dsn = new html_checkbox(array('name' => '_dsn_default', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['dsn_default'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('reqdsn'))),
+ 'content' => $input_dsn->show($config['dsn_default']?1:0),
+ );
+ }
+
+ if (!isset($no_override['reply_same_folder'])) {
+ $field_id = 'rcmfd_reply_same_folder';
+ $input_reply_same_folder = new html_checkbox(array('name' => '_reply_same_folder', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['reply_same_folder'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('replysamefolder'))),
+ 'content' => $input_reply_same_folder->show($config['reply_same_folder']?1:0),
+ );
+ }
+
+ if (!isset($no_override['reply_mode'])) {
+ $field_id = 'rcmfd_reply_mode';
+ $select_replymode = new html_select(array('name' => '_reply_mode', 'id' => $field_id));
+ $select_replymode->add(rcube_label('replyempty'), -1);
+ $select_replymode->add(rcube_label('replybottomposting'), 0);
+ $select_replymode->add(rcube_label('replytopposting'), 1);
+
+ $blocks['main']['options']['reply_mode'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('whenreplying'))),
+ 'content' => $select_replymode->show(intval($config['reply_mode'])),
+ );
+ }
+
+ if (!isset($no_override['spellcheck_before_send']) && $config['enable_spellcheck']) {
+ $field_id = 'rcmfd_spellcheck_before_send';
+ $input_spellcheck = new html_checkbox(array('name' => '_spellcheck_before_send', 'id' => $field_id, 'value' => 1));
+
+ $blocks['spellcheck']['options']['spellcheck_before_send'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('spellcheckbeforesend'))),
+ 'content' => $input_spellcheck->show($config['spellcheck_before_send']?1:0),
+ );
+ }
+
+ if ($config['enable_spellcheck']) {
+ foreach (array('syms', 'nums', 'caps') as $key) {
+ $key = 'spellcheck_ignore_'.$key;
+ if (!isset($no_override[$key])) {
+ $input_spellcheck = new html_checkbox(array('name' => '_'.$key, 'id' => 'rcmfd_'.$key, 'value' => 1));
+
+ $blocks['spellcheck']['options'][$key] = array(
+ 'title' => html::label($field_id, Q(rcube_label(str_replace('_', '', $key)))),
+ 'content' => $input_spellcheck->show($config[$key]?1:0),
+ );
}
+ }
+ }
+
+ if (!isset($no_override['show_sig'])) {
+ $field_id = 'rcmfd_show_sig';
+ $select_show_sig = new html_select(array('name' => '_show_sig', 'id' => $field_id));
+ $select_show_sig->add(rcube_label('never'), 0);
+ $select_show_sig->add(rcube_label('always'), 1);
+ $select_show_sig->add(rcube_label('newmessageonly'), 2);
+ $select_show_sig->add(rcube_label('replyandforwardonly'), 3);
+
+ $blocks['sig']['options']['show_sig'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autoaddsignature'))),
+ 'content' => $select_show_sig->show($RCMAIL->config->get('show_sig', 1)),
+ );
+ }
+
+ if (!isset($no_override['strip_existing_sig'])) {
+ $field_id = 'rcmfd_strip_existing_sig';
+ $input_stripexistingsig = new html_checkbox(array('name' => '_strip_existing_sig', 'id' => $field_id, 'value' => 1));
+
+ $blocks['sig']['options']['strip_existing_sig'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('replyremovesignature'))),
+ 'content' => $input_stripexistingsig->show($config['strip_existing_sig']?1:0),
+ );
+ }
+
+ if (!isset($no_override['forward_attachment'])) {
+ $field_id = 'rcmfd_forward_attachment';
+ $select = new html_select(array('name' => '_forward_attachment', 'id' => $field_id));
+ $select->add(rcube_label('inline'), 0);
+ $select->add(rcube_label('asattachment'), 1);
+
+ $blocks['main']['options']['forward_attachment'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('forwardmode'))),
+ 'content' => $select->show(intval($config['forward_attachment'])),
+ );
+ }
+
+ if (!isset($no_override['default_font'])) {
+ $field_id = 'rcmfd_default_font';
+ $fonts = rcube_fontdefs();
+ $selected = $config['default_font'];
+
+ $select = '<select name="_default_font" id="'.$field_id.'">';
+ $select .= '<option value=""' . (!$selected ? ' selected="selected"' : '') . '>---</option>';
+ foreach ($fonts as $fname => $font)
+ $select .= '<option value="'.$fname.'"'
+ . ($fname == $selected ? ' selected="selected"' : '')
+ . ' style=\'font-family: ' . $font . '\'>'
+ . Q($fname) . '</option>';
+ $select .= '</select>';
+
+ $blocks['main']['options']['default_font'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('defaultfont'))),
+ 'content' => $select
+ );
+ }
+
+ break;
+
+
+ // Addressbook config
+ case 'addressbook':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ if (!isset($no_override['default_addressbook'])
+ && ($books = $RCMAIL->get_address_sources(true, true))
+ ) {
+ $field_id = 'rcmfd_default_addressbook';
+ $select_abook = new html_select(array('name' => '_default_addressbook', 'id' => $field_id));
+
+ foreach ($books as $book) {
+ $select_abook->add(html_entity_decode($book['name'], ENT_COMPAT, 'UTF-8'), $book['id']);
+ }
+
+ $blocks['main']['options']['default_addressbook'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('defaultabook'))),
+ 'content' => $select_abook->show($config['default_addressbook']),
+ );
+ }
+
+ // show addressbook listing mode selection
+ if (!isset($no_override['addressbook_name_listing'])) {
+ $field_id = 'rcmfd_addressbook_name_listing';
+ $select_listing = new html_select(array('name' => '_addressbook_name_listing', 'id' => $field_id));
+ $select_listing->add(rcube_label('name'), 0);
+ $select_listing->add(rcube_label('firstname') . ' ' . rcube_label('surname'), 1);
+ $select_listing->add(rcube_label('surname') . ' ' . rcube_label('firstname'), 2);
+ $select_listing->add(rcube_label('surname') . ', ' . rcube_label('firstname'), 3);
+
+ $blocks['main']['options']['list_name_listing'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('listnamedisplay'))),
+ 'content' => $select_listing->show($config['addressbook_name_listing']),
+ );
}
- closedir($dir);
+ // show addressbook sort column
+ if (!isset($no_override['addressbook_sort_col'])) {
+ $field_id = 'rcmfd_addressbook_sort_col';
+ $select_sort = new html_select(array('name' => '_addressbook_sort_col', 'id' => $field_id));
+ $select_sort->add(rcube_label('name'), 'name');
+ $select_sort->add(rcube_label('firstname'), 'firstname');
+ $select_sort->add(rcube_label('surname'), 'surname');
+
+ $blocks['main']['options']['sort_col'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('listsorting'))),
+ 'content' => $select_sort->show($config['addressbook_sort_col']),
+ );
+ }
+
+ // show addressbook page size selection
+ if (!isset($no_override['addressbook_pagesize'])) {
+ $field_id = 'rcmfd_addressbook_pagesize';
+ $input_pagesize = new html_inputfield(array('name' => '_addressbook_pagesize', 'id' => $field_id, 'size' => 5));
+
+ $size = intval($config['addressbook_pagesize'] ? $config['addressbook_pagesize'] : $config['pagesize']);
+
+ $blocks['main']['options']['pagesize'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
+ 'content' => $input_pagesize->show($size ? $size : 50),
+ );
+ }
+
+ if (!isset($no_override['autocomplete_single'])) {
+ $field_id = 'rcmfd_autocomplete_single';
+ $checkbox = new html_checkbox(array('name' => '_autocomplete_single', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['autocomplete_single'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autocompletesingle'))),
+ 'content' => $checkbox->show($config['autocomplete_single']?1:0),
+ );
+ }
+
+ break;
+
+ // Special IMAP folders
+ case 'folders':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ // Configure special folders
+ if (!isset($no_override['default_folders'])) {
+ // load folders list only when needed
+ if ($current) {
+ $select = rcmail_mailbox_select(array(
+ 'noselection' => '---',
+ 'realnames' => true,
+ 'maxlength' => 30,
+ 'folder_filter' => 'mail',
+ 'folder_rights' => 'w',
+ // #1486114, #1488279
+ 'onchange' => "if ($(this).val() == 'INBOX') $(this).val('')",
+ ));
+ }
+ else // dummy select
+ $select = new html_select();
+
+ if (!isset($no_override['drafts_mbox']))
+ $blocks['main']['options']['drafts_mbox'] = array(
+ 'title' => Q(rcube_label('drafts')),
+ 'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox")),
+ );
+
+ if (!isset($no_override['sent_mbox']))
+ $blocks['main']['options']['sent_mbox'] = array(
+ 'title' => Q(rcube_label('sent')),
+ 'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox")),
+ );
+
+ if (!isset($no_override['junk_mbox']))
+ $blocks['main']['options']['junk_mbox'] = array(
+ 'title' => Q(rcube_label('junk')),
+ 'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox")),
+ );
+
+ if (!isset($no_override['trash_mbox']))
+ $blocks['main']['options']['trash_mbox'] = array(
+ 'title' => Q(rcube_label('trash')),
+ 'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox")),
+ );
+ }
+
+ break;
+
+ // Server settings
+ case 'server':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ 'maintenance' => array('name' => Q(rcube_label('maintenance'))),
+ );
+
+ if (!isset($no_override['read_when_deleted'])) {
+ $field_id = 'rcmfd_read_deleted';
+ $input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['read_when_deleted'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
+ 'content' => $input_readdeleted->show($config['read_when_deleted']?1:0),
+ );
+ }
+
+ if (!isset($no_override['flag_for_deletion'])) {
+ $field_id = 'rcmfd_flag_for_deletion';
+ $input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['flag_for_deletion'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
+ 'content' => $input_flagfordeletion->show($config['flag_for_deletion']?1:0),
+ );
+ }
+
+ // don't show deleted messages
+ if (!isset($no_override['skip_deleted'])) {
+ $field_id = 'rcmfd_skip_deleted';
+ $input_purge = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['skip_deleted'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
+ 'content' => $input_purge->show($config['skip_deleted']?1:0),
+ );
+ }
+
+ if (!isset($no_override['delete_always'])) {
+ $field_id = 'rcmfd_delete_always';
+ $input_delete_always = new html_checkbox(array('name' => '_delete_always', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['delete_always'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('deletealways'))),
+ 'content' => $input_delete_always->show($config['delete_always']?1:0),
+ );
+ }
+
+ if (!isset($no_override['delete_junk'])) {
+ $field_id = 'rcmfd_delete_junk';
+ $input_delete_junk = new html_checkbox(array('name' => '_delete_junk', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['delete_junk'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('deletejunk'))),
+ 'content' => $input_delete_junk->show($config['delete_junk']?1:0),
+ );
+ }
+
+ // Trash purging on logout
+ if (!isset($no_override['logout_purge'])) {
+ $field_id = 'rcmfd_logout_purge';
+ $input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
+
+ $blocks['maintenance']['options']['logout_purge'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
+ 'content' => $input_purge->show($config['logout_purge']?1:0),
+ );
+ }
+
+ // INBOX compacting on logout
+ if (!isset($no_override['logout_expunge'])) {
+ $field_id = 'rcmfd_logout_expunge';
+ $input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
+
+ $blocks['maintenance']['options']['logout_expunge'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
+ 'content' => $input_expunge->show($config['logout_expunge']?1:0),
+ );
+ }
+
+ break;
+ }
+
+ $data = $RCMAIL->plugins->exec_hook('preferences_list', array('section' => $sect['id'], 'blocks' => $blocks));
+ $found = false;
+
+ // create output
+ foreach ($data['blocks'] as $block) {
+ if (!empty($block['content']) || !empty($block['options'])) {
+ $found = true;
+ break;
+ }
+ }
+
+ if (!$found)
+ unset($sections[$idx]);
+ else
+ $sections[$idx]['blocks'] = $data['blocks'];
+ }
+
+ return array($sections, $plugin['cols']);
+}
+
+
+function rcmail_get_skins()
+{
+ $path = 'skins';
+ $skins = array();
+
+ $dir = opendir($path);
+
+ if (!$dir)
+ return false;
+
+ while (($file = readdir($dir)) !== false)
+ {
+ $filename = $path.'/'.$file;
+ if (!preg_match('/^\./', $file) && is_dir($filename) && is_readable($filename))
+ $skins[] = $file;
+ }
+
+ closedir($dir);
- return $skins;
+ return $skins;
}
@@ -1238,9 +977,9 @@ function rcmail_update_folder_row($name, $oldname=null, $subscribe=false, $class
// register UI objects
$OUTPUT->add_handlers(array(
- 'prefsframe' => 'rcmail_preferences_frame',
- 'sectionslist' => 'rcmail_sections_list',
- 'identitieslist' => 'rcmail_identities_list',
+ 'prefsframe' => 'rcmail_preferences_frame',
+ 'sectionslist' => 'rcmail_sections_list',
+ 'identitieslist' => 'rcmail_identities_list',
));
// register action aliases
diff --git a/program/steps/settings/responses.inc b/program/steps/settings/responses.inc
new file mode 100644
index 000000000..cfc4148c3
--- /dev/null
+++ b/program/steps/settings/responses.inc
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/responses.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, 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: |
+ | Manage and save canned response texts |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+if (!empty($_POST['_insert'])) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+ $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
+
+ if (!empty($name) && !empty($text)) {
+ $dupes = 0;
+ $responses = $RCMAIL->get_compose_responses(false, true);
+ foreach ($responses as $resp) {
+ if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
+ $dupes++;
+ }
+ if ($dupes) { // require a unique name
+ $name .= ' (' . ++$dupes . ')';
+ }
+
+ $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16));
+ $responses[] = $response;
+
+ if ($RCMAIL->user->save_prefs(array('compose_responses' => $responses))) {
+ $RCMAIL->output->command('add_response_item', $response);
+ $RCMAIL->output->command('display_message', rcube_label('successfullysaved'), 'confirmation');
+ }
+ else {
+ $RCMAIL->output->command('display_message', rcube_label('errorsaving'), 'error');
+ }
+ }
+
+ // send response
+ $RCMAIL->output->send();
+}
+
+
+if ($RCMAIL->action == 'delete-response') {
+ if ($key = get_input_value('_key', RCUBE_INPUT_GPC)) {
+ $responses = $RCMAIL->get_compose_responses(false, true);
+ foreach ($responses as $i => $response) {
+ if (empty($response['key']))
+ $response['key'] = substr(md5($response['name']), 0, 16);
+ if ($response['key'] == $key) {
+ unset($responses[$i]);
+ $deleted = $RCMAIL->user->save_prefs(array('compose_responses' => $responses));
+ break;
+ }
+ }
+ }
+
+ if ($deleted) {
+ $RCMAIL->output->command('display_message', rcube_label('deletedsuccessfully'), 'confirmation');
+ $RCMAIL->output->command('remove_response', $key);
+ }
+
+ if ($RCMAIL->output->ajax_call) {
+ $RCMAIL->output->send();
+ }
+}
+
+
+$OUTPUT->set_pagetitle(rcube_label('responses'));
+$OUTPUT->include_script('list.js');
+
+
+/**
+ *
+ */
+function rcmail_responses_list($attrib)
+{
+ global $RCMAIL, $OUTPUT;
+
+ $attrib += array('id' => 'rcmresponseslist', 'tagname' => 'table', 'cols' => 1);
+
+ $plugin = $RCMAIL->plugins->exec_hook('responses_list', array(
+ 'list' => $RCMAIL->get_compose_responses(true),
+ 'cols' => array('name')
+ ));
+
+ $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'key');
+
+ // set client env
+ $OUTPUT->add_gui_object('responseslist', $attrib['id']);
+ $OUTPUT->set_env('readonly_responses', array_values(array_map(function($rec){ return $rec['key']; },
+ array_filter($plugin['list'], function($item){ return !empty($item['static']); }))));
+
+ return $out;
+}
+
+
+// similar function as /steps/addressbook/func.inc::rcmail_contact_frame()
+function rcmail_response_frame($attrib)
+{
+ global $OUTPUT;
+
+ if (!$attrib['id']) {
+ $attrib['id'] = 'rcmResponseFrame';
+ }
+
+ $OUTPUT->set_env('contentframe', $attrib['id']);
+ return $OUTPUT->frame($attrib, true);
+}
+
+$OUTPUT->add_handlers(array(
+ 'responseframe' => 'rcmail_response_frame',
+ 'responseslist' => 'rcmail_responses_list',
+));
+$OUTPUT->add_label('deleteresponseconfirm');
+
+$OUTPUT->send('responses');
diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc
index 3e8b1d17e..945005d39 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -34,7 +34,6 @@ switch ($CURR_SECTION)
'time_format' => isset($_POST['_time_format']) ? get_input_value('_time_format', RCUBE_INPUT_POST) : ($CONFIG['time_format'] ? $CONFIG['time_format'] : 'H:i'),
'prettydate' => isset($_POST['_pretty_date']) ? TRUE : FALSE,
'refresh_interval' => isset($_POST['_refresh_interval']) ? intval($_POST['_refresh_interval'])*60 : $CONFIG['refresh_interval'],
- 'standard_windows' => isset($_POST['_standard_windows']) ? TRUE : FALSE,
'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
);
@@ -61,7 +60,6 @@ switch ($CURR_SECTION)
case 'mailview':
$a_user_prefs = array(
'message_extwin' => intval($_POST['_message_extwin']),
- 'message_show_email' => isset($_POST['_message_show_email']) ? TRUE : FALSE,
'prefer_html' => isset($_POST['_prefer_html']) ? TRUE : FALSE,
'inline_images' => isset($_POST['_inline_images']) ? TRUE : FALSE,
'show_images' => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0,
@@ -120,8 +118,6 @@ switch ($CURR_SECTION)
case 'folders':
$a_user_prefs = array(
- 'show_real_foldernames' =>
- isset($_POST['_show_real_foldernames']) ? TRUE : FALSE,
'drafts_mbox' => get_input_value('_drafts_mbox', RCUBE_INPUT_POST, true),
'sent_mbox' => get_input_value('_sent_mbox', RCUBE_INPUT_POST, true),
'junk_mbox' => get_input_value('_junk_mbox', RCUBE_INPUT_POST, true),
diff --git a/program/steps/utils/save_pref.inc b/program/steps/utils/save_pref.inc
index 7def8733d..7c30be71b 100644
--- a/program/steps/utils/save_pref.inc
+++ b/program/steps/utils/save_pref.inc
@@ -5,7 +5,7 @@
| program/steps/utils/save_pref.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2010, The Roundcube Dev Team |
+ | Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -19,16 +19,26 @@
+-----------------------------------------------------------------------+
*/
-$name = get_input_value('_name', RCUBE_INPUT_POST);
-$value = get_input_value('_value', RCUBE_INPUT_POST);
+$name = get_input_value('_name', RCUBE_INPUT_POST);
+$value = get_input_value('_value', RCUBE_INPUT_POST);
+$sessname = get_input_value('_session', RCUBE_INPUT_POST);
+
+// Whitelisted preferences and session variables, others
+// can be added by plugins
$whitelist = array(
'preview_pane',
'list_cols',
'collapsed_folders',
'collapsed_abooks',
);
+$whitelist_sess = array(
+ 'list_attrib/columns',
+);
+
+$whitelist = array_merge($whitelist, $RCMAIL->plugins->allowed_prefs);
+$whitelist_sess = array_merge($whitelist_sess, $RCMAIL->plugins->allowed_session_prefs);
-if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs))) {
+if (!in_array($name, $whitelist) || ($sessname && !in_array($sessname, $whitelist_sess))) {
raise_error(array('code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => sprintf("Hack attempt detected (user: %s)", $RCMAIL->get_user_name())),
@@ -42,7 +52,7 @@ if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs)))
$RCMAIL->user->save_prefs(array($name => $value));
// update also session if requested
-if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) {
+if ($sessname) {
// Support multidimensional arrays...
$vars = explode('/', $sessname);
@@ -57,5 +67,3 @@ if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) {
$OUTPUT->reset();
$OUTPUT->send();
-
-
diff --git a/program/steps/utils/spell.inc b/program/steps/utils/spell.inc
index 1c68e8328..a0dd35d27 100644
--- a/program/steps/utils/spell.inc
+++ b/program/steps/utils/spell.inc
@@ -42,13 +42,6 @@ else {
$result = $spellchecker->get_xml();
}
-if ($err = $spellchecker->error()) {
- rcube::raise_error(array('code' => 500, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Spell check engine error: " . trim($err)),
- true, false);
-}
-
// set response length
header("Content-Length: " . strlen($result));
diff --git a/program/steps/utils/spell_html.inc b/program/steps/utils/spell_html.inc
index 96b41e230..861e4ba48 100644
--- a/program/steps/utils/spell_html.inc
+++ b/program/steps/utils/spell_html.inc
@@ -46,11 +46,6 @@ else if ($request['method'] == 'learnWord') {
}
if ($error = $spellchecker->error()) {
- rcube::raise_error(array('code' => 500, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => sprintf("Spell check engine error: " . $error)),
- true, false);
-
echo '{"error":{"errstr":"' . addslashes($error) . '","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}';
exit;
}
diff --git a/skins/classic/addressbook.css b/skins/classic/addressbook.css
index 9575ae25f..10690f9ba 100644
--- a/skins/classic/addressbook.css
+++ b/skins/classic/addressbook.css
@@ -23,7 +23,7 @@
padding: 0;
margin: 0 5px;
overflow: hidden;
- background: url(images/abook_toolbar.png) 0 0 no-repeat transparent;
+ background: url(images/abook_toolbar.png?v=025d.15594) 0 0 no-repeat transparent;
opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
}
@@ -67,14 +67,6 @@
background-position: -128px -32px;
}
-#abooktoolbar a.exportAll {
- background-position: -128px 0;
-}
-
-#abooktoolbar a.exportAllSel {
- background-position: -128px -32px;
-}
-
#abooktoolbar span.separator {
width: 5px;
background-position: -162px 0;
@@ -118,7 +110,7 @@
#directorylistbox input
{
- margin: 0 0 0 20px;
+ margin: 0px;
font-size: 11px;
width: 90%;
}
@@ -144,8 +136,7 @@
width: 280px;
}
-#directorylist,
-#directorylist li ul
+#directorylist
{
list-style: none;
margin: 0;
@@ -153,15 +144,11 @@
background-color: #FFFFFF;
}
-#directorylist li ul
-{
- border-top: 1px solid #EBEBEB;
-}
-
#directorylist li
{
display: block;
font-size: 11px;
+ background: url(images/icons/folders.png?v=87af.4822) 5px -108px no-repeat;
border-bottom: 1px solid #EBEBEB;
white-space: nowrap;
}
@@ -173,37 +160,31 @@
padding-left: 25px;
padding-top: 2px;
padding-bottom: 2px;
- height: 16px;
text-decoration: none;
white-space: nowrap;
- background: url(images/icons/folders.png) 5px -108px no-repeat;
}
-#directorylist li ul li a
+#directorylist li.contactgroup
{
- padding-left: 45px;
+ padding-left: 15px;
+ background-position: 20px -143px;
}
-#directorylist li ul li:last-child
+#directorylist li.contactsearch
{
- border-bottom: 0;
-}
-
-#directorylist li.contactgroup a
-{
- background-position: 22px -143px;
+ background-position: 6px -162px;
}
-#directorylist li.contactsearch a
+#directorylist li.selected
{
- background-position: 6px -162px;
+ background-color: #929292;
+ border-bottom: 1px solid #898989;
}
-#directorylist li.selected > a
+#directorylist li.selected a
{
color: #FFF;
font-weight: bold;
- background-color: #929292;
}
#directorylist li.droptarget
@@ -224,37 +205,6 @@
-o-text-overflow: ellipsis;
}
-#contacts-table .contact.readonly td
-{
- font-style: italic;
-}
-
-#contacts-table td.name
-{
- width: 95%;
-}
-
-#contacts-table td.action
-{
- width: 12px;
- padding: 0px 6px 0 4px;
- text-align: right;
-}
-
-#contacts-table td.action a
-{
- font-size: 16px;
- font-weight: bold;
- font-style: normal;
- text-decoration: none;
- color: #333;
-}
-
-#contacts-table .selected td.action a
-{
- color: #fff;
-}
-
#contacts-box
{
position: absolute;
@@ -357,8 +307,7 @@ body.iframe,
}
#contactpic img {
- max-width: 60px;
- max-height: 80px;
+ width: 60px;
}
#contactpic.droptarget.hover {
diff --git a/skins/classic/common.css b/skins/classic/common.css
index 3c322f0ed..c76786747 100644
--- a/skins/classic/common.css
+++ b/skins/classic/common.css
@@ -20,7 +20,7 @@ body.extwin
margin: 10px;
}
-select, input, textarea
+td, th, div, p, select, input, textarea
{
font-size: 12px;
font-family: inherit;
@@ -93,7 +93,7 @@ input.button
font-size: 12px;
padding-left: 8px;
padding-right: 8px;
- background: url(images/buttons/bg.gif) repeat-x #f0f0f0;
+ background: url(images/buttons/bg.gif?v=30b2.196) repeat-x #f0f0f0;
border: 1px solid #a4a4a4;
}
@@ -182,7 +182,7 @@ body > #logo
right: 0px;
height: 24px;
left: 250px;
- background: url(images/taskbar.png) top right no-repeat;
+ background: url(images/taskbar.png?v=3878.1902) top right no-repeat;
padding: 10px 6px 5px 0px;
text-align: right;
white-space: nowrap;
@@ -195,7 +195,7 @@ body > #logo
color: #666666;
text-decoration: none;
padding: 6px 12px 6px 26px;
- background: url(images/taskicons.gif) no-repeat;
+ background: url(images/taskicons.gif?v=b8e0.1519) no-repeat;
}
#taskbar a:hover
@@ -246,7 +246,7 @@ body > #message div.notice,
body > #messagebody .part-notice,
#message-objects div.notice
{
- background: url(images/display/icons.png) 6px 3px no-repeat;
+ background: url(images/display/icons.png?v=e866.4201) 6px 3px no-repeat;
background-color: #F7FDCB;
border: 1px solid #C2D071;
}
@@ -256,7 +256,7 @@ body > #message div.warning,
#message-objects div.warning,
#message-objects div.error
{
- background: url(images/display/icons.png) 6px -97px no-repeat;
+ background: url(images/display/icons.png?v=e866.4201) 6px -97px no-repeat;
background-color: #EF9398;
border: 1px solid #DC5757;
}
@@ -264,7 +264,7 @@ body > #message div.warning,
body > #message div.confirmation,
#message-objects div.confirmation
{
- background: url(images/display/icons.png) 6px -47px no-repeat;
+ background: url(images/display/icons.png?v=e866.4201) 6px -47px no-repeat;
background-color: #A6EF7B;
border: 1px solid #76C83F;
}
@@ -272,7 +272,7 @@ body > #message div.confirmation,
body > #message div.loading,
#message-objects div.loading
{
- background: url(images/display/loading.gif) 6px 3px no-repeat;
+ background: url(images/display/loading.gif?v=9bae.2710) 6px 3px no-repeat;
background-color: #EBEBEB;
border: 1px solid #CCCCCC;
}
@@ -283,15 +283,6 @@ body > #message a
text-decoration: underline;
}
-body.extwin #closelink
-{
- position: absolute;
- top: 5px;
- right: 20px;
- text-align: right;
- z-index:100;
-}
-
.box
{
border: 1px solid #999;
@@ -309,7 +300,7 @@ body.extwin #closelink
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
white-space: nowrap;
- background: url(images/listheader.gif) top left repeat-x #CCC;
+ background: url(images/listheader.gif?v=ab42.314) top left repeat-x #CCC;
}
.boxtitle .rightalign
@@ -358,7 +349,7 @@ body.iframe .boxtitle
overflow: hidden;
height: 22px;
border-bottom: 1px solid #999;
- background: url(images/listheader.gif) top left repeat-x #CCC;
+ background: url(images/listheader.gif?v=ab42.314) top left repeat-x #CCC;
}
.boxfooter
@@ -370,7 +361,7 @@ body.iframe .boxtitle
overflow: hidden;
height: 22px;
border-top: 1px solid #999;
- background: url(images/listheader.gif) top left repeat-x #CCC;
+ background: url(images/listheader.gif?v=ab42.314) top left repeat-x #CCC;
}
.boxfooter a.button,
@@ -383,7 +374,7 @@ body.iframe .boxtitle
padding: 0px;
margin: 0;
overflow: hidden;
- background: url(images/icons/groupactions.png) 0 0 no-repeat transparent;
+ background: url(images/icons/groupactions.png?v=ace6.1092) 0 0 no-repeat transparent;
opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
}
@@ -420,7 +411,7 @@ body.iframe .boxtitle
margin: 1px;
margin-top: 2px;
overflow: hidden;
- background: url(images/pagenav.gif) 0 0 no-repeat transparent;
+ background: url(images/pagenav.gif?v=2e75.355) 0 0 no-repeat transparent;
opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
}
@@ -462,7 +453,7 @@ body.iframe .boxtitle
-moz-user-select: none;
-khtml-user-select: none;
position: absolute;
- background: url(images/dimple.png) center no-repeat;
+ background: url(images/dimple.png?v=42a0.158) center no-repeat;
}
.splitter-h
@@ -542,7 +533,7 @@ body.iframe .boxtitle
.popupmenu.selectable li a.selected
{
- background: url(images/messageicons.png) 2px -372px no-repeat;
+ background: url(images/messageicons.png?v=9df0.3673) 2px -372px no-repeat;
}
.popupmenu.selectable li a
@@ -564,13 +555,13 @@ body.iframe .boxtitle
.dropbutton:hover
{
-/* background: url(images/dbutton.png) 0 0 no-repeat transparent; */
+/* background: url(images/dbutton.png?v=7bba.240) 0 0 no-repeat transparent; */
}
.dropbutton span
{
width: 9px;
- background: url(images/dbutton.png) -53px 0 no-repeat transparent;
+ background: url(images/dbutton.png?v=7bba.240) -53px 0 no-repeat transparent;
}
.dropbutton span:hover
@@ -594,7 +585,7 @@ table.records-table thead tr td
vertical-align: middle;
border-bottom: 1px solid #999999;
color: #333333;
- background: url(images/listheader.gif) top left repeat-x #CCC;
+ background: url(images/listheader.gif?v=ab42.314) top left repeat-x #CCC;
font-size: 11px;
font-weight: bold;
}
@@ -631,32 +622,6 @@ table.records-table tr.unfocused td
background-color: #929292;
}
-ul.treelist li
-{
- position: relative;
-}
-
-ul.treelist li div.treetoggle
-{
- position: absolute;
- left: 8px !important;
- left: -16px;
- top: 1px;
- width: 14px;
- height: 16px;
- cursor: pointer;
-}
-
-ul.treelist li div.collapsed
-{
- background: url(images/icons/collapsed.png) bottom right no-repeat;
-}
-
-ul.treelist li div.expanded
-{
- background: url(images/icons/expanded.png) bottom right no-repeat;
-}
-
/***** mac-style quicksearch field *****/
@@ -668,7 +633,7 @@ ul.treelist li div.expanded
width: 190px;
height: 20px;
text-align: right;
- background: url(images/searchfield.gif) top left no-repeat;
+ background: url(images/searchfield.gif?v=aaf8.313) top left no-repeat;
}
#searchreset
@@ -701,7 +666,6 @@ ul.treelist li div.expanded
font-size: 11px;
padding: 0px;
border: none;
- outline: none;
}
/***** roundcube webmail pre-defined classes *****/
@@ -746,7 +710,7 @@ ul.treelist li div.expanded
content: " ";
width: 14px;
height: 14px;
- background: url(images/messageactions.png) -2px -128px no-repeat;
+ background: url(images/messageactions.png?v=e5b9.2211) -2px -128px no-repeat;
}
a.rcmContactAddress
@@ -796,7 +760,7 @@ a.rcmContactAddress:hover
margin-left: auto;
margin-right: auto;
margin-top: 50px;
- width: 400px;
+ width: 420px;
border: 1px solid #999;
}
@@ -963,7 +927,7 @@ span.tablink-selected
height: 23px !important;
height: 22px;
overflow: hidden;
- background: url(images/tabs-left.gif) top left no-repeat;
+ background: url(images/tabs-left.gif?v=0541.219) top left no-repeat;
}
span.tablink
@@ -990,7 +954,7 @@ span.tablink-selected a
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
- background: url(images/tabs-right.gif) top right no-repeat;
+ background: url(images/tabs-right.gif?v=5414.733) top right no-repeat;
}
span.tablink-selected a
@@ -1026,9 +990,9 @@ fieldset.tabbed
cursor: default;
}
.quota_bg { background-color: white; }
-.quota_high { background: url(images/quota-colors.png) repeat-x 0 -28px #f90509; }
-.quota_mid { background: url(images/quota-colors.png) repeat-x 0 -14px #e3e909; }
-.quota_low { background: url(images/quota-colors.png) repeat-x 0 0px #05f905; }
+.quota_high { background: url(images/quota-colors.png?v=c1e9.287) repeat-x 0 -28px #f90509; }
+.quota_mid { background: url(images/quota-colors.png?v=c1e9.287) repeat-x 0 -14px #e3e909; }
+.quota_low { background: url(images/quota-colors.png?v=c1e9.287) repeat-x 0 0px #05f905; }
.quota_text_high { color: white; }
.quota_text_mid { color: #666; }
.quota_text_low { color: #666; }
diff --git a/skins/classic/embed.css b/skins/classic/embed.css
index 6d2c63c6a..fbfa09501 100644
--- a/skins/classic/embed.css
+++ b/skins/classic/embed.css
@@ -16,7 +16,7 @@
margin-bottom: .8em;
min-height: 30px;
padding: 10px 10px 6px 46px;
- background: url(images/display/icons.png) 6px 3px no-repeat #F7FDCB;
+ background: url(images/display/icons.png?v=e866.4201) 6px 3px no-repeat #F7FDCB;
border: 1px solid #C2D071;
}
diff --git a/skins/classic/functions.js b/skins/classic/functions.js
index af561c37b..23c69805c 100644
--- a/skins/classic/functions.js
+++ b/skins/classic/functions.js
@@ -92,9 +92,8 @@ function rcube_mail_ui()
forwardmenu: {id:'forwardmenu', editable:1},
searchmenu: {id:'searchmenu', editable:1},
messagemenu: {id:'messagemenu'},
- attachmentmenu: {id:'attachmentmenu'},
listmenu: {id:'listmenu', editable:1},
- dragmenu: {id:'dragmenu', sticky:1},
+ dragmessagemenu:{id:'dragmessagemenu', sticky:1},
groupmenu: {id:'groupoptionsmenu', above:1},
mailboxmenu: {id:'mailboxoptionsmenu', above:1},
composemenu: {id:'composeoptionsmenu', editable:1, overlap:1},
@@ -134,24 +133,24 @@ show_popupmenu: function(popup, show)
{
var obj = this.popups[popup].obj,
above = this.popups[popup].above,
- ref = $(this.popups[popup].link ? this.popups[popup].link : rcube_find_object(popup+'link'));
+ ref = rcube_find_object(popup+'link');
if (typeof show == 'undefined')
show = obj.is(':visible') ? false : true;
else if (this.popups[popup].toggle && show && this.popups[popup].obj.is(':visible') )
show = false;
- if (show && ref.length) {
- var parent = ref.parent(),
+ if (show && ref) {
+ var parent = $(ref).parent(),
win = $(window),
- pos = parent.hasClass('dropbutton') ? parent.offset() : ref.offset();
+ pos = parent.hasClass('dropbutton') ? parent.offset() : $(ref).offset();
- if (!above && pos.top + ref.height() + obj.height() > win.height())
+ if (!above && pos.top + ref.offsetHeight + obj.height() > win.height())
above = true;
if (pos.left + obj.width() > win.width())
pos.left = win.width() - obj.width() - 30;
- obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.height())) });
+ obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.offsetHeight)) });
}
obj[show?'show':'hide']();
@@ -162,9 +161,9 @@ show_popupmenu: function(popup, show)
}
},
-dragmenu: function(show)
+dragmessagemenu: function(show)
{
- this.popups.dragmenu.obj[show?'show':'hide']();
+ this.popups.dragmessagemenu.obj[show?'show':'hide']();
},
forwardmenu: function(show)
@@ -326,7 +325,7 @@ listmenu: function(show)
};
},
-open_listmenu: function()
+open_listmenu: function(e)
{
this.listmenu();
},
@@ -381,35 +380,6 @@ spellmenu: function(show)
this.show_popupmenu('spellmenu', show);
},
-show_attachmentmenu: function(elem)
-{
- var id = elem.parentNode.id.replace(/^attach/, '');
-
- $('#attachmenuopen').unbind('click').attr('onclick', '').click(function(e) {
- return rcmail.command('open-attachment', id, this);
- });
-
- $('#attachmenudownload').unbind('click').attr('onclick', '').click(function() {
- rcmail.command('download-attachment', id, this);
- });
-
- this.popups.attachmentmenu.link = elem;
- rcmail.command('menu-open', {menu: 'attachmentmenu', id: id});
-},
-
-menu_open: function(p)
-{
- if (p && p.props && p.props.menu == 'attachmentmenu')
- this.show_popup('attachmentmenu');
- else
- this.open_listmenu();
-},
-
-menu_save: function(prop)
-{
- this.save_listmenu();
-},
-
body_mouseup: function(evt, p)
{
var i, target = rcube_event.get_target(evt);
@@ -492,18 +462,14 @@ switch_preview_pane: function(elem)
/* Message composing */
init_compose_form: function()
{
- var f, v, field, fields = ['cc', 'bcc', 'replyto', 'followupto'],
+ var f, field, fields = ['cc', 'bcc', 'replyto', 'followupto'],
div = document.getElementById('compose-div'),
headers_div = document.getElementById('compose-headers-div');
// Show input elements with non-empty value
for (f=0; f<fields.length; f++) {
- v = fields[f]; field = $('#_'+v);
- if (field.length) {
- field.on('change', {v:v}, function(e) { if (this.value) rcmail_ui.show_header_form(e.data.v); });
- if (field.val() != '')
- rcmail_ui.show_header_form(v);
- }
+ if ((field = $('#_'+fields[f])) && field.length && field.val() != '')
+ rcmail_ui.show_header_form(fields[f]);
}
// prevent from form data loss when pressing ESC key in IE
@@ -621,130 +587,14 @@ prev_sibling: function(elm)
while (ps && ps.nodeType == 3)
ps = ps.previousSibling;
return ps;
-},
-
-enable_command: function(p)
-{
- if (p.command == 'reply-list') {
- var label = rcmail.gettext(p.status ? 'replylist' : 'replyall');
- $('a.button.replyAll').attr('title', label);
- }
}
};
/**
- * Roundcube generic layer (floating box) class
- *
- * @constructor
- */
-function rcube_layer(id, attributes)
-{
- this.name = id;
-
- // create a new layer in the current document
- this.create = function(arg)
- {
- var l = (arg.x) ? arg.x : 0,
- t = (arg.y) ? arg.y : 0,
- w = arg.width,
- h = arg.height,
- z = arg.zindex,
- vis = arg.vis,
- parent = arg.parent,
- obj = document.createElement('DIV');
-
- obj.id = this.name;
- obj.style.position = 'absolute';
- obj.style.visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
- obj.style.left = l+'px';
- obj.style.top = t+'px';
- if (w)
- obj.style.width = w.toString().match(/\%$/) ? w : w+'px';
- if (h)
- obj.style.height = h.toString().match(/\%$/) ? h : h+'px';
- if (z)
- obj.style.zIndex = z;
-
- if (parent)
- parent.appendChild(obj);
- else
- document.body.appendChild(obj);
-
- this.elm = obj;
- };
-
- // create new layer
- if (attributes != null) {
- this.create(attributes);
- this.name = this.elm.id;
- }
- else // just refer to the object
- this.elm = document.getElementById(id);
-
- if (!this.elm)
- return false;
-
-
- // ********* layer object properties *********
-
- this.css = this.elm.style;
- this.event = this.elm;
- this.width = this.elm.offsetWidth;
- this.height = this.elm.offsetHeight;
- this.x = parseInt(this.elm.offsetLeft);
- this.y = parseInt(this.elm.offsetTop);
- this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false;
-
-
- // ********* layer object methods *********
-
- // move the layer to a specific position
- this.move = function(x, y)
- {
- this.x = x;
- this.y = y;
- this.css.left = Math.round(this.x)+'px';
- this.css.top = Math.round(this.y)+'px';
- };
-
- // change the layers width and height
- this.resize = function(w,h)
- {
- this.css.width = w+'px';
- this.css.height = h+'px';
- this.width = w;
- this.height = h;
- };
-
- // show or hide the layer
- this.show = function(a)
- {
- if(a == 1) {
- this.css.visibility = 'visible';
- this.visible = true;
- }
- else if(a == 2) {
- this.css.visibility = 'inherit';
- this.visible = true;
- }
- else {
- this.css.visibility = 'hidden';
- this.visible = false;
- }
- };
-
- // write new content into a Layer
- this.write = function(cont)
- {
- this.elm.innerHTML = cont;
- };
-
-};
-
-/**
* Scroller
*/
+
function rcmail_scroller(list, top, bottom)
{
var ref = this;
@@ -796,25 +646,24 @@ function iframe_events()
// Abbreviate mailbox names to fit width of the container
function rcube_render_mailboxlist()
{
- var list = $('#mailboxlist > li > a, #mailboxlist ul:visible > li > a');
+ var list = $('#mailboxlist > li a, #mailboxlist ul:visible > li a');
// it's too slow with really big number of folders, especially on IE
- if (list.length > (bw.ie && bw.vendver < 9 ? 40 : 100))
+ if (list.length > (bw.ie ? 25 : 100))
return;
- list.each(function() {
+ list.each(function(){
var elem = $(this),
text = elem.data('text');
if (!text) {
- text = elem.text().replace(/\s+\([0-9]+\)$/, '');
+ text = elem.text().replace(/\s+\(.+$/, '');
elem.data('text', text);
}
-
if (text.length < 6)
return;
- var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width() - 16);
+ var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width());
if (abbrev != text)
elem.attr('title', text);
elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev;
@@ -824,23 +673,19 @@ function rcube_render_mailboxlist()
// inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5
function fit_string_to_size(str, elem, len)
{
- var w, span, $span, result = str, ellip = '...';
+ var w, span, result = str, ellip = '...';
if (!rcmail.env.tmp_span) {
// it should be appended to elem to use the same css style
// but for performance reasons we'll append it to body (once)
- span = $('<b>').css({visibility: 'hidden', padding: '0px',
- 'font-family': elem.css('font-family'),
- 'font-size': elem.css('font-size')})
+ span = $('<b>').css({visibility: 'hidden', padding: '0px'})
.appendTo($('body', document)).get(0);
rcmail.env.tmp_span = span;
}
else {
span = rcmail.env.tmp_span;
}
-
- $span = $(span);
- $span.text(result);
+ span.innerHTML = result;
// on first run, check if string fits into the length already.
w = span.offsetWidth;
@@ -853,7 +698,7 @@ function fit_string_to_size(str, elem, len)
while (true) {
offLeft = mid - cut;
offRight = mid + cut;
- $span.text(str.substring(0,offLeft) + ellip + str.substring(offRight));
+ span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight);
// break loop if string fits size
if (offLeft < 3 || span.offsetWidth)
@@ -917,7 +762,7 @@ function percent_indicator(obj, data)
var bar2 = $('<div>');
bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
width: width + 'px', height: height + 'px', zIndex: 98})
- .addClass('quota_bg');
+ .addClass('quota_bg');
if (quota >= limit_high) {
main.addClass(' quota_text_high');
@@ -940,8 +785,8 @@ function percent_indicator(obj, data)
// Optional parameters used by TinyMCE
var rcmail_editor_settings = {
- skin: "default", // "default", "o2k7"
- skin_variant: "" // "", "silver", "black"
+ skin : "default", // "default", "o2k7"
+ skin_variant : "" // "", "silver", "black"
};
var rcmail_ui;
@@ -952,52 +797,40 @@ function rcube_init_mail_ui()
rcube_event.add_listener({ object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
rcube_event.add_listener({ object:rcmail_ui, method:'body_keydown', event:'keydown' });
- rcmail.addEventListener('init', function() {
- if (rcmail.env.quota_content)
- update_quota(rcmail.env.quota_content);
- rcmail.addEventListener('setquota', update_quota);
-
- $('iframe').load(iframe_events)
- .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
-
- if (rcmail.env.task == 'mail') {
- rcmail.addEventListener('enable-command', 'enable_command', rcmail_ui);
- rcmail.addEventListener('menu-open', 'menu_open', rcmail_ui);
- rcmail.addEventListener('menu-save', 'menu_save', rcmail_ui);
- rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);
- rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);
- rcmail.gui_object('dragmenu', 'dragmenu');
-
- if (rcmail.gui_objects.mailboxlist) {
- rcmail.treelist.addEventListener('expand', rcube_render_mailboxlist);
- rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist);
- rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist);
- rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist);
- rcmail.addEventListener('responseafterrefresh', rcube_render_mailboxlist);
- rcmail.addEventListener('afterimport-messages', function(){ rcmail_ui.show_popup('uploadform', false); });
-
- new rcmail_scroller('#mailboxlist-content', '#mailboxlist-title', '#mailboxlist-footer');
- }
+ if (rcmail.env.quota_content)
+ update_quota(rcmail.env.quota_content);
+ rcmail.addEventListener('setquota', update_quota);
- if (rcmail.env.action == 'compose')
- rcmail_ui.init_compose_form();
- else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
- // add menu link for each attachment
- $('#attachment-list > li[id^="attach"]').each(function() {
- $(this).append($('<a class="drop">').click(function() { rcmail_ui.show_attachmentmenu(this); }));
- });
- }
- else if (rcmail.env.task == 'addressbook') {
- rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); });
+ $('iframe').load(iframe_events)
+ .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
- if (rcmail.gui_objects.folderlist)
- new rcmail_scroller('#directorylist-content', '#directorylist-title', '#directorylist-footer');
+ if (rcmail.env.task == 'mail') {
+ rcmail.addEventListener('menu-open', 'open_listmenu', rcmail_ui);
+ rcmail.addEventListener('menu-save', 'save_listmenu', rcmail_ui);
+ rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);
+ rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);
+ rcmail.gui_object('message_dragmenu', 'dragmessagemenu');
- rcmail.gui_object('dragmenu', 'dragmenu');
- }
- else if (rcmail.env.task == 'settings') {
- if (rcmail.gui_objects.subscriptionlist)
- new rcmail_scroller('#folderlist-content', '#folderlist-title', '#folderlist-footer');
+ if (rcmail.gui_objects.mailboxlist) {
+ rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist);
+ rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist);
+ rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist);
+ rcmail.addEventListener('aftercollapse-folder', rcube_render_mailboxlist);
+
+ new rcmail_scroller('#mailboxlist-content', '#mailboxlist-title', '#mailboxlist-footer');
}
- });
+
+ if (rcmail.env.action == 'compose')
+ rcmail_ui.init_compose_form();
+ }
+ else if (rcmail.env.task == 'addressbook') {
+ rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); });
+
+ if (rcmail.gui_objects.folderlist)
+ new rcmail_scroller('#directorylist-content', '#directorylist-title', '#directorylist-footer');
+ }
+ else if (rcmail.env.task == 'settings') {
+ if (rcmail.gui_objects.subscriptionlist)
+ new rcmail_scroller('#folderlist-content', '#folderlist-title', '#folderlist-footer');
+ }
}
diff --git a/skins/classic/ie6hacks.css b/skins/classic/ie6hacks.css
index a431ee45e..0026d426a 100644
--- a/skins/classic/ie6hacks.css
+++ b/skins/classic/ie6hacks.css
@@ -2,7 +2,7 @@
#taskbar
{
- background: url(images/taskbar.gif) top right no-repeat;
+ background: url(images/taskbar.gif?v=5666.2033) top right no-repeat;
width: expression((parseInt(document.documentElement.clientWidth)-250)+'px');
}
@@ -26,17 +26,17 @@ body > #message div.confirmation,
#message-objects div.warning,
#message-objects div.confirmation
{
- background-image: url(images/display/icons.gif);
+ background-image: url(images/display/icons.gif?v=84d5.2329);
}
#messagemenu li a
{
- background-image: url(images/messageactions.gif);
+ background-image: url(images/messageactions.gif?v=dcdc.1916);
}
#mailboxlist li
{
- background-image: url(images/icons/folders.gif);
+ background-image: url(images/icons/folders.gif?v=59af.2568);
}
#messagetoolbar a
@@ -49,7 +49,7 @@ body > #message div.confirmation,
.boxfooter a.button,
.boxfooter a.buttonPas
{
- background-image: url(images/icons/groupactions.gif);
+ background-image: url(images/icons/groupactions.gif?v=677d.496);
}
.pagenav
@@ -60,23 +60,23 @@ body > #message div.confirmation,
.pagenav a.button,
.pagenav a.buttonPas
{
- background-image: url(images/pagenav.gif);
+ background-image: url(images/pagenav.gif?v=2e75.355);
}
#listcontrols a.button,
#listcontrols a.buttonPas {
- background-image: url(images/mail_footer.gif);
+ background-image: url(images/mail_footer.gif?v=83fb.1336);
}
#messagetoolbar a.button,
#messagetoolbar a.buttonPas {
- background-image: url(images/mail_toolbar.gif);
+ background-image: url(images/mail_toolbar.gif?v=183d.12821);
}
#abooktoolbar a.button,
#abooktoolbar a.buttonPas,
#abooktoolbar span.separator {
- background-image: url(images/abook_toolbar.gif);
+ background-image: url(images/abook_toolbar.gif?v=dfe4.5753);
}
ul.toolbarmenu li a,
@@ -106,7 +106,7 @@ ul.toolbarmenu li.separator_below
#directorylist li
{
- background-image: url(images/icons/folders.gif);
+ background-image: url(images/icons/folders.gif?v=59af.2568);
}
.boxlistcontent
@@ -155,7 +155,7 @@ ul.toolbarmenu li.separator_below
#messagelist tr td.subject span.forwarded,
#messagelist tr td.subject span.unreadchildren
{
- background-image: url(images/messageicons.gif);
+ background-image: url(images/messageicons.gif?v=2f0b.2222);
}
#messagelist tr td div.collapsed,
@@ -180,5 +180,5 @@ body.iframe .boxtitle
#abookactions a
{
- background-image: url("images/icons/groupactions.gif");
+ background-image: url(images/icons/groupactions.gif?v=677d.496);
}
diff --git a/skins/classic/iehacks.css b/skins/classic/iehacks.css
index fabf73db6..fc00732fa 100644
--- a/skins/classic/iehacks.css
+++ b/skins/classic/iehacks.css
@@ -90,13 +90,13 @@ body.iframe div.messageheaderbox
#abooktoolbar a.buttonPas
{
filter: alpha(opacity=35);
- background-image: url(images/abook_toolbar.gif);
+ background-image: url(images/abook_toolbar.gif?v=dfe4.5753);
}
#messagetoolbar a.buttonPas
{
filter: alpha(opacity=35);
- background-image: url(images/mail_toolbar.gif);
+ background-image: url(images/mail_toolbar.gif?v=183d.12821);
}
#listcontrols a.buttonPas
@@ -219,7 +219,7 @@ div.message-part div.pre
div.draglayercopy
{
border-color: #00cc00;
- background: url(images/messageactions.png) 0 -125px no-repeat #fff;
+ background: url(images/messageactions.png?v=e5b9.2211) 0 -125px no-repeat #fff;
}
html.ie8 .draglayercopy:before
diff --git a/skins/classic/images/favicon.ico b/skins/classic/images/favicon.ico
index 9ef2f3b9e..b3bd18c12 100644
--- a/skins/classic/images/favicon.ico
+++ b/skins/classic/images/favicon.ico
Binary files differ
diff --git a/skins/classic/images/mail_toolbar.png b/skins/classic/images/mail_toolbar.png
index 4a8431715..e68035da5 100644
--- a/skins/classic/images/mail_toolbar.png
+++ b/skins/classic/images/mail_toolbar.png
Binary files differ
diff --git a/skins/classic/includes/messagetoolbar.html b/skins/classic/includes/messagetoolbar.html
index 8f8efd291..bd14f490f 100644
--- a/skins/classic/includes/messagetoolbar.html
+++ b/skins/classic/includes/messagetoolbar.html
@@ -21,7 +21,7 @@
<roundcube:button name="markmenulink" id="markmenulink" type="link" class="button markmessage" title="markmessages" onclick="rcmail_ui.show_popup('markmenu');return false" content=" " />
<roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button messagemenu" title="moreactions" onclick="rcmail_ui.show_popup('messagemenu');return false" content=" " />
<roundcube:if condition="template:name == 'message'" />
-<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('move', this.options[this.selectedIndex].value)" class="mboxlist" folder_filter="mail" />
+<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mboxlist" folder_filter="mail" />
<roundcube:endif />
</div>
diff --git a/skins/classic/mail.css b/skins/classic/mail.css
index b8cc9f351..89cf0b884 100644
--- a/skins/classic/mail.css
+++ b/skins/classic/mail.css
@@ -36,7 +36,7 @@
padding: 0;
margin: 0 5px;
overflow: hidden;
- background: url(images/mail_toolbar.png) 0 0 no-repeat transparent;
+ background: url(images/mail_toolbar.png?v=1594.36649) 0 0 no-repeat transparent;
opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
}
@@ -107,14 +107,6 @@
background-position: -192px -32px;
}
-#messagetoolbar a.print {
- background-position: -224px 0;
-}
-
-#messagetoolbar a.printSel {
- background-position: -224px -32px;
-}
-
#messagetoolbar a.markmessage {
background-position: -256px 0;
}
@@ -163,14 +155,6 @@
background-position: -416px -32px;
}
-#messagetoolbar a.download {
- background-position: -480px 0;
-}
-
-#messagetoolbar a.downloadSel {
- background-position: -480px -32px;
-}
-
#messagetoolbar select.mboxlist
{
position: relative;
@@ -189,17 +173,15 @@
}
#messagemenu li a.active:hover,
-#attachmentmenu li a.active:hover,
#markmessagemenu li a.active:hover
{
color: #fff;
background-color: #c00;
}
-#messagemenu li a,
-#attachmentmenu li a
+#messagemenu li a
{
- background: url(images/messageactions.png) no-repeat 7px 0;
+ background: url(images/messageactions.png?v=e5b9.2211) no-repeat 7px 0;
background-position: 7px 20px;
}
@@ -208,8 +190,7 @@
background-position: 7px 1px;
}
-#messagemenu li a.downloadlink,
-#attachmentmenu li a.downloadlink
+#messagemenu li a.downloadlink
{
background-position: 7px -17px;
}
@@ -219,8 +200,7 @@
background-position: 7px -35px;
}
-#messagemenu li a.openlink,
-#attachmentmenu li a.openlink
+#messagemenu li a.openlink
{
background-position: 7px -53px;
}
@@ -233,7 +213,7 @@
#markmessagemenu li a,
#compose-attachments li a
{
- background: url(images/messageicons.png) no-repeat;
+ background: url(images/messageicons.png?v=9df0.3673) no-repeat;
}
#markmessagemenu li a.readlink
@@ -300,38 +280,10 @@
#messagepartcontainer
{
position: absolute;
- top: 0;
- left: 170px;
- right: 0;
- bottom: 0;
-}
-
-#messagepartheader
-{
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- width: 160px;
- border: 1px solid #999999;
- background-color: #F9F9F9;
- overflow: hidden;
-}
-
-#messagepartheader table
-{
- width: 100%;
- table-layout: fixed;
-}
-
-#messagepartheader table td
-{
- text-overflow: ellipsis;
-}
-
-#messagepartheader table td.title
-{
- width: 60px;
+ top: 80px;
+ left: 20px;
+ right: 20px;
+ bottom: 20px;
}
#mailcontframe
@@ -373,7 +325,31 @@
height: 100%;
min-height: 100%; /* Chrome 14 bug */
border: 1px solid #999999;
- background-color: #fff;
+ background-color: #F9F9F9;
+}
+
+
+#partheader
+{
+ position: absolute;
+ top: 10px;
+ left: 220px;
+ right: 20px;
+ height: 40px;
+}
+
+#partheader table td
+{
+ padding-left: 2px;
+ padding-right: 4px;
+ vertical-align: middle;
+ font-size: 11px;
+}
+
+#partheader table td.title
+{
+ color: #666666;
+ font-weight: bold;
}
@@ -408,7 +384,7 @@
display: block;
position: relative;
font-size: 11px;
- background: url(images/icons/folders.png) 5px 0 no-repeat;
+ background: url(images/icons/folders.png?v=87af.4822) 5px 0 no-repeat;
border-bottom: 1px solid #EBEBEB;
}
@@ -417,6 +393,32 @@
border-bottom: none;
}
+#mailboxlist li div
+{
+ position: absolute;
+ left: 8px !important;
+ left: -16px;
+ top: 1px;
+ width: 14px;
+ height: 16px;
+}
+
+#mailboxlist li div.collapsed,
+#mailboxlist li div.expanded
+{
+ cursor: pointer;
+}
+
+#mailboxlist li div.collapsed
+{
+ background: url(images/icons/collapsed.png?v=45aa.97) bottom right no-repeat;
+}
+
+#mailboxlist li div.expanded
+{
+ background: url(images/icons/expanded.png?v=f647.107) bottom right no-repeat;
+}
+
#mailboxlist li.inbox
{
background-position: 5px -18px;
@@ -534,7 +536,7 @@
margin-top: 4px;
margin-right: 2px;
overflow: hidden;
- background: url(images/mail_footer.png) 0 0 no-repeat transparent;
+ background: url(images/mail_footer.png?v=819f.977) 0 0 no-repeat transparent;
opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
}
@@ -631,50 +633,42 @@ body.messagelist
background-color: #F9F9F9;
}
-table.messagelist
+#messagelist
{
width: 100%;
display: table;
table-layout: fixed;
- border-collapse: collapse;
- border-spacing: 0;
- z-index: 1;
}
-table.messagelist.fixedcopy
-{
- z-index: 2;
-}
-
-.messagelist thead tr td
+#messagelist thead tr td
{
height: 20px;
padding: 0 4px 0 2px;
vertical-align: middle;
border-bottom: 1px solid #999999;
color: #333333;
- background: url(images/listheader.gif) top left repeat-x #CCC;
+ background: url(images/listheader.gif?v=ab42.314) top left repeat-x #CCC;
font-size: 11px;
font-weight: bold;
}
-.messagelist thead tr td.sortedASC,
-.messagelist thead tr td.sortedDESC
+#messagelist thead tr td.sortedASC,
+#messagelist thead tr td.sortedDESC
{
background-position: 0 -26px;
}
-.messagelist thead tr td.sortedASC a
+#messagelist thead tr td.sortedASC a
{
- background: url(images/icons/sort.gif) right 0 no-repeat;
+ background: url(images/icons/sort.gif?v=92aa.144) right 0 no-repeat;
}
-.messagelist thead tr td.sortedDESC a
+#messagelist thead tr td.sortedDESC a
{
- background: url(images/icons/sort.gif) right -14px no-repeat;
+ background: url(images/icons/sort.gif?v=92aa.144) right -14px no-repeat;
}
-.messagelist thead tr td a
+#messagelist thead tr td a
{
display: block;
width: auto !important;
@@ -683,19 +677,18 @@ table.messagelist.fixedcopy
text-decoration: none;
}
-.messagelist thead tr td.size.sortedASC a,
-.messagelist thead tr td.size.sortedDESC a
+#messagelist thead tr td.size
{
- padding-right: 18px;
+ text-align: left;
}
-.messagelist thead tr td.subject
+#messagelist thead tr td.subject
{
padding-left: 18px;
width: 99%;
}
-.messagelist tbody tr td
+#messagelist tbody tr td
{
height: 20px;
padding: 0;
@@ -709,7 +702,7 @@ table.messagelist.fixedcopy
cursor: default;
}
-.messagelist tbody tr td a
+#messagelist tbody tr td a
{
color: #000;
text-decoration: none;
@@ -717,267 +710,267 @@ table.messagelist.fixedcopy
cursor: inherit;
}
-.messagelist td img
+#messagelist td img
{
vertical-align: middle;
display: inline-block;
}
-.messagelist tbody tr td.flag,
-.messagelist tbody tr td.status,
-.messagelist tbody tr td.subject span.status
+#messagelist tbody tr td.flag,
+#messagelist tbody tr td.status,
+#messagelist tbody tr td.subject span.status
{
cursor: pointer;
}
-.messagelist tr td.flag span,
-.messagelist tr td.status span,
-.messagelist tr td.attachment span,
-.messagelist tr td.priority span
+#messagelist tr td.flag span,
+#messagelist tr td.status span,
+#messagelist tr td.attachment span,
+#messagelist tr td.priority span
{
display: block;
width: 15px;
}
-.messagelist tr td div.collapsed,
-.messagelist tr td div.expanded,
-.messagelist tr td.threads div.listmenu,
-.messagelist tr td.attachment span.attachment,
-.messagelist tr td.attachment span.report,
-.messagelist tr td.priority span.priority,
-.messagelist tr td.priority span.prio1,
-.messagelist tr td.priority span.prio2,
-.messagelist tr td.priority span.prio3,
-.messagelist tr td.priority span.prio4,
-.messagelist tr td.priority span.prio5,
-.messagelist tr td.flag span.flagged,
-.messagelist tr td.flag span.unflagged,
-.messagelist tr td.flag span.unflagged:hover,
-.messagelist tr td.status span.status,
-.messagelist tr td.status span.msgicon,
-.messagelist tr td.status span.deleted,
-.messagelist tr td.status span.unread,
-.messagelist tr td.status span.unreadchildren,
-.messagelist tr td.subject span.msgicon,
-.messagelist tr td.subject span.deleted,
-.messagelist tr td.subject span.unread,
-.messagelist tr td.subject span.replied,
-.messagelist tr td.subject span.forwarded,
-.messagelist tr td.subject span.unreadchildren
+#messagelist tr td div.collapsed,
+#messagelist tr td div.expanded,
+#messagelist tr td.threads div.listmenu,
+#messagelist tr td.attachment span.attachment,
+#messagelist tr td.attachment span.report,
+#messagelist tr td.priority span.priority,
+#messagelist tr td.priority span.prio1,
+#messagelist tr td.priority span.prio2,
+#messagelist tr td.priority span.prio3,
+#messagelist tr td.priority span.prio4,
+#messagelist tr td.priority span.prio5,
+#messagelist tr td.flag span.flagged,
+#messagelist tr td.flag span.unflagged,
+#messagelist tr td.flag span.unflagged:hover,
+#messagelist tr td.status span.status,
+#messagelist tr td.status span.msgicon,
+#messagelist tr td.status span.deleted,
+#messagelist tr td.status span.unread,
+#messagelist tr td.status span.unreadchildren,
+#messagelist tr td.subject span.msgicon,
+#messagelist tr td.subject span.deleted,
+#messagelist tr td.subject span.unread,
+#messagelist tr td.subject span.replied,
+#messagelist tr td.subject span.forwarded,
+#messagelist tr td.subject span.unreadchildren
{
display: inline-block;
vertical-align: middle;
height: 17px;
width: 15px;
- background: url(images/messageicons.png) center no-repeat;
+ background: url(images/messageicons.png?v=9df0.3673) center no-repeat;
}
-.messagelist tr td.attachment span.attachment
+#messagelist tr td.attachment span.attachment
{
background-position: 0 -170px;
}
-.messagelist tr td.attachment span.report
+#messagelist tr td.attachment span.report
{
background-position: 0 -255px;
}
-.messagelist tr td.priority span.priority
+#messagelist tr td.priority span.priority
{
background-position: 0 -309px;
}
-.messagelist tr td.priority span.prio5
+#messagelist tr td.priority span.prio5
{
background-position: 0 -358px;
}
-.messagelist tr td.priority span.prio4
+#messagelist tr td.priority span.prio4
{
background-position: 0 -340px;
}
-.messagelist tr td.priority span.prio3
+#messagelist tr td.priority span.prio3
{
background-position: 0 -324px;
}
-.messagelist tr td.priority span.prio2
+#messagelist tr td.priority span.prio2
{
background-position: 0 -309px;
}
-.messagelist tr td.priority span.prio1
+#messagelist tr td.priority span.prio1
{
background-position: 0 -290px;
}
-.messagelist tr td.flag span.flagged
+#messagelist tr td.flag span.flagged
{
background-position: 0 -153px;
}
-.messagelist tr td.flag span.unflagged:hover
+#messagelist tr td.flag span.unflagged:hover
{
background-position: 0 -136px;
}
-.messagelist tr td.subject span.msgicon,
-.messagelist tr td.subject span.unreadchildren
+#messagelist tr td.subject span.msgicon,
+#messagelist tr td.subject span.unreadchildren
{
background-position: 0 -51px;
margin: 0 2px;
}
-.messagelist tr td.subject span.replied
+#messagelist tr td.subject span.replied
{
background-position: 0 -85px;
}
-.messagelist tr td.subject span.forwarded
+#messagelist tr td.subject span.forwarded
{
background-position: 0 -68px;
}
-.messagelist tr td.subject span.replied.forwarded
+#messagelist tr td.subject span.replied.forwarded
{
background-position: 0 -102px;
}
-.messagelist tr td.status span.msgicon,
-.messagelist tr td.flag span.unflagged,
-.messagelist tr td.status span.unreadchildren
+#messagelist tr td.status span.msgicon,
+#messagelist tr td.flag span.unflagged,
+#messagelist tr td.status span.unreadchildren
{
background-position: 0 17px; /* no icon */
}
-.messagelist tr td.status span.msgicon:hover
+#messagelist tr td.status span.msgicon:hover
{
background-position: 0 -272px;
}
-.messagelist tr td.status span.deleted,
-.messagelist tr td.subject span.deleted
+#messagelist tr td.status span.deleted,
+#messagelist tr td.subject span.deleted
{
background-position: 0 -187px;
}
-.messagelist tr td.status span.status,
-.messagelist tr td.status span.unread,
-.messagelist tr td.subject span.unread
+#messagelist tr td.status span.status,
+#messagelist tr td.status span.unread,
+#messagelist tr td.subject span.unread
{
background-position: 0 -119px;
}
-.messagelist tr td div.collapsed
+#messagelist tr td div.collapsed
{
background-position: 0 -221px;
cursor: pointer;
}
-.messagelist tr td div.expanded
+#messagelist tr td div.expanded
{
background-position: 0 -204px;
cursor: pointer;
}
-.messagelist tr td.threads div.listmenu
+#messagelist tr td.threads div.listmenu
{
background-position: 0 -238px;
cursor: pointer;
}
-.messagelist tbody tr td.subject
+#messagelist tbody tr td.subject
{
width: 99%;
}
-.messagelist tbody tr td.subject a
+#messagelist tbody tr td.subject a
{
cursor: default;
vertical-align: middle; /* #1487091 */
}
/* thread parent message with unread children */
-.messagelist tbody tr.unroot td.subject a
+#messagelist tbody tr.unroot td.subject a
{
text-decoration: underline;
}
-.messagelist tr td.attachment,
-.messagelist tr td.threads,
-.messagelist tr td.status,
-.messagelist tr td.flag,
-.messagelist tr td.priority
+#messagelist tr td.attachment,
+#messagelist tr td.threads,
+#messagelist tr td.status,
+#messagelist tr td.flag,
+#messagelist tr td.priority
{
width: 17px;
padding: 0 0 0 2px;
}
-.messagelist tr td.size
+#messagelist tr td.size
{
width: 60px;
text-align: right;
padding: 0 2px;
}
-.messagelist tr td.fromto,
-.messagelist tr td.from,
-.messagelist tr td.to,
-.messagelist tr td.cc,
-.messagelist tr td.replyto
+#messagelist tr td.fromto,
+#messagelist tr td.from,
+#messagelist tr td.to,
+#messagelist tr td.cc,
+#messagelist tr td.replyto
{
width: 180px;
padding: 0 2px;
}
-.messagelist tr td.date
+#messagelist tr td.date
{
width: 118px;
padding: 0 2px;
}
-.messagelist tr.message
+#messagelist tr.message
{
background-color: #FFF;
}
-.messagelist tr.unread
+#messagelist tr.unread
{
font-weight: bold;
background-color: #FFFFFF;
}
-.messagelist tr.flagged td,
-.messagelist tr.flagged td a
+#messagelist tr.flagged td,
+#messagelist tr.flagged td a
{
color: #CC0000;
}
-.messagelist tr.selected td
+#messagelist tr.selected td
{
color: #FFFFFF;
background-color: #CC3333;
}
-.messagelist tr.unfocused td
+#messagelist tr.unfocused td
{
color: #FFFFFF;
background-color: #929292;
}
-.messagelist tr.selected td a
+#messagelist tr.selected td a
{
color: #FFFFFF;
}
-.messagelist tr.unfocused td a
+#messagelist tr.unfocused td a
{
color: #FFFFFF;
}
-.messagelist tr.deleted td,
-.messagelist tr.deleted td a
+#messagelist tr.deleted td,
+#messagelist tr.deleted td a
{
color: #CCCCCC;
}
@@ -1018,7 +1011,7 @@ td span.branch div.tree
{
height: 17px;
width: 15px;
- background: url(images/tree.gif) 0px 0px no-repeat;
+ background: url(images/tree.gif?v=9b73.92) 0px 0px no-repeat;
}
td span.branch div.l1
@@ -1126,7 +1119,7 @@ table.headers-table tr td.header span
min-height: 16px;
list-style-image: none;
list-style-type: none;
- background: url(images/icons/attachment.png) 4px 2px no-repeat #DFDFDF;
+ background: url(images/icons/attachment.png?v=08f7.518) 4px 2px no-repeat #DFDFDF;
}
#messageframe #attachment-list
@@ -1168,16 +1161,6 @@ table.headers-table tr td.header span
text-decoration: underline;
}
-#attachment-list li a.drop {
- background: url(images/icons/down_small.gif) no-repeat center 6px;
- width: 12px;
- height: 7px;
- cursor: pointer;
- padding: 5px 0 0;
- margin-left: 3px;
- display: inline-block;
-}
-
#messagebody
{
position:relative;
@@ -1341,27 +1324,20 @@ div.message-htmlpart div.rcmBody
text-decoration: underline;
}
-#messagelinks
+#openextwinlink
{
position: absolute;
top: 8px;
right: 10px;
- height: 16px;
- text-align: right;
-}
-
-#messageframe #messagelinks
-{
- top: 2px;
- right: 2px;
+ width: 15px;
+ height: 15px;
+ border: 0;
}
#compose-headers #openextwinlink
{
- position: absolute;
- height: 15px;
- top: 4px;
- right: 2px;
+ top: 4px;
+ right: 2px;
}
#full-headers
@@ -1387,12 +1363,12 @@ div.more-headers
div.show-headers
{
- background: url(images/icons/down_small.gif) no-repeat center;
+ background: url(images/icons/down_small.gif?v=f368.105) no-repeat center;
}
div.hide-headers
{
- background: url(images/icons/up_small.gif) no-repeat center;
+ background: url(images/icons/up_small.gif?v=c56c.106) no-repeat center;
}
#headers-source
@@ -1592,6 +1568,7 @@ input.from_address
#compose-attachments ul li
{
height: 18px;
+ line-height: 16px;
font-size: 11px;
padding-left: 2px;
padding-top: 2px;
@@ -1629,19 +1606,16 @@ input.from_address
vertical-align: middle;
}
-#upload-form,
#attachment-form
{
padding: 6px;
}
-#upload-form div,
#attachment-form div
{
padding: 2px;
}
-#upload-form div.buttons,
#attachment-form div.buttons
{
margin-top: 4px;
@@ -1677,7 +1651,7 @@ input.from_address
{
display: block;
font-size: 11px;
- background: url(images/icons/folders.png) 5px -108px no-repeat;
+ background: url(images/icons/folders.png?v=87af.4822) 5px -108px no-repeat;
border-bottom: 1px solid #EBEBEB;
white-space: nowrap;
}
@@ -1719,14 +1693,6 @@ input.from_address
-o-text-overflow: ellipsis;
}
-#contacts-table td span.email
-{
- display: inline;
- color: #ccc;
- font-style: italic;
- margin-left: 0.5em;
-}
-
#abookcountbar
{
margin-top: 4px;
@@ -1752,7 +1718,7 @@ input.from_address
padding-left: 5px;
padding-right: 5px;
text-shadow: 1px 1px white;
- background: url("images/icons/groupactions.png") no-repeat right -70px;
+ background: url(images/icons/groupactions.png?v=ace6.1092) no-repeat right -70px;
}
#abookactions a.disabled
diff --git a/skins/classic/settings.css b/skins/classic/settings.css
index 2433f5040..428e60884 100644
--- a/skins/classic/settings.css
+++ b/skins/classic/settings.css
@@ -85,8 +85,6 @@
{
font-weight: bold;
text-align: right;
- width: 1%;
- white-space: nowrap;
}
#bottomboxes
@@ -180,7 +178,7 @@ div.readtext
{
min-height: 200px;
padding-bottom: 2em;
- background: url(images/watermark.gif) no-repeat center;
+ background: url(images/watermark.gif?v=4094.9288) no-repeat center;
}
#license .sysname
@@ -255,15 +253,3 @@ div.crop
{
overflow: auto;
}
-
-#rcmfd_signature
-{
- width: 99%;
- min-width: 390px;
-}
-
-#rcmfd_signature_toolbar1 td,
-#rcmfd_signature_toolbar2 td
-{
- width: auto;
-}
diff --git a/skins/classic/templates/about.html b/skins/classic/templates/about.html
index 429dfcf5f..519acf773 100644
--- a/skins/classic/templates/about.html
+++ b/skins/classic/templates/about.html
@@ -7,15 +7,11 @@
</head>
<body>
-<roundcube:if condition="!request:_framed" />
-
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
<roundcube:include file="/includes/settingstabs.html" />
<div id="mainscreen" class="box darkbg crop">
-<roundcube:endif />
-
<div class="readtext">
<div id="license">
<roundcube:object name="aboutcontent" />
@@ -33,10 +29,7 @@ Some <a href="http://roundcube.net/license">exceptions</a> for skins &amp; plugi
<roundcube:object name="pluginlist" id="pluginlist" class="records-table" cellspacing="0" />
</div>
-
-<roundcube:if condition="!request:_framed" />
</div>
-<roundcube:endif />
</body>
</html>
diff --git a/skins/classic/templates/addressbook.html b/skins/classic/templates/addressbook.html
index 429b83438..1008cbf76 100644
--- a/skins/classic/templates/addressbook.html
+++ b/skins/classic/templates/addressbook.html
@@ -17,7 +17,7 @@
</style>
</head>
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -28,10 +28,7 @@
<roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletecontact" content=" " />
<span class="separator">&nbsp;</span>
<roundcube:button command="import" type="link" class="buttonPas import" classAct="button import" classSel="button importSel" title="importcontacts" content=" " />
-<span class="dropbutton">
<roundcube:button command="export" type="link" class="buttonPas export" classAct="button export" classSel="button exportSel" title="exportvcards" content=" " />
-<span id="exportmenulink" onclick="rcmail_ui.show_popup('exportmenu');return false"></span>
-</span>
<roundcube:button command="advanced-search" type="link" class="buttonPas search" classAct="button search" classSel="button searchSel" title="advsearch" content=" " />
<roundcube:container name="toolbar" id="abooktoolbar" />
</div>
@@ -42,13 +39,6 @@
<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" width="13" height="13" />
</div>
-<div id="exportmenu" class="popupmenu">
- <ul>
- <li><roundcube:button command="export" label="exportall" prop="sub" classAct="exportalllink active" class="exportalllink" /></li>
- <li><roundcube:button command="export-selected" label="exportsel" prop="sub" classAct="exportsellink active" class="exportsellink" /></li>
- </ul>
-</div>
-
<div id="searchmenu" class="popupmenu">
<ul class="toolbarmenu">
<li><label><input type="checkbox" name="s_mods[]" value="name" id="s_mod_name" onclick="rcmail_ui.set_searchmod(this)" /> <span><roundcube:label name="name" /></span></label></li>
@@ -64,7 +54,8 @@
<div id="directorylistbox">
<div id="directorylist-title" class="boxtitle"><roundcube:label name="groups" /></div>
<div id="directorylist-content" class="boxlistcontent">
- <roundcube:object name="directorylist" id="directorylist" class="treelist" />
+ <roundcube:object name="directorylist" id="directorylist" />
+ <roundcube:object name="groupslist" id="contactgroupslist" />
</div>
<div id="directorylist-footer" class="boxfooter">
<roundcube:button command="group-create" type="link" title="newcontactgroup" class="buttonPas addgroup" classAct="button addgroup" content=" " />
@@ -75,7 +66,7 @@
<div id="addressscreen">
<div id="addresslist">
-<roundcube:object name="addresslisttitle" label="contacts" tag="div" class="boxtitle" />
+<div class="boxtitle"><roundcube:label name="contacts" /></div>
<div class="boxlistcontent">
<roundcube:object name="addresslist" id="contacts-table" class="records-table" cellspacing="0" summary="Contacts list" noheader="true" />
</div>
@@ -116,16 +107,5 @@
</ul>
</div>
-<div id="dragmenu" class="popupmenu">
- <ul>
- <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
- <li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
- </ul>
-</div>
-
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/skins/classic/templates/compose.html b/skins/classic/templates/compose.html
index 5e259e11c..b6dab2c4c 100644
--- a/skins/classic/templates/compose.html
+++ b/skins/classic/templates/compose.html
@@ -16,10 +16,10 @@
</style>
</head>
<roundcube:if condition="env:extwin" />
-<body class="extwin">
+<body class="extwin" onload="rcube_init_mail_ui()">
<roundcube:object name="message" id="message" />
<roundcube:else />
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
<roundcube:endif />
@@ -44,7 +44,7 @@
<roundcube:button name="messageoptions" id="composemenulink" type="link" class="button messagemenu" title="messageoptions" onclick="rcmail_ui.show_popup('composemenu', true);return false" content=" " />
</div>
-<roundcube:form name="form" method="post">
+<form name="form" action="./" method="post">
<div id="mainscreen">
@@ -178,16 +178,23 @@
<tr>
<td><label for="rcmcomposereceipt"><roundcube:label name="returnreceipt" />:</label></td>
<td><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" /></td>
- </tr><tr>
+ </tr>
+ <roundcube:if condition="config:smtp_server != ''" />
+ <tr>
<td><label for="rcmcomposedsn"><roundcube:label name="dsn" />:</label></td>
<td><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" /></td>
- </tr><tr>
+ </tr>
+ <roundcube:endif />
+ <tr>
<td><label for="rcmcomposepriority"><roundcube:label name="priority" />:</label></td>
<td><roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" /></td>
- </tr><roundcube:if condition="!config:no_save_sent_messages" /><tr>
+ </tr>
+ <roundcube:if condition="!config:no_save_sent_messages" />
+ <tr>
<td><label><roundcube:label name="savesentmessagein" />:</label></td>
<td><roundcube:object name="storetarget" maxlength="30" /></td>
- </tr><roundcube:endif />
+ </tr>
+ <roundcube:endif />
</table>
</div>
@@ -197,9 +204,5 @@
<roundcube:object name="composeAttachmentForm" id="attachment-form" attachmentFieldSize="40" class="popupmenu" />
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/skins/classic/templates/contact.html b/skins/classic/templates/contact.html
index 8be112b49..d74a78b27 100644
--- a/skins/classic/templates/contact.html
+++ b/skins/classic/templates/contact.html
@@ -13,7 +13,7 @@
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
<roundcube:endif />
- <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" placeholderGroup="/images/contactgroup.png" /></div>
+ <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /></div>
<roundcube:object name="contacthead" id="contacthead" />
<div style="clear:both"></div>
<div id="contacttabs">
diff --git a/skins/classic/templates/contactadd.html b/skins/classic/templates/contactadd.html
index bad6daf28..05cc8aa82 100644
--- a/skins/classic/templates/contactadd.html
+++ b/skins/classic/templates/contactadd.html
@@ -5,11 +5,11 @@
<roundcube:include file="/includes/links.html" />
<script type="text/javascript" src="/functions.js"></script>
</head>
-<body class="iframe">
+<body class="iframe" onload="rcube_init_mail_ui()">
<div id="contact-title" class="boxtitle"><roundcube:label name="addcontact" /></div>
<div id="contact-details" class="boxcontent">
-<roundcube:form name="editform" method="post">
+<form name="editform" method="post" action="./">
<roundcube:if condition="strlen(env:sourcename)" />
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:object name="sourceselector" class="hint" id="sourceselect" /></div>
<roundcube:endif />
@@ -35,10 +35,7 @@
<roundcube:object name="photoUploadForm" id="upload-form" size="30" class="popupmenu" />
<roundcube:object name="fileDropArea" id="contactpic" />
-<script type="text/javascript">
-rcube_init_tabs('contacttabs');
-rcube_init_mail_ui();
-</script>
+<script type="text/javascript">rcube_init_tabs('contacttabs')</script>
</body>
</html>
diff --git a/skins/classic/templates/contactedit.html b/skins/classic/templates/contactedit.html
index c51cbf296..db8599ac6 100644
--- a/skins/classic/templates/contactedit.html
+++ b/skins/classic/templates/contactedit.html
@@ -5,11 +5,11 @@
<roundcube:include file="/includes/links.html" />
<script type="text/javascript" src="/functions.js"></script>
</head>
-<body class="iframe">
+<body class="iframe" onload="rcube_init_mail_ui()">
<div id="contact-title" class="boxtitle"><roundcube:label name="editcontact" /></div>
<div id="contact-details" class="boxcontent">
-<roundcube:form name="editform" method="post">
+<form name="editform" method="post" action="./">
<roundcube:if condition="strlen(env:sourcename)" />
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
<roundcube:endif />
@@ -35,10 +35,7 @@
<roundcube:object name="photoUploadForm" id="upload-form" size="30" class="popupmenu" />
<roundcube:object name="fileDropArea" id="contactpic" />
-<script type="text/javascript">
-rcube_init_tabs('contacttabs');
-rcube_init_mail_ui();
-</script>
+<script type="text/javascript">rcube_init_tabs('contacttabs')</script>
</body>
</html>
diff --git a/skins/classic/templates/folders.html b/skins/classic/templates/folders.html
index f86be092b..1ae8809ec 100644
--- a/skins/classic/templates/folders.html
+++ b/skins/classic/templates/folders.html
@@ -12,7 +12,7 @@
}
</style>
</head>
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -58,9 +58,5 @@
</ul>
</div>
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/skins/classic/templates/login.html b/skins/classic/templates/login.html
index 2dacd48ff..cca2bd934 100644
--- a/skins/classic/templates/login.html
+++ b/skins/classic/templates/login.html
@@ -15,7 +15,7 @@
<div class="boxtitle"><roundcube:label name="welcome" /></div>
<div class="boxcontent">
-<roundcube:form name="form" method="post">
+<form name="form" action="./" method="post">
<roundcube:object name="loginform" form="form" />
<p style="text-align:center;"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>
diff --git a/skins/classic/templates/mail.html b/skins/classic/templates/mail.html
index 10aebc96d..75a112ff5 100644
--- a/skins/classic/templates/mail.html
+++ b/skins/classic/templates/mail.html
@@ -18,7 +18,7 @@
}
</style>
</head>
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -28,7 +28,7 @@
<div id="mailboxlist-container">
<div id="mailboxlist-title" class="boxtitle"><roundcube:label name="mailboxlist" /></div>
<div id="mailboxlist-content" class="boxlistcontent">
-<roundcube:object name="mailboxlist" id="mailboxlist" class="treelist" folder_filter="mail" />
+<roundcube:object name="mailboxlist" id="mailboxlist" folder_filter="mail" />
</div>
<div id="mailboxlist-footer" class="boxfooter">
<roundcube:button name="mailboxmenulink" id="mailboxmenulink" type="link" title="folderactions" class="button groupactions" onclick="rcmail_ui.show_popup('mailboxmenu');return false" content=" " />
@@ -55,7 +55,6 @@
<div id="messagelistcontainer" class="boxlistcontent" style="top:0">
<roundcube:object name="messages"
id="messagelist"
- class="messagelist fixedheader"
cellspacing="0"
columns=""
summary="Message list"
@@ -131,9 +130,9 @@
<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" width="13" height="13" />
</div>
-<div id="dragmenu" class="popupmenu">
+<div id="dragmessagemenu" class="popupmenu">
<ul>
- <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
+ <li><roundcube:button command="moveto" onclick="return rcmail.drag_menu_action('moveto')" label="move" classAct="active" /></li>
<li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
</ul>
</div>
@@ -141,8 +140,7 @@
<div id="mailboxoptionsmenu" class="popupmenu">
<ul>
<li><roundcube:button command="expunge" type="link" label="compact" classAct="active" /></li>
- <li><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
- <li class="separator_below"><roundcube:button name="messageimport" type="link" class="active" label="importmessages" id="uploadformlink" onclick="rcmail_ui.show_popup('uploadform', true); return false" /></li>
+ <li class="separator_below"><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
<li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<roundcube:container name="mailboxoptions" id="mailboxoptionsmenu" />
</ul>
@@ -206,11 +204,5 @@
</div>
</div>
-<roundcube:object name="messageimportform" id="upload-form" attachmentFieldSize="40" class="popupmenu" />
-
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/skins/classic/templates/message.html b/skins/classic/templates/message.html
index 757c0a635..4a4068dbe 100644
--- a/skins/classic/templates/message.html
+++ b/skins/classic/templates/message.html
@@ -13,10 +13,10 @@
</style>
</head>
<roundcube:if condition="env:extwin" />
-<body class="extwin">
+<body class="extwin" onload="rcube_init_mail_ui()">
<roundcube:object name="message" id="message" />
<roundcube:else />
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -30,7 +30,7 @@
<div id="mailboxlist-container">
<div id="mailboxlist-title" class="boxtitle"><roundcube:label name="mailboxlist" /></div>
<div class="boxlistcontent">
- <roundcube:object name="mailboxlist" id="mailboxlist" class="treelist" maxlength="25" />
+ <roundcube:object name="mailboxlist" id="mailboxlist" maxlength="25" />
</div>
<div class="boxfooter"></div>
</div>
@@ -39,17 +39,9 @@
<div id="messageframe">
<div class="boxlistcontent" style="top:0; overflow-x:auto">
- <div id="messagelinks">
- <roundcube:if condition="env:optional_format=='text'" />
- <roundcube:button command="change-format" prop="text" image="/images/icons/text.png" width="15" height="15" title="changeformattext" id="changeformattext" />
- <roundcube:endif />
- <roundcube:if condition="env:optional_format=='html'" />
- <roundcube:button command="change-format" prop="html" image="/images/icons/html.png" width="15" height="15" title="changeformathtml" id="changeformathtml" />
- <roundcube:endif />
- </div>
<roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/silhouette.png" summary="Message headers" />
<roundcube:object name="messageFullHeaders" id="full-headers" />
-<roundcube:object name="messageAttachments" id="attachment-list" />
+<roundcube:object name="messageAttachments" id="attachment-list" maxlength="50" />
<roundcube:object name="messageObjects" id="message-objects" />
<roundcube:object name="messageBody" id="messagebody" />
</div>
@@ -73,17 +65,5 @@
</script>
<roundcube:endif />
-<div id="attachmentmenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="openlink" classAct="openlink active" innerclass="openlink" /></li>
- <li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="downloadlink" classAct="downloadlink active" innerclass="downloadlink" /></li>
- <roundcube:container name="attachmentmenu" id="attachmentmenu" />
- </ul>
-</div>
-
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/skins/classic/templates/messageerror.html b/skins/classic/templates/messageerror.html
index eb8c7e058..918e3092a 100644
--- a/skins/classic/templates/messageerror.html
+++ b/skins/classic/templates/messageerror.html
@@ -27,7 +27,7 @@
</style>
</head>
-<body>
+<body onload="rcube_init_mail_ui()">
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -42,7 +42,7 @@
<div id="mailboxlist-container">
<div class="boxtitle"><roundcube:label name="mailboxlist" /></div>
<div class="boxlistcontent">
- <roundcube:object name="mailboxlist" id="mailboxlist" class="treelist" folder_filter="mail" />
+ <roundcube:object name="mailboxlist" id="mailboxlist" folder_filter="mail" />
</div>
<div class="boxfooter"></div>
</div>
@@ -61,10 +61,6 @@
rcmail.add_onload('mailviewsplitv.init()');
</script>
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
<roundcube:endif />
diff --git a/skins/classic/templates/messagepart.html b/skins/classic/templates/messagepart.html
index 9f2215679..ce7dbe2e1 100644
--- a/skins/classic/templates/messagepart.html
+++ b/skins/classic/templates/messagepart.html
@@ -3,39 +3,23 @@
<head>
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
-<script type="text/javascript" src="/splitter.js"></script>
-<script type="text/javascript" src="/functions.js"></script>
-<style type="text/css">
-#messagepartheader { width: <roundcube:exp expression="!empty(cookie:mailpartsplitter) ? cookie:mailpartsplitter-5 : 170" />px; }
-#messagepartcontainer { left: <roundcube:exp expression="!empty(cookie:mailpartsplitter) ? cookie:mailpartsplitter+5 : 180" />px;
-<roundcube:exp expression="browser:ie ? ('width: expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:mailpartsplitter) ? cookie:mailpartsplitter+5 : 180).')+\\'px\\');') : ''" />
-}
-</style>
</head>
<body class="extwin">
-<roundcube:object name="message" id="message" />
-<div id="messagetoolbar">
- <roundcube:button command="download" type="link" class="button download" classAct="button download" classSel="button downloadSel" title="download" content=" " />
- <roundcube:button command="print" type="link" class="button print" classAct="button print" classSel="button printSel" title="print" content=" " />
- <roundcube:container name="toolbar" id="messagetoolbar" />
+<roundcube:include file="/includes/header.html" />
+
+<div id="partheader">
+<roundcube:object name="messagePartControls" cellpadding="2" cellspacing="0" />
+
+<div style="position:absolute; top:2px; right:0; width:12em; text-align:right">
+ [<a href="#close" class="closelink" onclick="self.close()"><roundcube:label name="close" /></a>]
</div>
+</div>
+
-<div id="mainscreen">
- <div id="messagepartheader">
- <div class="boxtitle" /><roundcube:label name="properties" /></div>
- <div class="boxlistcontent">
- <roundcube:object name="messagePartControls" class="records-table" cellspacing="0" />
- </div>
- </div>
- <div id="messagepartcontainer">
- <roundcube:object name="messagePartFrame" id="messagepartframe" width="100%" height="100%" />
- </div>
+<div id="messagepartcontainer">
+<roundcube:object name="messagePartFrame" id="messagepartframe" width="100%" height="100%" />
</div>
-<script type="text/javascript">
-var mailpartsplit = new rcube_splitter({id:'mailpartsplitter', p1: 'messagepartheader', p2: 'messagepartcontainer', orientation: 'v', relative: true, start: 165});
-rcmail.add_onload('mailpartsplit.init()');
-</script>
</body>
</html>
diff --git a/skins/classic/templates/messagepreview.html b/skins/classic/templates/messagepreview.html
index b42a06342..cc6fafab1 100644
--- a/skins/classic/templates/messagepreview.html
+++ b/skins/classic/templates/messagepreview.html
@@ -3,40 +3,18 @@
<head>
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
-<script type="text/javascript" src="/splitter.js"></script>
-<script type="text/javascript" src="/functions.js"></script>
</head>
<body class="iframe">
<div class="messageheaderbox">
- <div id="messagelinks">
- <roundcube:if condition="env:optional_format=='text'" />
- <roundcube:button command="change-format" prop="text" image="/images/icons/text.png" width="15" height="15" title="changeformattext" id="changeformattext" />
- <roundcube:endif />
- <roundcube:if condition="env:optional_format=='html'" />
- <roundcube:button command="change-format" prop="html" image="/images/icons/html.png" width="15" height="15" title="changeformathtml" id="changeformathtml" />
- <roundcube:endif />
- <roundcube:button command="extwin" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="openextwinlink" />
- </div>
+<roundcube:button command="extwin" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="openextwinlink" />
<roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/silhouette.png" summary="Message headers" />
<roundcube:object name="messageFullHeaders" id="full-headers" />
-<roundcube:object name="messageAttachments" id="attachment-list" />
+<roundcube:object name="messageAttachments" id="attachment-list" maxlength="50" />
</div>
<roundcube:object name="messageObjects" id="message-objects" />
<roundcube:object name="messageBody" id="messagebody" />
-<div id="attachmentmenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="openlink" classAct="openlink active" innerclass="openlink" /></li>
- <li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="downloadlink" classAct="downloadlink active" innerclass="downloadlink" /></li>
- <roundcube:container name="attachmentmenu" id="attachmentmenu" />
- </ul>
-</div>
-
-<script type="text/javascript">
-rcube_init_mail_ui();
-</script>
-
</body>
</html>
diff --git a/skins/classic/templates/responseedit.html b/skins/classic/templates/responseedit.html
new file mode 100644
index 000000000..67ba35bac
--- /dev/null
+++ b/skins/classic/templates/responseedit.html
@@ -0,0 +1,24 @@
+<!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" />
+<script type="text/javascript" src="/functions.js"></script>
+
+</head>
+<body class="iframe">
+
+<div id="prefs-title" class="boxtitle"><roundcube:object name="steptitle" /></div>
+
+<div id="response-details" class="boxcontent">
+ <roundcube:object name="responseform" class="propform" size="60" textareacols="60" textarearows="18" />
+
+ <div id="formfooter">
+ <div class="footerindent">
+ <roundcube:button command="save" type="input" class="button mainaction" label="save" condition="!env:readonly" />
+ </div>
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/skins/classic/templates/responses.html b/skins/classic/templates/responses.html
new file mode 100644
index 000000000..2459827b0
--- /dev/null
+++ b/skins/classic/templates/responses.html
@@ -0,0 +1,46 @@
+<!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" />
+<script type="text/javascript" src="/functions.js"></script>
+<script type="text/javascript" src="/splitter.js"></script>
+<style type="text/css">
+#identities-list { width: <roundcube:exp expression="!empty(cookie:identviewsplitter) ? cookie:identviewsplitter-5 : 295" />px; }
+#identity-box { left: <roundcube:exp expression="!empty(cookie:identviewsplitter) ? cookie:identviewsplitter+5 : 305" />px;
+ <roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:identviewsplitter) ? cookie:identviewsplitter+5 : 305).')+\\'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="identities-list">
+<div id="identity-title" class="boxtitle"><roundcube:label name="responses" /></div>
+<div class="boxlistcontent">
+<roundcube:object name="responsesList" id="identities-table" class="records-table" cellspacing="0" summary="Responses list" noheader="true" editIcon="" />
+</div>
+<div class="boxfooter">
+<roundcube:button command="add" type="link" title="newidentity" class="buttonPas addgroup" classAct="button addgroup" content=" " condition="config:identities_level:0<2" /><roundcube:button command="delete" type="link" title="delete" class="buttonPas delgroup" classAct="button delgroup" content=" " condition="config:identities_level:0<2" />
+</div>
+</div>
+
+<script type="text/javascript">
+ var identviewsplit = new rcube_splitter({id:'identviewsplitter', p1: 'identities-list', p2: 'identity-box', orientation: 'v', relative: true, start: 300 });
+ rcmail.add_onload('identviewsplit.init()');
+</script>
+
+<div id="identity-box">
+ <roundcube:object name="responseframe" id="identity-frame" width="100%" height="100%" frameborder="0" src="/watermark.html" />
+</div>
+
+</div>
+
+</body>
+</html>
diff --git a/skins/larry/addressbook.css b/skins/larry/addressbook.css
index 6bf9426c4..5befed9d7 100644
--- a/skins/larry/addressbook.css
+++ b/skins/larry/addressbook.css
@@ -67,7 +67,7 @@
#directorylist li a,
#contacts-table .contact td.name {
- background-image: url(images/listicons.png);
+ background-image: url(images/listicons.png?v=bd98.25486);
background-position: -100px 0;
background-repeat: no-repeat;
overflow: hidden;
@@ -75,27 +75,18 @@
text-overflow: ellipsis;
}
+#contacts-table .contact.readonly td {
+ font-style: italic;
+}
+
#directorylist li.addressbook a {
background-position: 6px -766px;
}
-#directorylist li.addressbook.selected > a {
+#directorylist li.addressbook.selected a {
background-position: 6px -791px;
}
-#directorylist li.addressbook ul li:last-child {
- border-bottom: 0;
-}
-
-#directorylist li.addressbook ul.groups {
- margin: 0;
- padding: 0;
-}
-
-#directorylist li.addressbook ul.groups li {
- width: 100%;
-}
-
#directorylist li.contactgroup a {
padding-left: 62px;
background-position: 32px -1555px;
@@ -121,34 +112,6 @@
margin-left: 8px;
}
-#directorylist li.addressbook div.collapsed,
-#directorylist li.addressbook div.expanded {
- top: 15px;
- left: 20px;
-}
-
-#contacts-table .contact.readonly td {
- font-style: italic;
-}
-
-#contacts-table td.name {
- width: 95%;
-}
-
-#contacts-table td.action {
- width: 24px;
- padding: 4px;
-}
-
-#contacts-table td.action a {
- display: block;
- width: 16px;
- height: 14px;
- text-indent: -5000px;
- overflow: hidden;
- background: url(images/listicons.png) -2px -1180px no-repeat;
-}
-
#contacts-table .contact td.name {
background-position: 6px -1603px;
}
@@ -159,29 +122,6 @@
font-weight: bold;
}
-#contacts-table .group td.name {
- background-position: 6px -1555px;
-}
-
-#contacts-table .group.selected td.name,
-#contacts-table .group.unfocused td.name {
- background-position: 6px -1579px;
- font-weight: bold;
-}
-
-#addresslist .boxtitle {
- padding-right: 95px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#addresslist .boxtitle a.poplink {
- color: #004458;
- font-size: 14px;
- line-height: 12px;
- text-decoration: none;
-}
-
#contact-frame {
position: absolute;
top: 0;
@@ -219,12 +159,12 @@
}
#contactpic img {
- max-width: 112px;
+ width: 112px;
visibility: inherit;
}
#contactpic.droptarget {
- background-image: url(images/filedrop.png);
+ background-image: url(images/filedrop.png?v=deab.605);
background-position: center;
background-repeat: no-repeat;
}
@@ -375,15 +315,5 @@ a.deletebutton {
height: 18px;
text-decoration: none;
text-indent: -5000px;
- background: url(images/buttons.png) -7px -377px no-repeat;
-}
-
-#import-box {
- position: absolute;
- bottom: 28px;
- top: 34px;
- left: 0;
- right: 0;
- overflow: auto;
- padding: 10px;
+ background: url(images/buttons.png?v=abf1.36693) -7px -377px no-repeat;
}
diff --git a/skins/larry/embed.css b/skins/larry/embed.css
index 2c8ba39dc..6b8a65f5d 100644
--- a/skins/larry/embed.css
+++ b/skins/larry/embed.css
@@ -15,7 +15,7 @@
font-weight: bold;
color: #996600;
border: 1px solid #ffdf0e;
- background: url("images/messages.png") no-repeat scroll 5px -83px #fef893;
+ background: url(images/messages.png?v=01ee.1736) no-repeat scroll 5px -83px #fef893;
padding: 6px 12px 4px 30px;
margin-bottom: 0.8em;
}
diff --git a/skins/larry/ie7hacks.css b/skins/larry/ie7hacks.css
index fc4713361..6d7af4787 100644
--- a/skins/larry/ie7hacks.css
+++ b/skins/larry/ie7hacks.css
@@ -41,7 +41,6 @@ a.deletebutton,
.boxfooter .listbutton .inner,
.attachmentslist li a.delete,
.attachmentslist li a.cancelupload,
-#contacts-table td.action a,
.previewheader .iconlink,
.minimal #taskbar .button-inner {
/* workaround for text-indent which also offsets the background image */
diff --git a/skins/larry/iehacks.css b/skins/larry/iehacks.css
index 960ce7648..9996824b0 100644
--- a/skins/larry/iehacks.css
+++ b/skins/larry/iehacks.css
@@ -29,8 +29,7 @@ input.button.mainaction:active {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2a2e31', endColorstr='#505050', GradientType=0);
}
-a.button,
-.buttongroup {
+a.button {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e6e6e6', GradientType=0);
}
@@ -48,10 +47,6 @@ input.button:active {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#bababa', endColorstr='#d8d8d8', GradientType=0);
}
-.buttongroup a.button.selected {
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#909090', endColorstr='#858585', GradientType=0);
-}
-
#message.statusbar {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eaeaea', endColorstr='#c8c8c8', GradientType=0);
}
@@ -123,7 +118,7 @@ ul.toolbarmenu li a.active:hover,
.pagenav a.button.disabled span.inner,
.boxfooter .listbutton.disabled .inner,
.dropbutton a.button.disabled + .dropbuttontip {
- background-image: url(images/buttons.gif);
+ background-image: url(images/buttons.gif?v=aab8.13054);
}
/*** addressbook.css ***/
diff --git a/skins/larry/images/buttons.gif b/skins/larry/images/buttons.gif
index 8a4a78ee4..d8a33d6b2 100644
--- a/skins/larry/images/buttons.gif
+++ b/skins/larry/images/buttons.gif
Binary files differ
diff --git a/skins/larry/images/buttons.png b/skins/larry/images/buttons.png
index 9f8f44536..4438d9cbc 100644
--- a/skins/larry/images/buttons.png
+++ b/skins/larry/images/buttons.png
Binary files differ
diff --git a/skins/larry/images/favicon.ico b/skins/larry/images/favicon.ico
index 9ef2f3b9e..b3bd18c12 100644
--- a/skins/larry/images/favicon.ico
+++ b/skins/larry/images/favicon.ico
Binary files differ
diff --git a/skins/larry/images/listicons.png b/skins/larry/images/listicons.png
index e4ffef660..f4505d4fa 100644
--- a/skins/larry/images/listicons.png
+++ b/skins/larry/images/listicons.png
Binary files differ
diff --git a/skins/larry/includes/footer.html b/skins/larry/includes/footer.html
index a4fa69296..ee93fcf57 100644
--- a/skins/larry/includes/footer.html
+++ b/skins/larry/includes/footer.html
@@ -8,16 +8,4 @@ $(document).ready(function(){
});
</script>
-<!--[if lte IE 8]>
-<script type="text/javascript">
-
-// fix missing :last-child selectors
-$(document).ready(function(){
- $('ul.treelist ul').each(function(i,ul){
- $('li:last-child', ul).css('border-bottom', 0);
- });
-});
-
-</script>
-<![endif]-->
diff --git a/skins/larry/includes/header.html b/skins/larry/includes/header.html
index 5a934d89b..f2efb8e06 100644
--- a/skins/larry/includes/header.html
+++ b/skins/larry/includes/header.html
@@ -2,7 +2,7 @@
<div id="topline">
<div class="topleft">
<roundcube:container name="topline-left" id="topline-left" />
- <roundcube:button name="about" type="link" label="about" class="about-link" onclick="UI.show_about(this);return false" condition="!env:extwin" />
+ <roundcube:button name="about" type="link" label="about" class="about-link" onclick="UI.show_about(this);return false" />
<roundcube:if condition="config:support_url" />
<a href="<roundcube:var name='config:support_url' />" target="_blank" class="support-link" id="supportlink"><roundcube:label name="support" /></a>
<roundcube:endif />
@@ -14,7 +14,7 @@
<span class="username"><roundcube:object name="username" /></span>
<roundcube:button command="logout" label="logout" class="button-logout" />
<roundcube:elseif condition="env:extwin" />
- <roundcube:button name="close" type="link" label="close" class="closelink" onclick="self.close()" />
+ <roundcube:button command="close" label="close" class="closelink" />
<roundcube:endif />
</div>
</div>
@@ -29,9 +29,11 @@
<roundcube:button command="logout" label="logout" class="button-logout" classSel="button-logout" innerClass="button-inner" />
<span class="minmodetoggle"></span>
</div>
- <roundcube:object name="logo" src="/images/roundcube_logo.png" id="toplogo" alt="Logo" onclick="rcmail.command('switch-task','mail');return false;" />
+ <roundcube:object name="logo" src="/images/roundcube_logo.png" id="toplogo" border="0" alt="Logo" onclick="rcmail.command('switch-task','mail');return false;" />
</div>
<roundcube:endif />
<br style="clear:both" />
</div>
+
+
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index b65b08112..c3495276e 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -2,7 +2,7 @@
* Roundcube webmail styles for the Email section
*
* Copyright (c) 2012, The Roundcube Dev Team
- * Screendesign by FLINT / Büro für Gestaltung, bueroflint.com
+ * Screendesign by FLINT / B�ro f�r Gestaltung, bueroflint.com
*
* The contents are subject to the Creative Commons Attribution-ShareAlike
* License. It is allowed to copy, distribute, transmit and to adapt the work
@@ -54,10 +54,6 @@
border-top: none;
}
-#composeview-right #mailview-bottom {
- border-radius: 0 0 4px 4px;
-}
-
#folderlist-header {
width: 100%;
height: 12px;
@@ -79,12 +75,6 @@
overflow: auto;
}
-/* Real browsers accept this (not IE) */
-html>/**/body #messagelist {
- overflow: auto;
- overflow-x: hidden;
-}
-
#messagelistfooter {
position: absolute;
bottom: 0;
@@ -151,7 +141,7 @@ a.iconbutton.threadmode.selected {
background-position: 6px 2px;
}
-#mailboxlist > li:first-child {
+#mailboxlist li:first-child {
border-radius: 4px 4px 0 0;
border-top: 0;
}
@@ -161,12 +151,12 @@ a.iconbutton.threadmode.selected {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
- background-image: url(images/listicons.png);
+ background-image: url(images/listicons.png?v=bd98.25486);
background-repeat: no-repeat;
background-position: 6px 3px;
}
-#mailboxlist li.mailbox.unread > a {
+#mailboxlist li.mailbox.unread a {
padding-right: 36px;
}
@@ -222,46 +212,6 @@ a.iconbutton.threadmode.selected {
background-position: 6px -1723px;
}
-#mailboxlist li.mailbox ul li.drafts > a {
- background-position: 23px -238px;
-}
-
-#mailboxlist li.mailbox ul li.drafts.selected > a {
- background-position: 23px -262px;
-}
-
-#mailboxlist li.mailbox ul li.sent > a {
- background-position: 23px -286px;
-}
-
-#mailboxlist li.mailbox ul li.sent.selected > a {
- background-position: 23px -310px;
-}
-
-#mailboxlist li.mailbox ul li.junk > a {
- background-position: 23px -334px;
-}
-
-#mailboxlist li.mailbox ul li.junk.selected > a {
- background-position: 23px -358px;
-}
-
-#mailboxlist li.mailbox ul li.trash > a {
- background-position: 23px -382px;
-}
-
-#mailboxlist li.mailbox ul li.trash.selected > a {
- background-position: 23px -406px;
-}
-
-#mailboxlist li.mailbox ul li.archive > a {
- background-position: 23px -1699px;
-}
-
-#mailboxlist li.mailbox ul li.archive.selected > a {
- background-position: 23px -1723px;
-}
-
#mailboxlist li.unread {
font-weight: bold;
}
@@ -274,17 +224,6 @@ a.iconbutton.threadmode.selected {
color: #017cb4;
}
-#mailboxlist li.mailbox div.treetoggle {
- top: 13px;
- left: 19px;
-}
-
-#mailboxlist li.mailbox ul li:last-child {
- border-bottom: 0;
-}
-
-/* nested mailboxes */
-
#mailboxlist li.mailbox ul {
list-style: none;
margin: 0;
@@ -292,57 +231,50 @@ a.iconbutton.threadmode.selected {
border-top: 1px solid #bbd3da;
}
+#mailboxlist li.mailbox ul li {
+ padding-left: 26px;
+}
+
#mailboxlist li.mailbox ul li a {
- padding-left: 52px; /* 36 + 1 x 16 */
- background-position: 22px -93px; /* 6 + 1 x 16 */
+ background-position: 6px -93px;
}
+
#mailboxlist li.mailbox ul li.selected > a {
- background-position: 22px -117px;
-}
-#mailboxlist li.mailbox ul li div.treetoggle {
- left: 33px;
- top: 14px;
+ background-position: 6px -117px;
}
-#mailboxlist li.mailbox ul ul li.mailbox a {
- padding-left: 68px; /* 2x */
- background-position: 38px -93px;
-}
-#mailboxlist li.mailbox ul ul li.selected > a {
- background-position: 38px -117px;
-}
-#mailboxlist li.mailbox ul ul li div.treetoggle {
- left: 48px;
+#mailboxlist li.mailbox ul li:last-child {
+ border-bottom: 0;
}
-#mailboxlist li.mailbox ul ul ul li.mailbox a {
- padding-left: 84px; /* 3x */
- background-position: 54px -93px;
-}
-#mailboxlist li.mailbox ul ul ul li.selected > a {
- background-position: 54px -117px;
-}
-#mailboxlist li.mailbox ul ul ul li div.treetoggle {
- left: 64px;
+#mailboxlist li.mailbox div.collapsed,
+#mailboxlist li.mailbox div.expanded {
+ position: absolute;
+ top: 13px;
+ left: 19px;
+ width: 13px;
+ height: 13px;
+ background: url(images/listicons.png?v=bd98.25486) -3px -144px no-repeat;
+ cursor: pointer;
}
-#mailboxlist li.mailbox ul ul ul ul li.mailbox a {
- padding-left: 100px; /* 4x */
- background-position: 70px -93px;
-}
-#mailboxlist li.mailbox ul ul ul ul li.selected > a {
- background-position: 70px -117px;
+#mailboxlist li.mailbox div.expanded {
+ background-position: -3px -168px;
}
-#mailboxlist li.mailbox ul ul ul ul li div.treetoggle {
- left: 80px;
+
+#mailboxlist li.mailbox.selected > div.collapsed {
+ background-position: -23px -144px;
}
-/* indent folders on levels > 4 */
-#mailboxlist li.mailbox ul ul ul ul ul li {
- padding-left: 16px;
+#mailboxlist li.mailbox.selected > div.expanded {
+ background-position: -23px -168px;
}
-#mailboxlist li.mailbox ul ul ul ul ul li div.treetoggle {
- left: 96px;
+
+
+#mailboxlist li.mailbox ul li div.collapsed,
+#mailboxlist li.mailbox ul li div.expanded {
+ left: 43px;
+ top: 14px;
}
#mailboxlist li.mailbox .unreadcount {
@@ -434,6 +366,7 @@ a.iconbutton.threadmode.selected {
position: absolute;
right: 0;
top: 0;
+ width: 400px;
}
#mailpreviewtoggle {
@@ -443,7 +376,7 @@ a.iconbutton.threadmode.selected {
right: 4px;
width: 20px;
height: 18px;
- background: url(images/buttons.png) -3px -458px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -3px -458px no-repeat;
}
#mailpreviewtoggle.enabled {
@@ -453,291 +386,278 @@ a.iconbutton.threadmode.selected {
/*** message list ***/
-/* this is necessary to make FF3 display borders */
-body:-moz-last-node #messagelist {
- border-collapse: separate;
-}
-
-table.messagelist {
- z-index: 1;
-}
-
-table.messagelist.fixedcopy {
- z-index: 2;
-}
-
-.messagelist thead td:first-child {
+#messagelist thead td:first-child {
border-radius: 4px 0 0 0; /* for Chrome */
}
-.messagelist tr td.attachment,
-.messagelist tr td.threads,
-.messagelist tr td.status,
-.messagelist tr td.flag,
-.messagelist tr td.priority {
+#messagelist tr td.attachment,
+#messagelist tr td.threads,
+#messagelist tr td.status,
+#messagelist tr td.flag,
+#messagelist tr td.priority {
width: 20px;
padding: 2px 3px;
}
-.webkit .messagelist tr td.attachment,
-.webkit .messagelist tr td.threads,
-.webkit .messagelist tr td.status,
-.webkit .messagelist tr td.flag,
-.webkit .messagelist tr td.priority {
+.webkit #messagelist tr td.attachment,
+.webkit #messagelist tr td.threads,
+.webkit #messagelist tr td.status,
+.webkit #messagelist tr td.flag,
+.webkit #messagelist tr td.priority {
width: 26px;
}
-.messagelist tr td.threads {
+#messagelist tr td.threads {
width: 26px;
}
-.webkit .messagelist tr td.threads {
+.webkit #messagelist tr td.threads {
width: 30px;
}
-.messagelist tr td.threads,
-.messagelist tr td.threads + td {
+#messagelist tr td.threads,
+#messagelist tr td.threads + td {
border-left: 0;
}
-.messagelist tr td.size {
+#messagelist tr td.size {
width: 60px;
text-align: right;
}
-.messagelist thead tr td.size {
+#messagelist thead tr td.size {
text-align: left;
}
-.messagelist tr td.fromto,
-.messagelist tr td.from,
-.messagelist tr td.to,
-.messagelist tr td.cc,
-.messagelist tr td.replyto {
+#messagelist tr td.fromto,
+#messagelist tr td.from,
+#messagelist tr td.to,
+#messagelist tr td.cc,
+#messagelist tr td.replyto {
width: 200px;
}
-.messagelist tr td.date {
- width: 135px;
+#messagelist tr td.date {
+ width: 125px;
}
-.messagelist tr.message {
+#messagelist tr.message {
/* background-color: #fff; */
}
-.messagelist tr.thread.expanded td {
+#messagelist tr.thread.expanded td {
background-color: #ededed;
}
-.messagelist tr.unread {
+#messagelist tr.unread {
font-weight: bold;
/* background-color: #fff; */
}
-.messagelist tr.flagged td,
-.messagelist tr.flagged td a {
+#messagelist tr.flagged td,
+#messagelist tr.flagged td a {
color: #f30;
}
-.messagelist thead tr td.sortedASC a,
-.messagelist thead tr td.sortedDESC a {
+#messagelist thead tr td.sortedASC a,
+#messagelist thead tr td.sortedDESC a {
color: #004458;
text-decoration: underline;
- background: url(images/listicons.png) right -912px no-repeat;
+ background: url(images/listicons.png?v=bd98.25486) right -912px no-repeat;
}
-.messagelist thead tr td.sortedASC a {
+#messagelist thead tr td.sortedASC a {
background-position: right -944px;
}
-.messagelist td img {
+#messagelist td img {
vertical-align: middle;
display: inline-block;
}
-.messagelist tbody td a {
+#messagelist tbody td a {
color: #333;
text-decoration: none;
white-space: nowrap;
cursor: default;
}
-.messagelist tbody tr td.flag,
-.messagelist tbody tr td.status,
-.messagelist tbody tr td.subject span.status {
+#messagelist tbody tr td.flag,
+#messagelist tbody tr td.status,
+#messagelist tbody tr td.subject span.status {
cursor: pointer;
}
-.messagelist tr td.flag span,
-.messagelist tr td.status span,
-.messagelist tr td.attachment span,
-.messagelist tr td.priority span {
+#messagelist tr td.flag span,
+#messagelist tr td.status span,
+#messagelist tr td.attachment span,
+#messagelist tr td.priority span {
display: block;
width: 20px;
}
-.messagelist tr td div.collapsed,
-.messagelist tr td div.expanded,
-.messagelist tr td.threads div.listmenu,
-.messagelist tr td.attachment span.attachment,
-.messagelist tr td.attachment span.report,
-.messagelist tr td.priority span.priority,
-.messagelist tr td.priority span.prio1,
-.messagelist tr td.priority span.prio2,
-.messagelist tr td.priority span.prio3,
-.messagelist tr td.priority span.prio4,
-.messagelist tr td.priority span.prio5,
-.messagelist tr td.flag span.flagged,
-.messagelist tr td.flag span.unflagged,
-.messagelist tr td.flag span.unflagged:hover,
-.messagelist tr td.status span.status,
-.messagelist tr td.status span.msgicon,
-.messagelist tr td.status span.deleted,
-.messagelist tr td.status span.unread,
-.messagelist tr td.status span.unreadchildren,
-.messagelist tr td.subject span.msgicon,
-.messagelist tr td.subject span.deleted,
-.messagelist tr td.subject span.unread,
-.messagelist tr td.subject span.replied,
-.messagelist tr td.subject span.forwarded,
-.messagelist tr td.subject span.unreadchildren {
+#messagelist tr td div.collapsed,
+#messagelist tr td div.expanded,
+#messagelist tr td.threads div.listmenu,
+#messagelist tr td.attachment span.attachment,
+#messagelist tr td.attachment span.report,
+#messagelist tr td.priority span.priority,
+#messagelist tr td.priority span.prio1,
+#messagelist tr td.priority span.prio2,
+#messagelist tr td.priority span.prio3,
+#messagelist tr td.priority span.prio4,
+#messagelist tr td.priority span.prio5,
+#messagelist tr td.flag span.flagged,
+#messagelist tr td.flag span.unflagged,
+#messagelist tr td.flag span.unflagged:hover,
+#messagelist tr td.status span.status,
+#messagelist tr td.status span.msgicon,
+#messagelist tr td.status span.deleted,
+#messagelist tr td.status span.unread,
+#messagelist tr td.status span.unreadchildren,
+#messagelist tr td.subject span.msgicon,
+#messagelist tr td.subject span.deleted,
+#messagelist tr td.subject span.unread,
+#messagelist tr td.subject span.replied,
+#messagelist tr td.subject span.forwarded,
+#messagelist tr td.subject span.unreadchildren {
display: inline-block;
vertical-align: middle;
height: 18px;
width: 20px;
padding: 0;
- background: url(images/listicons.png) -100px 0 no-repeat;
+ background: url(images/listicons.png?v=bd98.25486) -100px 0 no-repeat;
}
-.messagelist tbody tr td.attachment span.attachment {
+#messagelist tbody tr td.attachment span.attachment {
background-position: 0 -996px;
}
-.messagelist thead tr td.attachment span.attachment {
+#messagelist thead tr td.attachment span.attachment {
background-position: -24px -997px;
}
-.messagelist tbody tr td.attachment span.report {
+#messagelist tbody tr td.attachment span.report {
background-position: -24px -1116px;
}
-.messagelist tr td.priority span.prio5 {
+#messagelist tr td.priority span.prio5 {
background-position: 0 -1905px;
}
-.messagelist tr td.priority span.prio4 {
+#messagelist tr td.priority span.prio4 {
background-position: 0 -1885px;
}
-.messagelist tr td.priority span.prio2 {
+#messagelist tr td.priority span.prio2 {
background-position: 0 -1865px;
}
-.messagelist tr td.priority span.prio1 {
+#messagelist tr td.priority span.prio1 {
background-position: 0 -1845px;
}
-.messagelist tbody tr td.flag span.flagged {
+#messagelist tbody tr td.flag span.flagged {
background-position: 0 -1036px;
}
-.messagelist thead tr td.flag span.flagged {
+#messagelist thead tr td.flag span.flagged {
background-position: -24px -1036px;
}
-.messagelist tr td.status span.msgicon:hover {
+#messagelist tr td.status span.msgicon:hover {
background-position: -23px -1056px;
}
-.messagelist tr td.flag span.unflagged:hover {
+#messagelist tr td.flag span.unflagged:hover {
background-position: -23px -1076px;
}
-.messagelist tr td.subject span.msgicon,
-.messagelist tr td.subject span.unreadchildren {
+#messagelist tr td.subject span.msgicon,
+#messagelist tr td.subject span.unreadchildren {
background-position: 0 -1056px;
margin: 0 1px 0 0;
width: 24px;
}
-.messagelist tr td.subject span.replied {
+#messagelist tr td.subject span.replied {
background-position: 0 -1076px;
}
-.messagelist tr td.subject span.forwarded {
+#messagelist tr td.subject span.forwarded {
background-position: 0 -1096px;
}
-.messagelist tr td.subject span.replied.forwarded {
+#messagelist tr td.subject span.replied.forwarded {
background-position: 0 -1116px;
}
-.messagelist tr td.status span.msgicon,
-.messagelist tr td.flag span.unflagged,
-.messagelist tr td.status span.unreadchildren {
+#messagelist tr td.status span.msgicon,
+#messagelist tr td.flag span.unflagged,
+#messagelist tr td.status span.unreadchildren {
background-position: 0 1056px; /* no icon */
}
/*
-.messagelist tr td.status span.msgicon:hover {
+#messagelist tr td.status span.msgicon:hover {
background-position: 0 -272px;
}
*/
-.messagelist tr td.status span.deleted,
-.messagelist tr td.status span.deleted:hover,
-.messagelist tr td.subject span.deleted {
+#messagelist tr td.status span.deleted,
+#messagelist tr td.status span.deleted:hover,
+#messagelist tr td.subject span.deleted {
background-position: -22px -1096px;
}
-.messagelist tr td.status span.status,
-.messagelist tr td.status span.unread,
-.messagelist tr td.subject span.unread,
-.messagelist tr td.status span.unread:hover {
+#messagelist tr td.status span.status,
+#messagelist tr td.status span.unread,
+#messagelist tr td.subject span.unread,
+#messagelist tr td.status span.unread:hover {
background-position: 0 -1016px;
}
-.messagelist thead tr td.status span.status {
+#messagelist thead tr td.status span.status {
background-position: -24px -1016px;
}
-.messagelist tr td div.collapsed {
+#messagelist tr td div.collapsed {
background-position: 0 -1137px;
cursor: pointer;
}
-.messagelist tr td div.expanded {
+#messagelist tr td div.expanded {
background-position: 0 -1157px;
cursor: pointer;
}
-.messagelist tr td.threads div.listmenu {
+#messagelist tr td.threads div.listmenu {
background-position: 0 -976px;
cursor: pointer;
width: 26px;
}
-.messagelist thead tr td.subject,
-.messagelist tbody tr td.subject {
+#messagelist thead tr td.subject,
+#messagelist tbody tr td.subject {
width: 99%;
white-space: nowrap;
}
-.messagelist tbody tr td.subject a {
+#messagelist tbody tr td.subject a {
cursor: default;
vertical-align: middle; /* #1487091 */
}
/* thread parent message with unread children */
-.messagelist tbody tr.unroot td.subject a {
+#messagelist tbody tr.unroot td.subject a {
text-decoration: underline;
}
/**** tree indicators ****/
-.messagelist tbody tr td span.branch div {
+#messagelist tbody tr td span.branch div {
display: inline-block;
}
-.messagelist tbody tr td span.branch div.tree {
+#messagelist tbody tr td span.branch div.tree {
width: 15px;
}
@@ -771,6 +691,7 @@ table.messagelist.fixedcopy {
}
#messageheader,
+#partheader,
#composeheaders {
position: relative;
padding: 3px 0;
@@ -905,7 +826,7 @@ h3.subject {
left: 0;
width: 18px;
height: 16px;
- background: url(images/buttons.png) -27px -242px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -27px -242px no-repeat;
}
.moreheaderstoggle.remove .iconlink {
@@ -925,11 +846,11 @@ div.more-headers {
width: 12px;
height: 10px;
cursor: pointer;
- background: url(images/buttons.png) center -1579px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) center -1579px no-repeat;
}
div.hide-headers {
- background-position: center -1590px;
+ background-position: center -1589px;
}
#all-headers {
@@ -982,7 +903,7 @@ div.hide-headers {
width: 32px;
height: 32px;
overflow: hidden;
- background: url(images/contactpic_32px.png) center center no-repeat #fff;
+ background: url(images/contactpic_32px.png?v=09a3.287) center center no-repeat #fff;
border-radius: 3px;
}
@@ -1006,7 +927,7 @@ div.hide-headers {
overflow: hidden;
border-radius: 4px;
border: 1px solid #e6e6e6;
- background: url(images/contactpic_48px.png) center center no-repeat #fff;
+ background: url(images/contactpic_48px.png?v=1bc4.353) center center no-repeat #fff;
}
#messageheader #contactphoto img {
@@ -1015,8 +936,7 @@ div.hide-headers {
border-radius: 4px;
}
-#messageheader #countcontrols,
-#messageheader #formatcontrols {
+#messageheader #countcontrols {
position: absolute;
top: 8px;
right: 8px;
@@ -1024,11 +944,6 @@ div.hide-headers {
white-space: nowrap;
}
-#messageheader #formatcontrols {
- top: 38px;
- right: 8px;
-}
-
#messageheader .pagenav .countdisplay {
min-width: 0;
padding-right: 0.5em;
@@ -1099,8 +1014,8 @@ div.message-partheaders {
div.message-part pre,
div.message-htmlpart pre,
div.message-part div.pre {
- margin: 0;
- padding: 0;
+ margin: 0px;
+ padding: 0px;
font-family: monospace;
font-size: 12px;
white-space: -moz-pre-wrap !important;
@@ -1109,7 +1024,7 @@ div.message-part div.pre {
}
div.message-part span.sig {
- color: #666;
+ color: #666666;
}
div.message-part blockquote {
@@ -1117,7 +1032,7 @@ div.message-part blockquote {
border-left: 2px solid blue;
border-right: 2px solid blue;
background-color: #F6F6F6;
- margin: 2px 0 2px 0;
+ margin: 2px 0px 2px 0px;
padding: 1px 8px 1px 10px;
}
@@ -1128,9 +1043,9 @@ div.message-part blockquote blockquote {
}
div.message-part blockquote blockquote blockquote {
- color: #900;
- border-left: 2px solid #b00;
- border-right: 2px solid #b00;
+ color: #990000;
+ border-left: 2px solid #bb0000;
+ border-right: 2px solid #bb0000;
}
div.message-partheaders {
@@ -1205,10 +1120,10 @@ div.message-partheaders .headers-table td.header {
#messagepartcontainer {
position: absolute;
- top: 42px;
- left: 232px;
- right: 0;
- bottom: 0;
+ top: 60px;
+ left: 0px;
+ right: 0px;
+ bottom: 0px;
}
#messagepartframe {
@@ -1217,30 +1132,6 @@ div.message-partheaders .headers-table td.header {
height: 100%;
}
-#messagepartheader {
- position: absolute;
- top: 42px;
- left: 0;
- width: 220px;
- bottom: 0;
-}
-
-#messagepartheader table {
- table-layout: fixed;
- overflow: hidden;
-}
-
-#messagepartheader table td {
- text-overflow: ellipsis;
- overflow: hidden;
-}
-
-#messagepartheader table td.title {
- width: 60px;
- padding-right: 0;
-}
-
-
/*** message composition ***/
#composeview-left {
@@ -1313,25 +1204,12 @@ div.message-partheaders .headers-table td.header {
}
#compose-contacts li a, #contacts-table td {
- background: url(images/listicons.png) -100px 0 no-repeat;
+ background: url(images/listicons.png?v=bd98.25486) -100px 0 no-repeat;
overflow: hidden;
padding-left: 36px;
text-overflow: ellipsis;
}
-#contacts-table td.contactgroup a {
- color: #376572;
- text-decoration: none;
-}
-
-#contacts-table td.contactgroup a span {
- display: inline-block;
- font-size: 16px;
- font-weight: bold;
- line-height: 11px;
- margin-left: 0.3em;
-}
-
#contacts-table tr:first-child td {
border-top: 0;
}
@@ -1538,7 +1416,7 @@ div.message-partheaders .headers-table td.header {
}
#compose-attachments.droptarget {
- background-image: url(images/filedrop.png);
+ background-image: url(images/filedrop.png?v=deab.605);
background-position: center bottom;
background-repeat: no-repeat;
}
diff --git a/skins/larry/settings.css b/skins/larry/settings.css
index 59037ac76..213a4cf9b 100644
--- a/skins/larry/settings.css
+++ b/skins/larry/settings.css
@@ -52,7 +52,7 @@
#settings-sections span.listitem a,
#settings-sections span.tablink a {
padding-left: 36px;
- background-image: url(images/listicons.png);
+ background-image: url(images/listicons.png?v=bd98.25486);
background-position: -100px 0;
background-repeat: no-repeat;
}
@@ -267,13 +267,3 @@ img.skinthumbnail {
.webkit #pluginlist td.source {
width: 9em;
}
-
-#rcmfd_signature {
- width: 99%;
- min-width: 390px;
-}
-
-#rcmfd_signature_toolbar1 td,
-#rcmfd_signature_toolbar2 td {
- width: auto;
-}
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index d542768b7..81e5421ad 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -14,7 +14,7 @@ body {
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
color: #333;
- background: url(images/linen.jpg) repeat #d1d5d8;
+ background: url(images/linen.jpg?v=0382.14157) repeat #d1d5d8;
margin: 0;
}
@@ -50,8 +50,6 @@ textarea {
input[type="text"]:focus,
input[type="password"]:focus,
-input[type="text"]:required,
-input[type="password"]:required,
input.button:focus,
textarea:focus {
border-color: #4787b1;
@@ -179,8 +177,7 @@ input.mainaction {
/** link buttons **/
-a.button,
-.buttongroup {
+a.button {
display: inline-block;
margin: 0 2px;
padding: 2px 5px;
@@ -201,11 +198,6 @@ a.button,
text-decoration: none;
}
-.buttongroup {
- padding: 0;
- white-space: nowrap;
-}
-
a.button:focus,
input.button:focus {
border-color: #4fadd5;
@@ -239,29 +231,6 @@ a.button.disabled span.inner {
filter: alpha(opacity=40);
}
-.buttongroup a.button {
- margin: 0;
- border-width: 0 1px 0 0;
- border-radius: 0;
- background: none;
- box-shadow: none;
- -o-box-shadow: none;
- -webkit-box-shadow: none;
- -moz-box-shadow: none;
-}
-
-.buttongroup a.button.first,
-.buttongroup a.button:first-child {
- border-radius: 4px 0 0 4px;
- border-left: 0;
-}
-
-.buttongroup a.button.last,
-.buttongroup a.button:last-child {
- border-radius: 0 4px 4px 0;
- border-right: 0;
-}
-
a.button.pressed,
a.button:active,
input.button:active {
@@ -297,21 +266,6 @@ input.button:active {
background: linear-gradient(top, #bababa 0%, #d8d8d8 100%);
}
-.buttongroup a.button.selected,
-.buttongroup a.button.selected:hover {
- background: #8a8a8a;
- background: -moz-linear-gradient(top, #909090 0%, #858585 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#909090), color-stop(100%,#858585));
- background: -o-linear-gradient(top, #909090 0%, #858585 100%);
- background: -ms-linear-gradient(top, #909090 0%, #858585 100%);
- background: linear-gradient(top, #909090 0%, #858585 100%);
- -webkit-box-shadow: inset 0 1px 2px 0 #555;
- -moz-box-shadow: inset 0 1px 2px 0 #555;
- box-shadow: inset 0 1px 2px 0 #555;
- border-right-color: #555;
- border-left-color: #555;
-}
-
.pagenav a.button {
padding: 1px 3px;
height: 16px;
@@ -319,19 +273,13 @@ input.button:active {
margin-bottom: 1px;
}
-.pagenav .buttongroup a.button,
-.pagenav .buttongroup a.button:hover {
- padding: 1px 5px;
- margin-bottom: 0;
-}
-
.pagenav a.button span.inner {
display: inline-block;
width: 16px;
height: 13px;
text-indent: 1000px;
overflow: hidden;
- background: url(images/buttons.png) -6px -211px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -6px -211px no-repeat;
}
.pagenav a.prevpage span.inner {
@@ -370,20 +318,6 @@ input.button:active {
background-position: -29px -271px;
}
-.pagenav a.changeformat.html span.inner {
- background-position: -7px -1859px;
-}
-.pagenav a.changeformat.html.selected span.inner {
- background-position: -29px -1859px;
-}
-
-.pagenav a.changeformat.text span.inner {
- background-position: -7px -1874px;
-}
-.pagenav a.changeformat.text.selected span.inner {
- background-position: -29px -1874px;
-}
-
.pagenav .countdisplay {
display: inline-block;
padding: 3px 1em 0 1em;
@@ -402,7 +336,7 @@ a.iconbutton {
height: 18px;
text-decoration: none;
text-indent: -5000px;
- background: url(images/buttons.png) -1000px 0 no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -1000px 0 no-repeat;
}
a.iconbutton.disabled {
@@ -429,7 +363,7 @@ a.iconlink {
text-decoration: none;
white-space: nowrap;
padding: 2px 8px 2px 20px;
- background: url(images/buttons.png) -1000px 0 no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -1000px 0 no-repeat;
}
a.iconlink:hover {
@@ -474,7 +408,7 @@ a.iconlink.upload {
padding: 6px 30px 6px 25px;
display: inline-block;
white-space: nowrap;
- background: url(images/messages.png) 0 5px no-repeat;
+ background: url(images/messages.png?v=01ee.1736) 0 5px no-repeat;
cursor: default;
}
@@ -494,7 +428,7 @@ a.iconlink.upload {
}
#message div.loading {
- background: url(images/ajaxloader.gif) 2px 6px no-repeat;
+ background: url(images/ajaxloader.gif?v=c252.1434) 2px 6px no-repeat;
}
#message div a,
@@ -532,7 +466,7 @@ a.iconlink.upload {
.ui-dialog.warning .ui-dialog-title,
.ui-dialog.confirmation .ui-dialog-title {
padding-left: 25px;
- background: url(images/messages.png) 0 5px no-repeat;
+ background: url(images/messages.png?v=01ee.1736) 0 5px no-repeat;
text-shadow: 0 1px 1px #fff;
}
@@ -580,7 +514,7 @@ a.iconlink.upload {
#topline {
height: 18px;
- background: url(images/linen_header.jpg) repeat #666;
+ background: url(images/linen_header.jpg?v=514a.580) repeat #666;
border-bottom: 1px solid #4f4f4f;
padding: 2px 0 2px 10px;
color: #aaa;
@@ -613,7 +547,6 @@ a.iconlink.upload {
#toplogo {
padding-top: 2px;
cursor: pointer;
- border: none;
}
.topleft {
@@ -642,7 +575,7 @@ a.iconlink.upload {
#topline a.button-logout {
display: inline-block;
padding: 2px 10px 2px 20px;
- background: url(images/buttons.png) -6px -193px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -6px -193px no-repeat;
color: #fff;
}
@@ -693,6 +626,17 @@ a.iconlink.upload {
opacity: 0.999;
}
+.partwin #topline {
+ position: absolute;
+ right: 6px;
+ top: 18px;
+ width: auto;
+ z-index: 100;
+ background: transparent;
+ background: none;
+ border: 0;
+}
+
.minimal #topline a.button-logout {
display: none;
}
@@ -799,7 +743,7 @@ a.iconlink.upload {
text-shadow: 0px 1px 1px black;
padding: 5px 0 0 34px;
height: 19px;
- background: url(images/buttons.png) -1000px 0 no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -1000px 0 no-repeat;
}
#taskbar a.button-selected {
@@ -851,7 +795,7 @@ a.iconlink.upload {
width: 19px;
height: 46px;
cursor: pointer;
- background: url(images/buttons.png) -35px -1778px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -35px -1778px no-repeat;
}
.minimal #taskbar .minmodetoggle {
@@ -875,6 +819,10 @@ a.iconlink.upload {
top: 102px;
}
+.partwin #mainscreen {
+ top: 60px
+}
+
.extwin #mainscreen {
top: 40px;
}
@@ -884,7 +832,7 @@ a.iconlink.upload {
}
#mainscreen .offset {
- top: 42px;
+ margin-top: 42px;
}
.uibox {
@@ -924,7 +872,7 @@ a.iconlink.upload {
}
.watermark {
- background-image: url(images/watermark.jpg);
+ background-image: url(images/watermark.jpg?v=e784.5000);
background-position: center;
background-repeat: no-repeat;
}
@@ -1047,19 +995,11 @@ ul.listing li {
background-color: #d9ecf4;
}
-ul.listing li ul {
- border-top: 1px solid #bbd3da;
-}
-
ul.listing li.droptarget,
table.listing tr.droptarget td {
background-color: #e8e798;
}
-.listbox table.listing {
- background-color: #d9ecf4;
-}
-
table.listing,
table.layout {
border: 0;
@@ -1071,32 +1011,6 @@ table.layout td {
vertical-align: top;
}
-ul.treelist li {
- position: relative;
-}
-
-ul.treelist li div.treetoggle {
- position: absolute;
- top: 13px;
- left: 19px;
- width: 13px;
- height: 13px;
- background: url(images/listicons.png) -3px -144px no-repeat;
- cursor: pointer;
-}
-
-ul.treelist li div.treetoggle.expanded {
- background-position: -3px -168px;
-}
-
-ul.treelist li.selected > div.collapsed {
- background-position: -23px -144px;
-}
-
-ul.treelist li.selected > div.expanded {
- background-position: -23px -168px;
-}
-
.listbox .boxfooter {
position: absolute;
bottom: 0;
@@ -1135,7 +1049,7 @@ ul.treelist li.selected > div.expanded {
width: 48px;
height: 35px;
text-indent: -5000px;
- background: url(images/buttons.png) -1000px 0 no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -1000px 0 no-repeat;
}
.boxfooter .listbutton.add .inner {
@@ -1199,7 +1113,7 @@ ul.treelist li.selected > div.expanded {
text-indent: 1000px;
vertical-align: bottom;
overflow: hidden;
- background: url(images/buttons.png) -4px -286px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -4px -286px no-repeat;
}
.boxpagenav a.icon.prevpage {
@@ -1393,7 +1307,7 @@ body.iframe .footerleft.floating:before,
left: 0;
width: 100%;
height: 6px;
- background: url(images/overflowshadow.png) top center no-repeat;
+ background: url(images/overflowshadow.png?v=8bb4.307) top center no-repeat;
}
.boxcontent {
@@ -1501,7 +1415,7 @@ ul.proplist li {
#login-form .box-inner {
width: 430px;
- background: url(images/linen_login.jpg) top left no-repeat #5c5c5c;
+ background: url(images/linen_login.jpg?v=0484.10363) top left no-repeat #5c5c5c;
margin: 0 50px;
padding: 10px 24px 24px 24px;
border: 1px solid #333;
@@ -1513,7 +1427,7 @@ ul.proplist li {
}
#login-form .box-bottom {
- background: url(images/login_shadow.png) top center no-repeat;
+ background: url(images/login_shadow.png?v=3337.1069) top center no-repeat;
margin-top: -3px;
padding-top: 10px;
}
@@ -1590,7 +1504,6 @@ ul.proplist li {
#login-form #logo {
margin-bottom: 20px;
- border: none;
}
#login-form #message {
@@ -1677,7 +1590,7 @@ ul.proplist li {
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
- background: url(images/buttons.png) -100px 0 no-repeat transparent;
+ background: url(images/buttons.png?v=abf1.36693) -100px 0 no-repeat transparent;
border: 0;
border-radius: 0;
}
@@ -1699,7 +1612,7 @@ ul.proplist li {
top: 0;
height: 42px;
width: 18px;
- background: url(images/buttons.png) 0 -1255px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) 0 -1255px no-repeat;
cursor: pointer;
}
@@ -1800,7 +1713,6 @@ ul.proplist li {
}
.toolbar a.button.export {
- min-width: 74px;
background-position: center -1054px;
}
@@ -1816,9 +1728,6 @@ ul.proplist li {
background-position: 0 -1745px;
}
-.toolbar a.button.download {
- background-position: center -1906px;
-}
a.menuselector {
display: inline-block;
@@ -1842,7 +1751,7 @@ a.menuselector .handle {
height: 20px;
line-height: 19px;
text-shadow: 0px 1px 1px #fff;
- background: url(images/selector.png) right center no-repeat;
+ background: url(images/selector.png?v=799c.181) right center no-repeat;
border-radius: 4px;
}
@@ -1865,7 +1774,6 @@ select.decorated {
filter: alpha(opacity=0);
-khtml-appearance: none;
-webkit-appearance: none;
- border: 0;
}
html.opera select.decorated {
@@ -1881,7 +1789,6 @@ select.decorated option {
text-shadow: 0px 1px 1px #333;
padding: 4px 6px;
outline: none;
- cursor: default;
}
@@ -1894,7 +1801,7 @@ select.decorated option {
text-shadow: 0px 1px 1px #fff;
padding-left: 30px;
height: 18px;
- background: url(images/quota.png) -100px 0 no-repeat;
+ background: url(images/quota.png?v=4835.3622) -100px 0 no-repeat;
}
/*** popup menus ***/
@@ -1990,7 +1897,7 @@ ul.toolbarmenu.selectable li a {
}
ul.toolbarmenu.selectable li a.selected {
- background: url(images/messages.png) 4px -27px no-repeat;
+ background: url(images/messages.png?v=01ee.1736) 4px -27px no-repeat;
}
ul.toolbarmenu li label {
@@ -2010,7 +1917,7 @@ ul.toolbarmenu li span.icon {
min-height: 14px;
padding: 4px 4px 1px 24px;
height: 17px;
- background-image: url(images/listicons.png);
+ background-image: url(images/listicons.png?v=bd98.25486);
background-position: -100px 0;
background-repeat: no-repeat;
opacity: 0.2;
@@ -2117,7 +2024,7 @@ ul.toolbarmenu li span.conversation {
-moz-user-select: none;
-khtml-user-select: none;
position: absolute;
- background: url(images/splitter.png) center no-repeat;
+ background: url(images/splitter.png?v=2724.136) center no-repeat;
}
.splitter-h {
@@ -2177,7 +2084,7 @@ ul.toolbarmenu li span.conversation {
content: " ";
width: 16px;
height: 16px;
- background: url(images/buttons.png) -7px -358px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -7px -358px no-repeat;
z-index: 255;
}
@@ -2195,7 +2102,7 @@ ul.toolbarmenu li span.conversation {
.attachmentslist li {
display: block;
position: relative;
- background: url(images/filetypes.png) 0 0 no-repeat;
+ background: url(images/filetypes.png?v=3aa2.8551) 0 0 no-repeat;
margin-bottom: 1px;
}
@@ -2292,23 +2199,13 @@ ul.toolbarmenu li span.conversation {
display: block;
color: #333;
font-weight: bold;
- padding: 8px 15px 3px 30px;
+ padding: 3px 4px 3px 30px;
text-shadow: 0px 1px 1px #fff;
text-decoration: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
-}
-
-.attachmentslist li a.drop {
- background: url(images/buttons.png) no-repeat scroll center -1570px;
- width: 14px;
- height: 20px;
- cursor: pointer;
- position: absolute;
- right: 0;
- top: 0;
- padding: 0;
+ line-height: 20px;
}
#compose-attachments ul li {
@@ -2320,20 +2217,20 @@ ul.toolbarmenu li span.conversation {
}
.attachmentslist li.uploading {
- background: url(images/ajaxloader.gif) 2px 6px no-repeat;
+ background: url(images/ajaxloader.gif?v=c252.1434) 2px 6px no-repeat;
}
.attachmentslist li a.delete,
.attachmentslist li a.cancelupload {
position: absolute;
- top: 6px;
+ top: 4px;
right: 0;
- width: 24px;
+ width: 20px;
height: 18px;
padding: 0;
text-decoration: none;
text-indent: -5000px;
- background: url(images/buttons.png) -7px -337px no-repeat;
+ background: url(images/buttons.png?v=abf1.36693) -7px -337px no-repeat;
}
.attachmentslist li a.cancelupload {
diff --git a/skins/larry/svggradients.css b/skins/larry/svggradients.css
index c40d44f4b..2172ac31a 100644
--- a/skins/larry/svggradients.css
+++ b/skins/larry/svggradients.css
@@ -29,8 +29,7 @@ input.button.mainaction:active {
background-image: url(svggradient.php?c=2a2e31;505050);
}
-a.button,
-.buttongroup {
+a.button {
background-image: url(svggradient.php?c=f9f9f9;e6e6e6);
}
@@ -48,10 +47,6 @@ input.button:active {
background-image: url(svggradient.php?c=bababa;d8d8d8);
}
-.buttongroup a.button.selected {
- background-image: url(svggradient.php?c=909090;858585);
-}
-
#message.statusbar {
background-image: url(svggradient.php?c=eaeaea;c8c8c8);
}
diff --git a/skins/larry/templates/about.html b/skins/larry/templates/about.html
index e2bd0b019..301c301a9 100644
--- a/skins/larry/templates/about.html
+++ b/skins/larry/templates/about.html
@@ -4,11 +4,7 @@
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
</head>
-<roundcube:if condition="request:_framed" />
-<body class="iframe fullheight">
-<roundcube:else />
<body class="ui-widget-content">
-<roundcube:endif />
<div class="readtext">
<roundcube:object name="aboutcontent" />
diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html
index b33ebd999..1c1647708 100644
--- a/skins/larry/templates/addressbook.html
+++ b/skins/larry/templates/addressbook.html
@@ -13,11 +13,7 @@
<!-- toolbar -->
<div id="addressbooktoolbar" class="toolbar">
<roundcube:button command="import" type="link" class="button import disabled" classAct="button import" classSel="button import pressed" label="import" title="importcontacts" />
- <span class="dropbutton">
- <roundcube:button command="export" type="link" class="button export disabled" classAct="button export" classSel="button export pressed" label="export" title="exportvcards" />
- <span class="dropbuttontip" id="exportmenulink" onclick="UI.show_popup('exportmenu');return false"></span>
- </span>
-
+ <roundcube:button command="export" type="link" class="button export disabled" classAct="button export" classSel="button export pressed" label="export" title="exportvcards" />
<span class="spacer"></span>
<roundcube:button command="compose" type="link" class="button compose disabled" classAct="button compose" classSel="button compose pressed" label="compose" title="writenewmessage" />
<roundcube:button command="advanced-search" type="link" class="button search disabled" classAct="button search" classSel="button search pressed" label="advanced" title="advsearch" />
@@ -30,7 +26,7 @@
<div id="directorylistbox" class="uibox listbox">
<h2 id="directorylist-header" class="boxtitle"><roundcube:label name="groups" /></h2>
<div id="directorylist-content" class="scroller withfooter">
- <roundcube:object name="directorylist" id="directorylist" class="treelist listing" />
+ <roundcube:object name="directorylist" id="directorylist" class="listing" />
</div>
<div id="directorylist-footer" class="boxfooter">
<roundcube:button command="group-create" type="link" title="newcontactgroup" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button name="groupoptions" id="groupoptionslink" type="link" title="moreactions" class="listbutton groupactions" onclick="UI.show_popup('groupoptions');return false" innerClass="inner" content="&#9881;" />
@@ -50,7 +46,7 @@
<!-- contacts list -->
<div id="addresslist" class="uibox listbox">
-<roundcube:object name="addresslisttitle" label="contacts" tag="h2" class="boxtitle" />
+<h2 class="boxtitle"><roundcube:label name="contacts" /></h2>
<div class="scroller withfooter">
<roundcube:object name="addresslist" id="contacts-table" class="listing" noheader="true" />
</div>
@@ -79,12 +75,6 @@
</div><!-- end mainscreen -->
-<div id="exportmenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button command="export" label="exportall" prop="sub" class="exportalllink" classAct="exportalllink active" /></li>
- <li><roundcube:button command="export-selected" label="exportsel" prop="sub" class="exportsellink" classAct="exportsellink active" /></li>
- </ul>
-</div>
<div id="searchmenu" class="popupmenu">
<ul class="toolbarmenu">
@@ -106,13 +96,6 @@
</ul>
</div>
-<div id="dragcontactmenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
- <li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
- </ul>
-</div>
-
<roundcube:include file="/includes/footer.html" />
</body>
diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html
index 806939a42..1e2a45912 100644
--- a/skins/larry/templates/compose.html
+++ b/skins/larry/templates/compose.html
@@ -65,7 +65,7 @@
<div id="composeview-right">
-<roundcube:form name="form" method="post" id="compose-content" class="uibox">
+<form name="form" action="./" method="post" id="compose-content" class="uibox">
<!-- message headers -->
<div id="composeheaders">
@@ -85,25 +85,25 @@
</tr><tr id="compose-cc">
<td class="title top">
<label for="_cc"><roundcube:label name="cc" /></label>
- <a href="#cc" onclick="return UI.hide_header_row('cc');" class="iconbutton cancel" title="<roundcube:label name='delete' />">x</a>
+ <a href="#cc" onclick="return UI.hide_header_row('cc');" class="iconbutton cancel" title="<roundcube:label name='delete' />" />x</a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="cc" form="form" id="_cc" cols="70" rows="1" tabindex="3" /></td>
</tr><tr id="compose-bcc">
<td class="title top">
<label for="_bcc"><roundcube:label name="bcc" /></label>
- <a href="#bcc" onclick="return UI.hide_header_row('bcc');" class="iconbutton cancel" title="<roundcube:label name='delete' />">x</a>
+ <a href="#bcc" onclick="return UI.hide_header_row('bcc');" class="iconbutton cancel" title="<roundcube:label name='delete' />" />x</a>
</td>
- <td class="editfield"><roundcube:object name="composeHeaders" part="bcc" form="form" id="_bcc" cols="70" rows="1" tabindex="4" /></td>
+ <td colspan="2" class="editfield"><roundcube:object name="composeHeaders" part="bcc" form="form" id="_bcc" cols="70" rows="1" tabindex="4" /></td>
</tr><tr id="compose-replyto">
<td class="title top">
<label for="_replyto"><roundcube:label name="replyto" /></label>
- <a href="#replyto" onclick="return UI.hide_header_row('replyto');" class="iconbutton cancel" title="<roundcube:label name='delete' />">x</a>
+ <a href="#replyto" onclick="return UI.hide_header_row('replyto');" class="iconbutton cancel" title="<roundcube:label name='delete' />" />x</a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="replyto" form="form" id="_replyto" size="70" tabindex="5" /></td>
</tr><tr id="compose-followupto">
<td class="title top">
<label for="_followupto"><roundcube:label name="followupto" /></label>
- <a href="#followupto" onclick="return UI.hide_header_row('followupto');" class="iconbutton cancel" title="<roundcube:label name='delete' />">x</a>
+ <a href="#followupto" onclick="return UI.hide_header_row('followupto');" class="iconbutton cancel" title="<roundcube:label name='delete' />" />x</a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="followupto" form="form" id="_followupto" size="70" tabindex="7" /></td>
</tr><tr>
@@ -140,9 +140,11 @@
<span class="composeoption">
<label><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" /> <roundcube:label name="returnreceipt" /></label>
</span>
+ <roundcube:if condition="config:smtp_server != ''" />
<span class="composeoption">
<label><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" /> <roundcube:label name="dsn" /></label>
</span>
+ <roundcube:endif />
<roundcube:if condition="!config:no_save_sent_messages" />
<span class="composeoption">
<label><roundcube:label name="savesentmessagein" /> <roundcube:object name="storetarget" maxlength="30" style="max-width:12em" /></label>
@@ -185,7 +187,7 @@
</div><!-- end mainscreen -->
<div id="upload-dialog" class="propform popupdialog" title="<roundcube:label name='addattachment' />">
- <roundcube:object name="composeAttachmentForm" id="uploadform" buttons="no" />
+ <roundcube:object name="composeAttachmentForm" id="uploadform" attachmentFieldSize="40" buttons="no" />
<div class="formbuttons">
<roundcube:button command="send-attachment" type="input" class="button mainaction" label="upload" />
<roundcube:button name="close" type="input" class="button" label="cancel" onclick="UI.show_uploadform()" />
diff --git a/skins/larry/templates/contact.html b/skins/larry/templates/contact.html
index 59fe6f79f..d252049cd 100644
--- a/skins/larry/templates/contact.html
+++ b/skins/larry/templates/contact.html
@@ -13,7 +13,7 @@
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
<roundcube:endif />
- <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" placeholderGroup="/images/contactgroup.png" /></div>
+ <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /></div>
<roundcube:object name="contacthead" id="contacthead" />
<br style="clear:both" />
diff --git a/skins/larry/templates/contactedit.html b/skins/larry/templates/contactedit.html
index 3467ebe8e..f84936635 100644
--- a/skins/larry/templates/contactedit.html
+++ b/skins/larry/templates/contactedit.html
@@ -11,7 +11,7 @@
<roundcube:else /><roundcube:label name="editcontact" />
<roundcube:endif /></h1>
-<roundcube:form name="editform" method="post" id="contact-details" class="boxcontent">
+<form name="editform" method="post" action="./" id="contact-details" class="boxcontent">
<roundcube:if condition="strlen(env:sourcename)" />
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" condition="env:action!='add'" /><roundcube:object name="sourceselector" id="sourceselect" condition="env:action=='add'" /></div>
<roundcube:endif />
diff --git a/skins/larry/templates/importcontacts.html b/skins/larry/templates/importcontacts.html
index d3d0f2b93..89aea0a2e 100644
--- a/skins/larry/templates/importcontacts.html
+++ b/skins/larry/templates/importcontacts.html
@@ -14,18 +14,19 @@
<roundcube:button command="list" type="link" class="button back disabled" classAct="button back" classSel="button back pressed" label="back" />
</div>
-<div id="pluginbody" class="offset uibox contentbox">
+<div class="offset uibox contentbox">
<h2 class="boxtitle"><roundcube:label name="importcontacts" /></h2>
-<div id="import-box" class="boxcontent">
+<div class="boxcontent readtext">
<roundcube:object name="importstep" />
+
<br/>
+
<p class="formbuttons">
<roundcube:object name="importnav" class="button" />
</p>
-</div>
-<roundcube:object name="message" id="message" class="statusbar" />
+</div>
</div>
diff --git a/skins/larry/templates/login.html b/skins/larry/templates/login.html
index 13e919ad3..a605eb7fe 100644
--- a/skins/larry/templates/login.html
+++ b/skins/larry/templates/login.html
@@ -9,9 +9,9 @@
<div id="login-form">
<div class="box-inner">
-<roundcube:object name="logo" src="/images/roundcube_logo.png" id="logo" />
+<roundcube:object name="logo" src="/images/roundcube_logo.png" id="logo" border="0" />
-<roundcube:form name="form" method="post">
+<form name="form" action="./" method="post">
<roundcube:object name="loginform" form="form" size="40" />
<p class="formbuttons"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>
diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html
index f2c52c820..4b8f03951 100644
--- a/skins/larry/templates/mail.html
+++ b/skins/larry/templates/mail.html
@@ -30,7 +30,7 @@
<div id="folderlist-header"></div>
<div id="mailboxcontainer" class="uibox listbox">
<div id="folderlist-content" class="scroller withfooter">
-<roundcube:object name="mailboxlist" id="mailboxlist" class="treelist listing" folder_filter="mail" unreadwrap="%s" />
+<roundcube:object name="mailboxlist" id="mailboxlist" class="listing" folder_filter="mail" unreadwrap="%s" />
</div>
<div id="folderlist-footer" class="boxfooter">
<roundcube:button name="mailboxmenulink" id="mailboxmenulink" type="link" title="folderactions" class="listbutton groupactions" onclick="UI.show_popup('mailboxmenu');return false" innerClass="inner" content="&#9881;" />
@@ -70,7 +70,7 @@
<div id="messagelistcontainer" class="boxlistcontent">
<roundcube:object name="messages"
id="messagelist"
- class="records-table messagelist sortheader fixedheader"
+ class="records-table sortheader"
optionsmenuIcon="true" />
</div>
@@ -140,7 +140,7 @@
<div id="dragmessagemenu" class="popupmenu">
<ul class="toolbarmenu">
- <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
+ <li><roundcube:button command="moveto" onclick="return rcmail.drag_menu_action('moveto')" label="move" classAct="active" /></li>
<li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
</ul>
</div>
@@ -148,8 +148,7 @@
<div id="mailboxmenu" class="popupmenu">
<ul class="toolbarmenu" id="mailboxoptionsmenu">
<li><roundcube:button command="expunge" type="link" label="compact" classAct="active" /></li>
- <li><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
- <li><roundcube:button name="messageimport" type="link" class="active" label="importmessages" onclick="UI.show_uploadform()" /></li>
+ <li class="separator_below"><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
<li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<roundcube:container name="mailboxoptions" id="mailboxoptionsmenu" />
</ul>
@@ -227,14 +226,6 @@
</div>
</div>
-<div id="upload-dialog" class="propform popupdialog" title="<roundcube:label name='importmessages' />">
- <roundcube:object name="messageimportform" id="uploadform" buttons="no" />
- <div class="formbuttons">
- <roundcube:button command="import-messages" type="input" class="button mainaction" label="upload" />
- <roundcube:button name="close" type="input" class="button" label="cancel" onclick="UI.show_uploadform()" />
- </div>
-</div>
-
<roundcube:include file="/includes/footer.html" />
</body>
diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html
index 6937b00af..5ac079c96 100644
--- a/skins/larry/templates/message.html
+++ b/skins/larry/templates/message.html
@@ -17,7 +17,7 @@
<roundcube:endif />
<roundcube:include file="/includes/mailtoolbar.html" />
<div class="toolbarselect">
- <roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('move', this.options[this.selectedIndex].value)" class="mailboxlist decorated" folder_filter="mail" />
+ <roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mailboxlist decorated" folder_filter="mail" />
</div>
</div>
@@ -28,7 +28,7 @@
<!-- folders list -->
<div id="mailboxcontainer" class="uibox listbox">
<div class="scroller">
-<roundcube:object name="mailboxlist" id="mailboxlist" class="treelist listing" folder_filter="mail" unreadwrap="%s" />
+<roundcube:object name="mailboxlist" id="mailboxlist" class="listing" folder_filter="mail" unreadwrap="%s" />
</div>
</div>
@@ -56,21 +56,6 @@
<roundcube:button command="nextmessage" type="link" class="button nextpage disabled" classAct="button nextpage" classSel="button nextpage pressed" innerClass="inner" title="nextmessage" content="&amp;gt;" />
</div>
-<roundcube:if condition="env:optional_format=='text'" />
-<div class="pagenav" id="formatcontrols">
- <span class="buttongroup">
- <roundcube:button command="change-format" prop="html" type="link" class="button first changeformat html selected" innerClass="inner" title="changeformathtml" /><roundcube:button command="change-format" prop="text" type="link" class="button last changeformat text" classSel="button last changeformat text pressed" innerClass="inner" title="changeformattext" />
- </span>
-</div>
-<roundcube:elseif condition="env:optional_format=='html'" />
-<div class="pagenav" id="formatcontrols">
- <span class="buttongroup">
- <roundcube:button command="change-format" prop="html" type="link" class="button first changeformat html" classSel="button first changeformat html pressed" innerClass="inner" title="changeformathtml" /><roundcube:button command="change-format" prop="text" type="link" class="button last changeformat text selected" innerClass="inner" title="changeformattext" />
- </span>
-</div>
-<roundcube:endif />
-
-
<div id="contactphoto"><roundcube:object name="contactphoto" /></div>
</div>
@@ -90,14 +75,6 @@
</div><!-- end mainscreen -->
-<div id="attachmentmenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="icon" classAct="icon active" innerclass="icon extwin" /></li>
- <li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="icon" classAct="icon active" innerclass="icon download" /></li>
- <roundcube:container name="attachmentmenu" id="attachmentmenu" />
- </ul>
-</div>
-
<roundcube:include file="/includes/footer.html" />
</body>
diff --git a/skins/larry/templates/messageerror.html b/skins/larry/templates/messageerror.html
index a735d47f2..3c3c9acdb 100644
--- a/skins/larry/templates/messageerror.html
+++ b/skins/larry/templates/messageerror.html
@@ -28,7 +28,7 @@
<!-- folders list -->
<div id="mailboxcontainer" class="uibox listbox">
<div class="scroller">
- <roundcube:object name="mailboxlist" id="mailboxlist" class="treelist listing" folder_filter="mail" unreadwrap="%s" />
+ <roundcube:object name="mailboxlist" id="mailboxlist" class="listing" folder_filter="mail" unreadwrap="%s" />
</div>
</div>
diff --git a/skins/larry/templates/messagepart.html b/skins/larry/templates/messagepart.html
index d0e3a808d..dbb4940de 100644
--- a/skins/larry/templates/messagepart.html
+++ b/skins/larry/templates/messagepart.html
@@ -4,35 +4,33 @@
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
</head>
-<body class="extwin noscroll">
+<body class="partwin">
-<roundcube:include file="/includes/header.html" />
+<div id="header">
+<div id="topline">
+ <div class="topright">
+ <a href="#close" class="closelink" onclick="self.close()"><roundcube:label name="close" /></a>
+ </div>
+</div>
-<div id="mainscreen">
+<div id="topnav">
+ <roundcube:object name="logo" src="/images/roundcube_logo.png" id="toplogo" border="0" alt="Logo" />
+</div>
-<div id="messagetoolbar" class="toolbar fullwidth">
- <roundcube:button command="download" type="link" class="button download disabled" classAct="button download" classSel="button download pressed" label="download" />
- <roundcube:button command="print" type="link" class="button print disabled" classAct="button print" classSel="button print pressed" label="print" />
- <roundcube:container name="toolbar" id="messagetoolbar" />
+<br style="clear:both" />
</div>
-<div id="messagepartheader" class="uibox listbox">
- <h2 class="boxtitle"><roundcube:label name="properties" /></h2>
- <div class="scroller">
- <roundcube:object name="messagePartControls" class="listing" />
- </div>
+<div id="mainscreen">
+
+<div id="partheader" class="uibox">
+<roundcube:object name="messagePartControls" class="headers-table" />
</div>
<div id="messagepartcontainer" class="uibox">
- <div class="iframebox">
- <roundcube:object name="messagePartFrame" id="messagepartframe" frameborder="0" />
- </div>
- <roundcube:object name="message" id="message" class="statusbar" />
+<roundcube:object name="messagePartFrame" id="messagepartframe" frameborder="0" />
</div>
</div>
-<roundcube:include file="/includes/footer.html" />
-
</body>
</html>
diff --git a/skins/larry/templates/messagepreview.html b/skins/larry/templates/messagepreview.html
index f69f65125..aef282ac9 100644
--- a/skins/larry/templates/messagepreview.html
+++ b/skins/larry/templates/messagepreview.html
@@ -30,17 +30,6 @@
<!-- record navigation -->
<div id="countcontrols" class="pagenav">
-<roundcube:if condition="env:optional_format=='text'" />
- <span class="buttongroup">
- <roundcube:button command="change-format" prop="html" type="link" class="button first changeformat html selected" innerClass="inner" title="changeformathtml" content="HTML" /><roundcube:button command="change-format" prop="text" type="link" class="button last changeformat text" classSel="button changeformat text pressed" innerClass="inner" title="changeformattext" content="Text" />
- </span>
- &nbsp;
-<roundcube:elseif condition="env:optional_format=='html'" />
- <span class="buttongroup">
- <roundcube:button command="change-format" prop="html" type="link" class="button first changeformat html" classSel="button changeformat html pressed" innerClass="inner" title="changeformathtml" content="HTML" /><roundcube:button command="change-format" prop="text" type="link" class="button last changeformat text selected" innerClass="inner" title="changeformattext" content="Text" />
- </span>
- &nbsp;
-<roundcube:endif />
<roundcube:if condition="env:mailbox != config:drafts_mbox">
<roundcube:button command="reply" type="link" class="button reply" classSel="button reply pressed" innerClass="inner" title="replytomessage" content="&lt;-" />
<roundcube:button command="reply-all" type="link" class="button replyall" classSel="button replyall pressed" innerClass="inner" title="replytoallmessage" content="&lt;&lt;-" />
@@ -62,14 +51,6 @@
</div>
</div>
-<div id="attachmentmenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="icon" classAct="icon active" innerclass="icon extwin" /></li>
- <li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="icon" classAct="icon active" innerclass="icon download" /></li>
- <roundcube:container name="attachmentmenu" id="attachmentmenu" />
- </ul>
-</div>
-
<roundcube:include file="/includes/footer.html" />
</body>
diff --git a/skins/larry/templates/responseedit.html b/skins/larry/templates/responseedit.html
new file mode 100644
index 000000000..8f180fe7f
--- /dev/null
+++ b/skins/larry/templates/responseedit.html
@@ -0,0 +1,22 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+</head>
+<body class="iframe">
+
+<h1 class="boxtitle"><roundcube:object name="steptitle" /></h1>
+
+<div id="preferences-details" class="boxcontent">
+<roundcube:object name="responseform" class="propform" size="60" textareacols="60" textarearows="18" />
+</div>
+
+<div class="footerleft formbuttons">
+ <roundcube:button command="save" type="input" class="button mainaction" label="save" condition="!env:readonly" />
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html>
diff --git a/skins/larry/templates/responses.html b/skins/larry/templates/responses.html
new file mode 100644
index 000000000..fb40048c8
--- /dev/null
+++ b/skins/larry/templates/responses.html
@@ -0,0 +1,41 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+</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="identitieslist" class="uibox listbox">
+<h2 class="boxtitle"><roundcube:label name="responses" /></h2>
+<div class="scroller withfooter">
+<roundcube:object name="responsesList" id="identities-table" class="listing" cellspacing="0" summary="Responses list" noheader="true" />
+</div>
+<div class="boxfooter">
+<roundcube:button command="add" type="link" title="savenewresponse" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button command="delete" type="link" title="delete" class="listbutton delete disabled" classAct="listbutton delete" innerClass="inner" content="-" />
+</div>
+</div>
+
+<div id="identity-details" class="uibox contentbox">
+ <div class="iframebox">
+ <roundcube:object name="responseframe" 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" />
+
+</body>
+</html>
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index ae14d81b2..19f8a516a 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -17,9 +17,8 @@ function rcube_mail_ui()
var popupconfig = {
forwardmenu: { editable:1 },
searchmenu: { editable:1, callback:searchmenu },
- attachmentmenu: { },
listoptions: { editable:1 },
- dragmenu: { sticky:1 },
+ dragmessagemenu: { sticky:1 },
groupmenu: { above:1 },
mailboxmenu: { above:1 },
spellmenu: { callback: spellmenu },
@@ -38,12 +37,10 @@ function rcube_mail_ui()
this.init_tabs = init_tabs;
this.show_about = show_about;
this.show_popup = show_popup;
- this.add_popup = add_popup;
this.set_searchmod = set_searchmod;
this.show_uploadform = show_uploadform;
this.show_header_row = show_header_row;
this.hide_header_row = hide_header_row;
- this.update_quota = update_quota;
// set minimal mode on small screens (don't wait for document.ready)
@@ -88,26 +85,20 @@ function rcube_mail_ui()
/*** mail task ***/
if (rcmail.env.task == 'mail') {
- rcmail.addEventListener('menu-open', menu_open);
- rcmail.addEventListener('menu-save', menu_save);
+ rcmail.addEventListener('menu-open', show_listoptions);
+ rcmail.addEventListener('menu-save', save_listoptions);
rcmail.addEventListener('responseafterlist', function(e){ switch_view_mode(rcmail.env.threading ? 'thread' : 'list') });
var dragmenu = $('#dragmessagemenu');
if (dragmenu.length) {
- rcmail.gui_object('dragmenu', 'dragmessagemenu');
- popups.dragmenu = dragmenu;
+ rcmail.gui_object('message_dragmenu', 'dragmessagemenu');
+ popups.dragmessagemenu = dragmenu;
}
if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') {
- rcmail.addEventListener('enable-command', enable_command);
rcmail.addEventListener('aftershow-headers', function() { layout_messageview(); });
rcmail.addEventListener('afterhide-headers', function() { layout_messageview(); });
- $('#previewheaderstoggle').click(function(e){ toggle_preview_headers(); return false });
-
- // add menu link for each attachment
- $('#attachment-list > li').each(function() {
- $(this).append($('<a class="drop">').click(function() { attachmentmenu(this); }));
- });
+ $('#previewheaderstoggle').click(function(e){ toggle_preview_headers(this); return false });
}
else if (rcmail.env.action == 'compose') {
rcmail.addEventListener('aftertoggle-editor', function(){ window.setTimeout(function(){ layout_composeview() }, 200); });
@@ -116,14 +107,10 @@ function rcube_mail_ui()
layout_composeview();
// Show input elements with non-empty value
- var f, v, field, fields = ['cc', 'bcc', 'replyto', 'followupto'];
- for (f=0; f < fields.length; f++) {
- v = fields[f]; field = $('#_'+v);
- if (field.length) {
- field.on('change', {v: v}, function(e) { if (this.value) show_header_row(e.data.v, true); });
- if (field.val() != '')
- show_header_row(v, true);
- }
+ var field, fields = ['cc', 'bcc', 'replyto', 'followupto'];
+ for (var f=0; f < fields.length; f++) {
+ if ((field = $('#_'+fields[f])) && field.length && field.val() != '')
+ show_header_row(fields[f], true);
}
$('#composeoptionstoggle').click(function(){
@@ -155,12 +142,6 @@ function rcube_mail_ui()
new rcube_scroller('#folderlist-content', '#folderlist-header', '#folderlist-footer');
rcmail.addEventListener('setquota', update_quota);
- rcmail.addEventListener('enable-command', enable_command);
- rcmail.addEventListener('afterimport-messages', show_uploadform);
- }
- else if (rcmail.env.action == 'get') {
- new rcube_splitter({ id:'mailpartsplitterv', p1:'#messagepartheader', p2:'#messagepartcontainer',
- orientation:'v', relative:true, start:226, min:150, size:12}).init();
}
if ($('#mailview-left').length) {
@@ -199,8 +180,6 @@ function rcube_mail_ui()
/*** addressbook task ***/
else if (rcmail.env.task == 'addressbook') {
rcmail.addEventListener('afterupload-photo', show_uploadform);
- rcmail.addEventListener('beforepushgroup', push_contactgroup);
- rcmail.addEventListener('beforepopgroup', pop_contactgroup);
if (rcmail.env.action == '') {
new rcube_splitter({ id:'addressviewsplitterd', p1:'#addressview-left', p2:'#addressview-right',
@@ -210,12 +189,12 @@ function rcube_mail_ui()
new rcube_scroller('#directorylist-content', '#directorylist-header', '#directorylist-footer');
}
+ }
- var dragmenu = $('#dragcontactmenu');
- if (dragmenu.length) {
- rcmail.gui_object('dragmenu', 'dragcontactmenu');
- popups.dragmenu = dragmenu;
- }
+ // set min-width to show all toolbar buttons
+ var screen = $('.minwidth');
+ if (screen.length) {
+ screen.css('min-width', $('.toolbar').width() + $('#quicksearchbar').parent().width() + 20);
}
// turn a group of fieldsets into tabs
@@ -229,7 +208,6 @@ function rcube_mail_ui()
}
var select = $(this),
- parent = select.parent(),
height = Math.max(select.height(), 26) - 2,
width = select.width() - 22,
title = $('option', this).first().text();
@@ -244,23 +222,19 @@ function rcube_mail_ui()
overlay.children().width(width).height(height).css('line-height', (height - 1) + 'px');
+ select.change(function() {
+ var val = $('option:selected', this).text();
+ $(this).next().children().html(val);
+ });
+
+ var parent = select.parent();
if (parent.css('position') != 'absolute')
parent.css('position', 'relative');
// re-set original select width to fix click action and options width in some browsers
- select.width(overlay.width())
- .change(function() {
- var val = $('option:selected', this).text();
- $(this).next().children().text(val);
- });
+ select.width(overlay.width());
});
- // set min-width to show all toolbar buttons
- var screen = $('body > div.minwidth');
- if (screen.length) {
- screen.css('min-width', $('.toolbar').width() + $('#quicksearchbar').width() + $('#searchfilter').width() + 30);
- }
-
$(document.body)
.bind('mouseup', body_mouseup)
.bind('keyup', function(e){
@@ -316,36 +290,28 @@ function rcube_mail_ui()
/**
* Update UI on window resize
*/
- function resize(e)
+ function resize()
{
- // resize in intervals to prevent lags and double onresize calls in Chrome (#1489005)
- var interval = e ? 10 : 0;
-
- if (rcmail.resize_timeout)
- window.clearTimeout(rcmail.resize_timeout);
+ if (rcmail.env.task == 'mail') {
+ if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
+ layout_messageview();
+ else if (rcmail.env.action == 'compose')
+ layout_composeview();
+ }
- rcmail.resize_timeout = window.setTimeout(function() {
- if (rcmail.env.task == 'mail') {
- if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
- layout_messageview();
- else if (rcmail.env.action == 'compose')
- layout_composeview();
+ // make iframe footer buttons float if scrolling is active
+ $('body.iframe .footerleft').each(function(){
+ var footer = $(this),
+ body = $(document.body),
+ floating = footer.hasClass('floating'),
+ overflow = body.outerHeight(true) > $(window).height();
+
+ if (overflow != floating) {
+ var action = overflow ? 'addClass' : 'removeClass';
+ footer[action]('floating');
+ body[action]('floatingbuttons');
}
-
- // make iframe footer buttons float if scrolling is active
- $('body.iframe .footerleft').each(function(){
- var footer = $(this),
- body = $(document.body),
- floating = footer.hasClass('floating'),
- overflow = body.outerHeight(true) > $(window).height();
-
- if (overflow != floating) {
- var action = overflow ? 'addClass' : 'removeClass';
- footer[action]('floating');
- body[action]('floatingbuttons');
- }
- });
- }, interval);
+ });
}
/**
@@ -458,30 +424,6 @@ function rcube_mail_ui()
}
- function enable_command(p)
- {
- if (p.command == 'reply-list') {
- var label = rcmail.gettext(p.status ? 'replylist' : 'replyall');
- if (rcmail.env.action == 'preview')
- $('a.button.replyall').attr('title', label);
- else
- $('a.button.reply-all').text(label).attr('title', label);
- }
- }
-
-
- /**
- * Register a popup menu
- */
- function add_popup(popup, config)
- {
- var obj = popups[popup] = $('#'+popup);
- obj.appendTo(document.body); // move it to top for proper absolute positioning
-
- if (obj.length)
- popupconfig[popup] = $.extend(popupconfig[popup] || {}, config || {});
- }
-
/**
* Trigger for popup menus
*/
@@ -489,7 +431,7 @@ function rcube_mail_ui()
{
// auto-register menu object
if (config || !popupconfig[popup])
- add_popup(popup, config);
+ popupconfig[popup] = $.extend(popupconfig[popup] || {}, config);
var visible = show_popupmenu(popup, show),
config = popupconfig[popup];
@@ -504,7 +446,7 @@ function rcube_mail_ui()
{
var obj = popups[popup],
config = popupconfig[popup],
- ref = $(config.link ? config.link : '#'+popup+'link'),
+ ref = $('#'+popup+'link'),
above = config.above;
if (!obj) {
@@ -520,7 +462,7 @@ function rcube_mail_ui()
else if (config.toggle && show && obj.is(':visible'))
show = false;
- if (show && ref.length) {
+ if (show && ref) {
var parent = ref.parent(),
win = $(window),
pos;
@@ -604,11 +546,8 @@ function rcube_mail_ui()
mailviewsplit.handle.hide();
}
- if (rcmail.message_list) {
- if (visible && uid)
- rcmail.message_list.scrollto(uid);
- rcmail.message_list.resize();
- }
+ if (visible && uid && rcmail.message_list)
+ rcmail.message_list.scrollto(uid);
rcmail.command('save-pref', { name:'preview_pane', value:(visible?1:0) });
}
@@ -617,7 +556,7 @@ function rcube_mail_ui()
/**
* Switch between short and full headers display in message preview
*/
- function toggle_preview_headers()
+ function toggle_preview_headers(button)
{
$('#preview-shortheaders').toggle();
var full = $('#preview-allheaders').toggle(),
@@ -646,19 +585,6 @@ function rcube_mail_ui()
/**** popup callbacks ****/
- function menu_open(p)
- {
- if (p && p.props && p.props.menu == 'attachmentmenu')
- show_popupmenu('attachmentmenu');
- else
- show_listoptions();
- }
-
- function menu_save(prop)
- {
- save_listoptions();
- }
-
function searchmenu(show)
{
if (show && rcmail.env.search_mods) {
@@ -689,21 +615,6 @@ function rcube_mail_ui()
}
}
- function attachmentmenu(elem)
- {
- var id = elem.parentNode.id.replace(/^attach/, '');
-
- $('#attachmenuopen').unbind('click').attr('onclick', '').click(function(e) {
- return rcmail.command('open-attachment', id, this);
- });
-
- $('#attachmenudownload').unbind('click').attr('onclick', '').click(function() {
- rcmail.command('download-attachment', id, this);
- });
-
- popupconfig.attachmentmenu.link = elem;
- rcmail.command('menu-open', {menu: 'attachmentmenu', id: id});
- }
function spellmenu(show)
{
@@ -772,8 +683,7 @@ function rcube_mail_ui()
close: function() {
$dialog.dialog('destroy').hide();
},
- minWidth: 500,
- width: $dialog.width()+25
+ width: 650
}).show();
}
@@ -842,35 +752,6 @@ function rcube_mail_ui()
});
}
- function push_contactgroup(p)
- {
- // lets the contacts list swipe to the left, nice!
- var table = $('#contacts-table'),
- scroller = table.parent().css('overflow', 'hidden');
-
- table.clone()
- .css({ position:'absolute', top:'0', left:'0', width:table.width()+'px', 'z-index':10 })
- .appendTo(scroller)
- .animate({ left: -(table.width()+5) + 'px' }, 300, 'swing', function(){
- $(this).remove();
- scroller.css('overflow', 'auto')
- });
- }
-
- function pop_contactgroup(p)
- {
- // lets the contacts list swipe to the left, nice!
- var table = $('#contacts-table'),
- scroller = table.parent().css('overflow', 'hidden'),
- clone = table.clone().appendTo(scroller);
-
- table.css({ position:'absolute', top:'0', left:-(table.width()+5) + 'px', width:table.width()+'px', height:table.height()+'px', 'z-index':10 })
- .animate({ left:'0' }, 300, 'linear', function(){
- clone.remove();
- $(this).css({ position:'relative', left:'0', width:'100%', height:'auto', 'z-index':1 });
- scroller.css('overflow', 'auto')
- });
- }
function show_uploadform()
{
@@ -881,7 +762,7 @@ function rcube_mail_ui()
$dialog.dialog('close');
return;
}
-
+
// add icons to clone file input field
if (rcmail.env.action == 'compose' && !$dialog.data('extended')) {
$('<a>')
diff --git a/skins/larry/watermark.html b/skins/larry/watermark.html
index d1061d1f3..af28d6940 100644
--- a/skins/larry/watermark.html
+++ b/skins/larry/watermark.html
@@ -9,7 +9,7 @@ html, body {
}
body {
- background: url(images/watermark.jpg) center no-repeat #fff;
+ background: url(images/watermark.jpg?v=e784.5000) center no-repeat #fff;
}
</style>
diff --git a/temp/.htaccess b/temp/.htaccess
deleted file mode 100644
index 8e6a345dc..000000000
--- a/temp/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-Order allow,deny
-Deny from all \ No newline at end of file
diff --git a/tests/Framework/Browser.php b/tests/Framework/Browser.php
index c3860d8a3..832d4bf14 100644
--- a/tests/Framework/Browser.php
+++ b/tests/Framework/Browser.php
@@ -17,4 +17,207 @@ class Framework_Browser extends PHPUnit_Framework_TestCase
$this->assertInstanceOf('rcube_browser', $object, "Class constructor");
}
+
+ /**
+ * @dataProvider browsers
+ */
+ function test_browser($useragent, $opera, $chrome, $ie, $ns, $ns4, $khtml, $safari, $mz)
+ {
+
+ $object = $this->getBrowser($useragent);
+
+ $this->assertEquals($opera, $object->opera, 'Check for Opera failed');
+ $this->assertEquals($chrome, $object->chrome, 'Check for Chrome failed');
+ $this->assertEquals($ie, $object->ie, 'Check for IE failed');
+ $this->assertEquals($ns, $object->ns, 'Check for NS failed');
+ $this->assertEquals($ns4, $object->ns4, 'Check for NS4 failed');
+ $this->assertEquals($khtml, $object->khtml, 'Check for khtml failed');
+ $this->assertEquals($safari, $object->safari, 'Check for Safari failed');
+ $this->assertEquals($mz, $object->mz, 'Check for MZ failed');
+ }
+
+ /**
+ * @dataProvider os
+ */
+ function test_os($useragent, $windows, $linux, $unix, $mac)
+ {
+ $object = $this->getBrowser($useragent);
+
+ $this->assertEquals($windows, $object->win, 'Check Result of Windows');
+ $this->assertEquals($linux, $object->linux, 'Check Result of Linux');
+ $this->assertEquals($mac, $object->mac, 'Check Result of Mac');
+ $this->assertEquals($unix, $object->unix, 'Check Result of Unix');
+
+ }
+
+ /**
+ * @dataProvider versions
+ */
+ function test_version($useragent, $version)
+ {
+ $object = $this->getBrowser($useragent);
+ $this->assertEquals($version, $object->ver);
+ }
+
+ /**
+ * @dataProvider dom
+ */
+ function test_dom($useragent, $dom)
+ {
+ $object = $this->getBrowser($useragent);
+ $this->assertEquals($dom, $object->dom);
+
+ }
+
+ /**
+ * @dataProvider pngalpha
+ */
+ function test_pngalpha($useragent, $pngalpha)
+ {
+ $object = $this->getBrowser($useragent);
+ $this->assertEquals($pngalpha, $object->pngalpha);
+ }
+
+ /**
+ * @dataProvider imgdata
+ */
+ function test_imgdata($useragent, $imgdata)
+ {
+ $object = $this->getBrowser($useragent);
+ $this->assertEquals($imgdata, $object->imgdata);
+ }
+
+ function versions()
+ {
+ return $this->extractDataSet(array('version'));
+ }
+
+ function pngalpha()
+ {
+ return $this->extractDataSet(array('canPNGALPHA'));
+ }
+
+ function imgdata()
+ {
+ return $this->extractDataSet(array('canIMGDATA'));
+ }
+
+ private function extractDataSet($keys)
+ {
+ $keys = array_merge(array('useragent'), $keys);
+
+ $browser = $this->useragents();
+
+ $extracted = array();
+
+ foreach ($browser as $label => $data) {
+ foreach($keys as $key) {
+ $extracted[$data['useragent']][] = $data[$key];
+ }
+
+ }
+
+ return $extracted;
+ }
+
+ function lang()
+ {
+ return $this->extractDataSet(array('lang'));
+ }
+
+ function dom()
+ {
+ return $this->extractDataSet(array('hasDOM'));
+ }
+
+ function browsers()
+ {
+ return $this->extractDataSet(array('isOpera','isChrome','isIE','isNS','isNS4','isKHTML','isSafari','isMZ'));
+ }
+
+ function useragents()
+ {
+ return array(
+ 'WIN: Mozilla Firefox ' => array(
+ 'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1',
+ 'version' => '1.8', //Version
+ 'isWin' => true, //isWindows
+ 'isLinux' => false,
+ 'isMac' => false, //isMac
+ 'isUnix' => false, //isUnix
+ 'isOpera' => false, //isOpera
+ 'isChrome' => false, //isChrome
+ 'isIE' => false, //isIE
+ 'isNS' => false, //isNS
+ 'isNS4' => false, //isNS4
+ 'isKHTML' => false, //isKHTML
+ 'isSafari' => false, //isSafari
+ 'isMZ' => true, //isMZ
+ 'lang' => 'en-US', //lang
+ 'hasDOM' => true, //hasDOM
+ 'canPNGALPHA' => true, //canPNGALPHA
+ 'canIMGDATA' => true, //canIMGDATA
+ ),
+ 'LINUX: Bon Echo ' => array(
+ 'useragent' => 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.1) Gecko/20070222 BonEcho/2.0.0.1',
+ 'version' => '1.8', //Version
+ 'isWin' => false, //isWindows
+ 'isLinux' => true,
+ 'isMac' => false, //isMac
+ 'isUnix' => false, //isUnix
+ 'isOpera' => false, //isOpera
+ 'isChrome' => false, //isChrome
+ 'isIE' => false, //isIE
+ 'isNS' => false, //isNS
+ 'isNS4' => false, //isNS4
+ 'isKHTML' => false, //isKHTML
+ 'isSafari' => false, //isSafari
+ 'isMZ' => true, //isMZ
+ 'lang' => 'en-US', //lang
+ 'hasDOM' => true, //hasDOM
+ 'canPNGALPHA' => true, //canPNGALPHA
+ 'canIMGDATA' => true, //canIMGDATA
+ ),
+
+ 'Chrome Mac' => array(
+ 'useragent' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.461.0 Safari/534.3',
+ 'version' => '5', //Version
+ 'isWin' => false, //isWindows
+ 'isLinux' => false,
+ 'isMac' => true, //isMac
+ 'isUnix' => false, //isUnix
+ 'isOpera' => false, //isOpera
+ 'isChrome' => true, //isChrome
+ 'isIE' => false, //isIE
+ 'isNS' => false, //isNS
+ 'isNS4' => false, //isNS4
+ 'isKHTML' => true, //isKHTML
+ 'isSafari' => false, //isSafari
+ 'isMZ' => false, //isMZ
+ 'lang' => 'en-US', //lang
+ 'hasDOM' => false, //hasDOM
+ 'canPNGALPHA' => false, //canPNGALPHA
+ 'canIMGDATA' => true, //canIMGDATA
+ ),
+ );
+ }
+
+ function os()
+ {
+ return $this->extractDataSet(array('isWin','isLinux','isUnix','isMac'));
+ }
+
+ /**
+ * @param string $useragent
+ * @return rcube_browser
+ */
+ private function getBrowser($useragent)
+ {
+ /** @var $object rcube_browser */
+ $_SERVER['HTTP_USER_AGENT'] = $useragent;
+
+ $object = new rcube_browser();
+
+ return $object;
+ }
}
diff --git a/tests/Framework/Mime.php b/tests/Framework/Mime.php
index 4db1856be..1450b4f90 100644
--- a/tests/Framework/Mime.php
+++ b/tests/Framework/Mime.php
@@ -197,6 +197,10 @@ class Framework_Mime extends PHPUnit_Framework_TestCase
array("http://xx.xxx.xx.xxx:8080/addressbooks/roundcubexxxxx%40xxxxxxxxxxxxxxxxxxxxxxx.xx.xx/testing/", 70),
"http://xx.xxx.xx.xxx:8080/addressbooks/roundcubexxxxx%40xxxxxxxxxxxxxxxxxxxxxxx.xx.xx/testing/",
),
+ array(
+ array("this-is-just-some-blabla-to-make-this-more-than-seventy-five-characters-in-a-row -- this line should be wrapped", 20, "\n"),
+ "this-is-just-some-blabla-to-make-this-more-than-seventy-five-characters-in-a-row\n-- this line should\nbe wrapped",
+ ),
);
foreach ($samples as $sample) {
diff --git a/tests/Framework/StringReplacer.php b/tests/Framework/StringReplacer.php
index e23fb9b17..0fa7fae34 100644
--- a/tests/Framework/StringReplacer.php
+++ b/tests/Framework/StringReplacer.php
@@ -56,4 +56,20 @@ class Framework_StringReplacer extends PHPUnit_Framework_TestCase
$this->assertEquals($output, $result);
}
+
+ function test_linkrefs()
+ {
+ $input = "This is a sample message [1] to test the new linkref [ref0] replacement feature of [Roundcube].\n";
+ $input.= "\n";
+ $input.= "[1] http://en.wikipedia.org/wiki/Email\n";
+ $input.= "[ref0] www.link-ref.com\n";
+
+ $replacer = new rcube_string_replacer;
+ $result = $replacer->replace($input);
+ $result = $replacer->resolve($result);
+
+ $this->assertContains('[<a href="http://en.wikipedia.org/wiki/Email">1</a>] to', $result, "Numeric linkref replacements");
+ $this->assertContains('[<a href="http://www.link-ref.com">ref0</a>] repl', $result, "Alphanum linkref replacements");
+ $this->assertContains('of [Roundcube].', $result, "Don't touch strings wihtout an index entry");
+ }
}
diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
index 3f7f48c3a..1f1e57b0e 100644
--- a/tests/Framework/Utils.php
+++ b/tests/Framework/Utils.php
@@ -171,6 +171,12 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
$this->assertRegExp('/#rcmbody h1\s\{/', $mod, "Prefix tag styles (single)");
$this->assertRegExp('/#rcmbody h1, #rcmbody h2, #rcmbody h3, #rcmbody textarea\s+\{/', $mod, "Prefix tag styles (multiple)");
$this->assertRegExp('/#rcmbody \.noscript\s+\{/', $mod, "Prefix class styles");
+
+ $css = file_get_contents(TESTS_DIR . 'src/media.css');
+ $mod = rcube_utils::mod_css_styles($css, 'rcmbody');
+
+ $this->assertContains('#rcmbody table[class=w600]', $mod, 'Replace styles nested in @media block');
+ $this->assertContains('#rcmbody {width:600px', $mod, 'Replace body selector nested in @media block');
}
/**
@@ -288,6 +294,32 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
}
/**
+ * rcube:utils::anytodatetime()
+ */
+ function test_anytodatetime()
+ {
+ $test = array(
+ '2013-04-22' => '2013-04-22',
+ '2013/04/22' => '2013-04-22',
+ '2013.04.22' => '2013-04-22',
+ '22-04-2013' => '2013-04-22',
+ '22/04/2013' => '2013-04-22',
+ '22.04.2013' => '2013-04-22',
+ '04/22/2013' => '2013-04-22',
+ '22.4.2013' => '2013-04-22',
+ '20130422' => '2013-04-22',
+ '1900-10-10' => '1900-10-10',
+ '01-01-1900' => '1900-01-01',
+ '01/30/1960' => '1960-01-30'
+ );
+
+ foreach ($test as $datetime => $ts) {
+ $result = rcube_utils::anytodatetime($datetime);
+ $this->assertSame($ts, $result ? $result->format('Y-m-d') : '', "Error parsing date: $datetime");
+ }
+ }
+
+ /**
* rcube:utils::normalize _string()
*/
function test_normalize_string()
diff --git a/tests/MailFunc.php b/tests/MailFunc.php
index 319075abd..ab0074ef2 100644
--- a/tests/MailFunc.php
+++ b/tests/MailFunc.php
@@ -17,8 +17,6 @@ class MailFunc extends PHPUnit_Framework_TestCase
$RCMAIL->storage_init(false);
require_once INSTALL_PATH . 'program/steps/mail/func.inc';
-
- $GLOBALS['EMAIL_ADDRESS_PATTERN'] = $EMAIL_ADDRESS_PATTERN;
}
/**
@@ -147,7 +145,7 @@ class MailFunc extends PHPUnit_Framework_TestCase
// render HTML in normal mode
$html = rcmail_html4inline(rcmail_print_body($part, array('safe' => false)), 'foo');
- $mailto = '<a href="mailto:me@me.com?subject=this is the subject&amp;body=this is the body"'
+ $mailto = '<a href="mailto:me@me.com"'
.' onclick="return rcmail.command(\'compose\',\'me@me.com?subject=this is the subject&amp;body=this is the body\',this)" rel="noreferrer">e-mail</a>';
$this->assertRegExp('|'.preg_quote($mailto, '|').'|', $html, "Extended mailto links");
@@ -183,4 +181,88 @@ class MailFunc extends PHPUnit_Framework_TestCase
$this->assertRegExp('|src="cid:theCID"|', $html, "URI base resolving exception [1]");
$this->assertRegExp('|src="http://other\.domain\.tld/img3\.gif"|', $html, "URI base resolving exception [2]");
}
+
+ /**
+ * Test identities selection using Return-Path header
+ */
+ function test_rcmail_identity_select()
+ {
+ $identities = array(
+ array(
+ 'name' => 'Test',
+ 'email_ascii' => 'addr@domain.tld',
+ 'ident' => 'Test <addr@domain.tld>',
+ ),
+ array(
+ 'name' => 'Test',
+ 'email_ascii' => 'thing@domain.tld',
+ 'ident' => 'Test <thing@domain.tld>',
+ ),
+ array(
+ 'name' => 'Test',
+ 'email_ascii' => 'other@domain.tld',
+ 'ident' => 'Test <other@domain.tld>',
+ ),
+ );
+
+ $message = new stdClass;
+ $message->headers = new rcube_message_header;
+ $message->headers->set('Return-Path', '<some_thing@domain.tld>');
+ $res = rcmail_identity_select($message, $identities);
+
+ $this->assertSame($identities[0], $res);
+
+ $message->headers->set('Return-Path', '<thing@domain.tld>');
+ $res = rcmail_identity_select($message, $identities);
+
+ $this->assertSame($identities[1], $res);
+ }
+
+ /**
+ * Test identities selection (#1489378)
+ */
+ function test_rcmail_identity_select2()
+ {
+ $identities = array(
+ array(
+ 'name' => 'Test 1',
+ 'email_ascii' => 'addr1@domain.tld',
+ 'ident' => 'Test 1 <addr1@domain.tld>',
+ ),
+ array(
+ 'name' => 'Test 2',
+ 'email_ascii' => 'addr2@domain.tld',
+ 'ident' => 'Test 2 <addr2@domain.tld>',
+ ),
+ array(
+ 'name' => 'Test 3',
+ 'email_ascii' => 'addr3@domain.tld',
+ 'ident' => 'Test 3 <addr3@domain.tld>',
+ ),
+ array(
+ 'name' => 'Test 4',
+ 'email_ascii' => 'addr2@domain.tld',
+ 'ident' => 'Test 4 <addr2@domain.tld>',
+ ),
+ );
+
+ $message = new stdClass;
+ $message->headers = new rcube_message_header;
+
+ $message->headers->set('From', '<addr2@domain.tld>');
+ $res = rcmail_identity_select($message, $identities);
+ $this->assertSame($identities[1], $res);
+
+ $message->headers->set('From', 'Test 2 <addr2@domain.tld>');
+ $res = rcmail_identity_select($message, $identities);
+ $this->assertSame($identities[1], $res);
+
+ $message->headers->set('From', 'Other <addr2@domain.tld>');
+ $res = rcmail_identity_select($message, $identities);
+ $this->assertSame($identities[1], $res);
+
+ $message->headers->set('From', 'Test 4 <addr2@domain.tld>');
+ $res = rcmail_identity_select($message, $identities);
+ $this->assertSame($identities[3], $res);
+ }
}
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index da0f899a9..a5942c433 100644
--- a/tests/phpunit.xml
+++ b/tests/phpunit.xml
@@ -46,6 +46,7 @@
<file>./../plugins/help/tests/Help.php</file>
<file>./../plugins/hide_blockquote/tests/HideBlockquote.php</file>
<file>./../plugins/http_authentication/tests/HttpAuthentication.php</file>
+ <file>./../plugins/identity_select/tests/IdentitySelect.php</file>
<file>./../plugins/jqueryui/tests/Jqueryui.php</file>
<file>./../plugins/managesieve/tests/Managesieve.php</file>
<file>./../plugins/managesieve/tests/Parser.php</file>
diff --git a/tests/src/media.css b/tests/src/media.css
new file mode 100644
index 000000000..24eacc8a1
--- /dev/null
+++ b/tests/src/media.css
@@ -0,0 +1,22 @@
+.ReadMsgBody{width: 100%;}
+.ExternalClass{width: 100%;}
+div, p, a, li, td { -webkit-text-size-adjust:none; }
+@media (max-width: 450px){
+ table[class=w600], td[class=w600], table[class=w540], td[class=w540], img[class=w600]{ width:100% !important; }
+ table[class=w30], td[class=w30]{ width:20px !important; }
+ .pict img {max-width:260px; height:auto !important;}
+}
+@media (min-width: 450px) and (max-width: 600px){
+ table[class=w600], td[class=w600], table[class=w540], td[class=w540], img[class=w600]{ width:100% !important; }
+ table[class=w30], td[class=w30]{ width:20px !important; }
+ .pict img {max-width:410px; height:auto !important;}
+}
+@media (min-width:600px){
+ body {width:600px !important; margin:auto !important;}
+ .pict img {max-width:540px !important; height:auto !important;}
+}
+h1{ font-weight:bold; font-size:14px;color:#3c3c3c ;margin:0px; }
+h2{ color:#8DB048 ; font-size:14px; font-weight:bold; margin-top:20px; border-bottom:1px solid #d6d6d6; padding-bottom:4px; }
+h3{ color:#7e7e7e ; font-size:14px; font-weight:bold; margin:20px 0px 0px 0px; border-bottom:1px solid #d6d6d6; padding-bottom:0px 0px 4px 0px; }
+h4{ color:#8DB048 ; font-size:12px; font-weight:bold; margin:0px; padding:0px; }
+a:visited{cursor:pointer; color:#8DB048; text-decoration:none; border:none;}