summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
Diffstat (limited to 'program')
-rw-r--r--program/include/bc.php14
-rw-r--r--program/include/iniset.php20
-rw-r--r--program/include/rcmail.php279
-rw-r--r--program/include/rcmail_output_html.php129
-rw-r--r--program/js/app.js631
-rw-r--r--program/js/common.js125
-rw-r--r--program/js/editor.js4
-rw-r--r--program/js/jstz.min.js13
-rw-r--r--program/js/list.js261
-rw-r--r--program/js/treelist.js1090
-rw-r--r--program/lib/Mail/mime.php114
-rw-r--r--program/lib/Mail/mimePart.php40
-rw-r--r--program/lib/Net/Socket.php113
-rw-r--r--program/lib/Roundcube/bootstrap.php47
-rw-r--r--program/lib/Roundcube/html.php57
-rw-r--r--program/lib/Roundcube/rcube.php304
-rw-r--r--program/lib/Roundcube/rcube_addressbook.php32
-rw-r--r--program/lib/Roundcube/rcube_cache.php78
-rw-r--r--program/lib/Roundcube/rcube_cache_shared.php581
-rw-r--r--program/lib/Roundcube/rcube_config.php93
-rw-r--r--program/lib/Roundcube/rcube_contacts.php40
-rw-r--r--program/lib/Roundcube/rcube_csv2vcard.php53
-rw-r--r--program/lib/Roundcube/rcube_db.php178
-rw-r--r--program/lib/Roundcube/rcube_db_mssql.php32
-rw-r--r--program/lib/Roundcube/rcube_db_mysql.php32
-rw-r--r--program/lib/Roundcube/rcube_db_pgsql.php81
-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.php12
-rw-r--r--program/lib/Roundcube/rcube_imap.php261
-rw-r--r--program/lib/Roundcube/rcube_imap_cache.php208
-rw-r--r--program/lib/Roundcube/rcube_imap_generic.php310
-rw-r--r--program/lib/Roundcube/rcube_ldap.php1356
-rw-r--r--program/lib/Roundcube/rcube_ldap_generic.php1049
-rw-r--r--program/lib/Roundcube/rcube_ldap_result.php130
-rw-r--r--program/lib/Roundcube/rcube_message.php39
-rw-r--r--program/lib/Roundcube/rcube_message_header.php7
-rw-r--r--program/lib/Roundcube/rcube_mime.php221
-rw-r--r--program/lib/Roundcube/rcube_output.php2
-rw-r--r--program/lib/Roundcube/rcube_plugin.php42
-rw-r--r--program/lib/Roundcube/rcube_plugin_api.php119
-rw-r--r--program/lib/Roundcube/rcube_session.php170
-rw-r--r--program/lib/Roundcube/rcube_smtp.php14
-rw-r--r--program/lib/Roundcube/rcube_spellchecker.php161
-rw-r--r--program/lib/Roundcube/rcube_storage.php15
-rw-r--r--program/lib/Roundcube/rcube_string_replacer.php4
-rw-r--r--program/lib/Roundcube/rcube_user.php9
-rw-r--r--program/lib/Roundcube/rcube_utils.php56
-rw-r--r--program/lib/Roundcube/rcube_vcard.php41
-rw-r--r--program/lib/Roundcube/rcube_washtml.php50
-rw-r--r--program/lib/utf8.class.php4
-rw-r--r--program/localization/ar_SA/labels.inc10
-rw-r--r--program/localization/ar_SA/messages.inc2
-rw-r--r--program/localization/ast/labels.inc10
-rw-r--r--program/localization/ast/messages.inc2
-rw-r--r--program/localization/az_AZ/labels.inc20
-rw-r--r--program/localization/az_AZ/messages.inc24
-rw-r--r--program/localization/be_BE/labels.inc10
-rw-r--r--program/localization/be_BE/messages.inc2
-rw-r--r--program/localization/bg_BG/labels.inc16
-rw-r--r--program/localization/bg_BG/messages.inc2
-rw-r--r--program/localization/bn_BD/labels.inc10
-rw-r--r--program/localization/bn_BD/messages.inc2
-rw-r--r--program/localization/br/labels.inc10
-rw-r--r--program/localization/br/messages.inc2
-rw-r--r--program/localization/bs_BA/labels.inc12
-rw-r--r--program/localization/ca_ES/labels.inc14
-rw-r--r--program/localization/ca_ES/messages.inc70
-rw-r--r--program/localization/cs_CZ/labels.inc10
-rw-r--r--program/localization/cs_CZ/messages.inc8
-rw-r--r--program/localization/cy_GB/labels.inc20
-rw-r--r--program/localization/cy_GB/messages.inc2
-rw-r--r--program/localization/da_DK/labels.inc14
-rw-r--r--program/localization/da_DK/messages.inc4
-rw-r--r--program/localization/de_CH/labels.inc16
-rw-r--r--program/localization/de_CH/messages.inc2
-rw-r--r--program/localization/de_DE/labels.inc16
-rw-r--r--program/localization/de_DE/messages.inc2
-rw-r--r--program/localization/el_GR/labels.inc16
-rw-r--r--program/localization/el_GR/messages.inc60
-rw-r--r--program/localization/en_GB/labels.inc10
-rw-r--r--program/localization/en_GB/messages.inc2
-rw-r--r--program/localization/en_US/csv2vcard.inc17
-rw-r--r--program/localization/en_US/labels.inc11
-rw-r--r--program/localization/en_US/messages.inc9
-rw-r--r--program/localization/eo/labels.inc10
-rw-r--r--program/localization/eo/messages.inc2
-rw-r--r--program/localization/es_AR/labels.inc222
-rw-r--r--program/localization/es_AR/messages.inc2
-rw-r--r--program/localization/es_ES/labels.inc16
-rw-r--r--program/localization/es_ES/messages.inc2
-rw-r--r--program/localization/et_EE/labels.inc16
-rw-r--r--program/localization/et_EE/messages.inc4
-rw-r--r--program/localization/eu_ES/labels.inc10
-rw-r--r--program/localization/eu_ES/messages.inc2
-rw-r--r--program/localization/fa_AF/labels.inc10
-rw-r--r--program/localization/fa_AF/messages.inc2
-rw-r--r--program/localization/fa_IR/labels.inc20
-rw-r--r--program/localization/fa_IR/messages.inc2
-rw-r--r--program/localization/fi_FI/labels.inc21
-rw-r--r--program/localization/fr_FR/csv2vcard.inc96
-rw-r--r--program/localization/fr_FR/labels.inc90
-rw-r--r--program/localization/fr_FR/messages.inc2
-rw-r--r--program/localization/fy_NL/labels.inc10
-rw-r--r--program/localization/fy_NL/messages.inc171
-rwxr-xr-xprogram/localization/ga_IE/labels.inc10
-rwxr-xr-xprogram/localization/ga_IE/messages.inc2
-rw-r--r--program/localization/gl_ES/labels.inc82
-rw-r--r--program/localization/gl_ES/messages.inc24
-rw-r--r--program/localization/he_IL/labels.inc14
-rw-r--r--program/localization/he_IL/messages.inc4
-rw-r--r--program/localization/hi_IN/labels.inc10
-rw-r--r--program/localization/hi_IN/messages.inc2
-rw-r--r--program/localization/hr_HR/labels.inc10
-rw-r--r--program/localization/hr_HR/messages.inc2
-rw-r--r--program/localization/hu_HU/labels.inc16
-rw-r--r--program/localization/hu_HU/messages.inc4
-rw-r--r--program/localization/hy_AM/labels.inc10
-rw-r--r--program/localization/hy_AM/messages.inc2
-rw-r--r--program/localization/ia/labels.inc10
-rw-r--r--program/localization/ia/messages.inc2
-rw-r--r--program/localization/id_ID/labels.inc10
-rw-r--r--program/localization/id_ID/messages.inc2
-rw-r--r--program/localization/index.inc2
-rw-r--r--program/localization/is_IS/labels.inc10
-rw-r--r--program/localization/is_IS/messages.inc2
-rw-r--r--program/localization/it_IT/labels.inc14
-rw-r--r--program/localization/it_IT/messages.inc2
-rw-r--r--program/localization/ja_JP/labels.inc10
-rw-r--r--program/localization/ja_JP/messages.inc2
-rwxr-xr-xprogram/localization/ka_GE/labels.inc10
-rwxr-xr-xprogram/localization/ka_GE/messages.inc2
-rw-r--r--program/localization/km_KH/labels.inc10
-rw-r--r--program/localization/km_KH/messages.inc2
-rw-r--r--program/localization/ko_KR/labels.inc10
-rw-r--r--program/localization/ko_KR/messages.inc279
-rw-r--r--program/localization/ku/labels.inc10
-rw-r--r--program/localization/ku/messages.inc2
-rw-r--r--program/localization/lb_LU/labels.inc544
-rw-r--r--program/localization/lb_LU/messages.inc176
-rw-r--r--program/localization/lt_LT/labels.inc22
-rw-r--r--program/localization/lt_LT/messages.inc2
-rw-r--r--program/localization/lv_LV/labels.inc324
-rw-r--r--program/localization/lv_LV/messages.inc198
-rwxr-xr-xprogram/localization/mk_MK/labels.inc10
-rwxr-xr-xprogram/localization/mk_MK/messages.inc2
-rw-r--r--program/localization/ml_IN/labels.inc10
-rw-r--r--program/localization/ml_IN/messages.inc2
-rwxr-xr-xprogram/localization/mr_IN/labels.inc10
-rwxr-xr-xprogram/localization/mr_IN/messages.inc2
-rw-r--r--program/localization/ms_MY/labels.inc10
-rw-r--r--program/localization/ms_MY/messages.inc2
-rw-r--r--program/localization/nb_NO/labels.inc23
-rw-r--r--program/localization/nb_NO/messages.inc2
-rw-r--r--program/localization/ne_NP/labels.inc10
-rw-r--r--program/localization/ne_NP/messages.inc2
-rw-r--r--program/localization/nl_BE/labels.inc10
-rw-r--r--program/localization/nl_BE/messages.inc2
-rw-r--r--program/localization/nl_NL/labels.inc10
-rw-r--r--program/localization/nn_NO/labels.inc17
-rw-r--r--program/localization/nn_NO/messages.inc2
-rw-r--r--program/localization/pl_PL/labels.inc10
-rw-r--r--program/localization/pl_PL/messages.inc6
-rwxr-xr-xprogram/localization/ps/labels.inc10
-rwxr-xr-xprogram/localization/ps/messages.inc2
-rw-r--r--program/localization/pt_BR/labels.inc14
-rw-r--r--program/localization/pt_BR/messages.inc2
-rw-r--r--program/localization/pt_PT/labels.inc10
-rw-r--r--program/localization/pt_PT/messages.inc2
-rw-r--r--program/localization/ro_RO/labels.inc80
-rw-r--r--program/localization/ro_RO/messages.inc2
-rw-r--r--program/localization/ru_RU/labels.inc10
-rw-r--r--program/localization/ru_RU/messages.inc2
-rw-r--r--program/localization/si_LK/labels.inc10
-rw-r--r--program/localization/si_LK/messages.inc2
-rw-r--r--program/localization/sk_SK/labels.inc10
-rw-r--r--program/localization/sk_SK/messages.inc2
-rw-r--r--program/localization/sl_SI/labels.inc14
-rw-r--r--program/localization/sl_SI/messages.inc8
-rw-r--r--program/localization/sq_AL/labels.inc10
-rw-r--r--program/localization/sq_AL/messages.inc2
-rw-r--r--program/localization/sr_CS/labels.inc10
-rw-r--r--program/localization/sr_CS/messages.inc2
-rw-r--r--program/localization/sv_SE/labels.inc10
-rw-r--r--program/localization/sv_SE/messages.inc2
-rw-r--r--program/localization/ta_IN/labels.inc10
-rw-r--r--program/localization/ta_IN/messages.inc2
-rw-r--r--program/localization/th_TH/labels.inc10
-rw-r--r--program/localization/th_TH/messages.inc2
-rw-r--r--program/localization/tr_TR/labels.inc10
-rw-r--r--program/localization/tr_TR/messages.inc2
-rw-r--r--program/localization/uk_UA/labels.inc10
-rw-r--r--program/localization/uk_UA/messages.inc2
-rw-r--r--program/localization/vi_VN/labels.inc17
-rw-r--r--program/localization/vi_VN/messages.inc2
-rw-r--r--program/localization/zh_CN/labels.inc10
-rw-r--r--program/localization/zh_TW/labels.inc10
-rw-r--r--program/localization/zh_TW/messages.inc2
-rw-r--r--program/steps/addressbook/copy.inc12
-rw-r--r--program/steps/addressbook/delete.inc38
-rw-r--r--program/steps/addressbook/export.inc4
-rw-r--r--program/steps/addressbook/func.inc146
-rw-r--r--program/steps/addressbook/import.inc15
-rw-r--r--program/steps/addressbook/list.inc49
-rw-r--r--program/steps/addressbook/move.inc208
-rw-r--r--program/steps/addressbook/save.inc6
-rw-r--r--program/steps/addressbook/show.inc13
-rw-r--r--program/steps/addressbook/undo.inc25
-rw-r--r--program/steps/mail/autocomplete.inc2
-rw-r--r--program/steps/mail/check_recent.inc5
-rw-r--r--program/steps/mail/compose.inc133
-rw-r--r--program/steps/mail/copy.inc8
-rw-r--r--program/steps/mail/func.inc298
-rw-r--r--program/steps/mail/get.inc136
-rw-r--r--program/steps/mail/import.inc105
-rw-r--r--program/steps/mail/list_contacts.inc43
-rw-r--r--program/steps/mail/mark.inc10
-rw-r--r--program/steps/mail/move_del.inc6
-rw-r--r--program/steps/mail/search_contacts.inc19
-rw-r--r--program/steps/mail/sendmail.inc53
-rw-r--r--program/steps/mail/show.inc18
-rw-r--r--program/steps/settings/about.inc67
-rw-r--r--program/steps/settings/edit_folder.inc2
-rw-r--r--program/steps/settings/edit_prefs.inc2
-rw-r--r--program/steps/settings/folders.inc16
-rw-r--r--program/steps/settings/func.inc1972
-rw-r--r--program/steps/settings/save_prefs.inc7
-rw-r--r--program/steps/utils/save_pref.inc16
-rw-r--r--program/steps/utils/spell.inc7
-rw-r--r--program/steps/utils/spell_html.inc5
231 files changed, 10289 insertions, 5399 deletions
diff --git a/program/include/bc.php b/program/include/bc.php
index d8356338d..a7d7b5ac1 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 = rcmail::get_instance()->temp_gc();
+ rcmail::get_instance()->gc_temp();
}
function rcube_charset_convert($str, $from, $to=NULL)
@@ -287,7 +287,7 @@ function rcmail_remote_ip()
function rcube_check_referer()
{
- return rcmail::check_referer();
+ return rcube_utils::check_referer();
}
function rcube_timer()
@@ -405,6 +405,16 @@ 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 b32ae4e8e..919cc7682 100644
--- a/program/include/iniset.php
+++ b/program/include/iniset.php
@@ -24,21 +24,6 @@
define('RCMAIL_VERSION', '1.0-git');
define('RCMAIL_START', microtime(true));
-$config = array(
- // Some users are not using Installer, so we'll check some
- // critical PHP settings here. Only these, which doesn't provide
- // an error/warning in the logs later. See (#1486307).
- 'suhosin.session.encrypt' => 0,
- 'session.auto_start' => 0,
- 'file_uploads' => 1,
-);
-foreach ($config as $optname => $optval) {
- if ($optval != ini_get($optname) && @ini_set($optname, $optval) === false) {
- die("ERROR: Wrong '$optname' option value and it wasn't possible to set it to required value ($optval).\n"
- ."Check your PHP configuration (including php_admin_flag).");
- }
-}
-
if (!defined('INSTALL_PATH')) {
define('INSTALL_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/');
}
@@ -75,6 +60,11 @@ 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 1bde4034f..800eddac6 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -51,6 +51,7 @@ class rcmail extends rcube
*/
public $action = '';
public $comm_path = './';
+ public $filename = '';
private $address_books = array();
private $action_map = array();
@@ -65,12 +66,13 @@ 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()
+ static function get_instance($env = '')
{
if (!self::$instance || !is_a(self::$instance, 'rcmail')) {
- self::$instance = new rcmail();
+ self::$instance = new rcmail($env);
self::$instance->startup(); // init AFTER object was linked with self::$instance
}
@@ -86,6 +88,10 @@ 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();
@@ -98,7 +104,10 @@ class rcmail extends rcube
// reset some session parameters when changing task
if ($this->task != 'utils') {
- if ($this->session && $_SESSION['task'] != $this->task)
+ // we reset list page when switching to another task
+ // but only to the main task interface - empty action (#1489076)
+ // this will prevent from unintentional page reset on cross-task requests
+ if ($this->session && $_SESSION['task'] != $this->task && empty($this->action))
$this->session->remove('page');
// set current task to session
$_SESSION['task'] = $this->task;
@@ -159,7 +168,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 (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
+ if (version_compare(PHP_VERSION, '5.5.0', '<') && in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8');
}
}
@@ -225,6 +234,11 @@ class rcmail extends rcube
}
if (!$contacts) {
+ // there's no default, just return
+ if ($default) {
+ return null;
+ }
+
self::raise_error(array(
'code' => 700, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
@@ -258,13 +272,13 @@ class rcmail extends rcube
*/
public function get_address_sources($writeable = false, $skip_hidden = false)
{
- $abook_type = strtolower($this->config->get('address_book_type'));
- $ldap_config = $this->config->get('ldap_public');
+ $abook_type = (string) $this->config->get('address_book_type');
+ $ldap_config = (array) $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 ($abook_type != 'ldap' && $abook_type != '') {
+ if (!empty($abook_type) && strtolower($abook_type) != 'ldap') {
if (!isset($this->address_books['0']))
$this->address_books['0'] = new rcube_contacts($this->db, $this->get_user_id());
$list['0'] = array(
@@ -277,8 +291,7 @@ class rcmail extends rcube
);
}
- if ($ldap_config) {
- $ldap_config = (array) $ldap_config;
+ if (!empty($ldap_config)) {
foreach ($ldap_config as $id => $prop) {
// handle misconfiguration
if (empty($prop) || !is_array($prop)) {
@@ -287,7 +300,7 @@ class rcmail extends rcube
$list[$id] = array(
'id' => $id,
'name' => html::quote($prop['name']),
- 'groups' => is_array($prop['groups']),
+ 'groups' => !empty($prop['groups']) || !empty($prop['group_filters']),
'readonly' => !$prop['writable'],
'hidden' => $prop['hidden'],
'autocomplete' => in_array($id, $autocomplete)
@@ -594,7 +607,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($user, $domain) = explode('@', $post_user);
+ list(, $domain) = explode('@', $post_user);
// direct match in default_host array
if ($default_host[$post_host] || in_array($post_host, array_values($default_host))) {
@@ -698,28 +711,6 @@ 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
@@ -739,7 +730,7 @@ class rcmail extends rcube
$p['_task'] = $task;
unset($p['task']);
- $url = './';
+ $url = './' . $this->filename;
$delm = '?';
foreach (array_reverse($p) as $key => $val) {
if ($val !== '' && $val !== null) {
@@ -764,11 +755,6 @@ 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'))
@@ -929,189 +915,6 @@ 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,
- ));
-
- $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 (ini_get('safe_mode'))
- $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
@@ -1165,7 +968,7 @@ class rcmail extends rcube
*/
public function table_output($attrib, $table_data, $a_show_cols, $id_col)
{
- $table = new html_table(/*array('cols' => count($a_show_cols))*/);
+ $table = new html_table($attrib);
// add table header
if (!$attrib['noheader']) {
@@ -1528,9 +1331,10 @@ 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 $key => $folder) {
+ foreach ($arrFolders as $folder) {
$title = null;
$folder_class = $this->folder_classname($folder['id']);
$is_collapsed = strpos($collapsed, '&'.rawurlencode($folder['id']).'&') !== false;
@@ -1616,7 +1420,7 @@ class rcmail extends rcube
{
$out = '';
- foreach ($arrFolders as $key => $folder) {
+ foreach ($arrFolders as $folder) {
// skip exceptions (and its subfolders)
if (!empty($opts['exceptions']) && in_array($folder['id'], $opts['exceptions'])) {
continue;
@@ -1684,8 +1488,10 @@ class rcmail extends rcube
*/
public function localize_foldername($name, $with_path = true)
{
+ $realnames = $this->config->get('show_real_foldernames');
+
// try to localize path of the folder
- if ($with_path) {
+ if ($with_path && !$realnames) {
$storage = $this->get_storage();
$delimiter = $storage->get_hierarchy_delimiter();
$path = explode($delimiter, $name);
@@ -1702,12 +1508,11 @@ class rcmail extends rcube
}
}
- if ($folder_class = $this->folder_classname($name)) {
+ if (!$realnames && ($folder_class = $this->folder_classname($name))) {
return $this->gettext($folder_class);
}
- else {
- return rcube_charset::convert($name, 'UTF7-IMAP');
- }
+
+ return rcube_charset::convert($name, 'UTF7-IMAP');
}
@@ -1762,11 +1567,7 @@ class rcmail extends rcube
$quota_result = (array) $quota;
$quota_result['type'] = isset($_SESSION['quota_display']) ? $_SESSION['quota_display'] : '';
- 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 ($quota['total'] > 0) {
if (!isset($quota['percent'])) {
$quota_result['percent'] = min(100, round(($quota['used']/max(1,$quota['total']))*100));
}
@@ -1785,7 +1586,8 @@ class rcmail extends rcube
}
}
else {
- $quota_result['title'] = $this->gettext('unknown');
+ $unlimited = $this->config->get('quota_zero_as_unlimited');
+ $quota_result['title'] = $this->gettext($unlimited ? 'unlimited' : 'unknown');
$quota_result['percent'] = 0;
}
@@ -1964,7 +1766,8 @@ class rcmail extends rcube
public function upload_init()
{
// Enable upload progress bar
- if (($seconds = $this->config->get('upload_progress')) && ini_get('apc.rfc1867')) {
+ $rfc1867 = filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN);
+ if ($rfc1867 && ($seconds = $this->config->get('upload_progress'))) {
if ($field_name = ini_get('apc.rfc1867_name')) {
$this->output->set_env('upload_progress_name', $field_name);
$this->output->set_env('upload_progress_time', (int) $seconds);
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php
index 6100269b9..998779509 100644
--- a/program/include/rcmail_output_html.php
+++ b/program/include/rcmail_output_html.php
@@ -67,11 +67,12 @@ 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'));
$this->set_env('cookie_path', ini_get('session.cookie_path'));
- $this->set_env('cookie_secure', ini_get('session.cookie_secure'));
+ $this->set_env('cookie_secure', filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN));
// load the correct skin (in case user-defined)
$skin = $this->config->get('skin');
@@ -105,7 +106,6 @@ class rcmail_output_html extends rcmail_output
));
}
-
/**
* Set environment variable
*
@@ -121,7 +121,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Getter for the current page title
*
@@ -145,17 +144,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('skins/'.$skin) && is_readable('skins/'.$skin)) {
- $skin_path = 'skins/'.$skin;
- $valid = true;
+ if (!empty($skin) && is_dir($path . $skin) && is_readable($path . $skin)) {
+ $skin_path = 'skins/' . $skin;
+ $valid = true;
}
else {
$skin_path = $this->config->get('skin_path');
@@ -183,13 +182,16 @@ class rcmail_output_html extends rcmail_output
$this->skin_paths[] = $skin_path;
// read meta file and check for dependecies
- $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']);
+ $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']);
+ }
}
}
-
/**
* Check if a specific template exists
*
@@ -198,16 +200,17 @@ class rcmail_output_html extends rcmail_output
*/
public function template_exists($name)
{
- $found = false;
foreach ($this->skin_paths as $skin_path) {
- $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;
+ $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;
+ }
}
- return $found;
- }
+ return false;
+ }
/**
* Find the given file in the current skin path stack
@@ -233,7 +236,6 @@ class rcmail_output_html extends rcmail_output
return false;
}
-
/**
* Register a GUI object to the client script
*
@@ -246,7 +248,6 @@ class rcmail_output_html extends rcmail_output
$this->add_script(self::JS_OBJECT_NAME.".gui_object('$obj', '$id');");
}
-
/**
* Call a client method
*
@@ -262,7 +263,6 @@ class rcmail_output_html extends rcmail_output
$this->js_commands[] = $cmd;
}
-
/**
* Add a localized label to the client environment
*/
@@ -277,7 +277,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Invoke display_message command
*
@@ -304,7 +303,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Delete all stored env variables and commands
*
@@ -327,7 +325,6 @@ class rcmail_output_html extends rcmail_output
$this->body = '';
}
-
/**
* Redirect to a certain url
*
@@ -343,7 +340,6 @@ 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
@@ -377,7 +373,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Process template and write to stdOut
*
@@ -413,7 +408,6 @@ 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)
*
@@ -538,7 +532,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Return executable javascript code for all registered commands
*
@@ -570,7 +563,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Make URLs starting with a slash point to skin directory
*
@@ -590,7 +582,6 @@ class rcmail_output_html extends rcmail_output
return $str;
}
-
/**
* Show error page and terminate script execution
*
@@ -625,7 +616,6 @@ class rcmail_output_html extends rcmail_output
array($this, 'globals_callback'), $input);
}
-
/**
* Callback funtion for preg_replace_callback() in parse_with_globals()
*/
@@ -634,7 +624,6 @@ 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
@@ -646,7 +635,6 @@ class rcmail_output_html extends rcmail_output
array($this, 'file_callback'), $output);
}
-
/**
* Callback function for preg_replace_callback in write()
*
@@ -655,7 +643,7 @@ class rcmail_output_html extends rcmail_output
protected function file_callback($matches)
{
$file = $matches[3];
- $file[0] = preg_replace('!^/this/!', '/', $file[0]);
+ $file = preg_replace('!^/this/!', '/', $file);
// correct absolute paths
if ($file[0] == '/') {
@@ -672,7 +660,6 @@ class rcmail_output_html extends rcmail_output
return $matches[1] . '=' . $matches[2] . $file . $matches[4];
}
-
/**
* Public wrapper to dipp into template parsing.
*
@@ -689,7 +676,6 @@ class rcmail_output_html extends rcmail_output
return $input;
}
-
/**
* Parse for conditional tags
*
@@ -727,21 +713,18 @@ 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 eval("return (".$this->parse_expression($condition).");");
+ return $this->eval_expression($condition);
}
-
/**
* Inserts hidden field with CSRF-prevention-token into POST forms
*/
@@ -758,16 +741,16 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
- * Parses expression and replaces variables
+ * Parse & evaluate a given expression and return its result.
+ *
+ * @param string Expression statement
*
- * @param string Expression statement
- * @return string Expression value
+ * @return mixed Expression result
*/
- protected function parse_expression($expression)
+ protected function eval_expression ($expression)
{
- return preg_replace(
+ $expression = preg_replace(
array(
'/session:([a-z0-9_]+)/i',
'/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i',
@@ -779,16 +762,30 @@ class rcmail_output_html extends rcmail_output
),
array(
"\$_SESSION['\\1']",
- "\$this->app->config->get('\\1',rcube_utils::get_boolean('\\3'))",
- "\$this->env['\\1']",
+ "\$app->config->get('\\1',rcube_utils::get_boolean('\\3'))",
+ "\$env['\\1']",
"rcube_utils::get_input_value('\\1', rcube_utils::INPUT_GPC)",
"\$_COOKIE['\\1']",
- "\$this->browser->{'\\1'}",
+ "\$browser->{'\\1'}",
$this->template_name,
),
- $expression);
- }
+ $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);
+ }
/**
* Search for special tags in input and replace them
@@ -804,7 +801,6 @@ 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
@@ -839,7 +835,7 @@ class rcmail_output_html extends rcmail_output
// show a label
case 'label':
if ($attrib['expression'])
- $attrib['name'] = eval("return " . $this->parse_expression($attrib['expression']) .";");
+ $attrib['name'] = $this->eval_expression($attrib['expression']);
if ($attrib['name'] || $attrib['command']) {
// @FIXME: 'noshow' is useless, remove?
@@ -873,6 +869,7 @@ class rcmail_output_html extends rcmail_output
// include a file
case 'include':
$old_base_path = $this->base_path;
+ if (!empty($attrib['skin_path'])) $attrib['skinpath'] = $attrib['skin_path'];
if ($path = $this->get_skin_file($attrib['file'], $skin_path, $attrib['skinpath'])) {
$this->base_path = preg_replace('!plugins/\w+/!', '', $skin_path); // set base_path to core skin directory (not plugin's skin)
$path = realpath($path);
@@ -970,8 +967,7 @@ class rcmail_output_html extends rcmail_output
// return code for a specified eval expression
case 'exp':
- $value = $this->parse_expression($attrib['expression']);
- return eval("return html::quote($value);");
+ return html::quote($this->eval_expression($attrib['expression']));
// return variable
case 'var':
@@ -1008,12 +1004,13 @@ class rcmail_output_html extends rcmail_output
}
return html::quote($value);
- break;
+
+ case 'form':
+ return $this->form_tag($attrib);
}
return '';
}
-
/**
* Include a specific file and return it's contents
*
@@ -1030,7 +1027,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Create and register a button
*
@@ -1186,7 +1182,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Link an external script file
*
@@ -1217,7 +1212,6 @@ class rcmail_output_html extends rcmail_output
$this->script_files[$position][] = $file;
}
-
/**
* Add inline javascript code
*
@@ -1234,7 +1228,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Link an external css file
*
@@ -1245,7 +1238,6 @@ class rcmail_output_html extends rcmail_output
$this->css_files[] = $file;
}
-
/**
* Add HTML code to the page header
*
@@ -1256,7 +1248,6 @@ class rcmail_output_html extends rcmail_output
$this->header .= "\n" . $str;
}
-
/**
* Add HTML code to the page footer
* To be added right befor </body>
@@ -1268,7 +1259,6 @@ class rcmail_output_html extends rcmail_output
$this->footer .= "\n" . $str;
}
-
/**
* Process template and write to stdOut
*
@@ -1393,7 +1383,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Returns iframe object, registers some related env variables
*
@@ -1424,7 +1413,6 @@ class rcmail_output_html extends rcmail_output
/* ************* common functions delivering gui objects ************** */
-
/**
* Create a form tag with the necessary hidden fields
*
@@ -1446,12 +1434,11 @@ class rcmail_output_html extends rcmail_output
$attrib['noclose'] = true;
return html::tag('form',
- $attrib + array('action' => "./", 'method' => "get"),
+ $attrib + array('action' => $this->app->comm_path, 'method' => "get"),
$hidden . $content,
array('id','class','style','name','method','action','enctype','onsubmit'));
}
-
/**
* Build a form tag with a unique request token
*
@@ -1482,7 +1469,6 @@ 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
@@ -1514,7 +1500,6 @@ class rcmail_output_html extends rcmail_output
return rcube_utils::idn_to_utf8($username);
}
-
/**
* GUI object 'loginform'
* Returns code for the webmail login form
@@ -1614,7 +1599,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* GUI object 'preloader'
* Loads javascript code for images preloading
@@ -1637,7 +1621,6 @@ class rcmail_output_html extends rcmail_output
}', 'docready');
}
-
/**
* GUI object 'searchform'
* Returns code for search function
@@ -1676,7 +1659,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Builder for GUI object 'message'
*
@@ -1694,7 +1676,6 @@ 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 d194b7326..45a17d640 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -44,7 +44,9 @@ function rcube_webmail()
comm_path: './',
blankpage: 'program/resources/blank.gif',
recipients_separator: ',',
- recipients_delimiter: ', '
+ recipients_delimiter: ', ',
+ popup_width: 1150,
+ popup_width_small: 900
};
// create protected reference to myself
@@ -178,11 +180,6 @@ function rcube_webmail()
parent.rcmail.env.frame_lock = null;
}
- // Makes that reference to document.activeElement do not throw
- // "unspecified error" in IE9 (#1489008)
- if (this.env.framed && bw.ie)
- document.documentElement.focus();
-
// enable general commands
this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref',
'compose', 'undo', 'about', 'switch-task', 'menu-open', 'menu-save', true);
@@ -194,7 +191,7 @@ function rcube_webmail()
case 'mail':
// enable mail commands
- this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
+ 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, {
@@ -232,7 +229,7 @@ function rcube_webmail()
this.set_button_titles();
this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list',
- 'moveto', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource',
+ 'move', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource',
'print', 'load-attachment', 'download-attachment', 'show-headers', 'hide-headers', 'download',
'forward', 'forward-inline', 'forward-attachment', 'change-format'];
@@ -258,7 +255,8 @@ function rcube_webmail()
}
}
else if (this.env.action == 'compose') {
- this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'search', 'reset-search', 'extwin'];
+ 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')
@@ -279,12 +277,15 @@ function rcube_webmail()
// 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)
+ 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) {
@@ -319,17 +320,19 @@ function rcube_webmail()
}
// detect browser capabilities
- if (!this.is_framed())
+ 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', 'listsearch', 'advanced-search', true);
+ 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,
@@ -373,7 +376,7 @@ function rcube_webmail()
}
if (this.gui_objects.qsearchbox)
- this.enable_command('search', 'reset-search', 'moveto', true);
+ this.enable_command('search', 'reset-search', true);
break;
@@ -601,15 +604,16 @@ function rcube_webmail()
case 'extwin':
if (this.env.action == 'compose') {
- var form = this.gui_objects.messageform;
+ 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 = this.open_window('', 1100, 900);
+ form.target = win.name;
form.submit();
}
else {
- this.open_window(this.env.permaurl, 900, 900);
+ this.open_window(this.env.permaurl, true);
}
break;
@@ -791,16 +795,18 @@ function rcube_webmail()
// mail task commands
case 'move':
- case 'moveto':
+ case 'moveto': // deprecated
if (this.task == 'mail')
this.move_messages(props);
else if (this.task == 'addressbook')
- this.copy_contact(null, props);
+ 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':
@@ -862,11 +868,8 @@ function rcube_webmail()
// 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) {
- var attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', this.html_identifier('rcubemailattachment'+this.env.uid+props));
- if (attachment_win) {
- setTimeout(function(){ attachment_win.focus(); }, 10);
+ if (this.open_window(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1'))
break;
- }
}
this.goto_url('get', qstring+'&_download=1', false);
@@ -941,16 +944,13 @@ function rcube_webmail()
url._to = props;
}
else {
- // use contact_id passed as command parameter
- var n, len, a_cids = [];
+ var a_cids = [];
+ // use contact id passed as command parameter
if (props)
a_cids.push(props);
// get selected contacts
- 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]);
- }
+ 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);
@@ -985,8 +985,8 @@ function rcube_webmail()
// Reset the auto-save timer
clearTimeout(this.save_timer);
- // compose form did not change
- if (this.cmp_hash == this.compose_field_hash()) {
+ // 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;
}
@@ -1008,7 +1008,7 @@ function rcube_webmail()
// Reset the auto-save timer
clearTimeout(this.save_timer);
- this.upload_file(props || this.gui_objects.uploadform);
+ this.upload_file(props || this.gui_objects.uploadform, 'upload');
break;
case 'insert-sig':
@@ -1052,10 +1052,12 @@ function rcube_webmail()
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.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) {
- setTimeout(function(){ ref.printwin.focus(); }, 20);
if (this.env.action != 'show')
this.mark_message('read', uid);
}
@@ -1063,15 +1065,15 @@ function rcube_webmail()
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);
- }
+ 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 (uid = this.get_single_uid())
+ 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;
@@ -1108,11 +1110,31 @@ function rcube_webmail()
}
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');
@@ -1187,6 +1209,7 @@ function rcube_webmail()
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 {
@@ -1329,7 +1352,7 @@ function rcube_webmail()
this.drag_menu = function(e, target)
{
var modkey = rcube_event.get_modifier(e),
- menu = this.gui_objects.message_dragmenu;
+ menu = this.gui_objects.dragmenu;
if (menu && modkey == SHIFT_KEY && this.commands['copy']) {
var pos = rcube_event.get_mouse_pos(e);
@@ -1343,7 +1366,7 @@ function rcube_webmail()
this.drag_menu_action = function(action)
{
- var menu = this.gui_objects.message_dragmenu;
+ var menu = this.gui_objects.dragmenu;
if (menu) {
$(menu).hide();
}
@@ -1458,8 +1481,12 @@ function rcube_webmail()
list.draglayer.hide();
this.drag_end(e);
- if (!this.drag_menu(e, target))
- this.command('moveto', target);
+ 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
@@ -1506,7 +1533,7 @@ function rcube_webmail()
}
}
// Multi-message commands
- this.enable_command('delete', 'moveto', 'copy', 'mark', 'forward', 'forward-attachment', list.selection.length > 0);
+ 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))
@@ -1514,7 +1541,7 @@ function rcube_webmail()
// 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(); }, 200);
+ this.preview_timer = setTimeout(function() { ref.msglist_get_preview(); }, this.dblclick_time);
else if (this.env.contentframe)
this.show_contentframe(false);
};
@@ -1530,12 +1557,13 @@ function rcube_webmail()
var win = this.get_frame_window(this.env.contentframe);
- if (win && win.location.href.indexOf(this.env.blankpage)>=0) {
+ 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(); }, 200);
+
+ this.preview_timer = setTimeout(function() { ref.msglist_get_preview(); }, this.dblclick_time);
}
};
@@ -1543,11 +1571,11 @@ function rcube_webmail()
{
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)
@@ -1587,7 +1615,7 @@ function rcube_webmail()
this.msglist_set_coltypes = function(list)
{
- var i, found, name, cols = list.list.tHead.rows[0].cells;
+ var i, found, name, cols = list.thead.rows[0].cells;
this.env.coltypes = [];
@@ -1608,42 +1636,55 @@ function rcube_webmail()
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;
+ 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;
- if (this.task == 'settings')
- return id != this.env.mailbox ? 1 : 0;
+ case 'settings':
+ return id != this.env.mailbox ? 1 : 0;
- if (this.task == 'addressbook') {
- if (id != this.env.source && this.env.contactfolders[id]) {
- // droptarget is a group - contact add to group action
- 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) {
- // search result may contain contacts from many sources
- return (this.env.selection_sources.length > 1 || $.inArray(target_abook, this.env.selection_sources) == -1) ? 2 : 1;
+ 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;
}
}
- // droptarget is a (writable) addressbook - contact copy action
- else if (!this.env.contactfolders[id].readonly) {
- // search result may contain contacts from many sources
- return (this.env.selection_sources.length > 1 || $.inArray(id, this.env.selection_sources) == -1) ? 2 : 0;
- }
- }
}
return 0;
};
- this.open_window = function(url, width, height)
+ // open popup window
+ this.open_window = function(url, small, toolbar)
{
- var w = Math.min(width, screen.width - 10),
- h = Math.min(height, screen.height - 100),
- l = (screen.width - w) / 2 + (screen.left || 0),
- t = Math.max(0, (screen.height - h) / 2 + (screen.top || 0) - 20),
- wname = 'rcmextwin' + new Date().getTime(),
- extwin = window.open(url + '&_extwin=1', wname,
- 'width='+w+',height='+h+',top='+t+',left='+l+',resizable=yes,toolbar=no,status=no,location=no');
+ 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) {
@@ -1652,10 +1693,8 @@ function rcube_webmail()
// focus window, delayed to bring to front
window.setTimeout(function() { extwin.focus(); }, 10);
- // position window with setTimeout for Chrome (#1488931)
- window.setTimeout(function() { extwin.moveTo(l,t); }, bw.chrome ? 100 : 10);
- return wname;
+ return extwin;
};
@@ -1739,10 +1778,7 @@ function rcube_webmail()
+ (flags.flagged ? ' flagged' : '')
+ (flags.unread_children && flags.seen && !this.env.autoexpand_threads ? ' unroot' : '')
+ (message.selected ? ' selected' : ''),
- // for performance use DOM instead of jQuery here
- row = document.createElement('tr');
-
- row.id = 'rcmrow'+uid;
+ row = { cols:[], style:{}, id:'rcmrow'+uid };
// message status icons
css_class = 'msgicon';
@@ -1806,8 +1842,7 @@ function rcube_webmail()
// add each submitted col
for (n in this.env.coltypes) {
c = this.env.coltypes[n];
- col = document.createElement('td');
- col.className = String(c).toLowerCase();
+ col = { className: String(c).toLowerCase() };
if (c == 'flag') {
css_class = (flags.flagged ? 'flagged' : 'unflagged');
@@ -1852,8 +1887,7 @@ function rcube_webmail()
html = cols[c];
col.innerHTML = html;
-
- row.appendChild(col);
+ row.cols.push(col);
}
list.insert_row(row, attop);
@@ -1954,7 +1988,7 @@ function rcube_webmail()
}
else {
if (!preview && this.env.message_extwin && !this.env.extwin)
- this.open_window(this.env.comm_path+url, 1000, 1200);
+ this.open_window(this.env.comm_path+url, true);
else
this.location_href(this.env.comm_path+url, target, true);
@@ -1980,14 +2014,18 @@ function rcube_webmail()
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;
+ 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.busy)
+ if (!show && this.env.frame_lock)
this.set_busy(false, null, this.env.frame_lock);
};
@@ -2115,12 +2153,12 @@ function rcube_webmail()
this.clear_message_list = function()
{
- this.env.messages = {};
- this.last_selected = 0;
+ this.env.messages = {};
+ this.last_selected = 0;
- this.show_contentframe(false);
- if (this.message_list)
- this.message_list.clear(true);
+ this.show_contentframe(false);
+ if (this.message_list)
+ this.message_list.clear(true);
};
// send remote request to load message list
@@ -2216,7 +2254,7 @@ function rcube_webmail()
if (root)
row = rows[root] ? rows[root].obj : null;
else
- row = this.message_list.list.tBodies[0].firstChild;
+ row = this.message_list.tbody.firstChild;
while (row) {
if (row.nodeType == 1 && (r = rows[row.uid])) {
@@ -2392,7 +2430,7 @@ function rcube_webmail()
this.delete_excessive_thread_rows = function()
{
var rows = this.message_list.rows,
- tbody = this.message_list.list.tBodies[0],
+ tbody = this.message_list.tbody,
row = tbody.firstChild,
cnt = this.env.pagesize + 1;
@@ -2565,7 +2603,7 @@ function rcube_webmail()
// Hide message command buttons until a message is selected
this.enable_command(this.env.message_commands, false);
- this._with_selected_messages('moveto', post_data, lock);
+ this._with_selected_messages('move', post_data, lock);
};
// delete selected messages from the current mailbox
@@ -2624,7 +2662,7 @@ function rcube_webmail()
this._with_selected_messages('delete', post_data);
};
- // Send a specifc moveto/delete request with UIDs of all selected messages
+ // Send a specifc move/delete request with UIDs of all selected messages
// @private
this._with_selected_messages = function(action, post_data, lock)
{
@@ -2666,7 +2704,7 @@ function rcube_webmail()
this.delete_excessive_thread_rows();
if (!lock) {
- msg = action == 'moveto' ? 'movingmessage' : 'deletingmessage';
+ msg = action == 'move' ? 'movingmessage' : 'deletingmessage';
lock = this.display_message(this.get_label(msg), 'loading');
}
@@ -2980,11 +3018,12 @@ function rcube_webmail()
// open new compose window
if (this.env.compose_extwin && !this.env.extwin) {
- this.open_window(url, 1150, 900);
+ this.open_window(url);
}
else {
this.redirect(url);
- window.resizeTo(Math.max(1150, $(window).width()), Math.max(900, $(window).height()));
+ if (this.env.extwin)
+ window.resizeTo(Math.max(this.env.popup_width, $(window).width()), $(window).height() + 24);
}
};
@@ -3026,7 +3065,7 @@ function rcube_webmail()
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.env.opened_extwin) {
+ if (input_from.prop('type') == 'select-one') {
this.change_identity(input_from[0]);
}
}
@@ -3087,12 +3126,18 @@ function rcube_webmail()
this.compose_recipient_select = function(list)
{
- this.enable_command('add-recipient', list.selection.length > 0);
+ 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);
+ 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++) {
@@ -3111,8 +3156,10 @@ function rcube_webmail()
}
if (recipients.length && input.length) {
- var oldval = input.val();
- input.val((oldval ? oldval + this.env.recipients_delimiter : '') + recipients.join(this.env.recipients_delimiter));
+ 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 });
}
};
@@ -3302,6 +3349,15 @@ function rcube_webmail()
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);
};
@@ -3346,12 +3402,54 @@ function rcube_webmail()
if (!show_sig)
show_sig = this.env.show_sig;
- var cursor_pos, p = -1,
+ // 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;
+ 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]) {
@@ -3367,7 +3465,7 @@ function rcube_webmail()
sig = this.env.signatures[sig].text;
sig = sig.replace(/\r\n/g, '\n');
- p = this.env.sig_above ? message.indexOf(sig) : message.lastIndexOf(sig);
+ 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);
}
@@ -3376,7 +3474,7 @@ function rcube_webmail()
sig = this.env.signatures[id].text;
sig = sig.replace(/\r\n/g, '\n');
- if (this.env.sig_above) {
+ 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;
@@ -3420,7 +3518,7 @@ function rcube_webmail()
sigElem = doc.createElement('div');
sigElem.setAttribute('id', '_rc_sig');
- if (this.env.sig_above) {
+ 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
@@ -3451,8 +3549,8 @@ function rcube_webmail()
return true;
};
- // upload attachment file
- this.upload_file = function(form)
+ // upload (attachment) file
+ this.upload_file = function(form, action)
{
if (!form)
return false;
@@ -3479,7 +3577,7 @@ function rcube_webmail()
return;
}
- var frame_name = this.async_upload_form(form, 'upload', function(e) {
+ var frame_name = this.async_upload_form(form, action || 'upload', function(e) {
var d, content = '';
try {
if (this.contentDocument) {
@@ -3677,15 +3775,19 @@ function rcube_webmail()
this.env.search_id = null;
};
- this.sent_successfully = function(type, msg)
+ this.sent_successfully = function(type, msg, target)
{
this.display_message(msg, type);
if (this.env.extwin) {
- var opener_rc = this.opener();
+ var rc = this.opener();
this.lock_form(this.gui_objects.messageform);
- if (opener_rc)
- opener_rc.display_message(msg, type);
+ if (rc) {
+ rc.display_message(msg, type);
+ // refresh the folder where sent message was saved
+ if (target && rc.env.task == 'mail' && rc.env.action == '' && rc.env.mailbox == target)
+ rc.command('checkmail');
+ }
setTimeout(function(){ window.close() }, 1000);
}
else {
@@ -4057,43 +4159,55 @@ function rcube_webmail()
if (this.preview_timer)
clearTimeout(this.preview_timer);
- var n, id, sid, ref = this, writable = false,
+ 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) {
- for (n in list.selection) {
+
+ 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;
+ writable = writable || (!this.env.address_sources[sid].readonly && !contact.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;
+ 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);
+ 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', list.selection.length > 0);
+ this.enable_command('export-selected', 'copy', list.selection.length > 0);
this.enable_command('edit', id && writable);
- this.enable_command('delete', list.selection.length && writable);
+ this.enable_command('delete', 'move', list.selection.length > 0 && writable);
return false;
};
@@ -4121,11 +4235,29 @@ function rcube_webmail()
else if (!this.env.search_request)
folder = group ? 'G'+src+group : src;
- this.select_folder(folder, '', true);
-
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);
@@ -4180,16 +4312,38 @@ function rcube_webmail()
this.list_contacts_clear = function()
{
+ this.contact_list.data = {};
this.contact_list.clear(true);
this.show_contentframe(false);
- this.enable_command('delete', 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;
+ 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;
@@ -4199,7 +4353,9 @@ function rcube_webmail()
// load dummy content, unselect selected row(s)
if (!cid)
this.contact_list.clear_selection();
- this.enable_command('delete', 'compose', 'export-selected', cid);
+
+ this.enable_command('compose', rec && rec.email);
+ this.enable_command('export-selected', rec && rec._type != 'group');
}
else if (framed)
return false;
@@ -4229,14 +4385,38 @@ function rcube_webmail()
this.http_post('group-'+what+'members', post_data, lock);
};
- // copy a contact to the specified target (group or directory)
- this.copy_contact = function(cid, to)
+ 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 : '';
-
- if (!cid)
+ 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)
@@ -4249,13 +4429,12 @@ function rcube_webmail()
// tagret is a group
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};
+ return;
- this.http_post('copy', post_data, lock);
- }
+ 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) {
@@ -4266,19 +4445,53 @@ function rcube_webmail()
}
};
+ // 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 selection = this.contact_list.get_selection(),
- undelete = this.env.source && this.env.address_sources[this.env.source].undelete;
+ var undelete = this.env.source && this.env.address_sources[this.env.source].undelete;
- // exit if no mailbox specified or if selection is empty
- if (!(selection.length || this.env.cid) || (!undelete && !confirm(this.get_label('deletecontactconfirm'))))
+ if (!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');
+ 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 {
@@ -4293,6 +4506,11 @@ function rcube_webmail()
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)
@@ -4303,13 +4521,13 @@ function rcube_webmail()
post_data._search = this.env.search_request;
// send request to server
- this.http_post('delete', post_data, lock)
+ 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)
+ this.update_contact_row = function(cid, cols_arr, newcid, source, data)
{
var c, row, list = this.contact_list;
@@ -4322,31 +4540,18 @@ function rcube_webmail()
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]);
-
- // cid change
- 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 = '';
- }
- }
+ 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)
+ this.add_contact_row = function(cid, cols, classes, data)
{
if (!this.gui_objects.contactslist)
return false;
var c, col, list = this.contact_list,
- row = document.createElement('tr');
+ row = { cols:[] };
row.id = 'rcmrow'+this.html_identifier(cid);
row.className = 'contact ' + (classes || '');
@@ -4356,12 +4561,14 @@ function rcube_webmail()
// add each submitted col
for (c in cols) {
- col = document.createElement('td');
+ col = {};
col.className = String(c).toLowerCase();
col.innerHTML = cols[c];
- row.appendChild(col);
+ row.cols.push(col);
}
+ // store data in list member
+ list.data[cid] = data;
list.insert_row(row);
this.enable_command('export', list.rowcount > 0);
@@ -4465,11 +4672,22 @@ function rcube_webmail()
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) : $('ul.groups li:last', this.get_folder_li(this.env.source,'',true));
+ 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(type == 'contactsearch' ? this.gui_objects.folderlist : $('ul.groups', this.get_folder_li(this.env.source,'',true)));
+ else {
+ this.name_input_li.appendTo(ul);
+ ul.show(); // make sure the list is visible
+ }
}
this.name_input.select().focus();
@@ -4526,11 +4744,13 @@ function rcube_webmail()
this.reset_add_input = function()
{
if (this.name_input) {
+ var li = this.name_input.parent();
if (this.env.group_renaming) {
- var li = this.name_input.parent();
li.children().last().show();
this.env.group_renaming = false;
}
+ else if ($('li', li.parent()).length == 1)
+ li.parent().hide();
this.name_input.remove();
@@ -4958,18 +5178,16 @@ function rcube_webmail()
this.update_identity_row = function(id, name, add)
{
- var row, col, list = this.identity_list,
+ var 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);
+ if (add) {
+ list.insert_row({ id:'rcmrow'+rid, cols:[ { className:'mail', innerHTML:name } ] });
list.select(rid);
}
+ else {
+ list.update_row(rid, [ name ]);
+ }
};
@@ -5660,11 +5878,11 @@ function rcube_webmail()
};
// open a jquery UI dialog with the given content
- this.show_popup_dialog = function(html, title)
+ this.show_popup_dialog = function(html, title, buttons)
{
// forward call to parent window
if (this.is_framed()) {
- parent.rcmail.show_popup_dialog(html, title);
+ parent.rcmail.show_popup_dialog(html, title, buttons);
return;
}
@@ -5672,17 +5890,21 @@ function rcube_webmail()
.html(html)
.dialog({
title: title,
+ buttons: buttons,
modal: true,
resizable: true,
- width: 580,
+ 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+50), width: Math.min(w-20, width+50) })
- .dialog('option', 'position', ['center', 'center']); // only works in a separate call (!?)
+ // 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
@@ -5744,7 +5966,7 @@ function rcube_webmail()
this.set_message_coltypes = function(coltypes, repl, smart_col)
{
var list = this.message_list,
- thead = list ? list.list.tHead : null,
+ thead = list ? list.thead : null,
cell, col, n, len, th, tr;
this.env.coltypes = coltypes;
@@ -5757,14 +5979,14 @@ function rcube_webmail()
for (c=0, len=repl.length; c < len; c++) {
cell = document.createElement('td');
- cell.innerHTML = repl[c].html;
+ 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);
- thead = th;
+ list.thead = thead = th;
}
for (n=0, len=this.env.coltypes.length; n<len; n++) {
@@ -6174,7 +6396,7 @@ function rcube_webmail()
this.enable_command('export-selected', false);
}
- case 'moveto':
+ case 'move':
if (this.env.action == 'show') {
// re-enable commands on move/delete error
this.enable_command(this.env.message_commands, true);
@@ -6215,6 +6437,7 @@ function rcube_webmail()
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 });
}
}
@@ -6225,6 +6448,7 @@ function rcube_webmail()
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 });
}
}
@@ -6386,9 +6610,10 @@ function rcube_webmail()
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},
- beforeSend: function(xhr, s) { if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; },
+ 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'); }
});
@@ -6428,7 +6653,7 @@ function rcube_webmail()
multipart += '; filename="' + (f.name_bin || file.name) + '"' + crlf;
multipart += 'Content-Length: ' + file.size + crlf;
multipart += 'Content-Type: ' + file.type + crlf + crlf;
- multipart += e.target.result + crlf;
+ multipart += reader.result + crlf;
multipart += dashdash + boundary + crlf;
if (j == last) // we're done, submit the data
diff --git a/program/js/common.js b/program/js/common.js
index 1075225b4..de07ec131 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -251,7 +251,7 @@ remove_listener: function(p)
},
/**
- * Prevent event propagation and bubbeling
+ * Prevent event propagation and bubbling
*/
cancel: function(evt)
{
@@ -298,8 +298,7 @@ addEventListener: function(evt, func, obj)
if (!this._events[evt])
this._events[evt] = [];
- var e = {func:func, obj:obj ? obj : window};
- this._events[evt][this._events[evt].length] = e;
+ this._events[evt].push({func:func, obj:obj ? obj : window});
},
/**
@@ -372,117 +371,6 @@ triggerEvent: function(evt, e)
}; // end rcube_event_engine.prototype
-
-/**
- * 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;
- };
-
-};
-
-
// check if input is a valid email address
// By Cal Henderson <cal@iamcal.com>
// http://code.iamcal.com/php/rfc822/
@@ -537,7 +425,7 @@ function rcube_clone_object(obj)
for (var key in obj) {
if (obj[key] && typeof obj[key] === 'object')
- out[key] = clone_object(obj[key]);
+ out[key] = rcube_clone_object(obj[key]);
else
out[key] = obj[key];
}
@@ -717,7 +605,7 @@ if (bw.ie) {
// jQuery plugin to emulate HTML5 placeholder attributes on input elements
jQuery.fn.placeholder = function(text) {
return this.each(function() {
- var elem = $(this);
+ var active = false, elem = $(this);
this.title = text;
// Try HTML5 placeholder attribute first
@@ -742,8 +630,9 @@ jQuery.fn.placeholder = function(text) {
elem[(active ? 'addClass' : 'removeClass')]('placeholder').attr('spellcheck', active);
});
- // Do not blur currently focused element
- if (this != document.activeElement)
+ // Do not blur currently focused element (catch exception: #1489008)
+ try { active = this == document.activeElement; } catch(e) {}
+ if (!active)
elem.blur();
}
});
diff --git a/program/js/editor.js b/program/js/editor.js
index 3782de869..e403d1f63 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, {
@@ -80,7 +80,7 @@ function rcmail_editor_callback()
if (rcmail.env.default_font)
$(tinyMCE.get(rcmail.env.composebody).getBody()).css('font-family', rcmail.env.default_font);
- if (elem && elem.type == 'select-one' && !rcmail.env.opened_extwin) {
+ if (elem && elem.type == 'select-one') {
rcmail.change_identity(elem);
// Focus previously focused element
if (fe && fe.id != rcmail.env.composebody) {
diff --git a/program/js/jstz.min.js b/program/js/jstz.min.js
index 81c5057fd..d5f888cac 100644
--- a/program/js/jstz.min.js
+++ b/program/js/jstz.min.js
@@ -1,11 +1,2 @@
-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
+/*! 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
diff --git a/program/js/list.js b/program/js/list.js
index 9a531eaea..08e4444e1 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -30,6 +30,10 @@ function rcube_list_widget(list, p)
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 = [];
@@ -55,8 +59,8 @@ function rcube_list_widget(list, p)
this.in_selection_before = false;
this.focused = false;
this.drag_mouse_start = null;
- this.dblclick_time = 600;
- this.row_init = function(){};
+ 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')
@@ -73,11 +77,19 @@ rcube_list_widget.prototype = {
*/
init: function()
{
- if (this.list && this.list.tBodies[0]) {
+ 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.list.tBodies[0].rows;
+ var r, len, rows = this.tbody.childNodes;
for (r=0, len=rows.length; r<len; r++) {
this.init_row(rows[r]);
@@ -127,7 +139,8 @@ init_row: function(row)
if (document.all)
row.onselectstart = function() { return false; };
- this.row_init(this.rows[uid]);
+ this.row_init(this.rows[uid]); // legacy support
+ this.triggerEvent('initrow', this.rows[uid]);
}
},
@@ -137,16 +150,24 @@ init_row: function(row)
*/
init_header: function()
{
- if (this.list && this.list.tHead) {
+ 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 (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.list.tHead && this.list.tHead.rows) {
- for (r=0; r<this.list.tHead.rows[0].cells.length; r++) {
+ 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.list.tHead.rows[0].cells[r];
+ col = this.thead.rows[0].cells[r];
col.onmousedown = function(e){ return p.drag_column(e, this); };
this.colcount++;
}
@@ -154,16 +175,63 @@ init_header: function()
}
},
+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)
{
- var tbody = document.createElement('tbody');
+ 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.list.insertBefore(tbody, this.list.tBodies[0]);
- this.list.removeChild(this.list.tBodies[1]);
this.rows = [];
this.rowcount = 0;
@@ -181,12 +249,12 @@ clear: function(sel)
*/
remove_row: function(uid, sel_next)
{
- var obj = this.rows[uid] ? this.rows[uid].obj : null;
+ var node = this.rows[uid] ? this.rows[uid].obj : null;
- if (!obj)
+ if (!node)
return;
- obj.style.display = 'none';
+ node.style.display = 'none';
if (sel_next)
this.select_next();
@@ -199,12 +267,31 @@ remove_row: function(uid, sel_next)
/**
* Add row to the list and initialize it
*/
-insert_row: function(row, attop)
+insert_row: function(row, before)
{
- var tbody = this.list.tBodies[0];
+ 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 (attop && tbody.rows.length)
- tbody.insertBefore(row, tbody.firstChild);
+ if (before && tbody.childNodes.length)
+ tbody.insertBefore(row, (typeof before == 'object' && before.parentNode == tbody) ? before : tbody.firstChild);
else
tbody.appendChild(row);
@@ -212,6 +299,28 @@ insert_row: function(row, attop)
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;
+ }
+},
/**
@@ -230,8 +339,9 @@ focus: function(e)
}
// 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();
- $('iframe').each(function() { this.blur(); });
+ window.focus();
if (e || (e = window.event))
rcube_event.cancel(e);
@@ -270,8 +380,8 @@ drag_column: function(e, col)
this.add_dragfix();
// find selected column number
- for (var i=0; i<this.list.tHead.rows[0].cells.length; i++) {
- if (col == this.list.tHead.rows[0].cells[i]) {
+ 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;
}
@@ -434,6 +544,7 @@ collapse: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -450,7 +561,7 @@ expand: function(row)
this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
}
else {
- var tbody = this.list.tBodies[0];
+ var tbody = this.tbody;
new_row = tbody.firstChild;
depth = 0;
last_expanded_parent_depth = 0;
@@ -482,6 +593,7 @@ expand: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -503,7 +615,7 @@ collapse_all: function(row)
return false;
}
else {
- new_row = this.list.tBodies[0].firstChild;
+ new_row = this.tbody.firstChild;
depth = 0;
}
@@ -525,6 +637,7 @@ collapse_all: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -542,7 +655,7 @@ expand_all: function(row)
this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
}
else {
- new_row = this.list.tBodies[0].firstChild;
+ new_row = this.tbody.firstChild;
depth = 0;
}
@@ -563,6 +676,7 @@ expand_all: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -610,7 +724,7 @@ get_prev_row: function()
get_first_row: function()
{
if (this.rowcount) {
- var i, len, rows = this.list.tBodies[0].rows;
+ 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)
@@ -623,7 +737,7 @@ get_first_row: function()
get_last_row: function()
{
if (this.rowcount) {
- var i, rows = this.list.tBodies[0].rows;
+ 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)
@@ -633,6 +747,22 @@ get_last_row: function()
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
@@ -779,14 +909,20 @@ shift_select: function(id, control)
if (!this.rows[this.shift_start] || !this.selection.length)
this.shift_start = id;
- var n, from_rowIndex = this.rows[this.shift_start].obj.rowIndex,
- to_rowIndex = this.rows[id].obj.rowIndex,
- i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex),
- j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex);
+ 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.rows[n].obj.rowIndex >= i && this.rows[n].obj.rowIndex <= j) {
+ 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);
}
@@ -799,6 +935,13 @@ shift_select: function(id, control)
}
},
+/**
+ * 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
@@ -828,7 +971,7 @@ select_all: function(filter)
for (n in this.rows) {
if (!filter || this.rows[n][filter] == true) {
this.last_selected = n;
- this.highlight_row(n, true);
+ this.highlight_row(n, true, true);
}
else {
$(this.rows[n].obj).removeClass('selected').removeClass('unfocused');
@@ -923,7 +1066,7 @@ get_single_selection: function()
/**
* Highlight/unhighlight a row
*/
-highlight_row: function(id, multiple)
+highlight_row: function(id, multiple, norecur)
{
if (!this.rows[id])
return;
@@ -939,7 +1082,7 @@ highlight_row: function(id, multiple)
if (!this.in_selection(id)) { // select row
this.selection.push(id);
$(this.rows[id].obj).addClass('selected');
- if (!this.rows[id].expanded)
+ if (!norecur && !this.rows[id].expanded)
this.highlight_children(id, true);
}
else { // unselect row
@@ -949,7 +1092,7 @@ highlight_row: function(id, multiple)
this.selection = a_pre.concat(a_post);
$(this.rows[id].obj).removeClass('selected').removeClass('unfocused');
- if (!this.rows[id].expanded)
+ if (!norecur && !this.rows[id].expanded)
this.highlight_children(id, false);
}
}
@@ -967,7 +1110,7 @@ highlight_children: function(id, status)
for (i=0; i<len; i++) {
selected = this.in_selection(children[i]);
if ((status && !selected) || (!status && selected))
- this.highlight_row(children[i], true);
+ this.highlight_row(children[i], true, true);
}
},
@@ -1143,7 +1286,7 @@ drag_mouse_move: function(e)
this.draglayer.html('');
// get subjects of selected messages
- var i, n, obj;
+ var i, n, obj, me;
for (n=0; n<this.selection.length; n++) {
// only show 12 lines
if (n>12) {
@@ -1151,29 +1294,28 @@ drag_mouse_move: function(e)
break;
}
+ me = this;
if (obj = this.rows[this.selection[n]].obj) {
- for (i=0; i<obj.childNodes.length; i++) {
- if (obj.childNodes[i].nodeName == 'TD') {
- if (n == 0)
- this.drag_start_pos = $(obj.childNodes[i]).offset();
-
- if (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == i)) {
- var subject = $(obj.childNodes[i]).text();
+ $('> '+this.col_tagname(), obj).each(function(i,elem){
+ if (n == 0)
+ me.drag_start_pos = $(elem).offset();
- if (!subject)
- break;
+ 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);
- this.draglayer.append(entry);
- break;
+ me.draglayer.append(entry);
}
+
+ return false; // break
}
- }
+ });
}
}
@@ -1228,7 +1370,7 @@ drag_mouse_up: function(e)
// remove temp divs
this.del_dragfix();
- this.triggerEvent('dragend');
+ this.triggerEvent('dragend', e);
return rcube_event.cancel(e);
},
@@ -1248,7 +1390,7 @@ column_drag_mouse_move: function(e)
if (!this.col_draglayer) {
var lpos = $(this.list).offset(),
- cells = this.list.tHead.rows[0].cells;
+ cells = this.thead.rows[0].cells;
// create dragging layer
this.col_draglayer = $('<div>').attr('id', 'rcmcoldraglayer')
@@ -1341,7 +1483,7 @@ column_drag_mouse_up: function(e)
}
}
- this.triggerEvent('column_dragend');
+ this.triggerEvent('column_dragend', e);
return rcube_event.cancel(e);
},
@@ -1404,7 +1546,11 @@ del_dragfix: function()
*/
column_replace: function(from, to)
{
- var len, cells = this.list.tHead.rows[0].cells,
+ // 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');
@@ -1417,8 +1563,8 @@ column_replace: function(from, to)
cells[0].parentNode.replaceChild(elem, td);
// replace list cells
- for (r=0, len=this.list.tBodies[0].rows.length; r<len; r++) {
- row = this.list.tBodies[0].rows[r];
+ for (r=0, len=this.tbody.rows.length; r<len; r++) {
+ row = this.tbody.rows[r];
elem = row.cells[from];
before = row.cells[to];
@@ -1439,6 +1585,9 @@ column_replace: function(from, to)
else if (this.subject_col > from && to >= this.subject_col)
this.subject_col--;
+ if (this.fixed_header)
+ this.init_header();
+
this.triggerEvent('column_replace');
}
diff --git a/program/js/treelist.js b/program/js/treelist.js
index fec2d7f21..5913f44b4 100644
--- a/program/js/treelist.js
+++ b/program/js/treelist.js
@@ -23,552 +23,550 @@
*/
function rcube_treelist_widget(node, p)
{
- // apply some defaults to p
- p = $.extend({
- id_prefix: '',
- autoexpand: 1000,
- selectable: false,
- check_droptarget: function(node){ return !node.virtual }
- }, p || {});
-
- var container = $(node);
- var data = p.data || [];
- var indexbyid = {};
- var selection = null;
- var drag_active = false;
- var box_coords = {};
- var item_coords = [];
- var autoexpand_timer;
- var autoexpand_item;
- var body_scroll_top = 0;
- var list_scroll_top = 0;
- var me = this;
-
-
- /////// export public members and methods
-
- this.container = container;
- this.expand = expand;
- this.collapse = collapse;
- this.select = select;
- this.render = render;
- this.drag_start = drag_start;
- this.drag_end = drag_end;
- this.intersects = intersects;
- this.update = update_node;
- this.insert = insert;
- this.remove = remove;
- this.get_item = get_item;
- this.get_selection = get_selection;
-
-
- /////// startup code (constructor)
-
- // abort if node not found
- if (!container.length)
- return;
-
- if (p.data) {
- index_data({ children:data });
- }
- // load data from DOM
- else {
- update_data();
- }
-
- // register click handlers on list
- container.on('click', 'div.treetoggle', function(e){
- toggle(dom2id($(this).parent()));
- });
-
- container.on('click', 'li', function(e){
- var node = p.selectable ? indexbyid[dom2id($(this))] : null;
- if (node && !node.virtual) {
- select(node.id);
- e.stopPropagation();
- }
- });
-
-
- /////// private methods
-
- /**
- * Collaps a the node with the given ID
- */
- function collapse(id, recursive, set)
- {
- var node;
- if (node = indexbyid[id]) {
- node.collapsed = typeof set == 'undefined' || set;
- update_dom(node);
-
- // Work around a bug in IE6 and IE7, see #1485309
- if (window.bw && (bw.ie6 || bw.ie7) && node.collapsed) {
- id2dom(node.id).next().children('ul:visible').hide().show();
- }
-
- if (recursive && node.children) {
- for (var i=0; i < node.children.length; i++) {
- collapse(node.children[i].id, recursive, set);
- }
- }
-
- me.triggerEvent(node.collapsed ? 'collapse' : 'expand', node);
- }
- }
-
- /**
- * Expand a the node with the given ID
- */
- function expand(id, recursive)
- {
- collapse(id, recursive, false);
- }
-
- /**
- * Toggle collapsed state of a list node
- */
- function toggle(id, recursive)
- {
- var node;
- if (node = indexbyid[id]) {
- collapse(id, recursive, !node.collapsed);
- }
- }
-
- /**
- * Select a tree node by it's ID
- */
- function select(id)
- {
- if (selection) {
- id2dom(selection).removeClass('selected');
- selection = null;
- }
-
- var li = id2dom(id);
- if (li.length) {
- li.addClass('selected');
- selection = id;
- // TODO: expand all parent nodes if collapsed
- scroll_to_node(li);
- }
-
- me.triggerEvent('select', indexbyid[id]);
- }
-
- /**
- * Getter for the currently selected node ID
- */
- function get_selection()
- {
- return selection;
- }
-
- /**
- * Return the DOM element of the list item with the given ID
- */
- function get_item(id)
- {
- return id2dom(id).get(0);
- }
-
- /**
- * Insert the given node
- */
- function insert(node, parent_id, sort)
- {
- var li, parent_li,
- parent_node = parent_id ? indexbyid[parent_id] : null;
-
- // insert as child of an existing node
- if (parent_node) {
- if (!parent_node.children)
- parent_node.children = [];
-
- parent_node.children.push(node);
- parent_li = id2dom(parent_id);
-
- // re-render the entire subtree
- if (parent_node.children.length == 1) {
- render_node(parent_node, parent_li.parent(), parent_li);
- li = id2dom(node.id);
- }
- else {
- // append new node to parent's child list
- li = render_node(node, parent_li.children('ul').first());
- }
- }
- // insert at top level
- else {
- data.push(node);
- li = render_node(node, container);
- }
-
- indexbyid[node.id] = node;
-
- if (sort) {
- resort_node(li, typeof sort == 'string' ? '[class~="' + sort + '"]' : '');
- }
- }
-
- /**
- * Update properties of an existing node
- */
- function update_node(id, updates, sort)
- {
- var li, node = indexbyid[id];
- if (node) {
- li = id2dom(id);
-
- if (updates.id || updates.html || updates.children || updates.classes) {
- $.extend(node, updates);
- render_node(node, li.parent(), li);
- }
-
- if (node.id != id) {
- delete indexbyid[id];
- indexbyid[node.id] = node;
- }
-
- if (sort) {
- resort_node(li, typeof sort == 'string' ? '[class~="' + sort + '"]' : '');
- }
- }
- }
-
- /**
- * Helper method to sort the list of the given item
- */
- function resort_node(li, filter)
- {
- var first, sibling,
- myid = li.get(0).id,
- sortname = li.children().first().text().toUpperCase();
-
- li.parent().children('li' + filter).each(function(i, elem) {
- if (i == 0)
- first = elem;
- if (elem.id == myid) {
- // skip
- }
- else if (elem.id != myid && sortname >= $(elem).children().first().text().toUpperCase()) {
- sibling = elem;
- }
- else {
- return false;
- }
- });
-
- if (sibling) {
- li.insertAfter(sibling);
- }
- else if (first.id != myid) {
- li.insertBefore(first);
- }
-
- // reload data from dom
- update_data();
- }
-
- /**
- * Remove the item with the given ID
- */
- function remove(id)
- {
- var node, li;
- if (node = indexbyid[id]) {
- li = id2dom(id);
- li.remove();
-
- node.deleted = true;
- delete indexbyid[id];
-
- return true;
- }
-
- return false;
- }
-
- /**
- * (Re-)read tree data from DOM
- */
- function update_data()
- {
- data = walk_list(container);
- }
-
- /**
- * Apply the 'collapsed' status of the data node to the corresponding DOM element(s)
- */
- function update_dom(node)
- {
- var li = id2dom(node.id);
- li.children('ul').first()[(node.collapsed ? 'hide' : 'show')]();
- li.children('div.treetoggle').removeClass('collapsed expanded').addClass(node.collapsed ? 'collapsed' : 'expanded');
- me.triggerEvent('toggle', node);
- }
-
- /**
- * Render the tree list from the internal data structure
- */
- function render()
- {
- if (me.triggerEvent('renderBefore', data) === false)
- return;
-
- // remove all child nodes
- container.html('');
-
- // render child nodes
- for (var i=0; i < data.length; i++) {
- render_node(data[i], container);
- }
-
- me.triggerEvent('renderAfter', container);
- }
-
- /**
- * Render a specific node into the DOM list
- */
- function render_node(node, parent, replace)
- {
- if (node.deleted)
- return;
-
- var li = $('<li>')
- .attr('id', p.id_prefix + (p.id_encode ? p.id_encode(node.id) : node.id))
- .addClass((node.classes || []).join(' '));
-
- if (replace)
- replace.replaceWith(li);
- else
- li.appendTo(parent);
-
- if (typeof node.html == 'string') {
- li.html(node.html);
- }
- else if (typeof node.html == 'object') {
- li.append(node.html);
- }
-
- if (node.virtual)
- li.addClass('virtual');
- if (node.id == selection)
- li.addClass('selected');
-
- // add child list and toggle icon
- if (node.children && node.children.length) {
- $('<div class="treetoggle '+(node.collapsed ? 'collapsed' : 'expanded') + '">&nbsp;</div>').appendTo(li);
- var ul = $('<ul>').appendTo(li).attr('class', node.childlistclass);
- if (node.collapsed)
- ul.hide();
-
- for (var i=0; i < node.children.length; i++) {
- render_node(node.children[i], ul);
- }
- }
-
- return li;
- }
-
- /**
- * Recursively walk the DOM tree and build an internal data structure
- * representing the skeleton of this tree list.
- */
- function walk_list(ul)
- {
- var result = [];
- ul.children('li').each(function(i,e){
- var li = $(e), sublist = li.children('ul');
- var node = {
- id: dom2id(li),
- classes: li.attr('class').split(' '),
- virtual: li.hasClass('virtual'),
- html: li.children().first().get(0).outerHTML,
- children: walk_list(sublist)
- }
-
- if (sublist.length) {
- node.childlistclass = sublist.attr('class');
- }
- if (node.children.length) {
- node.collapsed = sublist.css('display') == 'none';
- }
- if (li.hasClass('selected')) {
- selection = node.id;
- }
-
- result.push(node);
- indexbyid[node.id] = node;
- })
-
- return result;
- }
-
- /**
- * Recursively walk the data tree and index nodes by their ID
- */
- function index_data(node)
- {
- if (node.id) {
- indexbyid[node.id] = node;
- }
- for (var c=0; node.children && c < node.children.length; c++) {
- index_data(node.children[c]);
- }
- }
-
- /**
- * Get the (stripped) node ID from the given DOM element
- */
- function dom2id(li)
- {
- var domid = li.attr('id').replace(new RegExp('^' + (p.id_prefix) || '%'), '');
- return p.id_decode ? p.id_decode(domid) : domid;
- }
-
- /**
- * Get the <li> element for the given node ID
- */
- function id2dom(id)
- {
- var domid = p.id_encode ? p.id_encode(id) : id;
- return $('#' + p.id_prefix + domid);
- }
-
- /**
- * Scroll the parent container to make the given list item visible
- */
- function scroll_to_node(li)
- {
- var scroller = container.parent(),
- current_offset = scroller.scrollTop(),
- rel_offset = li.offset().top - scroller.offset().top;
-
- if (rel_offset < 0 || rel_offset + li.height() > scroller.height())
- scroller.scrollTop(rel_offset + current_offset);
- }
-
- ///// drag & drop support
-
- /**
- * When dragging starts, compute absolute bounding boxes of the list and it's items
- * for faster comparisons while mouse is moving
- */
- function drag_start()
- {
- var li, item, height,
- pos = container.offset();
-
- body_scroll_top = bw.ie ? 0 : window.pageYOffset;
- list_scroll_top = container.parent().scrollTop();
-
- drag_active = true;
- box_coords = {
- x1: pos.left,
- y1: pos.top,
- x2: pos.left + container.width(),
- y2: pos.top + container.height()
- };
-
- item_coords = [];
- for (var id in indexbyid) {
- li = id2dom(id);
- item = li.children().first().get(0);
- if (height = item.offsetHeight) {
- pos = $(item).offset();
- item_coords[id] = {
- x1: pos.left,
- y1: pos.top,
- x2: pos.left + item.offsetWidth,
- y2: pos.top + height,
- on: id == autoexpand_item
- };
- }
- }
- }
-
- /**
- * Signal that dragging has stopped
- */
- function drag_end()
- {
- drag_active = false;
-
- if (autoexpand_timer) {
- clearTimeout(autoexpand_timer);
- autoexpand_timer = null;
- autoexpand_item = null;
- }
-
- $('li.droptarget', container).removeClass('droptarget');
- }
-
- /**
- * Determine if the given mouse coords intersect the list and one if its items
- */
- function intersects(mouse, highlight)
- {
- // offsets to compensate for scrolling while dragging a message
- var boffset = bw.ie ? -document.documentElement.scrollTop : body_scroll_top,
- moffset = list_scroll_top - container.parent().scrollTop(),
- result = null;
-
- mouse.top = mouse.y + -moffset - boffset;
-
- // no intersection with list bounding box
- if (mouse.x < box_coords.x1 || mouse.x >= box_coords.x2 || mouse.top < box_coords.y1 || mouse.top >= box_coords.y2) {
- // TODO: optimize performance for this operation
- $('li.droptarget', container).removeClass('droptarget');
- return result;
- }
-
- // check intersection with visible list items
- var pos, node;
- for (var id in item_coords) {
- pos = item_coords[id];
- if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.top >= pos.y1 && mouse.top < pos.y2) {
- node = indexbyid[id];
-
- // if the folder is collapsed, expand it after the configured time
- if (node.children && node.children.length && node.collapsed && p.autoexpand && autoexpand_item != id) {
- if (autoexpand_timer)
- clearTimeout(autoexpand_timer);
-
- autoexpand_item = id;
- autoexpand_timer = setTimeout(function() {
- expand(autoexpand_item);
- drag_start(); // re-calculate item coords
- autoexpand_item = null;
- }, p.autoexpand);
- }
- else if (autoexpand_timer && autoexpand_item != id) {
- clearTimeout(autoexpand_timer);
- autoexpand_item = null;
- autoexpand_timer = null;
- }
-
- // check if this item is accepted as drop target
- if (p.check_droptarget(node)) {
- if (highlight) {
- id2dom(id).addClass('droptarget');
- pos.on = true;
- }
- result = id;
- }
- else {
- result = null;
- }
- }
- else if (pos.on) {
- id2dom(id).removeClass('droptarget');
- pos.on = false;
- }
- }
-
- return result;
- }
+ // apply some defaults to p
+ p = $.extend({
+ id_prefix: '',
+ autoexpand: 1000,
+ selectable: false,
+ check_droptarget: function(node){ return !node.virtual }
+ }, p || {});
+
+ var container = $(node),
+ data = p.data || [],
+ indexbyid = {},
+ selection = null,
+ drag_active = false,
+ box_coords = {},
+ item_coords = [],
+ autoexpand_timer,
+ autoexpand_item,
+ body_scroll_top = 0,
+ list_scroll_top = 0,
+ me = this;
+
+
+ /////// export public members and methods
+
+ this.container = container;
+ this.expand = expand;
+ this.collapse = collapse;
+ this.select = select;
+ this.render = render;
+ this.drag_start = drag_start;
+ this.drag_end = drag_end;
+ this.intersects = intersects;
+ this.update = update_node;
+ this.insert = insert;
+ this.remove = remove;
+ this.get_item = get_item;
+ this.get_selection = get_selection;
+
+ /////// startup code (constructor)
+
+ // abort if node not found
+ if (!container.length)
+ return;
+
+ if (p.data)
+ index_data({ children:data });
+ // load data from DOM
+ else
+ update_data();
+
+ // register click handlers on list
+ container.on('click', 'div.treetoggle', function(e){
+ toggle(dom2id($(this).parent()));
+ });
+
+ container.on('click', 'li', function(e){
+ var node = p.selectable ? indexbyid[dom2id($(this))] : null;
+ if (node && !node.virtual) {
+ select(node.id);
+ e.stopPropagation();
+ }
+ });
+
+
+ /////// private methods
+
+ /**
+ * Collaps a the node with the given ID
+ */
+ function collapse(id, recursive, set)
+ {
+ var node;
+
+ if (node = indexbyid[id]) {
+ node.collapsed = typeof set == 'undefined' || set;
+ update_dom(node);
+
+ // Work around a bug in IE6 and IE7, see #1485309
+ if (window.bw && (bw.ie6 || bw.ie7) && node.collapsed) {
+ id2dom(node.id).next().children('ul:visible').hide().show();
+ }
+
+ if (recursive && node.children) {
+ for (var i=0; i < node.children.length; i++) {
+ collapse(node.children[i].id, recursive, set);
+ }
+ }
+
+ me.triggerEvent(node.collapsed ? 'collapse' : 'expand', node);
+ }
+ }
+
+ /**
+ * Expand a the node with the given ID
+ */
+ function expand(id, recursive)
+ {
+ collapse(id, recursive, false);
+ }
+
+ /**
+ * Toggle collapsed state of a list node
+ */
+ function toggle(id, recursive)
+ {
+ var node;
+ if (node = indexbyid[id]) {
+ collapse(id, recursive, !node.collapsed);
+ }
+ }
+
+ /**
+ * Select a tree node by it's ID
+ */
+ function select(id)
+ {
+ if (selection) {
+ id2dom(selection).removeClass('selected');
+ selection = null;
+ }
+
+ var li = id2dom(id);
+ if (li.length) {
+ li.addClass('selected');
+ selection = id;
+ // TODO: expand all parent nodes if collapsed
+ scroll_to_node(li);
+ }
+
+ me.triggerEvent('select', indexbyid[id]);
+ }
+
+ /**
+ * Getter for the currently selected node ID
+ */
+ function get_selection()
+ {
+ return selection;
+ }
+
+ /**
+ * Return the DOM element of the list item with the given ID
+ */
+ function get_item(id)
+ {
+ return id2dom(id).get(0);
+ }
+
+ /**
+ * Insert the given node
+ */
+ function insert(node, parent_id, sort)
+ {
+ var li, parent_li,
+ parent_node = parent_id ? indexbyid[parent_id] : null;
+
+ // insert as child of an existing node
+ if (parent_node) {
+ if (!parent_node.children)
+ parent_node.children = [];
+
+ parent_node.children.push(node);
+ parent_li = id2dom(parent_id);
+
+ // re-render the entire subtree
+ if (parent_node.children.length == 1) {
+ render_node(parent_node, parent_li.parent(), parent_li);
+ li = id2dom(node.id);
+ }
+ else {
+ // append new node to parent's child list
+ li = render_node(node, parent_li.children('ul').first());
+ }
+ }
+ // insert at top level
+ else {
+ data.push(node);
+ li = render_node(node, container);
+ }
+
+ indexbyid[node.id] = node;
+
+ if (sort) {
+ resort_node(li, typeof sort == 'string' ? '[class~="' + sort + '"]' : '');
+ }
+ }
+
+ /**
+ * Update properties of an existing node
+ */
+ function update_node(id, updates, sort)
+ {
+ var li, node = indexbyid[id];
+
+ if (node) {
+ li = id2dom(id);
+
+ if (updates.id || updates.html || updates.children || updates.classes) {
+ $.extend(node, updates);
+ render_node(node, li.parent(), li);
+ }
+
+ if (node.id != id) {
+ delete indexbyid[id];
+ indexbyid[node.id] = node;
+ }
+
+ if (sort) {
+ resort_node(li, typeof sort == 'string' ? '[class~="' + sort + '"]' : '');
+ }
+ }
+ }
+
+ /**
+ * Helper method to sort the list of the given item
+ */
+ function resort_node(li, filter)
+ {
+ var first, sibling,
+ myid = li.get(0).id,
+ sortname = li.children().first().text().toUpperCase();
+
+ li.parent().children('li' + filter).each(function(i, elem) {
+ if (i == 0)
+ first = elem;
+ if (elem.id == myid) {
+ // skip
+ }
+ else if (elem.id != myid && sortname >= $(elem).children().first().text().toUpperCase()) {
+ sibling = elem;
+ }
+ else {
+ return false;
+ }
+ });
+
+ if (sibling) {
+ li.insertAfter(sibling);
+ }
+ else if (first.id != myid) {
+ li.insertBefore(first);
+ }
+
+ // reload data from dom
+ update_data();
+ }
+
+ /**
+ * Remove the item with the given ID
+ */
+ function remove(id)
+ {
+ var node, li;
+
+ if (node = indexbyid[id]) {
+ li = id2dom(id);
+ li.remove();
+
+ node.deleted = true;
+ delete indexbyid[id];
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * (Re-)read tree data from DOM
+ */
+ function update_data()
+ {
+ data = walk_list(container);
+ }
+
+ /**
+ * Apply the 'collapsed' status of the data node to the corresponding DOM element(s)
+ */
+ function update_dom(node)
+ {
+ var li = id2dom(node.id);
+ li.children('ul').first()[(node.collapsed ? 'hide' : 'show')]();
+ li.children('div.treetoggle').removeClass('collapsed expanded').addClass(node.collapsed ? 'collapsed' : 'expanded');
+ me.triggerEvent('toggle', node);
+ }
+
+ /**
+ * Render the tree list from the internal data structure
+ */
+ function render()
+ {
+ if (me.triggerEvent('renderBefore', data) === false)
+ return;
+
+ // remove all child nodes
+ container.html('');
+
+ // render child nodes
+ for (var i=0; i < data.length; i++) {
+ render_node(data[i], container);
+ }
+
+ me.triggerEvent('renderAfter', container);
+ }
+
+ /**
+ * Render a specific node into the DOM list
+ */
+ function render_node(node, parent, replace)
+ {
+ if (node.deleted)
+ return;
+
+ var li = $('<li>')
+ .attr('id', p.id_prefix + (p.id_encode ? p.id_encode(node.id) : node.id))
+ .addClass((node.classes || []).join(' '));
+
+ if (replace)
+ replace.replaceWith(li);
+ else
+ li.appendTo(parent);
+
+ if (typeof node.html == 'string')
+ li.html(node.html);
+ else if (typeof node.html == 'object')
+ li.append(node.html);
+
+ if (node.virtual)
+ li.addClass('virtual');
+ if (node.id == selection)
+ li.addClass('selected');
+
+ // add child list and toggle icon
+ if (node.children && node.children.length) {
+ $('<div class="treetoggle '+(node.collapsed ? 'collapsed' : 'expanded') + '">&nbsp;</div>').appendTo(li);
+ var ul = $('<ul>').appendTo(li).attr('class', node.childlistclass);
+ if (node.collapsed)
+ ul.hide();
+
+ for (var i=0; i < node.children.length; i++) {
+ render_node(node.children[i], ul);
+ }
+ }
+
+ return li;
+ }
+
+ /**
+ * Recursively walk the DOM tree and build an internal data structure
+ * representing the skeleton of this tree list.
+ */
+ function walk_list(ul)
+ {
+ var result = [];
+ ul.children('li').each(function(i,e){
+ var li = $(e), sublist = li.children('ul');
+ var node = {
+ id: dom2id(li),
+ classes: li.attr('class').split(' '),
+ virtual: li.hasClass('virtual'),
+ html: li.children().first().get(0).outerHTML,
+ children: walk_list(sublist)
+ }
+
+ if (sublist.length) {
+ node.childlistclass = sublist.attr('class');
+ }
+ if (node.children.length) {
+ node.collapsed = sublist.css('display') == 'none';
+ }
+ if (li.hasClass('selected')) {
+ selection = node.id;
+ }
+
+ result.push(node);
+ indexbyid[node.id] = node;
+ })
+
+ return result;
+ }
+
+ /**
+ * Recursively walk the data tree and index nodes by their ID
+ */
+ function index_data(node)
+ {
+ if (node.id) {
+ indexbyid[node.id] = node;
+ }
+ for (var c=0; node.children && c < node.children.length; c++) {
+ index_data(node.children[c]);
+ }
+ }
+
+ /**
+ * Get the (stripped) node ID from the given DOM element
+ */
+ function dom2id(li)
+ {
+ var domid = li.attr('id').replace(new RegExp('^' + (p.id_prefix) || '%'), '');
+ return p.id_decode ? p.id_decode(domid) : domid;
+ }
+
+ /**
+ * Get the <li> element for the given node ID
+ */
+ function id2dom(id)
+ {
+ var domid = p.id_encode ? p.id_encode(id) : id;
+ return $('#' + p.id_prefix + domid);
+ }
+
+ /**
+ * Scroll the parent container to make the given list item visible
+ */
+ function scroll_to_node(li)
+ {
+ var scroller = container.parent(),
+ current_offset = scroller.scrollTop(),
+ rel_offset = li.offset().top - scroller.offset().top;
+
+ if (rel_offset < 0 || rel_offset + li.height() > scroller.height())
+ scroller.scrollTop(rel_offset + current_offset);
+ }
+
+ ///// drag & drop support
+
+ /**
+ * When dragging starts, compute absolute bounding boxes of the list and it's items
+ * for faster comparisons while mouse is moving
+ */
+ function drag_start()
+ {
+ var li, item, height,
+ pos = container.offset();
+
+ body_scroll_top = bw.ie ? 0 : window.pageYOffset;
+ list_scroll_top = container.parent().scrollTop();
+
+ drag_active = true;
+ box_coords = {
+ x1: pos.left,
+ y1: pos.top,
+ x2: pos.left + container.width(),
+ y2: pos.top + container.height()
+ };
+
+ item_coords = [];
+ for (var id in indexbyid) {
+ li = id2dom(id);
+ item = li.children().first().get(0);
+ if (height = item.offsetHeight) {
+ pos = $(item).offset();
+ item_coords[id] = {
+ x1: pos.left,
+ y1: pos.top,
+ x2: pos.left + item.offsetWidth,
+ y2: pos.top + height,
+ on: id == autoexpand_item
+ };
+ }
+ }
+ }
+
+ /**
+ * Signal that dragging has stopped
+ */
+ function drag_end()
+ {
+ drag_active = false;
+
+ if (autoexpand_timer) {
+ clearTimeout(autoexpand_timer);
+ autoexpand_timer = null;
+ autoexpand_item = null;
+ }
+
+ $('li.droptarget', container).removeClass('droptarget');
+ }
+
+ /**
+ * Determine if the given mouse coords intersect the list and one if its items
+ */
+ function intersects(mouse, highlight)
+ {
+ // offsets to compensate for scrolling while dragging a message
+ var boffset = bw.ie ? -document.documentElement.scrollTop : body_scroll_top,
+ moffset = list_scroll_top - container.parent().scrollTop(),
+ result = null;
+
+ mouse.top = mouse.y + -moffset - boffset;
+
+ // no intersection with list bounding box
+ if (mouse.x < box_coords.x1 || mouse.x >= box_coords.x2 || mouse.top < box_coords.y1 || mouse.top >= box_coords.y2) {
+ // TODO: optimize performance for this operation
+ $('li.droptarget', container).removeClass('droptarget');
+ return result;
+ }
+
+ // check intersection with visible list items
+ var pos, node;
+ for (var id in item_coords) {
+ pos = item_coords[id];
+ if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.top >= pos.y1 && mouse.top < pos.y2) {
+ node = indexbyid[id];
+
+ // if the folder is collapsed, expand it after the configured time
+ if (node.children && node.children.length && node.collapsed && p.autoexpand && autoexpand_item != id) {
+ if (autoexpand_timer)
+ clearTimeout(autoexpand_timer);
+
+ autoexpand_item = id;
+ autoexpand_timer = setTimeout(function() {
+ expand(autoexpand_item);
+ drag_start(); // re-calculate item coords
+ autoexpand_item = null;
+ }, p.autoexpand);
+ }
+ else if (autoexpand_timer && autoexpand_item != id) {
+ clearTimeout(autoexpand_timer);
+ autoexpand_item = null;
+ autoexpand_timer = null;
+ }
+
+ // check if this item is accepted as drop target
+ if (p.check_droptarget(node)) {
+ if (highlight) {
+ id2dom(id).addClass('droptarget');
+ pos.on = true;
+ }
+ result = id;
+ }
+ else {
+ result = null;
+ }
+ }
+ else if (pos.on) {
+ id2dom(id).removeClass('droptarget');
+ pos.on = false;
+ }
+ }
+
+ return result;
+ }
}
// use event processing functions from Roundcube's rcube_event_engine
diff --git a/program/lib/Mail/mime.php b/program/lib/Mail/mime.php
index 69a032cb8..e079af7e9 100644
--- a/program/lib/Mail/mime.php
+++ b/program/lib/Mail/mime.php
@@ -48,7 +48,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version CVS: $Id$
* @link http://pear.php.net/package/Mail_mime
*
* This class is based on HTML Mime Mail class from
@@ -89,7 +89,7 @@ require_once 'Mail/mimePart.php';
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version Release: @package_version@
* @link http://pear.php.net/package/Mail_mime
*/
class Mail_mime
@@ -254,6 +254,7 @@ class Mail_mime
$this->_txtbody .= $cont;
}
}
+
return true;
}
@@ -347,7 +348,7 @@ class Mail_mime
}
if (!$content_id) {
- $content_id = md5(uniqid(time()));
+ $content_id = preg_replace('/[^0-9a-zA-Z]/', '', uniqid(time(), true));
}
$this->_html_images[] = array(
@@ -429,8 +430,7 @@ class Mail_mime
if (!strlen($filename)) {
$msg = "The supplied filename for the attachment can't be empty";
- $err = PEAR::raiseError($msg);
- return $err;
+ return $this->_raiseError($msg);
}
$this->_parts[] = array(
@@ -465,16 +465,13 @@ class Mail_mime
{
// Check state of file and raise an error properly
if (!file_exists($file_name)) {
- $err = PEAR::raiseError('File not found: ' . $file_name);
- return $err;
+ return $this->_raiseError('File not found: ' . $file_name);
}
if (!is_file($file_name)) {
- $err = PEAR::raiseError('Not a regular file: ' . $file_name);
- return $err;
+ return $this->_raiseError('Not a regular file: ' . $file_name);
}
if (!is_readable($file_name)) {
- $err = PEAR::raiseError('File is not readable: ' . $file_name);
- return $err;
+ return $this->_raiseError('File is not readable: ' . $file_name);
}
// Temporarily reset magic_quotes_runtime and read file contents
@@ -500,7 +497,7 @@ class Mail_mime
* @return object The text mimePart object
* @access private
*/
- function _addTextPart(&$obj, $text)
+ function &_addTextPart(&$obj = null, $text = '')
{
$params['content_type'] = 'text/plain';
$params['encoding'] = $this->_build_params['text_encoding'];
@@ -509,11 +506,11 @@ class Mail_mime
if (is_object($obj)) {
$ret = $obj->addSubpart($text, $params);
- return $ret;
} else {
$ret = new Mail_mimePart($text, $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -526,7 +523,7 @@ class Mail_mime
* @return object The html mimePart object
* @access private
*/
- function _addHtmlPart(&$obj)
+ function &_addHtmlPart(&$obj = null)
{
$params['content_type'] = 'text/html';
$params['encoding'] = $this->_build_params['html_encoding'];
@@ -535,11 +532,11 @@ class Mail_mime
if (is_object($obj)) {
$ret = $obj->addSubpart($this->_htmlbody, $params);
- return $ret;
} else {
$ret = new Mail_mimePart($this->_htmlbody, $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -550,9 +547,8 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
- function _addMixedPart()
+ function &_addMixedPart()
{
- $params = array();
$params['content_type'] = 'multipart/mixed';
$params['eol'] = $this->_build_params['eol'];
@@ -572,17 +568,18 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
- function _addAlternativePart(&$obj)
+ function &_addAlternativePart(&$obj = null)
{
$params['content_type'] = 'multipart/alternative';
$params['eol'] = $this->_build_params['eol'];
if (is_object($obj)) {
- return $obj->addSubpart('', $params);
+ $ret = $obj->addSubpart('', $params);
} else {
$ret = new Mail_mimePart('', $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -596,17 +593,18 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
- function _addRelatedPart(&$obj)
+ function &_addRelatedPart(&$obj = null)
{
$params['content_type'] = 'multipart/related';
$params['eol'] = $this->_build_params['eol'];
if (is_object($obj)) {
- return $obj->addSubpart('', $params);
+ $ret = $obj->addSubpart('', $params);
} else {
$ret = new Mail_mimePart('', $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -619,7 +617,7 @@ class Mail_mime
* @return object The image mimePart object
* @access private
*/
- function _addHtmlImagePart(&$obj, $value)
+ function &_addHtmlImagePart(&$obj, $value)
{
$params['content_type'] = $value['c_type'];
$params['encoding'] = 'base64';
@@ -650,7 +648,7 @@ class Mail_mime
* @return object The image mimePart object
* @access private
*/
- function _addAttachmentPart(&$obj, $value)
+ function &_addAttachmentPart(&$obj, $value)
{
$params['eol'] = $this->_build_params['eol'];
$params['filename'] = $value['name'];
@@ -700,9 +698,9 @@ class Mail_mime
*
* @param string $separation The separation between these two parts.
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() function. See get() for more info.
* @param array $headers The extra headers that should be passed
- * to the &headers() function.
+ * to the headers() method.
* See that function for more info.
* @param bool $overwrite Overwrite the existing headers with new.
*
@@ -722,9 +720,7 @@ class Mail_mime
return $body;
}
- $head = $this->txtHeaders($headers, $overwrite);
- $mail = $head . $separation . $body;
- return $mail;
+ return $this->txtHeaders($headers, $overwrite) . $separation . $body;
}
/**
@@ -732,7 +728,7 @@ class Mail_mime
* mail delivery method.
*
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() method. See get() for more info.
*
* @return mixed The e-mail body or PEAR error object
* @access public
@@ -748,9 +744,9 @@ class Mail_mime
*
* @param string $filename Output file location
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() method. See get() for more info.
* @param array $headers The extra headers that should be passed
- * to the &headers() function.
+ * to the headers() function.
* See that function for more info.
* @param bool $overwrite Overwrite the existing headers with new.
*
@@ -762,8 +758,7 @@ class Mail_mime
{
// Check state of file and raise an error properly
if (file_exists($filename) && !is_writable($filename)) {
- $err = PEAR::raiseError('File is not writable: ' . $filename);
- return $err;
+ return $this->_raiseError('File is not writable: ' . $filename);
}
// Temporarily reset magic_quotes_runtime and read file contents
@@ -772,15 +767,13 @@ class Mail_mime
}
if (!($fh = fopen($filename, 'ab'))) {
- $err = PEAR::raiseError('Unable to open file: ' . $filename);
- return $err;
+ return $this->_raiseError('Unable to open file: ' . $filename);
}
// Write message headers into file (skipping Content-* headers)
$head = $this->txtHeaders($headers, $overwrite, true);
if (fwrite($fh, $head) === false) {
- $err = PEAR::raiseError('Error writing to file: ' . $filename);
- return $err;
+ return $this->_raiseError('Error writing to file: ' . $filename);
}
fclose($fh);
@@ -797,10 +790,10 @@ class Mail_mime
/**
* Writes (appends) the complete e-mail body into file.
- *
+ *
* @param string $filename Output file location
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() method. See get() for more info.
*
* @return mixed True or PEAR error object
* @access public
@@ -810,8 +803,7 @@ class Mail_mime
{
// Check state of file and raise an error properly
if (file_exists($filename) && !is_writable($filename)) {
- $err = PEAR::raiseError('File is not writable: ' . $filename);
- return $err;
+ return $this->_raiseError('File is not writable: ' . $filename);
}
// Temporarily reset magic_quotes_runtime and read file contents
@@ -820,8 +812,7 @@ class Mail_mime
}
if (!($fh = fopen($filename, 'ab'))) {
- $err = PEAR::raiseError('Unable to open file: ' . $filename);
- return $err;
+ return $this->_raiseError('Unable to open file: ' . $filename);
}
// Write the rest of the message into file
@@ -844,7 +835,7 @@ class Mail_mime
* @return mixed The MIME message content string, null or PEAR error object
* @access public
*/
- function &get($params = null, $filename = null, $skip_head = false)
+ function get($params = null, $filename = null, $skip_head = false)
{
if (isset($params)) {
while (list($key, $value) = each($params)) {
@@ -1004,8 +995,7 @@ class Mail_mime
}
if (!isset($message)) {
- $ret = null;
- return $ret;
+ return null;
}
// Use saved boundary
@@ -1023,16 +1013,14 @@ class Mail_mime
return $headers;
}
$this->_headers = array_merge($this->_headers, $headers);
- $ret = null;
- return $ret;
+ return null;
} else {
$output = $message->encode($boundary, $skip_head);
if ($this->_isError($output)) {
return $output;
}
$this->_headers = array_merge($this->_headers, $output['headers']);
- $body = $output['body'];
- return $body;
+ return $output['body'];
}
}
@@ -1050,7 +1038,7 @@ class Mail_mime
* @return array Assoc array with the mime headers
* @access public
*/
- function &headers($xtra_headers = null, $overwrite = false, $skip_content = false)
+ function headers($xtra_headers = null, $overwrite = false, $skip_content = false)
{
// Add mime version header
$headers['MIME-Version'] = '1.0';
@@ -1473,7 +1461,7 @@ class Mail_mime
}
/**
- * PEAR::isError wrapper
+ * PEAR::isError implementation
*
* @param mixed $data Object
*
@@ -1490,4 +1478,18 @@ class Mail_mime
return false;
}
+ /**
+ * PEAR::raiseError implementation
+ *
+ * @param $message A text error message
+ *
+ * @return PEAR_Error Instance of PEAR_Error
+ * @access private
+ */
+ function _raiseError($message)
+ {
+ // PEAR::raiseError() is not PHP 5.4 compatible
+ return new PEAR_Error($message);
+ }
+
} // End of class
diff --git a/program/lib/Mail/mimePart.php b/program/lib/Mail/mimePart.php
index f3e75dd10..c6e9f4aa8 100644
--- a/program/lib/Mail/mimePart.php
+++ b/program/lib/Mail/mimePart.php
@@ -48,7 +48,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version CVS: $Id$
* @link http://pear.php.net/package/Mail_mime
*/
@@ -70,7 +70,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version Release: @package_version@
* @link http://pear.php.net/package/Mail_mime
*/
class Mail_mimePart
@@ -368,12 +368,12 @@ class Mail_mimePart
function encodeToFile($filename, $boundary=null, $skip_head=false)
{
if (file_exists($filename) && !is_writable($filename)) {
- $err = PEAR::raiseError('File is not writeable: ' . $filename);
+ $err = $this->_raiseError('File is not writeable: ' . $filename);
return $err;
}
if (!($fh = fopen($filename, 'ab'))) {
- $err = PEAR::raiseError('Unable to open file: ' . $filename);
+ $err = $this->_raiseError('Unable to open file: ' . $filename);
return $err;
}
@@ -456,7 +456,7 @@ class Mail_mimePart
* @param array $params The parameters for the subpart, same
* as the $params argument for constructor.
*
- * @return Mail_mimePart A reference to the part you just added. It is
+ * @return Mail_mimePart A reference to the part you just added. In PHP4, it is
* crucial if using multipart/* in your subparts that
* you use =& in your script when calling this function,
* otherwise you will not be able to add further subparts.
@@ -464,8 +464,8 @@ class Mail_mimePart
*/
function &addSubpart($body, $params)
{
- $this->_subparts[] = new Mail_mimePart($body, $params);
- return $this->_subparts[count($this->_subparts) - 1];
+ $this->_subparts[] = $part = new Mail_mimePart($body, $params);
+ return $part;
}
/**
@@ -511,12 +511,12 @@ class Mail_mimePart
function _getEncodedDataFromFile($filename, $encoding, $fh=null)
{
if (!is_readable($filename)) {
- $err = PEAR::raiseError('Unable to read file: ' . $filename);
+ $err = $this->_raiseError('Unable to read file: ' . $filename);
return $err;
}
if (!($fd = fopen($filename, 'rb'))) {
- $err = PEAR::raiseError('Could not open file: ' . $filename);
+ $err = $this->_raiseError('Could not open file: ' . $filename);
return $err;
}
@@ -648,7 +648,7 @@ class Mail_mimePart
}
/**
- * Encodes the paramater of a header.
+ * Encodes the parameter of a header.
*
* @param string $name The name of the header-parameter
* @param string $value The value of the paramter
@@ -1013,7 +1013,7 @@ class Mail_mimePart
$value = substr($value, $cutpoint);
$cutpoint = $maxLength;
// RFC 2047 specifies that any split header should
- // be seperated by a CRLF SPACE.
+ // be separated by a CRLF SPACE.
if ($output) {
$output .= $eol . ' ';
}
@@ -1055,7 +1055,7 @@ class Mail_mimePart
}
// RFC 2047 specifies that any split header should
- // be seperated by a CRLF SPACE
+ // be separated by a CRLF SPACE
if ($output) {
$output .= $eol . ' ';
}
@@ -1227,7 +1227,7 @@ class Mail_mimePart
}
/**
- * PEAR::isError wrapper
+ * PEAR::isError implementation
*
* @param mixed $data Object
*
@@ -1244,4 +1244,18 @@ class Mail_mimePart
return false;
}
+ /**
+ * PEAR::raiseError implementation
+ *
+ * @param $message A text error message
+ *
+ * @return PEAR_Error Instance of PEAR_Error
+ * @access private
+ */
+ function _raiseError($message)
+ {
+ // PEAR::raiseError() is not PHP 5.4 compatible
+ return new PEAR_Error($message);
+ }
+
} // End of class
diff --git a/program/lib/Net/Socket.php b/program/lib/Net/Socket.php
index dd1047c43..bf1d1bbcd 100644
--- a/program/lib/Net/Socket.php
+++ b/program/lib/Net/Socket.php
@@ -4,7 +4,7 @@
*
* PHP Version 4
*
- * Copyright (c) 1997-2003 The PHP Group
+ * Copyright (c) 1997-2013 The PHP Group
*
* This source file is subject to version 2.0 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
@@ -23,7 +23,6 @@
* @author Chuck Hagenbuch <chuck@horde.org>
* @copyright 1997-2003 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP 2.02
- * @version CVS: $Id$
* @link http://pear.php.net/packages/Net_Socket
*/
@@ -77,11 +76,11 @@ class Net_Socket extends PEAR
var $port = 0;
/**
- * Number of seconds to wait on socket connections before assuming
+ * Number of seconds to wait on socket operations before assuming
* there's no more data. Defaults to no timeout.
- * @var integer $timeout
+ * @var integer|float $timeout
*/
- var $timeout = false;
+ var $timeout = null;
/**
* Number of bytes to read at a time in readLine() and
@@ -100,17 +99,17 @@ class Net_Socket extends PEAR
* Connect to the specified port. If called when the socket is
* already connected, it disconnects and connects again.
*
- * @param string $addr IP address or host name.
+ * @param string $addr IP address or host name (may be with protocol prefix).
* @param integer $port TCP port number.
* @param boolean $persistent (optional) Whether the connection is
* persistent (kept open between requests
* by the web server).
- * @param integer $timeout (optional) How long to wait for data.
+ * @param integer $timeout (optional) Connection socket timeout.
* @param array $options See options for stream_context_create.
*
* @access public
*
- * @return boolean | PEAR_Error True on success or a PEAR_Error on failure.
+ * @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
*/
function connect($addr, $port = 0, $persistent = null,
$timeout = null, $options = null)
@@ -122,11 +121,10 @@ class Net_Socket extends PEAR
if (!$addr) {
return $this->raiseError('$addr cannot be empty');
- } elseif (strspn($addr, '.0123456789') == strlen($addr) ||
- strstr($addr, '/') !== false) {
- $this->addr = $addr;
+ } else if (strspn($addr, ':.0123456789') == strlen($addr)) {
+ $this->addr = strpos($addr, ':') !== false ? '['.$addr.']' : $addr;
} else {
- $this->addr = @gethostbyname($addr);
+ $this->addr = $addr;
}
$this->port = $port % 65536;
@@ -135,22 +133,17 @@ class Net_Socket extends PEAR
$this->persistent = $persistent;
}
- if ($timeout !== null) {
- $this->timeout = $timeout;
- }
-
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
$errno = 0;
$errstr = '';
$old_track_errors = @ini_set('track_errors', 1);
+ if ($timeout <= 0) {
+ $timeout = @ini_get('default_socket_timeout');
+ }
+
if ($options && function_exists('stream_context_create')) {
- if ($this->timeout) {
- $timeout = $this->timeout;
- } else {
- $timeout = 0;
- }
$context = stream_context_create($options);
// Since PHP 5 fsockopen doesn't allow context specification
@@ -169,12 +162,7 @@ class Net_Socket extends PEAR
$errstr, $timeout, $context);
}
} else {
- if ($this->timeout) {
- $fp = @$openfunc($this->addr, $this->port, $errno,
- $errstr, $this->timeout);
- } else {
- $fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
- }
+ $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout);
}
if (!$fp) {
@@ -187,7 +175,7 @@ class Net_Socket extends PEAR
@ini_set('track_errors', $old_track_errors);
$this->fp = $fp;
-
+ $this->setTimeout();
return $this->setBlocking($this->blocking);
}
@@ -258,18 +246,31 @@ class Net_Socket extends PEAR
* expressed in the sum of seconds and microseconds
*
* @param integer $seconds Seconds.
- * @param integer $microseconds Microseconds.
+ * @param integer $microseconds Microseconds, optional.
*
* @access public
- * @return mixed true on success or a PEAR_Error instance otherwise
+ * @return mixed True on success or false on failure or
+ * a PEAR_Error instance when not connected
*/
- function setTimeout($seconds, $microseconds)
+ function setTimeout($seconds = null, $microseconds = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
- return socket_set_timeout($this->fp, $seconds, $microseconds);
+ if ($seconds === null && $microseconds === null) {
+ $seconds = (int) $this->timeout;
+ $microseconds = (int) (($this->timeout - $seconds) * 1000000);
+ } else {
+ $this->timeout = $seconds + $microseconds/1000000;
+ }
+
+ if ($this->timeout > 0) {
+ return stream_set_timeout($this->fp, (int) $seconds, (int) $microseconds);
+ }
+ else {
+ return false;
+ }
}
/**
@@ -315,17 +316,20 @@ class Net_Socket extends PEAR
return $this->raiseError('not connected');
}
- return socket_get_status($this->fp);
+ return stream_get_meta_data($this->fp);
}
/**
* Get a specified line of data
*
- * @param int $size ??
+ * @param int $size Reading ends when size - 1 bytes have been read,
+ * or a newline or an EOF (whichever comes first).
+ * If no size is specified, it will keep reading from
+ * the stream until it reaches the end of the line.
*
* @access public
- * @return $size bytes of data from the socket, or a PEAR_Error if
- * not connected.
+ * @return mixed $size bytes of data from the socket, or a PEAR_Error if
+ * not connected. If an error occurs, FALSE is returned.
*/
function gets($size = null)
{
@@ -370,9 +374,10 @@ class Net_Socket extends PEAR
*
* @access public
* @return mixed If the socket is not connected, returns an instance of
- * PEAR_Error
- * If the write succeeds, returns the number of bytes written
+ * PEAR_Error.
+ * If the write succeeds, returns the number of bytes written.
* If the write fails, returns false.
+ * If the socket times out, returns an instance of PEAR_Error.
*/
function write($data, $blocksize = null)
{
@@ -381,7 +386,22 @@ class Net_Socket extends PEAR
}
if (is_null($blocksize) && !OS_WINDOWS) {
- return @fwrite($this->fp, $data);
+ $written = @fwrite($this->fp, $data);
+
+ // Check for timeout or lost connection
+ if (!$written) {
+ $meta_data = $this->getStatus();
+
+ if (!is_array($meta_data)) {
+ return $meta_data; // PEAR_Error
+ }
+
+ if (!empty($meta_data['timed_out'])) {
+ return $this->raiseError('timed out');
+ }
+ }
+
+ return $written;
} else {
if (is_null($blocksize)) {
$blocksize = 1024;
@@ -391,9 +411,22 @@ class Net_Socket extends PEAR
$size = strlen($data);
while ($pos < $size) {
$written = @fwrite($this->fp, substr($data, $pos, $blocksize));
+
+ // Check for timeout or lost connection
if (!$written) {
+ $meta_data = $this->getStatus();
+
+ if (!is_array($meta_data)) {
+ return $meta_data; // PEAR_Error
+ }
+
+ if (!empty($meta_data['timed_out'])) {
+ return $this->raiseError('timed out');
+ }
+
return $written;
}
+
$pos += $written;
}
@@ -407,7 +440,7 @@ class Net_Socket extends PEAR
* @param string $data Data to write
*
* @access public
- * @return mixed fputs result, or an error
+ * @return mixed fwrite() result, or PEAR_Error when not connected
*/
function writeLine($data)
{
diff --git a/program/lib/Roundcube/bootstrap.php b/program/lib/Roundcube/bootstrap.php
index 0640a9448..182ea1232 100644
--- a/program/lib/Roundcube/bootstrap.php
+++ b/program/lib/Roundcube/bootstrap.php
@@ -31,16 +31,25 @@ $config = array(
// critical PHP settings here. Only these, which doesn't provide
// an error/warning in the logs later. See (#1486307).
'mbstring.func_overload' => 0,
- 'suhosin.session.encrypt' => 0,
- 'session.auto_start' => 0,
- 'file_uploads' => 1,
'magic_quotes_runtime' => 0,
'magic_quotes_sybase' => 0, // #1488506
);
+
+// check these additional ini settings if not called via CLI
+if (php_sapi_name() != 'cli') {
+ $config += array(
+ 'suhosin.session.encrypt' => 0,
+ 'file_uploads' => 1,
+ );
+}
+
foreach ($config as $optname => $optval) {
- if ($optval != ini_get($optname) && @ini_set($optname, $optval) === false) {
- die("ERROR: Wrong '$optname' option value and it wasn't possible to set it to required value ($optval).\n"
- ."Check your PHP configuration (including php_admin_flag).");
+ $ini_optval = filter_var(ini_get($optname), FILTER_VALIDATE_BOOLEAN);
+ if ($optval != $ini_optval && @ini_set($optname, $optval) === false) {
+ $error = "ERROR: Wrong '$optname' option value and it wasn't possible to set it to required value ($optval).\n"
+ . "Check your PHP configuration (including php_admin_flag).";
+ if (defined('STDERR')) fwrite(STDERR, $error); else echo $error;
+ exit(1);
}
}
@@ -284,32 +293,6 @@ 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 592720308..3e6e47a56 100644
--- a/program/lib/Roundcube/html.php
+++ b/program/lib/Roundcube/html.php
@@ -35,6 +35,7 @@ class html
public static $common_attrib = array('id','class','style','title','align');
public static $containers = array('iframe','div','span','p','h1','h2','h3','form','textarea','table','thead','tbody','tr','th','td','style','script');
+
/**
* Constructor
*
@@ -217,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')));
+ array('src','name','width','height','border','frameborder','onload')));
}
/**
@@ -332,7 +333,16 @@ class html
*/
public static function quote($str)
{
- return @htmlspecialchars($str, ENT_COMPAT, RCUBE_CHARSET);
+ static $flags;
+
+ if (!$flags) {
+ $flags = ENT_COMPAT;
+ if (defined('ENT_SUBSTITUTE')) {
+ $flags |= ENT_SUBSTITUTE;
+ }
+ }
+
+ return @htmlspecialchars($str, $flags, RCUBE_CHARSET);
}
}
@@ -350,8 +360,8 @@ class html_inputfield extends html
protected $allowed = array(
'type','name','value','size','tabindex','autocapitalize',
'autocomplete','checked','onchange','onclick','disabled','readonly',
- 'spellcheck','results','maxlength','src','multiple','placeholder',
- 'autofocus',
+ 'spellcheck','results','maxlength','src','multiple','accept',
+ 'placeholder','autofocus',
);
/**
@@ -668,6 +678,11 @@ 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;
+ }
}
/**
@@ -769,6 +784,11 @@ class html_table extends html
$index = $this->rowindex;
}
+ // make sure row object exists (#1489094)
+ if (!$this->rows[$index]) {
+ $this->rows[$index] = new stdClass;
+ }
+
$this->rows[$index]->attrib = $attr;
}
@@ -806,19 +826,20 @@ class html_table extends html
if (!empty($this->header)) {
$rowcontent = '';
foreach ($this->header as $c => $col) {
- $rowcontent .= self::tag('td', $col->attrib, $col->content);
+ $rowcontent .= self::tag($this->_col_tagname(), $col->attrib, $col->content);
}
- $thead = self::tag('thead', null, self::tag('tr', null, $rowcontent, parent::$common_attrib));
+ $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);
}
foreach ($this->rows as $r => $row) {
$rowcontent = '';
foreach ($row->cells as $c => $col) {
- $rowcontent .= self::tag('td', $col->attrib, $col->content);
+ $rowcontent .= self::tag($this->_col_tagname(), $col->attrib, $col->content);
}
if ($r < $this->rowindex || count($row->cells)) {
- $tbody .= self::tag('tr', $row->attrib, $rowcontent, parent::$common_attrib);
+ $tbody .= self::tag($this->_row_tagname(), $row->attrib, $rowcontent, parent::$common_attrib);
}
}
@@ -827,7 +848,7 @@ class html_table extends html
}
// add <tbody>
- $this->content = $thead . self::tag('tbody', null, $tbody);
+ $this->content = $thead . ($this->tagname == 'table' ? self::tag('tbody', null, $tbody) : $tbody);
unset($this->attrib['cols'], $this->attrib['rowsonly']);
return parent::show();
@@ -852,4 +873,22 @@ 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 3ae511e1e..ce97cd0a5 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)
+ static function get_instance($mode = 0, $env = '')
{
if (!self::$instance) {
- self::$instance = new rcube();
+ self::$instance = new rcube($env);
self::$instance->init($mode);
}
@@ -123,10 +123,10 @@ class rcube
/**
* Private constructor
*/
- protected function __construct()
+ protected function __construct($env = '')
{
// load configuration
- $this->config = new rcube_config;
+ $this->config = new rcube_config($env);
$this->plugins = new rcube_dummy_plugin_api;
register_shutdown_function(array($this, 'shutdown'));
@@ -258,6 +258,39 @@ 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
@@ -345,6 +378,7 @@ 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,
@@ -405,6 +439,7 @@ class rcube
$sess_domain = $this->config->get('session_domain');
$sess_path = $this->config->get('session_path');
$lifetime = $this->config->get('session_lifetime', 0) * 60;
+ $is_secure = $this->config->get('use_https') || rcube_utils::https_check();
// set session domain
if ($sess_domain) {
@@ -419,34 +454,44 @@ class rcube
ini_set('session.gc_maxlifetime', $lifetime * 2);
}
- ini_set('session.cookie_secure', rcube_utils::https_check());
+ ini_set('session.cookie_secure', $is_secure);
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, 'temp_gc'));
- $this->session->register_gc_handler(array($this, 'cache_gc'));
-
+ $this->session->register_gc_handler(array($this, 'gc'));
$this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
$this->session->set_ip_check($this->config->get('ip_check'));
// start PHP session (if not in CLI mode)
if ($_SERVER['REMOTE_ADDR']) {
- session_start();
+ $this->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 temp_gc()
+ public function gc_temp()
{
$tmp = unslashify($this->config->get('temp_dir'));
$expire = time() - 172800; // expire in 48 hours
@@ -468,14 +513,21 @@ class rcube
/**
- * Garbage collector for cache entries.
- * Set flag to expunge caches on shutdown
+ * Runs garbage collector with probability based on
+ * session settings. This is intended for environments
+ * without a session.
*/
- public function cache_gc()
+ public function gc_run()
{
- // 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;
+ $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();
+ }
+ }
}
@@ -859,6 +911,14 @@ 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();
}
@@ -870,9 +930,6 @@ class rcube
}
if (is_object($this->storage)) {
- if ($this->expunge_cache) {
- $this->storage->expunge_cache();
- }
$this->storage->close();
}
}
@@ -1081,6 +1138,9 @@ class rcube
'message' => $arg->getMessage(),
);
}
+ else if (is_string($arg)) {
+ $arg = array('message' => $arg, 'type' => 'php');
+ }
if (empty($arg['code'])) {
$arg['code'] = 500;
@@ -1093,14 +1153,24 @@ class rcube
return;
}
- if (($log || $terminate) && $arg['type'] && $arg['message']) {
+ $cli = php_sapi_name() == 'cli';
+
+ if (($log || $terminate) && !$cli && $arg['type'] && $arg['message']) {
$arg['fatal'] = $terminate;
self::log_bug($arg);
}
- // display error page and terminate script
- if ($terminate && is_object(self::$instance->output)) {
- self::$instance->output->raise_error($arg['code'], $arg['message']);
+ // terminate script
+ if ($terminate) {
+ // display error page
+ if (is_object(self::$instance->output)) {
+ self::$instance->output->raise_error($arg['code'], $arg['message']);
+ }
+ else if ($cli) {
+ fwrite(STDERR, 'ERROR: ' . $arg['message']);
+ }
+
+ exit(1);
}
}
@@ -1139,7 +1209,7 @@ class rcube
if (!self::write_log('errors', $log_entry)) {
// send error to PHPs error handler if write_log didn't succeed
- trigger_error($arg_arr['message']);
+ trigger_error($arg_arr['message'], E_USER_WARNING);
}
}
@@ -1277,6 +1347,188 @@ class rcube
return $_SESSION['language'];
}
}
+
+ /**
+ * 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,
+ ));
+
+ $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 cbc3c6773..4ed139c45 100644
--- a/program/lib/Roundcube/rcube_addressbook.php
+++ b/program/lib/Roundcube/rcube_addressbook.php
@@ -309,9 +309,14 @@ abstract class rcube_addressbook
* List all active contact groups of this source
*
* @param string Optional search string to match group name
+ * @param int Matching mode:
+ * 0 - partial (*abc*),
+ * 1 - strict (=),
+ * 2 - prefix (abc*)
+ *
* @return array Indexed list of contact groups, each a hash array
*/
- function list_groups($search = null)
+ function list_groups($search = null, $mode = 0)
{
/* empty for address books don't supporting groups */
return array();
@@ -370,9 +375,10 @@ abstract class rcube_addressbook
/**
* Add the given contact records the a certain group
*
- * @param string Group identifier
- * @param array List of contact identifiers to be added
- * @return int Number of contacts added
+ * @param string Group identifier
+ * @param array|string List of contact identifiers to be added
+ *
+ * @return int Number of contacts added
*/
function add_to_group($group_id, $ids)
{
@@ -383,9 +389,10 @@ abstract class rcube_addressbook
/**
* Remove the given contact records from a certain group
*
- * @param string Group identifier
- * @param array List of contact identifiers to be removed
- * @return int Number of deleted group members
+ * @param string Group identifier
+ * @param array|string List of contact identifiers to be removed
+ *
+ * @return int Number of deleted group members
*/
function remove_from_group($group_id, $ids)
{
@@ -425,7 +432,7 @@ abstract class rcube_addressbook
$out = array_merge($out, (array)$values);
}
else {
- list($f, $type) = explode(':', $c);
+ list(, $type) = explode(':', $c);
$out[$type] = array_merge((array)$out[$type], (array)$values);
}
}
@@ -528,17 +535,16 @@ abstract class rcube_addressbook
*/
public static function compose_contact_key($contact, $sort_col)
{
- $key = $contact[$sort_col] . ':' . $row['sourceid'];
+ $key = $contact[$sort_col] . ':' . $contact['sourceid'];
// add email to a key to not skip contacts with the same name (#1488375)
if (!empty($contact['email'])) {
- $key .= ':' . implode(':', (array)$contact['email']);
- }
+ $key .= ':' . implode(':', (array)$contact['email']);
+ }
- return $key;
+ return $key;
}
-
/**
* Compare search value with contact data
*
diff --git a/program/lib/Roundcube/rcube_cache.php b/program/lib/Roundcube/rcube_cache.php
index 92f12a8bf..a708cb292 100644
--- a/program/lib/Roundcube/rcube_cache.php
+++ b/program/lib/Roundcube/rcube_cache.php
@@ -38,6 +38,7 @@ class rcube_cache
private $type;
private $userid;
private $prefix;
+ private $table;
private $ttl;
private $packed;
private $index;
@@ -71,8 +72,9 @@ class rcube_cache
$this->db = function_exists('apc_exists'); // APC 3.1.4 required
}
else {
- $this->type = 'db';
- $this->db = $rcube->get_dbh();
+ $this->type = 'db';
+ $this->db = $rcube->get_dbh();
+ $this->table = $this->db->table_name('cache');
}
// convert ttl string to seconds
@@ -145,7 +147,7 @@ class rcube_cache
*/
function write($key, $data)
{
- return $this->write_record($key, $this->packed ? serialize($data) : $data);
+ return $this->write_record($key, $this->serialize($data));
}
@@ -192,20 +194,31 @@ class rcube_cache
*/
function expunge()
{
- if ($this->type == 'db' && $this->db) {
+ if ($this->type == 'db' && $this->db && $this->ttl) {
$this->db->query(
- "DELETE FROM ".$this->db->table_name('cache').
+ "DELETE FROM ".$this->table.
" WHERE user_id = ?".
" AND cache_key LIKE ?".
- " AND " . $this->db->unixtimestamp('created')." < ?",
+ " AND expires < " . $this->db->now(),
$this->userid,
- $this->prefix.'.%',
- time() - $this->ttl);
+ $this->prefix.'.%');
}
}
/**
+ * 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()
@@ -219,7 +232,7 @@ class rcube_cache
if ($this->cache_changes[$key]) {
// Make sure we're not going to write unchanged data
// by comparing current md5 sum with the sum calculated on DB read
- $data = $this->packed ? serialize($data) : $data;
+ $data = $this->serialize($data);
if (!$this->cache_sums[$key] || $this->cache_sums[$key] != md5($data)) {
$this->write_record($key, $data);
@@ -255,7 +268,7 @@ class rcube_cache
if ($data) {
$md5sum = md5($data);
- $data = $this->packed ? unserialize($data) : $data;
+ $data = $this->unserialize($data);
if ($nostore) {
return $data;
@@ -271,7 +284,7 @@ class rcube_cache
else {
$sql_result = $this->db->limitquery(
"SELECT data, cache_key".
- " FROM ".$this->db->table_name('cache').
+ " FROM " . $this->table.
" WHERE user_id = ?".
" AND cache_key = ?".
// for better performance we allow more records for one key
@@ -283,7 +296,7 @@ class rcube_cache
$key = substr($sql_arr['cache_key'], strlen($this->prefix)+1);
$md5sum = $sql_arr['data'] ? md5($sql_arr['data']) : null;
if ($sql_arr['data']) {
- $data = $this->packed ? unserialize($sql_arr['data']) : $sql_arr['data'];
+ $data = $this->unserialize($sql_arr['data']);
}
if ($nostore) {
@@ -326,7 +339,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->db->table_name('cache').
+ "DELETE FROM " . $this->table.
" WHERE user_id = ?".
" AND cache_key = ?",
$this->userid, $key);
@@ -337,8 +350,10 @@ class rcube_cache
// update existing cache record
if ($key_exists) {
$result = $this->db->query(
- "UPDATE ".$this->db->table_name('cache').
- " SET created = ". $this->db->now().", data = ?".
+ "UPDATE " . $this->table.
+ " SET created = " . $this->db->now().
+ ", expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL').
+ ", data = ?".
" WHERE user_id = ?".
" AND cache_key = ?",
$data, $this->userid, $key);
@@ -348,9 +363,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->db->table_name('cache').
- " (created, user_id, cache_key, data)".
- " VALUES (".$this->db->now().", ?, ?, ?)",
+ "INSERT INTO " . $this->table.
+ " (created, expires, user_id, cache_key, data)".
+ " VALUES (" . $this->db->now() . ", " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?, ?, ?)",
$this->userid, $key, $data);
}
@@ -364,7 +379,6 @@ class rcube_cache
* @param string $key Cache key name or pattern
* @param boolean $prefix_mode Enable it to clear all keys starting
* with prefix specified in $key
- *
*/
private function remove_record($key=null, $prefix_mode=false)
{
@@ -412,7 +426,7 @@ class rcube_cache
}
$this->db->query(
- "DELETE FROM ".$this->db->table_name('cache').
+ "DELETE FROM " . $this->table.
" WHERE user_id = ?" . $where,
$this->userid);
}
@@ -553,4 +567,28 @@ class rcube_cache
// This way each cache will have its own index
return sprintf('%d:%s%s', $this->userid, $this->prefix, 'INDEX');
}
+
+ /**
+ * Serializes data for storing
+ */
+ private function serialize($data)
+ {
+ if ($this->type == 'db') {
+ return $this->db->encode($data, $this->packed);
+ }
+
+ return $this->packed ? serialize($data) : $data;
+ }
+
+ /**
+ * Unserializes serialized data
+ */
+ private function unserialize($data)
+ {
+ if ($this->type == 'db') {
+ return $this->db->decode($data, $this->packed);
+ }
+
+ return $this->packed ? @unserialize($data) : $data;
+ }
}
diff --git a/program/lib/Roundcube/rcube_cache_shared.php b/program/lib/Roundcube/rcube_cache_shared.php
new file mode 100644
index 000000000..8f2574046
--- /dev/null
+++ b/program/lib/Roundcube/rcube_cache_shared.php
@@ -0,0 +1,581 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2011-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. |
+ | |
+ | PURPOSE: |
+ | Shared (cross-user) caching engine |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+/**
+ * Interface class for accessing Roundcube shared cache
+ *
+ * @package Framework
+ * @subpackage Cache
+ * @author Thomas Bruederli <roundcube@gmail.com>
+ * @author Aleksander Machniak <alec@alec.pl>
+ */
+class rcube_cache_shared
+{
+ /**
+ * Instance of database handler
+ *
+ * @var rcube_db|Memcache|bool
+ */
+ private $db;
+ private $type;
+ private $prefix;
+ private $ttl;
+ private $packed;
+ private $index;
+ private $table;
+ private $cache = array();
+ private $cache_changes = array();
+ private $cache_sums = array();
+
+
+ /**
+ * Object constructor.
+ *
+ * @param string $type Engine type ('db' or 'memcache' or 'apc')
+ * @param string $prefix Key name prefix
+ * @param string $ttl Expiration time of memcache/apc items
+ * @param bool $packed Enables/disabled data serialization.
+ * It's possible to disable data serialization if you're sure
+ * stored data will be always a safe string
+ */
+ function __construct($type, $prefix='', $ttl=0, $packed=true)
+ {
+ $rcube = rcube::get_instance();
+ $type = strtolower($type);
+
+ if ($type == 'memcache') {
+ $this->type = 'memcache';
+ $this->db = $rcube->get_memcache();
+ }
+ else if ($type == 'apc') {
+ $this->type = 'apc';
+ $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_shared');
+ }
+
+ // convert ttl string to seconds
+ $ttl = get_offset_sec($ttl);
+ if ($ttl > 2592000) $ttl = 2592000;
+
+ $this->ttl = $ttl;
+ $this->packed = $packed;
+ $this->prefix = $prefix;
+ }
+
+
+ /**
+ * Returns cached value.
+ *
+ * @param string $key Cache key name
+ *
+ * @return mixed Cached value
+ */
+ function get($key)
+ {
+ if (!array_key_exists($key, $this->cache)) {
+ return $this->read_record($key);
+ }
+
+ return $this->cache[$key];
+ }
+
+
+ /**
+ * Sets (add/update) value in cache.
+ *
+ * @param string $key Cache key name
+ * @param mixed $data Cache data
+ */
+ function set($key, $data)
+ {
+ $this->cache[$key] = $data;
+ $this->cache_changed = true;
+ $this->cache_changes[$key] = true;
+ }
+
+
+ /**
+ * Returns cached value without storing it in internal memory.
+ *
+ * @param string $key Cache key name
+ *
+ * @return mixed Cached value
+ */
+ function read($key)
+ {
+ if (array_key_exists($key, $this->cache)) {
+ return $this->cache[$key];
+ }
+
+ return $this->read_record($key, true);
+ }
+
+
+ /**
+ * Sets (add/update) value in cache and immediately saves
+ * it in the backend, no internal memory will be used.
+ *
+ * @param string $key Cache key name
+ * @param mixed $data Cache data
+ *
+ * @param boolean True on success, False on failure
+ */
+ function write($key, $data)
+ {
+ return $this->write_record($key, $this->serialize($data));
+ }
+
+
+ /**
+ * Clears the cache.
+ *
+ * @param string $key Cache key name or pattern
+ * @param boolean $prefix_mode Enable it to clear all keys starting
+ * with prefix specified in $key
+ */
+ function remove($key=null, $prefix_mode=false)
+ {
+ // Remove all keys
+ if ($key === null) {
+ $this->cache = array();
+ $this->cache_changed = false;
+ $this->cache_changes = array();
+ $this->cache_sums = array();
+ }
+ // Remove keys by name prefix
+ else if ($prefix_mode) {
+ foreach (array_keys($this->cache) as $k) {
+ if (strpos($k, $key) === 0) {
+ $this->cache[$k] = null;
+ $this->cache_changes[$k] = false;
+ unset($this->cache_sums[$k]);
+ }
+ }
+ }
+ // Remove one key by name
+ else {
+ $this->cache[$key] = null;
+ $this->cache_changes[$key] = false;
+ unset($this->cache_sums[$key]);
+ }
+
+ // Remove record(s) from the backend
+ $this->remove_record($key, $prefix_mode);
+ }
+
+
+ /**
+ * Remove cache records older than ttl
+ */
+ function expunge()
+ {
+ if ($this->type == 'db' && $this->db && $this->ttl) {
+ $this->db->query(
+ "DELETE FROM " . $this->table
+ . " WHERE cache_key LIKE ?"
+ . " AND expires < " . $this->db->now(),
+ $this->prefix . '.%');
+ }
+ }
+
+
+ /**
+ * 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_shared') . " WHERE expires < " . $db->now());
+ }
+
+
+ /**
+ * Writes the cache back to the DB.
+ */
+ function close()
+ {
+ if (!$this->cache_changed) {
+ return;
+ }
+
+ foreach ($this->cache as $key => $data) {
+ // The key has been used
+ if ($this->cache_changes[$key]) {
+ // Make sure we're not going to write unchanged data
+ // by comparing current md5 sum with the sum calculated on DB read
+ $data = $this->serialize($data);
+
+ if (!$this->cache_sums[$key] || $this->cache_sums[$key] != md5($data)) {
+ $this->write_record($key, $data);
+ }
+ }
+ }
+
+ $this->write_index();
+ }
+
+
+ /**
+ * Reads cache entry.
+ *
+ * @param string $key Cache key name
+ * @param boolean $nostore Enable to skip in-memory store
+ *
+ * @return mixed Cached value
+ */
+ private function read_record($key, $nostore=false)
+ {
+ if (!$this->db) {
+ return null;
+ }
+
+ if ($this->type != 'db') {
+ if ($this->type == 'memcache') {
+ $data = $this->db->get($this->ckey($key));
+ }
+ else if ($this->type == 'apc') {
+ $data = apc_fetch($this->ckey($key));
+ }
+
+ if ($data) {
+ $md5sum = md5($data);
+ $data = $this->unserialize($data);
+
+ if ($nostore) {
+ return $data;
+ }
+
+ $this->cache_sums[$key] = $md5sum;
+ $this->cache[$key] = $data;
+ }
+ else {
+ $this->cache[$key] = null;
+ }
+ }
+ else {
+ $sql_result = $this->db->limitquery(
+ "SELECT data, cache_key".
+ " FROM " . $this->table .
+ " WHERE cache_key = ?".
+ // for better performance we allow more records for one key
+ // get the newer one
+ " ORDER BY created DESC",
+ 0, 1, $this->prefix . '.' . $key);
+
+ if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
+ $md5sum = $sql_arr['data'] ? md5($sql_arr['data']) : null;
+ if ($sql_arr['data']) {
+ $data = $this->unserialize($sql_arr['data']);
+ }
+
+ if ($nostore) {
+ return $data;
+ }
+
+ $this->cache[$key] = $data;
+ $this->cache_sums[$key] = $md5sum;
+ }
+ else {
+ $this->cache[$key] = null;
+ }
+ }
+
+ return $this->cache[$key];
+ }
+
+
+ /**
+ * Writes single cache record into DB.
+ *
+ * @param string $key Cache key name
+ * @param mxied $data Serialized cache data
+ *
+ * @param boolean True on success, False on failure
+ */
+ private function write_record($key, $data)
+ {
+ if (!$this->db) {
+ return false;
+ }
+
+ if ($this->type == 'memcache' || $this->type == 'apc') {
+ return $this->add_record($this->ckey($key), $data);
+ }
+
+ $key_exists = array_key_exists($key, $this->cache_sums);
+ $key = $this->prefix . '.' . $key;
+
+ // Remove NULL rows (here we don't need to check if the record exist)
+ if ($data == 'N;') {
+ $this->db->query("DELETE FROM " . $this->table . " WHERE cache_key = ?", $key);
+ return true;
+ }
+
+ // 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 = ?".
+ " WHERE cache_key = ?",
+ $data, $key);
+ }
+ // add new cache record
+ else {
+ // 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, cache_key, data)".
+ " VALUES (".$this->db->now().", " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?, ?)",
+ $key, $data);
+ }
+
+ return $this->db->affected_rows($result);
+ }
+
+
+ /**
+ * Deletes the cache record(s).
+ *
+ * @param string $key Cache key name or pattern
+ * @param boolean $prefix_mode Enable it to clear all keys starting
+ * with prefix specified in $key
+ */
+ private function remove_record($key=null, $prefix_mode=false)
+ {
+ if (!$this->db) {
+ return;
+ }
+
+ if ($this->type != 'db') {
+ $this->load_index();
+
+ // Remove all keys
+ if ($key === null) {
+ foreach ($this->index as $key) {
+ $this->delete_record($key, false);
+ }
+ $this->index = array();
+ }
+ // Remove keys by name prefix
+ else if ($prefix_mode) {
+ foreach ($this->index as $k) {
+ if (strpos($k, $key) === 0) {
+ $this->delete_record($k);
+ }
+ }
+ }
+ // Remove one key by name
+ else {
+ $this->delete_record($key);
+ }
+
+ return;
+ }
+
+ // Remove all keys (in specified cache)
+ if ($key === null) {
+ $where = " WHERE cache_key LIKE " . $this->db->quote($this->prefix.'.%');
+ }
+ // Remove keys by name prefix
+ else if ($prefix_mode) {
+ $where = " WHERE cache_key LIKE " . $this->db->quote($this->prefix.'.'.$key.'%');
+ }
+ // Remove one key by name
+ else {
+ $where = " WHERE cache_key = " . $this->db->quote($this->prefix.'.'.$key);
+ }
+
+ $this->db->query("DELETE FROM " . $this->table . $where);
+ }
+
+
+ /**
+ * Adds entry into memcache/apc DB.
+ *
+ * @param string $key Cache key name
+ * @param mxied $data Serialized cache data
+ * @param bollean $index Enables immediate index update
+ *
+ * @param boolean True on success, False on failure
+ */
+ private function add_record($key, $data, $index=false)
+ {
+ if ($this->type == 'memcache') {
+ $result = $this->db->replace($key, $data, MEMCACHE_COMPRESSED, $this->ttl);
+ if (!$result) {
+ $result = $this->db->set($key, $data, MEMCACHE_COMPRESSED, $this->ttl);
+ }
+ }
+ else if ($this->type == 'apc') {
+ if (apc_exists($key)) {
+ apc_delete($key);
+ }
+ $result = apc_store($key, $data, $this->ttl);
+ }
+
+ // Update index
+ if ($index && $result) {
+ $this->load_index();
+
+ if (array_search($key, $this->index) === false) {
+ $this->index[] = $key;
+ $data = serialize($this->index);
+ $this->add_record($this->ikey(), $data);
+ }
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * Deletes entry from memcache/apc DB.
+ */
+ private function delete_record($key, $index=true)
+ {
+ if ($this->type == 'memcache') {
+ // #1488592: use 2nd argument
+ $this->db->delete($this->ckey($key), 0);
+ }
+ else {
+ apc_delete($this->ckey($key));
+ }
+
+ if ($index) {
+ if (($idx = array_search($key, $this->index)) !== false) {
+ unset($this->index[$idx]);
+ }
+ }
+ }
+
+
+ /**
+ * Writes the index entry into memcache/apc DB.
+ */
+ private function write_index()
+ {
+ if (!$this->db) {
+ return;
+ }
+
+ if ($this->type == 'db') {
+ return;
+ }
+
+ $this->load_index();
+
+ // Make sure index contains new keys
+ foreach ($this->cache as $key => $value) {
+ if ($value !== null) {
+ if (array_search($key, $this->index) === false) {
+ $this->index[] = $key;
+ }
+ }
+ }
+
+ $data = serialize($this->index);
+ $this->add_record($this->ikey(), $data);
+ }
+
+
+ /**
+ * Gets the index entry from memcache/apc DB.
+ */
+ private function load_index()
+ {
+ if (!$this->db) {
+ return;
+ }
+
+ if ($this->index !== null) {
+ return;
+ }
+
+ $index_key = $this->ikey();
+
+ if ($this->type == 'memcache') {
+ $data = $this->db->get($index_key);
+ }
+ else if ($this->type == 'apc') {
+ $data = apc_fetch($index_key);
+ }
+
+ $this->index = $data ? unserialize($data) : array();
+ }
+
+
+ /**
+ * Creates cache key name (for memcache and apc)
+ *
+ * @param string $key Cache key name
+ *
+ * @return string Cache key
+ */
+ private function ckey($key)
+ {
+ return $this->prefix . ':' . $key;
+ }
+
+
+ /**
+ * Creates index cache key name (for memcache and apc)
+ *
+ * @return string Cache key
+ */
+ private function ikey()
+ {
+ // This way each cache will have its own index
+ return $this->prefix . 'INDEX';
+ }
+
+ /**
+ * Serializes data for storing
+ */
+ private function serialize($data)
+ {
+ if ($this->type == 'db') {
+ return $this->db->encode($data, $this->packed);
+ }
+
+ return $this->packed ? serialize($data) : $data;
+ }
+
+ /**
+ * Unserializes serialized data
+ */
+ private function unserialize($data)
+ {
+ if ($this->type == 'db') {
+ return $this->db->decode($data, $this->packed);
+ }
+
+ return $this->packed ? @unserialize($data) : $data;
+ }
+}
diff --git a/program/lib/Roundcube/rcube_config.php b/program/lib/Roundcube/rcube_config.php
index 2190dc4c2..62567a0e0 100644
--- a/program/lib/Roundcube/rcube_config.php
+++ b/program/lib/Roundcube/rcube_config.php
@@ -26,6 +26,8 @@ class rcube_config
{
const DEFAULT_SKIN = 'larry';
+ private $env = '';
+ private $basedir = 'config/';
private $prop = array();
private $errors = array();
private $userprefs = array();
@@ -43,14 +45,21 @@ 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()
+ public function __construct($env = '')
{
+ $this->env = $env;
+ $this->basedir = RCUBE_CONFIG_DIR;
+
$this->load();
// Defaults, that we do not require you to configure,
@@ -67,16 +76,26 @@ class rcube_config
*/
private function load()
{
- // load main config file
- if (!$this->load_from_file(RCUBE_CONFIG_DIR . 'main.inc.php'))
- $this->errors[] = 'main.inc.php was not found.';
+ // Load default settings
+ if (!$this->load_from_file('defaults.inc.php')) {
+ $this->errors[] = 'defaults.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 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);
+ }
+ }
// load host-specific configuration
- $this->load_host_config();
+ if (!empty($_SERVER['HTTP_HOST']))
+ $this->load_host_config();
// set skin (with fallback to old 'skin_path' property)
if (empty($this->prop['skin'])) {
@@ -153,7 +172,7 @@ class rcube_config
}
if ($fname) {
- $this->load_from_file(RCUBE_CONFIG_DIR . $fname);
+ $this->load_from_file($fname);
}
}
@@ -162,19 +181,25 @@ class rcube_config
* Read configuration from a file
* and merge with the already stored config values
*
- * @param string $fpath Full path to the config file to be loaded
+ * @param string $file Name of the config file to be loaded
* @return booelan True on success, false on failure
*/
- public function load_from_file($fpath)
+ public function load_from_file($file)
{
- if (is_file($fpath) && is_readable($fpath)) {
+ $fpath = $this->resolve_path($file);
+ 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($rcmail_config)) {
- $this->prop = array_merge($this->prop, $rcmail_config, $this->userprefs);
+ if (is_array($config)) {
+ $this->merge($config);
+ return true;
+ }
+ // deprecated name of config variable
+ else if (is_array($rcmail_config)) {
+ $this->merge($rcmail_config);
return true;
}
}
@@ -182,6 +207,26 @@ class rcube_config
return false;
}
+ /**
+ * Helper method to resolve the absolute path to the given config file.
+ * This also takes the 'env' property into account.
+ */
+ public function resolve_path($file, $use_env = true)
+ {
+ if (strpos($file, '/') === false) {
+ $file = realpath($this->basedir . '/' . $file);
+ }
+
+ // check if <file>-env.ini exists
+ if ($file && $use_env && !empty($this->env)) {
+ $envfile = preg_replace('/\.(inc.php)$/', '-' . $this->env . '.\\1', $file);
+ if (is_file($envfile))
+ return $envfile;
+ }
+
+ return $file;
+ }
+
/**
* Getter for a specific config parameter
@@ -195,9 +240,6 @@ class rcube_config
if (isset($this->prop[$name])) {
$result = $this->prop[$name];
}
- else if (isset($this->legacy_props[$name])) {
- return $this->get($this->legacy_props[$name], $def);
- }
else {
$result = $def;
}
@@ -241,6 +283,7 @@ class rcube_config
public function merge($prefs)
{
$this->prop = array_merge($this->prop, $prefs, $this->userprefs);
+ $this->fix_legacy_props();
}
@@ -273,6 +316,8 @@ class rcube_config
$this->userprefs = $prefs;
$this->prop = array_merge($this->prop, $prefs);
+ $this->fix_legacy_props();
+
// 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'];
@@ -435,4 +480,18 @@ class rcube_config
return date_default_timezone_get();
}
+ /**
+ * Convert legacy options into new ones
+ */
+ private function fix_legacy_props()
+ {
+ foreach ($this->legacy_props as $new => $old) {
+ if (isset($this->prop[$old])) {
+ if (!isset($this->prop[$new])) {
+ $this->prop[$new] = $this->prop[$old];
+ }
+ unset($this->prop[$old]);
+ }
+ }
+ }
}
diff --git a/program/lib/Roundcube/rcube_contacts.php b/program/lib/Roundcube/rcube_contacts.php
index c66e98687..3919cdc6e 100644
--- a/program/lib/Roundcube/rcube_contacts.php
+++ b/program/lib/Roundcube/rcube_contacts.php
@@ -137,16 +137,34 @@ class rcube_contacts extends rcube_addressbook
* List all active contact groups of this source
*
* @param string Search string to match group name
+ * @param int Matching mode:
+ * 0 - partial (*abc*),
+ * 1 - strict (=),
+ * 2 - prefix (abc*)
+ *
* @return array Indexed list of contact groups, each a hash array
*/
- function list_groups($search = null)
+ function list_groups($search = null, $mode = 0)
{
$results = array();
if (!$this->groups)
return $results;
- $sql_filter = $search ? " AND " . $this->db->ilike('name', '%'.$search.'%') : '';
+ if ($search) {
+ switch (intval($mode)) {
+ case 1:
+ $sql_filter = $this->db->ilike('name', $search);
+ break;
+ case 2:
+ $sql_filter = $this->db->ilike('name', $search . '%');
+ break;
+ default:
+ $sql_filter = $this->db->ilike('name', '%' . $search . '%');
+ }
+
+ $sql_filter = " AND $sql_filter";
+ }
$sql_result = $this->db->query(
"SELECT * FROM ".$this->db->table_name($this->db_groups).
@@ -626,10 +644,6 @@ class rcube_contacts extends rcube_addressbook
$insert_id = $this->db->insert_id($this->db_name);
}
- // also add the newly created contact to the active group
- if ($insert_id && $this->group_id)
- $this->add_to_group($this->group_id, $insert_id);
-
$this->cache = null;
return $insert_id;
@@ -883,9 +897,10 @@ class rcube_contacts extends rcube_addressbook
/**
* Add the given contact records the a certain group
*
- * @param string Group identifier
- * @param array List of contact identifiers to be added
- * @return int Number of contacts added
+ * @param string Group identifier
+ * @param array|string List of contact identifiers to be added
+ *
+ * @return int Number of contacts added
*/
function add_to_group($group_id, $ids)
{
@@ -930,9 +945,10 @@ class rcube_contacts extends rcube_addressbook
/**
* Remove the given contact records from a certain group
*
- * @param string Group identifier
- * @param array List of contact identifiers to be removed
- * @return int Number of deleted group members
+ * @param string Group identifier
+ * @param array|string List of contact identifiers to be removed
+ *
+ * @return int Number of deleted group members
*/
function remove_from_group($group_id, $ids)
{
diff --git a/program/lib/Roundcube/rcube_csv2vcard.php b/program/lib/Roundcube/rcube_csv2vcard.php
index 0d3276b84..fb8d8f103 100644
--- a/program/lib/Roundcube/rcube_csv2vcard.php
+++ b/program/lib/Roundcube/rcube_csv2vcard.php
@@ -130,6 +130,21 @@ 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',
);
/**
@@ -230,8 +245,29 @@ 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",
);
protected $local_label_map = array();
@@ -268,7 +304,6 @@ 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 = '';
@@ -276,7 +311,7 @@ class rcube_csv2vcard
$this->map = array();
// Parse file
- foreach (preg_split("/[\r\n]+/", $csv) as $i => $line) {
+ foreach (preg_split("/[\r\n]+/", $csv) as $line) {
$elements = $this->parse_line($line);
if (empty($elements)) {
continue;
@@ -353,6 +388,12 @@ class rcube_csv2vcard
if (!empty($this->local_label_map)) {
for ($i = 0; $i < $size; $i++) {
$label = $this->local_label_map[$elements[$i]];
+
+ // special localization label
+ if ($label && $label[0] == '_') {
+ $label = substr($label, 1);
+ }
+
if ($label && !empty($this->csv2vcard_map[$label])) {
$map2[$i] = $this->csv2vcard_map[$label];
}
@@ -384,9 +425,13 @@ 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]) && $contact[$key] == '0/0/00') { // @TODO: localization?
- unset($contact[$key]);
+ if (!empty($contact[$key])) {
+ $date = preg_replace('/[0[:^word:]]/', '', $contact[$key]);
+ if (empty($date)) {
+ unset($contact[$key]);
+ }
}
}
diff --git a/program/lib/Roundcube/rcube_db.php b/program/lib/Roundcube/rcube_db.php
index 49bbe5c6e..852070073 100644
--- a/program/lib/Roundcube/rcube_db.php
+++ b/program/lib/Roundcube/rcube_db.php
@@ -47,6 +47,7 @@ class rcube_db
'identifier_end' => '"',
);
+ const DEBUG_LINE_LENGTH = 4096;
/**
* Factory, returns driver-specific instance of the class
@@ -99,27 +100,15 @@ 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
- *
- * @return PDO database handle
+ * @param array $dsn DSN for DB connections
+ * @param string $mode Connection mode (r|w)
*/
- protected function dsn_connect($dsn)
+ protected function dsn_connect($dsn, $mode)
{
$this->db_error = false;
$this->db_error_msg = null;
@@ -128,7 +117,7 @@ class rcube_db
$dsn_string = $this->dsn_string($dsn);
$dsn_options = $this->dsn_options($dsn);
- if ($db_pconn) {
+ if ($this->db_pconn) {
$dsn_options[PDO::ATTR_PERSISTENT] = true;
}
@@ -157,9 +146,10 @@ class rcube_db
return null;
}
+ $this->dbh = $dbh;
+ $this->db_mode = $mode;
+ $this->db_connected = true;
$this->conn_configure($dsn, $dbh);
-
- return $dbh;
}
/**
@@ -182,16 +172,6 @@ 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)
@@ -218,23 +198,14 @@ class rcube_db
$dsn = ($mode == 'r') ? $this->db_dsnr_array : $this->db_dsnw_array;
- $this->dbh = $this->dsn_connect($dsn);
- $this->db_connected = is_object($this->dbh);
+ $this->dsn_connect($dsn, $mode);
// use write-master when read-only fails
if (!$this->db_connected && $mode == 'r' && $this->is_replicated()) {
- $mode = 'w';
- $this->dbh = $this->dsn_connect($this->db_dsnw_array);
- $this->db_connected = is_object($this->dbh);
+ $this->dsn_connect($this->db_dsnw_array, 'w');
}
- if ($this->db_connected) {
- $this->db_mode = $mode;
- $this->set_charset('utf8');
- }
- else {
- $this->conn_failure = true;
- }
+ $this->conn_failure = !$this->db_connected;
}
/**
@@ -255,6 +226,11 @@ 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 . ';');
}
}
@@ -362,8 +338,10 @@ class rcube_db
*/
protected function _query($query, $offset, $numrows, $params)
{
+ $query = trim($query);
+
// Read or write ?
- $mode = preg_match('/^(select|show)/i', ltrim($query)) ? 'r' : 'w';
+ $mode = preg_match('/^(select|show|set)/i', $query) ? 'r' : 'w';
$this->db_connect($mode);
@@ -405,21 +383,25 @@ class rcube_db
$this->db_error_msg = null;
// send query
- $query = $this->dbh->query($query);
+ $result = $this->dbh->query($query);
- if ($query === false) {
+ if ($result === false) {
$error = $this->dbh->errorInfo();
- $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), true, false);
+ 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);
+ }
}
- $this->last_result = $query;
+ $this->last_result = $result;
- return $query;
+ return $result;
}
/**
@@ -444,17 +426,20 @@ class rcube_db
*
* @param mixed $result Optional query handle
* @return mixed Number of rows or false on failure
+ * @deprecated This method shows very poor performance and should be avoided.
*/
public function num_rows($result = null)
{
if ($result || ($result === null && ($result = $this->last_result))) {
// repeat query with SELECT COUNT(*) ...
- if (preg_match('/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i', $result->queryString, $m)) {
+ if (preg_match('/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/ims', $result->queryString, $m)) {
$query = $this->dbh->query('SELECT COUNT(*) FROM ' . $m[1], PDO::FETCH_NUM);
return $query ? intval($query->fetchColumn(0)) : false;
}
else {
- return count($result->fetchAll());
+ $num = count($result->fetchAll());
+ $result->execute(); // re-execute query because there's no seek(0)
+ return $num;
}
}
@@ -631,6 +616,22 @@ class rcube_db
}
/**
+ * Escapes a string so it can be safely used in a query
+ *
+ * @param string $str A string to escape
+ *
+ * @return string Escaped string for use in a query
+ */
+ public function escape($str)
+ {
+ if (is_null($str)) {
+ return 'NULL';
+ }
+
+ return substr($this->quote($str), 1, -1);
+ }
+
+ /**
* Quotes a string so it can be safely used as a table or column name
*
* @param string $str Value to quote
@@ -645,6 +646,20 @@ class rcube_db
}
/**
+ * Escapes a string so it can be safely used in a query
+ *
+ * @param string $str A string to escape
+ *
+ * @return string Escaped string for use in a query
+ * @deprecated Replaced by rcube_db::escape
+ * @see rcube_db::escape
+ */
+ public function escapeSimple($str)
+ {
+ return $this->escape($str);
+ }
+
+ /**
* Quotes a string so it can be safely used as a table or column name
*
* @param string $str Value to quote
@@ -668,11 +683,19 @@ 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()
+ public function now($interval = 0)
{
- return "now()";
+ if ($interval) {
+ $add = ' ' . ($interval > 0 ? '+' : '-') . ' INTERVAL ';
+ $add .= $interval > 0 ? intval($interval) : intval($interval) * -1;
+ $add .= ' SECOND';
+ }
+
+ return "now()" . $add;
}
/**
@@ -755,12 +778,19 @@ class rcube_db
/**
* Encodes non-UTF-8 characters in string/array/object (recursive)
*
- * @param mixed $input Data to fix
+ * @param mixed $input Data to fix
+ * @param bool $serialized Enable serialization
*
* @return mixed Properly UTF-8 encoded data
*/
- public static function encode($input)
+ public static function encode($input, $serialized = false)
{
+ // use Base64 encoding to workaround issues with invalid
+ // or null characters in serialized string (#1489142)
+ if ($serialized) {
+ return base64_encode(serialize($input));
+ }
+
if (is_object($input)) {
foreach (get_object_vars($input) as $idx => $value) {
$input->$idx = self::encode($value);
@@ -771,6 +801,7 @@ class rcube_db
foreach ($input as $idx => $value) {
$input[$idx] = self::encode($value);
}
+
return $input;
}
@@ -780,12 +811,24 @@ class rcube_db
/**
* Decodes encoded UTF-8 string/object/array (recursive)
*
- * @param mixed $input Input data
+ * @param mixed $input Input data
+ * @param bool $serialized Enable serialization
*
* @return mixed Decoded data
*/
- public static function decode($input)
+ public static function decode($input, $serialized = false)
{
+ // use Base64 encoding to workaround issues with invalid
+ // or null characters in serialized string (#1489142)
+ if ($serialized) {
+ // Keep backward compatybility where base64 wasn't used
+ if (strpos(substr($input, 0, 16), ':') !== false) {
+ return self::decode(@unserialize($input));
+ }
+
+ return @unserialize(base64_decode($input));
+ }
+
if (is_object($input)) {
foreach (get_object_vars($input) as $idx => $value) {
$input->$idx = self::decode($value);
@@ -813,17 +856,26 @@ class rcube_db
{
$rcube = rcube::get_instance();
- // return table name if configured
- $config_key = 'db_table_'.$table;
-
- if ($name = $rcube->config->get($config_key)) {
- return $name;
+ // add prefix to the table name if configured
+ if ($prefix = $rcube->config->get('db_prefix')) {
+ return $prefix . $table;
}
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 37a42678a..3c1b9d71f 100644
--- a/program/lib/Roundcube/rcube_db_mssql.php
+++ b/program/lib/Roundcube/rcube_db_mssql.php
@@ -29,38 +29,52 @@ class rcube_db_mssql extends rcube_db
public $db_provider = 'mssql';
/**
- * Driver initialization
+ * 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
*/
- protected function init()
+ public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
{
+ parent::__construct($db_dsnw, $db_dsnr, $pconn);
+
$this->options['identifier_start'] = '[';
$this->options['identifier_end'] = ']';
}
/**
- * Character setting
+ * Driver-specific configuration of database connection
+ *
+ * @param array $dsn DSN for DB connections
+ * @param PDO $dbh Connection handler
*/
- protected function set_charset($charset)
+ protected function conn_configure($dsn, $dbh)
{
- // UTF-8 is default
+ // Set date format in case of non-default language (#1488918)
+ $this->query("SET DATEFORMAT ymd");
}
/**
* 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()
+ public function now($interval = 0)
{
+ 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 8ab6403c8..6fa5ad768 100644
--- a/program/lib/Roundcube/rcube_db_mysql.php
+++ b/program/lib/Roundcube/rcube_db_mysql.php
@@ -30,16 +30,40 @@ class rcube_db_mysql extends rcube_db
public $db_provider = 'mysql';
/**
- * Driver initialization/configuration
+ * 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
*/
- protected function init()
+ public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
{
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ rcube::raise_error(array('code' => 600, 'type' => 'db',
+ 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => "MySQL driver requires PHP >= 5.3, current version is " . PHP_VERSION),
+ 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
@@ -127,7 +151,7 @@ class rcube_db_mysql extends rcube_db
$result[PDO::MYSQL_ATTR_FOUND_ROWS] = true;
// Enable AUTOCOMMIT mode (#1488902)
- $dsn_options[PDO::ATTR_AUTOCOMMIT] = true;
+ $result[PDO::ATTR_AUTOCOMMIT] = true;
return $result;
}
@@ -147,7 +171,7 @@ class rcube_db_mysql extends rcube_db
$result = $this->query('SHOW VARIABLES');
- while ($sql_arr = $this->fetch_array($result)) {
+ while ($row = $this->fetch_array($result)) {
$this->variables[$row[0]] = $row[1];
}
}
diff --git a/program/lib/Roundcube/rcube_db_pgsql.php b/program/lib/Roundcube/rcube_db_pgsql.php
index cf23c5e48..d72c9d6b3 100644
--- a/program/lib/Roundcube/rcube_db_pgsql.php
+++ b/program/lib/Roundcube/rcube_db_pgsql.php
@@ -29,6 +29,17 @@ 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)
@@ -53,19 +64,20 @@ class rcube_db_pgsql extends rcube_db
/**
* Return correct name for a specific database sequence
*
- * @param string $sequence Secuence name
+ * @param string $table Table name
*
* @return string Translated sequence name
*/
- protected function sequence_name($sequence)
+ protected function sequence_name($table)
{
- $rcube = rcube::get_instance();
+ // Note: we support only one sequence per table
+ // Note: The sequence name must be <table_name>_seq
+ $sequence = $table . '_seq';
+ $rcube = rcube::get_instance();
// return sequence name if configured
- $config_key = 'db_sequence_'.$sequence;
-
- if ($name = $rcube->config->get($config_key)) {
- return $name;
+ if ($prefix = $rcube->config->get('db_prefix')) {
+ return $prefix . $sequence;
}
return $sequence;
@@ -74,9 +86,6 @@ 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
@@ -88,6 +97,24 @@ 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
@@ -129,4 +156,38 @@ class rcube_db_pgsql extends rcube_db
return isset($this->variables[$varname]) ? $this->variables[$varname] : $default;
}
+ /**
+ * Returns PDO DSN string from DSN array
+ *
+ * @param array $dsn DSN parameters
+ *
+ * @return string DSN string
+ */
+ protected function dsn_string($dsn)
+ {
+ $params = array();
+ $result = 'pgsql:';
+
+ if ($dsn['hostspec']) {
+ $params[] = 'host=' . $dsn['hostspec'];
+ }
+ else if ($dsn['socket']) {
+ $params[] = 'host=' . $dsn['socket'];
+ }
+
+ if ($dsn['port']) {
+ $params[] = 'port=' . $dsn['port'];
+ }
+
+ if ($dsn['database']) {
+ $params[] = 'dbname=' . $dsn['database'];
+ }
+
+ if (!empty($params)) {
+ $result .= implode(';', $params);
+ }
+
+ return $result;
+ }
+
}
diff --git a/program/lib/Roundcube/rcube_db_sqlite.php b/program/lib/Roundcube/rcube_db_sqlite.php
index 145b8a371..b66c56097 100644
--- a/program/lib/Roundcube/rcube_db_sqlite.php
+++ b/program/lib/Roundcube/rcube_db_sqlite.php
@@ -29,13 +29,6 @@ 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)
@@ -56,10 +49,6 @@ 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');
@@ -83,30 +72,32 @@ class rcube_db_sqlite extends rcube_db
}
/**
- * Callback for sqlite: unix_timestamp()
+ * 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
*/
- public static function sqlite_unix_timestamp($timestamp = '')
+ public function unixtimestamp($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 "strftime('%s', $field)";
}
/**
- * Callback for sqlite: now()
+ * 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 static function sqlite_now()
+ public function now($interval = 0)
{
- return date("Y-m-d H:i:s");
+ if ($interval) {
+ $add = ($interval > 0 ? '+' : '') . intval($interval) . ' seconds';
+ }
+
+ return "datetime('now'" . ($add ? ",'$add'" : "") . ")";
}
/**
diff --git a/program/lib/Roundcube/rcube_db_sqlsrv.php b/program/lib/Roundcube/rcube_db_sqlsrv.php
index e5dfb1154..45c41cdaf 100644
--- a/program/lib/Roundcube/rcube_db_sqlsrv.php
+++ b/program/lib/Roundcube/rcube_db_sqlsrv.php
@@ -29,29 +29,46 @@ class rcube_db_sqlsrv extends rcube_db
public $db_provider = 'mssql';
/**
- * Driver initialization
+ * 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
*/
- protected function init()
+ public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
{
+ parent::__construct($db_dsnw, $db_dsnr, $pconn);
+
$this->options['identifier_start'] = '[';
$this->options['identifier_end'] = ']';
}
/**
- * Database character set setting
+ * Driver-specific configuration of database connection
+ *
+ * @param array $dsn DSN for DB connections
+ * @param PDO $dbh Connection handler
*/
- protected function set_charset($charset)
+ protected function conn_configure($dsn, $dbh)
{
- // UTF-8 is default
+ // Set date format in case of non-default language (#1488918)
+ $this->query("SET DATEFORMAT ymd");
}
/**
* 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()
+ public function now($interval = 0)
{
+ 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 8c628c912..12deb33ce 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 $n => $line)
+ foreach ($lines as $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 a55ba1600..09bb4e81b 100644
--- a/program/lib/Roundcube/rcube_image.php
+++ b/program/lib/Roundcube/rcube_image.php
@@ -93,6 +93,10 @@ 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;
}
@@ -124,6 +128,7 @@ class rcube_image
}
if ($result === '') {
+ @chmod($filename, 0600);
return $type;
}
}
@@ -147,6 +152,10 @@ 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)
@@ -183,6 +192,7 @@ class rcube_image
}
if ($result) {
+ @chmod($filename, 0600);
return $type;
}
}
@@ -223,6 +233,7 @@ class rcube_image
$result = rcube::exec($convert . ' 2>&1 -colorspace RGB -quality 75 {in} {type}:{out}', $p);
if ($result === '') {
+ @chmod($filename, 0600);
return true;
}
}
@@ -256,6 +267,7 @@ class rcube_image
}
if ($result) {
+ @chmod($filename, 0600);
return true;
}
}
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 0aa059c26..b60aefc5f 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -308,14 +308,7 @@ 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);
}
@@ -626,7 +619,7 @@ class rcube_imap extends rcube_storage
}
if ($mode == 'THREADS') {
- $res = $this->fetch_threads($folder, $force);
+ $res = $this->threads($folder);
$count = $res->count();
if ($status) {
@@ -656,11 +649,11 @@ class rcube_imap extends rcube_storage
$keys[] = 'ALL';
}
if ($status) {
- $keys[] = 'MAX';
+ $keys[] = 'MAX';
}
}
- // @TODO: if $force==false && $mode == 'ALL' we could try to use cache index here
+ // @TODO: if $mode == 'ALL' we could try to use cache index here
// get message count using (E)SEARCH
// not very performant but more precise (using UNDELETED)
@@ -791,7 +784,7 @@ class rcube_imap extends rcube_storage
$threads = $mcache->get_thread($folder);
}
else {
- $threads = $this->fetch_threads($folder);
+ $threads = $this->threads($folder);
}
return $this->fetch_thread_headers($folder, $threads, $page, $slice);
@@ -800,32 +793,47 @@ class rcube_imap extends rcube_storage
/**
* Method for fetching threads data
*
- * @param string $folder Folder name
- * @param bool $force Use IMAP server, no cache
+ * @param string $folder Folder name
*
* @return rcube_imap_thread Thread data object
*/
- function fetch_threads($folder, $force = false)
+ function threads($folder)
{
- if (!$force && ($mcache = $this->get_mcache_engine())) {
+ if ($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->check_connection()) {
- return new rcube_result_thread();
+ if (!empty($this->icache['threads'])) {
+ if ($this->icache['threads']->get_parameters('MAILBOX') == $folder) {
+ return $this->icache['threads'];
}
+ }
- // get all threads
- $result = $this->conn->thread($folder, $this->threading,
- $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
+ // get all threads
+ $result = $this->threads_direct($folder);
- // add to internal (fast) cache
- $this->icache['threads'] = $result;
+ // 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();
}
- return $this->icache['threads'];
+ // get all threads
+ return $this->conn->thread($folder, $this->threading,
+ $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
}
@@ -981,7 +989,7 @@ class rcube_imap extends rcube_storage
// use memory less expensive (and quick) method for big result set
$index = clone $this->index('', $this->sort_field, $this->sort_order);
// get messages uids for one page...
- $index->slice($start_msg, min($cnt-$from, $this->page_size));
+ $index->slice($from, min($cnt-$from, $this->page_size));
if ($slice) {
$index->slice(-$slice, $slice);
@@ -1180,12 +1188,15 @@ 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)
- {
- if ($this->threading) {
+ public function index($folder = '', $sort_field = NULL, $sort_order = NULL,
+ $no_threads = false, $no_search = false
+ ) {
+ if (!$no_threads && $this->threading) {
return $this->thread_index($folder, $sort_field, $sort_order);
}
@@ -1197,43 +1208,50 @@ class rcube_imap extends rcube_storage
// we have a saved search result, get index from there
if ($this->search_string) {
- if ($this->search_threads) {
- $this->search($folder, $this->search_string, $this->search_charset, $this->sort_field);
+ if ($this->search_set->is_empty()) {
+ return new rcube_result_index($folder, '* SORT');
}
- // 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);
- }
+ // 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))
+ ) {
$index = $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);
+ // $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);
+ }
}
- if ($this->sort_order != $index->get_parameters('ORDER')) {
- $index->revert();
- }
+ if (isset($index)) {
+ if ($this->sort_order != $index->get_parameters('ORDER')) {
+ $index->revert();
+ }
- return $index;
+ return $index;
+ }
}
// check local cache
if ($mcache = $this->get_mcache_engine()) {
- $index = $mcache->get_index($folder, $this->sort_field, $this->sort_order);
- }
- // fetch from IMAP server
- else {
- $index = $this->index_direct(
- $folder, $this->sort_field, $this->sort_order);
+ return $mcache->get_index($folder, $this->sort_field, $this->sort_order);
}
- return $index;
+ // fetch from IMAP server
+ return $this->index_direct($folder, $this->sort_field, $this->sort_order);
}
@@ -1241,22 +1259,24 @@ 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 bool $skip_cache Disables cache usage
+ * @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
*
* @return rcube_result_index Sorted list of message UIDs
*/
- public function index_direct($folder, $sort_field = null, $sort_order = null, $skip_cache = true)
+ public function index_direct($folder, $sort_field = null, $sort_order = null, $search = null)
{
- if (!$skip_cache && ($mcache = $this->get_mcache_engine())) {
- $index = $mcache->get_index($folder, $sort_field, $sort_order);
+ if (!empty($search)) {
+ $search = $this->search_set->get_compressed();
}
+
// use message index sort as default sorting
- else if (!$sort_field) {
+ if (!$sort_field) {
// use search result from count() if possible
- if ($this->options['skip_deleted'] && !empty($this->icache['undeleted_idx'])
+ if (empty($search) && $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
) {
@@ -1266,8 +1286,12 @@ class rcube_imap extends rcube_storage
return new rcube_result_index();
}
else {
- $index = $this->conn->search($folder,
- 'ALL' .($this->options['skip_deleted'] ? ' UNDELETED' : ''), true);
+ $query = $this->options['skip_deleted'] ? 'UNDELETED' : '';
+ if ($search) {
+ $query = trim($query . ' UID ' . $search);
+ }
+
+ $index = $this->conn->search($folder, $query, true);
}
}
else if (!$this->check_connection()) {
@@ -1276,13 +1300,18 @@ class rcube_imap extends rcube_storage
// fetch complete message index
else {
if ($this->get_capability('SORT')) {
- $index = $this->conn->sort($folder, $sort_field,
- $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
+ $query = $this->options['skip_deleted'] ? 'UNDELETED' : '';
+ if ($search) {
+ $query = trim($query . ' UID ' . $search);
+ }
+
+ $index = $this->conn->sort($folder, $sort_field, $query, true);
}
if (empty($index) || $index->is_error()) {
- $index = $this->conn->index($folder, "1:*", $sort_field,
- $this->options['skip_deleted'], false, true);
+ $index = $this->conn->index($folder, $search ? $search : "1:*",
+ $sort_field, $this->options['skip_deleted'],
+ $search ? true : false, true);
}
}
@@ -1315,7 +1344,7 @@ class rcube_imap extends rcube_storage
}
else {
// get all threads (default sort order)
- $threads = $this->fetch_threads($folder);
+ $threads = $this->threads($folder);
}
$this->set_sort_order($sort_field, $sort_order);
@@ -1326,9 +1355,10 @@ class rcube_imap extends rcube_storage
/**
- * Sort threaded result, using THREAD=REFS method
+ * Sort threaded result, using THREAD=REFS method if available.
+ * If not, use any method and re-sort the result in THREAD=REFS way.
*
- * @param rcube_result_thread $threads Threads result set
+ * @param rcube_result_thread $threads Threads result set
*/
protected function sort_threads($threads)
{
@@ -1340,17 +1370,16 @@ class rcube_imap extends rcube_storage
// THREAD=REFERENCES: sorting by sent date of root message
// THREAD=REFS: sorting by the most recent date in each thread
- if ($this->sort_field && ($this->sort_field != 'date' || $this->get_capability('THREAD') != 'REFS')) {
- $index = $this->index_direct($this->folder, $this->sort_field, $this->sort_order, false);
+ 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);
if (!$index->is_empty()) {
$threads->sort($index);
}
}
- else {
- if ($this->sort_order != $threads->get_parameters('ORDER')) {
- $threads->revert();
- }
+ else if ($this->sort_order != $threads->get_parameters('ORDER')) {
+ $threads->revert();
}
}
@@ -1423,8 +1452,6 @@ 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();
@@ -2240,13 +2267,14 @@ class rcube_imap extends rcube_storage
/**
* Append a mail message (source) to a specific folder
*
- * @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
+ * @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
*
* @return int|bool Appended message UID or True on success, False on error
*/
@@ -2639,7 +2667,6 @@ 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])
@@ -2652,19 +2679,14 @@ class rcube_imap extends rcube_storage
}
}
else {
- // 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]);
- }
- }
+ // 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);
}
}
}
@@ -2727,7 +2749,7 @@ class rcube_imap extends rcube_storage
// filter folders list according to rights requirements
if ($rights && $this->get_capability('ACL')) {
- $a_folders = $this->filter_rights($a_folders, $rights);
+ $a_mboxes = $this->filter_rights($a_mboxes, $rights);
}
// filter folders and sort them
@@ -2783,7 +2805,6 @@ 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();
@@ -3372,7 +3393,6 @@ class rcube_imap extends rcube_storage
{
if (!empty($this->options['fetch_headers'])) {
$headers = explode(' ', $this->options['fetch_headers']);
- $headers = array_map('strtoupper', $headers);
}
else {
$headers = array();
@@ -3382,7 +3402,7 @@ class rcube_imap extends rcube_storage
$headers = array_merge($headers, $this->all_headers);
}
- return implode(' ', array_unique($headers));
+ return $headers;
}
@@ -3695,7 +3715,7 @@ class rcube_imap extends rcube_storage
{
if ($this->caching && !$this->cache) {
$rcube = rcube::get_instance();
- $ttl = $rcube->config->get('message_cache_lifetime', '10d');
+ $ttl = $rcube->config->get('imap_cache_ttl', '10d');
$this->cache = $rcube->get_cache('IMAP', $this->caching, $ttl);
}
@@ -3743,21 +3763,6 @@ 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
@@ -3791,8 +3796,9 @@ 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');
$this->mcache = new rcube_imap_cache(
- $dbh, $this, $userid, $this->options['skip_deleted']);
+ $dbh, $this, $userid, $this->options['skip_deleted'], $ttl);
}
}
@@ -3814,6 +3820,15 @@ class rcube_imap extends rcube_storage
}
+ /**
+ * Delete outdated cache entries
+ */
+ function cache_gc()
+ {
+ rcube_imap_cache::gc();
+ }
+
+
/* --------------------------------
* protected methods
* --------------------------------*/
@@ -3847,7 +3862,7 @@ class rcube_imap extends rcube_storage
$delimiter = $this->get_hierarchy_delimiter();
// find default folders and skip folders starting with '.'
- foreach ($a_folders as $i => $folder) {
+ foreach ($a_folders as $folder) {
if ($folder[0] == '.') {
continue;
}
@@ -4107,9 +4122,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, $skip_cache = true)
+ public function message_index_direct($folder, $sort_field = null, $sort_order = null)
{
- return $this->index_direct($folder, $sort_field, $sort_order, $skip_cache);
+ return $this->index_direct($folder, $sort_field, $sort_order);
}
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 748474af2..061ac546d 100644
--- a/program/lib/Roundcube/rcube_imap_cache.php
+++ b/program/lib/Roundcube/rcube_imap_cache.php
@@ -49,6 +49,13 @@ class rcube_imap_cache
private $userid;
/**
+ * Expiration time in seconds
+ *
+ * @var int
+ */
+ private $ttl;
+
+ /**
* Internal (in-memory) cache
*
* @var array
@@ -83,13 +90,25 @@ 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
+ *
*/
- function __construct($db, $imap, $userid, $skip_deleted)
+ function __construct($db, $imap, $userid, $skip_deleted, $ttl=0)
{
+ // 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;
}
@@ -215,9 +234,7 @@ 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 $sort_field Sorting column
- * @param string $sort_order Sorting order (ASC|DESC)
+ * @param string $mailbox Folder name
*
* @return array Messages threaded index
*/
@@ -256,19 +273,11 @@ class rcube_imap_cache
if ($index === null) {
// Get mailbox data (UIDVALIDITY, counters, etc.) for status check
$mbox_data = $this->imap->folder_data($mailbox);
-
- 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;
+ // Get THREADS result
+ $index['object'] = $this->get_thread_data($mailbox, $mbox_data);
// insert/update
- $this->add_thread_row($mailbox, $threads, $mbox_data, $exists);
+ $this->add_thread_row($mailbox, $index['object'], $mbox_data, $exists);
}
$this->icache[$mailbox]['thread'] = $index;
@@ -407,8 +416,8 @@ class rcube_imap_cache
return;
}
- $msg = serialize($this->db->encode(clone $message));
$flags = 0;
+ $msg = clone $message;
if (!empty($message->flags)) {
foreach ($this->flags as $idx => $flag) {
@@ -417,30 +426,49 @@ class rcube_imap_cache
}
}
}
+
unset($msg->flags);
+ $msg = $this->db->encode($msg, true);
// update cache record (even if it exists, the update
// here will work as select, assume row exist if affected_rows=0)
if (!$force) {
$res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
- ." SET flags = ?, data = ?, changed = ".$this->db->now()
+ ." SET flags = ?, data = ?, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid = ?",
$flags, $msg, $this->userid, $mailbox, (int) $message->uid);
- if ($this->db->affected_rows()) {
+ if ($this->db->affected_rows($res)) {
return;
}
}
+ $this->db->set_option('ignore_key_errors', true);
+
// insert new record
- $this->db->query(
+ $res = $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_messages')
- ." (user_id, mailbox, uid, flags, changed, data)"
- ." VALUES (?, ?, ?, ?, ".$this->db->now().", ?)",
+ ." (user_id, mailbox, uid, flags, expires, data)"
+ ." VALUES (?, ?, ?, ?, ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?)",
$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);
}
@@ -481,7 +509,7 @@ class rcube_imap_cache
$this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
- ." SET changed = ".$this->db->now()
+ ." SET expires = ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
.", flags = flags ".($enabled ? "+ $idx" : "- $idx")
." WHERE user_id = ?"
." AND mailbox = ?"
@@ -604,23 +632,21 @@ class rcube_imap_cache
/**
- * Delete cache entries older than TTL
- *
- * @param string $ttl Lifetime of message cache entries
+ * Delete expired cache entries
*/
- function expunge($ttl)
+ static function gc()
{
- // get expiration timestamp
- $ts = get_offset_time($ttl, -1);
+ $rcube = rcube::get_instance();
+ $db = $rcube->get_dbh();
- $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_messages')
+ ." 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_index')
+ ." WHERE expires < " . $db->now());
- $this->db->query("DELETE FROM ".$this->db->table_name('cache_thread')
- ." WHERE changed < " . $this->db->fromunixtime($ts));
+ $db->query("DELETE FROM ".$db->table_name('cache_thread')
+ ." WHERE expires < " . $db->now());
}
@@ -639,7 +665,7 @@ class rcube_imap_cache
if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
$data = explode('@', $sql_arr['data']);
- $index = @unserialize($data[0]);
+ $index = $this->db->decode($data[0], true);
unset($data[0]);
if (empty($index)) {
@@ -676,7 +702,7 @@ class rcube_imap_cache
if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
$data = explode('@', $sql_arr['data']);
- $thread = @unserialize($data[0]);
+ $thread = $this->db->decode($data[0], true);
unset($data[0]);
if (empty($thread)) {
@@ -702,7 +728,7 @@ class rcube_imap_cache
$data, $mbox_data = array(), $exists = false, $modseq = null)
{
$data = array(
- serialize($data),
+ $this->db->encode($data, true),
$sort_field,
(int) $this->skip_deleted,
(int) $mbox_data['UIDVALIDITY'],
@@ -712,20 +738,38 @@ class rcube_imap_cache
$data = implode('@', $data);
if ($exists) {
- $sql_result = $this->db->query(
+ $res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_index')
- ." SET data = ?, valid = 1, changed = ".$this->db->now()
+ ." SET data = ?, valid = 1, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
+
+ if ($this->db->affected_rows($res)) {
+ return;
+ }
}
- 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', 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);
}
+
+ $this->db->set_option('ignore_key_errors', false);
}
@@ -735,28 +779,48 @@ class rcube_imap_cache
private function add_thread_row($mailbox, $data, $mbox_data = array(), $exists = false)
{
$data = array(
- serialize($data),
+ $this->db->encode($data, true),
(int) $this->skip_deleted,
(int) $mbox_data['UIDVALIDITY'],
(int) $mbox_data['UIDNEXT'],
);
$data = implode('@', $data);
+ $expires = ($this->ttl ? $this->db->now($this->ttl) : 'NULL');
+
if ($exists) {
- $sql_result = $this->db->query(
+ $res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_thread')
- ." SET data = ?, changed = ".$this->db->now()
+ ." SET data = ?, expires = $expires"
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
+
+ if ($this->db->affected_rows($res)) {
+ return;
+ }
}
- 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', 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);
}
+
+ $this->db->set_option('ignore_key_errors', false);
}
@@ -983,7 +1047,7 @@ class rcube_imap_cache
$uids, true, array('FLAGS'), $index['modseq'], $qresync);
if (!empty($result)) {
- foreach ($result as $id => $msg) {
+ foreach ($result as $msg) {
$uid = $msg->uid;
// Remove deleted message
if ($this->skip_deleted && !empty($msg->flags['DELETED'])) {
@@ -1004,7 +1068,7 @@ class rcube_imap_cache
$this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
- ." SET flags = ?, changed = ".$this->db->now()
+ ." SET flags = ?, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL')
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid = ?"
@@ -1032,17 +1096,18 @@ 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);
}
@@ -1067,7 +1132,7 @@ class rcube_imap_cache
*/
private function build_message($sql_arr)
{
- $message = $this->db->decode(unserialize($sql_arr['data']));
+ $message = $this->db->decode($sql_arr['data'], true);
if ($message) {
$message->flags = array();
@@ -1150,6 +1215,25 @@ 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 2ac1355fd..920c7184a 100644
--- a/program/lib/Roundcube/rcube_imap_generic.php
+++ b/program/lib/Roundcube/rcube_imap_generic.php
@@ -72,6 +72,8 @@ class rcube_imap_generic
const COMMAND_CAPABILITY = 2;
const COMMAND_LASTLINE = 4;
+ const DEBUG_LINE_LENGTH = 4098; // 4KB + 2B for \r\n
+
/**
* Object constructor
*/
@@ -713,6 +715,10 @@ class rcube_imap_generic
$auth_method = 'CHECK';
}
+ if (!empty($this->prefs['disabled_caps'])) {
+ $this->prefs['disabled_caps'] = array_map('strtoupper', (array)$this->prefs['disabled_caps']);
+ }
+
$result = false;
// initialize connection
@@ -746,7 +752,7 @@ class rcube_imap_generic
}
if ($this->prefs['timeout'] <= 0) {
- $this->prefs['timeout'] = ini_get('default_socket_timeout');
+ $this->prefs['timeout'] = max(0, intval(ini_get('default_socket_timeout')));
}
// Connect
@@ -1077,7 +1083,7 @@ class rcube_imap_generic
}
if (!$this->data['READ-WRITE']) {
- $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'EXPUNGE');
+ $this->setError(self::ERROR_READONLY, "Mailbox is read-only");
return false;
}
@@ -1327,9 +1333,8 @@ class rcube_imap_generic
$folders[$mailbox] = array();
}
- // 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') {
+ // store folder options
+ if ($cmd == 'LIST') {
// Add to options array
if (empty($this->data['LIST'][$mailbox]))
$this->data['LIST'][$mailbox] = $opts;
@@ -1561,11 +1566,12 @@ 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, 'ALL' . (!empty($add) ? ' '.$add : '')));
+ array("($field)", $encoding, !empty($add) ? $add : 'ALL'));
if ($code != self::ERROR_OK) {
$response = null;
@@ -1652,7 +1658,6 @@ class rcube_imap_generic
}
if (!empty($criteria)) {
- $modseq = stripos($criteria, 'MODSEQ') !== false;
$params .= ($params ? ' ' : '') . $criteria;
}
else {
@@ -1791,7 +1796,6 @@ 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;
}
}
@@ -1936,7 +1940,7 @@ class rcube_imap_generic
}
if (!$this->data['READ-WRITE']) {
- $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE');
+ $this->setError(self::ERROR_READONLY, "Mailbox is read-only");
return false;
}
@@ -1997,7 +2001,7 @@ class rcube_imap_generic
}
if (!$this->data['READ-WRITE']) {
- $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE');
+ $this->setError(self::ERROR_READONLY, "Mailbox is read-only");
return false;
}
@@ -2158,21 +2162,25 @@ class rcube_imap_generic
else if ($name == 'RFC822') {
$result[$id]->body = $value;
}
- else if ($name == 'BODY') {
- $body = $this->tokenizeResponse($line, 1);
- if ($value[0] == 'HEADER.FIELDS')
- $headers = $body;
- else if (!empty($value))
- $result[$id]->bodypart[$value[0]] = $body;
+ else if (stripos($name, 'BODY[') === 0) {
+ $name = str_replace(']', '', substr($name, 5));
+
+ if ($name == 'HEADER.FIELDS') {
+ // skip ']' after headers list
+ $this->tokenizeResponse($line, 1);
+ $headers = $this->tokenizeResponse($line, 1);
+ }
+ else if (strlen($name))
+ $result[$id]->bodypart[$name] = $value;
else
- $result[$id]->body = $body;
+ $result[$id]->body = $value;
}
}
// create array with header field:data
if (!empty($headers)) {
$headers = explode("\n", trim($headers));
- foreach ($headers as $hid => $resln) {
+ foreach ($headers as $resln) {
if (ord($resln[0]) <= 32) {
$lines[$ln] .= (empty($lines[$ln]) ? '' : "\n") . trim($resln);
} else {
@@ -2180,7 +2188,7 @@ class rcube_imap_generic
}
}
- while (list($lines_key, $str) = each($lines)) {
+ foreach ($lines as $str) {
list($field, $string) = explode(':', $str, 2);
$field = strtolower($field);
@@ -2265,24 +2273,53 @@ class rcube_imap_generic
return $result;
}
- function fetchHeaders($mailbox, $message_set, $is_uid = false, $bodystr = false, $add = '')
+ /**
+ * Returns message(s) data (flags, headers, etc.)
+ *
+ * @param string $mailbox Mailbox name
+ * @param mixed $message_set Message(s) sequence identifier(s) or UID(s)
+ * @param bool $is_uid True if $message_set contains UIDs
+ * @param bool $bodystr Enable to add BODYSTRUCTURE data to the result
+ * @param array $add_headers List of additional headers
+ *
+ * @return bool|array List of rcube_message_header elements, False on error
+ */
+ function fetchHeaders($mailbox, $message_set, $is_uid = false, $bodystr = false, $add_headers = array())
{
$query_items = array('UID', 'RFC822.SIZE', 'FLAGS', 'INTERNALDATE');
- if ($bodystr)
+ $headers = array('DATE', 'FROM', 'TO', 'SUBJECT', 'CONTENT-TYPE', 'CC', 'REPLY-TO',
+ 'LIST-POST', 'DISPOSITION-NOTIFICATION-TO', 'X-PRIORITY');
+
+ if (!empty($add_headers)) {
+ $add_headers = array_map('strtoupper', $add_headers);
+ $headers = array_unique(array_merge($headers, $add_headers));
+ }
+
+ if ($bodystr) {
$query_items[] = 'BODYSTRUCTURE';
- $query_items[] = 'BODY.PEEK[HEADER.FIELDS ('
- . 'DATE FROM TO SUBJECT CONTENT-TYPE CC REPLY-TO LIST-POST DISPOSITION-NOTIFICATION-TO X-PRIORITY'
- . ($add ? ' ' . trim($add) : '')
- . ')]';
+ }
+
+ $query_items[] = 'BODY.PEEK[HEADER.FIELDS (' . implode(' ', $headers) . ')]';
$result = $this->fetch($mailbox, $message_set, $is_uid, $query_items);
return $result;
}
- function fetchHeader($mailbox, $id, $uidfetch=false, $bodystr=false, $add='')
+ /**
+ * Returns message data (flags, headers, etc.)
+ *
+ * @param string $mailbox Mailbox name
+ * @param int $id Message sequence identifier or UID
+ * @param bool $is_uid True if $id is an UID
+ * @param bool $bodystr Enable to add BODYSTRUCTURE data to the result
+ * @param array $add_headers List of additional headers
+ *
+ * @return bool|rcube_message_header Message data, False on error
+ */
+ function fetchHeader($mailbox, $id, $is_uid = false, $bodystr = false, $add_headers = array())
{
- $a = $this->fetchHeaders($mailbox, $id, $uidfetch, $bodystr, $add);
+ $a = $this->fetchHeaders($mailbox, $id, $is_uid, $bodystr, $add_headers);
if (is_array($a)) {
return array_shift($a);
}
@@ -2446,6 +2483,7 @@ class rcube_imap_generic
$key = $this->nextTag();
$request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
$result = false;
+ $found = false;
// send request
if (!$this->putLine($request)) {
@@ -2465,18 +2503,26 @@ class rcube_imap_generic
break;
}
- if (!preg_match('/^\* ([0-9]+) FETCH (.*)$/', $line, $m)) {
+ // skip irrelevant untagged responses (we have a result already)
+ if ($found || !preg_match('/^\* ([0-9]+) FETCH (.*)$/', $line, $m)) {
continue;
}
$line = $m[2];
- $last = substr($line, -1);
// handle one line response
- if ($line[0] == '(' && $last == ')') {
+ if ($line[0] == '(' && substr($line, -1) == ')') {
// tokenize content inside brackets
- $tokens = $this->tokenizeResponse(preg_replace('/(^\(|\$)/', '', $line));
- $result = count($tokens) == 1 ? $tokens[0] : false;
+ // 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) {
+ if (preg_match('/^(BODY|BINARY)/i', $tokens[$i])) {
+ $result = $tokens[$i+1];
+ $found = true;
+ break;
+ }
+ }
if ($result !== false) {
if ($mode == 1) {
@@ -2494,8 +2540,13 @@ class rcube_imap_generic
else if (preg_match('/\{([0-9]+)\}$/', $line, $m)) {
$bytes = (int) $m[1];
$prev = '';
+ $found = true;
- while ($bytes > 0) {
+ // empty body
+ if (!$bytes) {
+ $result = '';
+ }
+ else while ($bytes > 0) {
$line = $this->readLine(8192);
if ($line === NULL) {
@@ -2577,11 +2628,11 @@ class rcube_imap_generic
/**
* Handler for IMAP APPEND command
*
- * @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)
+ * @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)
*
* @return string|bool On success APPENDUID response (if available) or True, False on failure
*/
@@ -2595,13 +2646,28 @@ 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]);
+ }
- if (!$binary) {
- $message = str_replace("\r", '', $message);
- $message = str_replace("\n", "\r\n", $message);
+ $len += strlen($msg[$i]);
+ }
}
- $len = strlen($message);
if (!$len) {
return false;
}
@@ -2626,7 +2692,32 @@ class rcube_imap_generic
}
}
- if (!$this->putLine($message)) {
+ 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
return false;
}
@@ -2665,94 +2756,23 @@ 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))) {
- $in_fp = fopen($path, 'r');
+ $fp = fopen($path, 'r');
}
- if (!$in_fp) {
+ if (!$fp) {
$this->setError(self::ERROR_UNKNOWN, "Couldn't open $path for reading");
return false;
}
- $body_separator = "\r\n\r\n";
- $len = filesize($path);
-
- if (!$len) {
- return false;
- }
-
+ $message = array();
if ($headers) {
- $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);
- }
- $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();
-
- 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");
+ $message[] = trim($headers, "\r\n") . "\r\n\r\n";
}
+ $message[] = $fp;
- return false;
+ return $this->append($mailbox, $message, $flags, $date, $binary);
}
/**
@@ -2970,7 +2990,7 @@ class rcube_imap_generic
}
foreach ($entries as $name => $value) {
- $entries[$name] = $this->escape($name) . ' ' . $this->escape($value);
+ $entries[$name] = $this->escape($name) . ' ' . $this->escape($value, true);
}
$entries = implode(' ', $entries);
@@ -3467,25 +3487,24 @@ class rcube_imap_generic
// Parenthesized list
case '(':
- case '[':
$str = substr($str, 1);
$result[] = self::tokenizeResponse($str);
break;
case ')':
- case ']':
$str = substr($str, 1);
return $result;
break;
- // String atom, number, NIL, *, %
+ // String atom, number, astring, NIL, *, %
default:
// empty string
if ($str === '' || $str === null) {
break 2;
}
- // excluded chars: SP, CTL, ), [, ]
- if (preg_match('/^([^\x00-\x20\x29\x5B\x5D\x7F]+)/', $str, $m)) {
+ // excluded chars: SP, CTL, ), DEL
+ // we do not exclude [ and ] (#1489223)
+ if (preg_match('/^([^\x00-\x20\x29\x7F]+)/', $str, $m)) {
$result[] = $m[1] == 'NIL' ? NULL : $m[1];
$str = substr($str, strlen($m[1]));
}
@@ -3502,7 +3521,7 @@ class rcube_imap_generic
if (is_array($element)) {
reset($element);
- while (list($key, $value) = each($element)) {
+ foreach ($element as $value) {
$string .= ' ' . self::r_implode($value);
}
}
@@ -3638,8 +3657,20 @@ class rcube_imap_generic
*/
static function strToTime($date)
{
- // support non-standard "GMTXXXX" literal
- $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $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);
// if date parsing fails, we have a date in non-rfc format
// remove token from the end and try again
@@ -3664,6 +3695,10 @@ 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;
}
@@ -3709,9 +3744,10 @@ class rcube_imap_generic
/**
* Set the value of the debugging flag.
*
- * @param boolean $debug New value for the debugging flag.
+ * @param boolean $debug New value for the debugging flag.
+ * @param callback $handler Logging handler function
*
- * @since 0.5-stable
+ * @since 0.5-stable
*/
function setDebug($debug, $handler = null)
{
@@ -3722,12 +3758,18 @@ 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 a2dd163e9..555a56471 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-2012, The Roundcube Dev Team |
- | Copyright (C) 2011-2012, Kolab Systems AG |
+ | Copyright (C) 2006-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. |
@@ -27,38 +27,50 @@
*/
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();
-
- /** private properties */
- protected $conn;
- protected $prop = array();
+ public $groups = false;
+ public $readonly = true;
+ public $ready = false;
+ public $group_id = 0;
+ public $coltypes = array();
+
+ // private properties
+ protected $ldap;
+ protected $prop = array();
protected $fieldmap = array();
+ protected $filter = '';
protected $sub_filter;
- protected $filter = '';
- protected $result = null;
- protected $ldap_result = null;
+ protected $result;
+ protected $ldap_result;
protected $mail_domain = '';
protected $debug = false;
- private $base_dn = '';
+ /**
+ * 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 $groups_base_dn = '';
- private $group_url = null;
+ private $group_url;
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
*/
@@ -66,8 +78,7 @@ class rcube_ldap extends rcube_addressbook
{
$this->prop = $p;
- if (isset($p['searchonly']))
- $this->searchonly = $p['searchonly'];
+ $fetch_attributes = array('objectClass');
// check if groups are configured
if (is_array($p['groups']) && count($p['groups'])) {
@@ -82,6 +93,21 @@ 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
@@ -169,7 +195,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 $attr => $class) {
+ foreach ($this->prop['sub_fields'] as $class) {
if (!empty($class)) {
$class = is_array($class) ? array_pop($class) : $class;
$this->sub_filter .= '(objectClass=' . $class . ')';
@@ -186,7 +212,24 @@ class rcube_ldap extends rcube_addressbook
// initialize cache
$rcube = rcube::get_instance();
- $this->cache = $rcube->get_cache('LDAP.' . asciiwords($this->prop['name']), 'db', 600);
+ 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->_connect();
}
@@ -199,49 +242,18 @@ class rcube_ldap extends rcube_addressbook
{
$rcube = rcube::get_instance();
- 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))
+ if ($this->ready)
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) {
- $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");
+ // skip host if connection failed
+ if (!$this->ldap->connect($host)) {
continue;
}
@@ -256,7 +268,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']) {
@@ -275,29 +287,46 @@ 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']) {
- 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']);
- }
-
- // 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);
+ $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);
- $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}");
+ $cache_key = 'DN.' . md5("$host:$search_bind_dn:$search_base_dn:$search_filter:"
+ .$this->prop['search_bind_pw']);
- $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];
- }
+ if ($this->cache && ($dn = $this->cache->get($cache_key))) {
+ $replaces['%dn'] = $dn;
}
else {
- $this->_debug("S: ".ldap_error($this->conn));
+ $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();
+ }
+
+ if ($ldap != $this->ldap) {
+ $ldap->close();
+ }
}
// DN not found
@@ -309,9 +338,13 @@ class rcube_ldap extends rcube_addressbook
'code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "DN not found using LDAP search."), true);
- return false;
+ continue;
}
}
+
+ if ($this->cache && !empty($replaces['%dn'])) {
+ $this->cache->set($cache_key, $replaces['%dn']);
+ }
}
// Replace the bind_dn and base_dn variables.
@@ -329,13 +362,13 @@ class rcube_ldap extends rcube_addressbook
}
else {
if (!empty($bind_dn)) {
- $this->ready = $this->bind($bind_dn, $bind_pass);
+ $this->ready = $this->ldap->bind($bind_dn, $bind_pass);
}
else if (!empty($this->prop['auth_cid'])) {
- $this->ready = $this->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
+ $this->ready = $this->ldap->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
}
else {
- $this->ready = $this->sasl_bind($bind_user, $bind_pass);
+ $this->ready = $this->ldap->sasl_bind($bind_user, $bind_pass);
}
}
@@ -346,10 +379,10 @@ class rcube_ldap extends rcube_addressbook
} // end foreach hosts
- if (!is_resource($this->conn)) {
+ if (!is_resource($this->ldap->conn)) {
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Could not connect to any LDAP server, last tried $hostname"), true);
+ 'message' => "Could not connect to any LDAP server, last tried $host"), true);
return false;
}
@@ -359,112 +392,47 @@ class rcube_ldap extends rcube_addressbook
/**
- * 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
+ * Close connection to LDAP server
*/
- public function sasl_bind($authc, $pass, $authz=null)
+ function 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 ($this->ldap) {
+ $this->ldap->close();
}
-
- 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;
}
/**
- * Bind connection with DN and password
- *
- * @param string Bind DN
- * @param string Bind password
+ * Returns address book name
*
- * @return boolean True on success, False on error
+ * @return string Address book name
*/
- public function bind($dn, $pass)
+ function get_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;
+ return $this->prop['name'];
}
/**
- * Close connection to LDAP server
+ * Set internal list page
+ *
+ * @param number Page number to list
*/
- function close()
+ function set_page($page)
{
- if ($this->conn)
- {
- $this->_debug("C: Close");
- ldap_unbind($this->conn);
- $this->conn = null;
- }
+ $this->list_page = (int)$page;
+ $this->ldap->set_vlv_page($this->list_page, $this->page_size);
}
-
/**
- * Returns address book name
+ * Set internal page size
*
- * @return string Address book name
+ * @param number Number of records to display on one page
*/
- function get_name()
+ function set_pagesize($size)
{
- return $this->prop['name'];
+ $this->page_size = (int)$size;
+ $this->ldap->set_vlv_page($this->list_page, $this->page_size);
}
@@ -524,16 +492,14 @@ 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
@@ -547,34 +513,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
- {
- // add general filter to query
- if (!empty($this->prop['filter']) && empty($this->filter))
- $this->set_search_set($this->prop['filter']);
+ else {
+ $prop = $this->group_id ? $this->group_data : $this->prop;
+
+ // use global search filter
+ if (!empty($this->filter))
+ $prop['filter'] = $this->filter;
// exec LDAP search if no result resource is stored
- if ($this->conn && !$this->ldap_result)
- $this->_exec_search();
+ if ($this->ready && !$this->ldap_result)
+ $this->ldap_result = $this->ldap->search($prop['base_dn'], $prop['filter'], $prop['scope'], $this->prop['attributes'], $prop);
// 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 && $this->prop['scope'] !== 'base' && !$this->vlv_active)
- ldap_sort($this->conn, $this->ldap_result, $this->sort_col);
+ if ($this->sort_col && $prop['scope'] !== 'base' && !$this->ldap->vlv_active)
+ $this->ldap_result->sort($this->sort_col);
// get all entries from the ldap server
- $entries = ldap_get_entries($this->conn, $this->ldap_result);
+ $entries = $this->ldap_result->entries();
}
} // end else
// start and end of the page
- $start_row = $this->vlv_active ? 0 : $this->result->first;
+ $start_row = $this->ldap->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;
@@ -599,43 +565,34 @@ class rcube_ldap extends rcube_addressbook
// fetch group object
if (empty($entries)) {
- $result = @ldap_read($this->conn, $dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL'));
- if ($result === false)
- {
- $this->_debug("S: ".ldap_error($this->conn));
+ $attribs = array('dn','objectClass','member','uniqueMember','memberURL');
+ $entries = $this->ldap->read_entries($dn, '(objectClass=*)', $attribs);
+ if ($entries === false) {
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();
- if (empty($entry['objectclass']))
- continue;
+ 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;
+ }
- 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 2;
}
}
-
- if ($this->prop['sizelimit'] && count($group_members) > $this->prop['sizelimit'])
- break;
}
return array_filter($group_members);
@@ -654,28 +611,24 @@ 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') : array_values($this->fieldmap);
- $attrib[] = 'objectClass';
+ $attrib = $count ? array('dn','objectClass') : $this->prop['list_attributes'];
$attrib[] = 'member';
$attrib[] = 'uniqueMember';
$attrib[] = 'memberURL';
- for ($i=0; $i < $entry[$attr]['count']; $i++)
- {
+ $filter = $this->prop['groups']['member_filter'] ? $this->prop['groups']['member_filter'] : '(objectclass=*)';
+
+ for ($i=0; $i < $entry[$attr]['count']; $i++) {
if (empty($entry[$attr][$i]))
continue;
- $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 = $this->ldap->read_entries($entry[$attr][$i], $filter, $attrib);
+ if ($members == false) {
$members = array();
}
@@ -701,34 +654,22 @@ 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];
- $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];
+ $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];
+ }
}
}
@@ -764,14 +705,11 @@ 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++;
}
@@ -783,34 +721,20 @@ class rcube_ldap extends rcube_addressbook
$rcube = rcube::get_instance();
$list_fields = $rcube->config->get('contactlist_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']);
-
+ if ($this->prop['vlv_search'] && $this->ready && join(',', (array)$fields) == join(',', $list_fields)) {
$this->result = new rcube_result_set(0);
- if (!$this->ldap_result) {
- $this->_debug("S: ".ldap_error($this->conn));
+ $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) {
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);
- $entries = ldap_get_entries($this->conn, $this->ldap_result);
-
- for ($i = 0; $i < $entries['count']; $i++) {
- $rec = $this->_ldap2result($entries[$i]);
+ $search = mb_strtolower($value);
+ foreach ($ldap_data as $i => $entry) {
+ $rec = $this->_ldap2result($entry);
foreach ($fields as $f) {
foreach ((array)$rec[$f] as $val) {
if ($this->compare_search_value($f, $val, $search, $mode)) {
@@ -836,31 +760,27 @@ 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" . $this->_quote_string($value) . "$ws)";
+ $filter .= "($field=$wp" . rcube_ldap_generic::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" . $this->_quote_string($val) . "$ws)";
+ $filter .= "($f=$wp" . rcube_ldap_generic::quote_string($val) . "$ws)";
if (count($attrs) > 1)
$filter .= ')';
}
@@ -871,6 +791,8 @@ class rcube_ldap extends rcube_addressbook
// add required (non empty) fields filter
$req_filter = '';
foreach ((array)$required as $field) {
+ if (in_array($field, (array)$fields)) // required field is already in search filter
+ continue;
if ($attrs = $this->_map_field($field)) {
if (count($attrs) > 1)
$req_filter .= '(|';
@@ -893,7 +815,6 @@ 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();
@@ -912,20 +833,20 @@ class rcube_ldap extends rcube_addressbook
function count()
{
$count = 0;
- if ($this->conn && $this->ldap_result) {
- $count = $this->vlv_active ? $this->vlv_count : ldap_count_entries($this->conn, $this->ldap_result);
+ if ($this->ldap_result) {
+ $count = $this->ldap_result->count();
}
else if ($this->group_id && $this->group_data['dn']) {
$count = count($this->list_group_members($this->group_data['dn'], true));
}
- 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'];
- }
+ // 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;
- $count = (int) $this->_exec_search(true);
+ if (!empty($this->filter)) { // Use global search filter
+ $prop['filter'] = $this->filter;
+ }
+ $count = $this->ldap->search($prop['base_dn'], $prop['filter'], $prop['scope'], array('dn'), $prop, true);
}
return new rcube_result_set($count, ($this->list_page-1) * $this->page_size);
@@ -955,28 +876,16 @@ class rcube_ldap extends rcube_addressbook
{
$res = $this->result = null;
- if ($this->conn && $dn)
- {
+ if ($this->ready && $dn) {
$dn = self::dn_decode($dn);
- $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));
+ if ($rec = $this->ldap->get_entry($dn)) {
+ $rec = array_change_key_case($rec, CASE_LOWER);
}
// Use ldap_list to get subentries like country (c) attribute (#1488123)
if (!empty($rec) && $this->sub_filter) {
- if ($entries = $this->ldap_list($dn, $this->sub_filter, array_keys($this->prop['sub_fields']))) {
+ if ($entries = $this->ldap->list_entries($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);
@@ -988,7 +897,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();
+ $this->result = new rcube_result_set(1);
$this->result->add($res);
}
}
@@ -1035,7 +944,6 @@ 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]) {
@@ -1102,12 +1010,12 @@ class rcube_ldap extends rcube_addressbook
}
// Build the new entries DN.
- $dn = $this->prop['LDAP_rdn'].'='.$this->_quote_string($newentry[$this->prop['LDAP_rdn']], true).','.$this->base_dn;
+ $dn = $this->prop['LDAP_rdn'].'='.rcube_ldap_generic::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 ($this->prop['sub_fields'] as $xf => $xclass) {
+ foreach (array_keys($this->prop['sub_fields']) as $xf) {
if (!empty($newentry[$xf])) {
$xfields[$xf] = $newentry[$xf];
unset($newentry[$xf]);
@@ -1115,19 +1023,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.'='.$this->_quote_string($xf).','.$dn;
+ $xdn = $xidx.'='.rcube_ldap_generic::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);
@@ -1170,7 +1078,7 @@ class rcube_ldap extends rcube_addressbook
}
}
- foreach ($this->fieldmap as $col => $fld) {
+ foreach ($this->fieldmap as $fld) {
if ($fld) {
$val = $ldap_data[$fld];
$old = $old_data[$fld];
@@ -1233,7 +1141,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;
}
@@ -1243,17 +1151,17 @@ class rcube_ldap extends rcube_addressbook
// Handle RDN change
if ($replacedata[$this->prop['LDAP_rdn']]) {
$newdn = $this->prop['LDAP_rdn'].'='
- .$this->_quote_string($replacedata[$this->prop['LDAP_rdn']], true)
+ .rcube_ldap_generic::quote_string($replacedata[$this->prop['LDAP_rdn']], true)
.','.$this->base_dn;
if ($dn != $newdn) {
$newrdn = $this->prop['LDAP_rdn'].'='
- .$this->_quote_string($replacedata[$this->prop['LDAP_rdn']], true);
+ .rcube_ldap_generic::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;
}
@@ -1269,8 +1177,8 @@ class rcube_ldap extends rcube_addressbook
// remove sub-entries
if (!empty($subdeldata)) {
foreach ($subdeldata as $fld => $val) {
- $subdn = $fld.'='.$this->_quote_string($val).','.$dn;
- if (!$this->ldap_delete($subdn)) {
+ $subdn = $fld.'='.rcube_ldap_generic::quote_string($val).','.$dn;
+ if (!$this->ldap->delete($subdn)) {
return false;
}
}
@@ -1278,7 +1186,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;
}
@@ -1286,7 +1194,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;
}
@@ -1297,8 +1205,7 @@ class rcube_ldap extends rcube_addressbook
// change the group membership of the contact
if ($this->groups) {
$group_ids = $this->get_record_groups($dn);
- foreach ($group_ids as $group_id)
- {
+ foreach (array_keys($group_ids) as $group_id) {
$this->remove_from_group($group_id, $dn);
$this->add_to_group($group_id, $newdn);
}
@@ -1310,12 +1217,12 @@ class rcube_ldap extends rcube_addressbook
// add sub-entries
if (!empty($subnewdata)) {
foreach ($subnewdata as $fld => $val) {
- $subdn = $fld.'='.$this->_quote_string($val).','.$dn;
+ $subdn = $fld.'='.rcube_ldap_generic::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);
}
}
@@ -1343,9 +1250,9 @@ class rcube_ldap extends rcube_addressbook
// Need to delete all sub-entries first
if ($this->sub_filter) {
- if ($entries = $this->ldap_list($dn, $this->sub_filter)) {
+ if ($entries = $this->ldap->list_entries($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;
}
@@ -1354,7 +1261,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;
}
@@ -1363,7 +1270,7 @@ class rcube_ldap extends rcube_addressbook
if ($this->groups) {
$dn = self::dn_encode($dn);
$group_ids = $this->get_record_groups($dn);
- foreach ($group_ids as $group_id) {
+ foreach (array_keys($group_ids) as $group_id) {
$this->remove_from_group($group_id, $dn);
}
}
@@ -1378,8 +1285,8 @@ class rcube_ldap extends rcube_addressbook
*/
function delete_all()
{
- //searching for contact entries
- $dn_list = $this->ldap_list($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)');
+ // searching for contact entries
+ $dn_list = $this->ldap->list_entries($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)');
if (!empty($dn_list)) {
foreach ($dn_list as $idx => $entry) {
@@ -1396,6 +1303,10 @@ 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;
@@ -1403,117 +1314,26 @@ class rcube_ldap extends rcube_addressbook
foreach ((array)$this->prop['autovalues'] as $lf => $templ) {
if (empty($attrs[$lf])) {
- // replace {attr} placeholders with concrete attribute values
- $templ = preg_replace('/\{\w+\}/', '', strtr($templ, $attrvals));
-
- if (strpos($templ, '(') !== false)
- $attrs[$lf] = eval("return ($templ);");
- else
- $attrs[$lf] = $templ;
- }
- }
- }
+ 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;
+ }
- /**
- * 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);
+ $attrs[$lf] = $fn();
}
- 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)));
- }
+ else {
+ // replace {attr} placeholders with concrete attribute values
+ $attrs[$lf] = preg_replace('/\{\w+\}/', '', strtr($templ, $attrvals));
}
-
- $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;
}
@@ -1522,12 +1342,20 @@ class rcube_ldap extends rcube_addressbook
*/
private function _ldap2result($rec)
{
- $out = array();
+ $out = array('_type' => 'person');
+ $fieldmap = $this->fieldmap;
if ($rec['dn'])
$out[$this->primary_key] = self::dn_encode($rec['dn']);
- foreach ($this->fieldmap as $rf => $lf)
+ // 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)
{
for ($i=0; $i < $rec[$lf]['count']; $i++) {
if (!($value = $rec[$lf][$i]))
@@ -1589,8 +1417,10 @@ 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)
- $save_cols[$key][$i] = join($delim, array($val['street'], $val['locality'], $val['zipcode'], $val['country']));
+ 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;
+ }
}
}
}
@@ -1628,11 +1458,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);
@@ -1641,6 +1471,15 @@ 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
@@ -1657,55 +1496,27 @@ 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;
- }
-
- /**
- * 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);
+ if ($this->ldap) {
+ $this->ldap->set_debug($dbg);
+ }
}
/**
* Setter for the current group
- * (empty, has to be re-implemented by extending class)
*/
function set_group($group_id)
{
- if ($group_id)
- {
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
+ if ($group_id) {
$this->group_id = $group_id;
- $this->group_data = $group_cache[$group_id];
+ $this->group_data = $this->get_group_entry($group_id);
}
- else
- {
+ else {
$this->group_id = 0;
$this->group_data = null;
}
@@ -1715,28 +1526,32 @@ class rcube_ldap extends rcube_addressbook
* List all active contact groups of this source
*
* @param string Optional search string to match group name
+ * @param int Matching mode:
+ * 0 - partial (*abc*),
+ * 1 - strict (=),
+ * 2 - prefix (abc*)
+ *
* @return array Indexed list of contact groups, each a hash array
*/
- function list_groups($search = null)
+ function list_groups($search = null, $mode = 0)
{
- if (!$this->groups)
+ if (!$this->groups) {
return array();
+ }
- // use cached list for searching
- $this->cache->expunge();
- if (!$search || ($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
+ $group_cache = $this->_fetch_groups();
+ $groups = array();
- $groups = array();
if ($search) {
- $search = mb_strtolower($search);
foreach ($group_cache as $group) {
- if (strpos(mb_strtolower($group['name']), $search) !== false)
+ if ($this->compare_search_value('name', $group['name'], $search, $mode)) {
$groups[] = $group;
+ }
}
}
- else
+ else {
$groups = $group_cache;
+ }
return array_values($groups);
}
@@ -1744,80 +1559,139 @@ class rcube_ldap extends rcube_addressbook
/**
* Fetch groups from server
*/
- private function _fetch_groups($vlv_page = 0)
+ private function _fetch_groups($vlv_page = null)
{
- $base_dn = $this->groups_base_dn;
- $filter = $this->prop['groups']['filter'];
- $name_attr = $this->prop['groups']['name_attr'];
+ // 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'];
+ $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];
- $this->_debug("C: Search [$filter][dn: $base_dn]");
+ $ldap = $this->ldap;
// 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;
- $vlv_active = $this->_vlv_set_controls($this->prop['groups'], $vlv_page+1, $page_size);
+ }
+
+ $ldap = clone $this->ldap;
+ $ldap->set_config($this->prop['groups']);
+ $ldap->set_vlv_page($vlv_page+1, $page_size);
}
- $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));
+ $attrs = array_unique(array('dn', 'objectClass', $name_attr, $email_attr, $sort_attr));
+ $ldap_data = $ldap->search($base_dn, $filter, $this->prop['groups']['scope'], $attrs, $this->prop['groups']);
+
+ if ($ldap_data === false) {
return array();
}
- $ldap_data = ldap_get_entries($this->conn, $res);
- $this->_debug("S: ".ldap_count_entries($this->conn, $res)." record(s)");
-
- $groups = array();
+ $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);
+ $group_count = $ldap_data->count();
+
+ foreach ($ldap_data as $entry) {
+ if (!$entry['dn']) // DN is mandatory
+ $entry['dn'] = $ldap_data->get_dn();
+
+ $group_name = is_array($entry[$name_attr]) ? $entry[$name_attr][0] : $entry[$name_attr];
+ $group_id = self::dn_encode($entry['dn']);
$groups[$group_id]['ID'] = $group_id;
- $groups[$group_id]['dn'] = $ldap_data[$i]['dn'];
+ $groups[$group_id]['dn'] = $entry['dn'];
$groups[$group_id]['name'] = $group_name;
- $groups[$group_id]['member_attr'] = $this->get_group_member_attr($ldap_data[$i]['objectclass']);
+ $groups[$group_id]['member_attr'] = $this->get_group_member_attr($entry['objectclass']);
// list email attributes of a group
- 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];
+ 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];
}
- $group_sortnames[] = mb_strtolower($ldap_data[$i][$sort_attr][0]);
+ $group_sortnames[] = mb_strtolower($entry[$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 ($vlv_active && $group_count == $page_size)
- {
- $next_page = $this->_fetch_groups(++$vlv_page);
- $groups = array_merge($groups, $next_page);
+ while ($this->prop['groups']['vlv'] && $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
- $this->cache->set('groups', $groups);
+ if ($this->cache) {
+ $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
@@ -1825,10 +1699,7 @@ class rcube_ldap extends rcube_addressbook
*/
function get_group($group_id)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
- $group_data = $group_cache[$group_id];
+ $group_data = $this->get_group_entry($group_id);
unset($group_data['dn'], $group_data['member_attr']);
return $group_data;
@@ -1842,24 +1713,24 @@ class rcube_ldap extends rcube_addressbook
*/
function create_group($group_name)
{
- $base_dn = $this->groups_base_dn;
- $new_dn = "cn=$group_name,$base_dn";
- $new_gid = self::dn_encode($group_name);
+ $new_dn = 'cn=' . rcube_ldap_generic::quote_string($group_name, true) . ',' . $this->groups_base_dn;
+ $new_gid = self::dn_encode($new_dn);
$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;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
return array('id' => $new_gid, 'name' => $group_name);
}
@@ -1872,19 +1743,18 @@ class rcube_ldap extends rcube_addressbook
*/
function delete_group($group_id)
{
- 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'];
- $del_dn = "cn=$group_name,$base_dn";
+ $group_cache = $this->_fetch_groups();
+ $del_dn = $group_cache[$group_id]['dn'];
- if (!$this->ldap_delete($del_dn)) {
+ if (!$this->ldap->delete($del_dn)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ unset($group_cache[$group_id]);
+ $this->cache->set('groups', $group_cache);
+ }
return true;
}
@@ -1899,21 +1769,19 @@ class rcube_ldap extends rcube_addressbook
*/
function rename_group($group_id, $new_name, &$new_gid)
{
- 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);
+ $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 (!$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;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
return $new_name;
}
@@ -1921,66 +1789,71 @@ class rcube_ldap extends rcube_addressbook
/**
* Add the given contact records the a certain group
*
- * @param string Group identifier
- * @param array List of contact identifiers to be added
- * @return int Number of contacts added
+ * @param string Group identifier
+ * @param array|string List of contact identifiers to be added
+ *
+ * @return int Number of contacts added
*/
function add_to_group($group_id, $contact_ids)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
+ $group_cache = $this->_fetch_groups();
+ $member_attr = $group_cache[$group_id]['member_attr'];
+ $group_dn = $group_cache[$group_id]['dn'];
+ $new_attrs = array();
- if (!is_array($contact_ids))
+ if (!is_array($contact_ids)) {
$contact_ids = explode(',', $contact_ids);
+ }
- $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)
+ 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;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
- return count($new_attrs['member']);
+ return count($new_attrs[$member_attr]);
}
/**
* Remove the given contact records from a certain group
*
- * @param string Group identifier
- * @param array List of contact identifiers to be removed
- * @return int Number of deleted group members
+ * @param string Group identifier
+ * @param array|string List of contact identifiers to be removed
+ *
+ * @return int Number of deleted group members
*/
function remove_from_group($group_id, $contact_ids)
{
- 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'];
+ $group_cache = $this->_fetch_groups();
$member_attr = $group_cache[$group_id]['member_attr'];
- $group_dn = "cn=$group_name,$base_dn";
+ $group_dn = $group_cache[$group_id]['dn'];
+ $del_attrs = array();
- $del_attrs = array();
- foreach (explode(",", $contact_ids) as $id)
+ if (!is_array($contact_ids)) {
+ $contact_ids = explode(',', $contact_ids);
+ }
+
+ 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;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
- return count($del_attrs['member']);
+ return count($del_attrs[$member_attr]);
}
/**
@@ -1993,206 +1866,63 @@ 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('\\' => '\\\\'));
- $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));
+ $ldap_data = $this->ldap->search($base_dn, $filter, 'sub', array('dn', $name_attr));
+ if ($res === false) {
return array();
}
- $ldap_data = ldap_get_entries($this->conn, $res);
- $this->_debug("S: ".ldap_count_entries($this->conn, $res)." record(s)");
$groups = array();
- 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;
+ 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;
}
+
return $groups;
}
/**
* Detects group member attribute name
*/
- private function get_group_member_attr($object_classes = array())
+ private function get_group_member_attr($object_classes = array(), $default = 'member')
{
if (empty($object_classes)) {
$object_classes = $this->prop['groups']['object_classes'];
}
+
if (!empty($object_classes)) {
foreach ((array)$object_classes as $oc) {
- switch (strtolower($oc)) {
- case 'group':
- case 'groupofnames':
- case 'kolabgroupofnames':
- $member_attr = 'member';
- break;
-
- case 'groupofuniquenames':
- case 'kolabgroupofuniquenames':
- $member_attr = 'uniqueMember';
- break;
+ if ($attr = self::$group_types[strtolower($oc)]) {
+ return $attr;
}
}
}
- if (!empty($member_attr)) {
- return $member_attr;
- }
-
if (!empty($this->prop['groups']['member_attr'])) {
return $this->prop['groups']['member_attr'];
}
- return 'member';
+ return $default;
}
/**
- * 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
@@ -2219,130 +1949,4 @@ 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
new file mode 100644
index 000000000..88378dc22
--- /dev/null
+++ b/program/lib/Roundcube/rcube_ldap_generic.php
@@ -0,0 +1,1049 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | Roundcube/rcube_ldap_generic.php |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012-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. |
+ | |
+ | PURPOSE: |
+ | Provide basic functionality for accessing LDAP directories |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Aleksander Machniak <machniak@kolabsys.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+/*
+ LDAP connection properties
+ --------------------------
+
+ $prop = array(
+ 'host' => '<ldap-server-address>',
+ // or
+ 'hosts' => array('directory.verisign.com'),
+ 'port' => 389,
+ 'use_tls' => true|false,
+ 'ldap_version' => 3, // using LDAPv3
+ 'auth_method' => '', // SASL authentication method (for proxy auth), e.g. DIGEST-MD5
+ 'attributes' => array('dn'), // List of attributes to read from the server
+ 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it)
+ 'config_root_dn' => 'cn=config', // Root DN to read config (e.g. vlv indexes) from
+ '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.
+ 'network_timeout' => 10, // The timeout (in seconds) for connect + bind arrempts. This is only supported in PHP >= 5.3.0 with OpenLDAP 2.x
+ 'referrals' => true|false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups
+ );
+*/
+
+/**
+ * Model class to access an LDAP directories
+ *
+ * @package Framework
+ * @subpackage LDAP
+ */
+class rcube_ldap_generic
+{
+ const UPDATE_MOD_ADD = 1;
+ const UPDATE_MOD_DELETE = 2;
+ const UPDATE_MOD_REPLACE = 4;
+ const UPDATE_MOD_FULL = 7;
+
+ public $conn;
+ public $vlv_active = false;
+
+ /** private properties */
+ protected $cache = null;
+ protected $config = array();
+ protected $attributes = array('dn');
+ protected $entries = null;
+ protected $result = null;
+ protected $debug = false;
+ protected $list_page = 1;
+ protected $page_size = 10;
+ protected $vlv_config = null;
+
+
+ /**
+ * Object constructor
+ *
+ * @param array $p LDAP connection properties
+ */
+ function __construct($p)
+ {
+ $this->config = $p;
+
+ if (is_array($p['attributes']))
+ $this->attributes = $p['attributes'];
+
+ if (!is_array($p['hosts']) && !empty($p['host']))
+ $this->config['hosts'] = array($p['host']);
+ }
+
+ /**
+ * Activate/deactivate debug mode
+ *
+ * @param boolean $dbg True if LDAP commands should be logged
+ */
+ public function set_debug($dbg = true)
+ {
+ $this->debug = $dbg;
+ }
+
+ /**
+ * Set connection options
+ *
+ * @param mixed $opt Option name as string or hash array with multiple options
+ * @param mixed $val Option value
+ */
+ public function set_config($opt, $val = null)
+ {
+ if (is_array($opt))
+ $this->config = array_merge($this->config, $opt);
+ else
+ $this->config[$opt] = $value;
+ }
+
+ /**
+ * Enable caching by passing an instance of rcube_cache to be used by this object
+ *
+ * @param object rcube_cache Instance or False to disable caching
+ */
+ public function set_cache($cache_engine)
+ {
+ $this->cache = $cache_engine;
+ }
+
+ /**
+ * Set properties for VLV-based paging
+ *
+ * @param number $page Page number to list (starting at 1)
+ * @param number $size Number of entries to display on one page
+ */
+ public function set_vlv_page($page, $size = 10)
+ {
+ $this->list_page = $page;
+ $this->page_size = $size;
+ }
+
+ /**
+ * Establish a connection to the LDAP server
+ */
+ public function connect($host = null)
+ {
+ 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);
+ return false;
+ }
+
+ if (is_resource($this->conn) && $this->config['host'] == $host)
+ return true;
+
+ if (empty($this->config['ldap_version']))
+ $this->config['ldap_version'] = 3;
+
+ // iterate over hosts if none specified
+ if (!$host) {
+ if (!is_array($this->config['hosts']))
+ $this->config['hosts'] = array($this->config['hosts']);
+
+ foreach ($this->config['hosts'] as $host) {
+ if ($this->connect($host)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // open connection to the given $host
+ $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
+ $hostname = $host . ($this->config['port'] ? ':'.$this->config['port'] : '');
+
+ $this->_debug("C: Connect to $hostname [{$this->config['name']}]");
+
+ if ($lc = @ldap_connect($host, $this->config['port'])) {
+ if ($this->config['use_tls'] === true)
+ if (!ldap_start_tls($lc))
+ continue;
+
+ $this->_debug("S: OK");
+
+ ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->config['ldap_version']);
+ $this->config['host'] = $host;
+ $this->conn = $lc;
+
+ if (!empty($this->config['network_timeout']))
+ ldap_set_option($lc, LDAP_OPT_NETWORK_TIMEOUT, $this->config['network_timeout']);
+
+ if (isset($this->config['referrals']))
+ ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->config['referrals']);
+ }
+ else {
+ $this->_debug("S: NOT OK");
+ }
+
+ 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 $hostname"),
+ true);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * 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
+ */
+ public function sasl_bind($authc, $pass, $authz=null)
+ {
+ 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);
+ return false;
+ }
+
+ if (!empty($authz)) {
+ $authz = 'u:' . $authz;
+ }
+
+ if (!empty($this->config['auth_method'])) {
+ $method = $this->config['auth_method'];
+ }
+ else {
+ $method = 'DIGEST-MD5';
+ }
+
+ $this->_debug("C: SASL 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' => "SASL Bind failed for authcid=$authc ".ldap_error($this->conn)),
+ true);
+ return false;
+ }
+
+ /**
+ * Bind connection with DN and password
+ *
+ * @param string $dn Bind DN
+ * @param string $pass Bind password
+ *
+ * @return boolean True on success, False on error
+ */
+ public function bind($dn, $pass)
+ {
+ if (!$this->conn) {
+ return false;
+ }
+
+ $this->_debug("C: Bind $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;
+ }
+
+ /**
+ * Close connection to LDAP server
+ */
+ public function close()
+ {
+ if ($this->conn) {
+ $this->_debug("C: Close");
+ ldap_unbind($this->conn);
+ $this->conn = null;
+ }
+ }
+
+ /**
+ * Return the last result set
+ *
+ * @return object rcube_ldap_result Result object
+ */
+ function get_result()
+ {
+ return $this->result;
+ }
+
+ /**
+ * Get a specific LDAP entry, identified by its DN
+ *
+ * @param string $dn Record identifier
+ * @return array Hash array
+ */
+ function get_entry($dn)
+ {
+ $rec = null;
+
+ if ($this->conn && $dn) {
+ $this->_debug("C: Read $dn [(objectclass=*)]");
+
+ if ($ldap_result = @ldap_read($this->conn, $dn, '(objectclass=*)', $this->attributes)) {
+ $this->_debug("S: OK");
+
+ if ($entry = ldap_first_entry($this->conn, $ldap_result)) {
+ $rec = ldap_get_attributes($this->conn, $entry);
+ }
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+
+ if (!empty($rec)) {
+ $rec['dn'] = $dn; // Add in the dn for the entry.
+ }
+ }
+
+ return $rec;
+ }
+
+ /**
+ * Execute the LDAP search based on the stored credentials
+ *
+ * @param string $base_dn The base DN to query
+ * @param string $filter The LDAP filter for search
+ * @param string $scope The LDAP scope (list|sub|base)
+ * @param array $attrs List of entry attributes to read
+ * @param array $prop Hash array with query configuration properties:
+ * - sort: array of sort attributes (has to be in sync with the VLV index)
+ * - search: search string used for VLV controls
+ * @param boolean $count_only Set to true if only entry count is requested
+ *
+ * @return mixed rcube_ldap_result object or number of entries (if count_only=true) or false on error
+ */
+ public function search($base_dn, $filter = '', $scope = 'sub', $attrs = array('dn'), $prop = array(), $count_only = false)
+ {
+ if (!$this->conn) {
+ return false;
+ }
+
+ if (empty($filter)) {
+ $filter = '(objectclass=*)';
+ }
+
+ $this->_debug("C: Search $base_dn for $filter");
+
+ $function = self::scope2func($scope, $ns_function);
+
+ // find available VLV index for this query
+ if (!$count_only && ($vlv_sort = $this->_find_vlv($base_dn, $filter, $scope, $prop['sort']))) {
+ // when using VLV, we get the total count by...
+ // ...either reading numSubOrdinates attribute
+ if (($sub_filter = $this->config['numsub_filter']) &&
+ ($result_count = @$ns_function($this->conn, $base_dn, $sub_filter, array('numSubOrdinates'), 0, 0, 0))
+ ) {
+ $counts = ldap_get_entries($this->conn, $result_count);
+ for ($vlv_count = $j = 0; $j < $counts['count']; $j++)
+ $vlv_count += $counts[$j]['numsubordinates'][0];
+ $this->_debug("D: total numsubordinates = " . $vlv_count);
+ }
+ // ...or by fetching all records dn and count them
+ else if (!function_exists('ldap_parse_virtuallist_control')) {
+ $vlv_count = $this->search($base_dn, $filter, $scope, array('dn'), $prop, true);
+ }
+
+ $this->vlv_active = $this->_vlv_set_controls($vlv_sort, $this->list_page, $this->page_size, $prop['search']);
+ }
+ else {
+ $this->vlv_active = false;
+ }
+
+ // only fetch dn for count (should keep the payload low)
+ if ($ldap_result = @$function($this->conn, $base_dn, $filter,
+ $attrs, 0, (int)$this->config['sizelimit'], (int)$this->config['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, $ldap_result, $errcode, $matcheddn, $errmsg, $referrals, $serverctrls)) {
+ ldap_parse_virtuallist_control($this->conn, $serverctrls, $last_offset, $vlv_count, $vresult);
+ $this->_debug("S: VLV result: last_offset=$last_offset; content_count=$vlv_count");
+ }
+ else {
+ $this->_debug("S: ".($errmsg ? $errmsg : ldap_error($this->conn)));
+ }
+ }
+ else if ($this->debug) {
+ $this->_debug("S: ".ldap_count_entries($this->conn, $ldap_result)." record(s) found");
+ }
+
+ $this->result = new rcube_ldap_result($this->conn, $ldap_result, $base_dn, $filter, $vlv_count);
+
+ return $count_only ? $this->result->count() : $this->result;
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+
+ return false;
+ }
+
+ /**
+ * Modify an LDAP entry on the server
+ *
+ * @param string $dn Entry DN
+ * @param array $params Hash array of entry attributes
+ * @param int $mode Update mode (UPDATE_MOD_ADD | UPDATE_MOD_DELETE | UPDATE_MOD_REPLACE)
+ */
+ public function modify($dn, $parms, $mode = 255)
+ {
+ // TODO: implement this
+
+ return false;
+ }
+
+ /**
+ * Wrapper for ldap_add()
+ *
+ * @see ldap_add()
+ */
+ public function add($dn, $entry)
+ {
+ $this->_debug("C: Add $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()
+ *
+ * @see ldap_delete()
+ */
+ public function delete($dn)
+ {
+ $this->_debug("C: Delete $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()
+ *
+ * @see ldap_mod_replace()
+ */
+ public function mod_replace($dn, $entry)
+ {
+ $this->_debug("C: Replace $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()
+ *
+ * @see ldap_mod_add()
+ */
+ public function mod_add($dn, $entry)
+ {
+ $this->_debug("C: Add $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()
+ *
+ * @see ldap_mod_del()
+ */
+ public function mod_del($dn, $entry)
+ {
+ $this->_debug("C: Delete $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()
+ *
+ * @see ldap_rename()
+ */
+ public function rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true)
+ {
+ $this->_debug("C: Rename $dn to $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() + ldap_get_entries()
+ *
+ * @see ldap_list()
+ * @see ldap_get_entries()
+ */
+ public function list_entries($dn, $filter, $attributes = array('dn'))
+ {
+ $list = array();
+ $this->_debug("C: List $dn [{$filter}]");
+
+ if ($result = ldap_list($this->conn, $dn, $filter, $attributes)) {
+ $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;
+ }
+
+ /**
+ * Wrapper for ldap_read() + ldap_get_entries()
+ *
+ * @see ldap_read()
+ * @see ldap_get_entries()
+ */
+ public function read_entries($dn, $filter, $attributes = null)
+ {
+ $this->_debug("C: Read $dn [{$filter}]");
+
+ if ($this->conn && $dn) {
+ if (!$attributes)
+ $attributes = $this->attributes;
+
+ $result = @ldap_read($this->conn, $dn, $filter, $attributes, 0, (int)$this->config['sizelimit'], (int)$this->config['timelimit']);
+ if ($result === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return ldap_get_entries($this->conn, $result);
+ }
+
+ return false;
+ }
+
+ /**
+ * Choose the right PHP function according to scope property
+ *
+ * @param string $scope The LDAP scope (sub|base|list)
+ * @param string $ns_function Function to be used for numSubOrdinates queries
+ * @return string PHP function to be used to query directory
+ */
+ public static 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;
+ }
+
+ /**
+ * Convert the given scope integer value to a string representation
+ */
+ public static function scopeint2str($scope)
+ {
+ switch ($scope) {
+ case 2: return 'sub';
+ case 1: return 'one';
+ case 0: return 'base';
+ default: $this->_debug("Scope $scope is not a valid scope integer");
+ }
+
+ return '';
+ }
+
+ /**
+ * Escapes the given value according to RFC 2254 so that it can be safely used in LDAP filters.
+ *
+ * @param string $val Value to quote
+ * @return string The escaped value
+ */
+ public static function escape_value($val)
+ {
+ return strtr($str, array('*'=>'\2a', '('=>'\28', ')'=>'\29',
+ '\\'=>'\5c', '/'=>'\2f'));
+ }
+
+ /**
+ * Escapes a DN value according to RFC 2253
+ *
+ * @param string $dn DN value o quote
+ * @return string The escaped value
+ */
+ public static function escape_dn($dn)
+ {
+ return strtr($str, array(','=>'\2c', '='=>'\3d', '+'=>'\2b',
+ '<'=>'\3c', '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c',
+ '"'=>'\22', '#'=>'\23'));
+ }
+
+ /**
+ * Normalize a LDAP result by converting entry attributes arrays into single values
+ *
+ * @param array $result LDAP result set fetched with ldap_get_entries()
+ * @return array Hash array with normalized entries, indexed by their DNs
+ */
+ public static function normalize_result($result)
+ {
+ if (!is_array($result)) {
+ return array();
+ }
+
+ $entries = array();
+ for ($i = 0; $i < $result['count']; $i++) {
+ $key = $result[$i]['dn'] ? $result[$i]['dn'] : $i;
+ $entries[$key] = self::normalize_entry($result[$i]);
+ }
+
+ return $entries;
+ }
+
+ /**
+ * 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)
+ {
+ $rec = array();
+ for ($i=0; $i < $entry['count']; $i++) {
+ $attr = $entry[$i];
+ if ($entry[$attr]['count'] == 1) {
+ switch ($attr) {
+ case 'objectclass':
+ $rec[$attr] = array(strtolower($entry[$attr][0]));
+ break;
+ default:
+ $rec[$attr] = $entry[$attr][0];
+ break;
+ }
+ }
+ else {
+ for ($j=0; $j < $entry[$attr]['count']; $j++) {
+ $rec[$attr][$j] = $entry[$attr][$j];
+ }
+ }
+ }
+
+ return $rec;
+ }
+
+ /**
+ * Set server controls for Virtual List View (paginated listing)
+ */
+ private function _vlv_set_controls($sort, $list_page, $page_size, $search = null)
+ {
+ $sort_ctrl = array('oid' => "1.2.840.113556.1.4.473", 'value' => self::_sort_ber_encode((array)$sort));
+ $vlv_ctrl = array('oid' => "2.16.840.1.113730.3.4.9", 'value' => self::_vlv_ber_encode(($offset = ($list_page-1) * $page_size + 1), $page_size, $search), 'iscritical' => true);
+
+ $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; $search)");
+
+ 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;
+ }
+
+ /**
+ * Returns unified attribute name (resolving aliases)
+ */
+ private static function _attr_name($namev)
+ {
+ // list of known attribute aliases
+ static $aliases = array(
+ 'gn' => 'givenname',
+ 'rfc822mailbox' => 'email',
+ 'userid' => 'uid',
+ 'emailaddress' => 'email',
+ 'pkcs9email' => 'email',
+ );
+
+ list($name, $limit) = explode(':', $namev, 2);
+ $suffix = $limit ? ':'.$limit : '';
+
+ return (isset($aliases[$name]) ? $aliases[$name] : $name) . $suffix;
+ }
+
+ /**
+ * Quotes attribute value string
+ *
+ * @param string $str Attribute value
+ * @param bool $dn True if the attribute is a DN
+ *
+ * @return string Quoted string
+ */
+ public 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);
+ }
+
+ /**
+ * Prints debug info to the log
+ */
+ private function _debug($str)
+ {
+ if ($this->debug && class_exists('rcube')) {
+ rcube::write_log('ldap', $str);
+ }
+ }
+
+
+ /***************** Virtual List View (VLV) related utility functions **************** */
+
+ /**
+ * Return the search string value to be used in VLV controls
+ */
+ private function _vlv_search($sort, $search)
+ {
+ foreach ($search as $attr => $value) {
+ if (!in_array(strtolower($attr), $sort)) {
+ $this->_debug("d: Cannot use VLV search using attribute not indexed: $attr (not in " . var_export($sort, true) . ")");
+ return null;
+ } else {
+ return $value;
+ }
+ }
+ }
+
+ /**
+ * Find a VLV index matching the given query attributes
+ *
+ * @return string Sort attribute or False if no match
+ */
+ private function _find_vlv($base_dn, $filter, $scope, $sort_attrs = null)
+ {
+ if (!$this->config['vlv'] || $scope == 'base') {
+ return false;
+ }
+
+ // get vlv config
+ $vlv_config = $this->_read_vlv_config();
+
+ if ($vlv = $vlv_config[$base_dn]) {
+ $this->_debug("D: Found a VLV for $base_dn");
+
+ if ($vlv['filter'] == strtolower($filter) || stripos($filter, '(&'.$vlv['filter'].'(') === 0) {
+ $this->_debug("D: Filter matches");
+ if ($vlv['scope'] == $scope) {
+ // Not passing any sort attributes means you don't care
+ if (empty($sort_attrs) || in_array($sort_attrs, $vlv['sort'])) {
+ return $vlv['sort'][0];
+ }
+ }
+ else {
+ $this->_debug("D: Scope does not match");
+ }
+ }
+ else {
+ $this->_debug("D: Filter does not match");
+ }
+ }
+ else {
+ $this->_debug("D: No VLV for $base_dn");
+ }
+
+ return false;
+ }
+
+ /**
+ * Return VLV indexes and searches including necessary configuration
+ * details.
+ */
+ private function _read_vlv_config()
+ {
+ if (empty($this->config['vlv']) || empty($this->config['config_root_dn'])) {
+ return array();
+ }
+ // return hard-coded VLV config
+ else if (is_array($this->config['vlv'])) {
+ return $this->config['vlv'];
+ }
+
+ // return cached result
+ if (is_array($this->vlv_config)) {
+ return $this->vlv_config;
+ }
+
+ if ($this->cache && ($cached_config = $this->cache->get('vlvconfig'))) {
+ $this->vlv_config = $cached_config;
+ return $this->vlv_config;
+ }
+
+ $this->vlv_config = array();
+
+ $ldap_result = ldap_search($this->conn, $this->config['config_root_dn'], '(objectclass=vlvsearch)', array('*'), 0, 0, 0);
+ $vlv_searches = new rcube_ldap_result($this->conn, $ldap_result, $this->config['config_root_dn'], '(objectclass=vlvsearch)');
+
+ if ($vlv_searches->count() < 1) {
+ $this->_debug("D: Empty result from search for '(objectclass=vlvsearch)' on '$config_root_dn'");
+ return array();
+ }
+
+ foreach ($vlv_searches->entries(true) as $vlv_search_dn => $vlv_search_attrs) {
+ // Multiple indexes may exist
+ $ldap_result = ldap_search($this->conn, $vlv_search_dn, '(objectclass=vlvindex)', array('*'), 0, 0, 0);
+ $vlv_indexes = new rcube_ldap_result($this->conn, $ldap_result, $vlv_search_dn, '(objectclass=vlvindex)');
+
+ // Reset this one for each VLV search.
+ $_vlv_sort = array();
+ foreach ($vlv_indexes->entries(true) as $vlv_index_dn => $vlv_index_attrs) {
+ $_vlv_sort[] = explode(' ', $vlv_index_attrs['vlvsort']);
+ }
+
+ $this->vlv_config[$vlv_search_attrs['vlvbase']] = array(
+ 'scope' => self::scopeint2str($vlv_search_attrs['vlvscope']),
+ 'filter' => strtolower($vlv_search_attrs['vlvfilter']),
+ 'sort' => $_vlv_sort,
+ );
+ }
+
+ // cache this
+ if ($this->cache)
+ $this->cache->set('vlvconfig', $this->vlv_config);
+
+ $this->_debug("D: Refreshed VLV config: " . var_export($this->vlv_config, true));
+
+ return $this->vlv_config;
+ }
+
+ /**
+ * 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 static 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
+
+ with 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 static 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;
+ }
+
+}
diff --git a/program/lib/Roundcube/rcube_ldap_result.php b/program/lib/Roundcube/rcube_ldap_result.php
new file mode 100644
index 000000000..efc3331bc
--- /dev/null
+++ b/program/lib/Roundcube/rcube_ldap_result.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | Roundcube/rcube_ldap_result.php |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 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. |
+ | |
+ | PURPOSE: |
+ | Model class that represents an LDAP search result |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+/**
+ * Model class representing an LDAP search result
+ *
+ * @package Framework
+ * @subpackage LDAP
+ */
+class rcube_ldap_result implements Iterator
+{
+ public $conn;
+ public $ldap;
+ public $base_dn;
+ public $filter;
+
+ private $count = null;
+ private $current = null;
+ private $iteratorkey = 0;
+
+ /**
+ * Default constructor
+ *
+ * @param resource $conn LDAP link identifier
+ * @param resource $ldap LDAP result entry identifier
+ * @param string $base_dn Base DN used to get this result
+ * @param string $filter Filter query used to get this result
+ * @param integer $count Record count value (pre-calculated)
+ */
+ function __construct($conn, $ldap, $base_dn, $filter, $count = null)
+ {
+ $this->conn = $conn;
+ $this->ldap = $ldap;
+ $this->base_dn = $base_dn;
+ $this->filter = $filter;
+ $this->count = $count;
+ }
+
+ /**
+ * Wrapper for ldap_sort()
+ */
+ public function sort($attr)
+ {
+ return ldap_sort($this->conn, $this->ldap, $attr);
+ }
+
+ /**
+ * Get entries count
+ */
+ public function count()
+ {
+ if (!isset($this->count))
+ $this->count = ldap_count_entries($this->conn, $this->ldap);
+
+ return $this->count;
+ }
+
+ /**
+ * Wrapper for ldap_get_entries()
+ *
+ * @param boolean $normalize Optionally normalize the entries to a list of hash arrays
+ * @return array List of LDAP entries
+ */
+ public function entries($normalize = false)
+ {
+ $entries = ldap_get_entries($this->conn, $this->ldap);
+ return $normalize ? rcube_ldap_generic::normalize_result($entries) : $entries;
+ }
+
+ /**
+ * Wrapper for ldap_get_dn() using the current entry pointer
+ */
+ public function get_dn()
+ {
+ return $this->current ? ldap_get_dn($this->conn, $this->current) : null;
+ }
+
+
+ /*** Implements the PHP 5 Iterator interface to make foreach work ***/
+
+ function current()
+ {
+ $attrib = ldap_get_attributes($this->conn, $this->current);
+ $attrib['dn'] = ldap_get_dn($this->conn, $this->current);
+ return $attrib;
+ }
+
+ function key()
+ {
+ return $this->iteratorkey;
+ }
+
+ function rewind()
+ {
+ $this->iteratorkey = 0;
+ $this->current = ldap_first_entry($this->conn, $this->ldap);
+ }
+
+ function next()
+ {
+ $this->iteratorkey++;
+ $this->current = ldap_next_entry($this->conn, $this->current);
+ }
+
+ function valid()
+ {
+ return (bool)$this->current;
+ }
+
+}
diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php
index 42d7b9bbe..797ca185e 100644
--- a/program/lib/Roundcube/rcube_message.php
+++ b/program/lib/Roundcube/rcube_message.php
@@ -85,12 +85,13 @@ class rcube_message
$this->headers = $this->storage->get_message($uid);
- if (!$this->headers)
+ if (!$this->headers) {
return;
+ }
$this->mime = new rcube_mime($this->headers->charset);
- $this->subject = $this->mime->decode_mime_string($this->headers->subject);
+ $this->subject = $this->headers->get('subject');
list(, $this->sender) = each($this->mime->decode_address_list($this->headers->from, 1));
$this->set_safe((intval($_GET['_safe']) || $_SESSION['safe_messages'][$this->folder.':'.$uid]));
@@ -125,15 +126,11 @@ class rcube_message
*/
public function get_header($name, $raw = false)
{
- if (empty($this->headers))
+ if (empty($this->headers)) {
return null;
+ }
- if ($this->headers->$name)
- $value = $this->headers->$name;
- else if ($this->headers->others[$name])
- $value = $this->headers->others[$name];
-
- return $raw ? $value : $this->mime->decode_header($value);
+ return $this->headers->get($name, !$raw);
}
@@ -152,12 +149,13 @@ class rcube_message
* Compose a valid URL for getting a message part
*
* @param string $mime_id Part MIME-ID
+ * @param mixed $embed Mimetype class for parts to be embedded
* @return string URL or false if part does not exist
*/
public function get_part_url($mime_id, $embed = false)
{
if ($this->mime_parts[$mime_id])
- return $this->opt['get_url'] . '&_part=' . $mime_id . ($embed ? '&_embed=1' : '');
+ return $this->opt['get_url'] . '&_part=' . $mime_id . ($embed ? '&_embed=1&_mimeclass=' . $embed : '');
else
return false;
}
@@ -364,7 +362,7 @@ class rcube_message
// parse headers from message/rfc822 part
if (!isset($structure->headers['subject']) && !isset($structure->headers['from'])) {
- list($headers, $dump) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 8192));
+ list($headers, ) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 32768));
$structure->headers = rcube_mime::parse_headers($headers);
}
}
@@ -372,7 +370,8 @@ class rcube_message
$mimetype = $structure->mimetype;
// show message headers
- if ($recursive && is_array($structure->headers) && (isset($structure->headers['subject']) || isset($structure->headers['from']))) {
+ if ($recursive && is_array($structure->headers) &&
+ (isset($structure->headers['subject']) || $structure->headers['from'] || $structure->headers['to'])) {
$c = new stdClass;
$c->type = 'headers';
$c->headers = $structure->headers;
@@ -486,14 +485,6 @@ 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];
@@ -578,10 +569,6 @@ 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') {
@@ -657,7 +644,7 @@ class rcube_message
$img_regexp = '/^image\/(gif|jpe?g|png|tiff|bmp|svg)/';
foreach ($this->inline_parts as $inline_object) {
- $part_url = $this->get_part_url($inline_object->mime_id, true);
+ $part_url = $this->get_part_url($inline_object->mime_id, $inline_object->ctype_primary);
if (isset($inline_object->content_id))
$a_replaces['cid:'.$inline_object->content_id] = $part_url;
if ($inline_object->content_location) {
@@ -798,7 +785,7 @@ class rcube_message
$uupart->size = strlen($uupart->body);
$uupart->mime_id = 'uu.' . $part->mime_id . '.' . $pid;
- $ctype = rcube_mime::content_type($uupart->body, $uupart->filename, 'application/octet-stream', true);
+ $ctype = rcube_mime::file_content_type($uupart->body, $uupart->filename, 'application/octet-stream', true);
$uupart->mimetype = $ctype;
list($uupart->ctype_primary, $uupart->ctype_secondary) = explode('/', $ctype);
diff --git a/program/lib/Roundcube/rcube_message_header.php b/program/lib/Roundcube/rcube_message_header.php
index 274ae7f9f..2c5e2b6c8 100644
--- a/program/lib/Roundcube/rcube_message_header.php
+++ b/program/lib/Roundcube/rcube_message_header.php
@@ -215,7 +215,12 @@ class rcube_message_header
$value = $this->others[$name];
}
- return $decode ? rcube_mime::decode_header($value, $this->charset) : $value;
+ if ($decode) {
+ $value = rcube_mime::decode_header($value, $this->charset);
+ $value = rcube_charset::clean($value);
+ }
+
+ return $value;
}
/**
diff --git a/program/lib/Roundcube/rcube_mime.php b/program/lib/Roundcube/rcube_mime.php
index b70d681c9..572540f47 100644
--- a/program/lib/Roundcube/rcube_mime.php
+++ b/program/lib/Roundcube/rcube_mime.php
@@ -127,10 +127,11 @@ class rcube_mime
* @param int $max List only this number of addresses
* @param boolean $decode Decode address strings
* @param string $fallback Fallback charset if none specified
+ * @param boolean $addronly Return flat array with e-mail addresses only
*
- * @return array Indexed list of addresses
+ * @return array Indexed list of addresses
*/
- static function decode_address_list($input, $max = null, $decode = true, $fallback = null)
+ static function decode_address_list($input, $max = null, $decode = true, $fallback = null, $addronly = false)
{
$a = self::parse_address_list($input, $decode, $fallback);
$out = array();
@@ -145,20 +146,21 @@ class rcube_mime
foreach ($a as $val) {
$j++;
$address = trim($val['address']);
- $name = trim($val['name']);
- if ($name && $address && $name != $address)
- $string = sprintf('%s <%s>', preg_match("/$special_chars/", $name) ? '"'.addcslashes($name, '"').'"' : $name, $address);
- else if ($address)
- $string = $address;
- else if ($name)
- $string = $name;
-
- $out[$j] = array(
- 'name' => $name,
- 'mailto' => $address,
- 'string' => $string
- );
+ if ($addronly) {
+ $out[$j] = $address;
+ }
+ else {
+ $name = trim($val['name']);
+ if ($name && $address && $name != $address)
+ $string = sprintf('%s <%s>', preg_match("/$special_chars/", $name) ? '"'.addcslashes($name, '"').'"' : $name, $address);
+ else if ($address)
+ $string = $address;
+ else if ($name)
+ $string = $name;
+
+ $out[$j] = array('name' => $name, 'mailto' => $address, 'string' => $string);
+ }
if ($max && $j==$max)
break;
@@ -359,6 +361,11 @@ class rcube_mime
$address = $m[1];
$name = '';
}
+ // special case (#1489092)
+ else if (preg_match('/(\s*<MAILER-DAEMON>)$/', $val, $m)) {
+ $address = 'MAILER-DAEMON';
+ $name = substr($val, 0, -strlen($m[1]));
+ }
else {
$name = $val;
}
@@ -476,9 +483,10 @@ class rcube_mime
$q_level = 0;
foreach ($text as $idx => $line) {
- if ($line[0] == '>') {
- // remove quote chars, store level in $q
- $line = preg_replace('/^>+/', '', $line, -1, $q);
+ if (preg_match('/^(>+)/', $line, $m)) {
+ // remove quote chars
+ $q = strlen($m[1]);
+ $line = preg_replace('/^>+/', '', $line);
// remove (optional) space-staffing
$line = preg_replace('/^ /', '', $line);
@@ -541,9 +549,10 @@ class rcube_mime
foreach ($text as $idx => $line) {
if ($line != '-- ') {
- if ($line[0] == '>') {
- // remove quote chars, store level in $level
- $line = preg_replace('/^>+/', '', $line, -1, $level);
+ if (preg_match('/^(>+)/', $line, $m)) {
+ // remove quote chars
+ $level = strlen($m[1]);
+ $line = preg_replace('/^>+/', '', $line);
// remove (optional) space-staffing and spaces before the line end
$line = preg_replace('/(^ | +$)/', '', $line);
$prefix = str_repeat('>', $level) . ' ';
@@ -564,82 +573,122 @@ class rcube_mime
/**
- * Improved wordwrap function.
+ * Improved wordwrap function with multibyte support.
+ * The code is based on Zend_Text_MultiByte::wordWrap().
*
- * @param string $string Text to wrap
- * @param int $width Line width
- * @param string $break Line separator
- * @param bool $cut Enable to cut word
- * @param string $charset Charset of $string
+ * @param string $string Text to wrap
+ * @param int $width Line width
+ * @param string $break Line separator
+ * @param bool $cut Enable to cut word
+ * @param string $charset Charset of $string
+ * @param bool $wrap_quoted When enabled quoted lines will not be wrapped
*
* @return string Text
*/
- public static function wordwrap($string, $width=75, $break="\n", $cut=false, $charset=null)
+ public static function wordwrap($string, $width=75, $break="\n", $cut=false, $charset=null, $wrap_quoted=true)
{
- if ($charset && function_exists('mb_internal_encoding')) {
+ // Note: Never try to use iconv instead of mbstring functions here
+ // Iconv's substr/strlen are 100x slower (#1489113)
+
+ if ($charset && $charset != RCUBE_CHARSET && function_exists('mb_internal_encoding')) {
mb_internal_encoding($charset);
}
- $para = preg_split('/\r?\n/', $string);
- $string = '';
+ // Convert \r\n to \n, this is our line-separator
+ $string = str_replace("\r\n", "\n", $string);
+ $separator = "\n"; // must be 1 character length
+ $result = array();
- while (count($para)) {
- $line = array_shift($para);
- if ($line[0] == '>') {
- $string .= $line . (count($para) ? $break : '');
- continue;
- }
+ while (($stringLength = mb_strlen($string)) > 0) {
+ $breakPos = mb_strpos($string, $separator, 0);
- $list = explode(' ', $line);
- $len = 0;
- while (count($list)) {
- $line = array_shift($list);
- $l = mb_strlen($line);
- $space = $len ? 1 : 0;
- $newlen = $len + $l + $space;
+ // quoted line (do not wrap)
+ if ($wrap_quoted && $string[0] == '>') {
+ if ($breakPos === $stringLength - 1 || $breakPos === false) {
+ $subString = $string;
+ $cutLength = null;
+ }
+ else {
+ $subString = mb_substr($string, 0, $breakPos);
+ $cutLength = $breakPos + 1;
+ }
+ }
+ // next line found and current line is shorter than the limit
+ else if ($breakPos !== false && $breakPos < $width) {
+ if ($breakPos === $stringLength - 1) {
+ $subString = $string;
+ $cutLength = null;
+ }
+ else {
+ $subString = mb_substr($string, 0, $breakPos);
+ $cutLength = $breakPos + 1;
+ }
+ }
+ else {
+ $subString = mb_substr($string, 0, $width);
- if ($newlen <= $width) {
- $string .= ($space ? ' ' : '').$line;
- $len += ($space + $l);
+ // last line
+ if ($breakPos === false && $subString === $string) {
+ $cutLength = null;
}
else {
- if ($l > $width) {
- if ($cut) {
- $start = 0;
- while ($l) {
- $str = mb_substr($line, $start, $width);
- $strlen = mb_strlen($str);
- $string .= ($len ? $break : '').$str;
- $start += $strlen;
- $l -= $strlen;
- $len = $strlen;
+ $nextChar = mb_substr($string, $width, 1);
+
+ if ($nextChar === ' ' || $nextChar === $separator) {
+ $afterNextChar = mb_substr($string, $width + 1, 1);
+
+ if ($afterNextChar === false) {
+ $subString .= $nextChar;
+ }
+
+ $cutLength = mb_strlen($subString) + 1;
+ }
+ else {
+ $spacePos = mb_strrpos($subString, ' ', 0);
+
+ if ($spacePos !== false) {
+ $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) {
+ $subString = mb_substr($string, 0, $spacePos);
+ $cutLength = $spacePos + 1;
+ }
+ else {
+ $subString = mb_substr($string, 0, $breakPos);
+ $cutLength = $breakPos + 1;
}
}
else {
- $string .= ($len ? $break : '').$line;
- if (count($list)) {
- $string .= $break;
- }
- $len = 0;
+ $subString = mb_substr($subString, 0, $width);
+ $cutLength = $width;
}
}
- else {
- $string .= $break.$line;
- $len = $l;
- }
}
}
- if (count($para)) {
- $string .= $break;
+ $result[] = $subString;
+
+ if ($cutLength !== null) {
+ $string = mb_substr($string, $cutLength, ($stringLength - $cutLength));
+ }
+ else {
+ break;
}
}
- if ($charset && function_exists('mb_internal_encoding')) {
+ if ($charset && $charset != RCUBE_CHARSET && function_exists('mb_internal_encoding')) {
mb_internal_encoding(RCUBE_CHARSET);
}
- return $string;
+ return implode($break, $result);
}
@@ -746,7 +795,7 @@ class rcube_mime
}
foreach ($file_paths as $fp) {
- if (is_readable($fp)) {
+ if (@is_readable($fp)) {
$lines = file($fp, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
break;
}
@@ -769,11 +818,35 @@ class rcube_mime
// fallback to some well-known types most important for daily emails
if (empty($mime_types)) {
- $mime_extensions = @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
- $mime_extensions += array('gif' => 'image/gif', 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'tif' => 'image/tiff');
+ $mime_extensions = (array) @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
- foreach ($mime_extensions as $ext => $mime)
+ foreach ($mime_extensions as $ext => $mime) {
$mime_types[$mime][] = $ext;
+ }
+ }
+
+ // Add some known aliases that aren't included by some mime.types (#1488891)
+ // the order is important here so standard extensions have higher prio
+ $aliases = array(
+ 'image/gif' => array('gif'),
+ 'image/png' => array('png'),
+ 'image/x-png' => array('png'),
+ 'image/jpeg' => array('jpg', 'jpeg', 'jpe'),
+ 'image/jpg' => array('jpg', 'jpeg', 'jpe'),
+ 'image/pjpeg' => array('jpg', 'jpeg', 'jpe'),
+ 'image/tiff' => array('tif'),
+ 'message/rfc822' => array('eml'),
+ 'text/x-mail' => array('eml'),
+ );
+
+ foreach ($aliases as $mime => $exts) {
+ $mime_types[$mime] = array_unique(array_merge((array) $mime_types[$mime], $exts));
+
+ foreach ($exts as $ext) {
+ if (!isset($mime_extensions[$ext])) {
+ $mime_extensions[$ext] = $mime;
+ }
+ }
}
return $mimetype ? $mime_types[$mimetype] : $mime_extensions;
diff --git a/program/lib/Roundcube/rcube_output.php b/program/lib/Roundcube/rcube_output.php
index b8ae86cf6..7ccf9a02e 100644
--- a/program/lib/Roundcube/rcube_output.php
+++ b/program/lib/Roundcube/rcube_output.php
@@ -162,7 +162,7 @@ abstract class rcube_output
header("Cache-Control: private, must-revalidate");
}
else {
- header("Cache-Control: private, no-cache, must-revalidate, post-check=0, pre-check=0");
+ header("Cache-Control: private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
}
}
diff --git a/program/lib/Roundcube/rcube_plugin.php b/program/lib/Roundcube/rcube_plugin.php
index 9ea0f73d3..3153a8410 100644
--- a/program/lib/Roundcube/rcube_plugin.php
+++ b/program/lib/Roundcube/rcube_plugin.php
@@ -60,6 +60,14 @@ abstract class rcube_plugin
*/
public $noframe = false;
+ /**
+ * A list of config option names that can be modified
+ * by the user via user interface (with save-prefs command)
+ *
+ * @var array
+ */
+ public $allowed_prefs;
+
protected $home;
protected $urlbase;
private $mytask;
@@ -84,6 +92,16 @@ 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
@@ -209,7 +227,7 @@ abstract class rcube_plugin
$rcube->load_language($lang, $add);
// add labels to client
- if ($add2client) {
+ if ($add2client && method_exists($rcube->output, 'add_label')) {
if (is_array($add2client)) {
$js_labels = array_map(array($this, 'label_map_callback'), $add2client);
}
@@ -222,6 +240,24 @@ 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
@@ -372,6 +408,10 @@ 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 111c177d9..33f04eaa5 100644
--- a/program/lib/Roundcube/rcube_plugin_api.php
+++ b/program/lib/Roundcube/rcube_plugin_api.php
@@ -36,6 +36,7 @@ class rcube_plugin_api
public $task = '';
public $output;
public $handlers = array();
+ public $allowed_prefs = array();
protected $plugins = array();
protected $tasks = array();
@@ -202,6 +203,11 @@ class rcube_plugin_api
$plugin->init();
$this->plugins[$plugin_name] = $plugin;
}
+
+ if (!empty($plugin->allowed_prefs)) {
+ $this->allowed_prefs = array_merge($this->allowed_prefs, $plugin->allowed_prefs);
+ }
+
return true;
}
}
@@ -222,6 +228,119 @@ 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
diff --git a/program/lib/Roundcube/rcube_session.php b/program/lib/Roundcube/rcube_session.php
index 82ff8a804..646933b71 100644
--- a/program/lib/Roundcube/rcube_session.php
+++ b/program/lib/Roundcube/rcube_session.php
@@ -32,6 +32,7 @@ class rcube_session
private $ip;
private $start;
private $changed;
+ private $time_diff = 0;
private $reloaded = false;
private $unsets = array();
private $gc_handlers = array();
@@ -42,6 +43,7 @@ class rcube_session
private $secret = '';
private $ip_check = false;
private $logging = false;
+ private $storage;
private $memcache;
@@ -52,18 +54,21 @@ class rcube_session
{
$this->db = $db;
$this->start = microtime(true);
- $this->ip = $_SERVER['REMOTE_ADDR'];
+ $this->ip = rcube_utils::remote_addr();
$this->logging = $config->get('log_session', false);
$lifetime = $config->get('session_lifetime', 1) * 60;
$this->set_lifetime($lifetime);
// use memcache backend
- if ($config->get('session_storage', 'db') == 'memcache') {
+ $this->storage = $config->get('session_storage', 'db');
+ if ($this->storage == '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'),
@@ -79,7 +84,9 @@ class rcube_session
true, true);
}
}
- else {
+ else if ($this->storage != 'php') {
+ ini_set('session.serialize_handler', 'php');
+
// set custom functions for PHP session management
session_set_save_handler(
array($this, 'open'),
@@ -87,7 +94,23 @@ class rcube_session
array($this, 'db_read'),
array($this, 'db_write'),
array($this, 'db_destroy'),
- array($this, 'db_gc'));
+ 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'];
}
}
@@ -116,6 +139,25 @@ 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
@@ -125,14 +167,16 @@ class rcube_session
public function db_read($key)
{
$sql_result = $this->db->query(
- "SELECT vars, ip, changed FROM ".$this->db->table_name('session')
- ." WHERE sess_id = ?", $key);
+ "SELECT vars, ip, changed, " . $this->db->now() . " AS ts"
+ . " FROM " . $this->db->table_name('session')
+ . " WHERE sess_id = ?", $key);
if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
- $this->changed = strtotime($sql_arr['changed']);
- $this->ip = $sql_arr['ip'];
- $this->vars = base64_decode($sql_arr['vars']);
- $this->key = $key;
+ $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;
return !empty($this->vars) ? (string) $this->vars : '';
}
@@ -152,8 +196,9 @@ class rcube_session
*/
public function db_write($key, $vars)
{
- $ts = microtime(true);
- $now = $this->db->fromunixtime((int)$ts);
+ $now = $this->db->now();
+ $table = $this->db->table_name('session');
+ $ts = microtime(true);
// no session row in DB (db_read() returns false)
if (!$this->key) {
@@ -171,22 +216,19 @@ class rcube_session
$newvars = $this->_fixvars($vars, $oldvars);
if ($newvars !== $oldvars) {
- $this->db->query(
- sprintf("UPDATE %s SET vars=?, changed=%s WHERE sess_id=?",
- $this->db->table_name('session'), $now),
- base64_encode($newvars), $key);
+ $this->db->query("UPDATE $table "
+ . "SET changed = $now, vars = ? WHERE sess_id = ?",
+ base64_encode($newvars), $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 if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
+ $this->db->query("UPDATE $table SET changed = $now"
+ . " WHERE sess_id = ?", $key);
}
}
else {
- $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);
+ $this->db->query("INSERT INTO $table (sess_id, vars, ip, created, changed)"
+ . " VALUES (?, ?, ?, $now, $now)",
+ $key, base64_encode($vars), (string)$this->ip);
}
return true;
@@ -203,10 +245,15 @@ class rcube_session
if (is_array($a_oldvars)) {
// remove unset keys on oldvars
foreach ((array)$this->unsets as $var) {
- $path = explode('.', $var);
- $k = array_pop($path);
- $node = &$this->get_node($path, $a_oldvars);
- unset($node[$k]);
+ if (isset($a_oldvars[$var])) {
+ unset($a_oldvars[$var]);
+ }
+ else {
+ $path = explode('.', $var);
+ $k = array_pop($path);
+ $node = &$this->get_node($path, $a_oldvars);
+ unset($node[$k]);
+ }
}
$newvars = $this->serialize(array_merge(
@@ -241,25 +288,6 @@ 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
@@ -335,11 +363,11 @@ class rcube_session
/**
* Execute registered garbage collector routines
*/
- public function gc()
+ public function gc($maxlifetime)
{
- foreach ($this->gc_handlers as $fct) {
- call_user_func($fct);
- }
+ // move gc execution to the script shutdown function
+ // see rcube::shutdown() and rcube_session::write_close()
+ return $this->gc_enabled = $maxlifetime;
}
@@ -361,6 +389,25 @@ 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
@@ -402,7 +449,7 @@ class rcube_session
/**
* Unset a session variable
*
- * @param string Varibale name (can be a path denoting a certain node in the session array, e.g. compose.attachments.5)
+ * @param string Variable name (can be a path denoting a certain node in the session array, e.g. compose.attachments.5)
* @return boolean True on success
*/
public function remove($var=null)
@@ -413,10 +460,15 @@ class rcube_session
$this->unsets[] = $var;
- $path = explode('.', $var);
- $key = array_pop($path);
- $node = &$this->get_node($path, $_SESSION);
- unset($node[$key]);
+ if (isset($_SESSION[$var])) {
+ unset($_SESSION[$var]);
+ }
+ else {
+ $path = explode('.', $var);
+ $key = array_pop($path);
+ $node = &$this->get_node($path, $_SESSION);
+ unset($node[$key]);
+ }
return true;
}
@@ -428,7 +480,7 @@ class rcube_session
public function kill()
{
$this->vars = null;
- $this->ip = $_SERVER['REMOTE_ADDR']; // update IP (might have changed)
+ $this->ip = rcube_utils::remote_addr(); // update IP (might have changed)
$this->destroy(session_id());
rcube_utils::setcookie($this->cookiename, '-del-', time() - 60);
}
@@ -642,10 +694,10 @@ class rcube_session
function check_auth()
{
$this->cookie = $_COOKIE[$this->cookiename];
- $result = $this->ip_check ? $_SERVER['REMOTE_ADDR'] == $this->ip : true;
+ $result = $this->ip_check ? rcube_utils::remote_addr() == $this->ip : true;
if (!$result) {
- $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . $_SERVER['REMOTE_ADDR']);
+ $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . rcube_utils::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 5c7d2203c..60b1389ea 100644
--- a/program/lib/Roundcube/rcube_smtp.php
+++ b/program/lib/Roundcube/rcube_smtp.php
@@ -33,6 +33,8 @@ 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
@@ -119,7 +121,7 @@ class rcube_smtp
}
// try to connect to server and exit on failure
- $result = $this->conn->connect($smtp_timeout);
+ $result = $this->conn->connect($CONFIG['smtp_timeout']);
if (PEAR::isError($result)) {
$this->response[] = "Connection failed: ".$result->getMessage();
@@ -327,6 +329,12 @@ 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));
}
@@ -433,9 +441,9 @@ class rcube_smtp
$recipients = rcube_utils::explode_quoted_string(',', $recipients);
reset($recipients);
- while (list($k, $recipient) = each($recipients)) {
+ foreach ($recipients as $recipient) {
$a = rcube_utils::explode_quoted_string(' ', $recipient);
- while (list($k2, $word) = each($a)) {
+ foreach ($a as $word) {
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_spellchecker.php b/program/lib/Roundcube/rcube_spellchecker.php
index 816bcad2f..df4365223 100644
--- a/program/lib/Roundcube/rcube_spellchecker.php
+++ b/program/lib/Roundcube/rcube_spellchecker.php
@@ -84,6 +84,9 @@ 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);
}
@@ -115,6 +118,9 @@ 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);
}
@@ -133,6 +139,9 @@ 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);
}
@@ -314,11 +323,6 @@ 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;
}
@@ -331,6 +335,141 @@ 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
@@ -372,9 +511,19 @@ 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);
@@ -588,7 +737,7 @@ class rcube_spellchecker
if (empty($plugin['abort'])) {
$dict = array();
- $this->rc->db->query(
+ $sql_result = $this->rc->db->query(
"SELECT data FROM ".$this->rc->db->table_name('dictionary')
." WHERE user_id ". ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
." AND " . $this->rc->db->quoteIdentifier('language') . " = ?",
diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php
index 700d12ffb..4b336f210 100644
--- a/program/lib/Roundcube/rcube_storage.php
+++ b/program/lib/Roundcube/rcube_storage.php
@@ -540,12 +540,13 @@ abstract class rcube_storage
/**
* Append a mail message (source) to a specific folder.
*
- * @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 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
*
* @return int|bool Appended message UID or True on success, False on error
*/
@@ -986,6 +987,6 @@ abstract class rcube_storage
/**
* Delete outdated cache entries
*/
- abstract function expunge_cache();
+ abstract function cache_gc();
} // end class rcube_storage
diff --git a/program/lib/Roundcube/rcube_string_replacer.php b/program/lib/Roundcube/rcube_string_replacer.php
index b8768bc98..0fc90a55a 100644
--- a/program/lib/Roundcube/rcube_string_replacer.php
+++ b/program/lib/Roundcube/rcube_string_replacer.php
@@ -95,12 +95,12 @@ class rcube_string_replacer
$attrib = (array)$this->options['link_attribs'];
$attrib['href'] = $url_prefix . $url;
- $i = $this->add($prefix . html::a($attrib, rcube::Q($url)) . $suffix);
+ $i = $this->add(html::a($attrib, rcube::Q($url)) . $suffix);
}
// Return valid link for recognized schemes, otherwise
// return the unmodified string for unrecognized schemes.
- return $i >= 0 ? $this->get_replacement($i) : $matches[0];
+ return $i >= 0 ? $prefix . $this->get_replacement($i) : $matches[0];
}
/**
diff --git a/program/lib/Roundcube/rcube_user.php b/program/lib/Roundcube/rcube_user.php
index 505b190d1..5e9c9af80 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().", ?, ?, ?)",
- strip_newlines($data['user']),
- strip_newlines($data['host']),
- strip_newlines($data['language']));
+ $data['user'],
+ $data['host'],
+ $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[] = strip_newlines($user_email);
+ $email_list[] = $user_email;
}
// identities_level check
else if (count($email_list) > 1 && $rcube->config->get('identities_level', 0) > 1) {
@@ -547,7 +547,6 @@ 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 1ae782a25..cf87dedb7 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -360,12 +360,8 @@ class rcube_utils
return $value;
}
- // strip single quotes if magic_quotes_sybase is enabled
- if (ini_get('magic_quotes_sybase')) {
- $value = str_replace("''", "'", $value);
- }
// strip slashes if magic_quotes enabled
- else if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
+ if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
$value = stripslashes($value);
}
@@ -404,7 +400,7 @@ class rcube_utils
$out = array();
$src = $mode == self::INPUT_GET ? $_GET : ($mode == self::INPUT_POST ? $_POST : $_REQUEST);
- foreach ($src as $key => $value) {
+ foreach (array_keys($src) as $key) {
$fname = $key[0] == '_' ? substr($key, 1) : $key;
if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname)) {
$out[$fname] = self::get_input_value($key, $mode);
@@ -510,17 +506,24 @@ 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]+)$/i', $filename, $m)) {
- $classes[] = $m[1];
+
+ if (preg_match('/\.([a-z0-9]+)$/', $filename, $m)) {
+ if (!in_array($m[1], $classes)) {
+ $classes[] = $m[1];
+ }
}
- return strtolower(join(" ", $classes));
+ return join(" ", $classes);
}
@@ -663,6 +666,21 @@ 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
@@ -726,11 +744,23 @@ class rcube_utils
return mktime(0,0,0, intval($matches[2]), intval($matches[3]), intval($matches[1]));
}
else if (is_numeric($date)) {
- return $date;
+ return (int) $date;
}
- // support non-standard "GMTXXXX" literal
- $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $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);
// if date parsing fails, we have a date in non-rfc format.
// remove token from the end and try again
@@ -743,7 +773,7 @@ class rcube_utils
$date = implode(' ', $d);
}
- return $ts;
+ return (int) $ts;
}
diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php
index de28767f8..a71305c4b 100644
--- a/program/lib/Roundcube/rcube_vcard.php
+++ b/program/lib/Roundcube/rcube_vcard.php
@@ -90,7 +90,7 @@ class rcube_vcard
*/
public function __construct($vcard = null, $charset = RCUBE_CHARSET, $detect = false, $fieldmap = array())
{
- if (!empty($fielmap)) {
+ if (!empty($fieldmap)) {
$this->extend_fieldmap($fieldmap);
}
@@ -481,7 +481,7 @@ class rcube_vcard
$vcard_block = '';
$in_vcard_block = false;
- foreach (preg_split("/[\r\n]+/", $data) as $i => $line) {
+ foreach (preg_split("/[\r\n]+/", $data) as $line) {
if ($in_vcard_block && !empty($line)) {
$vcard_block .= $line . "\n";
}
@@ -491,7 +491,9 @@ class rcube_vcard
if (preg_match('/^END:VCARD$/i', $line)) {
// parse vcard
$obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true, self::$fieldmap);
- if (!empty($obj->displayname) || !empty($obj->email)) {
+ // FN and N is required by vCard format (RFC 2426)
+ // on import we can be less restrictive, let's addressbook decide
+ if (!empty($obj->displayname) || !empty($obj->surname) || !empty($obj->firstname) || !empty($obj->email)) {
$out[] = $obj;
}
@@ -712,9 +714,15 @@ class rcube_vcard
$value[] = $attrvalues;
}
else if (is_bool($attrvalues)) {
- // true means just tag, not tag=value, as in PHOTO;BASE64:...
+ // true means just a tag, not tag=value, as in PHOTO;BASE64:...
if ($attrvalues) {
- $attr .= strtoupper(";$attrname");
+ // vCard v3 uses ENCODING=B (#1489183)
+ if ($attrname == 'base64') {
+ $attr .= ";ENCODING=B";
+ }
+ else {
+ $attr .= strtoupper(";$attrname");
+ }
}
}
else {
@@ -782,9 +790,30 @@ class rcube_vcard
}
return $result;
}
+
+ $s = strtr($s, $rep2);
+ }
+
+ // some implementations (GMail) use non-standard backslash before colon (#1489085)
+ // we will handle properly any backslashed character - removing dummy backslahes
+ // return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';'));
+
+ $s = str_replace("\r", '', $s);
+ $pos = 0;
+
+ while (($pos = strpos($s, '\\', $pos)) !== false) {
+ $next = substr($s, $pos + 1, 1);
+ if ($next == 'n' || $next == 'N') {
+ $s = substr_replace($s, "\n", $pos, 2);
+ }
+ else {
+ $s = substr_replace($s, '', $pos, 1);
+ }
+
+ $pos += 1;
}
- return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';'));
+ return $s;
}
/**
diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php
index 27dff9f48..6b2efcc78 100644
--- a/program/lib/Roundcube/rcube_washtml.php
+++ b/program/lib/Roundcube/rcube_washtml.php
@@ -113,10 +113,9 @@ class rcube_washtml
'type', 'rows', 'cols', 'disabled', 'readonly', 'checked', 'multiple', 'value'
);
- /* Block elements which could be empty but cannot be returned in short form (<tag />) */
- static $block_elements = array('div', 'p', 'pre', 'blockquote', 'a', 'font', 'center',
- 'table', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'dl', 'strong',
- 'i', 'b', 'u', 'span',
+ /* Elements which could be empty and be returned in short form (<tag />) */
+ static $void_elements = array('area', 'base', 'br', 'col', 'command', 'embed', 'hr',
+ 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'
);
/* State for linked objects in HTML */
@@ -134,12 +133,15 @@ class rcube_washtml
/* Ignore these HTML tags but process their content */
private $_ignore_elements = array();
- /* Block elements which could be empty but cannot be returned in short form (<tag />) */
- private $_block_elements = array();
+ /* Elements which could be empty and be returned in short form (<tag />) */
+ private $_void_elements = array();
/* Allowed HTML attributes */
private $_html_attribs = array();
+ /* Max nesting level */
+ private $max_nesting_level;
+
/**
* Class constructor
@@ -149,9 +151,9 @@ class rcube_washtml
$this->_html_elements = array_flip((array)$p['html_elements']) + array_flip(self::$html_elements) ;
$this->_html_attribs = array_flip((array)$p['html_attribs']) + array_flip(self::$html_attribs);
$this->_ignore_elements = array_flip((array)$p['ignore_elements']) + array_flip(self::$ignore_elements);
- $this->_block_elements = array_flip((array)$p['block_elements']) + array_flip(self::$block_elements);
+ $this->_void_elements = array_flip((array)$p['void_elements']) + array_flip(self::$void_elements);
- unset($p['html_elements'], $p['html_attribs'], $p['ignore_elements'], $p['block_elements']);
+ unset($p['html_elements'], $p['html_attribs'], $p['ignore_elements'], $p['void_elements']);
$this->config = $p + array('show_washed' => true, 'allow_remote' => false, 'cid_map' => array());
}
@@ -284,12 +286,26 @@ class rcube_washtml
* It output only allowed tags with allowed attributes
* and allowed inline styles
*/
- private function dumpHtml($node)
+ private function dumpHtml($node, $level = 0)
{
if (!$node->hasChildNodes()) {
return '';
}
+ $level++;
+
+ if ($this->max_nesting_level > 0 && $level == $this->max_nesting_level - 1) {
+ // log error message once
+ if (!$this->max_nesting_level_error) {
+ $this->max_nesting_level_error = true;
+ rcube::raise_error(array('code' => 500, 'type' => 'php',
+ 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => "Maximum nesting level exceeded (xdebug.max_nesting_level={$this->max_nesting_level})"),
+ true, false);
+ }
+ return '<!-- ignored -->';
+ }
+
$node = $node->firstChild;
$dump = '';
@@ -299,19 +315,19 @@ class rcube_washtml
$tagName = strtolower($node->tagName);
if ($callback = $this->handlers[$tagName]) {
$dump .= call_user_func($callback, $tagName,
- $this->wash_attribs($node), $this->dumpHtml($node), $this);
+ $this->wash_attribs($node), $this->dumpHtml($node, $level), $this);
}
else if (isset($this->_html_elements[$tagName])) {
- $content = $this->dumpHtml($node);
+ $content = $this->dumpHtml($node, $level);
$dump .= '<' . $tagName . $this->wash_attribs($node) .
- ($content != '' || isset($this->_block_elements[$tagName]) ? ">$content</$tagName>" : ' />');
+ ($content === '' && isset($this->_void_elements[$tagName]) ? ' />' : ">$content</$tagName>");
}
else if (isset($this->_ignore_elements[$tagName])) {
$dump .= '<!-- ' . htmlspecialchars($tagName, ENT_QUOTES) . ' not allowed -->';
}
else {
$dump .= '<!-- ' . htmlspecialchars($tagName, ENT_QUOTES) . ' ignored -->';
- $dump .= $this->dumpHtml($node); // ignore tags not its content
+ $dump .= $this->dumpHtml($node, $level); // ignore tags not its content
}
break;
@@ -324,14 +340,14 @@ class rcube_washtml
break;
case XML_HTML_DOCUMENT_NODE:
- $dump .= $this->dumpHtml($node);
+ $dump .= $this->dumpHtml($node, $level);
break;
case XML_DOCUMENT_TYPE_NODE:
break;
default:
- $dump . '<!-- node type ' . $node->nodeType . ' -->';
+ $dump .= '<!-- node type ' . $node->nodeType . ' -->';
}
} while($node = $node->nextSibling);
@@ -358,6 +374,9 @@ class rcube_washtml
$this->config['base_url'] = '';
}
+ // Detect max nesting level (for dumpHTML) (#1489110)
+ $this->max_nesting_level = (int) @ini_get('xdebug.max_nesting_level');
+
@$node->loadHTML($html);
return $this->dumpHtml($node);
}
@@ -405,6 +424,7 @@ class rcube_washtml
rcube::raise_error(array('code' => 620, 'type' => 'php',
'line' => __LINE__, 'file' => __FILE__,
'message' => $errstr), true, false);
+
return '';
}
diff --git a/program/lib/utf8.class.php b/program/lib/utf8.class.php
index e0dc9e2bd..0446159c7 100644
--- a/program/lib/utf8.class.php
+++ b/program/lib/utf8.class.php
@@ -60,8 +60,8 @@ Class utf8 {
function loadCharset($charset) {
$charset = preg_replace(array('/^WINDOWS-*125([0-8])$/', '/^CP-/'), array('CP125\\1', 'CP'), $charset);
- if (isset($aliases[$charset]))
- $charset = $aliases[$charset];
+ if (isset($this->aliases[$charset]))
+ $charset = $this->aliases[$charset];
$this->charset = $charset;
diff --git a/program/localization/ar_SA/labels.inc b/program/localization/ar_SA/labels.inc
index 7dc8c15ad..bc1764b0f 100644
--- a/program/localization/ar_SA/labels.inc
+++ b/program/localization/ar_SA/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'المسودات';
$labels['sent'] = 'المرسل';
$labels['trash'] = 'المهملات';
$labels['junk'] = 'غير المرغوب';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'الموضوع';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'الصÙحة الحالية';
$labels['unread'] = 'غير المقروءة';
$labels['flagged'] = 'موسوم';
$labels['unanswered'] = 'بلا رد';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'محذوÙ';
$labels['undeleted'] = 'غير محذوÙØ©';
$labels['invert'] = 'عكس';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'وضع طريقة السرد';
$labels['folderactions'] = 'إجراءات المجلد...';
$labels['compact'] = 'ضغط';
$labels['empty'] = 'تÙريغ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'المساحة المستخدمة';
$labels['unknown'] = 'مجهول';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'استعادة البحث للاÙتراضي';
$labels['searchmod'] = 'أماكن البحث';
$labels['msgtext'] = 'كامل الرسالة';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'اÙتح ÙÙŠ ناÙذة جديدة';
$labels['emlsave'] = 'تنزيل (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'عرض المجموعة الأخيرة';
$labels['group'] = 'مجموعة';
$labels['groups'] = 'المجموعات';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'العناوين الشخصية';
$labels['searchsave'] = 'Ø­Ùظ البحث';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'إنشاء رسائل بنسق HTML';
$labels['htmlonreply'] = 'حال الرد على الرسائل بصيغة HTML Ùقط';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'توقيع HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'إظهار قسم المعاينة';
$labels['skin'] = 'شكل الواجهة';
$labels['logoutclear'] = 'Ø¥Ùراغ سلة المحذوÙات عند الخروج';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'إزالة التوقيع من الرسالة
$labels['autoaddsignature'] = 'إضاÙØ© التوقيع آلياً';
$labels['newmessageonly'] = 'الرسالة الجديدة Ùقط';
$labels['replyandforwardonly'] = 'الردود والتمريرات Ùقط';
-$labels['replysignaturepos'] = 'إضاÙØ© التوقيع عند الرد أو التمرير';
-$labels['belowquote'] = 'بعد الاقتباس';
-$labels['abovequote'] = 'قبل الاقتباس';
$labels['insertsignature'] = 'إضاÙØ© التوقيع';
$labels['previewpanemarkread'] = 'تحديد الرسائل المÙعاينة كمقروءة';
$labels['afternseconds'] = 'بعد $n ثواني';
@@ -473,6 +476,7 @@ $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 e10c83228..9429a3910 100644
--- a/program/localization/ar_SA/messages.inc
+++ b/program/localization/ar_SA/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'خطأ ÙÙŠ قاعدة البيانات!';
$messages['requesttimedout'] = 'Request timed out';
$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['invalidrequest'] = 'طلب غير صالح! لم تحÙظ أية بيانات.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'لم يعثر على أية رسائل ÙÙŠ صندوق البريد هذا';
diff --git a/program/localization/ast/labels.inc b/program/localization/ast/labels.inc
index 996c6043f..8c1985eef 100644
--- a/program/localization/ast/labels.inc
+++ b/program/localization/ast/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Ensin lleer';
$labels['flagged'] = 'Marcáu';
$labels['unanswered'] = 'Ensin contestar';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Desaniciáu';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invertir';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Facer el mensaxe n\'HTML';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Firma HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Entever';
$labels['skin'] = 'Estilu';
$labels['logoutclear'] = 'Vaciar la papelera al zarrar la sesión';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 135f70b73..9e415b8ec 100644
--- a/program/localization/ast/messages.inc
+++ b/program/localization/ast/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Fallu de la solicitú. Nun se guardaron datos.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'Nun doi con mensaxes';
diff --git a/program/localization/az_AZ/labels.inc b/program/localization/az_AZ/labels.inc
index 60e861177..129315ec0 100644
--- a/program/localization/az_AZ/labels.inc
+++ b/program/localization/az_AZ/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Kopyala';
$labels['move'] = 'Köçür';
$labels['moveto'] = 'Burada köçür...';
$labels['download'] = 'Endir';
-$labels['open'] = 'Open';
+$labels['open'] = 'Aç';
$labels['showattachment'] = 'Göstər';
$labels['showanyway'] = 'İstənilən halda göstər';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Hazırki səhifəni';
$labels['unread'] = 'Oxunmamışları';
$labels['flagged'] = 'İşarəliləri';
$labels['unanswered'] = 'Cavabsızları';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Silinmişləri';
$labels['undeleted'] = 'Silinməyib';
$labels['invert'] = 'İnvertliləri';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Sadə mətn formatında göstər';
+$labels['changeformathtml'] = 'HTML formatında göstər';
// message compose
$labels['editasnew'] = 'Yeni kimi redaktÉ™ et';
@@ -338,8 +342,8 @@ $labels['composeto'] = 'Seçilmiş ünvanlara məktub yaz';
$labels['contactsfromto'] = '$count ünvanının $from - $to arası';
$labels['print'] = 'Çap et';
$labels['export'] = 'Ä°xrac et';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Hamısını İxrac et';
+$labels['exportsel'] = 'Seçilmişləri İxrac et';
$labels['exportvcards'] = 'Ünvanları vCards formatında ixrac et';
$labels['newcontactgroup'] = 'Ãœnvanlar qrupunu yarat';
$labels['grouprename'] = 'Qruğun adını dəyişdir';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML-dÉ™ mesaj yaz';
$labels['htmlonreply'] = 'yalnız HTML mesajlar ilə cavab';
$labels['htmlonreplyandforward'] = 'HTML məktuba cavab və yönəltmə zamanı';
$labels['htmlsignature'] = 'HTML imza';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Prevyu paneli göstər';
$labels['skin'] = 'Ä°nterfeys stili';
$labels['logoutclear'] = 'Poçtdan çıxan zaman səbəti təmizlə';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Cavab zamanı imzanı sil';
$labels['autoaddsignature'] = 'İmzanı avtomatik əlavə et';
$labels['newmessageonly'] = 'yalnız yeni məktublarda';
$labels['replyandforwardonly'] = 'Yalnız cavab və yönəldilənlərdə';
-$labels['replysignaturepos'] = 'Cavab və yönəltmə zamanı imzanı bərkid';
-$labels['belowquote'] = 'sitatdan sonra';
-$labels['abovequote'] = 'sitatdan əvvəl';
$labels['insertsignature'] = 'İmza əlavə et';
$labels['previewpanemarkread'] = 'Baxılmış şəkilləri oxunmuş kimi qeyd et';
$labels['afternseconds'] = '$n saniyədən sonra';
@@ -473,6 +476,7 @@ $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 939827247..418f270be 100644
--- a/program/localization/az_AZ/messages.inc
+++ b/program/localization/az_AZ/messages.inc
@@ -17,20 +17,22 @@
*/
$messages = array();
-$messages['errortitle'] = 'Xəta baş verib!';
-$messages['loginfailed'] = 'GiriÅŸ uÄŸursuz oldu';
-$messages['cookiesdisabled'] = 'Sizin brauzer kukiləri qəbul etmir';
-$messages['sessionerror'] = 'Sizin sessiya köhnəlib';
-$messages['storageerror'] = 'IMAP serverlə bağlantı alınmadı';
-$messages['servererror'] = 'Server xətası!';
-$messages['servererrormsg'] = 'Server xətası: $msg';
-$messages['dberror'] = 'Məlumatlar bazasında xəta!';
+$messages['errortitle'] = 'Xəta baş verdi!';
+$messages['loginfailed'] = 'GiriÅŸ uÄŸursuz oldu.';
+$messages['cookiesdisabled'] = 'Sizin brauzer kukiləri qəbul etmir.';
+$messages['sessionerror'] = 'Sizin sessiya köhnəlib.';
+$messages['storageerror'] = 'IMAP serverlə bağlantı alınmadı.';
+$messages['servererror'] = 'Server Xətası!';
+$messages['servererrormsg'] = 'Server Xətası: $msg';
+$messages['dberror'] = 'Məlumatlar Bazasında Xəta!';
$messages['requesttimedout'] = 'Sorğunun gözləmə müddəti bitdi';
-$messages['errorreadonly'] = 'ÆmÉ™liyyatı etmÉ™k mümkün deyil. Qovluq yalnız oxunuÅŸ üçündür.';
+$messages['errorreadonly'] = 'ÆmÉ™liyyatı icra etmÉ™k mümkün deyil. Qovluq yalnız oxunuÅŸ üçündür.';
$messages['errornoperm'] = 'ÆmÉ™liyyatı etmÉ™k mümkün deyil. GiriÅŸ qadaÄŸandır.';
+$messages['erroroverquota'] = 'ÆmÉ™liyyat icra edilÉ™ bilinmir. BoÅŸ disk hÉ™cmi yoxdur.';
+$messages['erroroverquotadelete'] = 'Boş disk həcmi yoxdur. Məktubu silmək üçün SHIFT+DEL düyməsini istifadə edin.';
$messages['invalidrequest'] = 'Səhv sorğu! Məlumat yaddaşda qalmadı.';
-$messages['invalidhost'] = 'Səhv server adı';
-$messages['nomessagesfound'] = 'Poçt qutusunda məktub tapılmadı';
+$messages['invalidhost'] = 'Səhv server adı.';
+$messages['nomessagesfound'] = 'Poçt qutusunda məktub tapılmadı.';
$messages['loggedout'] = 'Çıxış uğurlu oldu. Sağ olun!';
$messages['mailboxempty'] = 'Poçt qutusu boşdur';
$messages['refreshing'] = 'Yenilənmə...';
diff --git a/program/localization/be_BE/labels.inc b/program/localization/be_BE/labels.inc
index db3893ced..56339a926 100644
--- a/program/localization/be_BE/labels.inc
+++ b/program/localization/be_BE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Чарнавікі';
$labels['sent'] = 'ДаÑланыÑ';
$labels['trash'] = 'Сметніца';
$labels['junk'] = 'Спам';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ТÑма';
@@ -162,6 +163,7 @@ $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';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $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';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 0aaa4d4d7..73cdb3ed8 100644
--- a/program/localization/be_BE/messages.inc
+++ b/program/localization/be_BE/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Памылка базы даных!';
$messages['requesttimedout'] = 'Request timed out';
$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['invalidrequest'] = 'Ðе дзейÑны запыт! Ð”Ð°Ð½Ñ‹Ñ Ð½Ðµ захаваныÑ.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'No messages found in this mailbox.';
diff --git a/program/localization/bg_BG/labels.inc b/program/localization/bg_BG/labels.inc
index fa92ec042..dd5be6e64 100644
--- a/program/localization/bg_BG/labels.inc
+++ b/program/localization/bg_BG/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Чернови';
$labels['sent'] = 'Изпратени';
$labels['trash'] = 'Кошче';
$labels['junk'] = 'Спам';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Заглавие';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Копиране';
$labels['move'] = 'ПремеÑтване';
$labels['moveto'] = 'ПремеÑти в...';
$labels['download'] = 'Изтегли';
-$labels['open'] = 'Open';
+$labels['open'] = 'Отвори';
$labels['showattachment'] = 'Показване';
$labels['showanyway'] = 'Показване въпреки това';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Страница';
$labels['unread'] = 'Ðови';
$labels['flagged'] = 'ОтбелÑзано';
$labels['unanswered'] = 'Без отговор';
+$labels['withattachment'] = 'С прикачен файл';
$labels['deleted'] = 'Изтрито';
$labels['undeleted'] = 'Ðе е изтрит';
$labels['invert'] = 'Инвертирай';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Кратък ÑпиÑък';
$labels['folderactions'] = 'ДейÑÑ‚Ð²Ð¸Ñ Ð·Ð° папки...';
$labels['compact'] = 'Свиване';
$labels['empty'] = 'Изпразни';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Използвано мÑÑто';
$labels['unknown'] = 'нÑма информациÑ';
@@ -202,11 +205,12 @@ $labels['resetsearch'] = 'ИзчиÑти Ñ‚ÑŠÑ€Ñенето и покажи вÑ
$labels['searchmod'] = 'ТърÑене във';
$labels['msgtext'] = 'ЦÑлото Ñъобщение';
$labels['body'] = 'ОÑновен текÑÑ‚';
+$labels['type'] = 'Type';
$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'] = 'Промени като ново';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'ПоÑледна Ñтраница';
$labels['group'] = 'Група';
$labels['groups'] = 'Групи';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Лични адреÑи';
$labels['searchsave'] = 'Запази Ñ‚ÑŠÑ€Ñенето';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'ПиÑане на Ñъобщениe като HTML';
$labels['htmlonreply'] = 'Ñамо при отговор на HTML ÑъбощениÑ';
$labels['htmlonreplyandforward'] = 'Ñамо при препращане или отговор на HTML Ñъобщение';
$labels['htmlsignature'] = 'HTML подпиÑ';
+$labels['showemail'] = 'Показва email Ð°Ð´Ñ€ÐµÑ Ñ ÐµÐºÑ€Ð°Ð½Ð½Ð¾Ñ‚Ð¾ име';
$labels['previewpane'] = 'Панел за преглед';
$labels['skin'] = 'СмÑна изгледа на интерфейÑа';
$labels['logoutclear'] = 'ИзчиÑти кошчето при изход';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Премахване на предишниÑ
$labels['autoaddsignature'] = 'Ðвтоматично добавÑне на подпиÑ';
$labels['newmessageonly'] = 'Ñамо на нови ÑъобщениÑ';
$labels['replyandforwardonly'] = 'Ñамо на отговори и препратени';
-$labels['replysignaturepos'] = 'ПоÑтавÑне на Ð¿Ð¾Ð´Ð¿Ð¸Ñ Ð¿Ñ€Ð¸ отговор или препращане';
-$labels['belowquote'] = 'над цитатът';
-$labels['abovequote'] = 'под цитатът';
$labels['insertsignature'] = 'Вмъкване на подпиÑ';
$labels['previewpanemarkread'] = 'Маркиране на прегледаните ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ°Ñ‚Ð¾ прочетени';
$labels['afternseconds'] = 'Ñлед $n Ñекунди';
@@ -473,6 +476,7 @@ $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 ead68921c..219772e74 100644
--- a/program/localization/bg_BG/messages.inc
+++ b/program/localization/bg_BG/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Грешка Ñ Ð±Ð°Ð·Ð°Ñ‚Ð° данни!';
$messages['requesttimedout'] = 'ЗаÑвката е Ñ Ð¸Ð·Ñ‚ÐµÐºÐ»Ð¾ време';
$messages['errorreadonly'] = 'ОперациÑта не може да бъде изпълнена. Папката е Ñ Ð¿Ñ€Ð°Ð²Ð° Ñамо за четене';
$messages['errornoperm'] = 'ОперациÑта не може да бъде изпълнена. Отказани права за доÑтъп';
+$messages['erroroverquota'] = 'Ðевъзможно извършване на дейÑтвието, нÑма доÑтатъчно Ñвободно диÑково проÑтранÑтво.';
+$messages['erroroverquotadelete'] = 'ÐÑма доÑтатъчно Ñвободно диÑково проÑтранÑтво. Ползвайте SHIFT+DEL за да изтриете Ñъобщение.';
$messages['invalidrequest'] = 'Ðевалидна заÑвка! Данните не Ñа Ñъхранени.';
$messages['invalidhost'] = 'Ðевалидно име на Ñървър';
$messages['nomessagesfound'] = 'ÐÑма ÑъобщениÑ';
diff --git a/program/localization/bn_BD/labels.inc b/program/localization/bn_BD/labels.inc
index 0f20bba37..1273ef192 100644
--- a/program/localization/bn_BD/labels.inc
+++ b/program/localization/bn_BD/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'খসড়া';
$labels['sent'] = 'পà§à¦°à§‡à¦°à¦¿à¦¤(পাঠানো মেইল)';
$labels['trash'] = 'ডাসà§à¦Ÿà¦¬à¦¿à¦¨';
$labels['junk'] = 'আজেবাজে মেইল';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'বিষয়';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'নাদেখা (unread)';
$labels['flagged'] = 'দাগানো (flagged)';
$labels['unanswered'] = 'উতà§à¦¤à¦° না দেওয়া গà§à¦²à§‹';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'টাইটকরà§à¦¨';
$labels['empty'] = 'খালিকরà§à¦¨';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ডিসà§à¦• ঠখালি যায়গা';
$labels['unknown'] = 'অজানা';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'নতà§à¦¨à¦•à¦°à§‡ খà§à¦œà§à¦¨';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'নতà§à¦¨ উইনà§à¦¡à§‹ তে দেখà§à¦¨';
$labels['emlsave'] = 'Download (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'শেষের গà§à¦²à§‹ দেখান';
$labels['group'] = 'Group';
$labels['groups'] = 'গà§à¦°à§à¦ª';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'নিজের ঠিকানা';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML ঠমেইল/চিঠি লিখà§à¦¨';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML ঠসà§à¦¬à¦¾à¦•à§à¦·à¦°';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'ছোটোকরে দেখার জায়গা';
$labels['skin'] = 'মেইলবকà§à¦¸ à¦à¦° পà§à¦°à§‹à¦Ÿà¦¾à¦° চেহারা';
$labels['logoutclear'] = 'বেরহবার সময় ডাসà§à¦Ÿà¦¬à¦¿à¦¨ অটোমেটিক খালি হবে';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 eaa4024b1..44d5fcc60 100644
--- a/program/localization/bn_BD/messages.inc
+++ b/program/localization/bn_BD/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'à¦à¦‡ মেইলবকà§à¦¸à§‡ কোনো চিঠি নাই';
diff --git a/program/localization/br/labels.inc b/program/localization/br/labels.inc
index 95756e393..c88fd92a6 100644
--- a/program/localization/br/labels.inc
+++ b/program/localization/br/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Na lennet';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Sevel ur c\'hemennad er furmad HTML';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Sinadur HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Diskouez panel alberz';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 425dad996..c1988577d 100644
--- a/program/localization/br/messages.inc
+++ b/program/localization/br/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Fazi stlennvon !';
$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'] = 'Kemennadoù ebet er voest lizhiri';
diff --git a/program/localization/bs_BA/labels.inc b/program/localization/bs_BA/labels.inc
index f2a871cdd..61989e6b3 100644
--- a/program/localization/bs_BA/labels.inc
+++ b/program/localization/bs_BA/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Trenutna stranica';
$labels['unread'] = 'NeproÄitano';
$labels['flagged'] = 'Važno';
$labels['unanswered'] = 'Neodgovoreno';
+$labels['withattachment'] = 'Sa prilogom';
$labels['deleted'] = 'Obrisano';
$labels['undeleted'] = 'Nije obrisano';
$labels['invert'] = 'Izokreni';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -222,7 +226,7 @@ $labels['mailreplyintro'] = '$date, $sender je napisao/la:';
$labels['originalmessage'] = 'Originalna poruka';
$labels['editidents'] = 'Uredi identitete';
-$labels['spellcheck'] = 'Spelovanje';
+$labels['spellcheck'] = 'Pravopis';
$labels['checkspelling'] = 'Provjera pravopisa';
$labels['resumeediting'] = 'Nastavi uređivanje';
$labels['revertto'] = 'Vrati na';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Piši HTML poruke';
$labels['htmlonreply'] = 'samo kao odgovor na HTML poruke';
$labels['htmlonreplyandforward'] = 'prilikom prosljeđivanja ili odgovaranja na HTML poruku';
$labels['htmlsignature'] = 'HTML potpis';
+$labels['showemail'] = 'Prikaži email adresu sa imenom';
$labels['previewpane'] = 'Prikaži pregled poruke';
$labels['skin'] = 'Skin interfejsa';
$labels['logoutclear'] = 'OÄisti smeće prilikom odjavljivanja';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Prilikom odgovaranja na poruku, ukloni origin
$labels['autoaddsignature'] = 'Automatski dodaj potpis';
$labels['newmessageonly'] = 'samo za nove poruke';
$labels['replyandforwardonly'] = 'samo za odgovore i prosljeđivanja';
-$labels['replysignaturepos'] = 'Prilikom odgovaranja ili prosljeđivanja potpis ubaci';
-$labels['belowquote'] = 'ispod citata';
-$labels['abovequote'] = 'iznad citata';
$labels['insertsignature'] = 'Umetni potpis';
$labels['previewpanemarkread'] = 'Obilježi prikazane poruke kao proÄitane';
$labels['afternseconds'] = 'nakon $n sekundi';
@@ -473,6 +476,7 @@ $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/ca_ES/labels.inc b/program/localization/ca_ES/labels.inc
index 1bcb526ea..ca0129de4 100644
--- a/program/localization/ca_ES/labels.inc
+++ b/program/localization/ca_ES/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Pàgina actual';
$labels['unread'] = 'No llegits';
$labels['flagged'] = 'Marcat';
$labels['unanswered'] = 'No respost';
+$labels['withattachment'] = 'Amb fitxer adjunt';
$labels['deleted'] = 'Suprimit';
$labels['undeleted'] = 'No s\'ha suprimit';
$labels['invert'] = 'Inverteix';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Mostra en format de text net';
+$labels['changeformathtml'] = 'Mostra en format HTML';
// message compose
$labels['editasnew'] = 'Edita com a nou';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Escriu missatges en HTML';
$labels['htmlonreply'] = 'només en resposta a missatges en HTML';
$labels['htmlonreplyandforward'] = 'en reenviament o resposta a missatge HTML';
$labels['htmlsignature'] = 'Signatura en HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Mostra el panell de previsualització';
$labels['skin'] = 'Aparença d\'interfície';
$labels['logoutclear'] = 'Buida la paperera al tancar la sessió';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Quan es contesti, suprimeix la signatura orig
$labels['autoaddsignature'] = 'Afegeix la signatura automàticament';
$labels['newmessageonly'] = 'només si és un missatge nou';
$labels['replyandforwardonly'] = 'només a respostes i reenviaments';
-$labels['replysignaturepos'] = 'Quan es contesti o reenviï, posa-hi la signatura';
-$labels['belowquote'] = 'sota les cometes';
-$labels['abovequote'] = 'sobre les cometes';
$labels['insertsignature'] = 'Inserta la signatura';
$labels['previewpanemarkread'] = 'Marca els missatges previsualitzats com a llegits';
$labels['afternseconds'] = 'després de $n segons';
@@ -473,6 +476,7 @@ $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 5f0e1d609..70c3fbd0c 100644
--- a/program/localization/ca_ES/messages.inc
+++ b/program/localization/ca_ES/messages.inc
@@ -19,24 +19,26 @@
$messages = array();
$messages['errortitle'] = 'Hi ha hagut un error!';
$messages['loginfailed'] = 'L\'accés ha fallat.';
-$messages['cookiesdisabled'] = 'El vostre navegador no accepta cookies';
-$messages['sessionerror'] = 'La vostra sessió no existeix o ha expirat';
-$messages['storageerror'] = 'Error de conexió amb el servidor IMAP';
+$messages['cookiesdisabled'] = 'El vostre navegador no accepta cookies.';
+$messages['sessionerror'] = 'La vostra sessió no existeix o ha expirat.';
+$messages['storageerror'] = 'Error de connexió amb el servidor IMAP.';
$messages['servererror'] = 'Error del Servidor!';
$messages['servererrormsg'] = 'Error del Servidor: $msg';
$messages['dberror'] = 'Error a la Base de Dades!';
$messages['requesttimedout'] = 'S\'ha esgotat el temps de la sol·licitud';
$messages['errorreadonly'] = 'Impossible de realitzar l\'operació. La carpeta és de només lectura.';
$messages['errornoperm'] = 'Impossible de realitzar l\'operació. Permís denegat.';
-$messages['invalidrequest'] = 'Petició no vàlida! No s\'ha desat les dades.';
+$messages['erroroverquota'] = 'No s\'ha pogut completar l\'operació. No hi ha prou espai lliure al disc dur.';
+$messages['erroroverquotadelete'] = 'No hi ha prou espai lliure. Feu servir MAJÚS+SUPR per suprimir el missatge.';
+$messages['invalidrequest'] = 'Petició no vàlida! No s\'han desat les dades.';
$messages['invalidhost'] = 'Nom de servidor no vàlid.';
$messages['nomessagesfound'] = 'No s\'han trobat missatges en aquesta bústia.';
-$messages['loggedout'] = 'Heu tancat la sessió. A reveure!';
+$messages['loggedout'] = 'Heu tancat la sessió correctament. A reveure!';
$messages['mailboxempty'] = 'La bústia és buida.';
-$messages['refreshing'] = 'Refrescant...';
+$messages['refreshing'] = 'S\'està refrescant...';
$messages['loading'] = 'S\'està carregant…';
$messages['uploading'] = 'S\'està pujant el fitxer...';
-$messages['uploadingmany'] = 'S\'està pujant els fitxers...';
+$messages['uploadingmany'] = 'S\'estan pujant els fitxers...';
$messages['loadingdata'] = 'S\'estan carregant les dades...';
$messages['checkingmail'] = 'S’està comprovant si hi ha missatges nous…';
$messages['sendingmessage'] = 'S’està enviant el missatge…';
@@ -52,26 +54,26 @@ $messages['encryptedmessage'] = 'Aquest és un missatge xifrat i no pot ser most
$messages['nocontactsfound'] = 'No s\'ha trobat cap contacte.';
$messages['contactnotfound'] = 'No s\'ha trobat el contacte sol·licitat.';
$messages['contactsearchonly'] = 'Introduïu termes de cerca per trobar contactes';
-$messages['sendingfailed'] = 'Error enviant missatge.';
+$messages['sendingfailed'] = 'Error enviant el missatge.';
$messages['senttooquickly'] = 'Si us plau, espereu $sec segon(s) abans d\'enviar aquest missatge.';
$messages['errorsavingsent'] = 'Hi ha hagut un error mentre es desava el missatge enviat.';
-$messages['errorsaving'] = 'Hi ha hagut un error mentre es desava.';
+$messages['errorsaving'] = 'Hi ha hagut un error mentre s\'estava desant.';
$messages['errormoving'] = 'No s\'ha pogut moure el(s) missatge(s).';
$messages['errorcopying'] = 'No s\'ha pogut copiar el(s) missatge(s).';
-$messages['errordeleting'] = 'No s\'ha pogut suprimir el missatge.';
+$messages['errordeleting'] = 'No s\'ha pogut suprimir el(s) missatge(s).';
$messages['errormarking'] = 'No s\'ha pogut marcar el(s) missatge(s).';
-$messages['deletecontactconfirm'] = 'Esteu segurs de voler suprimir el(s) contacte(s) selecionat(s)?';
-$messages['deletegroupconfirm'] = 'Esteu segurs de voler suprimirr el grup seleccionat?';
-$messages['deletemessagesconfirm'] = 'Esteu segurs de voler suprimir el(s) missatge(s) selecionat(s)?';
+$messages['deletecontactconfirm'] = 'Esteu segurs de voler suprimir el(s) contacte(s) seleccionat(s)?';
+$messages['deletegroupconfirm'] = 'Esteu segurs de voler suprimir el grup seleccionat?';
+$messages['deletemessagesconfirm'] = 'Esteu segurs de voler suprimir el(s) missatge(s) seleccionat(s)?';
$messages['deletefolderconfirm'] = 'Esteu segurs de voler suprimir aquesta carpeta?';
$messages['purgefolderconfirm'] = 'Esteu segurs de voler suprimir tots els missatges d\'aquesta carpeta?';
$messages['contactdeleting'] = 'S\'està suprimint els contacte(s)...';
$messages['groupdeleting'] = 'S\'està suprimint el grup...';
$messages['folderdeleting'] = 'S\'està suprimint la carpeta...';
$messages['foldermoving'] = 'S\'està movent la carpeta...';
-$messages['foldersubscribing'] = 'S\'està subscribint la carpeta...';
-$messages['folderunsubscribing'] = 'S\'està cancelant la subscripció de la carpeta...';
-$messages['formincomplete'] = 'El formulari no ha estat emplenat totalment.';
+$messages['foldersubscribing'] = 'S\'està subscrivint la carpeta...';
+$messages['folderunsubscribing'] = 'S\'està cancel·lant la subscripció de la carpeta...';
+$messages['formincomplete'] = 'El formulari no ha estat emplenat completament.';
$messages['noemailwarning'] = 'Si us plau, introduïu una adreça de correu electrònic vàlida.';
$messages['nonamewarning'] = 'Si us plau, introduïu un nom.';
$messages['nopagesizewarning'] = 'Si us plau, introduïu una mida de pàgina.';
@@ -91,11 +93,11 @@ $messages['checking'] = 'S\'està comprovant...';
$messages['nospellerrors'] = 'No s\'han trobat errors d\'ortografia.';
$messages['folderdeleted'] = 'Carpeta suprimida correctament.';
$messages['foldersubscribed'] = 'Carpeta subscrita correctament.';
-$messages['folderunsubscribed'] = 'Carpeta desubscrita correctament.';
+$messages['folderunsubscribed'] = 'Carpeta de-subscrita correctament.';
$messages['folderpurged'] = 'La carpeta ha estat buidada correctament.';
$messages['folderexpunged'] = 'La carpeta ha estat compactada correctament.';
$messages['deletedsuccessfully'] = 'Suprimit correctament.';
-$messages['converting'] = 'S\'està traient format del missatge...';
+$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.';
@@ -103,13 +105,13 @@ $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 el missatge...';
-$messages['copyingmessage'] = 'S\'està copiant missatge...';
-$messages['copyingcontact'] = 'S\'està copiant els contacte(s)...';
-$messages['deletingmessage'] = 'S\'està suprimint els missatge(s)...';
-$messages['markingmessage'] = 'S\'està marcant els missatge(s)...';
-$messages['addingmember'] = 'S\'està afegint els contacte(s) al grup...';
-$messages['removingmember'] = 'S\'està suprimint els contacte(s) del grup...';
+$messages['movingmessage'] = 'S\'està movent missatge(s)...';
+$messages['copyingmessage'] = 'S\'està copiant missatge(s)...';
+$messages['copyingcontact'] = 'S\'està copiant 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...';
+$messages['removingmember'] = 'S\'està suprimint contacte(s) del grup...';
$messages['receiptsent'] = 'Confirmació de lectura enviada correctament.';
$messages['errorsendingreceipt'] = 'No es pot enviar la confirmació.';
$messages['deleteidentityconfirm'] = 'Esteu segurs de voler suprimir aquesta identitat?';
@@ -132,16 +134,16 @@ $messages['smtpconnerror'] = 'Error SMTP ($code): La connexió al servidor ha fa
$messages['smtpautherror'] = 'Error SMTP ($code): La identificació ha fallat.';
$messages['smtpfromerror'] = 'Error SMTP ($code): No s\'ha pogut posar "$from" com a remitent ($msg).';
$messages['smtptoerror'] = 'Error SMTP ($code): No s\'ha pogut posar "$to" com a destinatari ($msg).';
-$messages['smtprecipientserror'] = 'Error SMTP: No s\'ha pogut analitzar la lista de destinataris.';
+$messages['smtprecipientserror'] = 'Error SMTP: No s\'ha pogut analitzar la llista de destinataris.';
$messages['smtperror'] = 'Error SMTP: $msg';
$messages['emailformaterror'] = 'Adreça de correu no vàlida: $email';
$messages['toomanyrecipients'] = 'Massa destinataris. Reduïu el nombre de destinataris a $max.';
$messages['maxgroupmembersreached'] = 'El nombre de membres del grup excedeix el màxim de $max.';
$messages['internalerror'] = 'Hi ha hagut un error intern. Si us plau torneu-ho a provar.';
-$messages['contactdelerror'] = 'No s\'ha pogut suprimir el(s) contacte(s).';
-$messages['contactdeleted'] = 'Contacte(s) suprimits(s) correctament.';
-$messages['contactrestoreerror'] = 'No s\'ha pogut restaurar el(s) contacte(s) suprimits(s).';
-$messages['contactrestored'] = 'Contacte(s) restaurats correctament.';
+$messages['contactdelerror'] = 'No s\'han pogut suprimir el(s) contacte(s).';
+$messages['contactdeleted'] = 'Contacte(s) suprimit(s) correctament.';
+$messages['contactrestoreerror'] = 'No s\'ha pogut restaurar el(s) contacte(s) suprimit(s).';
+$messages['contactrestored'] = 'Contacte(s) restaurat(s) correctament.';
$messages['groupdeleted'] = 'Grup suprimit correctament.';
$messages['grouprenamed'] = 'Grup reanomenat correctament.';
$messages['groupcreated'] = 'Grup creat correctament.';
@@ -149,7 +151,7 @@ $messages['savedsearchdeleted'] = 'S\'ha suprimit correctament la cerca desada.'
$messages['savedsearchdeleteerror'] = 'No s\'ha pogut suprimit la cerca desada.';
$messages['savedsearchcreated'] = 'S\'ha creat correctament la cerca desada.';
$messages['savedsearchcreateerror'] = 'No s\'ha pogut crear la cerca desada.';
-$messages['messagedeleted'] = 'Missatge(s) suprimits(s) correctament.';
+$messages['messagedeleted'] = 'Missatge(s) suprimit(s) correctament.';
$messages['messagemoved'] = 'Missatge(s) mogut(s) correctament.';
$messages['messagecopied'] = 'Missatge(s) copiat(s) correctament.';
$messages['messagemarked'] = 'Missatge(s) marcat(s) correctament.';
@@ -160,10 +162,10 @@ $messages['nametoolong'] = 'El nom és massa llarg.';
$messages['folderupdated'] = 'La carpeta ha estat actualitzada correctament.';
$messages['foldercreated'] = 'La carpeta ha estat creada correctament.';
$messages['invalidimageformat'] = 'No és un format d\'imatge vàlid.';
-$messages['mispellingsfound'] = 'S\'han detectat errors d\'ortografia al misstage.';
+$messages['mispellingsfound'] = 'S\'han detectat errors d\'ortografia al missatge.';
$messages['parentnotwritable'] = 'No s\'ha pogut crear/moure la carpeta dins de la carpeta ascendent seleccionada. No hi ha permisos d\'escriptura.';
$messages['messagetoobig'] = 'La part del missatge és massa gran per processar-la.';
-$messages['attachmentvalidationerror'] = 'ATENCIÓ! Aquest adjunt és sospitós perquè el seu tipus no coincideix amb el tipus declarat al missatge. Si no confies en l\'emissor, no l\'hauries d\'obrir al navegador perquè pot contenir elements maliciosos. <br/><br/><em>Expected: $expected; found: $detected</em>';
-$messages['noscriptwarning'] = 'Atenció: Aquest client de correu necessita Javascript! Per a poder fer-lo servir, has d\'activar Javascript a les opcions del navegador.';
+$messages['attachmentvalidationerror'] = 'ATENCIÓ! Aquest adjunt és sospitós perquè el seu tipus no coincideix amb el tipus declarat al missatge. Si no confieu en l\'emissor, no l\'hauríeu d\'obrir al navegador perquè pot contenir elements maliciosos. <br/><br/><em>S\'esperava: $expected; s\'ha trobat: $detected</em>';
+$messages['noscriptwarning'] = 'Atenció: Aquest client de correu necessita Javascript! Per a poder fer-lo servir, heu d\'activar Javascript a les opcions del navegador.';
?>
diff --git a/program/localization/cs_CZ/labels.inc b/program/localization/cs_CZ/labels.inc
index 2240065e7..b5cc093d8 100644
--- a/program/localization/cs_CZ/labels.inc
+++ b/program/localization/cs_CZ/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Aktuální stránka';
$labels['unread'] = 'NepÅ™eÄtené';
$labels['flagged'] = 'OznaÄené';
$labels['unanswered'] = 'NeoznaÄené';
+$labels['withattachment'] = 'S přílohou';
$labels['deleted'] = 'Smazané';
$labels['undeleted'] = 'Nesmazáno';
$labels['invert'] = 'Převrátit';
@@ -192,6 +194,7 @@ $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ý';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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í';
@@ -401,6 +406,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['previewpane'] = 'Zobrazit panel náhledu';
$labels['skin'] = 'Vzhled';
$labels['logoutclear'] = 'Vyprázdnit koš při odhlášení';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Při odpovídání odstranit ze zprávy půvo
$labels['autoaddsignature'] = 'Automaticky přidat podpis';
$labels['newmessageonly'] = 'pouze k novým zprávám';
$labels['replyandforwardonly'] = 'jen k odpovědi a přeposílané zprávě';
-$labels['replysignaturepos'] = 'Při odpovídání nebo přeposílání zprávy vložit podpis';
-$labels['belowquote'] = 'pod citaci';
-$labels['abovequote'] = 'nad citaci';
$labels['insertsignature'] = 'Vložit podpis';
$labels['previewpanemarkread'] = 'OznaÄit zobrazené zprávy jako pÅ™eÄtené';
$labels['afternseconds'] = 'po $n sekundách';
@@ -473,6 +476,7 @@ $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 cee1bd09a..59b2c6bd6 100644
--- a/program/localization/cs_CZ/messages.inc
+++ b/program/localization/cs_CZ/messages.inc
@@ -24,14 +24,16 @@ $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 v databázi!';
+$messages['dberror'] = 'Chyba databáze!';
$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í.';
+$messages['erroroverquota'] = 'Příkaz nelze provést, není volné místo na disku.';
+$messages['erroroverquotadelete'] = 'Není volné místo na disku. Použijte SHIFT+DEL k odstranění zprávy.';
$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. Nashledanou!';
+$messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Na shledanou!';
$messages['mailboxempty'] = 'Schránka je prázdná';
$messages['refreshing'] = 'Obnovuji...';
$messages['loading'] = 'NaÄítám...';
@@ -124,6 +126,8 @@ $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 9b695e140..ca1f17426 100644
--- a/program/localization/cy_GB/labels.inc
+++ b/program/localization/cy_GB/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Copio';
$labels['move'] = 'Symud';
$labels['moveto'] = 'Symud i...';
$labels['download'] = 'Llwytho lawr';
-$labels['open'] = 'Open';
+$labels['open'] = 'Agor';
$labels['showattachment'] = 'Dangos';
$labels['showanyway'] = 'Dangos beth bynnag';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Tudalen gyfredol';
$labels['unread'] = 'Heb eu darllen';
$labels['flagged'] = 'Nodwyd';
$labels['unanswered'] = 'Heb ei ateb';
+$labels['withattachment'] = 'Gyda atodiad';
$labels['deleted'] = 'Dilewyd';
$labels['undeleted'] = 'Heb ei ddileu';
$labels['invert'] = 'Gwrth-droi';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Golwg rhestr';
$labels['folderactions'] = 'Gweithredoedd ffolder...';
$labels['compact'] = 'Crynhoi';
$labels['empty'] = 'Gwagio';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Defnydd';
$labels['unknown'] = 'anhysbys';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Dangos mewn fformat testun plaen';
+$labels['changeformathtml'] = 'Dangos mewn fformat HTML';
// message compose
$labels['editasnew'] = 'Golygu fel neges newydd';
@@ -338,8 +342,8 @@ $labels['composeto'] = 'Ysgrifennu neges at';
$labels['contactsfromto'] = 'Cysylltiadau $from i $to o $count';
$labels['print'] = 'Argraffu';
$labels['export'] = 'Allforio';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Allforio popeth';
+$labels['exportsel'] = 'Allforio dewiswyd';
$labels['exportvcards'] = 'Allforio cysylltiadau mewn fformat vCard';
$labels['newcontactgroup'] = 'Creu grŵp cysylltiadau newydd';
$labels['grouprename'] = 'Ail-enwi grŵp';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,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['previewpane'] = 'Dangos ffenest rhagolwg';
$labels['skin'] = 'Croen rhyngwyneb';
$labels['logoutclear'] = 'Clirio\'r Sbwriel wrth allgofnodi';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Wrth ateb, dileu\'r llofnod gwreiddiol o\'r n
$labels['autoaddsignature'] = 'Ychwanegu llofnod yn awtomatig';
$labels['newmessageonly'] = 'negeseuon newydd yn unig';
$labels['replyandforwardonly'] = 'atebion a danfon ymlaen yn unig';
-$labels['replysignaturepos'] = 'Wrth ateb neu ddanfon ymlaen, rhoi\'r llofnod';
-$labels['belowquote'] = 'o dan y dyfynniad';
-$labels['abovequote'] = 'uwchben y dyfynniad';
$labels['insertsignature'] = 'Mewnosod llofnod';
$labels['previewpanemarkread'] = 'Nodi negeseuon rhagolwg fel darllenwyd';
$labels['afternseconds'] = 'ar ôl $n eiliad';
@@ -473,6 +476,7 @@ $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 553422948..edadc3b45 100644
--- a/program/localization/cy_GB/messages.inc
+++ b/program/localization/cy_GB/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Gwall Cronfa Ddata!';
$messages['requesttimedout'] = 'Cais wedi dod i derfyn amser';
$messages['errorreadonly'] = 'Methwyd gweithredu. Mae\'r ffolder yn darllen-yn-unig';
$messages['errornoperm'] = 'Methwyd gweithredu. Gwrthodwyd caniatad';
+$messages['erroroverquota'] = 'Methwyd gweithredu. Nid oes gofod gwag ar y disg.';
+$messages['erroroverquotadelete'] = 'Dim gofod gwag ar y disg. Defnyddiwch SHIFT+DEL i ddileu neges.';
$messages['invalidrequest'] = 'Cais annilys! Ni chadwyd unrhyw wybodaeth.';
$messages['invalidhost'] = 'Enw gweinydd annilys.';
$messages['nomessagesfound'] = 'Dim negeseuon wedi eu canfod yn y blwch hwn';
diff --git a/program/localization/da_DK/labels.inc b/program/localization/da_DK/labels.inc
index cb4e3b55c..a5b9b3bc8 100644
--- a/program/localization/da_DK/labels.inc
+++ b/program/localization/da_DK/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Aktuel side';
$labels['unread'] = 'Ulæste';
$labels['flagged'] = 'Markeret';
$labels['unanswered'] = 'Ubesvaret';
+$labels['withattachment'] = 'Med vedhæftning';
$labels['deleted'] = 'Slettede';
$labels['undeleted'] = 'Ikke slettet';
$labels['invert'] = 'Invertér';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Listevisningsmode';
$labels['folderactions'] = 'Mappehandlinger...';
$labels['compact'] = 'Ryd op';
$labels['empty'] = 'Tøm';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Diskforbrug';
$labels['unknown'] = 'ukendt';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Vis i ren tekst format';
+$labels['changeformathtml'] = 'Vis i HTML format';
// message compose
$labels['editasnew'] = 'Redigér som ny';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,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['previewpane'] = 'Forhåndsvisning';
$labels['skin'] = 'Brugerflade';
$labels['logoutclear'] = 'Tøm Papirkurv når jeg logger af';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Fjern original signatur fra besked, når der
$labels['autoaddsignature'] = 'Indsæt automatisk signatur';
$labels['newmessageonly'] = 'kun på nye beskeder';
$labels['replyandforwardonly'] = 'kun på svar og videresendelse af beskeder';
-$labels['replysignaturepos'] = 'Når beskeder besvares eller videresendes; indsæt signatur';
-$labels['belowquote'] = 'under det citerede';
-$labels['abovequote'] = 'over det citerede';
$labels['insertsignature'] = 'Indsæt signatur';
$labels['previewpanemarkread'] = 'Markér forhåndsviste beskeder som læst';
$labels['afternseconds'] = 'efter $n sekunder';
@@ -473,6 +476,7 @@ $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 6b8ce1928..9a0b8e4a5 100644
--- a/program/localization/da_DK/messages.inc
+++ b/program/localization/da_DK/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Database fejl!';
$messages['requesttimedout'] = 'Forespørgselstiden udløb';
$messages['errorreadonly'] = 'Kunne ikke udføre den ønskede handling. Mappen er skrivebeskyttet.';
$messages['errornoperm'] = 'Kunne ikke udføre den ønskede handling. Adgang nægtet.';
+$messages['erroroverquota'] = 'Kan ikke udføre handlingen. Der er ikke nok ledig diskplads.';
+$messages['erroroverquotadelete'] = 'Der er ikke nok ledig diskplads. Brug SHIFT+DEL til at slette en meddelelse.';
$messages['invalidrequest'] = 'Ugyldig forespørgsel! Ingen data blev gemt.';
$messages['invalidhost'] = 'Ugyldigt servernavn.';
$messages['nomessagesfound'] = 'Der blev ikke fundet nogen beskeder i denne postkasse.';
@@ -163,7 +165,7 @@ $messages['invalidimageformat'] = 'Ikke et gyldigt billedformat.';
$messages['mispellingsfound'] = 'Der er fundet stavefejl i beskeden.';
$messages['parentnotwritable'] = 'Kan ikke oprette/flytte mappe ind i valgt mappe. Ingen adgangsrettigheder.';
$messages['messagetoobig'] = 'Denne del af beskeden er for stor til at blive behandlet.';
-$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'] = 'ADVARSEL! Den vedhæftede fil er mistænkelig - Typen stemmer ikke overens med den oplyste type. Hvis du ikke har tillid til afsender, skal du ikke åbne filen da den kan indholde onsindet indhold. <br/><br/><em>Forventet: $expected; Fundet: $detected</em>';
$messages['noscriptwarning'] = 'Advarsel: Denne webmailclient kræver Javascript! For at kunne bruge den slå venligst Javascripts til i din browserindstillinger.';
?>
diff --git a/program/localization/de_CH/labels.inc b/program/localization/de_CH/labels.inc
index 98bbd8837..67d42bb05 100644
--- a/program/localization/de_CH/labels.inc
+++ b/program/localization/de_CH/labels.inc
@@ -37,12 +37,13 @@ $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';
-$labels['from'] = 'Absender';
+$labels['from'] = 'Von';
$labels['sender'] = 'Absender';
-$labels['to'] = 'Empfänger';
+$labels['to'] = 'An';
$labels['cc'] = 'Kopie (CC)';
$labels['bcc'] = 'Blind-Kopie';
$labels['replyto'] = 'Antwort an';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Aktuelle Seite';
$labels['unread'] = 'Ungelesene';
$labels['flagged'] = 'Markierte';
$labels['unanswered'] = 'Unbeantwortete';
+$labels['withattachment'] = 'Mit Anhang';
$labels['deleted'] = 'Gelöschte';
$labels['undeleted'] = 'Nicht gelöscht';
$labels['invert'] = 'Umkehren';
@@ -176,7 +178,7 @@ $labels['threaded'] = 'Gruppiert';
$labels['autoexpand_threads'] = 'Konversationen aufklappen';
$labels['do_expand'] = 'alle';
$labels['expand_only_unread'] = 'nur ungelesene';
-$labels['fromto'] = 'Sender/Empfänger';
+$labels['fromto'] = 'Von/An';
$labels['flag'] = 'Markierung';
$labels['attachment'] = 'Anhang';
$labels['nonesort'] = 'Keine';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Anzeigemodus';
$labels['folderactions'] = 'Ordneraktionen...';
$labels['compact'] = 'Packen';
$labels['empty'] = 'Leeren';
+$labels['importmessages'] = 'Nachrichten importieren';
$labels['quota'] = 'Verwendeter Speicherplatz';
$labels['unknown'] = 'unbekannt';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Letzte Seite';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppen';
+$labels['listgroup'] = 'Gruppenmitglieder anzeigen';
$labels['personaladrbook'] = 'Persönliches Adressbuch';
$labels['searchsave'] = 'Suche speichern';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML-Nachrichten verfassen';
$labels['htmlonreply'] = 'nur Antworten auf HTML-Nachrichten';
$labels['htmlonreplyandforward'] = 'Antworten oder Weiterleiten einer HTML-Nachricht';
$labels['htmlsignature'] = 'HTML-Signatur';
+$labels['showemail'] = 'E-Mail-Adresse und Namen anzeigen';
$labels['previewpane'] = 'Nachrichtenvorschau anzeigen';
$labels['skin'] = 'Oberflächendesign';
$labels['logoutclear'] = 'Papierkorb beim Abmelden leeren';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Beim Antworten die Signatur der Originalnachr
$labels['autoaddsignature'] = 'Signatur automatisch einfügen';
$labels['newmessageonly'] = 'nur bei neuen Nachrichten';
$labels['replyandforwardonly'] = 'nur bei Antworten und Weiterleitungen';
-$labels['replysignaturepos'] = 'Beim Antworten oder Weiterleiten die Signatur';
-$labels['belowquote'] = 'unter der Originalnachricht einfügen';
-$labels['abovequote'] = 'über der Originalnachricht einfügen';
$labels['insertsignature'] = 'Signatur einfügen';
$labels['previewpanemarkread'] = 'Nachricht in Vorschau als gelesen markieren';
$labels['afternseconds'] = 'nach $n Sekunden';
@@ -473,6 +476,7 @@ $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 f3697a825..27175be9e 100644
--- a/program/localization/de_CH/messages.inc
+++ b/program/localization/de_CH/messages.inc
@@ -126,6 +126,8 @@ $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 956e32aa4..662ad2c70 100644
--- a/program/localization/de_DE/labels.inc
+++ b/program/localization/de_DE/labels.inc
@@ -37,12 +37,13 @@ $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';
-$labels['from'] = 'Absender';
+$labels['from'] = 'Von';
$labels['sender'] = 'Absender';
-$labels['to'] = 'Empfänger';
+$labels['to'] = 'An';
$labels['cc'] = 'Kopie';
$labels['bcc'] = 'Blindkopie';
$labels['replyto'] = 'Antwort an';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Aktuelle Seite';
$labels['unread'] = 'Ungelesene';
$labels['flagged'] = 'Markierte';
$labels['unanswered'] = 'Unbeantwortete';
+$labels['withattachment'] = 'Mit Anhang';
$labels['deleted'] = 'Gelöschte';
$labels['undeleted'] = 'Nicht gelöscht';
$labels['invert'] = 'Invertieren';
@@ -176,7 +178,7 @@ $labels['threaded'] = 'Gruppiert';
$labels['autoexpand_threads'] = 'Konversationen aufklappen';
$labels['do_expand'] = 'alle';
$labels['expand_only_unread'] = 'nur ungelesene';
-$labels['fromto'] = 'Sender/Empfänger';
+$labels['fromto'] = 'Von/An';
$labels['flag'] = 'Markierung';
$labels['attachment'] = 'Anhang';
$labels['nonesort'] = 'Keine';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Anzeigemodus';
$labels['folderactions'] = 'Ordneraktionen...';
$labels['compact'] = 'Packen';
$labels['empty'] = 'Leeren';
+$labels['importmessages'] = 'Nachrichten importieren';
$labels['quota'] = 'Speicherplatz';
$labels['unknown'] = 'unbekannt';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Letzte Seite';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppen';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persönliches Adressbuch';
$labels['searchsave'] = 'Suchergebnisse speichern';
@@ -401,6 +406,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['previewpane'] = 'Nachrichtenvorschau anzeigen';
$labels['skin'] = 'Oberflächendesign';
$labels['logoutclear'] = 'Papierkorb beim Abmelden leeren';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Beim Antworten Signatur der Originalnachricht
$labels['autoaddsignature'] = 'Signatur automatisch einfügen';
$labels['newmessageonly'] = 'nur bei neuen Nachrichten';
$labels['replyandforwardonly'] = 'nur bei Antworten und Weiterleitungen';
-$labels['replysignaturepos'] = 'Beim Antworten die Signatur';
-$labels['belowquote'] = 'unter der Originalnachricht einfügen';
-$labels['abovequote'] = 'über der Originalnachricht einfügen';
$labels['insertsignature'] = 'Signatur einfügen';
$labels['previewpanemarkread'] = 'Nachricht in Vorschau als gelesen markieren';
$labels['afternseconds'] = 'nach $n Sekunden';
@@ -473,6 +476,7 @@ $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 eeaba7db2..ba0936d28 100644
--- a/program/localization/de_DE/messages.inc
+++ b/program/localization/de_DE/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Datenbankfehler!';
$messages['requesttimedout'] = 'Zeitüberschreitung der Anforderung';
$messages['errorreadonly'] = 'Die Aktion kann nicht ausgeführt werden. Der Ordner ist schreibgeschützt.';
$messages['errornoperm'] = 'Die Aktion kann nicht ausgeführt werden. Zugriff verweigert.';
+$messages['erroroverquota'] = 'Die Aktion kann nicht ausgeführt werden. Nicht genug freier Speicherplatz.';
+$messages['erroroverquotadelete'] = 'Nicht genug freier Speicherplatz. Verwenden sie SHIFT+ENTF um Nachrichten zu löschen.';
$messages['invalidrequest'] = 'Ungültige Anfrage! Es wurden keine Daten gespeichert.';
$messages['invalidhost'] = 'Ungültiger Server Name';
$messages['nomessagesfound'] = 'Keine Nachrichten in diesem Ordner.';
diff --git a/program/localization/el_GR/labels.inc b/program/localization/el_GR/labels.inc
index b3166730f..d3030e574 100644
--- a/program/localization/el_GR/labels.inc
+++ b/program/localization/el_GR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'ΠÏόχειÏα';
$labels['sent'] = 'Απεσταλμένα';
$labels['trash'] = 'Κάδος ΑποÏÏιμάτων';
$labels['junk'] = 'ΑνεπιθÏμητα';
+$labels['show_real_foldernames'] = 'Εμφάνιση Ï€Ïαγματικών ονομάτων για ειδικοÏÏ‚ φακέλους';
// message listing
$labels['subject'] = 'Θέμα';
@@ -64,7 +65,7 @@ $labels['copy'] = 'ΑντιγÏαφή';
$labels['move'] = 'Μετακίνηση';
$labels['moveto'] = 'Μετακίνηση σε...';
$labels['download'] = 'Λήψη';
-$labels['open'] = 'Open';
+$labels['open'] = 'Ανοιγμα';
$labels['showattachment'] = 'Εμφάνιση';
$labels['showanyway'] = 'Εμφάνιση';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'ΤÏέχουσα σελίδα';
$labels['unread'] = 'Μη αναγνωσμένο';
$labels['flagged'] = 'Σημειωμένο';
$labels['unanswered'] = 'Αναπάντητο';
+$labels['withattachment'] = 'Με επισÏναψη';
$labels['deleted'] = 'ΔιεγÏαμμένο';
$labels['undeleted'] = 'Μη διεγÏαμμένο';
$labels['invert'] = 'ΑναστÏοφή';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'ΠÏοβολή σε λίστα';
$labels['folderactions'] = 'ΕνέÏγειες στους φακέλους';
$labels['compact'] = 'Συμπίεση';
$labels['empty'] = 'Άδειασμα';
+$labels['importmessages'] = 'Εισαγωγή μηνυμάτων';
$labels['quota'] = 'ΧÏήση δίσκου';
$labels['unknown'] = 'άγνωστο';
@@ -202,11 +205,12 @@ $labels['resetsearch'] = 'ΕπαναφοÏά Αναζήτησης';
$labels['searchmod'] = 'Aλλαγή αναζήτησης';
$labels['msgtext'] = 'Σε όλο το μήνυμα';
$labels['body'] = 'Σώμα';
+$labels['type'] = 'Type';
$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'] = 'ΕπεξεÏγασία σαν νέο';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Εμφάνιση της τελευταίας σελ
$labels['group'] = 'Ομάδα';
$labels['groups'] = 'Ομάδες';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ΠÏοσωπικές ΔιυθÏνσεις';
$labels['searchsave'] = 'Αποθήκευση αναζήτησης';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'ΔημιουÏγία μηνÏματος σε μοÏφή
$labels['htmlonreply'] = 'μόνο σε απάντηση μηνÏματος μοÏφής HTML';
$labels['htmlonreplyandforward'] = 'σε Ï€Ïοώθηση ή σε απάντηση σε HTML μήνυμα';
$labels['htmlsignature'] = 'ΥπογÏαφή HTML';
+$labels['showemail'] = 'Εμφάνιση διεÏθυνσης e-mail με το εμφανιζόμενο όνομα';
$labels['previewpane'] = 'Εμφάνιση Ï€Ïοεπισκόπησης';
$labels['skin'] = 'Θέμα εμφάνισης';
$labels['logoutclear'] = 'Άδειασμα του κάδου στην έξοδο';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Όταν το μήνυμα είναι απάÎ
$labels['autoaddsignature'] = 'Η υπογÏαφή να Ï€Ïοστίθεται αυτόματα';
$labels['newmessageonly'] = 'μόνο στα νέα μηνÏματα';
$labels['replyandforwardonly'] = 'μόνο στις απαντήσεις και Ï€Ïοωθήσεις';
-$labels['replysignaturepos'] = 'Όταν γίνεται απάντηση ή Ï€Ïοώθηση, η υπογÏαφή να τοποθετείτε';
-$labels['belowquote'] = 'πάνω από την παÏάθεση';
-$labels['abovequote'] = 'κάτω από την παÏάθεση';
$labels['insertsignature'] = 'ΠÏοσθήκη υπογÏαφής';
$labels['previewpanemarkread'] = 'Στα μηνÏματα που έγινε Ï€Ïοεπισκόπηση να μαÏκάÏονται σαν αναγνωσμένα';
$labels['afternseconds'] = 'μετά από $n δευτεÏόλεπτα';
@@ -473,6 +476,7 @@ $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 542066efa..dc2499d8b 100644
--- a/program/localization/el_GR/messages.inc
+++ b/program/localization/el_GR/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Σφάλμα βάσης δεδομένων!';
$messages['requesttimedout'] = 'Το αίτημα εξέπνευσε χÏονικά';
$messages['errorreadonly'] = 'Η διαδικασία δεν μποÏεί να ολοκληÏωθεί. Ο φάκελος είναι μόνο για ανάγνωση.';
$messages['errornoperm'] = 'Η διαδικασία δεν μποÏεί να ολοκληÏωθεί. ΆÏνηση άδειας';
+$messages['erroroverquota'] = 'Δεν είναι δυνατή η εκτέλεση της λειτουÏγίας. Δεν υπάÏχει ελεÏθεÏος χώÏος στο δίσκο. ';
+$messages['erroroverquotadelete'] = 'Δεν υπάÏχει ελεÏθεÏος χώÏος στο δίσκο. ΧÏησιμοποιήστε το συνδυασμό πλήκτÏων SHIFT DEL για να διαγÏάψετε ένα μήνυμα.';
$messages['invalidrequest'] = 'Λανθασμένο αίτημα! Δεν αποθηκεÏτηκαν δεδομένα.';
$messages['invalidhost'] = 'ΆκυÏο όνομα εξυπηÏετητή.';
$messages['nomessagesfound'] = 'Δε βÏέθηκαν μηνÏματα σε αυτή τη θυÏίδα';
@@ -90,8 +92,8 @@ $messages['searching'] = 'Αναζήτηση...';
$messages['checking'] = 'Έλεγχος...';
$messages['nospellerrors'] = 'Δε βÏέθηκαν οÏθογÏαφικά λάθη';
$messages['folderdeleted'] = 'Ο φάκελος διαγÏάφηκε επιτυχώς';
-$messages['foldersubscribed'] = 'Folder successfully subscribed.';
-$messages['folderunsubscribed'] = 'Folder successfully unsubscribed.';
+$messages['foldersubscribed'] = 'Ο φάκελος εχει εγγÏαφεί με επιτυχία.';
+$messages['folderunsubscribed'] = 'Ο φάκελος διαγÏάφηκε επιτυχώς';
$messages['folderpurged'] = 'Ο φάκελος καθαÏίστηκε με επιτυχία.';
$messages['folderexpunged'] = 'Ο φάκελος συμπιέστηκε με επιτυχία.';
$messages['deletedsuccessfully'] = 'ΔιαγÏαφή Επιτυχώς';
@@ -119,9 +121,9 @@ $messages['selectimportfile'] = 'Επιλέξτε αÏχείο για ανέβα
$messages['addresswriterror'] = 'Η επιλεγμένη ατζέντα διευθÏνσεων δεν είνα εγγÏάψιμη';
$messages['contactaddedtogroup'] = 'Οι επαφές Ï€Ïοστέθηκαν στην ομάδα με επιτυχία.';
$messages['contactremovedfromgroup'] = 'Οι επαφές αφαιÏέθηκαν από την ομάδα με επιτυχία.';
-$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$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'] = 'Η λειτουÏγία δεν επιτÏέπεται!';
@@ -140,30 +142,30 @@ $messages['maxgroupmembersreached'] = 'Ο αÏιθμός των μελών τηÏ
$messages['internalerror'] = 'ΠÏοέκυψε ένα εσωτεÏικό σφάλμα. ΠαÏακαλώ δοκιμάστε πάλι.';
$messages['contactdelerror'] = 'Δεν είναι δυνατή η διαγÏαφή της επαφής/ων';
$messages['contactdeleted'] = 'Η επαφή/ές διαγÏάφηκαν με επιτυχία.';
-$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['contactrestoreerror'] = 'Οι διαγÏαφημενη επαφη(ες) δεν μποÏουν να επαναφεÏθουν.';
+$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['autocompletemore'] = 'ΠεÏισσότεÏες ταιÏιάστες καταχωÏήσεις βÏέθηκαν. ΠληκτÏολογείστε πεÏισσότεÏους χαÏακτήÏες.';
+$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['noscriptwarning'] = 'ΠÏοειδοποίηση : Αυτή η υπηÏεσία webmail απαιτεί Javascript! Για να ΤΟ χÏησιμοποιήσετε ενεÏγοποιήστε τΟ JavaScript στις Ïυθμίσεις του browser σας. ';
?>
diff --git a/program/localization/en_GB/labels.inc b/program/localization/en_GB/labels.inc
index 49b6be519..f903b0cf5 100644
--- a/program/localization/en_GB/labels.inc
+++ b/program/localization/en_GB/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $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';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Show last set';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Compose HTML messages';
$labels['htmlonreply'] = 'on reply to HTML message only';
$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';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 f819147b0..21e7539b4 100644
--- a/program/localization/en_GB/messages.inc
+++ b/program/localization/en_GB/messages.inc
@@ -28,6 +28,8 @@ $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.';
diff --git a/program/localization/en_US/csv2vcard.inc b/program/localization/en_US/csv2vcard.inc
index 5412f7e20..e7b86795b 100644
--- a/program/localization/en_US/csv2vcard.inc
+++ b/program/localization/en_US/csv2vcard.inc
@@ -91,3 +91,20 @@ $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 252e0ce68..1865bcb3d 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $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';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,8 @@ $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)';
@@ -353,6 +358,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -401,6 +407,7 @@ $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';
@@ -454,9 +461,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +477,7 @@ $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/messages.inc b/program/localization/en_US/messages.inc
index f9b5e00a6..47b0f797d 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -101,13 +101,16 @@ $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['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['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...';
@@ -126,6 +129,8 @@ $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/eo/labels.inc b/program/localization/eo/labels.inc
index 823fc25cb..3c2930c89 100644
--- a/program/localization/eo/labels.inc
+++ b/program/localization/eo/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Nuna paÄo';
$labels['unread'] = 'Nelegitan';
$labels['flagged'] = 'Markita';
$labels['unanswered'] = 'Nerespondita';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Forigita';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Inversigu';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Montru lastan';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupoj';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persona Adresoj';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Uzado de HTML-redaktilo';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML subskribo';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Montru antaÅ­rigardejon';
$labels['skin'] = 'Interfaco-etoso';
$labels['logoutclear'] = 'Malplenigu rubujon je eliro';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 32771733d..4d72fe54b 100644
--- a/program/localization/eo/messages.inc
+++ b/program/localization/eo/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Datumbaz-eraro!';
$messages['requesttimedout'] = 'Request timed out';
$messages['errorreadonly'] = 'Ne povis fari agon. Dosierujo estas nurlega';
$messages['errornoperm'] = 'Ne povis fari agon. Ne havas permeson.';
+$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'] = 'Nevalida peto';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'Neniu mesaÄo en ĉi tiu dosierujo';
diff --git a/program/localization/es_AR/labels.inc b/program/localization/es_AR/labels.inc
index 3e6793e51..5bc53f7f0 100644
--- a/program/localization/es_AR/labels.inc
+++ b/program/localization/es_AR/labels.inc
@@ -37,11 +37,12 @@ $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';
$labels['from'] = 'Remitente';
-$labels['sender'] = 'Sender';
+$labels['sender'] = 'Remitente';
$labels['to'] = 'Destinatario';
$labels['cc'] = 'Copia';
$labels['bcc'] = 'Cco';
@@ -52,21 +53,21 @@ $labels['size'] = 'Tamaño';
$labels['priority'] = 'Prioridad';
$labels['organization'] = 'Organización';
$labels['readstatus'] = 'Read status';
-$labels['listoptions'] = 'List options...';
+$labels['listoptions'] = 'Listar opciones...';
$labels['mailboxlist'] = 'Carpetas';
$labels['messagesfromto'] = 'Mensajes $from a $to de $count';
-$labels['threadsfromto'] = 'Threads $from to $to of $count';
+$labels['threadsfromto'] = '$from a $to de $count conversaciones';
$labels['messagenrof'] = 'Mensaje $nr de $count';
-$labels['fromtoshort'] = '$from – $to of $count';
+$labels['fromtoshort'] = '$from – $to de $count';
$labels['copy'] = 'Copiar';
$labels['move'] = 'Mover';
$labels['moveto'] = 'Mover a...';
$labels['download'] = 'Descargar';
$labels['open'] = 'Open';
-$labels['showattachment'] = 'Show';
-$labels['showanyway'] = 'Show it anyway';
+$labels['showattachment'] = 'Mostrar';
+$labels['showanyway'] = 'Mostrar esto siempre';
$labels['filename'] = 'Nombre del archivo';
$labels['filesize'] = 'Tamaño del archivo';
@@ -122,18 +123,18 @@ $labels['longdec'] = 'Diciembre';
$labels['today'] = 'Hoy';
// toolbar buttons
-$labels['refresh'] = 'Refresh';
+$labels['refresh'] = 'Actualizar';
$labels['checkmail'] = 'Revisar si hay nuevos mensajes';
$labels['compose'] = 'Escribir un mensaje';
$labels['writenewmessage'] = 'Crear nuevo mensaje';
-$labels['reply'] = 'Reply';
+$labels['reply'] = 'Responder';
$labels['replytomessage'] = 'Responder mensaje';
$labels['replytoallmessage'] = 'Responder al emisor y a todos los destinatarios';
-$labels['replyall'] = 'Reply all';
-$labels['replylist'] = 'Reply list';
-$labels['forward'] = 'Forward';
-$labels['forwardinline'] = 'Forward inline';
-$labels['forwardattachment'] = 'Forward as attachment';
+$labels['replyall'] = 'Responder a todos';
+$labels['replylist'] = 'Responder a lista';
+$labels['forward'] = 'Reenviar';
+$labels['forwardinline'] = 'Reenviar en linea';
+$labels['forwardattachment'] = 'Reenviar como adjunto';
$labels['forwardmessage'] = 'Reenviar mensaje';
$labels['deletemessage'] = 'Eliminar mensaje';
$labels['movemessagetotrash'] = 'Mover mensaje a la papelera';
@@ -144,16 +145,16 @@ $labels['nextmessage'] = 'Mostrar siguente mensaje';
$labels['lastmessage'] = 'Mostrar último mensaje';
$labels['backtolist'] = 'Volver a la lista de mensajes';
$labels['viewsource'] = 'Mostrar código';
-$labels['mark'] = 'Mark';
+$labels['mark'] = 'Marcar';
$labels['markmessages'] = 'Marcar mensajes';
$labels['markread'] = 'Como leído';
$labels['markunread'] = 'Como no leído';
$labels['markflagged'] = 'Como marcado';
$labels['markunflagged'] = 'Como no marcado';
-$labels['moreactions'] = 'More actions...';
-$labels['more'] = 'More';
-$labels['back'] = 'Back';
-$labels['options'] = 'Options';
+$labels['moreactions'] = 'Mas acciones...';
+$labels['more'] = 'Más';
+$labels['back'] = 'Atrás';
+$labels['options'] = 'Opciones';
$labels['select'] = 'Elija';
$labels['all'] = 'Todos';
@@ -162,36 +163,38 @@ $labels['currpage'] = 'Página actual';
$labels['unread'] = 'Sin leer';
$labels['flagged'] = 'Marcado';
$labels['unanswered'] = 'Sin respuesta';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Eliminado';
-$labels['undeleted'] = 'Not deleted';
+$labels['undeleted'] = 'No eliminado';
$labels['invert'] = 'Invertir';
$labels['filter'] = 'Filtrar';
-$labels['list'] = 'List';
-$labels['threads'] = 'Threads';
+$labels['list'] = 'Lista';
+$labels['threads'] = 'Conversaciones';
$labels['expand-all'] = 'Expandir Todos';
$labels['expand-unread'] = 'Expandir No Leidos';
$labels['collapse-all'] = 'Colapsar Todos';
-$labels['threaded'] = 'Threaded';
+$labels['threaded'] = 'Como conversaciones';
-$labels['autoexpand_threads'] = 'Expand message threads';
-$labels['do_expand'] = 'all threads';
+$labels['autoexpand_threads'] = 'Expandir mensajes en conversación';
+$labels['do_expand'] = 'todas las conversaciones';
$labels['expand_only_unread'] = 'solo con mensajes no leídos';
-$labels['fromto'] = 'From/To';
-$labels['flag'] = 'Flag';
+$labels['fromto'] = 'De/A';
+$labels['flag'] = 'Marca';
$labels['attachment'] = 'Adjunto';
$labels['nonesort'] = 'Ninguno';
$labels['sentdate'] = 'Fecha de Enviado';
$labels['arrival'] = 'Fecha de Recepción';
$labels['asc'] = 'Ascendente';
$labels['desc'] = 'Descendente';
-$labels['listcolumns'] = 'List columns';
-$labels['listsorting'] = 'Sorting column';
-$labels['listorder'] = 'Sorting order';
+$labels['listcolumns'] = 'Listar columnas';
+$labels['listsorting'] = 'Ordenar por';
+$labels['listorder'] = 'Ordenado por';
$labels['listmode'] = 'List view mode';
-$labels['folderactions'] = 'Folder actions...';
+$labels['folderactions'] = 'Acciones de carpeta...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Vaciar';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconocido';
@@ -202,6 +205,7 @@ $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)';
@@ -210,29 +214,29 @@ $labels['changeformathtml'] = 'Display in HTML format';
// message compose
$labels['editasnew'] = 'Editar como nuevo';
-$labels['send'] = 'Send';
+$labels['send'] = 'Enviar';
$labels['sendmessage'] = 'Enviar ahora el mensaje';
$labels['savemessage'] = 'Guardar como borrador';
$labels['addattachment'] = 'Añadir un archivo';
$labels['charset'] = 'Codificación';
$labels['editortype'] = 'Tipo de editor';
$labels['returnreceipt'] = 'Acuse de recibo';
-$labels['dsn'] = 'Delivery status notification';
-$labels['mailreplyintro'] = 'On $date, $sender wrote:';
-$labels['originalmessage'] = 'Original Message';
+$labels['dsn'] = 'Notificación de estado del envío';
+$labels['mailreplyintro'] = 'El $date, $sender escribió:';
+$labels['originalmessage'] = 'Mensaje original';
-$labels['editidents'] = 'Edit identities';
-$labels['spellcheck'] = 'Spell';
+$labels['editidents'] = 'Editar identidades';
+$labels['spellcheck'] = 'Gramática';
$labels['checkspelling'] = 'Revisar ortografía';
$labels['resumeediting'] = 'Continuar edición';
$labels['revertto'] = 'Revertir a';
-$labels['attach'] = 'Attach';
+$labels['attach'] = 'Adjuntar';
$labels['attachments'] = 'Adjuntos';
$labels['upload'] = 'Agregar';
-$labels['uploadprogress'] = '$percent ($current from $total)';
+$labels['uploadprogress'] = '$percent ($current de $total)';
$labels['close'] = 'Cerrar';
-$labels['messageoptions'] = 'Message options...';
+$labels['messageoptions'] = 'Opciones de mensaje...';
$labels['low'] = 'Bajo';
$labels['lowest'] = 'Bajísimo';
@@ -243,9 +247,9 @@ $labels['highest'] = 'Altísimo';
$labels['nosubject'] = '(sin asunto)';
$labels['showimages'] = 'Mostrar imágenes';
$labels['alwaysshow'] = 'Siempre mostrar imágenes de $sender';
-$labels['isdraft'] = 'This is a draft message.';
-$labels['andnmore'] = '$nr more...';
-$labels['togglemoreheaders'] = 'Show more message headers';
+$labels['isdraft'] = 'Este es un borrador.';
+$labels['andnmore'] = '$nr más...';
+$labels['togglemoreheaders'] = 'Mostrarme más encabezados de mensaje';
$labels['togglefullheaders'] = 'Toggle raw message headers';
$labels['htmltoggle'] = 'HTML';
@@ -269,68 +273,68 @@ $labels['receiptnote'] = 'Nota: Esta notificación sólo significa que su mensaj
$labels['name'] = 'Nombre completo';
$labels['firstname'] = 'Nombre';
$labels['surname'] = 'Apellido';
-$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['middlename'] = 'Segundo nombre';
+$labels['nameprefix'] = 'Prefijo';
+$labels['namesuffix'] = 'Subfijo';
+$labels['nickname'] = 'Sobre nombre';
+$labels['jobtitle'] = 'Puesto';
+$labels['department'] = 'Departamento';
+$labels['gender'] = 'Sexo';
+$labels['maidenname'] = 'Apellido de soltera';
$labels['email'] = 'Correo';
-$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['phone'] = 'Teléfono';
+$labels['address'] = 'Dirección';
+$labels['street'] = 'Calle';
+$labels['locality'] = 'Ciudad';
+$labels['zipcode'] = 'Código Postal';
+$labels['region'] = 'Estado/Provincia';
+$labels['country'] = 'País';
+$labels['birthday'] = 'Cumpleaños';
+$labels['anniversary'] = 'Aniversario';
+$labels['website'] = 'Sitio Web';
+$labels['instantmessenger'] = 'Mensajería Instantanea';
+$labels['notes'] = 'Notas';
+$labels['male'] = 'masculino';
+$labels['female'] = 'femenino';
+$labels['manager'] = 'Administrador';
+$labels['assistant'] = 'Asistente';
+$labels['spouse'] = 'Cónygue';
+$labels['allfields'] = 'Todos los campos';
+$labels['search'] = 'Buscar';
+$labels['advsearch'] = 'Búsqueda Avanzada';
+$labels['advanced'] = 'Avanzado';
+$labels['other'] = 'Otro';
+
+$labels['typehome'] = 'Particular';
+$labels['typework'] = 'Laboral';
+$labels['typeother'] = 'Otro';
+$labels['typemobile'] = 'Móvil';
+$labels['typemain'] = 'Principal';
+$labels['typehomefax'] = 'Fax Particular';
+$labels['typeworkfax'] = 'Fax Laboral';
+$labels['typecar'] = 'Auto';
$labels['typepager'] = 'Pager';
$labels['typevideo'] = 'Video';
-$labels['typeassistant'] = 'Assistant';
-$labels['typehomepage'] = 'Home Page';
+$labels['typeassistant'] = 'Asistente';
+$labels['typehomepage'] = 'Página Personal';
$labels['typeblog'] = 'Blog';
-$labels['typeprofile'] = 'Profile';
+$labels['typeprofile'] = 'Perfil';
-$labels['addfield'] = 'Add field...';
+$labels['addfield'] = 'Agregar campo...';
$labels['addcontact'] = 'Añadir nuevo contacto';
$labels['editcontact'] = 'Editar contacto';
-$labels['contacts'] = 'Contacts';
-$labels['contactproperties'] = 'Contact properties';
-$labels['personalinfo'] = 'Personal information';
+$labels['contacts'] = 'Contactos';
+$labels['contactproperties'] = 'Propiedades del contacto';
+$labels['personalinfo'] = 'Información personal';
$labels['edit'] = 'Editar';
$labels['cancel'] = 'Cancelar';
$labels['save'] = 'Guardar';
$labels['delete'] = 'Eliminar';
-$labels['rename'] = 'Rename';
-$labels['addphoto'] = 'Add';
-$labels['replacephoto'] = 'Replace';
-$labels['uploadphoto'] = 'Upload photo';
+$labels['rename'] = 'Renombrar';
+$labels['addphoto'] = 'Agregar';
+$labels['replacephoto'] = 'Reemplazar';
+$labels['uploadphoto'] = 'Subir foto';
$labels['newcontact'] = 'Añadir nuevo contacto';
$labels['deletecontact'] = 'Eliminar contactos seleccionados';
@@ -342,9 +346,9 @@ $labels['exportall'] = 'Export all';
$labels['exportsel'] = 'Export selected';
$labels['exportvcards'] = 'Exportar contactos en format vCard';
$labels['newcontactgroup'] = 'Crear Nuevo Grupo de Contacto';
-$labels['grouprename'] = 'Rename group';
-$labels['groupdelete'] = 'Delete group';
-$labels['groupremoveselected'] = 'Remove selected contacts from group';
+$labels['grouprename'] = 'Renombrar grupo';
+$labels['groupdelete'] = 'Eliminar grupo';
+$labels['groupremoveselected'] = 'Remover del grupo los contactos seleccionados';
$labels['previouspage'] = 'Mostrar grupo anterior';
$labels['firstpage'] = 'Mostrar primer grupo';
@@ -353,22 +357,23 @@ $labels['lastpage'] = 'Mostrar último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Direcciones personales';
-$labels['searchsave'] = 'Save search';
-$labels['searchdelete'] = 'Delete search';
+$labels['searchsave'] = 'Guardar búsqueda';
+$labels['searchdelete'] = 'Eliminar búsqueda';
$labels['import'] = 'Importar';
$labels['importcontacts'] = 'Importar contactos';
$labels['importfromfile'] = 'Importar desde el archivo:';
-$labels['importtarget'] = 'Add new contacts to address book:';
+$labels['importtarget'] = 'Agregar nuevos contactos a la libreta de direcciones:';
$labels['importreplace'] = 'Reemplazar completamente la lista de contactos';
-$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['importdesc'] = 'Puedes subir contactos desde una libreta de direcciones existente.<br/>Actualmente soportamos la importación de direcciones utilizando el formato <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> o CSV (Valores Separados por Coma).';
$labels['done'] = 'Hecho';
// settings
$labels['settingsfor'] = 'Configuración para';
-$labels['about'] = 'About';
+$labels['about'] = 'Acerca de';
$labels['preferences'] = 'Preferencias';
$labels['userpreferences'] = 'Preferencias de usuario';
$labels['editpreferences'] = 'Editar preferencias de usuario';
@@ -385,8 +390,8 @@ $labels['defaultcharset'] = 'Juego de Caracteres por Defecto';
$labels['htmlmessage'] = 'Mensaje HTML';
$labels['messagepart'] = 'Part';
$labels['digitalsig'] = 'Digital Signature';
-$labels['dateformat'] = 'Date format';
-$labels['timeformat'] = 'Time format';
+$labels['dateformat'] = 'Formato de fecha';
+$labels['timeformat'] = 'Formato de tiempo';
$labels['prettydate'] = 'Fecha detallada';
$labels['setdefault'] = 'Seleccionar opción por defecto';
$labels['autodetect'] = 'Automático';
@@ -395,12 +400,13 @@ $labels['timezone'] = 'Zona horaria';
$labels['pagesize'] = 'Filas por página';
$labels['signature'] = 'Firma';
$labels['dstactive'] = 'Cambio de horario';
-$labels['showinextwin'] = 'Open message in a new window';
-$labels['composeextwin'] = 'Compose in a new window';
+$labels['showinextwin'] = 'Abrir mensaje en nueva ventana';
+$labels['composeextwin'] = 'Redactar en nueva ventana';
$labels['htmleditor'] = 'Componer mensaje en HTML';
-$labels['htmlonreply'] = 'on reply to HTML message';
-$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
+$labels['htmlonreply'] = 'al responder un mensaje HTML';
+$labels['htmlonreplyandforward'] = 'al reenviar o responder un mensaje HTML';
$labels['htmlsignature'] = 'Firma HTML';
+$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';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Al responder, eliminar la firma del mensaje o
$labels['autoaddsignature'] = 'Agregar la firma automáticamente';
$labels['newmessageonly'] = 'nuevos mensajes solamente';
$labels['replyandforwardonly'] = 'respuestas o reenvios solamente';
-$labels['replysignaturepos'] = 'Agregar firma al responder o reenviar';
-$labels['belowquote'] = 'debajo de la cita';
-$labels['abovequote'] = 'sobre la cita';
$labels['insertsignature'] = 'Insertar firma';
$labels['previewpanemarkread'] = 'Marcar mensajes previsualizados como leidos';
$labels['afternseconds'] = 'despues de $n segundos';
@@ -473,6 +476,7 @@ $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 167fbe290..1cec9f01d 100644
--- a/program/localization/es_AR/messages.inc
+++ b/program/localization/es_AR/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Error en base de datos!';
$messages['requesttimedout'] = 'Tiempo de espera agotado';
$messages['errorreadonly'] = 'No se pudo realizar la operación. La carpeta es de sólo lectura.';
$messages['errornoperm'] = 'No se pudo realizar la operación. Permiso denegado.';
+$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'] = 'Peteción invalida! No se guardó nada.';
$messages['invalidhost'] = 'Nombre de servidor inválido.';
$messages['nomessagesfound'] = 'No se han encontrado mensajes en esta casilla';
diff --git a/program/localization/es_ES/labels.inc b/program/localization/es_ES/labels.inc
index cbee58b6e..11d14fa08 100644
--- a/program/localization/es_ES/labels.inc
+++ b/program/localization/es_ES/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Copiar';
$labels['move'] = 'Mover';
$labels['moveto'] = 'Mover a…';
$labels['download'] = 'Descargar';
-$labels['open'] = 'Open';
+$labels['open'] = 'Abrir';
$labels['showattachment'] = 'Mostrar';
$labels['showanyway'] = 'Mostrarlo de todos modos';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Página actual';
$labels['unread'] = 'Sin leer';
$labels['flagged'] = 'Señalado';
$labels['unanswered'] = 'Sin respuesta';
+$labels['withattachment'] = 'Con adjunto';
$labels['deleted'] = 'Eliminado';
$labels['undeleted'] = 'No eliminado';
$labels['invert'] = 'Invertir';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Mostrar en formato de texto sencillo';
+$labels['changeformathtml'] = 'Mostrar en formato HTML';
// message compose
$labels['editasnew'] = 'Editar como nuevo';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,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['previewpane'] = 'Mostrar vista preliminar';
$labels['skin'] = 'Apariencia de la interfaz';
$labels['logoutclear'] = 'Vaciar papelera al cerrar sesión';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Eliminar la firma original del mensaje al res
$labels['autoaddsignature'] = 'Añadir firma automáticamente';
$labels['newmessageonly'] = 'solamente mensaje nuevo';
$labels['replyandforwardonly'] = 'respuestas y reenvíos solamente';
-$labels['replysignaturepos'] = 'Colocar firma al responder o reenviar';
-$labels['belowquote'] = 'abajo del texto seleccionado';
-$labels['abovequote'] = 'arriba del texto seleccionado';
$labels['insertsignature'] = 'Insertar firma';
$labels['previewpanemarkread'] = 'Marcar mensaje previsualizado como leído';
$labels['afternseconds'] = 'después de $n segundos';
@@ -473,6 +476,7 @@ $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 6c031df29..d4bd81402 100644
--- a/program/localization/es_ES/messages.inc
+++ b/program/localization/es_ES/messages.inc
@@ -126,6 +126,8 @@ $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 cb184b086..a8bc28403 100644
--- a/program/localization/et_EE/labels.inc
+++ b/program/localization/et_EE/labels.inc
@@ -37,6 +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';
// message listing
$labels['subject'] = 'Pealkiri';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Kopeeri';
$labels['move'] = 'Liiguta';
$labels['moveto'] = 'liiguta kausta...';
$labels['download'] = 'laadi arvutisse';
-$labels['open'] = 'Open';
+$labels['open'] = 'Ava';
$labels['showattachment'] = 'Näita';
$labels['showanyway'] = 'Näita ikka';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Praegune leht';
$labels['unread'] = 'Lugemata';
$labels['flagged'] = 'Märgistatud';
$labels['unanswered'] = 'Vastamata';
+$labels['withattachment'] = 'Koos manusega';
$labels['deleted'] = 'Kustutatud';
$labels['undeleted'] = 'Pole kustutatud';
$labels['invert'] = 'Vaheta';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Näita lihttekstina';
+$labels['changeformathtml'] = 'Näita HTMLis';
// message compose
$labels['editasnew'] = 'Kasuta uue kirja põhjana';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Kasuta HTML redaktorit';
$labels['htmlonreply'] = 'vaid HTML-vormingus kirjale vastamisel';
$labels['htmlonreplyandforward'] = 'edastamisel või HTML kirjale vastates';
$labels['htmlsignature'] = 'HTML allkiri';
+$labels['showemail'] = 'Näita nime juures e-posti aadressi';
$labels['previewpane'] = 'Näita eelvaate akent';
$labels['skin'] = 'Kliendi välimus';
$labels['logoutclear'] = 'Tühjenda väljumisel prügikast';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Vastates eemalda kirjast esialgne allkiri';
$labels['autoaddsignature'] = 'Lisa allkiri automaatselt';
$labels['newmessageonly'] = 'ainult uutele';
$labels['replyandforwardonly'] = 'ainult vastates ja edastades';
-$labels['replysignaturepos'] = 'Vastates või edastades aseta allkiri';
-$labels['belowquote'] = 'tsiteeritu alla';
-$labels['abovequote'] = 'tsiteeritu kohale';
$labels['insertsignature'] = 'Sisesta allkiri';
$labels['previewpanemarkread'] = 'Märgi eelvaadatud kirjad loetuks';
$labels['afternseconds'] = '$n sekundi pärast';
@@ -473,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignoreeri sõnu, milles on numbreid';
$labels['spellcheckignorecaps'] = 'Ignoreeri suurte tähtedega kirjutatud sõnu';
$labels['addtodict'] = 'Lisa sõnastikku';
$labels['mailtoprotohandler'] = 'Kasuta mailto: linkide avamisel';
+$labels['standardwindows'] = 'Käsitle hüpikaknaid tavaliste akendena';
$labels['forwardmode'] = 'Kirja edastamine';
$labels['inline'] = 'kirja sees';
$labels['asattachment'] = 'manusena';
diff --git a/program/localization/et_EE/messages.inc b/program/localization/et_EE/messages.inc
index 653b48be5..4d58b0a75 100644
--- a/program/localization/et_EE/messages.inc
+++ b/program/localization/et_EE/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Andmebaasi tõrge!';
$messages['requesttimedout'] = 'Päring aegus';
$messages['errorreadonly'] = 'Operatsioon nurjus. Kaustale on vaid lugemisõigus';
$messages['errornoperm'] = 'Operatsioon nurjus. Ligipääsu õigused puuduvad';
+$messages['erroroverquota'] = 'Operatsioon nurjus. Ketas on täis.';
+$messages['erroroverquotadelete'] = 'Ketas on täis. Kirja kustutamiseks vajuta SHIFT+DEL.';
$messages['invalidrequest'] = 'Lubamatu päring! Andmeid ei salvestatud.';
$messages['invalidhost'] = 'Lubamatu serveri nimi.';
$messages['nomessagesfound'] = 'Postkast paistab tühi olevat';
@@ -124,6 +126,8 @@ $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 eb61f4c8c..fedce7de5 100644
--- a/program/localization/eu_ES/labels.inc
+++ b/program/localization/eu_ES/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Uneko orrialdea';
$labels['unread'] = 'Irakurri gabeak';
$labels['flagged'] = 'Banderaduna';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Ezabatuak';
$labels['undeleted'] = 'Ezabatu gabeak';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Azken sorta ikusi';
$labels['group'] = 'Group';
$labels['groups'] = 'Taldeak';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Helbide pertsonalak';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML mezuak sortu';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML sinadura';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Aurrebista panela ikusi';
$labels['skin'] = 'Azal-interfazea';
$labels['logoutclear'] = 'Garbitu Zakarronzia irtetean';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 118f53ff6..a3985b233 100644
--- a/program/localization/eu_ES/messages.inc
+++ b/program/localization/eu_ES/messages.inc
@@ -28,6 +28,8 @@ $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';
diff --git a/program/localization/fa_AF/labels.inc b/program/localization/fa_AF/labels.inc
index 6a4904d7e..38154c23c 100644
--- a/program/localization/fa_AF/labels.inc
+++ b/program/localization/fa_AF/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'نامه های ناتکمیل';
$labels['sent'] = 'ارسال شده';
$labels['trash'] = 'اشغال دانی';
$labels['junk'] = 'بیکاره';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'مضمون';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'ناخوانده';
$labels['flagged'] = 'نشانی شده';
$labels['unanswered'] = 'پیامهای جواب نداده شده';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'خلاصه';
$labels['empty'] = 'خالي';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = '‌طريقه استعمال ديسک';
$labels['unknown'] = 'نامعلوم';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'بازنشاندن جستجو';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'در پینجره ای جدید باز کنید';
$labels['emlsave'] = 'Download (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'بسته اخير را نشان دهيد';
$labels['group'] = 'Group';
$labels['groups'] = 'گروه ها';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ادرس های شخصي';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'پيغام ايچ ټي ام ايل رانوشته Ú©Ù†Ù
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'امضای حساب ایمیل بشکل ایچ تی ام ال';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'چوکات پیشنما را نشان دهید';
$labels['skin'] = 'تمپلیت محیط کاربری';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 aa479b9c6..4f3d4be55 100644
--- a/program/localization/fa_AF/messages.inc
+++ b/program/localization/fa_AF/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'هيچ پيغامی در اين صندوق پستي درياÙت نه شد';
diff --git a/program/localization/fa_IR/labels.inc b/program/localization/fa_IR/labels.inc
index 8bba66c26..79bfbbe9d 100644
--- a/program/localization/fa_IR/labels.inc
+++ b/program/localization/fa_IR/labels.inc
@@ -22,7 +22,7 @@ $labels = array();
$labels['welcome'] = 'به $product خوش آمدید';
$labels['username'] = 'نام کاربری';
$labels['password'] = 'گذرواژه';
-$labels['server'] = 'سرور';
+$labels['server'] = 'سرویس‌دهنده';
$labels['login'] = 'ورود';
// taskbar
@@ -34,9 +34,10 @@ $labels['addressbook'] = 'دÙتر نشانی';
// mailbox names
$labels['inbox'] = 'صندوق ورودی';
$labels['drafts'] = 'پیش‌نویس‌ها';
-$labels['sent'] = 'ارسال شده';
-$labels['trash'] = 'زباله‌دان';
+$labels['sent'] = 'Ùرستاده شده';
+$labels['trash'] = 'سطل آشغال';
$labels['junk'] = 'بنجل';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'موضوع';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'صÙحه جاری';
$labels['unread'] = 'خوانده‌نشده';
$labels['flagged'] = 'پرچم‌دار';
$labels['unanswered'] = 'پاسخ داده نشده';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'حذ٠شده';
$labels['undeleted'] = 'حذ٠نشده';
$labels['invert'] = 'وارونه';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'نوع مشاهده Ùهرست';
$labels['folderactions'] = 'اعمال پوشه...';
$labels['compact'] = 'Ùشرده';
$labels['empty'] = 'خالی';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ùضای استÙاده شده';
$labels['unknown'] = 'ناشناخته';
@@ -202,11 +205,12 @@ $labels['resetsearch'] = 'جستجوی دوباره';
$labels['searchmod'] = 'اصلاحات جستجو';
$labels['msgtext'] = 'کل پیغام';
$labels['body'] = 'بدنه';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'باز کردن در پنجره‌ی جدید';
$labels['emlsave'] = 'بارگیری (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'نمایش در قالب متنی';
+$labels['changeformathtml'] = 'نمایش در قالب اچ‌تی‌ام‌ال';
// message compose
$labels['editasnew'] = 'ویرایش به عنوان جدید';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'نمایش صÙحه آخر';
$labels['group'] = 'گروه';
$labels['groups'] = 'گروه‌ها';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'نشانی‌های شخصی';
$labels['searchsave'] = 'ذخیره جستجو';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML ‌نوشتن پیغام‌های';
$labels['htmlonreply'] = 'Ùقط در پاسخ به پیغام HTML';
$labels['htmlonreplyandforward'] = 'در بازگردانی یا پاسخ به پیغام‌های HTML';
$labels['htmlsignature'] = 'HTML امضای';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'نمایش قاب پیش‌نمایش';
$labels['skin'] = 'پوسته ظاهری';
$labels['logoutclear'] = 'تمیز کردن زباله دان هنگام برون‌رÙت';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'هنگام پاسخ امضاء اصلی را
$labels['autoaddsignature'] = 'اضاÙÙ‡ کردن خودکار امضاء';
$labels['newmessageonly'] = 'Ùقط پیغام جدید';
$labels['replyandforwardonly'] = 'Ùقط پاسخ‌ها Ùˆ ارجاع‌ها';
-$labels['replysignaturepos'] = 'هنگام پاسخ یا ارجاع امضاء را قرار داده شود';
-$labels['belowquote'] = 'زیر نقل‌قول';
-$labels['abovequote'] = 'بالای نقل‌قول';
$labels['insertsignature'] = 'درج امضاء';
$labels['previewpanemarkread'] = 'نشانه‌گذاری پیغام‌های پیش مرور شده به عنوان خوانده شده';
$labels['afternseconds'] = 'بعد از $s ثانیه';
@@ -473,6 +476,7 @@ $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 5db68b005..ff53c650e 100644
--- a/program/localization/fa_IR/messages.inc
+++ b/program/localization/fa_IR/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'خطای پایگاه‌داده';
$messages['requesttimedout'] = 'زمان درخواست تمام شد';
$messages['errorreadonly'] = 'ناتوانی در انجام عملیات. پوشه Ùقط خواندنی است.';
$messages['errornoperm'] = 'ناتوانی در انجام عملیات. دسترسی وجود ندارد.';
+$messages['erroroverquota'] = 'ناتوانی در انجام عملیات. Ùضای دیسک خالی نیست.';
+$messages['erroroverquotadelete'] = 'Ùضای دیسک خالی نیست. برای حذ٠پیغام از SHIFT+DEL استÙاده کنید.';
$messages['invalidrequest'] = 'درخواست نامعتبر! هیچ داده‌ای ذخیره نشد.';
$messages['invalidhost'] = 'نام سرور غیرمعتبر.';
$messages['nomessagesfound'] = 'هیچ پیغامی در این صندوق پیدا نشد.';
diff --git a/program/localization/fi_FI/labels.inc b/program/localization/fi_FI/labels.inc
index 62c2d6b07..ef0f0bff0 100644
--- a/program/localization/fi_FI/labels.inc
+++ b/program/localization/fi_FI/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Luonnokset';
$labels['sent'] = 'Lähetetyt';
$labels['trash'] = 'Roskakori';
$labels['junk'] = 'Roskaposti';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Aihe';
@@ -64,6 +65,7 @@ $labels['copy'] = 'Kopioi';
$labels['move'] = 'Siirrä';
$labels['moveto'] = 'siirrä kansioon...';
$labels['download'] = 'lataa';
+$labels['open'] = 'Avaa';
$labels['showattachment'] = 'Näytä';
$labels['showanyway'] = 'Näytä silti';
@@ -161,6 +163,7 @@ $labels['currpage'] = 'Nykyinen sivu';
$labels['unread'] = 'Lukemattomat';
$labels['flagged'] = 'Korostettu';
$labels['unanswered'] = 'Vastaamaton';
+$labels['withattachment'] = 'Liitteen kera';
$labels['deleted'] = 'Poistettu';
$labels['undeleted'] = 'Ei poistettu';
$labels['invert'] = 'Käännä';
@@ -191,6 +194,7 @@ $labels['listmode'] = 'Listausnäkymä';
$labels['folderactions'] = 'Kansiotoiminnot...';
$labels['compact'] = 'Tiivistä';
$labels['empty'] = 'Tyhjennä';
+$labels['importmessages'] = 'Tuo viestejä';
$labels['quota'] = 'Levytila';
$labels['unknown'] = 'tuntematon';
@@ -201,9 +205,12 @@ $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)';
+$labels['changeformattext'] = 'Näytä raakatekstimuodossa';
+$labels['changeformathtml'] = 'Näytä HTML-muodossa';
// message compose
$labels['editasnew'] = 'Muokkaa uutena';
@@ -241,9 +248,9 @@ $labels['nosubject'] = '(ei otsikkoa)';
$labels['showimages'] = 'Näytä kuvat';
$labels['alwaysshow'] = 'Näytä aina lähettäjältä $sender saapuneet kuvat';
$labels['isdraft'] = 'Tämä on luonnosviesti.';
-$labels['andnmore'] = '$nr more...';
+$labels['andnmore'] = '$nr lisää...';
$labels['togglemoreheaders'] = 'Näytä lisää viestiotsakkeita';
-$labels['togglefullheaders'] = 'Toggle raw message headers';
+$labels['togglefullheaders'] = 'Viestin otsakkeet päällä/pois';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Tavallinen teksti';
@@ -350,6 +357,7 @@ $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';
@@ -360,7 +368,7 @@ $labels['importcontacts'] = 'Tuo yhteystiedot';
$labels['importfromfile'] = 'Tuo tiedostosta:';
$labels['importtarget'] = 'Lisää uudet yhteystiedot osoitekirjaan:';
$labels['importreplace'] = 'Korvaa koko osoitekirja';
-$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['importdesc'] = 'Voit tuoda yhteystietoja olemassa olevasta osoitekirjasta.<br/>Tuettuja muotoja ovat <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> ja CSV (pilkuin erotetut arvot).';
$labels['done'] = 'Valmis';
// settings
@@ -396,8 +404,9 @@ $labels['showinextwin'] = 'Avaa viesti uudessa ikkunassa';
$labels['composeextwin'] = 'Lähetä viesti uudessa ikkunassa';
$labels['htmleditor'] = 'Kirjoita HTML-muodossa';
$labels['htmlonreply'] = 'Vain vastatessa HTML-viesteihin';
-$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
+$labels['htmlonreplyandforward'] = 'välittäessä tai vastatessa HTML-viestiin';
$labels['htmlsignature'] = 'HTML-allekirjoitus';
+$labels['showemail'] = 'Näytä sähköpostiosoite näyttönimen kanssa';
$labels['previewpane'] = 'Näytä esikatselulehti';
$labels['skin'] = 'Käyttöliittymän teema';
$labels['logoutclear'] = 'Tyhjennä roskakori kirjautuessa ulos';
@@ -451,9 +460,6 @@ $labels['replyremovesignature'] = 'Vastattaessa poista alkuperäinen allekirjoit
$labels['autoaddsignature'] = 'Lisää allekirjoitus automaattisesti';
$labels['newmessageonly'] = 'vain uuteen viestiin';
$labels['replyandforwardonly'] = 'vain vastauksiin ja välityksiin';
-$labels['replysignaturepos'] = 'Vastattaessa tai välitettäessä laita allekirjoitus';
-$labels['belowquote'] = 'lainauksen alle';
-$labels['abovequote'] = 'lainauksen ylle';
$labels['insertsignature'] = 'Lisää allekirjoitus';
$labels['previewpanemarkread'] = 'Merkitse esikatsellut viestit luetuiksi';
$labels['afternseconds'] = '$n sekunnin jälkeen';
@@ -470,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Jätä huomiotta sanat, joissa on numeroita';
$labels['spellcheckignorecaps'] = 'Jätä huomiotta sanat, joissa kaikki kirjaimet on isoja';
$labels['addtodict'] = 'Lisää sanakirjaan';
$labels['mailtoprotohandler'] = 'Rekisteröi mailto:-linkkien protokollakäsitteljä';
+$labels['standardwindows'] = 'Käsittele popup-ikkunoita tavallisina ikkunoina';
$labels['forwardmode'] = 'Viestin välitys';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'liitteenä';
diff --git a/program/localization/fr_FR/csv2vcard.inc b/program/localization/fr_FR/csv2vcard.inc
new file mode 100644
index 000000000..bb77001b5
--- /dev/null
+++ b/program/localization/fr_FR/csv2vcard.inc
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/<lang>/csv2vcard.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. |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+// This is a list of CSV column names specified in CSV file header
+// These must be original texts used in Outlook/Thunderbird exported csv files
+// Encoding UTF-8
+
+$map = array();
+
+// MS Outlook 2010
+$map['anniversary'] = "Anniversaire de mariage ou fête";
+$map['assistants_name'] = "Nom de l''assistant(e)";
+$map['assistants_phone'] = "Téléphone de l''assistant(e)";
+$map['birthday'] = "Anniversaire";
+$map['business_city'] = "Ville (bureau)";
+$map['business_countryregion'] = "Pays/Région (bureau)";
+$map['business_fax'] = "Télécopie (bureau)";
+$map['business_phone'] = "Téléphone (bureau)";
+$map['business_phone_2'] = "Téléphone 2 (bureau)";
+$map['business_postal_code'] = "Code postal (bureau)";
+$map['business_state'] = "Dép/Région (bureau)";
+$map['business_street'] = "Rue (bureau)";
+$map['car_phone'] = "Téléphone (voiture)";
+$map['categories'] = "Catégories";
+$map['company'] = "Société";
+$map['department'] = "Service";
+$map['email_address'] = "Adresse de messagerie";
+$map['first_name'] = "Prénom";
+$map['gender'] = "Sexe";
+$map['home_city'] = "Ville (domicile)";
+$map['home_countryregion'] = "Pays/Région (domicile)";
+$map['home_fax'] = "Télécopie (domicile)";
+$map['home_phone'] = "Téléphone (domicile)";
+$map['home_phone_2'] = "Téléphone 2 (domicile)";
+$map['home_postal_code'] = "Code postal (domicile)";
+$map['home_state'] = "Dép/Région (domicile)";
+$map['home_street'] = "Rue (domicile)";
+$map['job_title'] = "Profession";
+$map['last_name'] = "Nom";
+$map['managers_name'] = "Manager's Name";
+$map['middle_name'] = "Deuxième prénom";
+$map['mobile_phone'] = "Tél. mobile";
+$map['notes'] = "Notes";
+$map['other_city'] = "Ville (autre)";
+$map['other_countryregion'] = "Pays/Région (autre)";
+$map['other_fax'] = "Télécopie (autre)";
+$map['other_phone'] = "Téléphone (autre)";
+$map['other_postal_code'] = "Code postal (autre)";
+$map['other_state'] = "Dép/Région (autre)";
+$map['other_street'] = "Rue (autre)";
+$map['pager'] = "Récepteur de radiomessagerie";
+$map['primary_phone'] = "Téléphone principal";
+$map['spouse'] = "Conjoint(e)";
+$map['suffix'] = "Suffixe";
+$map['title'] = "Titre";
+$map['web_page'] = "Page Web";
+
+// Thunderbird
+$map['birth_day'] = "Jour";
+$map['birth_month'] = "Mois";
+$map['birth_year'] = "Année de naissance";
+$map['display_name'] = "Nom à afficher";
+$map['fax_number'] = "Fax";
+$map['home_address'] = "Adresse privée";
+$map['home_country'] = "Région";
+$map['home_zipcode'] = "Code postal";
+$map['mobile_number'] = "Portable";
+$map['nickname'] = "Surnom";
+$map['organization'] = "Société";
+$map['pager_number'] = "Pager";
+$map['primary_email'] = "Adresse électronique principale";
+$map['secondary_email'] = "Adresse électronique secondaire";
+$map['web_page_1'] = "Site Web 1";
+$map['web_page_2'] = "Site Web 2";
+$map['work_phone'] = "Tél. professionnel";
+$map['work_address'] = "Adresse professionnelle";
+$map['work_country'] = "Région";
+$map['work_zipcode'] = "Code postal";
+
+// Other
+$map['_home_city'] = "Ville";
diff --git a/program/localization/fr_FR/labels.inc b/program/localization/fr_FR/labels.inc
index 4a78e565f..2a4f3a169 100644
--- a/program/localization/fr_FR/labels.inc
+++ b/program/localization/fr_FR/labels.inc
@@ -26,9 +26,9 @@ $labels['server'] = 'Serveur';
$labels['login'] = 'Connexion';
// taskbar
-$labels['logout'] = 'Quitter';
+$labels['logout'] = 'Déconnexion';
$labels['mail'] = 'Courriel';
-$labels['settings'] = 'Préférences';
+$labels['settings'] = 'Paramètres';
$labels['addressbook'] = 'Carnet d\'adresses';
// mailbox names
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Brouillons';
$labels['sent'] = 'Messages envoyés';
$labels['trash'] = 'Corbeille';
$labels['junk'] = 'Indésirables';
+$labels['show_real_foldernames'] = 'Montrer les noms réels pour les dossiers spéciaux';
// message listing
$labels['subject'] = 'Objet';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Copier';
$labels['move'] = 'Déplacer';
$labels['moveto'] = 'Déplacer vers...';
$labels['download'] = 'Télécharger';
-$labels['open'] = 'Open';
+$labels['open'] = 'Ouvrir';
$labels['showattachment'] = 'Afficher';
$labels['showanyway'] = 'Afficher quand même';
@@ -127,7 +128,7 @@ $labels['checkmail'] = 'Vérification des nouveaux messages';
$labels['compose'] = 'Composer un nouveau message';
$labels['writenewmessage'] = 'Écrire un nouveau message';
$labels['reply'] = 'Répondre';
-$labels['replytomessage'] = 'Répondre au message';
+$labels['replytomessage'] = 'Répondre à l\'expéditeur';
$labels['replytoallmessage'] = 'Répondre à tous';
$labels['replyall'] = 'Répondre à tous';
$labels['replylist'] = 'Répondre à la liste';
@@ -143,13 +144,13 @@ $labels['firstmessage'] = 'Voir le premier message';
$labels['nextmessage'] = 'Voir le message suivant';
$labels['lastmessage'] = 'Voir le dernier message';
$labels['backtolist'] = 'Retourner à la liste des messages';
-$labels['viewsource'] = 'Voir le source';
+$labels['viewsource'] = 'Voir la source';
$labels['mark'] = 'Marquer';
$labels['markmessages'] = 'Marquer les messages';
-$labels['markread'] = 'Comme lus';
-$labels['markunread'] = 'Comme non lus';
-$labels['markflagged'] = 'Comme suivi';
-$labels['markunflagged'] = 'Comme non-suivi';
+$labels['markread'] = 'Comme lu(s)';
+$labels['markunread'] = 'Comme non lu(s)';
+$labels['markflagged'] = 'Comme suivi(s)';
+$labels['markunflagged'] = 'Comme non-suivi(s)';
$labels['moreactions'] = 'Plus d\'actions...';
$labels['more'] = 'Plus';
$labels['back'] = 'Retour';
@@ -159,18 +160,19 @@ $labels['select'] = 'Sélectionner';
$labels['all'] = 'Tous';
$labels['none'] = 'Aucun';
$labels['currpage'] = 'Page courante';
-$labels['unread'] = 'Non lus';
-$labels['flagged'] = 'Marqué';
-$labels['unanswered'] = 'Non répondu';
-$labels['deleted'] = 'Supprimé';
-$labels['undeleted'] = 'Non supprimé';
+$labels['unread'] = 'Non lu(s)';
+$labels['flagged'] = 'Marqué(s)';
+$labels['unanswered'] = 'Non répondu(s)';
+$labels['withattachment'] = 'Avec pièce jointe';
+$labels['deleted'] = 'Supprimé(s)';
+$labels['undeleted'] = 'Non supprimé(s)';
$labels['invert'] = 'Inverser';
$labels['filter'] = 'Filtre';
$labels['list'] = 'Lister';
$labels['threads'] = 'Sujets';
-$labels['expand-all'] = 'Afficher Tous';
-$labels['expand-unread'] = 'Afficher Non-lus';
-$labels['collapse-all'] = 'Fermer Tous';
+$labels['expand-all'] = 'Tout afficher';
+$labels['expand-unread'] = 'Afficher non-lu(s)';
+$labels['collapse-all'] = 'Fermer tous';
$labels['threaded'] = 'Par sujet';
$labels['autoexpand_threads'] = 'Développer les sujets';
@@ -189,9 +191,10 @@ $labels['listsorting'] = 'Colonne de tri';
$labels['listorder'] = 'Ordre de tri';
$labels['listmode'] = 'Mode d\'affichage de la liste';
-$labels['folderactions'] = 'Actions du dossier';
+$labels['folderactions'] = 'Actions du dossier...';
$labels['compact'] = 'Compacter';
$labels['empty'] = 'Vider';
+$labels['importmessages'] = 'Importer des messages';
$labels['quota'] = 'Occupation disque';
$labels['unknown'] = 'inconnue';
@@ -202,17 +205,18 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Afficher au format texte';
+$labels['changeformathtml'] = 'Afficher au format HTML';
// message compose
$labels['editasnew'] = 'Éditer en tant que nouveau message';
$labels['send'] = 'Envoyer';
-$labels['sendmessage'] = 'Envoyer';
-$labels['savemessage'] = 'Enregistrer';
+$labels['sendmessage'] = 'Envoyer un message';
+$labels['savemessage'] = 'Sauvegarder comme brouillon';
$labels['addattachment'] = 'Joindre un fichier';
$labels['charset'] = 'Encodage';
$labels['editortype'] = 'Type d\'éditeur';
@@ -222,14 +226,14 @@ $labels['mailreplyintro'] = 'Le $date, $sender a écrit :';
$labels['originalmessage'] = 'Message original';
$labels['editidents'] = 'Modifier les identités';
-$labels['spellcheck'] = 'Vérifier l\'orthographe';
+$labels['spellcheck'] = 'Orthographe';
$labels['checkspelling'] = 'Vérifier l\'orthographe';
$labels['resumeediting'] = 'Retourner à l\'édition';
$labels['revertto'] = 'Revenir à';
$labels['attach'] = 'Joindre';
$labels['attachments'] = 'Fichiers joints';
-$labels['upload'] = 'Joindre';
+$labels['upload'] = 'Transférer';
$labels['uploadprogress'] = '$percent ($current sur $total)';
$labels['close'] = 'Fermer';
$labels['messageoptions'] = 'Options du message';
@@ -249,7 +253,7 @@ $labels['togglemoreheaders'] = 'Afficher plus d\'en-têtes du message';
$labels['togglefullheaders'] = 'Afficher/Cacher l\'entête du message';
$labels['htmltoggle'] = 'HTML';
-$labels['plaintoggle'] = 'texte brut';
+$labels['plaintoggle'] = 'Texte brut';
$labels['savesentmessagein'] = 'Enregistrer le message envoyé dans';
$labels['dontsave'] = 'ne pas enregistrer';
$labels['maxuploadsize'] = 'La taille maximum autorisée pour un fichier est $size';
@@ -263,7 +267,7 @@ $labels['addfollowupto'] = 'Ajouter Faire suivre à';
$labels['mdnrequest'] = 'L\'expéditeur de ce message a demandé d\'être prévenu quand vous lirez ce message. Souhaitez-vous prévenir l\'expéditeur ?';
$labels['receiptread'] = 'Accusé de réception (lu)';
$labels['yourmessage'] = 'Ceci est un accusé de réception pour votre message';
-$labels['receiptnote'] = 'Note : Cet accusé de réception indique seulement que le message a été affiché sur l\'ordinateur du destinataire. Il n\'y a aucune garantie que le destinataire a lu ou compris le contenu du message.';
+$labels['receiptnote'] = 'Note : Cet accusé de réception indique seulement que le message a été affiché sur l\'ordinateur du destinataire. Il n\'y a aucune garantie que le destinataire ait lu ou compris le contenu du message.';
// address boook
$labels['name'] = 'Nom à afficher';
@@ -274,9 +278,9 @@ $labels['nameprefix'] = 'Préfixe';
$labels['namesuffix'] = 'Suffixe';
$labels['nickname'] = 'Surnom';
$labels['jobtitle'] = 'Fonction';
-$labels['department'] = 'Département';
+$labels['department'] = 'Service';
$labels['gender'] = 'Sexe';
-$labels['maidenname'] = 'Nom de naissance';
+$labels['maidenname'] = 'Nom de jeune fille';
$labels['email'] = 'Courriel';
$labels['phone'] = 'Téléphone';
$labels['address'] = 'Adresse';
@@ -317,7 +321,7 @@ $labels['typeblog'] = 'Blog';
$labels['typeprofile'] = 'Profil';
$labels['addfield'] = 'Ajouter un champ...';
-$labels['addcontact'] = 'Ajouter le contact sélectionné à votre Carnet d\'adresses';
+$labels['addcontact'] = 'Ajouter le contact sélectionné à votre carnet d\'adresses';
$labels['editcontact'] = 'Modifier le contact';
$labels['contacts'] = 'Contacts';
$labels['contactproperties'] = 'Propriétés du contact';
@@ -330,7 +334,7 @@ $labels['delete'] = 'Supprimer';
$labels['rename'] = 'Renommer';
$labels['addphoto'] = 'Ajouter';
$labels['replacephoto'] = 'Remplacer';
-$labels['uploadphoto'] = 'Envoyer une photo';
+$labels['uploadphoto'] = 'Transférer une photo';
$labels['newcontact'] = 'Créer un nouveau contact';
$labels['deletecontact'] = 'Supprimer les contacts sélectionnés';
@@ -344,7 +348,7 @@ $labels['exportvcards'] = 'Exporter les contacts au format vCard';
$labels['newcontactgroup'] = 'Créer un nouveau groupe de contacts';
$labels['grouprename'] = 'Renommer le groupe';
$labels['groupdelete'] = 'Supprimer le groupe';
-$labels['groupremoveselected'] = 'Retiré les contacts sélectionnés du groupe';
+$labels['groupremoveselected'] = 'Retirer les contacts sélectionnés du groupe';
$labels['previouspage'] = 'Montrer page précédente';
$labels['firstpage'] = 'Voir la première page';
@@ -353,6 +357,7 @@ $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';
@@ -361,9 +366,9 @@ $labels['searchdelete'] = 'Supprimer la recherche';
$labels['import'] = 'Importer';
$labels['importcontacts'] = 'Importer les contacts';
$labels['importfromfile'] = 'Importer depuis un fichier :';
-$labels['importtarget'] = 'Ajouter de nouveaux contact au carnet d’adresse :';
-$labels['importreplace'] = 'Remplacer le carnet d\'adresse entier';
-$labels['importdesc'] = 'Vous pouvez télécharger des contacts à partir d\'un carnet d\'adresses existant.<br/>Nous supportons actuellement l\'importation d\'adresses à partir des format de données <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> ou CSV (comma -séparés).';
+$labels['importtarget'] = 'Ajouter de nouveaux contact au carnet d’adresses :';
+$labels['importreplace'] = 'Remplacer le carnet d\'adresses entier';
+$labels['importdesc'] = 'Vous pouvez transférer des contacts à partir d\'un carnet d\'adresses existant.<br/>Nous supportons actuellement l\'importation d\'adresses à partir des format de données <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> ou CSV (champs séparés par une virgule).';
$labels['done'] = 'Terminé';
// settings
@@ -401,12 +406,13 @@ $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['previewpane'] = 'Afficher le panneau d\'aperçu';
$labels['skin'] = 'Thème de l\'interface';
$labels['logoutclear'] = 'Vider la corbeille à la déconnexion';
$labels['logoutcompact'] = 'Compacter la boite de réception à la déconnexion';
$labels['uisettings'] = 'Interface utilisateur';
-$labels['serversettings'] = 'Préférences du serveur';
+$labels['serversettings'] = 'Paramètres du serveur';
$labels['mailboxview'] = 'Vue du courrier';
$labels['mdnrequests'] = 'Notifications à l\'expéditeur';
$labels['askuser'] = 'demander à l\'utilisateur';
@@ -450,29 +456,27 @@ $labels['whenreplying'] = 'En répondant';
$labels['replyempty'] = 'Ne pas citer le message original';
$labels['replytopposting'] = 'commencer le nouveau message au-dessus de l\'original';
$labels['replybottomposting'] = 'commencer le nouveau message en-dessous de l\'original';
-$labels['replyremovesignature'] = 'En répondant, supprimer la signature d\'origine du message';
+$labels['replyremovesignature'] = 'Supprimer la signature d\'origine du message lors de la réponse';
$labels['autoaddsignature'] = 'Ajouter la signature automatiquement';
$labels['newmessageonly'] = 'nouveau message uniquement';
$labels['replyandforwardonly'] = 'réponses et transferts uniquement';
-$labels['replysignaturepos'] = 'En répondant ou en transférant, placer la signature';
-$labels['belowquote'] = 'en-dessous de la citation';
-$labels['abovequote'] = 'au-dessus de la citation';
$labels['insertsignature'] = 'Insérer la signature';
$labels['previewpanemarkread'] = 'Marquer les messages prévisualisés comme lus';
$labels['afternseconds'] = 'après $n secondes';
$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\'adresse par défaut';
-$labels['autocompletesingle'] = 'Ne pas tenir compte des adresses emails alternatives dans l\'autoremplissage';
+$labels['defaultabook'] = 'Carnet d\'adresses par défaut';
+$labels['autocompletesingle'] = 'Ne pas tenir compte des adresses de courriel alternatives dans l\'autoremplissage';
$labels['listnamedisplay'] = 'Lister les contacts comme';
-$labels['spellcheckbeforesend'] = 'Vérifier l’orthographe avant l’envoie d’un message';
+$labels['spellcheckbeforesend'] = 'Vérifier l’orthographe avant l’envoi 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';
$labels['spellcheckignorecaps'] = 'Ignorer les mots entièrement en majuscule';
$labels['addtodict'] = 'Ajouter au dictionnaire';
$labels['mailtoprotohandler'] = 'Enregistrer le gestionnaire de protocole pour les liens mailto:';
+$labels['standardwindows'] = 'Manipuler les menus surgissants comme des fenêtres standards';
$labels['forwardmode'] = 'Transfert des messages';
$labels['inline'] = 'dans le corps';
$labels['asattachment'] = 'en pièce jointe';
@@ -508,7 +512,7 @@ $labels['plugin'] = 'Plugin';
$labels['version'] = 'Version';
$labels['source'] = 'Source';
$labels['license'] = 'Licence';
-$labels['support'] = 'Support';
+$labels['support'] = 'Obtenir un support technique';
// units
$labels['B'] = 'o';
diff --git a/program/localization/fr_FR/messages.inc b/program/localization/fr_FR/messages.inc
index bd3fd2094..a736e103e 100644
--- a/program/localization/fr_FR/messages.inc
+++ b/program/localization/fr_FR/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Erreur avec la base de donnée!';
$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['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.';
diff --git a/program/localization/fy_NL/labels.inc b/program/localization/fy_NL/labels.inc
index d04d7e89c..5ffd906eb 100644
--- a/program/localization/fy_NL/labels.inc
+++ b/program/localization/fy_NL/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $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';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $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';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 1dacf4adc..16f4c67bf 100644
--- a/program/localization/fy_NL/messages.inc
+++ b/program/localization/fy_NL/messages.inc
@@ -2,15 +2,172 @@
/*
+-----------------------------------------------------------------------+
- | localization/fy_NL/messages.inc |
+ | localization/<lang>/messages.inc |
| |
- | Language file of the Roundcube Webmail client |
- | Copyright (C) 2012, The Roundcube Dev Team |
- | Licensed under the GNU General Public License |
+ | 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. |
| |
+-----------------------------------------------------------------------+
- | Author: unknown |
- +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/messages/
*/
-$messages = array(); \ No newline at end of file
+$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.';
+
+?>
diff --git a/program/localization/ga_IE/labels.inc b/program/localization/ga_IE/labels.inc
index 7169a8800..9fffaf42a 100755
--- a/program/localization/ga_IE/labels.inc
+++ b/program/localization/ga_IE/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Na rudaí nach bhuil corraithe';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Scríobh teachtaireachta HTML';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Mana clabhsúir HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Taispeáin an pána réamhamharc';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 140b88639..70aa28a36 100755
--- a/program/localization/ga_IE/messages.inc
+++ b/program/localization/ga_IE/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Ní bhfuair mé aon teachtaireacht i bosca postas seo';
diff --git a/program/localization/gl_ES/labels.inc b/program/localization/gl_ES/labels.inc
index 13fdfa793..c624c462e 100644
--- a/program/localization/gl_ES/labels.inc
+++ b/program/localization/gl_ES/labels.inc
@@ -37,11 +37,12 @@ $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';
$labels['from'] = 'Remitente';
-$labels['sender'] = 'Sender';
+$labels['sender'] = 'Remitente';
$labels['to'] = 'Destinatario';
$labels['cc'] = 'Copia (Cc)';
$labels['bcc'] = 'Copia oculta (Cco)';
@@ -58,15 +59,15 @@ $labels['mailboxlist'] = 'Cartafoles';
$labels['messagesfromto'] = 'Mensaxes da $from á $to de $count';
$labels['threadsfromto'] = 'Fíos do $from ao $to de $count';
$labels['messagenrof'] = 'Mensaxe $nr de $count';
-$labels['fromtoshort'] = '$from – $to of $count';
+$labels['fromtoshort'] = '$from - $to de $count';
$labels['copy'] = 'Copiar';
$labels['move'] = 'Mover';
$labels['moveto'] = 'Mover a...';
$labels['download'] = 'Descargar';
-$labels['open'] = 'Open';
-$labels['showattachment'] = 'Show';
-$labels['showanyway'] = 'Show it anyway';
+$labels['open'] = 'Abrir';
+$labels['showattachment'] = 'Amosar';
+$labels['showanyway'] = 'Amosala de tódolos xeitos';
$labels['filename'] = 'Nome de ficheiro';
$labels['filesize'] = 'Tamaño de ficheiro';
@@ -131,7 +132,7 @@ $labels['replytomessage'] = 'Respostar a mensaxe';
$labels['replytoallmessage'] = 'Respostar á lista ou ao remitente e a tódolos destinatarios';
$labels['replyall'] = 'Respostar a todos';
$labels['replylist'] = 'Respostar á lista de correo';
-$labels['forward'] = 'Forward';
+$labels['forward'] = 'Reenviar';
$labels['forwardinline'] = 'Reenviar inserido';
$labels['forwardattachment'] = 'Reenviar como anexo';
$labels['forwardmessage'] = 'Reenviar a mensaxe';
@@ -144,7 +145,7 @@ $labels['nextmessage'] = 'Amosar a seguinte mensaxe';
$labels['lastmessage'] = 'Amosar a última mensaxe';
$labels['backtolist'] = 'Voltar á lista de mensaxes';
$labels['viewsource'] = 'Ver código fonte';
-$labels['mark'] = 'Mark';
+$labels['mark'] = 'Marcar';
$labels['markmessages'] = 'Marcar mensaxes';
$labels['markread'] = 'Como lidas';
$labels['markunread'] = 'Como non lidas';
@@ -162,8 +163,9 @@ $labels['currpage'] = 'Páxina actual';
$labels['unread'] = 'Non lidas';
$labels['flagged'] = 'Marcadas';
$labels['unanswered'] = 'Non respostadas';
+$labels['withattachment'] = 'Con anexo';
$labels['deleted'] = 'Marcadas como eliminadas';
-$labels['undeleted'] = 'Not deleted';
+$labels['undeleted'] = 'Non borradas';
$labels['invert'] = 'Inverter';
$labels['filter'] = 'Filtrar';
$labels['list'] = 'Lista';
@@ -192,6 +194,7 @@ $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';
@@ -201,16 +204,17 @@ $labels['quicksearch'] = 'Busca rápida';
$labels['resetsearch'] = 'Restablecer a busca';
$labels['searchmod'] = 'Modificadores de busca';
$labels['msgtext'] = 'Mensaxe enteira';
-$labels['body'] = 'Body';
+$labels['body'] = 'Corpo';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir nunha nova fiestra';
$labels['emlsave'] = 'Gardar (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Amosar en texto plano';
+$labels['changeformathtml'] = 'Amosar en HTML';
// message compose
$labels['editasnew'] = 'Editar como nova';
-$labels['send'] = 'Send';
+$labels['send'] = 'Enviar';
$labels['sendmessage'] = 'Enviar a mensaxe agora';
$labels['savemessage'] = 'Gardar a mensaxe como borrador';
$labels['addattachment'] = 'Anexar un ficheiro';
@@ -222,12 +226,12 @@ $labels['mailreplyintro'] = 'O $date, $sender escribiu:';
$labels['originalmessage'] = 'Mensaxe orixinal';
$labels['editidents'] = 'Modificar identidades';
-$labels['spellcheck'] = 'Spell';
+$labels['spellcheck'] = 'Ortografía';
$labels['checkspelling'] = 'Revisar a ortografía';
$labels['resumeediting'] = 'Voltar á edición';
$labels['revertto'] = 'Voltar a';
-$labels['attach'] = 'Attach';
+$labels['attach'] = 'Anexar';
$labels['attachments'] = 'Ficheiros anexos';
$labels['upload'] = 'Cargar';
$labels['uploadprogress'] = '$percent ($current de $total)';
@@ -244,9 +248,9 @@ $labels['nosubject'] = '(Sen asunto)';
$labels['showimages'] = 'Amosar as imaxes';
$labels['alwaysshow'] = 'Amosar sempre as imaxes nas mensaxes de $sender';
$labels['isdraft'] = 'Esta mensaxe é un borrador';
-$labels['andnmore'] = '$nr more...';
-$labels['togglemoreheaders'] = 'Show more message headers';
-$labels['togglefullheaders'] = 'Toggle raw message headers';
+$labels['andnmore'] = '$nr máis...';
+$labels['togglemoreheaders'] = 'Amosar máis cabecerias';
+$labels['togglefullheaders'] = 'Conmutar cabeceiras en bruto';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Só texto';
@@ -338,13 +342,13 @@ $labels['composeto'] = 'Redactar mensaxe para';
$labels['contactsfromto'] = 'Contactos do $from ao $to de $count';
$labels['print'] = 'Imprimir';
$labels['export'] = 'Exportar';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Exportar todas';
+$labels['exportsel'] = 'Exportar as seleccionadas';
$labels['exportvcards'] = 'Exportar os contactos en formato vCard';
$labels['newcontactgroup'] = 'Crear novo grupo de contactos';
$labels['grouprename'] = 'Mudar o nome do grupo';
$labels['groupdelete'] = 'Borrar o grupo';
-$labels['groupremoveselected'] = 'Remove selected contacts from group';
+$labels['groupremoveselected'] = 'Eliminar do grupo os contactos seleccionados';
$labels['previouspage'] = 'Amosar o grupo anterior';
$labels['firstpage'] = 'Amosar o primeiro grupo';
@@ -353,6 +357,7 @@ $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';
@@ -363,7 +368,7 @@ $labels['importcontacts'] = 'Importar contactos';
$labels['importfromfile'] = 'Importar desde ficheiro:';
$labels['importtarget'] = 'Engadir contactos ao caderno de enderezos:';
$labels['importreplace'] = 'Substituír completamente o caderno de enderezos';
-$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['importdesc'] = 'Pode cargar contactos desde un caderno de enderezos preexistente.<br/>Pódense importar enderezos en formato <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> ou CSV (valores separados por comas)';
$labels['done'] = 'Rematado';
// settings
@@ -383,8 +388,8 @@ $labels['edititem'] = 'Editar';
$labels['preferhtml'] = 'Prefiro HTML';
$labels['defaultcharset'] = 'Xogo de caracteres por omisión';
$labels['htmlmessage'] = 'Mensaxe HTML';
-$labels['messagepart'] = 'Part';
-$labels['digitalsig'] = 'Digital Signature';
+$labels['messagepart'] = 'Parte';
+$labels['digitalsig'] = 'Sinatura dixital';
$labels['dateformat'] = 'Formato da data';
$labels['timeformat'] = 'Formato da hora';
$labels['prettydate'] = 'Data decorada';
@@ -395,12 +400,13 @@ $labels['timezone'] = 'Zona horaria';
$labels['pagesize'] = 'Liñas por páxina';
$labels['signature'] = 'Sinatura';
$labels['dstactive'] = 'Cambio de hora según horario de verán';
-$labels['showinextwin'] = 'Open message in a new window';
-$labels['composeextwin'] = 'Compose in a new window';
+$labels['showinextwin'] = 'Abrir a mensaxe nunha nova xanela';
+$labels['composeextwin'] = 'Redactar nunha xanela nova';
$labels['htmleditor'] = 'Redactar mensaxes HTML';
$labels['htmlonreply'] = 'só cando se resposte a unha mensaxe HTML';
-$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
+$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['previewpane'] = 'Amosar previsualización';
$labels['skin'] = 'Aspecto da interface';
$labels['logoutclear'] = 'Baleirar o cubo do lixo ao saír';
@@ -418,14 +424,14 @@ $labels['readwhendeleted'] = 'Marcar a mensaxe como lida ao eliminar';
$labels['flagfordeletion'] = 'Marcar a mensaxe para eliminar no canto de eliminar';
$labels['skipdeleted'] = 'Non amosar as mensaxes marcadas como eliminadas';
$labels['deletealways'] = 'Eliminar as mensaxes aínda que non se poidan gardar no cubo do lixo';
-$labels['deletejunk'] = 'Directly delete messages in Junk';
+$labels['deletejunk'] = 'Borrar automáticamente as mensaxes no cartafol "Correo lixo"';
$labels['showremoteimages'] = 'Amosar as imaxes remotas';
$labels['fromknownsenders'] = 'de remitentes coñecidos';
$labels['always'] = 'sempre';
$labels['showinlineimages'] = 'Amosar as imaxes anexas baixo a mensaxe';
$labels['autosavedraft'] = 'Gardar borrador automáticamente';
$labels['everynminutes'] = 'cada $n minuto(s)';
-$labels['refreshinterval'] = 'Refresh (check for new messages, etc.)';
+$labels['refreshinterval'] = 'Refrescar (buscar novas mensaxes, etc)';
$labels['never'] = 'nunca';
$labels['immediately'] = 'de inmediato';
$labels['messagesdisplaying'] = 'Visualización das mensaxes';
@@ -447,35 +453,33 @@ $labels['maintenance'] = 'Mantemento';
$labels['newmessage'] = 'Mensaxes novas';
$labels['signatureoptions'] = 'Opcións da firma';
$labels['whenreplying'] = 'Ao respostar';
-$labels['replyempty'] = 'do not quote the original message';
+$labels['replyempty'] = 'non citar a mensaxe orixinal';
$labels['replytopposting'] = 'comezar a nova mensaxe enriba da orixinal';
$labels['replybottomposting'] = 'comezar a nova mensaxe embaixo da orixinal';
$labels['replyremovesignature'] = 'Eliminar a firma do remitente ao respostar';
$labels['autoaddsignature'] = 'Engadir firma automáticamente';
$labels['newmessageonly'] = 'só nas mensaxes novas';
$labels['replyandforwardonly'] = 'só nas respostas e reenvíos';
-$labels['replysignaturepos'] = 'Ao respostar ou reenviar colocar a firma';
-$labels['belowquote'] = 'embaixo do texto citado';
-$labels['abovequote'] = 'enriba do texto citado';
$labels['insertsignature'] = 'Engadir firma';
$labels['previewpanemarkread'] = 'Marcar como lidas as mensaxes previsualizadas';
$labels['afternseconds'] = 'logo de $n segundos';
$labels['reqmdn'] = 'Solicitar sempre unha notificación da entrega';
$labels['reqdsn'] = 'Solicitar sempre unha notificación do estado de envío';
$labels['replysamefolder'] = 'Deixar as respostas no cartafol onde está a mensaxe á que se responde';
-$labels['defaultabook'] = 'Default address book';
+$labels['defaultabook'] = 'Caderno de enderezos por defecto';
$labels['autocompletesingle'] = 'Ignorar as direccións alternativas no autocompletado';
-$labels['listnamedisplay'] = 'List contacts as';
+$labels['listnamedisplay'] = 'Listar os contactos coma';
$labels['spellcheckbeforesend'] = 'Revisar a ortografía antes de enviar unha mensaxe';
$labels['spellcheckoptions'] = 'Opción da revisión ortográfica';
$labels['spellcheckignoresyms'] = 'Ignorar as palabras con símbolos';
$labels['spellcheckignorenums'] = 'Ignorar as palabras con números';
$labels['spellcheckignorecaps'] = 'Ignorar as palabras escritas en maiúsculas';
$labels['addtodict'] = 'Engadir ao diccionario';
-$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['forwardmode'] = 'Messages forwarding';
-$labels['inline'] = 'inline';
-$labels['asattachment'] = 'as attachment';
+$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';
$labels['folder'] = 'Cartafol';
$labels['folders'] = 'Cartafoles';
@@ -503,7 +507,7 @@ $labels['sortasc'] = 'Orde ascendente';
$labels['sortdesc'] = 'Orde descendente';
$labels['undo'] = 'Desfacer';
-$labels['installedplugins'] = 'Installed plugins';
+$labels['installedplugins'] = 'Complementos instalados';
$labels['plugin'] = 'Complemento';
$labels['version'] = 'Versión';
$labels['source'] = 'Fonte';
diff --git a/program/localization/gl_ES/messages.inc b/program/localization/gl_ES/messages.inc
index 6f230bc89..8fc2cb424 100644
--- a/program/localization/gl_ES/messages.inc
+++ b/program/localization/gl_ES/messages.inc
@@ -17,7 +17,7 @@
*/
$messages = array();
-$messages['errortitle'] = 'An error occurred!';
+$messages['errortitle'] = 'Ocurreu un erro!';
$messages['loginfailed'] = 'O contrasinal ou o nome de usuario son incorrectos.';
$messages['cookiesdisabled'] = 'O seu navegador non acepta galletas.';
$messages['sessionerror'] = 'A súa sesión non é válida ou expirou.';
@@ -25,15 +25,17 @@ $messages['storageerror'] = 'Fallou a conexión co servidor IMAP.';
$messages['servererror'] = 'Erro do servidor!';
$messages['servererrormsg'] = 'Erro do servidor: $msg';
$messages['dberror'] = 'Erro na base de datos!';
-$messages['requesttimedout'] = 'Request timed out';
+$messages['requesttimedout'] = 'A petición expirou';
$messages['errorreadonly'] = 'Non foi posible realizar a operación. O cartafol é de só lectura.';
$messages['errornoperm'] = 'Non foi posible realizar a operación. Permiso denegado.';
+$messages['erroroverquota'] = 'Non se pode realizar a operación, non hai espacio no disco.';
+$messages['erroroverquotadelete'] = 'Non hai espacio no disco. Utilice Maiúsculas+Supr para borrar unha mensaxe.';
$messages['invalidrequest'] = 'Petición inválida!. Non se gardou ningún dato.';
-$messages['invalidhost'] = 'Invalid server name.';
+$messages['invalidhost'] = 'O nome do servidor non é válido.';
$messages['nomessagesfound'] = 'Non se atoparon mensaxes nesta caixa de correo.';
$messages['loggedout'] = 'Rematou correctamente a súa sesión. Ata logo!';
$messages['mailboxempty'] = 'A caixa de correo está vacía.';
-$messages['refreshing'] = 'Refreshing...';
+$messages['refreshing'] = 'A refrescar...';
$messages['loading'] = 'Cargando...';
$messages['uploading'] = 'Cargando ficheiro...';
$messages['uploadingmany'] = 'Cargando ficheiros...';
@@ -112,18 +114,20 @@ $messages['addingmember'] = 'Engadindo o(s) contacto(s) ao grupo...';
$messages['removingmember'] = 'Eliminando o(s) contacto(s) do grupo...';
$messages['receiptsent'] = 'A notificación da entrega enviouse correctamente.';
$messages['errorsendingreceipt'] = 'Non foi posible enviar a notificación da entrega.';
-$messages['deleteidentityconfirm'] = 'Do you really want to delete this identity?';
+$messages['deleteidentityconfirm'] = 'Quere eliminar esta identidade?';
$messages['nodeletelastidentity'] = 'Non pode eliminar esta identidade, é a última.';
$messages['forbiddencharacter'] = 'O nome do cartafol contén un carácter non válido.';
$messages['selectimportfile'] = 'Por favor, escolla un ficheiro para cargar.';
$messages['addresswriterror'] = 'Non se pode escribir no caderno de enderezos que escolleu.';
$messages['contactaddedtogroup'] = 'Engadiuse correctamente o contacto a este grupo.';
$messages['contactremovedfromgroup'] = 'Suprimiuse correctamente o contacto deste grupo.';
-$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$messages['nogroupassignmentschanged'] = 'Non cambiou ningunha asignación de grupo.';
$messages['importwait'] = 'A importar. Por favor, agarde...';
-$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
+$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?';
@@ -162,8 +166,8 @@ $messages['foldercreated'] = 'O cartafol creouse correctamente.';
$messages['invalidimageformat'] = 'O formato da imaxe non é válido.';
$messages['mispellingsfound'] = 'Atopáronse erros ortográficos na mensaxe.';
$messages['parentnotwritable'] = 'Non foi posible crear/mover o cartafol no cartafol padre escollido porque non ten permisos.';
-$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['messagetoobig'] = 'A mensaxe é demasiado grande para procesala';
+$messages['attachmentvalidationerror'] = 'ATENCIÓN! Este anexo é sospeitoso porque o seu tipo non coincide o tipo declarado na mensaxe. Se non confía no remitente, non debería abrilo, porque podería conter un virus ou malware.<br/><br/><em>Tipo agardado: $expected; Tipo detectado: $detected</em>';
+$messages['noscriptwarning'] = 'Atención: Este servicio de correo web precisa de Javascript!. Por favor, active javascript nas opción do seu navegador.';
?>
diff --git a/program/localization/he_IL/labels.inc b/program/localization/he_IL/labels.inc
index 698b73493..7ad04ab4a 100644
--- a/program/localization/he_IL/labels.inc
+++ b/program/localization/he_IL/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'טיוטות';
$labels['sent'] = 'נשלח';
$labels['trash'] = '×שפה';
$labels['junk'] = 'זבל';
+$labels['show_real_foldernames'] = 'הצגת שמות ××ž×™×ª×™×™× ×©×œ תיקיות מיוחדות';
// message listing
$labels['subject'] = 'נוש×';
@@ -133,7 +134,7 @@ $labels['replyall'] = 'מענה לכול×';
$labels['replylist'] = 'מענה לרשימת תפוצה';
$labels['forward'] = 'העברה';
$labels['forwardinline'] = 'העבר בגוף ההודעה';
-$labels['forwardattachment'] = 'העבר כקובץ מצורף';
+$labels['forwardattachment'] = 'העבר כצרופה';
$labels['forwardmessage'] = 'העבר הודעה';
$labels['deletemessage'] = 'מחיקה';
$labels['movemessagetotrash'] = 'השלכה ל×שפה';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'דף נוכחי';
$labels['unread'] = '×œ× × ×§×¨×ו';
$labels['flagged'] = 'מסומן';
$labels['unanswered'] = '×œ× × ×¢× ×”';
+$labels['withattachment'] = '×¢× ×¦×¨×•×¤×”';
$labels['deleted'] = 'נמחק';
$labels['undeleted'] = '×œ× × ×ž×—×§';
$labels['invert'] = 'היפוך הסימון';
@@ -192,6 +194,7 @@ $labels['listmode'] = '×ופן הצגת רשימה';
$labels['folderactions'] = 'פעולות על תיקי×';
$labels['compact'] = 'פינוי שטח ×œ× ×ž× ×•×¦×œ';
$labels['empty'] = 'ריקון';
+$labels['importmessages'] = '×™×™×‘×•× ×”×•×“×¢×•×ª';
$labels['quota'] = 'ניצול קיבולת';
$labels['unknown'] = '×œ× ×™×“×•×¢';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'ניקוי תיבת החיפוש';
$labels['searchmod'] = 'מ×פייני חיפוש';
$labels['msgtext'] = 'כל ההודעה';
$labels['body'] = 'גוף ההודעה';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'פתיחה בחלון חדש';
$labels['emlsave'] = 'הורדת הודעה בפורמט EML';
@@ -228,7 +232,7 @@ $labels['resumeediting'] = 'המשך עריכה';
$labels['revertto'] = 'חזור למצב קוד×';
$labels['attach'] = 'צירוף';
-$labels['attachments'] = '×§×‘×¦×™× ×ž×¦×•×¨×¤×™×';
+$labels['attachments'] = 'צרופות';
$labels['upload'] = 'העל××”';
$labels['uploadprogress'] = '( $total מתוך $current ) $percent';
$labels['close'] = 'סגירה';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'הצגת הקבוצה ×”×חרונה';
$labels['group'] = 'קבוצה';
$labels['groups'] = 'קבוצות';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'כתובות פרטיות';
$labels['searchsave'] = 'שמירת החיפוש';
@@ -403,6 +408,7 @@ $labels['htmleditor'] = 'יצירת הודעה מעוצבת';
$labels['htmlonreply'] = 'רק במענה להודעת HTML';
$labels['htmlonreplyandforward'] = 'להעביר ×ו להשיב להודעה שהגיעה בפורמט HTML';
$labels['htmlsignature'] = 'חתימה מעוצבת';
+$labels['showemail'] = 'הצגת כתובת דו×"ל ×¢× ×©× ×”×©×•×œ×—';
$labels['previewpane'] = 'תצוגה מוקדמת';
$labels['skin'] = 'ערכת מר××”';
$labels['logoutclear'] = 'ריקון סל ×שפה ביצי××”';
@@ -456,9 +462,6 @@ $labels['replyremovesignature'] = 'החתימה תוסר מההודעה המקו
$labels['autoaddsignature'] = 'הוספה ×וטומטית של חתימה';
$labels['newmessageonly'] = 'הודעה חדשה בלבד';
$labels['replyandforwardonly'] = 'מענה והעברת הודעה בלבד';
-$labels['replysignaturepos'] = 'במענה ×ו בהעברת הודעה, החתימה תופיע';
-$labels['belowquote'] = 'בסוף ההודעה המקורית';
-$labels['abovequote'] = 'בתחילת ההודעה המקורית';
$labels['insertsignature'] = 'שיבוץ חתימה';
$labels['previewpanemarkread'] = 'סימון הודעה שנצפתה כנקר××”';
$labels['afternseconds'] = 'ל×חר $n שניות';
@@ -475,6 +478,7 @@ $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 be4ef2824..37ebcea01 100644
--- a/program/localization/he_IL/messages.inc
+++ b/program/localization/he_IL/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = '! שגי××” במסד הנתוני×';
$messages['requesttimedout'] = '×ª× ×”×–×ž×Ÿ המוקצב לבקשה';
$messages['errorreadonly'] = '×œ× × ×™×ª×Ÿ לבצע הפעולה ×›×™ התיק ניתן לקרי××” בלבד';
$messages['errornoperm'] = '×œ× × ×™×ª×Ÿ לבצע הפעולה ×›×™ ×ין הרש××” לבצעה';
+$messages['erroroverquota'] = '×œ× × ×™×ª×Ÿ לבצע הפעולה ×›×™ ×œ× ×ž×§×•× ×¤× ×•×™ על הדיסק';
+$messages['erroroverquotadelete'] = '×ין ×ž×§×•× ×¤× ×•×™ על הדיסק. יש להשתמש ב SHIFT+DELETE כדי למחוק ההודעה';
$messages['invalidrequest'] = 'בקשה ×œ× ×—×•×§×™×ª. המידע ×œ× × ×©×ž×¨';
$messages['invalidhost'] = '×©× ×©×¨×ª ×œ× ×—×•×§×™';
$messages['nomessagesfound'] = '×œ× × ×ž×¦×ו הודעות בתיבה זו';
@@ -124,6 +126,8 @@ $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 4564e1226..303e0b5fb 100644
--- a/program/localization/hi_IN/labels.inc
+++ b/program/localization/hi_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'डà¥à¤°à¤¾à¤«à¤¼à¤Ÿ';
$labels['sent'] = 'भेजा गया';
$labels['trash'] = 'रदà¥à¤¦à¥€';
$labels['junk'] = 'सà¥à¤ªà¥ˆà¤®';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विशय';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'अनदेखी';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'छोटा करें';
$labels['empty'] = 'मेल रदà¥à¤¦à¥€ में डालें';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤• उपयोग';
$labels['unknown'] = 'अजà¥à¤žà¤¾à¤¤';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'आखिरी बनà¥à¤¡à¤² दिखाà¤à¤‚'
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'मेल à¤à¤š-टी-à¤à¤®-à¤à¤² (HTML) मे ल
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'à¤à¤š-टी-à¤à¤®-à¤à¤² (HTML) दसà¥à¤¤à¤–त';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'à¤à¤²à¤• पटà¥à¤Ÿà¥€ दिखाà¤à¤‚';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 328dbe00e..1d55f5c48 100644
--- a/program/localization/hi_IN/messages.inc
+++ b/program/localization/hi_IN/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'इस मेलबॉकà¥à¤¸ में कोई मेल नहीं है';
diff --git a/program/localization/hr_HR/labels.inc b/program/localization/hr_HR/labels.inc
index bf5364653..4578fed2b 100644
--- a/program/localization/hr_HR/labels.inc
+++ b/program/localization/hr_HR/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Trenutna stranica';
$labels['unread'] = 'NeproÄitane';
$labels['flagged'] = 'OznaÄene';
$labels['unanswered'] = 'Neodgovrene';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Obrisano';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Obrni';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Zadnja strana';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupe';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Privatna adresa';
$labels['searchsave'] = 'Pohrani pretragu';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Sastavi HTML poruke';
$labels['htmlonreply'] = 'odgovor samo na HTML poruke';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML potpis';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Prikaži podruÄje pregleda';
$labels['skin'] = 'Tema izgleda';
$labels['logoutclear'] = 'OÄisti smeće pri izlazu';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Kod odgovaranja, makni originalni potpis iz p
$labels['autoaddsignature'] = 'Automatski dodaj potpis';
$labels['newmessageonly'] = 'samo nova poruka';
$labels['replyandforwardonly'] = 'samo odgovori i proslijeđivanja';
-$labels['replysignaturepos'] = 'Kod downloada ili proslijeđivanja postavi potpis';
-$labels['belowquote'] = 'ispod citata';
-$labels['abovequote'] = 'iznad citata';
$labels['insertsignature'] = 'Umetni potpis';
$labels['previewpanemarkread'] = 'Obilježi pregledane poruke kao proÄitane';
$labels['afternseconds'] = 'nakon $n sekundi';
@@ -473,6 +476,7 @@ $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 c3a4f1779..3e6cc6daf 100644
--- a/program/localization/hr_HR/messages.inc
+++ b/program/localization/hr_HR/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Greška baze podataka!';
$messages['requesttimedout'] = 'Request timed out';
$messages['errorreadonly'] = 'Nemoguća izvedba operacije. Mapa je samo za Äitanje.';
$messages['errornoperm'] = 'Nemoguća izvedba operacije. Dozvola odbijena.';
+$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'] = 'Nepravilan zahtijev! Podaci nisu spremljeni.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'Nema poruka u sanduÄiću';
diff --git a/program/localization/hu_HU/labels.inc b/program/localization/hu_HU/labels.inc
index 96c43d146..abdc7e891 100644
--- a/program/localization/hu_HU/labels.inc
+++ b/program/localization/hu_HU/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Másolás';
$labels['move'] = 'Ãthelyezés';
$labels['moveto'] = 'Ãthelyezés...';
$labels['download'] = 'letöltés';
-$labels['open'] = 'Open';
+$labels['open'] = 'Megnyítás';
$labels['showattachment'] = 'Megjelenítés';
$labels['showanyway'] = 'Megjelnités mindenképpen';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Aktuális oldal';
$labels['unread'] = 'Olvasatlan';
$labels['flagged'] = 'Megjelölt';
$labels['unanswered'] = 'Megválaszolatlan';
+$labels['withattachment'] = 'Csatolmánnyal';
$labels['deleted'] = 'Törölt';
$labels['undeleted'] = 'Nem lett törölve';
$labels['invert'] = 'Invertálás';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Megjelenítés sima szöveges formátumban';
+$labels['changeformathtml'] = 'Megjelenítés HTML formátumban';
// message compose
$labels['editasnew'] = 'Szerkesztés újként';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML üzenet írása';
$labels['htmlonreply'] = 'csak HTML üzenetre válaszolva';
$labels['htmlonreplyandforward'] = 'HTML üzenet továbbításakor vagy az arra való válaszoláskor';
$labels['htmlsignature'] = 'HTML aláírás';
+$labels['showemail'] = 'Az email címek megjelenítése a partner nevével';
$labels['previewpane'] = 'Előnézeti kép';
$labels['skin'] = 'Kinézet';
$labels['logoutclear'] = 'Törölt elemek mappa ürítése kilépéskor';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Válasznál az eredeti aláírás eltávolít
$labels['autoaddsignature'] = 'Aláírás automatikus hozzáadása';
$labels['newmessageonly'] = 'csak új üzenetnél';
$labels['replyandforwardonly'] = 'válasznál és továbbításnál';
-$labels['replysignaturepos'] = 'Válasznál és továbbításnál kerüljön az aláírás';
-$labels['belowquote'] = 'az idézett szöveg alá';
-$labels['abovequote'] = 'az idézett szöveg fölé';
$labels['insertsignature'] = 'Aláírás beillesztése';
$labels['previewpanemarkread'] = 'Előnézetben megjelent üzenetek megjelölése olvasottként';
$labels['afternseconds'] = '$n másodperc elteltével';
@@ -473,6 +476,7 @@ $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 ee3e8a9a5..6528602a4 100644
--- a/program/localization/hu_HU/messages.inc
+++ b/program/localization/hu_HU/messages.inc
@@ -17,7 +17,7 @@
*/
$messages = array();
-$messages['errortitle'] = 'Hiba történt';
+$messages['errortitle'] = 'Hiba történt!';
$messages['loginfailed'] = 'Sikertelen bejelentkezés.';
$messages['cookiesdisabled'] = 'A böngésző nem támogatja a sütik használatát';
$messages['sessionerror'] = 'Érvénytelen vagy lejárt munkamenet';
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Adatbázishiba!';
$messages['requesttimedout'] = 'A kérés túllépte az időkorlátot';
$messages['errorreadonly'] = 'A műveletet nem sikerült végrehajtani. A mappa írásvédett.';
$messages['errornoperm'] = 'A műveletet nem sikerült végrehajtani. Hozzáférés megtagadva.';
+$messages['erroroverquota'] = 'A műveletet nem lehetett végrehajtani mivel nincs elég szabad hely a merevlemezen.';
+$messages['erroroverquotadelete'] = 'Nincs elég szabad hely a merevlemezen. A SHIFT+DEL billenytyű kombinációt használd az üzenet törléséhez.';
$messages['invalidrequest'] = 'Érvénytelen kérés! Az adatok nem lettek elmentve.';
$messages['invalidhost'] = 'Hibás szerver hoszt név';
$messages['nomessagesfound'] = 'A fiók nem tartalmaz leveleket';
diff --git a/program/localization/hy_AM/labels.inc b/program/localization/hy_AM/labels.inc
index 3612dc974..8ee9316c4 100644
--- a/program/localization/hy_AM/labels.inc
+++ b/program/localization/hy_AM/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'ÕÖ‡Õ¡Õ£Ö€Õ¥Ö€';
$labels['sent'] = 'ÕˆÖ‚Õ²Õ¡Ö€Õ¯Õ¾Õ¡Õ®';
$labels['trash'] = 'Ô±Õ²Õ¢Õ¡Ö€Õ¯Õ²';
$labels['junk'] = 'Ô¹Õ¡ÖƒÕ¸Õ¶';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÕŽÕ¥Ö€Õ¶Õ¡Õ£Õ«Ö€';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Ô±Õ¼Õ¯Õ¡ Õ§Õ»';
$labels['unread'] = 'Õ‰Õ¯Õ¡Ö€Õ¤Õ¡ÖÕ¡Õ®Õ¨';
$labels['flagged'] = 'Õ†Õ·Õ¾Õ¡Õ®';
$labels['unanswered'] = 'Ô±Õ¶ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Õ‹Õ¶Õ»Õ¾Õ¡Õ®';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Õ“Õ¸Õ­Õ¡Õ¿Õ¥Õ²Õ¥Õ¬';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¯Õ¸Õ¾ Õ¿Õ¥Õ½Ö„Õ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨';
$labels['folderactions'] = 'Պանակի գործողություններ…';
$labels['compact'] = 'ÕÕ¥Õ²Õ´Õ¥Õ¬';
$labels['empty'] = 'Ô´Õ¡Õ¿Õ¡Ö€Õ¯Õ¥Õ¬';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ô´Õ«Õ½Õ¯Õ¡ÕµÕ«Õ¶ Õ¿Õ¡Ö€Õ¡Õ®Ö„';
$labels['unknown'] = 'Õ¡Õ¶Õ°Õ¡ÕµÕ¿';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'ÕŽÕ¥Ö€Õ½Õ¯Õ½Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ¸Ö‚Õ´Õ¨';
$labels['searchmod'] = 'ÕˆÖ€Õ¸Õ¶Õ´Õ¡Õ¶ ÖƒÕ¸ÖƒÕ¸Õ­Õ«Õ¹Õ¶Õ¥Ö€';
$labels['msgtext'] = 'ÕˆÕ²Õ» Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ô²Õ¡ÖÕ¥Õ¬ Õ¶Õ¸Ö€ ÕºÕ¡Õ¿Õ¸Ö‚Õ°Õ¡Õ¶Õ¸Ö‚Õ´';
$labels['emlsave'] = 'Õ†Õ¥Ö€Õ¢Õ¥Õ¼Õ¶Õ¥Õ¬ (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»Õ¨';
$labels['group'] = 'Ô½Õ¸Ö‚Õ´Õ¢';
$labels['groups'] = 'Ô½Õ´Õ¢Õ¥Ö€';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Ô±Õ¶Õ±Õ¶Õ¡Õ¯Õ¡Õ¶ Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€';
$labels['searchsave'] = 'ÕŠÕ¡Õ°ÕºÕ¡Õ¶Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ¸Ö‚Õ´Õ¨';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'ÕÕ¿Õ¥Õ²Õ®Õ¥Õ¬ HTML Õ¶Õ¡Õ´Õ¡Õ¯Õ¶Õ¥Ö€';
$labels['htmlonreply'] = 'Õ´Õ«Õ¡ÕµÕ¶ HTML Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶Õ¨ ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬Õ«Õ½';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ ÕºÕ¡Õ¿Õ¸Ö‚Õ°Õ¡Õ¶Õ¨';
$labels['skin'] = 'ÕÕ¥Õ½Ö„Õ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯';
$labels['logoutclear'] = 'Ô´Õ¸Ö‚Ö€Õ½ Õ£Õ¡Õ¬Õ¸Ö‚Ö Õ¤Õ¡Õ¿Õ¡Ö€Õ¯Õ¥Õ¬ Õ¡Õ²Õ¢Õ¡Ö€Õ¯Õ²Õ¨';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'ÕŠÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬Õ«Õ½ Õ°Õ¥Õ¼Õ¡ÖÕ¶Õ¥Õ¬ Õ°Õ
$labels['autoaddsignature'] = 'Ô±Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶';
$labels['newmessageonly'] = 'Õ´Õ«Õ¡ÕµÕ¶ Õ¶Õ¸Ö€ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¸Ö‚Õ´';
$labels['replyandforwardonly'] = 'ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¶Õ¥Ö€Õ¸Ö‚Õ´ Ö‡ ÖƒÕ¸Õ­Õ¡Õ¶ÖÕ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¸Ö‚Õ´';
-$labels['replysignaturepos'] = 'Ô±Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬Õ«Õ½ Õ¯Õ¡Õ´ ÖƒÕ¸Õ­Õ¡Õ¶ÖÕ¥Õ¬Õ«Õ½';
-$labels['belowquote'] = 'Õ„Õ¥Õ»Õ¢Õ¥Ö€Õ´Õ¡Õ¶ Õ¶Õ¥Ö€Ö„Ö‡Õ¸Ö‚Õ´';
-$labels['abovequote'] = 'Õ„Õ¥Õ»Õ¢Õ¥Ö€Õ´Õ¡Õ¶ Õ¾Õ¥Ö€Ö‡Õ¸Ö‚Õ´';
$labels['insertsignature'] = 'Õ†Õ¥Ö€Õ¤Õ¶Õ¥Õ¬ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨';
$labels['previewpanemarkread'] = 'Õ†Õ·Õ¥Õ¬ Õ¶Õ¡Õ­Õ¡Õ¤Õ«Õ¿Õ¾Õ¡Õ® Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ Õ¸Ö€ÕºÕ¥Õ½ Õ¨Õ¶Õ©Õ¥Ö€ÖÕ¾Õ¡Õ®';
$labels['afternseconds'] = '$n Õ¾Õ¡Ö€Õ¯ÕµÕ¡Õ¶ Õ°Õ¥Õ¿Õ¸';
@@ -473,6 +476,7 @@ $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 bbb083a21..6b3f4ebe9 100644
--- a/program/localization/hy_AM/messages.inc
+++ b/program/localization/hy_AM/messages.inc
@@ -28,6 +28,8 @@ $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['invalidrequest'] = 'ÕÕ­Õ¡Õ¬ Õ°Õ¡Ö€ÖÕ¸Ö‚Õ´, Õ¡ÕºÕ¡Ö€Õ¤ÕµÕ¸Ö‚Õ¶Ö‰';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'Ô±ÕµÕ½ ÖƒÕ¸Õ½Õ¿Õ¡Ö€Õ¯Õ²Õ¸Ö‚Õ´ Õ¶Õ¡Õ´Õ¡Õ¯Õ¶Õ¥Ö€ Õ¹Õ¯Õ¡Õ¶';
diff --git a/program/localization/ia/labels.inc b/program/localization/ia/labels.inc
index 89273c147..1cd614d35 100644
--- a/program/localization/ia/labels.inc
+++ b/program/localization/ia/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Non legite';
$labels['flagged'] = 'Marcate';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Delete';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Inverter';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Gruppo';
$labels['groups'] = 'Gruppos';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adresses personal';
$labels['searchsave'] = 'Salveguardar cerca';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Compose HTML messages';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Signatura HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Show preview pane';
$labels['skin'] = 'Apparentia de interfacie';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$labels['autoaddsignature'] = 'Automaticamente inserta signatura';
$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'] = 'Insertar signatura';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = 'after $n seconds';
@@ -473,6 +476,7 @@ $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 fca8404b2..ebc6953d2 100644
--- a/program/localization/ia/messages.inc
+++ b/program/localization/ia/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Error de base de datos!';
$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.';
diff --git a/program/localization/id_ID/labels.inc b/program/localization/id_ID/labels.inc
index 4877434ed..73bb0156d 100644
--- a/program/localization/id_ID/labels.inc
+++ b/program/localization/id_ID/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Halaman sekarang';
$labels['unread'] = 'Belum terbaca';
$labels['flagged'] = 'Ditandai';
$labels['unanswered'] = 'Belum terjawab';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Terhapus';
$labels['undeleted'] = 'Tidak terhapus';
$labels['invert'] = 'Sebaliknya';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'Atur ulang pencarian';
$labels['searchmod'] = 'Peubah pencarian';
$labels['msgtext'] = 'Seluruh pesan';
$labels['body'] = 'Badan';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Buka dalam jendela baru';
$labels['emlsave'] = 'Unduh (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Perlihatkan himpunan terakhir';
$labels['group'] = 'Kelompok';
$labels['groups'] = 'Kelompok';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Alamat pribadi';
$labels['searchsave'] = 'Simpan pencarian';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Tulis pesan HTML';
$labels['htmlonreply'] = 'balasan untuk pesan HTML saja';
$labels['htmlonreplyandforward'] = 'ketika meneruskan atau membalas pesan HTML';
$labels['htmlsignature'] = 'Tandatangan HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Unjuk pratinjau';
$labels['skin'] = 'Tampilan antarmuka';
$labels['logoutclear'] = 'Bersihkan Tong Sampah saat keluar';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'ketika membalas pesan hapus tanda tangan dari
$labels['autoaddsignature'] = 'Otomatis tambahkan tanda tangan';
$labels['newmessageonly'] = 'Hanya untuk pesan baru';
$labels['replyandforwardonly'] = 'Hanya untuk dijawab dan diteruskan';
-$labels['replysignaturepos'] = 'ketika membalas atau meneruskan pesan tambahkan tanda tangan';
-$labels['belowquote'] = 'Dibawah kutipan';
-$labels['abovequote'] = 'Diatas kutipan';
$labels['insertsignature'] = 'Isi tanda tangan';
$labels['previewpanemarkread'] = 'Tandai pesan yang sudah dilihat';
$labels['afternseconds'] = 'setelah $n detik';
@@ -473,6 +476,7 @@ $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 b604d0242..04d8242ad 100644
--- a/program/localization/id_ID/messages.inc
+++ b/program/localization/id_ID/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Basis data Error!';
$messages['requesttimedout'] = 'Permintaan melewati batas waktu';
$messages['errorreadonly'] = 'Tidak bisa melakukan operasi. Folder hanya bisa dibaca.';
$messages['errornoperm'] = 'Tidak bisa melakukan operasi. Ijin ditolak.';
+$messages['erroroverquota'] = 'Tidak dapat melakukan operasi. Disk penuh.';
+$messages['erroroverquotadelete'] = 'Disk penuh. Tekan SHIFT + DEL untuk menghapus pesan';
$messages['invalidrequest'] = 'Permintaan tidak valid! Tidak ada data yang tersimpan.';
$messages['invalidhost'] = 'Nama server invalid.';
$messages['nomessagesfound'] = 'Surat tidak ditemukan di kotak masuk ini';
diff --git a/program/localization/index.inc b/program/localization/index.inc
index bfb770cac..4b848dc49 100644
--- a/program/localization/index.inc
+++ b/program/localization/index.inc
@@ -70,6 +70,7 @@ $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 (മലയാളം)',
@@ -133,6 +134,7 @@ $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 c8d49bf23..c2859ce75 100644
--- a/program/localization/is_IS/labels.inc
+++ b/program/localization/is_IS/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Núverandi síða';
$labels['unread'] = 'Ólesið';
$labels['flagged'] = 'Flaggað';
$labels['unanswered'] = 'Ósvarað';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Eytt';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Umhverfa';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Skrifa HTML-skeyti';
$labels['htmlonreply'] = 'sem svar við HTML-skeytum aðeins';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML-undirskrift';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Sýna forskoðunarglugga';
$labels['skin'] = 'Sniðmát á viðmóti';
$labels['logoutclear'] = 'Tæma rusl við útskráningu';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Þegar svarað fjarlægja upphaflega undirskr
$labels['autoaddsignature'] = 'Bæta undirskrift við sjálfkrafa';
$labels['newmessageonly'] = 'ný skeyti eingöngu';
$labels['replyandforwardonly'] = 'svör og áframsendingar eingöngu';
-$labels['replysignaturepos'] = 'Þegar skeytum er svarað eða áframsend setja undirskrift';
-$labels['belowquote'] = 'undir tilvitnun';
-$labels['abovequote'] = 'fyrir ofan tilvitnun';
$labels['insertsignature'] = 'Bæta undirskrift við';
$labels['previewpanemarkread'] = 'Merka forskoðuð skeyti sem lesin';
$labels['afternseconds'] = 'eftir $n sekúndur';
@@ -473,6 +476,7 @@ $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 530e8008f..6e9f35af3 100644
--- a/program/localization/is_IS/messages.inc
+++ b/program/localization/is_IS/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Engin skeyti eru í þessu pósthólfi';
diff --git a/program/localization/it_IT/labels.inc b/program/localization/it_IT/labels.inc
index 97be929cf..55cd432f7 100644
--- a/program/localization/it_IT/labels.inc
+++ b/program/localization/it_IT/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Pagina corrente';
$labels['unread'] = 'Non letti';
$labels['flagged'] = 'Contrassegnato';
$labels['unanswered'] = 'Senza risposta';
+$labels['withattachment'] = 'Con allegato';
$labels['deleted'] = 'Cancellato';
$labels['undeleted'] = 'Non eliminato';
$labels['invert'] = 'Inverti';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Visualizza nel formato testo semplice';
+$labels['changeformathtml'] = 'Visualizza nel formato HTML';
// message compose
$labels['editasnew'] = 'Modifica come nuovo';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Ultima pagina';
$labels['group'] = 'Gruppo';
$labels['groups'] = 'Gruppi';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Rubrica Personale';
$labels['searchsave'] = 'Salva ricerca';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Scrivi i messaggi in HTML';
$labels['htmlonreply'] = 'solo in risposta a messaggi HTML';
$labels['htmlonreplyandforward'] = 'su inoltro o risposta a messaggi HTML';
$labels['htmlsignature'] = 'Firma in HTML';
+$labels['showemail'] = 'Visualizza indirizzi email con il nome visualizzato';
$labels['previewpane'] = 'Mostra l\'anteprima';
$labels['skin'] = 'Tema interfaccia';
$labels['logoutclear'] = 'Svuota il Cestino all\'uscita';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Quando rispondi, rimuovi la firma dal messagg
$labels['autoaddsignature'] = 'Aggiungi automaticamente la firma';
$labels['newmessageonly'] = 'solo ai nuovi messaggi';
$labels['replyandforwardonly'] = 'solo alle risposte e inoltri';
-$labels['replysignaturepos'] = 'In risposta o inoltro, posiziona la firma';
-$labels['belowquote'] = 'sotto la citazione';
-$labels['abovequote'] = 'sopra la citazione';
$labels['insertsignature'] = 'Inserisci firma';
$labels['previewpanemarkread'] = 'Segna i messagi in anteprima come letti';
$labels['afternseconds'] = 'dopo $n secondi';
@@ -473,6 +476,7 @@ $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 66c248e74..80395b551 100644
--- a/program/localization/it_IT/messages.inc
+++ b/program/localization/it_IT/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Errore del database!';
$messages['requesttimedout'] = 'Richiesta scaduta';
$messages['errorreadonly'] = 'Impossibile eseguire l\'operazione. Cartella in sola lettura';
$messages['errornoperm'] = 'Impossibile eseguire l\'operazione. Permesso negato';
+$messages['erroroverquota'] = 'Impossibile eseguire l\'operazione. Spazio su disco non sufficiente.';
+$messages['erroroverquotadelete'] = 'Spazio su disco non sufficiente. Utilizza SHIFT+CANC per eliminare un messaggio.';
$messages['invalidrequest'] = 'Richiesta non valida! Nessun dato salvato.';
$messages['invalidhost'] = 'Nome del server non valido.';
$messages['nomessagesfound'] = 'Nessun messaggio trovato in questa cartella';
diff --git a/program/localization/ja_JP/labels.inc b/program/localization/ja_JP/labels.inc
index 685dba0b3..767aff23a 100644
--- a/program/localization/ja_JP/labels.inc
+++ b/program/localization/ja_JP/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = '下書ã';
$labels['sent'] = 'é€ä¿¡æ¸ˆã¿';
$labels['trash'] = 'ã”ã¿ç®±';
$labels['junk'] = '迷惑メール';
+$labels['show_real_foldernames'] = '特殊フォルダーã®å®Ÿéš›ã®åå‰ã‚’表示';
// message listing
$labels['subject'] = '件å';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'ç¾åœ¨ã®ãƒšãƒ¼ã‚¸';
$labels['unread'] = '未読';
$labels['flagged'] = 'フラグ付ã';
$labels['unanswered'] = '未返信';
+$labels['withattachment'] = '添付ファイルã‚ã‚Š';
$labels['deleted'] = '削除済ã¿';
$labels['undeleted'] = '削除済ã¿ã§ãªã„';
$labels['invert'] = 'å転';
@@ -192,6 +194,7 @@ $labels['listmode'] = '一覧表示モード';
$labels['folderactions'] = 'フォルダーã®æ“作...';
$labels['compact'] = '圧縮';
$labels['empty'] = '空';
+$labels['importmessages'] = 'メッセージをインãƒãƒ¼ãƒˆ';
$labels['quota'] = 'ディスクã®ä½¿ç”¨çŠ¶æ³';
$labels['unknown'] = 'ä¸æ˜Ž';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = '検索を解除';
$labels['searchmod'] = '検索ã®æ¡ä»¶';
$labels['msgtext'] = 'メッセージ全体';
$labels['body'] = '本文';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'æ–°ã—ã„ウィンドウã§é–‹ã';
$labels['emlsave'] = 'ダウンロード(.emlå½¢å¼)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = '最後ã®ãƒšãƒ¼ã‚¸ã‚’表示';
$labels['group'] = 'グループ';
$labels['groups'] = 'グループ';
+$labels['listgroup'] = 'グループã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’一覧';
$labels['personaladrbook'] = '個人ã®ä½æ‰€';
$labels['searchsave'] = '検索情報をä¿å­˜';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = '作æˆæ™‚ã«HTMLメッセージを使用';
$labels['htmlonreply'] = '返信時ã«HTMLメッセージを使用';
$labels['htmlonreplyandforward'] = '転é€ã¾ãŸã¯HTMLメッセージã¸ã®è¿”ä¿¡';
$labels['htmlsignature'] = 'HTMLã®ç½²å';
+$labels['showemail'] = 'é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’表示åã¨å…±ã«è¡¨ç¤º';
$labels['previewpane'] = 'プレビュー枠ã®è¡¨ç¤º';
$labels['skin'] = 'インターフェイスã®ã‚¹ã‚­ãƒ³';
$labels['logoutclear'] = 'ログアウト時ã«ã”ã¿ç®±ã®å†…容を消去';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = '返信時ã«å…ƒã®ç½²åをメッセージã‹
$labels['autoaddsignature'] = '自動的ã«ç½²åを付加';
$labels['newmessageonly'] = 'æ–°ã—ã„メッセージã ã‘';
$labels['replyandforwardonly'] = '返信ã¨è»¢é€ã ã‘';
-$labels['replysignaturepos'] = '返信や転é€ã§ç½²åを挿入ã™ã‚‹ä½ç½®';
-$labels['belowquote'] = '引用ã®å¾Œ';
-$labels['abovequote'] = '引用ã®å‰';
$labels['insertsignature'] = 'ç½²åを挿入';
$labels['previewpanemarkread'] = 'プレビューã—ãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’既読ã«è¨­å®š';
$labels['afternseconds'] = '$n秒後';
@@ -473,6 +476,7 @@ $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 6c6008a55..f4dd0fceb 100644
--- a/program/localization/ja_JP/messages.inc
+++ b/program/localization/ja_JP/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'データベースã®ã‚¨ãƒ©ãƒ¼ã§ã™!';
$messages['requesttimedout'] = 'リクエストã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆ';
$messages['errorreadonly'] = 'æ“作を実行ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚フォルダーã¯èª­ã¿è¾¼ã¿å°‚用ã§ã™ã€‚';
$messages['errornoperm'] = 'æ“作を実行ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚権é™ãŒã‚ã‚Šã¾ã›ã‚“。';
+$messages['erroroverquota'] = 'æ“作を実行ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚空ãディスク容é‡ãŒã‚ã‚Šã¾ã›ã‚“。';
+$messages['erroroverquotadelete'] = '空ãディスク容é‡ãŒã‚ã‚Šã¾ã›ã‚“。メッセージを削除ã™ã‚‹ã«ã¯ SHIFT+DEL を使用ã—ã¦ãã ã•ã„。';
$messages['invalidrequest'] = 'ä¸æ­£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆã§ã™! データã¯ä¿å­˜ã—ã¦ã„ã¾ã›ã‚“。';
$messages['invalidhost'] = 'æ­£ã—ããªã„サーãƒãƒ¼åã§ã™ã€‚';
$messages['nomessagesfound'] = 'ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã«ã¯ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯ã‚ã‚Šã¾ã›ã‚“。';
diff --git a/program/localization/ka_GE/labels.inc b/program/localization/ka_GE/labels.inc
index b3a712515..b0126c44e 100755
--- a/program/localization/ka_GE/labels.inc
+++ b/program/localization/ka_GE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'დრáƒáƒ”ბითი';
$labels['sent'] = 'გáƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜';
$labels['trash'] = 'წáƒáƒ¨áƒšáƒ˜áƒšáƒ˜';
$labels['junk'] = 'სპáƒáƒ›áƒ˜';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'სáƒáƒ—áƒáƒ£áƒ áƒ˜';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'მიმდინáƒáƒ áƒ” გვერდი';
$labels['unread'] = 'წáƒáƒ£áƒ™áƒ˜áƒ—ხáƒáƒ•áƒ˜';
$labels['flagged'] = 'მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜';
$labels['unanswered'] = 'უპáƒáƒ¡áƒ£áƒ®áƒ';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'წáƒáƒ¨áƒšáƒ˜áƒšáƒ˜';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'შებრუნებული';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'შეკუმშვáƒ';
$labels['empty'] = 'გáƒáƒªáƒáƒ áƒ˜áƒ”ლებáƒ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'შეზღუდვáƒ';
$labels['unknown'] = 'უცნáƒáƒ‘ი';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'ძიების გáƒáƒ¡áƒ£áƒ¤áƒ—áƒáƒ•áƒ”ბáƒ'
$labels['searchmod'] = 'ძებნის ვáƒáƒ áƒ˜áƒáƒœáƒ¢áƒ”ბი';
$labels['msgtext'] = 'ყველრშეტყáƒáƒ‘ინებáƒ';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'გáƒáƒ®áƒ¡áƒœáƒ áƒáƒ®áƒáƒš ფáƒáƒœáƒ¯áƒáƒ áƒáƒ¨áƒ˜';
$labels['emlsave'] = 'გáƒáƒ“მáƒáƒ¬áƒ”რრ(.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'ბáƒáƒšáƒáƒ¡ ჩვენებáƒ';
$labels['group'] = 'ჯგუფი';
$labels['groups'] = 'ჯგუფები';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'პერსáƒáƒœáƒáƒšáƒ£áƒ áƒ˜ მისáƒáƒ›áƒáƒ áƒ—ები';
$labels['searchsave'] = 'ძებნის შენáƒáƒ®áƒ•áƒ';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'შეტყáƒáƒ‘ინების შექმნáƒ
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML ხელმáƒáƒ¬áƒ”რáƒ';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'ჩვენებáƒ';
$labels['skin'] = 'ინტერფეისი';
$labels['logoutclear'] = 'წáƒáƒ¨áƒšáƒ˜áƒšáƒ”ბის გáƒáƒ¡áƒ£áƒ¤áƒ—áƒáƒ•áƒ”ბრგáƒáƒ›áƒáƒ¡áƒ•áƒšáƒ˜áƒ¡áƒáƒ¡';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'წáƒáƒ˜áƒ¨áƒáƒšáƒáƒ¡ ხელმáƒáƒ¬áƒ
$labels['autoaddsignature'] = 'áƒáƒ•áƒ¢áƒáƒ›áƒáƒ¢áƒ£áƒ áƒáƒ“ დáƒáƒ”მáƒáƒ¢áƒáƒ¡ ხელმáƒáƒ¬áƒ”რáƒ';
$labels['newmessageonly'] = 'მხáƒáƒšáƒáƒ“ áƒáƒ®áƒáƒšáƒ˜ შეტყáƒáƒ‘ინებáƒ';
$labels['replyandforwardonly'] = 'მხáƒáƒšáƒáƒ“ გáƒáƒ“áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒ¡ დრპáƒáƒ¡áƒ£áƒ®áƒ˜áƒ¡ შემთხვევáƒáƒ¨áƒ˜';
-$labels['replysignaturepos'] = 'მხáƒáƒšáƒáƒ“ პáƒáƒ¡áƒ£áƒ®áƒ˜áƒ¡ áƒáƒœ გáƒáƒ“áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒ¡ შემთხვევáƒáƒ¨áƒ˜ გáƒáƒ§áƒ•áƒ”ს ხელმáƒáƒ¬áƒ”რáƒ';
-$labels['belowquote'] = 'ციტáƒáƒ¢áƒ˜áƒ¡ შემდეგ';
-$labels['abovequote'] = 'ციტáƒáƒ¢áƒáƒ›áƒ“ე';
$labels['insertsignature'] = 'ხელმáƒáƒªáƒ”რის ჩáƒáƒ¡áƒ›áƒ';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = '$n წáƒáƒ›áƒ˜áƒ¡ შემდეგ';
@@ -473,6 +476,7 @@ $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 7ad0b665b..754343fac 100755
--- a/program/localization/ka_GE/messages.inc
+++ b/program/localization/ka_GE/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'მáƒáƒœáƒáƒªáƒ”მთრბáƒáƒ–ის შეცდ
$messages['requesttimedout'] = 'Request timed out';
$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
$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['invalidrequest'] = 'áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ მáƒáƒ—ხáƒáƒ•áƒœáƒ! მáƒáƒœáƒáƒªáƒ”მების შენáƒáƒ®áƒ•áƒ áƒáƒ  მáƒáƒ®áƒ”რხდáƒ.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'áƒáƒ  áƒáƒ áƒ˜áƒ¡ áƒáƒ®áƒáƒšáƒ˜ შეტყáƒáƒ‘ინებáƒ';
diff --git a/program/localization/km_KH/labels.inc b/program/localization/km_KH/labels.inc
index a344e60c2..bc2836a53 100644
--- a/program/localization/km_KH/labels.inc
+++ b/program/localization/km_KH/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'សំបុážáŸ’រពង្រៀង';
$labels['sent'] = 'សំបុážáŸ’រដែលបានបញ្ជូន';
$labels['trash'] = 'ធុងសំរាម';
$labels['junk'] = 'សំបុážáŸ’រមិនល្អ';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ចំណងជើង';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'ទំពáŸážšáž“áŸáŸ‡';
$labels['unread'] = 'មិនទាន់អាន';
$labels['flagged'] = 'មានកំណážáŸ‹ážŸáŸ†áž‚ាល់ដោយផ្កាយ';
$labels['unanswered'] = 'មិនទាន់ឆ្លើយážáž”';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'បានលុបរួច';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'បញ្ច្រស់';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'បង្ហាញជាážáž¶ážšáž¶áž„';
$labels['folderactions'] = 'មុážáž„ារážáž';
$labels['compact'] = 'បង្រួម';
$labels['empty'] = 'áž‘áž‘áŸážš';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ទំហំសំបុážáŸ’រទាំងអស់ដែលមាន';
$labels['unknown'] = 'មិនស្គាល់';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'កំណážáŸ‹áž›áž€áŸ’ážážáŸážŽáŸ’ឌស្វáŸ
$labels['searchmod'] = 'កែសំរួលលក្ážážáŸážŽáŸ’ឌស្វែងរក';
$labels['msgtext'] = 'សំបុážáŸ’រទាំងមូល';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'បើកក្នុងវីនដូវážáŸ’មី';
$labels['emlsave'] = 'រក្សាទុកទិន្ននáŸáž™áž‡áž¶áž¯áž€ážŸáž¶ážšáž”្រភáŸáž‘(.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'ទំពáŸážšáž…ុងក្រោយ';
$labels['group'] = 'ក្រុម';
$labels['groups'] = 'ក្រុម';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'អាសយដ្ឋានផ្ទាល់ážáŸ’លួន';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'សរសáŸážšážŸáŸ†áž”áž»ážáŸ’ážšážáž¶áž˜áž”ែប
$labels['htmlonreply'] = 'ឆ្លើយážáž”សំបុážáŸ’ážšážáž¶áž˜áž”ែប HTML';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'áž ážáŸ’ážáž›áŸážáž¶ážáž¶áž˜áž”ែប HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'បង្ហាញប្រអប់សំរាប់មើលសំបុážáŸ’ážš';
$labels['skin'] = 'ការរចនាទំពáŸážš';
$labels['logoutclear'] = 'សំអាážáž’ុងសំរាមពáŸáž›áž–áž·áž“áž·ážáŸ’យចáŸáž‰';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'នៅ​ពáŸáž›â€‹áž†áŸ’លើយ​ážáž”
$labels['autoaddsignature'] = 'បញ្ចូលហážáŸ’ážáž›áŸážáž¶ážŠáŸ„យស្វáŸáž™áž”្រវážáŸ’ážáž·';
$labels['newmessageonly'] = 'សំរាប់សំបុážáŸ’ážšážáŸ’មីážáŸ‚ប៉ុណ្ណោះ';
$labels['replyandforwardonly'] = 'សំរាប់ឆើ្លយážáž”​និងផ្ញើបន្ážážáŸ‚​ប៉ុណ្ណោះ';
-$labels['replysignaturepos'] = 'បញ្ចូលហážáŸ’ážáž›áŸážáž¶áž“ៅពáŸáž›áž†áž¾áŸ’លយážáž”​និងផ្ញើបន្áž';
-$labels['belowquote'] = 'ពីក្រោមសម្រង់អážáŸ’ážáž”áž‘';
-$labels['abovequote'] = 'ពីលើសម្រង់អážáŸ’ážáž”áž‘';
$labels['insertsignature'] = 'បញ្ចូលហážáŸ’ážáž›áŸážáž¶';
$labels['previewpanemarkread'] = 'កំណážáŸ‹ážŸáŸ†áž”áž»ážáŸ’រ​ដែល​បាន​បង្ហាញ​​ជា​សំបុážáŸ’របាន​អាន​រួច';
$labels['afternseconds'] = 'ក្រោយពី $n វិនាទី';
@@ -473,6 +476,7 @@ $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 c9ede486e..1f629fa6c 100644
--- a/program/localization/km_KH/messages.inc
+++ b/program/localization/km_KH/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Database Error!';
$messages['requesttimedout'] = 'Request timed out';
$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['invalidrequest'] = 'មិនអាចរក្សាទុកទិន្ននáŸáž™áž”ានពីព្រោះមានបញ្ហានៅពáŸáž›áž”ញ្ជូនទិន្ននáŸáž™';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'ពុំមានសំបុážáŸ’រក្នុងប្រអប់សំបុážáŸ’ážšáž“áŸáŸ‡áž‘áŸ';
diff --git a/program/localization/ko_KR/labels.inc b/program/localization/ko_KR/labels.inc
index 667fb422a..60a9275ac 100644
--- a/program/localization/ko_KR/labels.inc
+++ b/program/localization/ko_KR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = '임시 보관함';
$labels['sent'] = '보낸 편지함';
$labels['trash'] = '휴지통';
$labels['junk'] = '스팸 편지함';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '제목';
@@ -162,6 +163,7 @@ $labels['currpage'] = '현재 페ì´ì§€';
$labels['unread'] = 'ì½ì§€ ì•ŠìŒ';
$labels['flagged'] = '깃발로 표시ë¨';
$labels['unanswered'] = '답장하지 ì•ŠìŒ';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'ì‚­ì œë¨';
$labels['undeleted'] = 'ì‚­ì œë˜ì§€ ì•ŠìŒ';
$labels['invert'] = '반전';
@@ -192,6 +194,7 @@ $labels['listmode'] = '화면 모드 ëª©ë¡ ë³´ê¸°';
$labels['folderactions'] = 'í´ë” 명령';
$labels['compact'] = '간단하게';
$labels['empty'] = '비어 있ìŒ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ë””ìŠ¤í¬ ì‚¬ìš©ëŸ‰';
$labels['unknown'] = 'ì•Œ 수 ì—†ìŒ';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = '검색 재설정';
$labels['searchmod'] = 'ìˆ˜ì •ìž ê²€ìƒ‰';
$labels['msgtext'] = '전체 메시지';
$labels['body'] = '본문';
+$labels['type'] = 'Type';
$labels['openinextwin'] = '새 ì°½ì—ì„œ 열기';
$labels['emlsave'] = '다운로드(.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = '마지막 페ì´ì§€ 보기';
$labels['group'] = '그룹';
$labels['groups'] = '그룹';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ê°œì¸ ì£¼ì†Œ';
$labels['searchsave'] = '검색 저장';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML 메시지 작성';
$labels['htmlonreply'] = 'HTML 메시지 회신 시';
$labels['htmlonreplyandforward'] = '전달 ë˜ëŠ” HTML 메시지 회신 ì‹œ';
$labels['htmlsignature'] = 'HTML 서명';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = '미리보기 창 보기';
$labels['skin'] = 'ì¸í„°íŽ˜ì´ìŠ¤ 스킨';
$labels['logoutclear'] = '로그아웃할 때 휴지통 비우기';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = '회신 ì‹œ 메시지ì—ì„œ ì›ë¬¸ ì„œëª…ì„ ì
$labels['autoaddsignature'] = '서명 ìžë™ìœ¼ë¡œ 추가';
$labels['newmessageonly'] = '새로운 메시지ì—만';
$labels['replyandforwardonly'] = '회신 ë° ì „ë‹¬ ì‹œì—만';
-$labels['replysignaturepos'] = '회신 ë˜ëŠ” 전달 ì‹œ 서명 추가';
-$labels['belowquote'] = 'ì¸ìš©ë¬¸ 하단';
-$labels['abovequote'] = 'ì¸ìš©ë¬¸ ìƒë‹¨';
$labels['insertsignature'] = '서명 삽입';
$labels['previewpanemarkread'] = '미리 본 메시지를 ì½ìŒìœ¼ë¡œ 표시';
$labels['afternseconds'] = '$n초 후';
@@ -473,6 +476,7 @@ $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 4efd2f3d3..bf42c9c89 100644
--- a/program/localization/ko_KR/messages.inc
+++ b/program/localization/ko_KR/messages.inc
@@ -17,153 +17,156 @@
*/
$messages = array();
-$messages['errortitle'] = 'ì—러가 ë°œìƒ!';
+$messages['errortitle'] = '오류 ë°œìƒ!';
$messages['loginfailed'] = '로그ì¸ì´ 실패하였습니다.';
-$messages['cookiesdisabled'] = '브ë¼ìš°ì €ê°€ 쿠키를 지ì›í•˜ì§€ 않습니다';
-$messages['sessionerror'] = 'ì„¸ì…˜ì´ ìœ íš¨í•˜ì§€ 않거나 종료ë˜ì—ˆìŠµë‹ˆë‹¤';
+$messages['cookiesdisabled'] = '브ë¼ìš°ì €ê°€ 쿠키를 지ì›í•˜ì§€ 않습니다.';
+$messages['sessionerror'] = 'ì„¸ì…˜ì´ ìœ íš¨í•˜ì§€ 않거나 종료ë˜ì—ˆìŠµë‹ˆë‹¤.';
$messages['storageerror'] = 'IMAP 서버 연결 실패';
-$messages['servererror'] = '서버 ì—러!';
-$messages['servererrormsg'] = '서버 ì—러: $msg';
-$messages['dberror'] = 'ë°ì´í„°ë² ì´ìŠ¤ ì—러!';
+$messages['servererror'] = '서버 오류!';
+$messages['servererrormsg'] = '서버 오류: $msg';
+$messages['dberror'] = 'ë°ì´í„°ë² ì´ìŠ¤ 오류!';
$messages['requesttimedout'] = '요청 시간 초과';
-$messages['errorreadonly'] = 'ëª…ë ¹ì„ ìˆ˜í–‰í•  수 없습니다. ì½ê¸°ì „ìš© í´ë”.';
-$messages['errornoperm'] = 'ëª…ë ¹ì„ ìˆ˜í–‰í•  수 없습니다. ê¶Œí•œì´ ê±°ë¶€ ë¨.';
-$messages['invalidrequest'] = 'ìž˜ëª»ëœ ìš”ì²­! ë°ì´í„°ëŠ” 저장ë˜ì§€ 않았ìŒ.';
+$messages['errorreadonly'] = 'ëª…ë ¹ì„ ìˆ˜í–‰í•  수 없습니다. ì½ê¸° ì „ìš© í´ë”ìž„.';
+$messages['errornoperm'] = 'ëª…ë ¹ì„ ìˆ˜í–‰í•  수 없습니다. ê¶Œí•œì´ ê±°ë¶€ë¨.';
+$messages['erroroverquota'] = 'ìž‘ì—…ì„ ìˆ˜í–‰í•  수 ì—†ìŒ. 여유 ê³µê°„ì´ ì—†ìŒ.';
+$messages['erroroverquotadelete'] = '여유 ê³µê°„ì´ ì—†ìŒ. SHIFT-DELì„ ì´ìš©í•˜ì—¬ 메시지를 삭제하세요.';
+$messages['invalidrequest'] = 'ìž˜ëª»ëœ ìš”ì²­! ë°ì´í„°ê°€ 저장ë˜ì§€ 않았ìŒ.';
$messages['invalidhost'] = 'ìž˜ëª»ëœ ì„œë²„ ì´ë¦„입니다.';
-$messages['nomessagesfound'] = 'ì´ ë©”ì¼í•¨ì— ë©”ì¼ì´ 없습니다';
-$messages['loggedout'] = 'ì„¸ì…˜ì„ ì„±ê³µì ìœ¼ë¡œ 종료하였습니다. 안녕히 가십시오!';
-$messages['mailboxempty'] = 'ë©”ì¼í•¨ì´ 비어있습니다';
-$messages['refreshing'] = '새로고침 중 ...';
+$messages['nomessagesfound'] = 'ì´ ë©”ì¼í•¨ì— ë©”ì¼ì´ 없습니다.';
+$messages['loggedout'] = 'ì„¸ì…˜ì„ ì„±ê³µì ìœ¼ë¡œ 종료하였습니다. 안녕히 가세요!';
+$messages['mailboxempty'] = 'ë©”ì¼í•¨ì´ 비어있습니다.';
+$messages['refreshing'] = '새로 고치는 중 ...';
$messages['loading'] = '불러오는 중...';
-$messages['uploading'] = 'í•˜ë‚˜ì˜ íŒŒì¼ ì˜¬ë¦¬ê¸°...';
-$messages['uploadingmany'] = '여러 íŒŒì¼ ì˜¬ë¦¬ê¸°...';
-$messages['loadingdata'] = 'ë°ì´í„° 불러오는 중...';
-$messages['checkingmail'] = '새 ë©”ì¼ í™•ì¸ ì¤‘...';
-$messages['sendingmessage'] = 'ë©”ì¼ ë³´ë‚´ëŠ” 중...';
-$messages['messagesent'] = 'ë©”ì¼ì„ 성공ì ìœ¼ë¡œ 보냈습니다';
-$messages['savingmessage'] = 'ë©”ì¼ ì €ìž¥ 중...';
-$messages['messagesaved'] = 'ë©”ì¼ì´ 드래프트 í´ë”ì— ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤';
-$messages['successfullysaved'] = '성공ì ìœ¼ë¡œ 저장';
-$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['deletegroupconfirm'] = 'ì •ë§ë¡œ ì„ íƒí•œ ê·¸ë£¹ì„ ì‚­ì œí•˜ëŠ” ê²ƒì„ ì›í•˜ì‹­ë‹ˆê¹Œ?';
-$messages['deletemessagesconfirm'] = 'ì •ë§ ì„ íƒí•œ ë©”ì¼ë“¤ì„ 삭제하시겠습니까?';
-$messages['deletefolderconfirm'] = 'ì •ë§ ì´ í´ë”를 삭제하시겠습니까?';
-$messages['purgefolderconfirm'] = 'ì •ë§ ì´ í´ë”ì˜ ëª¨ë“  ë©”ì¼ì„ 삭제하시겠습니까?';
-$messages['contactdeleting'] = 'ì—°ë½ì²˜(들) ì‚­ì œ 중...';
+$messages['uploading'] = '파ì¼ì„ 업로드하는 중...';
+$messages['uploadingmany'] = '파ì¼ì„ 업로드하는 중...';
+$messages['loadingdata'] = 'ë°ì´í„°ë¥¼ 불러오는 중...';
+$messages['checkingmail'] = '새 메시지를 확ì¸í•˜ëŠ” 중...';
+$messages['sendingmessage'] = '메시지를 보내는 중...';
+$messages['messagesent'] = '메시지를 성공ì ìœ¼ë¡œ 보냈습니다.';
+$messages['savingmessage'] = '메시지를 저장하는 중...';
+$messages['messagesaved'] = '메시지가 ìž„ì‹œ ë³´ê´€í•¨ì— ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤.';
+$messages['successfullysaved'] = '성공ì ìœ¼ë¡œ 저장ë¨.';
+$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['deletegroupconfirm'] = 'ì •ë§ë¡œ ì„ íƒí•œ ê·¸ë£¹ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?';
+$messages['deletemessagesconfirm'] = 'ì •ë§ë¡œ ì„ íƒí•œ 메시지를 삭제하시겠습니까?';
+$messages['deletefolderconfirm'] = 'ì •ë§ë¡œ ì´ í´ë”를 삭제하시겠습니까?';
+$messages['purgefolderconfirm'] = 'ì •ë§ë¡œ ì´ í´ë”ì˜ ëª¨ë“  메시지를 삭제하시겠습니까?';
+$messages['contactdeleting'] = 'ì—°ë½ì²˜ ì‚­ì œ 중...';
$messages['groupdeleting'] = '그룹 삭제 중...';
-$messages['folderdeleting'] = 'í´ë” 지우는 중...';
-$messages['foldermoving'] = 'í´ë” 옮기는 중...';
-$messages['foldersubscribing'] = 'í´ë”ì˜ êµ¬ë…ì„ í™œì„±í™” 하는 중...';
+$messages['folderdeleting'] = 'í´ë”를 삭제하는 중...';
+$messages['foldermoving'] = 'í´ë”를 ì´ë™í•˜ëŠ” 중...';
+$messages['foldersubscribing'] = 'í´ë”를 구ë…하는 중...';
$messages['folderunsubscribing'] = 'í´ë”ì˜ êµ¬ë…ì„ ì·¨ì†Œí•˜ëŠ” 중...';
-$messages['formincomplete'] = 'ì–‘ì‹ì„ 완전히 채우지 않았습니다';
-$messages['noemailwarning'] = '유효한 ì´ë©”ì¼ ì£¼ì†Œë¥¼ 넣어주십시오';
-$messages['nonamewarning'] = 'ì´ë¦„ì„ ë„£ì–´ì£¼ì‹­ì‹œì˜¤';
-$messages['nopagesizewarning'] = '페ì´ì§€ í¬ê¸°ë¥¼ 넣어주십시오';
-$messages['nosenderwarning'] = 'ë°œì‹ ìž ì´ë©”ì¼ ì£¼ì†Œë¥¼ 넣어주십시오';
-$messages['norecipientwarning'] = 'ì ì–´ë„ í•œ ê°œ ì´ìƒì˜ 수신 주소를 넣어주십시오';
-$messages['nosubjectwarning'] = '"제목"ì´ ì—†ìŠµë‹ˆë‹¤. ì œëª©ì„ ë„£ìœ¼ì‹œê² ìŠµë‹ˆê¹Œ?';
-$messages['nobodywarning'] = 'í…스트 ì—†ì´ ë©”ì¼ì„ 보낼까요?';
-$messages['notsentwarning'] = 'ë©”ì¼ì„ 보내지 않았습니다. ë©”ì¼ì„ 버리시겠습니까?';
-$messages['noldapserver'] = '검색할 LDAP 서버를 ì„ íƒí•˜ì„¸ìš”';
-$messages['nosearchname'] = 'ì—°ë½ì²˜ ì´ë¦„ì´ë‚˜ ë©”ì¼ ì£¼ì†Œë¥¼ 넣으세요';
-$messages['notuploadedwarning'] = 'ì•„ì§ ëª¨ë“  첨부가 업로드ë˜ì§€ 않았습니다. 기다리거나 업로드를 취소하기 ë°”ëžë‹ˆë‹¤.';
-$messages['searchsuccessful'] = '$nrê°œì˜ ë©”ì¼ ë°œê²¬';
-$messages['contactsearchsuccessful'] = '$nr ì—°ë½ì²˜ 발견ë¨.';
-$messages['searchnomatch'] = '검색 결과가 없습니다';
+$messages['formincomplete'] = 'ì–‘ì‹ì„ 완전히 작성ë˜ì§€ 않았습니다.';
+$messages['noemailwarning'] = '유효한 ì´ë©”ì¼ ì£¼ì†Œë¥¼ 입력하시기 ë°”ëžë‹ˆë‹¤.';
+$messages['nonamewarning'] = 'ì´ë¦„ì„ ìž…ë ¥í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.';
+$messages['nopagesizewarning'] = '페ì´ì§€ í¬ê¸°ë¥¼ 입력하시기 ë°”ëžë‹ˆë‹¤.';
+$messages['nosenderwarning'] = 'ë°œì‹ ì¸ ì´ë©”ì¼ ì£¼ì†Œë¥¼ 입력하시기 ë°”ëžë‹ˆë‹¤.';
+$messages['norecipientwarning'] = 'ì ì–´ë„ í•œ ê°œ ì´ìƒì˜ ìˆ˜ì‹ ì¸ ì£¼ì†Œë¥¼ 입력하시기 ë°”ëžë‹ˆë‹¤.';
+$messages['nosubjectwarning'] = '"제목" 필드가 비어있습니다. 지금 입력하시겠습니까?';
+$messages['nobodywarning'] = 'í…스트가 없는 메시지를 보내시겠습니까?';
+$messages['notsentwarning'] = '메시지를 보내지 못했습니다. 메시지를 í기하시겠습니까?';
+$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['folderunsubscribed'] = 'í´ë”ê°€ 성공ì ìœ¼ë¡œ êµ¬ë… ì·¨ì†Œ ë¨.';
-$messages['folderpurged'] = 'í´ë”ê°€ 성공ì ìœ¼ë¡œ 비워졌습니다.';
-$messages['folderexpunged'] = 'í´ë”ê°€ 성공ì ìœ¼ë¡œ 압축 ë˜ì—ˆìŠµë‹ˆë‹¤.';
-$messages['deletedsuccessfully'] = '성공ì ìœ¼ë¡œ 삭제하였습니다';
-$messages['converting'] = 'ë©”ì¼ì˜ í¬ë§·ì„ 지우는 중...';
-$messages['messageopenerror'] = '서버ì—ì„œ ë©”ì¼ì„ 가져올 수 없습니다';
-$messages['fileuploaderror'] = 'íŒŒì¼ ì—…ë¡œë“œ 실패';
-$messages['filesizeerror'] = '올린 파ì¼ì´ $sizeì˜ ìµœëŒ€ í¬ê¸°ë¥¼ 초과했습니다';
-$messages['copysuccess'] = '$nrê°œì˜ ì£¼ì†Œë¥¼ 성공ì ìœ¼ë¡œ 복사했습니다';
-$messages['copyerror'] = '주소를 복사할 수 없습니다';
-$messages['sourceisreadonly'] = 'ì´ ì£¼ì†Œ 소스는 ì½ê¸° 전용입니다';
-$messages['errorsavingcontact'] = 'ì—°ë½ì²˜ 주소를 저장할 수 없습니다';
-$messages['movingmessage'] = '메시지 ì´ë™ 중...';
-$messages['copyingmessage'] = '메시지(들) 복사 중...';
-$messages['copyingcontact'] = 'ì—°ë½ì²˜(들) 복사 중...';
-$messages['deletingmessage'] = '메시지(들) 삭제 중...';
-$messages['markingmessage'] = '메시지(들)ì— í‘œì‹œ 중...';
-$messages['addingmember'] = 'ê·¸ë£¹ì— ì—°ë½ì²˜(들)ì„ ì¶”ê°€ 중...';
-$messages['removingmember'] = '그룹으로 부터 ì—°ë½ì²˜ë¥¼ ì‚­ì œ 중...';
-$messages['receiptsent'] = 'ë©”ì¼ ì½ìŒ 확ì¸ì„ 보냈습니다';
-$messages['errorsendingreceipt'] = 'ì½ìŒ 확ì¸ì„ 보낼 수 없습니다';
+$messages['checking'] = 'í™•ì¸ ì¤‘...';
+$messages['nospellerrors'] = '맞춤법 오류를 찾지 못함.';
+$messages['folderdeleted'] = 'í´ë”를 성공ì ìœ¼ë¡œ 삭제함.';
+$messages['foldersubscribed'] = 'í´ë”를 성공ì ìœ¼ë¡œ 구ë…함.';
+$messages['folderunsubscribed'] = 'í´ë”를 성공ì ìœ¼ë¡œ êµ¬ë… ì·¨ì†Œí•¨.';
+$messages['folderpurged'] = 'í´ë”를 성공ì ìœ¼ë¡œ 비웠습니다.';
+$messages['folderexpunged'] = 'í´ë”를 성공ì ìœ¼ë¡œ 압축하였습니다.';
+$messages['deletedsuccessfully'] = '성공ì ìœ¼ë¡œ 삭제함.';
+$messages['converting'] = 'ì„œì‹ ì„¤ì • ì‚­ì œ 중...';
+$messages['messageopenerror'] = '서버ì—ì„œ 메시지를 불러올 수 ì—†ìŒ.';
+$messages['fileuploaderror'] = 'íŒŒì¼ ì—…ë¡œë“œë¥¼ 실패함.';
+$messages['filesizeerror'] = 'ì—…ë¡œë“œëœ íŒŒì¼ì´ 최대 í¬ê¸°ì¸ $size를 초과하였습니다.';
+$messages['copysuccess'] = '$nrê°œì˜ ì£¼ì†Œë¥¼ 성공ì ìœ¼ë¡œ 복사함.';
+$messages['copyerror'] = '모든 주소를 복사할 수 ì—†ìŒ.';
+$messages['sourceisreadonly'] = 'ì´ ì£¼ì†Œì˜ ì†ŒìŠ¤ëŠ” ì½ê¸° 전용입니다.';
+$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['selectimportfile'] = '업로드할 파ì¼ì„ ì„ íƒí•˜ì„¸ìš”';
-$messages['addresswriterror'] = 'ì„ íƒí•œ 주소ë¡ì€ 쓸 수 없습니다';
-$messages['contactaddedtogroup'] = 'ì´ ê·¸ë£¹ì— ì—°ë½ì²˜ë¥¼ 성공ì ìœ¼ë¡œ 추가 함.';
-$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['opnotpermitted'] = 'ìž‘ì—…ì´ í—ˆê°€ë˜ì§€ 않았습니다!';
-$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 ì—러: ìˆ˜ì‹ ìž ëª©ë¡ì„ 분ì„(parse)í•  수 ì—†ìŒ.';
-$messages['smtperror'] = 'SMTP ì—러: $msg';
-$messages['emailformaterror'] = 'ìž˜ëª»ëœ e-mail 주소: $email';
-$messages['toomanyrecipients'] = '수신ìžê°€ 너무 많습니다. 수신ìžì˜ 수를 $maxë¡œ 줄ì´ì„¸ìš”.';
-$messages['maxgroupmembersreached'] = '그룹 구성ì›ì˜ 수가 최대 ì¸ì› $max를 초과하였습니다.';
-$messages['internalerror'] = '내부 오류가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤. 다시 ì‹œë„하기 ë°”ëžë‹ˆë‹¤.';
-$messages['contactdelerror'] = 'ì—°ë½ì²˜(들)ì„ ì§€ìš¸ 수 없습니다.';
-$messages['contactdeleted'] = 'ì—°ë½ì²˜(들)ì´ ì„±ê³µì ìœ¼ë¡œ 제거 ë¨.';
-$messages['contactrestoreerror'] = 'ì‚­ì œëœ ì—°ë½ì²˜(들)ì„ ë³µêµ¬í•  수 ì—†ìŒ.';
-$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['autocompletemore'] = 'ë§Žì€ í•­ëª©ì´ ë°œê²¬ë˜ì—ˆìŠµë‹ˆë‹¤. ë” ë§Žì€ ë¬¸ìžë¥¼ 입력하세요.';
-$messages['namecannotbeempty'] = 'ì´ë¦„ì´ ë¹„ì›Œì ¸ì„œëŠ” 안ë©ë‹ˆë‹¤.';
+$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['opnotpermitted'] = 'ìž‘ì—…ì´ í—ˆê°€ë˜ì§€ ì•ŠìŒ!';
+$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 오류: ìˆ˜ì‹ ì¸ ëª©ë¡ì„ 분ì„(parse)í•  수 ì—†ìŒ.';
+$messages['smtperror'] = 'SMTP 오류: $msg';
+$messages['emailformaterror'] = '유효하지 ì•Šì€ ì´ë©”ì¼ ì£¼ì†Œ: $email';
+$messages['toomanyrecipients'] = '수신ì¸ì´ 너무 많ìŒ. ìˆ˜ì‹ ì¸ ìˆ˜ë¥¼ $max명으로 줄ì´ì„¸ìš”.';
+$messages['maxgroupmembersreached'] = '그룹 구성ì›ì˜ 수가 최대 ì¸ì›ì¸ $maxëª…ì„ ì´ˆê³¼í•©ë‹ˆë‹¤.';
+$messages['internalerror'] = '내부 오류가 ë°œìƒí•¨. ìž¬ì‹œë„ í•´ì£¼ì‹œê¸° ë°”ëžë‹ˆë‹¤.';
+$messages['contactdelerror'] = 'ì—°ë½ì²˜ë¥¼ 삭제할 수 ì—†ìŒ.';
+$messages['contactdeleted'] = 'ì—°ë½ì²˜ê°€ 성공ì ìœ¼ë¡œ ì‚­ì œë¨.';
+$messages['contactrestoreerror'] = 'ì‚­ì œëœ ì—°ë½ì²˜ë¥¼ 복구할 수 ì—†ìŒ.';
+$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['autocompletemore'] = 'ë” ë§Žì€ ì¼ì¹˜ í•­ëª©ì´ ë°œê²¬ë¨. ë” ë§Žì€ ë¬¸ìžë¥¼ 입력해주시기 ë°”ëžë‹ˆë‹¤.';
+$messages['namecannotbeempty'] = 'ì´ë¦„ì„ ë¹„ì›Œë‘˜ 수 없습니다.';
$messages['nametoolong'] = 'ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤.';
-$messages['folderupdated'] = 'í´ë”를 성공ì ìœ¼ë¡œ 갱신 함.';
-$messages['foldercreated'] = 'í´ë”를 성공ì ìœ¼ë¡œ ìƒì„± 함.';
-$messages['invalidimageformat'] = '올바른 ì´ë¯¸ì§€ í¬ë©§ì´ 아님.';
-$messages['mispellingsfound'] = '메시지ì—ì„œ 맞춤법 오류를 ê°ì§€ 하였ìŒ.';
-$messages['parentnotwritable'] = 'ì„ íƒí•œ 부모 í´ë”ì— í´ë”를 ìƒì„±í•˜ê±°ë‚˜ ì´ë™í•  수 ì—†ìŒ. ì ‘ê·¼ ê¶Œí•œì´ ì—†ìŒ.';
-$messages['messagetoobig'] = 'ì²˜ë¦¬í•˜ê¸°ì— ë„ˆë¬´ í° ë©”ì‹œì§€ 입니다.';
-$messages['attachmentvalidationerror'] = '경고! ì´ ì²¨ë¶€ 파ì¼ì€ ë©”ì‹œì§€ì˜ ì„ ì–¸ 유형과 ì¼ì¹˜í•˜ì§€ ì•Šê¸°ë•Œë¬¸ì— ì˜ì‹¬ë©ë‹ˆë‹¤. 보낸 ì‚¬ëžŒì„ ë¯¿ì„ ìˆ˜ 없다면, 악성 코드를 í¬í•¨í•˜ëŠ”ì§€ë„ ëª¨ë¥´ê¸° ë•Œë¬¸ì— ë¸Œë¼ìš°ì €ì—ì„œ ì—´ 수 없습니다. <br/><br/><em> 예측 í•œ 종류 : $expected; 발견 í•œ 종류 : $found</ em>';
-$messages['noscriptwarning'] = '경고: ì´ ì›¹ ë©”ì¼ ì„œë¹„ìŠ¤ëŠ” Javascriptê°€ 필요합니다! 사용하려면 Javascript를 브ë¼ìš°ì € 설정ì—ì„œ 활성화하십시오.';
+$messages['folderupdated'] = 'í´ë”ê°€ 성공ì ìœ¼ë¡œ ì—…ë°ì´íŠ¸ë¨.';
+$messages['foldercreated'] = 'í´ë”ê°€ 성공ì ìœ¼ë¡œ ìƒì„±ë¨.';
+$messages['invalidimageformat'] = '유효한 ì´ë¯¸ì§€ 형ì‹ì´ 아님.';
+$messages['mispellingsfound'] = '메시지ì—ì„œ 맞춤법 오류가 ê°ì§€ë˜ì—ˆìŒ.';
+$messages['parentnotwritable'] = 'ì„ íƒí•œ ìƒìœ„ í´ë”ì— í´ë”를 ìƒì„±/ì´ë™í•  수 ì—†ìŒ. ì ‘ê·¼ ê¶Œí•œì´ ì—†ìŒ.';
+$messages['messagetoobig'] = '메시지 ë¶€ë¶„ì´ ì²˜ë¦¬í•˜ê¸°ì—는 너무 í½ë‹ˆë‹¤.';
+$messages['attachmentvalidationerror'] = '경고! ì´ ì²¨ë¶€ 파ì¼ì˜ ìœ í˜•ì´ ë©”ì‹œì§€ì—ì„œ ì„ ì–¸ëœ ìœ í˜•ê³¼ ì¼ì¹˜í•˜ì§€ 않기 ë•Œë¬¸ì— ì˜ì‹¬ë©ë‹ˆë‹¤. 발신ì¸ì„ 신뢰할 수 ì—†ì„ ê²½ìš°, 악성 코드를 í¬í•¨í•  ìˆ˜ë„ ìžˆê¸° ë•Œë¬¸ì— ë¸Œë¼ìš°ì €ì—ì„œ 열지 않는 ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤. <br/><br/><em> 예ìƒí•œ 유형: $expected; ë°œê²¬ëœ ìœ í˜•: $found</ em>';
+$messages['noscriptwarning'] = '경고: ì´ ì›¹ ë©”ì¼ ì„œë¹„ìŠ¤ëŠ” ìžë°”스í¬ë¦½íŠ¸ê°€ 필요합니다! ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì‹œë ¤ë©´ ìžë°”스í¬ë¦½íŠ¸ë¥¼ 브ë¼ìš°ì € 설정ì—ì„œ 활성화하시기 ë°”ëžë‹ˆë‹¤.';
?>
diff --git a/program/localization/ku/labels.inc b/program/localization/ku/labels.inc
index 5c6786502..6a3c16a5f 100644
--- a/program/localization/ku/labels.inc
+++ b/program/localization/ku/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Nexwendî';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Peyameke HTML biafirîne';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Åžanenava HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Panela berê nîşan bide';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 6783209a3..9d219cbf5 100644
--- a/program/localization/ku/messages.inc
+++ b/program/localization/ku/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Di vê peyamdankê de tu peyam nehat dîtin';
diff --git a/program/localization/lb_LU/labels.inc b/program/localization/lb_LU/labels.inc
new file mode 100644
index 000000000..1dff3a9e7
--- /dev/null
+++ b/program/localization/lb_LU/labels.inc
@@ -0,0 +1,544 @@
+<?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 = 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';
+$labels['to'] = 'Un';
+$labels['cc'] = 'CC';
+$labels['bcc'] = 'BCC';
+$labels['replyto'] = 'Äntwert un';
+$labels['followupto'] = 'Noverfollgung un';
+$labels['date'] = 'Datum';
+$labels['size'] = 'Gréisst';
+$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...';
+$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';
+$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';
+$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';
+$labels['apr'] = 'Abr';
+$labels['may'] = 'Mee';
+$labels['jun'] = 'Jun';
+$labels['jul'] = 'Jul';
+$labels['aug'] = 'Aug';
+$labels['sep'] = 'Sep';
+$labels['oct'] = 'Okt';
+$labels['nov'] = 'Nov';
+$labels['dec'] = 'Dez';
+
+// months long
+$labels['longjan'] = 'Januar';
+$labels['longfeb'] = 'Februar';
+$labels['longmar'] = 'Mäerz';
+$labels['longapr'] = 'Abrëll';
+$labels['longmay'] = 'Mee';
+$labels['longjun'] = 'Juni';
+$labels['longjul'] = 'Juli';
+$labels['longaug'] = 'August';
+$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';
+$labels['writenewmessage'] = 'Neie Message schreiwen';
+$labels['reply'] = 'Äntweren';
+$labels['replytomessage'] = 'Dem Ofsender äntweren';
+$labels['replytoallmessage'] = 'Dem Ofsender an allen Empfänger äntweren';
+$labels['replyall'] = 'U jiddwereen äntweren';
+$labels['replylist'] = 'Äntwert-Lëscht';
+$labels['forward'] = 'Weiderleeden';
+$labels['forwardinline'] = 'Am Message weiderleeden';
+$labels['forwardattachment'] = 'Als Unhank weiderleeden';
+$labels['forwardmessage'] = 'De Message weiderleeden';
+$labels['deletemessage'] = 'Message läschen';
+$labels['movemessagetotrash'] = 'Message an d\'Poubelle réckelen';
+$labels['printmessage'] = 'Dëse Message drécken';
+$labels['previousmessage'] = 'Message virdru weisen';
+$labels['firstmessage'] = 'Éischte Message weisen';
+$labels['nextmessage'] = 'Nächste Message weisen';
+$labels['lastmessage'] = 'Leschte Message weisen';
+$labels['backtolist'] = 'Zréck bei d\'Lëscht vun de Messagen';
+$labels['viewsource'] = 'Source weisen';
+$labels['mark'] = 'Markéieren';
+$labels['markmessages'] = 'Messagë markéieren';
+$labels['markread'] = 'Als gelies';
+$labels['markunread'] = 'Als ongelies';
+$labels['markflagged'] = 'Mat Fändel';
+$labels['markunflagged'] = 'Ouni Fändel';
+$labels['moreactions'] = 'Mei Aktiounen...';
+$labels['more'] = 'Méi';
+$labels['back'] = 'Zréck';
+$labels['options'] = 'Optiounen';
+
+$labels['select'] = 'Auswielen';
+$labels['all'] = 'All';
+$labels['none'] = 'Keng';
+$labels['currpage'] = 'Aktuell Säit';
+$labels['unread'] = 'Ongelies';
+$labels['flagged'] = 'Mat Fändel';
+$labels['unanswered'] = 'Net beäntwert';
+$labels['withattachment'] = 'Mat Unhank';
+$labels['deleted'] = 'Geläscht';
+$labels['undeleted'] = 'Net geläscht';
+$labels['invert'] = 'Ëmdréinen';
+$labels['filter'] = 'Filter';
+$labels['list'] = 'Lëscht';
+$labels['threads'] = 'Diskussiounen';
+$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';
+$labels['fromto'] = 'Vun/Un';
+$labels['flag'] = 'Fändel';
+$labels['attachment'] = 'Unhank';
+$labels['nonesort'] = 'Keng';
+$labels['sentdate'] = 'Verschéckt';
+$labels['arrival'] = 'Ukomm';
+$labels['asc'] = 'opsteigend';
+$labels['desc'] = 'ofsteigend';
+$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';
+$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';
+$labels['savemessage'] = 'Als Brouillon späicheren';
+$labels['addattachment'] = 'E Fichier drunhänken';
+$labels['charset'] = 'Zeechesaz';
+$labels['editortype'] = 'Editor-Typ';
+$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['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';
+$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';
+$labels['middlename'] = 'Mëttelnumm';
+$labels['nameprefix'] = 'Präfix';
+$labels['namesuffix'] = 'Suffix';
+$labels['nickname'] = 'Spëtznumm';
+$labels['jobtitle'] = 'Job-Titel';
+$labels['department'] = 'Departement';
+$labels['gender'] = 'Geschlecht';
+$labels['maidenname'] = 'Meedechersnumm';
+$labels['email'] = 'E-Mail';
+$labels['phone'] = 'Telefon';
+$labels['address'] = 'Adress';
+$labels['street'] = 'Strooss';
+$labels['locality'] = 'Uertschaft';
+$labels['zipcode'] = 'Postleitzuel';
+$labels['region'] = 'Staat';
+$labels['country'] = 'Land';
+$labels['birthday'] = 'Gebuertsdatum';
+$labels['anniversary'] = 'Anniversaire';
+$labels['website'] = 'Websäit';
+$labels['instantmessenger'] = 'Instant-Messenger';
+$labels['notes'] = 'Notizen';
+$labels['male'] = 'männlech';
+$labels['female'] = 'weiblech';
+$labels['manager'] = 'Manager';
+$labels['assistant'] = 'Assistent';
+$labels['spouse'] = 'Liewenspartner';
+$labels['allfields'] = 'All d\'Felder';
+$labels['search'] = 'Sichen';
+$labels['advsearch'] = 'Avancéiert Sich';
+$labels['advanced'] = 'Avancéiert';
+$labels['other'] = 'Aneres';
+
+$labels['typehome'] = 'Doheem';
+$labels['typework'] = 'Aarbecht';
+$labels['typeother'] = 'Aneres';
+$labels['typemobile'] = 'Mobil';
+$labels['typemain'] = 'Haapt';
+$labels['typehomefax'] = 'Fax Doheem';
+$labels['typeworkfax'] = 'Fax Aarbecht';
+$labels['typecar'] = 'Auto';
+$labels['typepager'] = 'Pager';
+$labels['typevideo'] = 'Video';
+$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';
+$labels['delete'] = 'Läschen';
+$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';
+$labels['contactsfromto'] = 'Kontakter $from bis $to vun $count';
+$labels['print'] = 'Drécke';
+$labels['export'] = 'Exportéieren';
+$labels['exportall'] = 'All exportéieren';
+$labels['exportsel'] = 'Déi ausgewielten exportéieren';
+$labels['exportvcards'] = 'Kontakter am vCard-Format exportéieren';
+$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['importreplace'] = 'Dat ganzt Adressbuch ersetzen';
+$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';
+$labels['messagepart'] = 'Deel';
+$labels['digitalsig'] = 'Digital Signatur';
+$labels['dateformat'] = 'Datums-Format';
+$labels['timeformat'] = 'Zäit-Format';
+$labels['prettydate'] = 'Schéin Daten';
+$labels['setdefault'] = 'Als standard definéieren';
+$labels['autodetect'] = 'Automatesch';
+$labels['language'] = 'Sprooch';
+$labels['timezone'] = 'Zäitzon';
+$labels['pagesize'] = 'Reie pro Säit';
+$labels['signature'] = 'Ënnerschrëft';
+$labels['dstactive'] = 'Summerzäit';
+$labels['showinextwin'] = 'Message an neier Fënster opmaache';
+$labels['composeextwin'] = 'An enger neier Fënster schreiwen';
+$labels['htmleditor'] = 'HTML-Messagë schreiwen';
+$labels['htmlonreply'] = 'bei Äntwert op e Message mat Formatéierungen';
+$labels['htmlonreplyandforward'] = 'bei Weiderleedung oder Äntwert op e Message mat Formatéierungen';
+$labels['htmlsignature'] = 'Formatéiert Ënnerschrëft';
+$labels['showemail'] = 'Email-Adress mat ganzem Numm uweisen';
+$labels['previewpane'] = 'Virschau-Panneau uweisen';
+$labels['skin'] = 'Opmaachung vum Interface';
+$labels['logoutclear'] = 'Poubelle beim Logout eidelmaachen';
+$labels['logoutcompact'] = 'Mailbox beim Logout eidelmaachen';
+$labels['uisettings'] = 'Benotzer-Interface';
+$labels['serversettings'] = 'Server-Astellungen';
+$labels['mailboxview'] = 'Mailbox-Usiicht';
+$labels['mdnrequests'] = 'Bei Ufro no Empfanksbestätegung';
+$labels['askuser'] = 'mech froen';
+$labels['autosend'] = 'Bestätegung schécken';
+$labels['autosendknown'] = 'Bestätegung u meng Kontakter schécken, anerefalls nofroen';
+$labels['autosendknownignore'] = 'Bestätegung u meng Kontakter schécken, anerefalls ignoréieren';
+$labels['ignore'] = 'ignoréieren';
+$labels['readwhendeleted'] = 'Beim Läschen de Message als gelies markéieren';
+$labels['flagfordeletion'] = 'De Message als "läschbar" markéieren amplaz en ze läschen';
+$labels['skipdeleted'] = 'Geläschte Messagen net uweisen';
+$labels['deletealways'] = 'Falls Messagen net an d\'Poubelle kënne geréckelt ginn, läsch se';
+$labels['deletejunk'] = 'Messagen am Spam-Dossier direkt läschen';
+$labels['showremoteimages'] = 'Biller an de Maile vun externe Serveren nolueden';
+$labels['fromknownsenders'] = 'vu bekannte Senderen';
+$labels['always'] = 'ëmmer';
+$labels['showinlineimages'] = 'Biller déi drunhänken ënnert dem Message uweisen';
+$labels['autosavedraft'] = 'Brouillon automatesch späicheren';
+$labels['everynminutes'] = 'all $n Minutt(en)';
+$labels['refreshinterval'] = 'Frësch lueden (nei Messagen ofruffen, etc.)';
+$labels['never'] = 'ni';
+$labels['immediately'] = 'direkt';
+$labels['messagesdisplaying'] = 'Messagen uweisen';
+$labels['messagescomposition'] = 'Messagë schreiwen';
+$labels['mimeparamfolding'] = 'Nimm vun den Unhäng';
+$labels['2231folding'] = 'Kompletten RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (Microsoft Outlook)';
+$labels['2047folding'] = 'Kompletten RFC 2047 (anerer)';
+$labels['force7bit'] = 'MIME-Kodéierung fir 8-Bit-Zeeche benotzen';
+$labels['advancedoptions'] = 'Avancéiert Optiounen';
+$labels['focusonnewmessage'] = 'Browser-Fënster fokusséiere wann en neie Message ukënnt';
+$labels['checkallfolders'] = 'Nei Messagen an allen Dossieren opruffen';
+$labels['displaynext'] = 'Nom Réckelen/Läsche vun engem Message deen nächsten uweisen';
+$labels['defaultfont'] = 'Standard-Schrëft fir e Message mat Formatéierungen';
+$labels['mainoptions'] = 'Haapt-Optiounen';
+$labels['browseroptions'] = 'Browser-Optiounen';
+$labels['section'] = 'Beräich';
+$labels['maintenance'] = 'Maintenance';
+$labels['newmessage'] = 'Neie Message';
+$labels['signatureoptions'] = 'Optioune vun der Ënnerschrëft';
+$labels['whenreplying'] = 'Bei enger Äntwert';
+$labels['replyempty'] = 'den Original-Message net zitéieren';
+$labels['replytopposting'] = 'neie Message iwwert dem Zitat ufänken';
+$labels['replybottomposting'] = 'neie Message ënnert dem Zitat ufänken';
+$labels['replyremovesignature'] = 'Bei enger Äntwert d\'Original-Ënnerschrëft aus dem Message huelen';
+$labels['autoaddsignature'] = 'Ënnerschrëft automatesch drasetzen';
+$labels['newmessageonly'] = 'just bei neie Messagen';
+$labels['replyandforwardonly'] = 'just bei Äntwerten a Weiderleedungen';
+$labels['insertsignature'] = 'Ënnerschrëft drasetzen';
+$labels['previewpanemarkread'] = 'D\'Messagen an der Virschau als gelies markéieren';
+$labels['afternseconds'] = 'no $n Sekonnen';
+$labels['reqmdn'] = 'Ëmmer eng Empfanksbestätegung ufroen';
+$labels['reqdsn'] = 'Ëmmer eng Empfanks-Status-Meldung ufroen';
+$labels['replysamefolder'] = 'Äntwert an de selweschten Dossier setze wéi de Message op dee geäntwert gëtt';
+$labels['defaultabook'] = 'Standard Adress-Buch';
+$labels['autocompletesingle'] = 'Alternativ Email-Adressen bei der automatescher Vervollstänneung iwwersprangen';
+$labels['listnamedisplay'] = 'Kontakter oplëschten als';
+$labels['spellcheckbeforesend'] = 'Orthographie kontrolléieren bevir de Message verschéckt gëtt';
+$labels['spellcheckoptions'] = 'Orthographie-Korrektur-Optiounen';
+$labels['spellcheckignoresyms'] = 'Wierder mat Symboler ignoréieren';
+$labels['spellcheckignorenums'] = 'Wierder mat Zuelen ignoréieren';
+$labels['spellcheckignorecaps'] = 'Wierder mat just Groussbuschtawen ignoréieren';
+$labels['addtodict'] = 'An den Dictionnaire setzen';
+$labels['mailtoprotohandler'] = 'Protokoll-Handhaber fir "mailto:"-Links registréieren';
+$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';
+$labels['subscribed'] = 'Abonnéiert';
+$labels['messagecount'] = 'Messagen';
+$labels['create'] = 'Erstellen';
+$labels['createfolder'] = 'Neien Dossier erstellen';
+$labels['managefolders'] = 'Dossieren geréieren';
+$labels['specialfolders'] = 'Speziell Dossieren';
+$labels['properties'] = 'Astellungen';
+$labels['folderproperties'] = 'Dossiers-Astellungen';
+$labels['parentfolder'] = 'Elteren-Dossier';
+$labels['location'] = 'Plaz';
+$labels['info'] = 'Informatioun';
+$labels['getfoldersize'] = 'Klick fir d\'Dossiers-Gréisst ze kréien';
+$labels['changesubscription'] = 'Klick fir den Abonnement ze änneren';
+$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';
+$labels['easterneuropean'] = 'Ost-Europäesch';
+$labels['southeasterneuropean'] = 'Süd-Ost-Europäesch';
+$labels['baltic'] = 'Baltesch';
+$labels['cyrillic'] = 'Kyrilesch';
+$labels['arabic'] = 'Arabesch';
+$labels['greek'] = 'Griechesch';
+$labels['hebrew'] = 'Häbräesch';
+$labels['turkish'] = 'Türkesch';
+$labels['nordic'] = 'Nordesch';
+$labels['thai'] = 'Thai';
+$labels['celtic'] = 'Keltesch';
+$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
new file mode 100644
index 000000000..5599f227b
--- /dev/null
+++ b/program/localization/lb_LU/messages.inc
@@ -0,0 +1,176 @@
+<?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/
+*/
+
+$messages = array();
+$messages['errortitle'] = 'Ee Feeler ass opgetrueden!';
+$messages['loginfailed'] = 'Login feelgeschloen.';
+$messages['cookiesdisabled'] = 'Däi Browser acceptéiert keng Cookien.';
+$messages['sessionerror'] = 'Deng Sessioun ass ongëlteg oder verfall.';
+$messages['storageerror'] = 'D\'Verbindung mam Späicher-Server ass feelgeschloen.';
+$messages['servererror'] = 'Server-Feeler!';
+$messages['servererrormsg'] = 'Server-Feeler: $msg';
+$messages['dberror'] = 'Datebank-Feeler!';
+$messages['requesttimedout'] = 'D\'Ufro huet ze laang gedauert';
+$messages['errorreadonly'] = 'D\'Operatioun kann net ofgeschloss ginn. Den Dossier ass schreifgeschützt.';
+$messages['errornoperm'] = 'D\'Operatioun kann net ofgeschloss ginn. Zougrëff verweigert.';
+$messages['erroroverquota'] = 'D\'Operatioun konnt net ausgefouert ginn. Et ass net méi genuch Plaz um Disk.';
+$messages['erroroverquotadelete'] = 'Et ass net méi genuch Plaz um Disk. Benotz Shift+Delete fir e message ze läschen.';
+$messages['invalidrequest'] = 'Ongëlteg Ufro! Et goufe keng Date gespäichert.';
+$messages['invalidhost'] = 'Ongëltege Server-Numm.';
+$messages['nomessagesfound'] = 'Keng Messagen an der Mailbox fonnt.';
+$messages['loggedout'] = 'Du hues dech erfollegräich ofgemellt. Äddi!';
+$messages['mailboxempty'] = 'D\'Mailbox ass eidel.';
+$messages['refreshing'] = 'Lueden nei...';
+$messages['loading'] = 'Lueden...';
+$messages['uploading'] = 'Fichier gëtt eropgelueden...';
+$messages['uploadingmany'] = 'Fichiere ginn eropgelueden...';
+$messages['loadingdata'] = 'Date gi gelueden..';
+$messages['checkingmail'] = 'Nei Messagë ginn ofgeruff...';
+$messages['sendingmessage'] = 'Message gëtt geschéckt...';
+$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['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.';
+$messages['blockedimages'] = 'Fir deng Privatsphär ze schütze, gi Biller vun externe Serveren an dësem Message net gelueden.';
+$messages['encryptedmessage'] = 'Dëst ass e verschlësselte Message a kann net ugewise ginn. Et deet eis Leed!';
+$messages['nocontactsfound'] = 'Keng Kontakter fonnt.';
+$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['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.';
+$messages['errordeleting'] = 'D\'Messagë konnten net geläscht ginn.';
+$messages['errormarking'] = 'D\'Messagë konnten net markéiert ginn.';
+$messages['deletecontactconfirm'] = 'Wëlls du wierklech déi ausgewielte Kontakter läschen?';
+$messages['deletegroupconfirm'] = 'Wëlls du wierklech déi ausgewielte Gruppe läschen?';
+$messages['deletemessagesconfirm'] = 'Wëlls du wierklech déi ausgewielte Messagë läschen?';
+$messages['deletefolderconfirm'] = 'Wëlls du dësen Dossier wierklech läschen?';
+$messages['purgefolderconfirm'] = 'Wëlls du wierklech all d\'Messagen an dësem Dossier läschen?';
+$messages['contactdeleting'] = 'Kontakter gi geläscht...';
+$messages['groupdeleting'] = 'Grupp gëtt geläscht...';
+$messages['folderdeleting'] = 'Dossier gëtt geläscht...';
+$messages['foldermoving'] = 'Dossier gëtt geréckelt...';
+$messages['foldersubscribing'] = 'Dossier gëtt abonnéiert...';
+$messages['folderunsubscribing'] = 'Dossier gëtt desabonnéiert...';
+$messages['formincomplete'] = 'De Formular war net komplett ausgefëlt.';
+$messages['noemailwarning'] = 'Gëff w.e.gl eng gëlteg Email-Adress an.';
+$messages['nonamewarning'] = 'Gëff w.e.gl en Numm an.';
+$messages['nopagesizewarning'] = 'Gëff w.e.gl eng Säitegréisst an.';
+$messages['nosenderwarning'] = 'Gëff w.e.gl d\'Adress vum Ofsender an.';
+$messages['norecipientwarning'] = 'Gëff w.e.gl op mannst een Empfänger an.';
+$messages['nosubjectwarning'] = 'D\'Feld "Sujet" ass eidel. Wëlls du elo eent uginn?';
+$messages['nobodywarning'] = 'Soll dëse Message ouni Text verschéckt ginn?';
+$messages['notsentwarning'] = 'De Message gouf net verschéckt. Wëlls du e verwerfen?';
+$messages['noldapserver'] = 'Wiel w.e.gl en LDAP-Server fir d\'Sich aus.';
+$messages['nosearchname'] = 'Gëff w.e.gl en Numm oder eng E-Mail-Adress fir de Kontakt an.';
+$messages['notuploadedwarning'] = 'Net all d\'Unhäng goufen eropgelueden. Waart w.e.gl e Moment oder briech den Upload of.';
+$messages['searchsuccessful'] = '$nr Messagë fonnt.';
+$messages['contactsearchsuccessful'] = '$nr Kontakter fonnt.';
+$messages['searchnomatch'] = 'D\'Sich huet keng Treffer bruecht.';
+$messages['searching'] = 'Sichen...';
+$messages['checking'] = 'Kontrolléieren...';
+$messages['nospellerrors'] = 'Et goufe keng Schreiffeeler fonnt.';
+$messages['folderdeleted'] = 'Dossier erfollegräich geläscht.';
+$messages['foldersubscribed'] = 'Dossier erfollegräich abonnéiert.';
+$messages['folderunsubscribed'] = 'Dossier erfollegräich desabonnéiert.';
+$messages['folderpurged'] = 'Dossier erfollegräich eidelgemaach.';
+$messages['folderexpunged'] = 'Dossier erfollegräich kompaktéiert.';
+$messages['deletedsuccessfully'] = 'Erfollegräich geläscht.';
+$messages['converting'] = 'Formatéierunge gi geläscht...';
+$messages['messageopenerror'] = 'Message konnt net vum Server geluede ginn.';
+$messages['fileuploaderror'] = 'Upload vum Fichier feelgeschloen.';
+$messages['filesizeerror'] = 'Den eropgeluedene Fichier ass méi grouss wéi déi maximal erlaabte Gréisst vun $size.';
+$messages['copysuccess'] = 'Et goufen erfollegräich $nr Kontakter kopéiert.';
+$messages['movesuccess'] = 'Et goufen erfollegräich $nr Kontakter geréckelt.';
+$messages['copyerror'] = 'Konnt d\'Kontakter net kopéieren';
+$messages['moveerror'] = 'Konnt d\'Kontakter net réckelen.';
+$messages['sourceisreadonly'] = 'D\'Adresse-Quell ass schreifgeschützt.';
+$messages['errorsavingcontact'] = 'D\'Kontakt-Adress konnt net gespäichert ginn.';
+$messages['movingmessage'] = 'Messagë gi geréckelt...';
+$messages['copyingmessage'] = 'Messagë gi kopéiert...';
+$messages['copyingcontact'] = 'Kontakter gi kopéiert...';
+$messages['movingcontact'] = 'Kontakter gi geréckelt...';
+$messages['deletingmessage'] = 'Messagë gi geläscht...';
+$messages['markingmessage'] = 'Messagë gi markéiert...';
+$messages['addingmember'] = 'Kontakter ginn an d\'grupp gesat...';
+$messages['removingmember'] = 'Kontakter ginn aus der Grupp erausgeholl...';
+$messages['receiptsent'] = 'Empfanksbestätegung erfollegräich verschéckt.';
+$messages['errorsendingreceipt'] = 'Konnt d\'Bestätegung net verschécken.';
+$messages['deleteidentityconfirm'] = 'Wëlls du dës Identitéit wierklech läschen?';
+$messages['nodeletelastidentity'] = 'Du kanns dës Identitéit net läschen, well et deng lescht ass.';
+$messages['forbiddencharacter'] = 'Den Numm vum Dossier enthält verbueden Zeechen.';
+$messages['selectimportfile'] = 'Wuel w.e.gl e Fichier aus fir eropzelueden.';
+$messages['addresswriterror'] = 'Dat ausgewieltent Adressbucht ass schreifgeschützt.';
+$messages['contactaddedtogroup'] = 'Kontakter erfollegräich an d\'Grupp gesat.';
+$messages['contactremovedfromgroup'] = 'Kontakter erfollegräich aus der Grupp erausgeholl.';
+$messages['nogroupassignmentschanged'] = 'Keng Gruppen-Zouuerdnung geännert.';
+$messages['importwait'] = 'Import leeft, ee Moment w.e.gl...';
+$messages['importformaterror'] = 'Import feelgeschloen! Den eropgeluedene Fichier ass kee gëltegen Date-Fichier.';
+$messages['importconfirm'] = '<b>$inserted Kontakter erfollegräich importéiert</b>';
+$messages['importconfirmskipped'] = '<b>$skipped existéierend Anträg iwwersprongen</b>';
+$messages['importmessagesuccess'] = 'Erfollegräich $nr Messagen importéiert';
+$messages['importmessageerror'] = 'Import feelgeschloen! Den eropgeluedene Fichier ass kee gëltege Message oder kee Mailbox-Fichier.';
+$messages['opnotpermitted'] = 'Operatioun net zougelooss!';
+$messages['nofromaddress'] = 'An der ausgewieltener Identitéit feelt d\'E-Mail-Adress.';
+$messages['editorwarning'] = 'Bei engem Wiessel op den Text-Editor ginn all d\'Formatéierunge verluer. Wëlls du sécher weidermaachen?';
+$messages['httpreceivedencrypterror'] = 'E fatale Konfiguratiouns-Feeler ass opgetrueden. Kontaktéier w.e.gl. den Administrator esou séier ewéi méiglech. <b>Däi Message kann net geschéckt ginn.</b> ';
+$messages['smtpconnerror'] = 'SMTP-Feeler ($code): Et konnt keng Verbindung mam Server hirgestallt ginn.';
+$messages['smtpautherror'] = 'SMTP-Feeler ($code): Authentifizéierung feelgeschloen.';
+$messages['smtpfromerror'] = 'SMTP-Feeler ($code): Den Ofsender "$from" konnt net gesat ginn ($msg).';
+$messages['smtptoerror'] = 'SMTP-Feeler ($code): Den Empfänger "$to" konnt net dobäigesat ginn ($msg).';
+$messages['smtprecipientserror'] = 'SMTP-Feeler: D\'Empfänger-Lëscht kann net verschafft ginn.';
+$messages['smtperror'] = 'SMTP-Feeler: $msg';
+$messages['emailformaterror'] = 'Ongëlteg E-Mail-Adress: $email';
+$messages['toomanyrecipients'] = 'Zevill Empfänger. Reduzéier d\'Zuel vun den Empfänger op $max.';
+$messages['maxgroupmembersreached'] = 'D\'Unzuel vu Gruppememberen iwwersteigt de Maximum vun $max.';
+$messages['internalerror'] = 'En interne Feeler ass opgetrueden. Probéier w.e.gl nach eng Kéier.';
+$messages['contactdelerror'] = 'Kontakter konnten net geläscht ginn.';
+$messages['contactdeleted'] = 'Kontakter erfollegräich geläscht.';
+$messages['contactrestoreerror'] = 'Déi geläschte Kontakter konnten net recuperéiert ginn.';
+$messages['contactrestored'] = 'Kontakter erfollegräich recuperéiert.';
+$messages['groupdeleted'] = 'Grupp erfollegräich geläscht.';
+$messages['grouprenamed'] = 'Grupp erfollegräich ëmbenannt.';
+$messages['groupcreated'] = 'Grupp erfollegräich creéiert.';
+$messages['savedsearchdeleted'] = 'Déi gespäicherte Sich gouf erfollegräich geläscht.';
+$messages['savedsearchdeleteerror'] = 'Déi gespäicherte Sich konnt net geläscht ginn.';
+$messages['savedsearchcreated'] = 'Déi gespäicherte Sich gouf erfollegräich erstallt.';
+$messages['savedsearchcreateerror'] = 'Déi gespäicherte Sich konnt net erstallt ginn.';
+$messages['messagedeleted'] = 'Messagen erfollegräich geläscht.';
+$messages['messagemoved'] = 'Messagen erfollegräich geréckelt.';
+$messages['messagecopied'] = 'Messagen erfollegräich kopéiert.';
+$messages['messagemarked'] = 'Messagen erfollegräich markéiert.';
+$messages['autocompletechars'] = 'Gëff e mimumum vun $min Zeechen u fir déi automatesch Vervollstänegung.';
+$messages['autocompletemore'] = 'Et goufe méi passend Treffer fonnt. Tipp w.e.gl. nach e puer Buschtawe méi.';
+$messages['namecannotbeempty'] = 'Den Numm kann net eidel sinn.';
+$messages['nametoolong'] = 'Den Numm ass ze laang.';
+$messages['folderupdated'] = 'Dossier erfollegräich aktualiséiert.';
+$messages['foldercreated'] = 'Dossier erfollegräich ugeluecht.';
+$messages['invalidimageformat'] = 'Kee gëltegt Bild-Format';
+$messages['mispellingsfound'] = 'Et goufe Schreiffeeler am Message fonnt.';
+$messages['parentnotwritable'] = 'Den Dossier konnt net am ausgewielten Dossier erstallt oder an den Dossier erageréckelt ginn. Keng Zougrëffsrechter.';
+$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 376f9c771..31cb44d27 100644
--- a/program/localization/lt_LT/labels.inc
+++ b/program/localization/lt_LT/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Kopijuoti';
$labels['move'] = 'Perkelti';
$labels['moveto'] = 'Perkelti į…';
$labels['download'] = 'Parsisiųsti';
-$labels['open'] = 'Open';
+$labels['open'] = 'Atverti';
$labels['showattachment'] = 'Rodyti';
$labels['showanyway'] = 'Vistiek rodyti';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'matomus Å¡iame puslapyje';
$labels['unread'] = 'neskaitytus';
$labels['flagged'] = 'su gairele';
$labels['unanswered'] = 'neatsakytus';
+$labels['withattachment'] = 'Su priedu';
$labels['deleted'] = 'pašalintus';
$labels['undeleted'] = 'Neištrintas';
$labels['invert'] = 'invertuoti';
@@ -192,6 +194,7 @@ $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';
@@ -201,12 +204,13 @@ $labels['quicksearch'] = 'SparÄioji paieÅ¡ka';
$labels['resetsearch'] = 'Atšaukti paiešką';
$labels['searchmod'] = 'Paieškos modifikatoriai';
$labels['msgtext'] = 'Visas laiškas';
-$labels['body'] = 'Body';
+$labels['body'] = 'Laiško tekstas';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Atverti naujame lange';
$labels['emlsave'] = 'Parsisiųsti (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Rodyti grynojo teksto formatu';
+$labels['changeformathtml'] = 'Rodyti HTML formatu';
// message compose
$labels['editasnew'] = 'Redaguoti kaip naujÄ…';
@@ -338,8 +342,8 @@ $labels['composeto'] = 'Rašyti laišką';
$labels['contactsfromto'] = 'Adresatai nuo $from iki $to iš $count';
$labels['print'] = 'Spausdinti';
$labels['export'] = 'Eksportuoti';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Eksportuoti visus';
+$labels['exportsel'] = 'Eksportuoti pažymėtus';
$labels['exportvcards'] = 'Eksportuoti adresatus „vCard“ formatu';
$labels['newcontactgroup'] = 'Kurti adresatų grupę';
$labels['grouprename'] = 'Pervardinti grupÄ™';
@@ -353,6 +357,7 @@ $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ą';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Laiškus kurti HTML formatu';
$labels['htmlonreply'] = 'tik atsakymus į HTML formato laiškus';
$labels['htmlonreplyandforward'] = 'atsakant į HTML laiÅ¡kÄ… arba jį persiunÄiant';
$labels['htmlsignature'] = 'HTML parašas';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Rodyti laiško peržiūros polangį';
$labels['skin'] = 'Grafinis apvalkalas';
$labels['logoutclear'] = 'Išvalyti Šiukšlinę atsijungiant';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Pašalinti cituojamame laiške esantį paraš
$labels['autoaddsignature'] = 'Automatiškai pridėti parašą';
$labels['newmessageonly'] = 'tik naujuose laiškuose';
$labels['replyandforwardonly'] = 'tik atsakymuose ir persiunÄiamuose laiÅ¡kuose';
-$labels['replysignaturepos'] = 'Atsakant ir persiunÄiant laiÅ¡kus, paraÅ¡Ä… pridÄ—ti';
-$labels['belowquote'] = 'po citata';
-$labels['abovequote'] = 'virš citatos';
$labels['insertsignature'] = 'Pridėti parašą';
$labels['previewpanemarkread'] = 'Peržiūros polangyje parodytus laiškus žymėti skaitytais';
$labels['afternseconds'] = 'praÄ—jus $n sek.';
@@ -473,6 +476,7 @@ $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 6a8e00239..df19c291b 100644
--- a/program/localization/lt_LT/messages.inc
+++ b/program/localization/lt_LT/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Duomenų bazės klaida!';
$messages['requesttimedout'] = 'Baigėsi užklausai skirtas laikas';
$messages['errorreadonly'] = 'Nepavyko atlikti veiksmo – aplankas prieinamas tik skaitymui.';
$messages['errornoperm'] = 'Nepavyko atlikti veiksmo – nepakanka teisių.';
+$messages['erroroverquota'] = 'Nepavyko atlikti veiksmo. Diske trūksta laisvos vietos.';
+$messages['erroroverquotadelete'] = 'Diske trūksta laisvos vietos. Laiškui pašalinti naudokite Lyg2+Šal (Shift+Del) klavišų kombinaciją.';
$messages['invalidrequest'] = 'Netinkama užklausa! Duomenys neišsaugoti.';
$messages['invalidhost'] = 'Negalimas serverio vardas.';
$messages['nomessagesfound'] = 'Šioje pašto dėžutėje laiškų nėra.';
diff --git a/program/localization/lv_LV/labels.inc b/program/localization/lv_LV/labels.inc
index a71d5e554..0fe5b0faf 100644
--- a/program/localization/lv_LV/labels.inc
+++ b/program/localization/lv_LV/labels.inc
@@ -23,50 +23,51 @@ $labels['welcome'] = 'Esiet laipni lūgti $product';
$labels['username'] = 'LietotÄjvÄrds';
$labels['password'] = 'Parole';
$labels['server'] = 'Serveris';
-$labels['login'] = 'Pieslēgties';
+$labels['login'] = 'Autorizēties';
// taskbar
-$labels['logout'] = 'Atslēgties';
+$labels['logout'] = 'Iziet';
$labels['mail'] = 'E-pasts';
-$labels['settings'] = 'Personīgie iestatījumi';
+$labels['settings'] = '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'] = 'Miskaste';
+$labels['trash'] = 'Papīrgrozs';
$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'] = 'Sender';
+$labels['sender'] = 'SÅ«tÄ«tÄjs';
$labels['to'] = 'Kam';
$labels['cc'] = 'Cc';
$labels['bcc'] = 'Bcc';
-$labels['replyto'] = 'Reply-To';
-$labels['followupto'] = 'Followup-To';
+$labels['replyto'] = 'Atbildēt-Uz';
+$labels['followupto'] = 'Sekot-Uz';
$labels['date'] = 'Datums';
$labels['size'] = 'Izmērs';
$labels['priority'] = 'PrioritÄte';
$labels['organization'] = 'Uzņēmums';
$labels['readstatus'] = 'Izlasīšanas statuss';
-$labels['listoptions'] = 'List options...';
+$labels['listoptions'] = 'Vēstuļu saraksta attēlošanas iestatījumi...';
$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 of $count';
+$labels['messagenrof'] = '$nr. vēstule no $count';
+$labels['fromtoshort'] = '$from – $to no $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'] = 'Open';
-$labels['showattachment'] = 'Show';
-$labels['showanyway'] = 'Show it anyway';
+$labels['open'] = 'Atvērt';
+$labels['showattachment'] = 'RÄdÄ«t';
+$labels['showanyway'] = 'Vienalga rÄdÄ«t';
$labels['filename'] = 'Faila nosaukums';
$labels['filesize'] = 'Faila izmērs';
@@ -122,76 +123,78 @@ $labels['longdec'] = 'Decembris';
$labels['today'] = 'Å odien';
// toolbar buttons
-$labels['refresh'] = 'Refresh';
-$labels['checkmail'] = 'PÄrbaudÄ«t pastu';
+$labels['refresh'] = 'Atjaunot';
+$labels['checkmail'] = 'PÄrbaudÄ«t e-pastu';
$labels['compose'] = 'Rakstīt vēstuli';
$labels['writenewmessage'] = 'Rakstīt jaunu vēstuli';
-$labels['reply'] = 'Reply';
-$labels['replytomessage'] = 'Atbildēt';
-$labels['replytoallmessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam un visiem saņēmÄ“jiem';
+$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['replyall'] = 'Atbildēt visiem';
$labels['replylist'] = 'Atbildēt listei';
-$labels['forward'] = 'Forward';
+$labels['forward'] = 'PÄrsÅ«tÄ«t';
$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 miskasti';
-$labels['printmessage'] = 'izdrukÄt';
+$labels['movemessagetotrash'] = 'PÄrvietot vÄ“stuli uz papÄ«rgrozu';
+$labels['printmessage'] = 'IzdrukÄt Å¡o vÄ“stuli';
$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'] = '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['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['currpage'] = 'PaÅ¡reizÄ“jÄ lapa';
-$labels['unread'] = 'nelasÄ«tÄs';
-$labels['flagged'] = 'iezÄ«mÄ“tÄs';
-$labels['unanswered'] = 'neatbildÄ“tÄs';
-$labels['deleted'] = 'dzÄ“stÄs';
-$labels['undeleted'] = 'Not deleted';
-$labels['invert'] = 'invertēt';
+$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['filter'] = 'Filtrēt';
-$labels['list'] = 'Saraksts';
-$labels['threads'] = 'Vijumi';
+$labels['list'] = 'RÄdÄ«t kÄ sarakstu';
+$labels['threads'] = 'RÄdÄ«t kÄ vijumus';
$labels['expand-all'] = 'Izvērst visus';
-$labels['expand-unread'] = 'Izvērst neizlasītos';
-$labels['collapse-all'] = 'Savērst visu';
-$labels['threaded'] = 'Savīts';
+$labels['expand-unread'] = 'IzvÄ“rst neizlasÄ«tÄs';
+$labels['collapse-all'] = 'Sakļaut visas';
+$labels['threaded'] = 'RÄdÄ«t vijumus';
$labels['autoexpand_threads'] = 'Izvērst vēstuļu vijumus';
-$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['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['attachment'] = 'Pielikums';
-$labels['nonesort'] = 'Neviens';
+$labels['nonesort'] = 'Neviena';
$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Ärtot pÄ“c kolonnas';
+$labels['listsorting'] = 'KÄrtoÅ¡anas kolonnas';
$labels['listorder'] = 'KÄrtoÅ¡anas secÄ«ba';
-$labels['listmode'] = 'Saraksta režīms';
+$labels['listmode'] = 'Attēlošanas veids';
$labels['folderactions'] = 'Darbības ar mapēm...';
-$labels['compact'] = 'saspiest';
-$labels['empty'] = 'iztukšot';
+$labels['compact'] = 'Saspiest';
+$labels['empty'] = 'Iztukšot';
+$labels['importmessages'] = 'Importēt vēstules';
$labels['quota'] = 'Kvota';
$labels['unknown'] = 'nezinÄms';
@@ -199,35 +202,36 @@ $labels['unlimited'] = 'neierobežots';
$labels['quicksearch'] = 'Ä€rtÄ meklÄ“Å¡ana';
$labels['resetsearch'] = 'Atstatīt meklēšanu';
-$labels['searchmod'] = 'Meklēt laukos:';
-$labels['msgtext'] = 'VÄ“stules tekstÄ';
-$labels['body'] = 'Body';
+$labels['searchmod'] = 'Meklēšanas modifikatori:';
+$labels['msgtext'] = 'VisÄ vÄ“stulÄ“';
+$labels['body'] = 'Pamatteksts';
+$labels['type'] = 'Tips';
-$labels['openinextwin'] = 'atvÄ“rt jaunÄ logÄ';
+$labels['openinextwin'] = 'AtvÄ“rt jaunÄ logÄ';
$labels['emlsave'] = 'lejupielÄdÄ“t (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'RÄdÄ«t kÄ neformatÄ“tu tekstu';
+$labels['changeformathtml'] = 'RÄdÄ«t kÄ HTML formatÄ“tu';
// message compose
-$labels['editasnew'] = 'rediģēt kÄ jaunu';
-$labels['send'] = 'Send';
+$labels['editasnew'] = 'Rediģēt kÄ jaunu';
+$labels['send'] = 'Sūtīt';
$labels['sendmessage'] = 'Sūtīt vēstuli';
-$labels['savemessage'] = 'SaglabÄt uzmetumu';
+$labels['savemessage'] = 'SaglabÄt kÄ uzmetumu';
$labels['addattachment'] = 'Pievienot failu';
$labels['charset'] = 'Rakstzīmju kopa';
$labels['editortype'] = 'Redaktora tips';
$labels['returnreceipt'] = 'SaņemÅ¡anas apstiprinÄjums';
-$labels['dsn'] = 'Atskaite par piegÄdi';
+$labels['dsn'] = 'PiegÄdes atskaite';
$labels['mailreplyintro'] = '$sender @ $date rakstīja:';
$labels['originalmessage'] = 'SÄkotnÄ“jÄ vÄ“stule';
$labels['editidents'] = 'Rediģēt identitÄtes';
-$labels['spellcheck'] = 'Spell';
+$labels['spellcheck'] = 'IzrunÄt';
$labels['checkspelling'] = 'PÄrbaudÄ«t pareizrakstÄ«bu';
$labels['resumeediting'] = 'TurpinÄt rediģēšanu';
$labels['revertto'] = 'Atgriezt uz';
-$labels['attach'] = 'Attach';
+$labels['attach'] = 'Pievienot';
$labels['attachments'] = 'Pielikumi';
$labels['upload'] = 'AugÅ¡upielÄdÄ“t';
$labels['uploadprogress'] = '$percent ($current no $total)';
@@ -240,13 +244,13 @@ $labels['normal'] = 'NormÄla';
$labels['high'] = 'Augsta';
$labels['highest'] = 'AugstÄkÄ';
-$labels['nosubject'] = '(no subject)';
+$labels['nosubject'] = '(bez tēmas)';
$labels['showimages'] = 'RÄdÄ«t attÄ“lus';
-$labels['alwaysshow'] = 'VienmÄ“r rÄdÄ«t attÄ“lus no $sender';
+$labels['alwaysshow'] = 'VienmÄ“r rÄdÄ«t attÄ“lus vÄ“stulÄ“s, kuras sÅ«tÄ«jis $sender';
$labels['isdraft'] = 'Å is ir melnraksts.';
-$labels['andnmore'] = '$nr more...';
-$labels['togglemoreheaders'] = 'Show more message headers';
-$labels['togglefullheaders'] = 'Toggle raw message headers';
+$labels['andnmore'] = '$nr vairÄk...';
+$labels['togglemoreheaders'] = 'RÄdÄ«t galvenes papildus informÄciju';
+$labels['togglefullheaders'] = 'SlÄ“pt galvenes papildus informÄciju';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'VienkÄrÅ¡s teksts';
@@ -256,14 +260,14 @@ $labels['maxuploadsize'] = 'MaksimÄlais atļautais faila izmÄ“rs ir $size';
$labels['addcc'] = 'Pievienot Cc';
$labels['addbcc'] = 'Pievienot Bcc';
-$labels['addreplyto'] = 'Pievienot Reply-To';
+$labels['addreplyto'] = 'Pievienot Atbildēt-Uz';
$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 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 Å¡o apstiprinÄjumu?';
$labels['receiptread'] = 'SaņemÅ¡anas apstiprinÄjums';
-$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.';
+$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.';
// address boook
$labels['name'] = 'UzrÄdÄ«tais vÄrds';
@@ -272,33 +276,33 @@ $labels['surname'] = 'UzvÄrds';
$labels['middlename'] = 'Otrais vÄrds';
$labels['nameprefix'] = 'Prefikss';
$labels['namesuffix'] = 'Sufikss';
-$labels['nickname'] = 'Iesauka (nick)';
+$labels['nickname'] = 'SegvÄrds';
$labels['jobtitle'] = 'Amats';
$labels['department'] = 'Nodaļa';
$labels['gender'] = 'Dzimums';
-$labels['maidenname'] = 'PirmslaulÄ«bu uzvÄrds';
+$labels['maidenname'] = 'PirmslaulÄ«bas uzvÄrds';
$labels['email'] = 'E-pasts';
$labels['phone'] = 'TÄlrunis';
$labels['address'] = 'Adrese';
$labels['street'] = 'Iela';
$labels['locality'] = 'Pilsēta';
-$labels['zipcode'] = 'Pasta kods';
+$labels['zipcode'] = 'Pasta indekss';
$labels['region'] = 'Novads';
$labels['country'] = 'Pilsēta';
$labels['birthday'] = 'Dzimšanas diena';
$labels['anniversary'] = 'Gadadiena';
-$labels['website'] = 'Web lapa';
+$labels['website'] = 'MÄjaslapa';
$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 draugs';
+$labels['spouse'] = 'LaulÄtais';
$labels['allfields'] = 'Visi lauki';
$labels['search'] = 'Meklēt';
$labels['advsearch'] = 'PaplaÅ¡inÄtÄ meklÄ“Å¡ana';
-$labels['advanced'] = 'Advanced';
+$labels['advanced'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
$labels['other'] = 'Cits';
$labels['typehome'] = 'MÄjas';
@@ -306,22 +310,22 @@ $labels['typework'] = 'Darbs';
$labels['typeother'] = 'Cits';
$labels['typemobile'] = 'Mobilais tÄlrunis';
$labels['typemain'] = 'Galvenais';
-$labels['typehomefax'] = 'MÄjas Fax';
-$labels['typeworkfax'] = 'Darba Fax';
+$labels['typehomefax'] = 'Fakss mÄjÄs';
+$labels['typeworkfax'] = 'Fakss darbÄ';
$labels['typecar'] = 'Auto';
$labels['typepager'] = 'Peidžeris';
$labels['typevideo'] = 'Video';
$labels['typeassistant'] = 'Asistents';
-$labels['typehomepage'] = 'Web lapa';
+$labels['typehomepage'] = 'MÄjaslapa';
$labels['typeblog'] = 'Blogs';
$labels['typeprofile'] = 'Profils';
$labels['addfield'] = 'Pievienot lauku...';
-$labels['addcontact'] = 'Pievienot iezÄ«mÄ“to ierakstu adreÅ¡u grÄmatai';
-$labels['editcontact'] = 'Rediģēt adreÅ¡u grÄmatas ierakstu';
+$labels['addcontact'] = 'Pievienot jaunu kontaktu';
+$labels['editcontact'] = 'Rediģēt kontaktu';
$labels['contacts'] = 'Kontakti';
$labels['contactproperties'] = 'Kontakta īpašības';
-$labels['personalinfo'] = 'PersoniskÄ informÄcija';
+$labels['personalinfo'] = 'PersonÄ«gÄ informÄcija';
$labels['edit'] = 'Rediģēt';
$labels['cancel'] = 'Atcelt';
@@ -330,29 +334,30 @@ $labels['delete'] = 'Dzēst';
$labels['rename'] = 'PÄrdÄ“vÄ“t';
$labels['addphoto'] = 'Pievienot';
$labels['replacephoto'] = 'Aizvietot';
-$labels['uploadphoto'] = 'Upload photo';
+$labels['uploadphoto'] = 'AugÅ¡upielÄdÄ“t fotogrÄfiju';
-$labels['newcontact'] = 'Izveidot jaunu ierakstu';
-$labels['deletecontact'] = 'Dzēst iezīmētos ierakstus';
+$labels['newcontact'] = 'Izveidot jaunu kontaktu';
+$labels['deletecontact'] = 'Dzēst atzīmētos kontaktus';
$labels['composeto'] = 'Rakstīt vēstuli';
-$labels['contactsfromto'] = 'Ieraksti $from līdz $to no $count';
+$labels['contactsfromto'] = 'Ieraksti no $from lÄ«dz $to - kopÄ $count';
$labels['print'] = 'DrukÄt';
$labels['export'] = 'Eksportēt';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Eksportēt visu';
+$labels['exportsel'] = 'Eksportēt atzīmēto';
$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'] = 'Remove selected contacts from group';
+$labels['groupremoveselected'] = 'Dzēst atzīmētos kontaktus no grupas';
-$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['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['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';
@@ -361,71 +366,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'] = '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['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['done'] = 'Pabeigts';
// settings
$labels['settingsfor'] = 'Iestatījumi';
$labels['about'] = 'Par';
$labels['preferences'] = 'Iestatījumi';
-$labels['userpreferences'] = 'LietotÄja preferences';
-$labels['editpreferences'] = 'Rediģēt lietotÄja preferences';
+$labels['userpreferences'] = 'LietotÄja iestatÄ«jumi';
+$labels['editpreferences'] = 'Rediģēt iestatījumus';
$labels['identities'] = 'IdentitÄtes';
-$labels['manageidentities'] = 'Rediģēt Å¡Ä« konta identitÄtes';
+$labels['manageidentities'] = 'Rediģēt identitÄtes';
$labels['newidentity'] = 'Jauna identitÄte';
$labels['newitem'] = 'Jauns';
$labels['edititem'] = 'Rediģēt';
-$labels['preferhtml'] = 'Dot priekÅ¡roku HTML formatÄ“tÄm vÄ“stulÄ“m';
+$labels['preferhtml'] = 'RÄdÄ«t HTML formatÄ“tÄs vÄ“stules';
$labels['defaultcharset'] = 'NoklusÄ“tÄ rakstzÄ«mju kopa';
-$labels['htmlmessage'] = 'HTML vēstule';
-$labels['messagepart'] = 'Part';
-$labels['digitalsig'] = 'Digital Signature';
+$labels['htmlmessage'] = 'HTML formatēta vēstule';
+$labels['messagepart'] = 'Daļa';
+$labels['digitalsig'] = 'DigitÄlais paraksts';
$labels['dateformat'] = 'Datuma formÄts';
$labels['timeformat'] = 'Laika formÄts';
-$labels['prettydate'] = 'Formatēt datumus';
+$labels['prettydate'] = 'RÄdÄ«t Ä«sos datumus';
$labels['setdefault'] = 'Uzlikt kÄ noklusÄ“to';
-$labels['autodetect'] = 'AutomÄtiski';
+$labels['autodetect'] = 'AutomÄtiska';
$labels['language'] = 'Valoda';
$labels['timezone'] = 'Laika zona';
$labels['pagesize'] = 'Rindas lapÄ';
$labels['signature'] = 'Paraksts';
$labels['dstactive'] = 'Vasaras/ziemas laiks';
-$labels['showinextwin'] = 'Open message in a new window';
-$labels['composeextwin'] = 'Compose in a new window';
-$labels['htmleditor'] = 'Rakstīt HTML vēstules';
+$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['htmlonreply'] = 'tikai atbildot uz HTML formatÄ“tÄm vÄ“stulÄ“m';
-$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
-$labels['htmlsignature'] = 'HTML paraksts';
+$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['previewpane'] = 'RÄdÄ«t priekÅ¡skatÄ«juma paneli';
-$labels['skin'] = 'Interfeisa izskats';
-$labels['logoutclear'] = 'Izejot no sistēmas, iztīrīt miskasti';
-$labels['logoutcompact'] = 'Izejot no sistēmas, saspiest iesūtni';
+$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['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 lietotÄjam';
+$labels['askuser'] = 'jautÄt man vai sÅ«tÄ«t';
$labels['autosend'] = 'sÅ«tÄ«t automÄtiski';
-$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['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['skipdeleted'] = 'NerÄdÄ«t dzÄ“stÄs vÄ“stules';
-$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['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['always'] = 'vienmēr';
$labels['showinlineimages'] = 'RÄdÄ«t pielikuma attÄ“lus zem 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['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['never'] = 'nekad';
$labels['immediately'] = 'nekavējoties';
$labels['messagesdisplaying'] = 'Vēstuļu attēlošana';
@@ -435,47 +441,45 @@ $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Ä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['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['mainoptions'] = 'Galvenie iestatījumi';
-$labels['browseroptions'] = 'Browser Options';
-$labels['section'] = 'Kategorija';
+$labels['browseroptions'] = 'PÄrlÅ«ka iestatÄ«jumi';
+$labels['section'] = 'Sadaļa';
$labels['maintenance'] = 'Uzturēšana';
$labels['newmessage'] = 'VÄ“stuļu pienÄkÅ¡ana';
$labels['signatureoptions'] = 'Paraksta iestatījumi';
$labels['whenreplying'] = 'Atbildot';
-$labels['replyempty'] = 'do not quote the original message';
+$labels['replyempty'] = 'neiekļaut vÄ“stules sÄkotnÄ“jo tekstu';
$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 jaunas vēstules';
-$labels['replyandforwardonly'] = 'tikai atbildes un pÄrsÅ«tÄ«jumi';
-$labels['replysignaturepos'] = 'Atbildot vai pÄrsÅ«tot ievietot parakstu';
-$labels['belowquote'] = 'zem citÄta';
-$labels['abovequote'] = 'virs citÄta';
+$labels['newmessageonly'] = 'tikai jaunÄm vÄ“stulÄ“m';
+$labels['replyandforwardonly'] = 'tikai atbildÄ“m un pÄrsÅ«tÄ«jumiem';
$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 atskati par vēstules izlasīšanu';
-$labels['reqdsn'] = 'VienmÄ“r pieprasÄ«t atskati par vÄ“stules piegÄdÄÅ¡anu saņēmÄ“ja serverim';
+$labels['reqmdn'] = 'VienmÄ“r pieprasÄ«t saņemÅ¡anas apstiprinÄjumu';
+$labels['reqdsn'] = 'VienmÄ“r pieprasÄ«t atskati par piegÄdi';
$labels['replysamefolder'] = 'GlabÄt atbildes tajÄ paÅ¡Ä mapÄ“, kurÄ ir vÄ“stule, uz kuru tika atbildÄ“ts';
-$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['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['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'] = 'Register protocol handler for mailto: links';
-$labels['forwardmode'] = 'Messages forwarding';
-$labels['inline'] = 'inline';
-$labels['asattachment'] = 'as attachment';
+$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['folder'] = 'Mapi';
$labels['folders'] = 'Mapes';
@@ -492,8 +496,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ēšanu';
-$labels['foldertype'] = 'Mapes veids';
+$labels['changesubscription'] = 'Uzklikšķiniet, lai mainītu abonēšanas iestatījumus';
+$labels['foldertype'] = 'Mapes tips';
$labels['personalfolder'] = 'PrivÄta mape';
$labels['otherfolder'] = 'Cita lietotÄja mape';
$labels['sharedfolder'] = 'Publiska mape';
@@ -503,7 +507,7 @@ $labels['sortasc'] = 'KÄrtot augoÅ¡Ä secÄ«bÄ';
$labels['sortdesc'] = 'KÄrtot dilstoÅ¡Ä secÄ«bÄ';
$labels['undo'] = 'Atsaukt';
-$labels['installedplugins'] = 'Installed plugins';
+$labels['installedplugins'] = 'UzstÄdÄ«tie spraudņi';
$labels['plugin'] = 'Spraudnis';
$labels['version'] = 'Versija';
$labels['source'] = 'OriÄ£inÄls';
@@ -517,7 +521,7 @@ $labels['MB'] = 'MB';
$labels['GB'] = 'GB';
// character sets
-$labels['unicode'] = 'Unikoda';
+$labels['unicode'] = 'Unikods';
$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 d65976fa2..37ceb0463 100644
--- a/program/localization/lv_LV/messages.inc
+++ b/program/localization/lv_LV/messages.inc
@@ -17,153 +17,157 @@
*/
$messages = array();
-$messages['errortitle'] = 'An error occurred!';
-$messages['loginfailed'] = 'NeizdevÄs pieslÄ“gties';
+$messages['errortitle'] = 'RadÄs kļūda!';
+$messages['loginfailed'] = 'PieslÄ“gties neizdevÄs';
$messages['cookiesdisabled'] = 'JÅ«su pÄrlÅ«kprogramma neatbalsta sÄ«kdatnes (cookies)';
-$messages['sessionerror'] = 'JÅ«su sessija ir beigusies';
+$messages['sessionerror'] = 'JÅ«su sessija ir beigusies.';
$messages['storageerror'] = 'NeizdevÄs pieslÄ“gties IMAP serverim';
-$messages['servererror'] = 'Servera kļūme.';
+$messages['servererror'] = 'Servera kļūda!';
$messages['servererrormsg'] = 'Servera kļūda: $msg';
$messages['dberror'] = 'DatubÄzes kļūda!';
-$messages['requesttimedout'] = 'Request timed out';
-$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['invalidrequest'] = 'NederÄ«gs pieprasÄ«jums. Dati netika saglabÄti.';
-$messages['invalidhost'] = 'Invalid server name.';
+$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['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';
$messages['nomessagesfound'] = 'Å ajÄ pastkastÄ“ nav vÄ“stuļu';
-$messages['loggedout'] = 'Jūs esat veiksmīgi atslēdzies no sistēmas';
-$messages['mailboxempty'] = 'Pastkaste tukša';
-$messages['refreshing'] = 'Refreshing...';
+$messages['loggedout'] = 'Jūs esat veiksmīgi atslēdzies no sistēmas. Uz redzēšanos!';
+$messages['mailboxempty'] = 'Pastkaste ir tukša';
+$messages['refreshing'] = 'Atjauno...';
$messages['loading'] = 'Notiek ielÄde...';
-$messages['uploading'] = 'Notiek faila augÅ¡upielÄde...';
+$messages['uploading'] = 'AugÅ¡upielÄde failu...';
$messages['uploadingmany'] = 'AugÅ¡upielÄdÄ“ failus...';
-$messages['loadingdata'] = 'Tiek ielÄdÄ“ti dati...';
-$messages['checkingmail'] = 'Notiek pasta pÄrbaude...';
-$messages['sendingmessage'] = 'Tiek sūtīta vēstule...';
+$messages['loadingdata'] = 'IelÄdÄ“ datus...';
+$messages['checkingmail'] = 'Notiek pasta pÄrbaude ...';
+$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 pie uzmetumiem';
-$messages['successfullysaved'] = 'IestatÄ«jumi veiksmÄ«gi saglabÄti';
-$messages['addedsuccessfully'] = 'Ieraksts veiksmÄ«gi pievienots adreÅ¡u grÄmatai';
-$messages['contactexists'] = 'Ieraksts ar Å¡Ädu e-pasta adresi jau eksistÄ“';
+$messages['savingmessage'] = 'VÄ“stule tiek saglabÄta ...';
+$messages['messagesaved'] = 'VÄ“stule saglabÄta Uzmetumos';
+$messages['successfullysaved'] = 'VeiksmÄ«gi saglabÄts.';
+$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Ä“.';
-$messages['blockedimages'] = 'DroÅ¡Ä«bas nolÅ«kos attÄ“li, kas tiek ielÄdÄ“ti no cita servera, Å¡ajÄ vÄ“stulÄ“ ir bloÄ·Ä“ti';
-$messages['encryptedmessage'] = 'Å Ä« ir Å¡ifrÄ“ta vÄ“stule un diemžēl nevar tikt parÄdÄ«ta';
-$messages['nocontactsfound'] = 'Ieraksti netika atrasti';
-$messages['contactnotfound'] = 'Prasītais kontakts nav atrasts';
-$messages['contactsearchonly'] = 'Ievadiet meklēšanas kritērijus, lai atrastu kontaktus';
+$messages['blockedimages'] = 'DroÅ¡Ä«bas nolÅ«kos attÄ“li, kuri tiek ielÄdÄ“ti no cita servera, Å¡ajÄ vÄ“stulÄ“ ir bloÄ·Ä“ti';
+$messages['encryptedmessage'] = 'Atvainojiet - Å¡Ä« ir Å¡ifrÄ“ta vÄ“stule un diemžēl nevar tikt parÄdÄ«ta ...';
+$messages['nocontactsfound'] = 'Kontakti netika atrasti';
+$messages['contactnotfound'] = 'Pieprasītais kontakts nav atrasts';
+$messages['contactsearchonly'] = 'Lai atrastu kontaktus, ievadiet meklēšanas kritērijus';
$messages['sendingfailed'] = 'Vēstule netika nosūtīta';
$messages['senttooquickly'] = 'Lūdzu uzgaidiet $sec sekundi(-es) pirms sūtiet šo vēstuli';
-$messages['errorsavingsent'] = 'Notika kļūda saglabÄjot nosÅ«tÄ«to vÄ“stuli';
-$messages['errorsaving'] = 'SaglabÄjot vÄ“stuli notikusi kļūme, vÄ“stule netika saglabÄta';
-$messages['errormoving'] = 'VÄ“stule netika pÄrvietota';
-$messages['errorcopying'] = 'NeizdevÄs pÄrkopÄ“t vÄ“stules.';
-$messages['errordeleting'] = 'Vēstule netika dzēsta';
-$messages['errormarking'] = 'Nebija iespējams iezīmēt vēstuli';
-$messages['deletecontactconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st iezÄ«mÄ“to(Äs) kontaktpersonas?';
+$messages['errorsavingsent'] = 'SaglabÄjot vÄ“stuli notika kļūda - vÄ“stule netika saglabÄta';
+$messages['errorsaving'] = 'SaglabÄjot notika kļūda';
+$messages['errormoving'] = 'VÄ“stule(s) netika pÄrvietota(s)';
+$messages['errorcopying'] = 'VÄ“stules pÄrkopÄ“t neizdevÄs';
+$messages['errordeleting'] = 'VÄ“stules izdzÄ“st neizdevÄs';
+$messages['errormarking'] = 'Iezīmēt vēstules nebija iespējams';
+$messages['deletecontactconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st iezÄ«mÄ“tÄs kontaktpersonas?';
$messages['deletegroupconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to grupu?';
-$messages['deletemessagesconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st iezÄ«mÄ“to(Äs) vÄ“stules?';
+$messages['deletemessagesconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st iezÄ«mÄ“tÄs vÄ“stules?';
$messages['deletefolderconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡o mapi?';
-$messages['purgefolderconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st visas vÄ“stules, kas atrodas Å¡ajÄ mapÄ“?';
-$messages['contactdeleting'] = 'Kontakts(-i) tiek dzēsti...';
+$messages['purgefolderconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st visas vÄ“stules, kuras atrodas Å¡ajÄ mapÄ“?';
+$messages['contactdeleting'] = 'Dzēš kontaktus...';
$messages['groupdeleting'] = 'Dzēš grupu...';
$messages['folderdeleting'] = 'Dzēš mapi...';
-$messages['foldermoving'] = 'PÄrvietoju mapi...';
+$messages['foldermoving'] = 'PÄrvieto mapi...';
$messages['foldersubscribing'] = 'Pieslēdz mapi...';
$messages['folderunsubscribing'] = 'Atslēdz mapi...';
-$messages['formincomplete'] = 'FormulÄrs nav pilnÄ«bÄ aizpildÄ«ts';
-$messages['noemailwarning'] = 'LÅ«dzu ievadiet pareizu e-pasta adresi';
+$messages['formincomplete'] = 'Forma nav pilnÄ«bÄ aizpildÄ«ta';
+$messages['noemailwarning'] = 'LÅ«dzu ievadiet korektu e-pasta adresi';
$messages['nonamewarning'] = 'LÅ«dzu ievadiet vÄrdu';
$messages['nopagesizewarning'] = 'Lūdzu ievadiet lapas izmēru';
-$messages['nosenderwarning'] = 'Lūdzu ievadiet saņēmēja e-pasta adresi';
+$messages['nosenderwarning'] = 'LÅ«dzu ievadiet sÅ«tÄ«tÄja e-pasta adresi';
$messages['norecipientwarning'] = 'Lūdzu ievadiet vismaz vienu saņēmēju';
$messages['nosubjectwarning'] = 'Lauks "temats" ir tukšs. Vai vēlaties to aizpildīt tagad?';
-$messages['nobodywarning'] = 'Sūtīt vēstuli bez satura teksta?';
-$messages['notsentwarning'] = 'VÄ“stule netika nosÅ«tÄ«ta. Vai tieÅ¡Äm vÄ“laties atcelt vÄ“stules rakstÄ«sanu?';
-$messages['noldapserver'] = 'Lūdzu izvēlaties LDAP serveri';
+$messages['nobodywarning'] = 'Sūtīt vēstuli bez teksta?';
+$messages['notsentwarning'] = 'VÄ“stule netika nosÅ«tÄ«ta. Vai tieÅ¡Äm vÄ“laties atcelt vÄ“stules rakstÄ«Å¡anu?';
+$messages['noldapserver'] = 'Lai meklētu, lūdzu izvēlaties LDAP serveri';
$messages['nosearchname'] = 'LÅ«dzu ievadiet kontaktpersonas vÄrdu vai e-pasta adresi';
-$messages['notuploadedwarning'] = 'Visi pielikumi vÄ“l nav augÅ¡upielÄdÄ“ti. LÅ«dzu uzgaidiet vai atceļiet augÅ¡upielÄdi!';
+$messages['notuploadedwarning'] = 'Visi pielikumi vÄ“l nav augÅ¡upielÄdÄ“ti - lÅ«dzu uzgaidiet vai atceļiet augÅ¡upielÄdi';
$messages['searchsuccessful'] = 'Atrastas $nr vēstules';
-$messages['contactsearchsuccessful'] = 'Atrasti $nr kontakti.';
-$messages['searchnomatch'] = 'MeklÄ“Å¡anÄ nekas netika atrasts';
-$messages['searching'] = 'Notiek meklēšana...';
-$messages['checking'] = 'Notiek pÄrbaude...';
-$messages['nospellerrors'] = 'Netika atrastas pareizrakstības kļudas';
+$messages['contactsearchsuccessful'] = 'Atrasti $nr kontakti';
+$messages['searchnomatch'] = 'Meklējot nekas netika atrasts';
+$messages['searching'] = 'Meklē...';
+$messages['checking'] = 'PÄrbauda...';
+$messages['nospellerrors'] = 'Pareizrakstības kļūdas netika atrastas';
$messages['folderdeleted'] = 'Mape veiksmīgi izdzēsta';
$messages['foldersubscribed'] = 'Mape veiksmīgi pieslēgta.';
$messages['folderunsubscribed'] = 'Mape veiksmīgi atslēgta.';
$messages['folderpurged'] = 'Mape tika veiksmīgi iztukšota.';
-$messages['folderexpunged'] = 'Mape tika veiksmīgi saspiesta.';
+$messages['folderexpunged'] = 'Mape saspiesta veiksmīgi';
$messages['deletedsuccessfully'] = 'Veiksmīgi izdzēsts';
-$messages['converting'] = 'Tiek novÄkts vÄ“stules formatÄ“jums...';
+$messages['converting'] = 'Tiek noņemts vēstules formatējums...';
$messages['messageopenerror'] = 'NevarÄ“ja ielÄdÄ“t vÄ“stuli no servera';
-$messages['fileuploaderror'] = 'NeizdevÄs ielÄdÄ“t failu';
-$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['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['sourceisreadonly'] = 'Adreses avots ir lasÄ«Å¡anas režīmÄ tikai';
-$messages['errorsavingcontact'] = 'NevarÄ“ja saglabÄt kontakta adreses';
-$messages['movingmessage'] = 'PÄrvietoju vÄ“stules...';
+$messages['errorsavingcontact'] = 'Kontakta adresi nevarÄ“ja saglabÄt.';
+$messages['movingmessage'] = 'PÄrvieto vÄ“stules...';
$messages['copyingmessage'] = 'Kopē vēstules...';
$messages['copyingcontact'] = 'Kopē kontaktus...';
$messages['deletingmessage'] = 'Dzēš vēstules...';
$messages['markingmessage'] = 'Atzīmē vēstules...';
-$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['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['contactaddedtogroup'] = 'Kontakti tika veiksmīgi pievienoti šai grupai.';
$messages['contactremovedfromgroup'] = 'Kontakti tika veiksmīgi atvienoti no šīs grupas.';
-$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$messages['nogroupassignmentschanged'] = 'GrupÄ nekas netika mainÄ«ts.';
$messages['importwait'] = 'Importēju, lūdzu uzgaidiet...';
-$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
-$messages['importconfirm'] = '<b>Veiksmīgi ieimportēti $inserted kontakti, netika importēti $skipped esoši ieraksti</b>:<p><em>$names</em></p>';
+$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['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 vÄ“laties turpinÄt?';
-$messages['httpreceivedencrypterror'] = 'Kļūme. Lūdzu sazinieties ar administratoru. <b>Nav iespējams nosūtīt vēstuli.</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 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['smtpconnerror'] = 'SMTP kļūme ($code): NeizdevÄs pieslÄ“gties serverim';
-$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['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['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'] = '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['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['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 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['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['namecannotbeempty'] = 'LÅ«dzu ievadiet vÄrdu.';
-$messages['nametoolong'] = 'VÄrds ir par garu.';
+$messages['nametoolong'] = 'VÄrds ir pÄrÄk garÅ¡.';
$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 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'] = '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'] = '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['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.';
?>
diff --git a/program/localization/mk_MK/labels.inc b/program/localization/mk_MK/labels.inc
index c8190276e..519df5823 100755
--- a/program/localization/mk_MK/labels.inc
+++ b/program/localization/mk_MK/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Ðепратени';
$labels['sent'] = 'Пратени';
$labels['trash'] = 'Корпа';
$labels['junk'] = 'Ѓубре';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÐаÑлов';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Ðепрочитани';
$labels['flagged'] = 'Обележано';
$labels['unanswered'] = 'Ðеодговорено';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Избришано';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Обратно';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Компактно';
$labels['empty'] = 'ИÑпразни';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ИÑкориÑтен проÑтор';
$labels['unknown'] = 'непознато';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'Ðово пребарување';
$labels['searchmod'] = 'Модификатори на пребарувањето';
$labels['msgtext'] = 'Цело пиÑмо';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори во нов прозорец';
$labels['emlsave'] = 'Преземи (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Прикажи ја поÑледната Ñтран
$labels['group'] = 'Group';
$labels['groups'] = 'Групи';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Лични адреÑи';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Пиши HTML порака';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML потпиÑ';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Прикажи прозорец за преглед';
$labels['skin'] = 'Модел на изгледот';
$labels['logoutclear'] = 'ИÑчиÑти ја Кантата при излез';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'При одговарање отÑтрани
$labels['autoaddsignature'] = 'ÐвтоматÑки додавај потпиÑ';
$labels['newmessageonly'] = 'Ñамо нови пиÑма';
$labels['replyandforwardonly'] = 'Ñамо одгорови и препраќања';
-$labels['replysignaturepos'] = 'При одговарање или препраќање Ñтави потпиÑ';
-$labels['belowquote'] = 'под цитираното';
-$labels['abovequote'] = 'над цитираното';
$labels['insertsignature'] = 'Вметни потпиÑ';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = 'after $n seconds';
@@ -473,6 +476,7 @@ $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 c14370b14..f7a8d9a12 100755
--- a/program/localization/mk_MK/messages.inc
+++ b/program/localization/mk_MK/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Ðеважечко барање! Податоците не Ñе зачувани.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'Ðемате пиÑма во ова Ñандаче';
diff --git a/program/localization/ml_IN/labels.inc b/program/localization/ml_IN/labels.inc
index 463256c0e..7d3fdc501 100644
--- a/program/localization/ml_IN/labels.inc
+++ b/program/localization/ml_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'പൂരàµâ€à´¤àµà´¤à´¿à´¯à´¾à´•à´¾à´¤àµà´¤à´µ';
$labels['sent'] = 'അയചàµà´šà´µ';
$labels['trash'] = 'ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿ';
$labels['junk'] = 'ആവശàµà´¯à´®à´¿à´²àµà´²à´¾à´¤àµà´¤à´µ';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'വിഷയം';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'നിലവിലàµà´³à´³ പേജàµ';
$labels['unread'] = 'വായികàµà´•à´¾à´¤àµà´¤à´¤àµ';
$labels['flagged'] = 'അടയാളപàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯à´µ';
$labels['unanswered'] = 'മറàµà´ªà´Ÿà´¿ കൊടàµà´•àµà´•à´¾à´¤àµà´¤';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'മായàµà´šàµà´šà´µ';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'തലതിരികàµà´•àµà´•';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'à´šàµà´°àµà´•àµà´•àµ';
$labels['empty'] = 'ശൂനàµà´¯à´‚';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'à´¡à´¿à´¸àµà´•àµà´•àµ ഉപയോഗം';
$labels['unknown'] = 'അറിയാതàµà´¤';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'à´®àµà´´àµà´µà´¨àµâ€ സനàµà´¦àµ‡à´¶à´µàµà´‚';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'à´ªàµà´¤à´¿à´¯ വിനàµâ€à´¡àµ‹à´¯à´¿à´²àµâ€ à´¤àµà´±à´•àµà´•àµà´•';
$labels['emlsave'] = 'Download (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'കൂടàµà´Ÿà´‚';
$labels['groups'] = 'കൂടàµà´Ÿà´™àµà´™à´³àµâ€';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'à´¸àµà´µà´•à´¾à´°àµà´¯ വിലാസങàµà´™à´³àµâ€';
$labels['searchsave'] = 'തിരയലàµâ€ സൂകàµà´·à´¿à´•àµà´•àµà´•';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML സനàµà´¦àµ‡à´¶à´™àµà´™à´³àµâ€ à´°à´šà´¿à´•à
$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';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$labels['autoaddsignature'] = 'Automatically add signature';
$labels['newmessageonly'] = 'à´ªàµà´¤à´¿à´¯ സനàµà´¦àµ‡à´¶à´‚ മാതàµà´°à´‚';
$labels['replyandforwardonly'] = 'replies and forwards only';
-$labels['replysignaturepos'] = 'When replying or forwarding place signature';
-$labels['belowquote'] = 'ഉദàµà´§à´¾à´°à´£à´¤àµà´¤à´¿à´¨àµ താഴെ';
-$labels['abovequote'] = 'above the quote';
$labels['insertsignature'] = 'Insert signature';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = '$n നിമിഷങàµà´™à´³àµâ€ à´•à´´à´¿à´žàµà´žàµàµ';
@@ -473,6 +476,7 @@ $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 85dc43d77..28eb22be2 100644
--- a/program/localization/ml_IN/messages.inc
+++ b/program/localization/ml_IN/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Database Error!';
$messages['requesttimedout'] = 'Request timed out';
$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
$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['invalidrequest'] = 'അസാധàµà´µà´¾à´¯ അപേകàµà´· ! ഒരൠരേഖയàµà´‚ സൂകàµà´·à´¿à´šàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´²';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'No messages found in this mailbox.';
diff --git a/program/localization/mr_IN/labels.inc b/program/localization/mr_IN/labels.inc
index 804fb5651..d26583d4d 100755
--- a/program/localization/mr_IN/labels.inc
+++ b/program/localization/mr_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'मसà¥à¤¦à¤¾';
$labels['sent'] = 'पाठवलेले';
$labels['trash'] = 'कचरा पेटी';
$labels['junk'] = 'नको असलेले कचरा संदेश';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विषय';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'सधà¥â€à¤¯à¤¾à¤šà¥‡ पान';
$labels['unread'] = 'न वाचलेले';
$labels['flagged'] = 'खूण लावलेले';
$labels['unanswered'] = 'उतà¥à¤¤à¤° न दिलेले';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'काढून टाकलेला(ले)';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'उलट करा';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'यादी दरà¥à¤¶à¤• पधà¥â€à¤¦à¤¤';
$labels['folderactions'] = 'फोलà¥à¤¡à¤° कृती..';
$labels['compact'] = 'छोटा';
$labels['empty'] = 'रिकामा';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤•à¤šà¤¾ वापर';
$labels['unknown'] = 'माहित नसलेला';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'परत शोध';
$labels['searchmod'] = 'बदलकरà¥à¤¤à¥â€à¤¯à¤¾à¤‚ना शोधा';
$labels['msgtext'] = 'संपूरà¥à¤£ संदेश';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'नवीन खिडकी उघडा';
$labels['emlsave'] = 'इà¤à¤®à¤à¤² सà¥â€à¤µà¤°à¥‚पात उतरवून घà¥à¤¯à¤¾';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'शेवटचा संच दाखवा';
$labels['group'] = 'गट';
$labels['groups'] = 'अनेक गट';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'वैयकà¥à¤¤à¤¿à¤• पतà¥à¤¤à¥‡';
$labels['searchsave'] = 'शोध जतन करा';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'à¤à¤š टी à¤à¤® à¤à¤² संदेश तयाà¤
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'à¤à¤š टी à¤à¤® à¤à¤² सही';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾à¤ªà¥‚रà¥à¤µ तावदान दाखवा';
$labels['skin'] = 'दृषà¥à¤¯ गोषà¥à¤Ÿà¥€';
$labels['logoutclear'] = 'खातà¥à¤¯à¤¾à¤¤à¥‚न बाहेर पडतांना कचरा पेटी साफ करा';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'उतà¥â€à¤¤à¤° देताना मà¥à
$labels['autoaddsignature'] = 'आपोआप सही करा';
$labels['newmessageonly'] = 'फकà¥â€à¤¤ नवीन संदेश';
$labels['replyandforwardonly'] = 'फकà¥â€à¤¤ उतà¥â€à¤¤à¤°à¥‡ आâ€à¤£à¥€ पà¥à¤¢à¥‡ पाठवलेले संदेश';
-$labels['replysignaturepos'] = 'उतà¥â€à¤¤à¤° देताना किंवा पà¥à¤¢à¥‡ पाठवताना सही करा';
-$labels['belowquote'] = 'उतारया खाली';
-$labels['abovequote'] = 'उतारयाचà¥â€à¤¯à¤¾ वर';
$labels['insertsignature'] = 'सही मधà¥â€à¤¯à¥‡ टाका';
$labels['previewpanemarkread'] = 'पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ संदेश पाहीले अशी खà¥à¤£ करा';
$labels['afternseconds'] = '$n कà¥à¤·à¤£à¤¾à¤¨à¤‚तर';
@@ -473,6 +476,7 @@ $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 98edd7efd..bc4097fb5 100755
--- a/program/localization/mr_IN/messages.inc
+++ b/program/localization/mr_IN/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'माहितीसाठा चूक !';
$messages['requesttimedout'] = 'Request timed out';
$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['invalidrequest'] = 'अवैध विनंती! माहिती साठवलेली नाही.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'या खातà¥à¤¯à¤¾à¤®à¤§à¥‡ कोणताही संदेश आलेला नाही';
diff --git a/program/localization/ms_MY/labels.inc b/program/localization/ms_MY/labels.inc
index 43884e986..a6bdfbfa0 100644
--- a/program/localization/ms_MY/labels.inc
+++ b/program/localization/ms_MY/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Muka terkini';
$labels['unread'] = 'Belum dibaca';
$labels['flagged'] = 'Ditanda';
$labels['unanswered'] = 'Belum dijawab';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Telah dipadam';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Songsangkan';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Karang mesej HTML';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Tandatangan HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Pamer ruang previu';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Kosongkan Tong sampah ketika keluar';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 0cddd6749..72d2e3075 100644
--- a/program/localization/ms_MY/messages.inc
+++ b/program/localization/ms_MY/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Tiada mesej dijumpai dalam kotak mel ini';
diff --git a/program/localization/nb_NO/labels.inc b/program/localization/nb_NO/labels.inc
index ecbe8545e..b5c8ce4c6 100644
--- a/program/localization/nb_NO/labels.inc
+++ b/program/localization/nb_NO/labels.inc
@@ -37,11 +37,12 @@ $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';
$labels['from'] = 'Avsender';
-$labels['sender'] = 'Sender';
+$labels['sender'] = 'Avsender';
$labels['to'] = 'Mottaker';
$labels['cc'] = 'Kopi til';
$labels['bcc'] = 'Blindkopi til';
@@ -64,6 +65,7 @@ $labels['copy'] = 'Kopier';
$labels['move'] = 'Flytt';
$labels['moveto'] = 'flytt til...';
$labels['download'] = 'last ned';
+$labels['open'] = 'Ã…pen';
$labels['showattachment'] = 'Vis';
$labels['showanyway'] = 'Vis likevel';
@@ -161,6 +163,7 @@ $labels['currpage'] = 'Gjeldende side';
$labels['unread'] = 'Uleste';
$labels['flagged'] = 'Flagget';
$labels['unanswered'] = 'Ubesvarte';
+$labels['withattachment'] = 'Med vedlegg';
$labels['deleted'] = 'Slettet';
$labels['undeleted'] = 'Ikke slettet';
$labels['invert'] = 'Inverter';
@@ -191,6 +194,7 @@ $labels['listmode'] = 'Listevisningsmodus';
$labels['folderactions'] = 'Mappehandlinger...';
$labels['compact'] = 'Rydd opp';
$labels['empty'] = 'Tøm';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Plassforbruk';
$labels['unknown'] = 'ukjent';
@@ -200,10 +204,13 @@ $labels['quicksearch'] = 'Hurtigsøk';
$labels['resetsearch'] = 'Nullstill søk';
$labels['searchmod'] = 'Søke felt';
$labels['msgtext'] = 'Hele meldingen';
-$labels['body'] = 'Body';
+$labels['body'] = 'Meldingstekst';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ã…pne i nytt vindu';
$labels['emlsave'] = 'Last ned (.eml)';
+$labels['changeformattext'] = 'Vis i ren tekst';
+$labels['changeformathtml'] = 'Vis i HTML';
// message compose
$labels['editasnew'] = 'Rediger som ny';
@@ -335,8 +342,8 @@ $labels['composeto'] = 'Skriv e-post til';
$labels['contactsfromto'] = 'Kontakter $from til $to av $count';
$labels['print'] = 'Skriv ut';
$labels['export'] = 'Eksporter';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Eksporter alle';
+$labels['exportsel'] = 'Eksporter valgte';
$labels['exportvcards'] = 'Eksporter kontakter i vCard-format';
$labels['newcontactgroup'] = 'Opprett ny kontaktgruppe';
$labels['grouprename'] = 'Endre navn på gruppe';
@@ -350,6 +357,7 @@ $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';
@@ -380,7 +388,7 @@ $labels['edititem'] = 'Rediger punkt';
$labels['preferhtml'] = 'Foretrekk HTML';
$labels['defaultcharset'] = 'Standard tegnsett';
$labels['htmlmessage'] = 'HTML-melding';
-$labels['messagepart'] = 'Part';
+$labels['messagepart'] = 'Del';
$labels['digitalsig'] = 'Digital signatur';
$labels['dateformat'] = 'Datoformat';
$labels['timeformat'] = 'Tidsformat';
@@ -398,6 +406,7 @@ $labels['htmleditor'] = 'Bruk HTML-editor';
$labels['htmlonreply'] = 'ved svar på HTML-melding';
$labels['htmlonreplyandforward'] = 'ved videresending av eller svar på HTML-melding';
$labels['htmlsignature'] = 'HTML-signatur';
+$labels['showemail'] = 'Vis e-postadresse sammen med visningsnavn';
$labels['previewpane'] = 'Forhåndsvisning';
$labels['skin'] = 'Utseende';
$labels['logoutclear'] = 'Tøm søppel ved utlogging';
@@ -451,9 +460,6 @@ $labels['replyremovesignature'] = 'Fjern orginalsignaturen i svar på melding';
$labels['autoaddsignature'] = 'Legg til signatur';
$labels['newmessageonly'] = 'kun på nye meldinger';
$labels['replyandforwardonly'] = 'kun i svar og videresendinger';
-$labels['replysignaturepos'] = 'Plassering av signatur ved svar eller videresending';
-$labels['belowquote'] = 'over sitert melding';
-$labels['abovequote'] = 'under sitert melding';
$labels['insertsignature'] = 'Sett inn signatur';
$labels['previewpanemarkread'] = 'Merk forhåndsviste meldinger som lest';
$labels['afternseconds'] = 'etter $n sekunder';
@@ -470,6 +476,7 @@ $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 939d1da76..7785f474a 100644
--- a/program/localization/nb_NO/messages.inc
+++ b/program/localization/nb_NO/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Databasefeil!';
$messages['requesttimedout'] = 'Forespørselen har fått et tidsavbrudd';
$messages['errorreadonly'] = 'Kunne ikke utføre handlingen. Mappen kan kun leses.';
$messages['errornoperm'] = 'Kan ikke utføre operasjon. Nektet tilgang.';
+$messages['erroroverquota'] = 'Kunne ikke utføre handlingen, tomt for diskplass.';
+$messages['erroroverquotadelete'] = 'Ingen ledig plass på disk. Bruk SHIFT+DEL for å slette en melding.';
$messages['invalidrequest'] = 'Ugyldig forespørsel! Ingen data ble lagret.';
$messages['invalidhost'] = 'Ugyldig servernavn.';
$messages['nomessagesfound'] = 'Det ble ikke funnet noen meldinger i denne mappen';
diff --git a/program/localization/ne_NP/labels.inc b/program/localization/ne_NP/labels.inc
index 26be68f35..5f69e1916 100644
--- a/program/localization/ne_NP/labels.inc
+++ b/program/localization/ne_NP/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'डà¥à¤°à¤¾à¤«à¥à¤Ÿà¤¹à¤°à¥‚';
$labels['sent'] = 'पठईà¤à¤•à¤¾ मेलहरà¥';
$labels['trash'] = 'रदà¥à¤¦à¥€ टोकरी';
$labels['junk'] = 'सà¥à¤ªà¤¾à¤®';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विषय';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'नपढिà¤à¤•à¤¾ |';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'छोटो गरà¥à¤¨à¥à¤¹à¥‹à¤¸';
$labels['empty'] = 'खाली गरà¥à¤¨à¥‡';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤•à¤•à¥‹ उपभोग';
$labels['unknown'] = 'अजà¥à¤žà¤¾à¤¤';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'अनà¥à¤¤à¤¿à¤® सेट देखाउनà¥à
$labels['group'] = 'Group';
$labels['groups'] = 'समूहहरà¥';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त ठेगानाहरà¥';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'à¤à¤š-टी-à¤à¤®-à¤à¤² (HTML) मेल लखन
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'à¤à¤š-टी-à¤à¤®-à¤à¤² (HTML) हसà¥à¤¤à¤¾à¤•à¥à¤·à¤°';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'पूरà¥à¤µ दृषà¥à¤¯ देखाउनà¥à¤¹à¥‹à¤¸';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 0c764ba8a..c5214bb0f 100644
--- a/program/localization/ne_NP/messages.inc
+++ b/program/localization/ne_NP/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'यो मेलबकà¥à¤¸ मा कà¥à¤¨à¥ˆ मेल छैन';
diff --git a/program/localization/nl_BE/labels.inc b/program/localization/nl_BE/labels.inc
index 82cf3a023..1e6bb2d2f 100644
--- a/program/localization/nl_BE/labels.inc
+++ b/program/localization/nl_BE/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Huidige pagina';
$labels['unread'] = 'Ongelezen';
$labels['flagged'] = 'Geselecteerd';
$labels['unanswered'] = 'Onbeantwoord';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Verwijderd';
$labels['undeleted'] = 'Niet verwijderd';
$labels['invert'] = 'Selectie omkeren';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Toon laatste';
$labels['group'] = 'Groep';
$labels['groups'] = 'Groepen';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlijke adressen';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML berichten opmaken';
$labels['htmlonreply'] = 'enkel bij beantwoorden van een HTML bericht';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML handtekening';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Toon voorbeeldvenster';
$labels['skin'] = 'Opmaakprofiel';
$labels['logoutclear'] = 'Prullenbak legen bij uitloggen';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Verwijder handtekening uit het origneel bij b
$labels['autoaddsignature'] = 'Handtekening automatisch toevoegen';
$labels['newmessageonly'] = 'alleen bij nieuwe berichten';
$labels['replyandforwardonly'] = 'alleen bij beantwoorden en doorsturen';
-$labels['replysignaturepos'] = 'Ondertekening plaatsen bij beantwoorden of doorsturen';
-$labels['belowquote'] = 'onder het citaat';
-$labels['abovequote'] = 'boven het citaat';
$labels['insertsignature'] = 'Handtekening invoegen';
$labels['previewpanemarkread'] = 'Markeer voorbeeldbericht als gelezen';
$labels['afternseconds'] = 'Na $n seconden';
@@ -473,6 +476,7 @@ $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 7e61c97c8..d87329dc3 100644
--- a/program/localization/nl_BE/messages.inc
+++ b/program/localization/nl_BE/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Database Fout!';
$messages['requesttimedout'] = 'Aanvraag verlopen';
$messages['errorreadonly'] = 'Kon opdracht niet uitvoeren. Map is alleen-lezen.';
$messages['errornoperm'] = 'Kon opdracht niet uitvoeren. Toegang geweigerd.';
+$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'] = 'Ongeldige aanvraag! Er zijn geen gegevens opgeslagen.';
$messages['invalidhost'] = 'Ongeldige server.';
$messages['nomessagesfound'] = 'Er zijn geen berichten in deze map...';
diff --git a/program/localization/nl_NL/labels.inc b/program/localization/nl_NL/labels.inc
index 2d34a5135..8a6f994fa 100644
--- a/program/localization/nl_NL/labels.inc
+++ b/program/localization/nl_NL/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Huidige pagina';
$labels['unread'] = 'Ongelezen';
$labels['flagged'] = 'Gemarkeerd';
$labels['unanswered'] = 'Onbeantwoord';
+$labels['withattachment'] = 'Met bijlage';
$labels['deleted'] = 'Verwijderd';
$labels['undeleted'] = 'Niet verwijderd';
$labels['invert'] = 'Selectie omkeren';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Lijstweergave';
$labels['folderactions'] = 'Mapacties...';
$labels['compact'] = 'Opschonen';
$labels['empty'] = 'Legen';
+$labels['importmessages'] = 'Berichten importeren';
$labels['quota'] = 'Opslagverbruik';
$labels['unknown'] = 'onbekend';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Laatste pagina';
$labels['group'] = 'Groep';
$labels['groups'] = 'Groepen';
+$labels['listgroup'] = 'Toon groepsleden';
$labels['personaladrbook'] = 'Persoonlijk adresboek';
$labels['searchsave'] = 'Zoekopdracht opslaan';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Berichten opstellen in HTML-opmaak';
$labels['htmlonreply'] = 'alleen bij beantwoorden van HTML-berichten';
$labels['htmlonreplyandforward'] = 'bij doorsturen of beantwoorden van een HTML-bericht';
$labels['htmlsignature'] = 'HTML-ondertekening';
+$labels['showemail'] = 'Toon e-mailadressen met weergavenaam';
$labels['previewpane'] = 'Toon voorbeeldvenster';
$labels['skin'] = 'Interfacestijl';
$labels['logoutclear'] = 'Prullenbak legen bij uitloggen';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Verwijder oorspronkelijke ondertekening van b
$labels['autoaddsignature'] = 'Ondertekening automatisch toevoegen';
$labels['newmessageonly'] = 'alleen bij nieuwe berichten';
$labels['replyandforwardonly'] = 'alleen bij antwoorden en doorsturen';
-$labels['replysignaturepos'] = 'Ondertekening plaatsen bij antwoorden of doorsturen';
-$labels['belowquote'] = 'onder het citaat';
-$labels['abovequote'] = 'boven het citaat';
$labels['insertsignature'] = 'Ondertekening invoegen';
$labels['previewpanemarkread'] = 'Markeer voorbeeldberichten als gelezen';
$labels['afternseconds'] = 'na $n seconden';
@@ -473,6 +476,7 @@ $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/nn_NO/labels.inc b/program/localization/nn_NO/labels.inc
index 725919d14..5934a01d9 100644
--- a/program/localization/nn_NO/labels.inc
+++ b/program/localization/nn_NO/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -64,6 +65,7 @@ $labels['copy'] = 'Kopier';
$labels['move'] = 'Flytt';
$labels['moveto'] = 'flytt til …';
$labels['download'] = 'Last ned';
+$labels['open'] = 'Open';
$labels['showattachment'] = 'Vis';
$labels['showanyway'] = 'Vis likevel';
@@ -161,6 +163,7 @@ $labels['currpage'] = 'Gjeldande side';
$labels['unread'] = 'Uleste';
$labels['flagged'] = 'Flagga';
$labels['unanswered'] = 'Ikkje svara';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Sletta';
$labels['undeleted'] = 'Ikkje sletta';
$labels['invert'] = 'Inverter';
@@ -191,6 +194,7 @@ $labels['listmode'] = 'Listevisningmodus';
$labels['folderactions'] = 'Mappehandlingar';
$labels['compact'] = 'Kompakt';
$labels['empty'] = 'Tom';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Plassbruk';
$labels['unknown'] = 'ukjend';
@@ -201,9 +205,12 @@ $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)';
+$labels['changeformattext'] = 'Display in plain text format';
+$labels['changeformathtml'] = 'Display in HTML format';
// message compose
$labels['editasnew'] = 'Rediger som ny';
@@ -335,8 +342,8 @@ $labels['composeto'] = 'Ny melding til';
$labels['contactsfromto'] = 'Kontaktar $from til $to av $count';
$labels['print'] = 'Skriv ut';
$labels['export'] = 'Eksport';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Eksporter alle';
+$labels['exportsel'] = 'Eksporter valde';
$labels['exportvcards'] = 'Eksporter kontaktar i vCard-format';
$labels['newcontactgroup'] = 'Lag ny kontaktgruppe';
$labels['grouprename'] = 'Endre namn på gruppe';
@@ -350,6 +357,7 @@ $labels['lastpage'] = 'Siste side';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppar';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlege adresser';
$labels['searchsave'] = 'Lagre søk';
@@ -398,6 +406,7 @@ $labels['htmleditor'] = 'Lag HTML-meldingar';
$labels['htmlonreply'] = 'ved svar på HTML-melding';
$labels['htmlonreplyandforward'] = 'ved vidaresending av eller svar på HTML-melding';
$labels['htmlsignature'] = 'HTML-signatur';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Vis førehandsvisningsboks';
$labels['skin'] = 'Bunad';
$labels['logoutclear'] = 'Fjern alt i «sletta element» ved utlogging';
@@ -451,9 +460,6 @@ $labels['replyremovesignature'] = 'Fjern den original signatur frå eposten når
$labels['autoaddsignature'] = 'Legg signatur til automatisk';
$labels['newmessageonly'] = 'berre på nye epostar';
$labels['replyandforwardonly'] = 'berre på svar og vidaresending';
-$labels['replysignaturepos'] = 'NÃ¥r du svarar eller sender vidare, plasser signaturen';
-$labels['belowquote'] = 'nedanfor siteringa';
-$labels['abovequote'] = 'oppanfor siteringa';
$labels['insertsignature'] = 'Sett inn signatur';
$labels['previewpanemarkread'] = 'Merk forehandsviste epostar som leste';
$labels['afternseconds'] = 'etter $n sekund';
@@ -470,6 +476,7 @@ $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 e82beaf93..3dce30b98 100644
--- a/program/localization/nn_NO/messages.inc
+++ b/program/localization/nn_NO/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Databasefeil!';
$messages['requesttimedout'] = 'Førespurnaden fekk tidsavbrot';
$messages['errorreadonly'] = 'Klarte ikkje utføra handlinga. Mappa kan berre lesast.';
$messages['errornoperm'] = 'Klarte ikkje utføra handlinga. Nekta tilgang.';
+$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'] = 'Eg forstår ingen ting! Ingen data lagra.';
$messages['invalidhost'] = 'Ugyldig tenarnamn.';
$messages['nomessagesfound'] = 'Ingen meldingar i denne postkassa.';
diff --git a/program/localization/pl_PL/labels.inc b/program/localization/pl_PL/labels.inc
index 7a4248830..d7b9cd2d4 100644
--- a/program/localization/pl_PL/labels.inc
+++ b/program/localization/pl_PL/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Bieżąca strona';
$labels['unread'] = 'Nieprzeczytane';
$labels['flagged'] = 'Oznaczone';
$labels['unanswered'] = 'Bez odpowiedzi';
+$labels['withattachment'] = 'Z załącznikiem';
$labels['deleted'] = 'Usunięte';
$labels['undeleted'] = 'Nieusunięte';
$labels['invert'] = 'Odwróć';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Ostatnia strona';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupy';
+$labels['listgroup'] = 'Członkowie grupy';
$labels['personaladrbook'] = 'Kontakty osobiste';
$labels['searchsave'] = 'Zapisz wyszukiwanie';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Twórz wiadomości HTML';
$labels['htmlonreply'] = 'tylko w odpowiedzi na wiadomość HTML';
$labels['htmlonreplyandforward'] = 'podczas przesyłania dalej lub odpowiedzi na wiadomość HTML';
$labels['htmlsignature'] = 'Podpis w HTML';
+$labels['showemail'] = 'Pokazuj adres e-mail wraz z nazwÄ…/opisem';
$labels['previewpane'] = 'Pokaż podgląd wiadomości';
$labels['skin'] = 'WyglÄ…d interfejsu';
$labels['logoutclear'] = 'Przy wylogowaniu opróżnij Kosz';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Podczas odpowiedzi usuń podpis z cytowanej t
$labels['autoaddsignature'] = 'Automatycznie wstaw podpis';
$labels['newmessageonly'] = 'tylko dla nowych wiadomości';
$labels['replyandforwardonly'] = 'tylko dla przekazywania i odpowiedzi';
-$labels['replysignaturepos'] = 'Podczas odpowiedzi wstaw podpis';
-$labels['belowquote'] = 'poniżej cytowanej treści';
-$labels['abovequote'] = 'ponad cytowaną treścią';
$labels['insertsignature'] = 'Wstaw podpis';
$labels['previewpanemarkread'] = 'Oznacz podglądane wiadomości jako przeczytane';
$labels['afternseconds'] = 'po $n sekundach';
@@ -473,6 +476,7 @@ $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 68e33fa1b..3cac0c426 100644
--- a/program/localization/pl_PL/messages.inc
+++ b/program/localization/pl_PL/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'BÅ‚Ä…d bazy danych!';
$messages['requesttimedout'] = 'Upłynął limit czasu żądania';
$messages['errorreadonly'] = 'Nie można wykonać operacji. Folder tylko do odczytu.';
$messages['errornoperm'] = 'Nie można wykonać operacji. Brak uprawnień.';
+$messages['erroroverquota'] = 'Nie można wykonać operacji. Brak miejsca na dysku.';
+$messages['erroroverquotadelete'] = 'Brak miejsca na dysku. Użyj SHIFT+DEL aby usunąć wiadomość.';
$messages['invalidrequest'] = 'Błędne żądanie! Nie zapisano danych.';
$messages['invalidhost'] = 'Błędna nazwa serwera.';
$messages['nomessagesfound'] = 'Brak wiadomości w skrzynce.';
@@ -43,7 +45,7 @@ $messages['sendingmessage'] = 'Wysyłanie wiadomości...';
$messages['messagesent'] = 'Wiadomość została wysłana.';
$messages['savingmessage'] = 'Zapisywanie wiadomości...';
$messages['messagesaved'] = 'Wiadomość została zapisana w folderze Kopie robocze.';
-$messages['successfullysaved'] = 'Zapisano.';
+$messages['successfullysaved'] = 'Zapisano pomyślnie.';
$messages['addedsuccessfully'] = 'Kontakt został dodany.';
$messages['contactexists'] = 'Kontakt o podanym adresie e-mail już istnieje!';
$messages['contactnameexists'] = 'Kontakt z podaną nazwą już istnieje!';
@@ -124,6 +126,8 @@ $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 05f6c3d32..d5e513419 100755
--- a/program/localization/ps/labels.inc
+++ b/program/localization/ps/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'بارليک';
$labels['sent'] = 'Ù„ÛÚ–Ù„ شوي ليکونه';
$labels['trash'] = 'کثاÙت دانÛ';
$labels['junk'] = 'جنک';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'مضمون';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'نالوستي';
$labels['flagged'] = 'Ø¨Û Ú©Ø§Ø±Ù‡';
$labels['unanswered'] = 'ناÚواب شوي';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Ú©ÛÚšÚ©Ù„ÛŒ';
$labels['empty'] = 'تش';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ټيکلي لارښود';
$labels['unknown'] = 'نامعلوم';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'د Ù¾Ù„Ù¼Ù†Û Ø¨ÙŠØ§Ø³Ù…ÙˆÙ†';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'په نوي Ú©Ú“Ú©Û Ú©Û Ù¾Ø±Ø§Ù†ÙŠØ²Ù‡';
$labels['emlsave'] = 'Download (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'پای غونډ وښيه';
$labels['group'] = 'Group';
$labels['groups'] = 'Ú‰Ù„Û';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Úاني پتÛ';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'ايچ ټي‌ام ايل استوزي وليکه';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'ايچ ټي ام ايل لاسليک';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'پخوانی چوکاټ وښييه';
$labels['skin'] = 'انټرÙيس بڼه';
$labels['logoutclear'] = 'کثاÙت داني د ÙˆØªÙ†Û Ù¾Ù‡ وخت Ú©Û Ù¾Ø§Ú©Ù‡ Ú©Ú“Ù‡';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 c133b8c0e..d3a8483ee 100755
--- a/program/localization/ps/messages.inc
+++ b/program/localization/ps/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'ليکبکس Ú©Û Ù‡ÛÚ… استوزي ونه مونده';
diff --git a/program/localization/pt_BR/labels.inc b/program/localization/pt_BR/labels.inc
index 55068df5b..e70ae35b9 100644
--- a/program/localization/pt_BR/labels.inc
+++ b/program/localization/pt_BR/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Página atual';
$labels['unread'] = 'Não lidas';
$labels['flagged'] = 'Marcadas';
$labels['unanswered'] = 'Não respondidas';
+$labels['withattachment'] = 'Com anexo';
$labels['deleted'] = 'Excluídas';
$labels['undeleted'] = 'Não excluídas';
$labels['invert'] = 'Inverter';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -266,7 +270,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 de exibição';
+$labels['name'] = 'Nome';
$labels['firstname'] = 'Primeiro Nome';
$labels['surname'] = 'Sobrenome';
$labels['middlename'] = 'Segundo Nome';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Criar mensagens em HTML';
$labels['htmlonreply'] = 'em resposta à mensagem em HTML somente';
$labels['htmlonreplyandforward'] = 'em resposta ou encaminhamento de mensagem em HTML';
$labels['htmlsignature'] = 'Assinatura em HTML';
+$labels['showemail'] = 'Exibir o endereço de email junto ao nome de exibição';
$labels['previewpane'] = 'Exibir pré-visualização';
$labels['skin'] = 'Aparência da interface (tema)';
$labels['logoutclear'] = 'Esvaziar a Lixeira ao sair';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Remover assinatura original da mensagem ao re
$labels['autoaddsignature'] = 'Adicionar assinatura automaticamente';
$labels['newmessageonly'] = 'somente em novas mensagens';
$labels['replyandforwardonly'] = 'somente em respostas e encaminhamentos';
-$labels['replysignaturepos'] = 'Inserir assinatura ao responder ou encaminhar';
-$labels['belowquote'] = 'abaixo da citação';
-$labels['abovequote'] = 'acima da citação';
$labels['insertsignature'] = 'Inserir assinatura';
$labels['previewpanemarkread'] = 'Marcar mensagens pré-visualizadas como lidas';
$labels['afternseconds'] = 'depois de $n segundos';
@@ -473,6 +476,7 @@ $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';
@@ -485,7 +489,7 @@ $labels['messagecount'] = 'Mensagens';
$labels['create'] = 'Criar';
$labels['createfolder'] = 'Criar nova pasta';
$labels['managefolders'] = 'Gerenciar pastas';
-$labels['specialfolders'] = 'Pastas especiais';
+$labels['specialfolders'] = 'Pastas de sistema';
$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 f734c7fbd..6ec481b8f 100644
--- a/program/localization/pt_BR/messages.inc
+++ b/program/localization/pt_BR/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Erro no banco de dados!';
$messages['requesttimedout'] = 'Tempo da requisição esgotado';
$messages['errorreadonly'] = 'Não foi possível realizar a operação. Pasta somente leitura';
$messages['errornoperm'] = 'Não foi possível realizar a operação. Acesso negado';
+$messages['erroroverquota'] = 'Não foi possível realizar a operação. Não há espaço disponível.';
+$messages['erroroverquotadelete'] = 'Não há espaço disponível. Utilize SHIFT+DEL para apagar a mensagem.';
$messages['invalidrequest'] = 'Requisição inválida! Nenhum dado foi salvo.';
$messages['invalidhost'] = 'Endereço de servidor inválido.';
$messages['nomessagesfound'] = 'Nenhuma mensagem encontrada nessa caixa de mensagens';
diff --git a/program/localization/pt_PT/labels.inc b/program/localization/pt_PT/labels.inc
index 62fa8bbb4..cc4c534e0 100644
--- a/program/localization/pt_PT/labels.inc
+++ b/program/localization/pt_PT/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Página actual';
$labels['unread'] = 'Não lidas';
$labels['flagged'] = 'Sinalizadas';
$labels['unanswered'] = 'Não respondidas';
+$labels['withattachment'] = 'Com anexo';
$labels['deleted'] = 'Eliminadas';
$labels['undeleted'] = 'Não eliminada';
$labels['invert'] = 'Inverter selecção';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Escrever mensagens em HTML';
$labels['htmlonreply'] = 'apenas em resposta a mensagens HTML';
$labels['htmlonreplyandforward'] = 'no reencaminhamento ou resposta de mensagem em HTML';
$labels['htmlsignature'] = 'Assinatura em HTML';
+$labels['showemail'] = 'Mostrar endereço de e-mail com o nome a exibir';
$labels['previewpane'] = 'Mostrar pré-visualização';
$labels['skin'] = 'Aspecto [tema]';
$labels['logoutclear'] = 'Esvaziar a Reciclagem ao sair';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Ao responder, remover a assinatura original d
$labels['autoaddsignature'] = 'Adicionar assinatura automaticamente';
$labels['newmessageonly'] = 'apenas em novas mensagens';
$labels['replyandforwardonly'] = 'apenas em respostas e reenvios';
-$labels['replysignaturepos'] = 'Ao responder ou reencaminhar colocar assinatura';
-$labels['belowquote'] = 'depois da citação';
-$labels['abovequote'] = 'antes da citação';
$labels['insertsignature'] = 'Inserir assinatura';
$labels['previewpanemarkread'] = 'Marcar mensagem como lida';
$labels['afternseconds'] = 'após $n segundos';
@@ -473,6 +476,7 @@ $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 638b0fcdd..88b96e60e 100644
--- a/program/localization/pt_PT/messages.inc
+++ b/program/localization/pt_PT/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Erro na base de dados!';
$messages['requesttimedout'] = 'A solicitação expirou';
$messages['errorreadonly'] = 'Não foi possível efectuar a operação. A pasta é só de leitura.';
$messages['errornoperm'] = 'Não tem permissões para efectuar esta operação.';
+$messages['erroroverquota'] = 'Não foi possível executar a operação. Não há espaço livre em disco.';
+$messages['erroroverquotadelete'] = 'Não há espaço livre em disco. Use SHIFT + DEL para eliminar algumas mensagens.';
$messages['invalidrequest'] = 'Pedido inválido! Não foi guardada nenhuma informação.';
$messages['invalidhost'] = 'Nome do servidor inválido.';
$messages['nomessagesfound'] = 'Não existem mensagens nesta pasta.';
diff --git a/program/localization/ro_RO/labels.inc b/program/localization/ro_RO/labels.inc
index 0dcd97919..4f6ddb1fa 100644
--- a/program/localization/ro_RO/labels.inc
+++ b/program/localization/ro_RO/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Ciorne';
$labels['sent'] = 'Trimise';
$labels['trash'] = 'Gunoi';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subiect';
@@ -46,25 +47,25 @@ $labels['to'] = 'Destinatar';
$labels['cc'] = 'Copie (CC)';
$labels['bcc'] = 'Copie oarbă (BCC)';
$labels['replyto'] = 'Răspunde la';
-$labels['followupto'] = 'Followup-To';
+$labels['followupto'] = 'Followup La';
$labels['date'] = 'Data';
$labels['size'] = 'Mărime';
$labels['priority'] = 'Prioritate';
$labels['organization'] = 'Organizaţie';
-$labels['readstatus'] = 'Starea de citit';
+$labels['readstatus'] = 'Citit/Necitit';
$labels['listoptions'] = 'Listează opţiunile...';
$labels['mailboxlist'] = 'Dosare';
$labels['messagesfromto'] = 'Mesaje de la $from până la $to din $count';
$labels['threadsfromto'] = 'Grupuri de la $from până la $to din $count';
-$labels['messagenrof'] = '$nr mesaje din $count';
+$labels['messagenrof'] = 'Mesajul $nr din $count';
$labels['fromtoshort'] = '$from - $to din $count';
$labels['copy'] = 'Copiază';
$labels['move'] = 'Mută';
$labels['moveto'] = 'Mută in...';
$labels['download'] = 'Descarcă';
-$labels['open'] = 'Open';
+$labels['open'] = 'Deschide';
$labels['showattachment'] = 'Arată';
$labels['showanyway'] = 'Arată oricum';
@@ -127,22 +128,22 @@ $labels['checkmail'] = 'Verifică mesaje noi';
$labels['compose'] = 'Scrie un mesaj';
$labels['writenewmessage'] = 'Scrie mesaj nou';
$labels['reply'] = 'Răspunde';
-$labels['replytomessage'] = 'Răspunde la mesaj';
+$labels['replytomessage'] = 'Răspunde expeditorului';
$labels['replytoallmessage'] = 'Răspunde la toţi';
$labels['replyall'] = 'Răspunde la toţi';
-$labels['replylist'] = 'Lista de răspuns';
+$labels['replylist'] = 'Răspunde listei';
$labels['forward'] = 'Înaintează';
$labels['forwardinline'] = 'Înaintează ca citat';
$labels['forwardattachment'] = 'Înaintează ca ataşament';
$labels['forwardmessage'] = 'Trimite mesajul mai departe';
-$labels['deletemessage'] = 'Trimite mesajul la gunoi';
+$labels['deletemessage'] = 'Șterge mesajul';
$labels['movemessagetotrash'] = 'Mută mesajul la gunoi';
$labels['printmessage'] = 'Listează mesajul';
$labels['previousmessage'] = 'Afişează mesajul anterior';
$labels['firstmessage'] = 'Afişează primul mesaj';
$labels['nextmessage'] = 'Afişează următorul mesaj';
$labels['lastmessage'] = 'Afişează ultimul mesaj';
-$labels['backtolist'] = 'ÃŽnapoi la lista cu mesaje';
+$labels['backtolist'] = 'ÃŽnapoi la mesaje';
$labels['viewsource'] = 'Afişează sursa';
$labels['mark'] = 'Marchează';
$labels['markmessages'] = 'Marchează mesajele';
@@ -157,11 +158,12 @@ $labels['options'] = 'Opţiuni';
$labels['select'] = 'Selectează';
$labels['all'] = 'Toate';
-$labels['none'] = 'Fără sortare';
+$labels['none'] = 'Niciunul';
$labels['currpage'] = 'Pagina curentă';
$labels['unread'] = 'Necitite';
$labels['flagged'] = 'Marcat';
$labels['unanswered'] = 'Fără răspuns';
+$labels['withattachment'] = 'Cu atașament';
$labels['deleted'] = 'Åžterse';
$labels['undeleted'] = 'Nu a fost șters';
$labels['invert'] = 'Inversează';
@@ -189,9 +191,10 @@ $labels['listsorting'] = 'Sortează după';
$labels['listorder'] = 'Ordinea de sortare';
$labels['listmode'] = 'Mod de vizualizare';
-$labels['folderactions'] = 'Actiuni asupra folder-ului...';
+$labels['folderactions'] = 'Acțiuni dosar...';
$labels['compact'] = 'Compactează';
$labels['empty'] = 'GoleÅŸte';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Spaţiu folosit';
$labels['unknown'] = 'necunoscut';
@@ -202,17 +205,18 @@ $labels['resetsearch'] = 'Anulează căutarea';
$labels['searchmod'] = 'Parametrii de căutare';
$labels['msgtext'] = 'Tot mesajul';
$labels['body'] = 'Corp';
+$labels['type'] = 'Type';
-$labels['openinextwin'] = 'Deschide într-o fereastră nouă';
+$labels['openinextwin'] = 'Deschide în fereastră nouă';
$labels['emlsave'] = 'Salvează în format .eml';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Afișează în format text';
+$labels['changeformathtml'] = 'Afișează în format HTML';
// message compose
$labels['editasnew'] = 'Editează ca nou';
$labels['send'] = 'Trimite';
$labels['sendmessage'] = 'Trimite mesaj';
-$labels['savemessage'] = 'Salvează această ciornă';
+$labels['savemessage'] = 'Salvează ciornă';
$labels['addattachment'] = 'Ataşează fişier';
$labels['charset'] = 'Set de caractere';
$labels['editortype'] = 'Tip de editor';
@@ -243,21 +247,21 @@ $labels['highest'] = 'Cea mai mare';
$labels['nosubject'] = '(fără subiect)';
$labels['showimages'] = 'Afişează imagini';
$labels['alwaysshow'] = 'Afişează întotdeauna imaginile de la $sender';
-$labels['isdraft'] = 'Acesta este un mesaj schiţă.';
+$labels['isdraft'] = 'Acest mesaj este o ciornă.';
$labels['andnmore'] = '$nr mai multe...';
$labels['togglemoreheaders'] = 'Arată mai mult din antet';
$labels['togglefullheaders'] = 'Arată mai puțin din antet';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Text simplu';
-$labels['savesentmessagein'] = 'Salvează mesajele în';
+$labels['savesentmessagein'] = 'Salvează mesajele trimise în';
$labels['dontsave'] = 'Nu salva';
-$labels['maxuploadsize'] = 'Mărimea maximă admisă a fişierului este $size';
+$labels['maxuploadsize'] = 'Mărimea maxim admisă a fişierului este $size';
-$labels['addcc'] = 'Adaugă Cc';
-$labels['addbcc'] = 'Adaugă Bcc';
+$labels['addcc'] = 'Adaugă CC';
+$labels['addbcc'] = 'Adaugă BCC';
$labels['addreplyto'] = 'Adaugă Raspunde-La';
-$labels['addfollowupto'] = 'Adaugă Followup-To';
+$labels['addfollowupto'] = 'Adaugă Followup-La';
// mdn
$labels['mdnrequest'] = 'Expeditorul acestui mesaj a solicitat să fie notificat la cititrea mesajului. Doriţi să notificaţi expeditorul?';
@@ -266,7 +270,7 @@ $labels['yourmessage'] = 'Aceasta este o confirmare de primire a mesajului dumne
$labels['receiptnote'] = 'Notă: Această confirmare doar vă informează că mesajul a fost afişat pe calculatorul destinatarului. Nu există nici o garanţie că destinatarul a citit sau a inţeles conţinutul mesajului.';
// address boook
-$labels['name'] = 'Numele Contactului';
+$labels['name'] = 'Numele Contact';
$labels['firstname'] = 'Nume';
$labels['surname'] = 'Prenume';
$labels['middlename'] = 'Iniţiala tatălui';
@@ -280,11 +284,11 @@ $labels['maidenname'] = 'Nume de fată';
$labels['email'] = 'E-Mail';
$labels['phone'] = 'Telefon';
$labels['address'] = 'Adresă';
-$labels['street'] = 'Stradă';
+$labels['street'] = 'Strada';
$labels['locality'] = 'OraÈ™';
$labels['zipcode'] = 'Cod poÅŸtal';
$labels['region'] = 'Stat/Judeţ';
-$labels['country'] = 'Țară';
+$labels['country'] = 'Èšara';
$labels['birthday'] = 'Ziua de naÅŸtere:';
$labels['anniversary'] = 'Aniversare';
$labels['website'] = 'Pagină web';
@@ -301,8 +305,8 @@ $labels['advsearch'] = 'Căutare avansată';
$labels['advanced'] = 'Avansat';
$labels['other'] = 'Altele';
-$labels['typehome'] = 'Pagina Principală';
-$labels['typework'] = 'Servici';
+$labels['typehome'] = 'Acasă';
+$labels['typework'] = 'Serviciu';
$labels['typeother'] = 'Altele';
$labels['typemobile'] = 'Mobil';
$labels['typemain'] = 'Principal';
@@ -317,7 +321,7 @@ $labels['typeblog'] = 'Blog';
$labels['typeprofile'] = 'Profil';
$labels['addfield'] = 'Adaugă câmp...';
-$labels['addcontact'] = 'Adaugă contactul selectat în agendă';
+$labels['addcontact'] = 'Adaugă contact nou';
$labels['editcontact'] = 'Modifică contact';
$labels['contacts'] = 'Contacte';
$labels['contactproperties'] = 'Proprietăţile contactului...';
@@ -330,7 +334,7 @@ $labels['delete'] = 'Åžterge';
$labels['rename'] = 'RedenumeÅŸte';
$labels['addphoto'] = 'Adaugă';
$labels['replacephoto'] = 'Înlocuiește';
-$labels['uploadphoto'] = 'Încarcă poya';
+$labels['uploadphoto'] = 'Încarcă imagine';
$labels['newcontact'] = 'Creează contact nou';
$labels['deletecontact'] = 'Åžterge contactul selectat';
@@ -347,12 +351,13 @@ $labels['groupdelete'] = 'Șterge grupul';
$labels['groupremoveselected'] = 'Șterge contactele selectate din grup';
$labels['previouspage'] = 'Pagina anterioară';
-$labels['firstpage'] = 'Arată primul set';
+$labels['firstpage'] = 'Prima pagină';
$labels['nextpage'] = 'Pagina următoare';
-$labels['lastpage'] = 'Arată ultimul set';
+$labels['lastpage'] = 'Ultima pagină';
$labels['group'] = 'Grup';
$labels['groups'] = 'Grupuri';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adrese personale';
$labels['searchsave'] = 'Salvează căutarea';
@@ -363,7 +368,7 @@ $labels['importcontacts'] = 'Importă contacte';
$labels['importfromfile'] = 'Importă din fişier:';
$labels['importtarget'] = 'Adaugă contactele noi în agenda:';
$labels['importreplace'] = 'Înlocuieşte întreaga agendă';
-$labels['importdesc'] = 'Puteți încărcat contacte dintr-o agendă existentă.<br/>Momentan este suportat importul în formatul <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> sau în formatul CSV (comma-separated).';
+$labels['importdesc'] = 'Puteți încărca contacte dintr-o agendă existentă.<br/>Momentan este suportat importul în formatul <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> sau în formatul CSV (comma-separated).';
$labels['done'] = 'Finalizat';
// settings
@@ -394,13 +399,14 @@ $labels['language'] = 'Limba';
$labels['timezone'] = 'Fus orar';
$labels['pagesize'] = 'Rânduri pe pagină';
$labels['signature'] = 'Semnătură';
-$labels['dstactive'] = 'Reglare automată oră de vară';
+$labels['dstactive'] = 'Reglare ora de vară';
$labels['showinextwin'] = 'Deschide mesajul în fereastră nouă';
$labels['composeextwin'] = 'Compune mesajul în fereastră nouă';
$labels['htmleditor'] = 'Scrie mesaje HTML';
$labels['htmlonreply'] = 'la răspunsul doar către un mesaj HTML';
$labels['htmlonreplyandforward'] = 'la trimitere mai departe sau la răspuns la mesaj HTML';
$labels['htmlsignature'] = 'Semnatură HTML';
+$labels['showemail'] = 'Arată adresa email alături de nume afișat';
$labels['previewpane'] = 'Previzualizare mail';
$labels['skin'] = 'Temă interfaţă';
$labels['logoutclear'] = 'GoleÅŸte CoÅŸul de Gunoi la deconectare';
@@ -409,15 +415,15 @@ $labels['uisettings'] = 'Interfaţă utilizator';
$labels['serversettings'] = 'Configuraţii server';
$labels['mailboxview'] = 'Afişare căsuţă poştală';
$labels['mdnrequests'] = 'Notificări expeditor';
-$labels['askuser'] = 'întreabă utilizatorul';
+$labels['askuser'] = 'întreabă-mă';
$labels['autosend'] = 'trimite automat';
$labels['autosendknown'] = 'trimite confirmarea de primire către contactele mele, în rest întreabă-mă';
$labels['autosendknownignore'] = 'trimite confirmarea de primire către contactele mele, în rest ignoră';
$labels['ignore'] = 'ignoră';
-$labels['readwhendeleted'] = 'Marchează mesajul ca şi citit la ştergere';
+$labels['readwhendeleted'] = 'Marchează mesajul ca citit la ştergere';
$labels['flagfordeletion'] = 'Marchează mesajul pentru ştergere în loc de a-l şterge direct';
$labels['skipdeleted'] = 'Nu arăta mesajele şterse';
-$labels['deletealways'] = 'Dacă mutarea mesajelor în coş eşuează, se vor şterge';
+$labels['deletealways'] = 'Dacă mutarea mesajelor în Coş eşuează, șterge-le';
$labels['deletejunk'] = 'Șterge direct mesajele în Junk';
$labels['showremoteimages'] = 'Arată imaginile care nu fac parte din e-mail';
$labels['fromknownsenders'] = 'de la expeditori cunoscuţi';
@@ -441,7 +447,7 @@ $labels['checkallfolders'] = 'Verifică toate dosarele pentru mesaje noi';
$labels['displaynext'] = 'După ştergerea sau mutarea unui mesaj afişează-l pe următorul din listă';
$labels['defaultfont'] = 'Font-ul implicit al mesajului HTML';
$labels['mainoptions'] = 'Opţiuni principale';
-$labels['browseroptions'] = 'Optiuni browser';
+$labels['browseroptions'] = 'Opțiuni browser';
$labels['section'] = 'Secţiune';
$labels['maintenance'] = 'Mentenanţă';
$labels['newmessage'] = 'Mesaj nou';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Când răspundeţi, se şterge semnătura ori
$labels['autoaddsignature'] = 'Adăugarea automată a semnăturii';
$labels['newmessageonly'] = 'numai la mesajele noi';
$labels['replyandforwardonly'] = 'numai la răspunsuri si cele trimise mai departe';
-$labels['replysignaturepos'] = 'Când răspundeţi sau trimiteţi mai departe, semnătura se va plasa';
-$labels['belowquote'] = 'dedesubtul citatului';
-$labels['abovequote'] = 'deasupra citatului';
$labels['insertsignature'] = 'Introduce o semnătură';
$labels['previewpanemarkread'] = 'Marchează mesajele previzualizate ca citite';
$labels['afternseconds'] = 'după $n secunde';
@@ -473,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignoră cuvintele cu numere';
$labels['spellcheckignorecaps'] = 'Ignoră cuvintele din litere mari';
$labels['addtodict'] = 'Adaugă la dicţionar';
$labels['mailtoprotohandler'] = 'Îregistrează handler protocol pentru mailto: link-uri';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Trimitere mai departe mesaj';
$labels['inline'] = 'într-e linii';
$labels['asattachment'] = 'ca atașament';
diff --git a/program/localization/ro_RO/messages.inc b/program/localization/ro_RO/messages.inc
index 68d1ab6a7..96b9de593 100644
--- a/program/localization/ro_RO/messages.inc
+++ b/program/localization/ro_RO/messages.inc
@@ -28,6 +28,8 @@ $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['invalidrequest'] = 'Solicitare invalidă! Datele nu au fost salvate.';
$messages['invalidhost'] = 'Hosname invalid';
$messages['nomessagesfound'] = 'Nu a fost găsit nici un mesaj în această căsuţă poştală';
diff --git a/program/localization/ru_RU/labels.inc b/program/localization/ru_RU/labels.inc
index 6b6d0c6bd..d2b8e75c4 100644
--- a/program/localization/ru_RU/labels.inc
+++ b/program/localization/ru_RU/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Черновики';
$labels['sent'] = 'Отправленные';
$labels['trash'] = 'Корзина';
$labels['junk'] = 'СПÐÐœ';
+$labels['show_real_foldernames'] = 'Показывать наÑтоÑщие Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñпециальных папок';
// message listing
$labels['subject'] = 'Тема';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ñтраница';
$labels['unread'] = 'Ðепрочитанные';
$labels['flagged'] = 'Помеченные';
$labels['unanswered'] = 'Ðеотвеченные';
+$labels['withattachment'] = 'С вложением';
$labels['deleted'] = 'Удаленное';
$labels['undeleted'] = 'Ðе удалено';
$labels['invert'] = 'Инвертное';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Режим проÑмотра';
$labels['folderactions'] = 'Операции над папкой...';
$labels['compact'] = 'Сжать';
$labels['empty'] = 'ОпуÑтошить';
+$labels['importmessages'] = 'Импорт Ñообщений';
$labels['quota'] = 'Квота';
$labels['unknown'] = 'неизвеÑтно';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'СброÑ';
$labels['searchmod'] = 'Варианты поиÑка';
$labels['msgtext'] = 'Ð’ÑÑ‘ Ñообщение';
$labels['body'] = 'Тело пиÑьма';
+$labels['type'] = 'Тип';
$labels['openinextwin'] = 'Открыть в новом окне';
$labels['emlsave'] = 'Сохранить (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Показать поÑледнюю ÑтраницÑ
$labels['group'] = 'Группа';
$labels['groups'] = 'Группы';
+$labels['listgroup'] = 'СпиÑок членов группы';
$labels['personaladrbook'] = 'ПерÑональные адреÑа';
$labels['searchsave'] = 'Сохранить запроÑ';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Создавать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² HTML';
$labels['htmlonreply'] = 'только в ответ на Ñообщение в HTML';
$labels['htmlonreplyandforward'] = 'при переÑылке или ответе на HTML Ñообщение';
$labels['htmlsignature'] = 'ПодпиÑÑŒ в HTML';
+$labels['showemail'] = 'Показывать Ð°Ð´Ñ€ÐµÑ Ñлектронной почты и Ð¸Ð¼Ñ Ð°Ð´Ñ€ÐµÑата';
$labels['previewpane'] = 'Показать панель превью';
$labels['skin'] = 'Стиль оформлениÑ';
$labels['logoutclear'] = 'Очищать корзину при выходе';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Удалить подпиÑÑŒ при отве
$labels['autoaddsignature'] = 'ÐвтоматичеÑки добавлÑÑ‚ÑŒ подпиÑÑŒ';
$labels['newmessageonly'] = 'только в новых ÑообщениÑÑ…';
$labels['replyandforwardonly'] = 'только в ответах и переÑылках';
-$labels['replysignaturepos'] = 'Прикрепить подпиÑÑŒ при ответе и переÑылке';
-$labels['belowquote'] = 'поÑле цитаты';
-$labels['abovequote'] = 'до цитаты';
$labels['insertsignature'] = 'Ð’Ñтавить подпиÑÑŒ';
$labels['previewpanemarkread'] = 'Отмечать проÑмотренные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ°Ðº прочитанные';
$labels['afternseconds'] = 'через $n Ñекунд';
@@ -473,6 +476,7 @@ $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 0693887c0..f9c8c433a 100644
--- a/program/localization/ru_RU/messages.inc
+++ b/program/localization/ru_RU/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Ошибка базы данных!';
$messages['requesttimedout'] = 'Превышено Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа';
$messages['errorreadonly'] = 'Ðевозможно выполнить операцию. Папка доÑтупна только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ';
$messages['errornoperm'] = 'Ðевозможно выполнить операцию. ДоÑтуп запрещён';
+$messages['erroroverquota'] = 'Ðевозможно выполнить операцию. Ðет Ñвободного меÑта на диÑке.';
+$messages['erroroverquotadelete'] = 'Ðет Ñвободного меÑта на диÑке. ИÑпользуйте SHIFT+DEL Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑообщениÑ.';
$messages['invalidrequest'] = 'Ðеверный запроÑ! Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ðµ Ñохранена.';
$messages['invalidhost'] = 'Ðеверное Ð¸Ð¼Ñ Ñервера.';
$messages['nomessagesfound'] = 'Сообщений не найдено';
diff --git a/program/localization/si_LK/labels.inc b/program/localization/si_LK/labels.inc
index eddc01b57..92d33d3b7 100644
--- a/program/localization/si_LK/labels.inc
+++ b/program/localization/si_LK/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'කටු සටහන්';
$labels['sent'] = 'යà·à·€à·–';
$labels['trash'] = 'ඉවතලන බඳුන';
$labels['junk'] = 'සුන්බුන්';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'මà·à¶­à·˜à¶šà·à·€';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'දà·à¶±à¶§ ඇති පිටුව';
$labels['unread'] = 'නොකියවූ';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'මක෠දà·à¶¸à·–';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'බහà·à¶½à·”ම් ක්â€à¶»à·’යà·...';
$labels['compact'] = 'සංයුක්ත';
$labels['empty'] = 'හිස්';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'නොදනී';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'සෙවුම යලි පිහිටවීම';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'සම්පූර්ණ පණිවිඩය';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'නව කවුළුවක විවෘත කරන්න';
$labels['emlsave'] = 'Download (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'අවසà·à¶± පිටුව පෙන්වනà
$labels['group'] = 'කණ්ඩà·à¶ºà¶¸';
$labels['groups'] = 'කණ්ඩà·à¶ºà¶¸à·Š';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'පුද්ගලික ලිපිනය';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML පණිවිඩයක් සෑදීම';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML අත්සන';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'පූර්වදර්à·à¶± කොටස පෙන්නන්න';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$labels['autoaddsignature'] = 'ස්වයංක්â€à¶»à·“යව අත්සන ඇතුලත් කරන්න';
$labels['newmessageonly'] = 'අලුත් පණිවිඩය පමණක්';
$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'] = 'අත්සන ඇතුලත් කරන්න';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = 'තත්පර $nකට පසු';
@@ -473,6 +476,7 @@ $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 b8ecab335..c3828bc64 100644
--- a/program/localization/si_LK/messages.inc
+++ b/program/localization/si_LK/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'දත්ත ගබඩà·à·€à·š දà·à·‚ය!';
$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'] = 'ලියුම් පෙට්ටියේ පනිවුඩ නà·à¶­';
diff --git a/program/localization/sk_SK/labels.inc b/program/localization/sk_SK/labels.inc
index 7b993e77a..465252409 100644
--- a/program/localization/sk_SK/labels.inc
+++ b/program/localization/sk_SK/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Aktuálna stránka';
$labels['unread'] = 'NepreÄítané';
$labels['flagged'] = 'OznaÄené';
$labels['unanswered'] = 'NeoznaÄené';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Zmazané';
$labels['undeleted'] = 'Nevymazané';
$labels['invert'] = 'Prevrátiť';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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ť';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Vytvoriť HTML správu';
$labels['htmlonreply'] = 'len v odpovedi na HTML správy';
$labels['htmlonreplyandforward'] = 'pri preposielaní alebo odpovedi na HTML správu';
$labels['htmlsignature'] = 'HTML podpis';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Ukázať náhľad';
$labels['skin'] = 'Vzhľad';
$labels['logoutclear'] = 'Vyprázdniť kôš pri odhlásení';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Pri odpovedaní odstrániť zo správy pôvod
$labels['autoaddsignature'] = 'Automaticky pridať podpis';
$labels['newmessageonly'] = 'iba k novým správam';
$labels['replyandforwardonly'] = 'len k odpovede a preposílanej správe';
-$labels['replysignaturepos'] = 'Pri odpovedaní alebo preposielanie správy vložiť podpis';
-$labels['belowquote'] = 'nad citáciu';
-$labels['abovequote'] = 'pod citáciu';
$labels['insertsignature'] = 'Vložit podpis';
$labels['previewpanemarkread'] = 'OznaÄiÅ¥ zobrazenej správy ako preÄítané';
$labels['afternseconds'] = 'po $n sekundách';
@@ -473,6 +476,7 @@ $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 f0ee82978..a6f319db6 100644
--- a/program/localization/sk_SK/messages.inc
+++ b/program/localization/sk_SK/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Databázová chyba!';
$messages['requesttimedout'] = 'Čas požiadavky vypršal';
$messages['errorreadonly'] = 'Nemožno vykonaÅ¥ operáciu. Adresár je len na Äítanie';
$messages['errornoperm'] = 'Nemožno vykonať operáciu. Prístup odmietnutý';
+$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'] = 'Chybný požiadavek. Žiadne údaje neboli uložené.';
$messages['invalidhost'] = 'Neplatný názov servera';
$messages['nomessagesfound'] = 'Vo Vašej schránke nie je žiadna správa';
diff --git a/program/localization/sl_SI/labels.inc b/program/localization/sl_SI/labels.inc
index 70150e4d9..c33ea479c 100644
--- a/program/localization/sl_SI/labels.inc
+++ b/program/localization/sl_SI/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Trenutna stran';
$labels['unread'] = 'Neprebrano';
$labels['flagged'] = 'OznaÄeno';
$labels['unanswered'] = 'NeoznaÄeno';
+$labels['withattachment'] = 'S priponko';
$labels['deleted'] = 'Izbrisano';
$labels['undeleted'] = 'Ni izbrisano';
$labels['invert'] = 'Zamenjaj';
@@ -192,6 +194,7 @@ $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';
@@ -202,11 +205,12 @@ $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'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Prikaži kot golo besedilo';
+$labels['changeformathtml'] = 'Prikaži v formatu HTML';
// message compose
$labels['editasnew'] = 'Uredi kot novo';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Zadnja stran';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupine';
+$labels['listgroup'] = 'IzpiÅ¡i seznam Älanov skupine';
$labels['personaladrbook'] = 'Stiki';
$labels['searchsave'] = 'Shrani iskanje';
@@ -401,6 +406,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['previewpane'] = 'Prikaži predogled';
$labels['skin'] = 'Tema uporabniškega vmesnika';
$labels['logoutclear'] = 'Izprazni mapo Smeti ob odjavi';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Pri odgovoru na sporoÄilo odstrani izvorni p
$labels['autoaddsignature'] = 'Samodejno dodaj podpis';
$labels['newmessageonly'] = 'samo novim sporoÄilom';
$labels['replyandforwardonly'] = 'samo k odgovorom in posredovanim sporoÄilom';
-$labels['replysignaturepos'] = 'Pri odgovoru ali posredovanju sporoÄila vstavi podpis';
-$labels['belowquote'] = 'pod citiran tekst';
-$labels['abovequote'] = 'nad citiran tekst';
$labels['insertsignature'] = 'Vstavi podpis';
$labels['previewpanemarkread'] = 'OznaÄi predogledana sporoÄila kot prebrana';
$labels['afternseconds'] = 'po $n sekundah';
@@ -473,6 +476,7 @@ $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 3fd113b0d..dc731d01b 100644
--- a/program/localization/sl_SI/messages.inc
+++ b/program/localization/sl_SI/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Napaka v bazi';
$messages['requesttimedout'] = 'Zahteva je potekla';
$messages['errorreadonly'] = 'Operacije ni bilo mogoÄe izvrÅ¡iti. Mapa je na voljo samo za branje.';
$messages['errornoperm'] = 'Operacije ni bilo mogoÄe izvrÅ¡iti. Dostop zavrnjen.';
+$messages['erroroverquota'] = 'Operacije ni mogoÄe izvrÅ¡iti. Diskovni prostor je zaseden.';
+$messages['erroroverquotadelete'] = 'Zmanjkalo je diskovnega prostora. Za izbris sporoÄila porabite tipki SHIFT+DEL.';
$messages['invalidrequest'] = 'Neveljavna zahteva. Podatki niso bili shranjeni.';
$messages['invalidhost'] = 'Nepravilno ime strežnika';
$messages['nomessagesfound'] = 'V poÅ¡tnem predalu ni sporoÄil.';
@@ -119,11 +121,13 @@ $messages['selectimportfile'] = 'Izberite datoteko, ki jo želite prenesti';
$messages['addresswriterror'] = 'Izbran imenik ni zapisljiv';
$messages['contactaddedtogroup'] = 'Stik je bil uspešno dodan v skupino';
$messages['contactremovedfromgroup'] = 'Stik je bil uspešno izbrisan iz skupine';
-$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$messages['nogroupassignmentschanged'] = 'Dodeljevanje skupini ni bilo spremenjeno.';
$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?';
@@ -163,7 +167,7 @@ $messages['invalidimageformat'] = 'Neveljaven format slike';
$messages['mispellingsfound'] = 'V sporoÄilu so bile najdene napake v Ärkovanju';
$messages['parentnotwritable'] = 'Podmape v tej mapi ni bilo mogoÄe ustvariti/premakniti. Nimate pravic.';
$messages['messagetoobig'] = 'SporoÄilo je preveliko za obdelavo.';
-$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'] = 'OPOZORILO! Priponka vsebuje sumljivo vsebino, saj tip priponke ne ustreza tipu, doloÄenemu v sporoÄilu. ÄŒe ne zaupate poÅ¡iljatelju, priponke v brskalniku ne odpirajte, saj lahko vsebuje zlonamerno vsebino. <br/><br/><em>PriÄakovano: $expected; Najdeno: $detected</em>';
$messages['noscriptwarning'] = 'Opozorilo: Ta spletna stran zahteva Javascript! Za uporabo jo vkljuÄite v nastavitvah vaÅ¡ega brskalnika.';
?>
diff --git a/program/localization/sq_AL/labels.inc b/program/localization/sq_AL/labels.inc
index 52ff45cd6..e2cb6791b 100644
--- a/program/localization/sq_AL/labels.inc
+++ b/program/localization/sq_AL/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'Palexuar';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'Unanswered';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Deleted';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Shkruaj mesazhe HTML';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'Nënshkrimi HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Shiko si duket';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$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';
@@ -473,6 +476,7 @@ $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 46e7197e0..56bb9feb2 100644
--- a/program/localization/sq_AL/messages.inc
+++ b/program/localization/sq_AL/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'Nuk ka mesazhe në këtë kuti postare';
diff --git a/program/localization/sr_CS/labels.inc b/program/localization/sr_CS/labels.inc
index 1e84735e6..4bdf25020 100644
--- a/program/localization/sr_CS/labels.inc
+++ b/program/localization/sr_CS/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'U pripremi';
$labels['sent'] = 'ПоÑлате';
$labels['trash'] = 'Канта';
$labels['junk'] = 'Смеће';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÐаÑлов';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Тренутна Ñтраница';
$labels['unread'] = 'Ðепрочитане';
$labels['flagged'] = 'Означено';
$labels['unanswered'] = 'Ðеодговорено';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'ОбриÑано';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'Уведи';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'ЛиÑÑ‚ режим приказивања';
$labels['folderactions'] = 'ПоÑтавке фаÑцикле';
$labels['compact'] = 'Компакција';
$labels['empty'] = 'ИÑпразни';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Квота';
$labels['unknown'] = 'непозната';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'Прикажи Ñве поруке';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Цела порука';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори у новом прозору';
$labels['emlsave'] = 'Довнлоад (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Прикажи поÑледњи Ñкуп';
$labels['group'] = 'Група';
$labels['groups'] = 'Групе';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Личне адреÑе';
$labels['searchsave'] = 'Сачувај претрагу';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'СаÑтави HTML поруке';
$labels['htmlonreply'] = 'Ñамо при одговору на HTML поруку';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML потпиÑ';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Прикажи панел за преглед';
$labels['skin'] = 'ИнтерфејÑ';
$labels['logoutclear'] = 'Избриши Ñмеће при логовању';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'При одговору одÑтрани ор
$labels['autoaddsignature'] = 'ÐутоматÑки додај потпиÑ';
$labels['newmessageonly'] = 'Ñамо нове поруке';
$labels['replyandforwardonly'] = 'Ñамо одговори и проÑлеђивања';
-$labels['replysignaturepos'] = 'При одговору или проÑлеђивању додај потпиÑ';
-$labels['belowquote'] = 'иÑпод квоте';
-$labels['abovequote'] = 'изнад квоте';
$labels['insertsignature'] = 'Убаци потпиÑ';
$labels['previewpanemarkread'] = 'Прегледану поруку означи као прочитану';
$labels['afternseconds'] = 'након $n Ñекунди';
@@ -473,6 +476,7 @@ $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 7ffbbd34a..32007e6f2 100644
--- a/program/localization/sr_CS/messages.inc
+++ b/program/localization/sr_CS/messages.inc
@@ -28,6 +28,8 @@ $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['invalidrequest'] = 'Погрешан захтев! Подаци ниÑу Ñачувани.';
$messages['invalidhost'] = 'Погрешно име Ñервера.';
$messages['nomessagesfound'] = 'Ðемате порука у Ñандучету.';
diff --git a/program/localization/sv_SE/labels.inc b/program/localization/sv_SE/labels.inc
index c1a91cf82..7169aeba8 100644
--- a/program/localization/sv_SE/labels.inc
+++ b/program/localization/sv_SE/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Sida';
$labels['unread'] = 'Olästa';
$labels['flagged'] = 'Flaggade';
$labels['unanswered'] = 'Obesvarade';
+$labels['withattachment'] = 'Med bilaga';
$labels['deleted'] = 'Borttagna';
$labels['undeleted'] = 'Inte borttaget';
$labels['invert'] = 'Invertera';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $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';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Skriv meddelanden i HTML-format';
$labels['htmlonreply'] = 'Endast vid svar på meddelande i HTML-format';
$labels['htmlonreplyandforward'] = 'Vid svar på eller vidarebefordran av meddelande i HTML-format';
$labels['htmlsignature'] = 'HTML-signatur';
+$labels['showemail'] = 'Visa namn och adress';
$labels['previewpane'] = 'Visa meddelandefältet';
$labels['skin'] = 'Stilmall för användargränssnitt';
$labels['logoutclear'] = 'Töm papperskorgen vid utloggning';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Ta bort befintlig signatur från meddelandet
$labels['autoaddsignature'] = 'Infoga signatur automatiskt';
$labels['newmessageonly'] = 'Vid nytt meddelande';
$labels['replyandforwardonly'] = 'Vid svar och vidarebefordran';
-$labels['replysignaturepos'] = 'Vid svar eller vidarebefordran infoga signatur';
-$labels['belowquote'] = 'Nedanför befintligt meddelande';
-$labels['abovequote'] = 'Ovanför befintligt meddelande';
$labels['insertsignature'] = 'Infoga signatur';
$labels['previewpanemarkread'] = 'Märk meddelande som läst vid visning';
$labels['afternseconds'] = 'Efter $n sekunder';
@@ -473,6 +476,7 @@ $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 65ee6827d..63dddc548 100644
--- a/program/localization/sv_SE/messages.inc
+++ b/program/localization/sv_SE/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Databasfel!';
$messages['requesttimedout'] = 'Begäran tog för lång tid';
$messages['errorreadonly'] = 'Åtgärden kunde inte utföras. Katalogen är skrivskyddad';
$messages['errornoperm'] = 'Åtgärden kunde inte utföras. Otillräcklig befogenhet';
+$messages['erroroverquota'] = 'Åtgärden kunde inte utföras. Otillräckligt lagringsutrymme.';
+$messages['erroroverquotadelete'] = 'Otillräckligt lagringsutrymme. Tryck på SHIFT och DEL för att ta bort ett meddelande.';
$messages['invalidrequest'] = 'Ogiltig begäran! Informationen sparades inte.';
$messages['invalidhost'] = 'Ogiltigt servernamn.';
$messages['nomessagesfound'] = 'Inga meddelanden';
diff --git a/program/localization/ta_IN/labels.inc b/program/localization/ta_IN/labels.inc
index 1cbffb588..197e80606 100644
--- a/program/localization/ta_IN/labels.inc
+++ b/program/localization/ta_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'வரைவà¯à®•à®³à¯';
$labels['sent'] = 'அனà¯à®ªà¯à®ªà®¿à®¯ அஞà¯à®šà®²à¯';
$labels['trash'] = 'கà¯à®ªà¯à®ªà¯ˆ';
$labels['junk'] = 'எரிதமà¯';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'தலைபà¯à®ªà¯';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Current page';
$labels['unread'] = 'படிகà¯à®•à®¾à®¤à®¤à¯';
$labels['flagged'] = 'நடà¯à®šà®¤à¯à®¤à®¿à®°à®®à®¿à®Ÿà¯à®Ÿà®¤à¯';
$labels['unanswered'] = 'பதிலளிகà¯à®•à®¾à®¤à®¤à¯';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'நீகà¯à®•à®¿à®¯à®¤à¯';
$labels['undeleted'] = 'Not deleted';
$labels['invert'] = 'தலைகீழà¯';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'கà¯à®±à¯à®•à®¿à®¯';
$labels['empty'] = 'காலி';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ அளவà¯';
$labels['unknown'] = 'தெரியாத';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'தேடலை மறà¯à®…மை';
$labels['searchmod'] = 'மாறà¯à®±à®¿à®•à®³à¯ˆ தேடà¯';
$labels['msgtext'] = 'à®®à¯à®´à¯ செயà¯à®¤à®¿';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'பà¯à®¤à¯ சாளரதà¯à®¤à®¿à®²à¯ திற';
$labels['emlsave'] = 'பதிவிறகà¯à®•à¯ (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'கடைசி கà¯à®´à¯à®µà¯ˆ காடà¯à®Ÿà
$labels['group'] = 'Group';
$labels['groups'] = 'கà¯à®´à¯à®•à¯à®•à®³à¯';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'சà¯à®¯ à®®à¯à®•à®µà®°à®¿';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'HTML செயà¯à®¤à®¿à®•à®³à¯ˆ எழà¯à®¤à¯';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'HTML கையொபà¯à®ªà®®à¯';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'à®®à¯à®¨à¯à®¤à®¿à®¯ பாதà¯à®¤à®¿à®¯à¯ˆ காடà¯à®Ÿà¯';
$labels['skin'] = 'à®®à¯à®•à®ªà¯à®ªà¯ தோறà¯à®±à®®à¯';
$labels['logoutclear'] = 'வெளியேறà¯à®®à¯ போத௠கà¯à®ªà¯à®ªà¯ˆà®¯à¯ˆ காலி செயà¯';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'பதிலளிகà¯à®•à¯à®®à¯ பேà®
$labels['autoaddsignature'] = 'தானாக கையொபà¯à®ªà®¤à¯à®¤à¯ˆ சேரà¯';
$labels['newmessageonly'] = 'பà¯à®¤à¯ செயà¯à®¤à®¿ மடà¯à®Ÿà¯à®®à¯';
$labels['replyandforwardonly'] = 'பதிலளிபà¯à®ªà¯ à®®à¯à®©à¯à®…னà¯à®ªà¯à®ªà¯ மடà¯à®Ÿà¯à®®à¯';
-$labels['replysignaturepos'] = 'பதிலளிகà¯à®•à¯à®®à¯ போதà¯à®®à¯ à®®à¯à®©à¯à®…னà¯à®ªà¯à®ªà¯à®®à¯ போதà¯à®®à¯ கையோபà¯à®ªà®®à®¿à®Ÿà¯';
-$labels['belowquote'] = 'மேறà¯à®•à¯‹à®³à¯à®•à¯à®•à¯ கீழே';
-$labels['abovequote'] = 'மேறà¯à®•à¯‹à®³à¯à®•à¯à®•à¯ மேலே';
$labels['insertsignature'] = 'கையோபà¯à®ªà®®à®¿à®Ÿà¯';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = 'after $n seconds';
@@ -473,6 +476,7 @@ $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 c06765435..65e611f88 100644
--- a/program/localization/ta_IN/messages.inc
+++ b/program/localization/ta_IN/messages.inc
@@ -28,6 +28,8 @@ $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'] = 'செலà¯à®²à®¾à®¤ வேணà¯à®Ÿà¯à®•à¯‹à®³à¯! எநà¯à®¤ தரவà¯à®®à¯ சேமிகà¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.';
$messages['invalidhost'] = 'Invalid server name.';
$messages['nomessagesfound'] = 'இநà¯à®¤ தபால௠பெடà¯à®Ÿà®¿à®¯à®¿à®²à¯ எநà¯à®¤ தரவà¯à®®à¯ சேமிகà¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ';
diff --git a/program/localization/th_TH/labels.inc b/program/localization/th_TH/labels.inc
index 93f2304e1..85b091e5b 100644
--- a/program/localization/th_TH/labels.inc
+++ b/program/localization/th_TH/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายร่าง';
$labels['sent'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸‚าออà¸';
$labels['trash'] = 'ถังขยะ';
$labels['junk'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายขยะ';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'หัวจดหมาย';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'หน้าปัจจุบัน';
$labels['unread'] = 'จดหมายที่ไม่ได้อ่าน';
$labels['flagged'] = 'Flagged';
$labels['unanswered'] = 'ยังไม่ได้ตอบ';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'ลบà¹à¸¥à¹‰à¸§';
$labels['undeleted'] = 'ยังไม่ได้ลบ';
$labels['invert'] = 'Invert';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'à¹à¸šà¸šà¸¢à¹ˆà¸­';
$labels['empty'] = 'ว่างเปล่า';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'พื้นที่ใช้งาน';
$labels['unknown'] = 'ไม่ทราบ';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'เขียนจดหมายà¹à¸šà¸š HTML';
$labels['htmlonreply'] = 'on reply to HTML message';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = 'ลายมือชื่อà¹à¸šà¸š HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'à¹à¸ªà¸”งหน้าต่างตัวอย่างà¹à¸ªà¸”งผล';
$labels['skin'] = 'Interface skin';
$labels['logoutclear'] = 'Clear Trash on logout';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'When replying remove original signature from
$labels['autoaddsignature'] = 'เพิ่มลายเซ็นต์เข้าไปอัตโนมัติ';
$labels['newmessageonly'] = 'เฉพาะข้อความใหม่เท่านั้น';
$labels['replyandforwardonly'] = 'ตอบà¸à¸¥à¸±à¸šà¹à¸¥à¸°à¸ªà¹ˆà¸‡à¸•à¹ˆà¸­à¹€à¸—่านั้น';
-$labels['replysignaturepos'] = 'When replying or forwarding place signature';
-$labels['belowquote'] = 'below the quote';
-$labels['abovequote'] = 'above the quote';
$labels['insertsignature'] = 'à¹à¸—รà¸à¸¥à¸²à¸¢à¹€à¸‹à¹‡à¸™à¸•à¹Œ';
$labels['previewpanemarkread'] = 'Mark previewed messages as read';
$labels['afternseconds'] = 'after $n seconds';
@@ -473,6 +476,7 @@ $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 1b78b7d60..826930c0e 100644
--- a/program/localization/th_TH/messages.inc
+++ b/program/localization/th_TH/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'เà¸à¸´à¸”ข้อผิดพลาดเà¸à¸µà¹ˆà¸
$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['nomessagesfound'] = 'ไม่มีจดหมายในà¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายนี้';
diff --git a/program/localization/tr_TR/labels.inc b/program/localization/tr_TR/labels.inc
index d8e9e20cf..c62c5c079 100644
--- a/program/localization/tr_TR/labels.inc
+++ b/program/localization/tr_TR/labels.inc
@@ -37,6 +37,7 @@ $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';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Åžimdiki sayfa';
$labels['unread'] = 'Okunmamışları';
$labels['flagged'] = 'Ä°ÅŸaretlenmiÅŸleri';
$labels['unanswered'] = 'Yanıtlanmamışları';
+$labels['withattachment'] = 'Eklenti ile';
$labels['deleted'] = 'SilinmiÅŸleri';
$labels['undeleted'] = 'SilinmemiÅŸ';
$labels['invert'] = 'Seçimi Tersine Çevir';
@@ -192,6 +194,7 @@ $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';
@@ -202,6 +205,7 @@ $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)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'Sonuncuyu göster';
$labels['group'] = 'Grup';
$labels['groups'] = 'Gruplar';
+$labels['listgroup'] = 'Grup üyelerini listele';
$labels['personaladrbook'] = 'Adresler';
$labels['searchsave'] = 'Aramayı kaydet';
@@ -401,6 +406,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['previewpane'] = 'Önizleme panelini göster';
$labels['skin'] = 'Arayüz görünümü';
$labels['logoutclear'] = 'Oturumu kapatınca Çöpü temizle';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'Yanıtlarken önceki imzaları sil';
$labels['autoaddsignature'] = 'Otomatik olarak imza ekle';
$labels['newmessageonly'] = 'sadece yeni postalarda';
$labels['replyandforwardonly'] = 'sadece yanıtlar ve yönlendirmelerde';
-$labels['replysignaturepos'] = 'Yanıtlarken veya yönlendirirken imzayı yerleştir';
-$labels['belowquote'] = 'alıntının altına';
-$labels['abovequote'] = 'alıntının üstüne';
$labels['insertsignature'] = 'Ä°mza ekle';
$labels['previewpanemarkread'] = 'Önzilemede görünen postaları okunmuş işaretle';
$labels['afternseconds'] = '$n saniye sonra';
@@ -473,6 +476,7 @@ $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 3b451d556..3f728b523 100644
--- a/program/localization/tr_TR/messages.inc
+++ b/program/localization/tr_TR/messages.inc
@@ -126,6 +126,8 @@ $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 35be96cab..6ff37ee21 100644
--- a/program/localization/uk_UA/labels.inc
+++ b/program/localization/uk_UA/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Чернетки';
$labels['sent'] = 'ÐадіÑлані';
$labels['trash'] = 'Кошик';
$labels['junk'] = 'Спам';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Тема';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'Поточна Ñторінка';
$labels['unread'] = 'Ðепрочитані';
$labels['flagged'] = 'Із зірочкою';
$labels['unanswered'] = 'Без відповіді';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Видалені';
$labels['undeleted'] = 'Ðе видалено';
$labels['invert'] = 'Інвертувати виділеннÑ';
@@ -192,6 +194,7 @@ $labels['listmode'] = 'Режим переглÑду';
$labels['folderactions'] = 'Операції з папкою...';
$labels['compact'] = 'СтиÑнути';
$labels['empty'] = 'Спорожнити';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ВикориÑтано';
$labels['unknown'] = 'невідомо';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'ОчиÑтити пошук';
$labels['searchmod'] = 'Де шукати';
$labels['msgtext'] = 'Ð’ уÑьому лиÑÑ‚Ñ–';
$labels['body'] = 'Тіло повідомленнÑ';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Відкрити в новому вікні';
$labels['emlsave'] = 'Зберегти (.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = 'ОÑÑ‚Ð°Ð½Ð½Ñ Ñторінка';
$labels['group'] = 'Група';
$labels['groups'] = 'Групи';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ПерÑональні адреÑи';
$labels['searchsave'] = 'Зберегти пошук';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = 'Створювати лиÑти в HTML';
$labels['htmlonreply'] = 'тільки у відповідь на HTML повідомленнÑ';
$labels['htmlonreplyandforward'] = 'під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ відповіді на Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ HTML';
$labels['htmlsignature'] = 'ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð² HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Показати панель переглÑду';
$labels['skin'] = 'Тема';
$labels['logoutclear'] = 'Очищати кошик при виході';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = 'При відповіді видалÑти п
$labels['autoaddsignature'] = 'Ðвтоматично додавати підпиÑ';
$labels['newmessageonly'] = 'тільки до нових лиÑтів';
$labels['replyandforwardonly'] = 'тільки при відповідÑÑ… та переÑилках';
-$labels['replysignaturepos'] = 'При відповідÑÑ… чи переÑилках додавати підпиÑ';
-$labels['belowquote'] = 'піÑÐ»Ñ Ñ†Ð¸Ñ‚Ð°Ñ‚Ð¸';
-$labels['abovequote'] = 'перед цитатою';
$labels['insertsignature'] = 'Додати підпиÑ';
$labels['previewpanemarkread'] = 'Позначити переглÑнуті лиÑти Ñк прочитані';
$labels['afternseconds'] = 'через $n Ñекунд';
@@ -473,6 +476,7 @@ $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/uk_UA/messages.inc b/program/localization/uk_UA/messages.inc
index 522f1f4fc..521492d99 100644
--- a/program/localization/uk_UA/messages.inc
+++ b/program/localization/uk_UA/messages.inc
@@ -28,6 +28,8 @@ $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['invalidrequest'] = 'Ðевірний запит! Дані не збережено.';
$messages['invalidhost'] = 'Ðевірне ім\'Ñ Ñерверу.';
$messages['nomessagesfound'] = 'ЛиÑтів не знайдено';
diff --git a/program/localization/vi_VN/labels.inc b/program/localization/vi_VN/labels.inc
index 00d04b46b..aad0dafe6 100644
--- a/program/localization/vi_VN/labels.inc
+++ b/program/localization/vi_VN/labels.inc
@@ -37,6 +37,7 @@ $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 Ä‘á»';
@@ -64,6 +65,7 @@ $labels['copy'] = 'Sao chép';
$labels['move'] = 'Di Chuyển';
$labels['moveto'] = 'Di chuyển tới...';
$labels['download'] = 'Tải vá»';
+$labels['open'] = 'Open';
$labels['showattachment'] = 'Hiển thị';
$labels['showanyway'] = 'Tiếp tục hiển thị';
@@ -161,6 +163,7 @@ $labels['currpage'] = 'Trang hiện tại';
$labels['unread'] = 'ChÆ°a Ä‘á»c';
$labels['flagged'] = 'Äã đánh dấu';
$labels['unanswered'] = 'ChÆ°a trả lá»i';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = 'Äã xóa';
$labels['undeleted'] = 'Chưa xóa được';
$labels['invert'] = 'Äảo ngược';
@@ -191,6 +194,7 @@ $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õ';
@@ -201,9 +205,12 @@ $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';
+$labels['changeformattext'] = 'Display in plain text format';
+$labels['changeformathtml'] = 'Display in HTML format';
// message compose
$labels['editasnew'] = 'Sá»­a nhÆ° má»™t email má»›i';
@@ -335,8 +342,8 @@ $labels['composeto'] = 'Soạn thư cho';
$labels['contactsfromto'] = 'Liên hệ từ $from - $to / $count';
$labels['print'] = 'In ra';
$labels['export'] = 'Trích xuất';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Xuất tất cả';
+$labels['exportsel'] = 'Xuất mục chá»n';
$labels['exportvcards'] = 'Tải dữ liệu máy theo định dạng vCard';
$labels['newcontactgroup'] = 'Tạo nhóm liên lạc mới';
$labels['grouprename'] = 'Äổi tên nhóm';
@@ -350,6 +357,7 @@ $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';
@@ -398,6 +406,7 @@ $labels['htmleditor'] = 'Soạn thư dạng HTML';
$labels['htmlonreply'] = 'Chỉ trả lá»i lại bằng thÆ° HTML';
$labels['htmlonreplyandforward'] = 'Khi chuyển tiếp hoặc trả lá»i thÆ° theo định dạng HTML';
$labels['htmlsignature'] = 'Chữ ký HTML';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = 'Hiển thị ô Xem thử';
$labels['skin'] = 'BỠmặt giao diện';
$labels['logoutclear'] = 'Xóa sạch rác khi thoát';
@@ -451,9 +460,6 @@ $labels['replyremovesignature'] = 'Khi trả lá»i bá» chữ ký cÅ© khá»i ná»
$labels['autoaddsignature'] = 'Tự động thêm chữ ký';
$labels['newmessageonly'] = 'chỉ thư mới';
$labels['replyandforwardonly'] = 'chỉ trả lá»i và chuyển tiếp thÆ°';
-$labels['replysignaturepos'] = 'Khi trả lá»i hoặc chuyển tiếp thÆ° thêm vào chữ ký';
-$labels['belowquote'] = 'Dưới phần nội dung cũ';
-$labels['abovequote'] = 'trên phần nội dung cũ';
$labels['insertsignature'] = 'Chèn chữ ký';
$labels['previewpanemarkread'] = 'Äánh dẫu thÆ° xem thá»­ là đã Ä‘á»c';
$labels['afternseconds'] = 'sau $n giây';
@@ -470,6 +476,7 @@ $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 1d5f5f84c..50bf71846 100644
--- a/program/localization/vi_VN/messages.inc
+++ b/program/localization/vi_VN/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = 'Lỗi cơ sở dữ liệu';
$messages['requesttimedout'] = 'Yêu cầu hết hạn';
$messages['errorreadonly'] = 'Không thể thá»±c hiện thao tác. ThÆ° mục chỉ cho phép Ä‘á»c.';
$messages['errornoperm'] = 'Bạn không đủ quyá»n hạn để thá»±c hiện thao tác này.';
+$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'] = 'Yêu cầu không hợp lệ! Không có dữ liệu nào được lưu.';
$messages['invalidhost'] = 'Sai thông tin máy chủ';
$messages['nomessagesfound'] = 'Không thấy có thư nào trong hộp thư này.';
diff --git a/program/localization/zh_CN/labels.inc b/program/localization/zh_CN/labels.inc
index 9b79283b1..b568a7008 100644
--- a/program/localization/zh_CN/labels.inc
+++ b/program/localization/zh_CN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'è‰ç¨¿ç®±';
$labels['sent'] = 'å·²å‘é€é‚®ä»¶';
$labels['trash'] = '已删除邮件';
$labels['junk'] = '垃圾邮件';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '主题';
@@ -162,6 +163,7 @@ $labels['currpage'] = '当å‰é¡µ';
$labels['unread'] = '未读邮件';
$labels['flagged'] = '已标记邮件';
$labels['unanswered'] = '未回å¤é‚®ä»¶';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = '已删除邮件';
$labels['undeleted'] = '未删除邮件';
$labels['invert'] = 'å选';
@@ -192,6 +194,7 @@ $labels['listmode'] = '列表视图样å¼';
$labels['folderactions'] = '文件夹æ“作...';
$labels['compact'] = '压缩';
$labels['empty'] = '清空';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = '邮箱容é‡';
$labels['unknown'] = '未知';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = '清空';
$labels['searchmod'] = '修改æœç´¢';
$labels['msgtext'] = 'æ•´å°é‚®ä»¶';
$labels['body'] = '正文';
+$labels['type'] = 'Type';
$labels['openinextwin'] = '在新窗å£ä¸­æ‰“å¼€';
$labels['emlsave'] = '下载(.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = '最åŽä¸€é¡µ';
$labels['group'] = '分组';
$labels['groups'] = '分组';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = '个人通讯录';
$labels['searchsave'] = 'ä¿å­˜æœç´¢';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = '使用 HTML 编辑器';
$labels['htmlonreply'] = 'ä»…å½“å›žå¤ HTML 邮件';
$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
$labels['htmlsignature'] = '使用 HTML ç­¾å';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = '显示预览窗å£';
$labels['skin'] = 'ç•Œé¢çš®è‚¤';
$labels['logoutclear'] = '退出时清空回收站';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = '当回å¤æ—¶ä»Žé‚®ä»¶ç§»é™¤åŽŸå§‹ç­¾å';
$labels['autoaddsignature'] = '自动æ’入签å';
$labels['newmessageonly'] = '仅新邮件';
$labels['replyandforwardonly'] = '仅回å¤å’Œè½¬å‘邮件';
-$labels['replysignaturepos'] = '当回å¤æˆ–转å‘æ—¶æ’入签å';
-$labels['belowquote'] = 'ä½äºŽåŽŸæ–‡ä¸‹æ–¹';
-$labels['abovequote'] = 'ä½äºŽåŽŸæ–‡ä¸Šæ–¹';
$labels['insertsignature'] = 'æ’入签å';
$labels['previewpanemarkread'] = '标记预览邮件为已读';
$labels['afternseconds'] = '$n 秒之åŽ';
@@ -473,6 +476,7 @@ $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_TW/labels.inc b/program/localization/zh_TW/labels.inc
index 488a7ab2d..7726da5dd 100644
--- a/program/localization/zh_TW/labels.inc
+++ b/program/localization/zh_TW/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'è‰ç¨¿åŒ£';
$labels['sent'] = '寄件備份';
$labels['trash'] = '垃圾桶';
$labels['junk'] = '垃圾郵件';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '主旨';
@@ -162,6 +163,7 @@ $labels['currpage'] = 'ç›®å‰é é¢';
$labels['unread'] = '未讀å–的郵件';
$labels['flagged'] = '已加標記的郵件';
$labels['unanswered'] = '未回覆的郵件';
+$labels['withattachment'] = 'With attachment';
$labels['deleted'] = '已刪除的郵件';
$labels['undeleted'] = '未刪除的郵件';
$labels['invert'] = 'åé¸';
@@ -192,6 +194,7 @@ $labels['listmode'] = '清單檢視模å¼';
$labels['folderactions'] = '資料夾動作...';
$labels['compact'] = '壓縮';
$labels['empty'] = '清空';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ç£ç¢Ÿä½¿ç”¨é‡';
$labels['unknown'] = '未知';
@@ -202,6 +205,7 @@ $labels['resetsearch'] = 'é‡è¨­æœå°‹';
$labels['searchmod'] = '修改æœå°‹';
$labels['msgtext'] = 'æ•´å°éƒµä»¶';
$labels['body'] = '內文';
+$labels['type'] = 'Type';
$labels['openinextwin'] = '在新視窗開啟';
$labels['emlsave'] = '下載(.eml)';
@@ -353,6 +357,7 @@ $labels['lastpage'] = '顯示最後一é ';
$labels['group'] = '群組';
$labels['groups'] = '群組';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = '個人通訊錄';
$labels['searchsave'] = '儲存æœå°‹çµæžœ';
@@ -401,6 +406,7 @@ $labels['htmleditor'] = '使用 HTML 撰寫郵件';
$labels['htmlonreply'] = 'åªæœ‰åœ¨å›žè¦†HTML信件時';
$labels['htmlonreplyandforward'] = 'åªæœ‰åœ¨è½‰å¯„或回覆HTML信件時';
$labels['htmlsignature'] = 'HTML ç°½å檔';
+$labels['showemail'] = 'Show email address with display name';
$labels['previewpane'] = '顯示é è¦½çª—æ ¼';
$labels['skin'] = '版é¢é¢¨æ ¼';
$labels['logoutclear'] = '登出時清空垃圾桶';
@@ -454,9 +460,6 @@ $labels['replyremovesignature'] = '回覆時移除原有簽å檔';
$labels['autoaddsignature'] = '自動附加簽å';
$labels['newmessageonly'] = 'åªæœ‰æ–°è¨Šæ¯';
$labels['replyandforwardonly'] = 'åªæœ‰å›žè¦†æˆ–轉寄';
-$labels['replysignaturepos'] = '當回覆或轉寄時附上簽å檔';
-$labels['belowquote'] = '引用的下方';
-$labels['abovequote'] = '引用的上方';
$labels['insertsignature'] = 'æ’入簽å檔';
$labels['previewpanemarkread'] = '標示已é è¦½è¨Šæ¯ç‚ºå·²è®€å–';
$labels['afternseconds'] = '$n 秒之後';
@@ -473,6 +476,7 @@ $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 f0f92c848..5605ba815 100644
--- a/program/localization/zh_TW/messages.inc
+++ b/program/localization/zh_TW/messages.inc
@@ -28,6 +28,8 @@ $messages['dberror'] = '資料庫錯誤!';
$messages['requesttimedout'] = 'è¦æ±‚逾時';
$messages['errorreadonly'] = '動作無法完æˆã€‚資料夾唯讀';
$messages['errornoperm'] = '動作無法完æˆã€‚權é™ä¸ç¬¦';
+$messages['erroroverquota'] = '動作無法完æˆã€‚硬碟空間ä¸å¤ ';
+$messages['erroroverquotadelete'] = '硬碟空間ä¸å¤ ,請使用SHIFT+DEL來刪除訊æ¯';
$messages['invalidrequest'] = 'è¦æ±‚無效ï¼æœªå„²å­˜ä»»ä½•è³‡æ–™ã€‚';
$messages['invalidhost'] = '無效的伺æœå™¨å稱';
$messages['nomessagesfound'] = '此郵件匣沒有任何郵件';
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc
index 480a9b52e..d4387194a 100644
--- a/program/steps/addressbook/copy.inc
+++ b/program/steps/addressbook/copy.inc
@@ -57,10 +57,16 @@ 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
- if (!empty($a_record['email']))
- $result = $TARGET->search('email', $a_record['email'], 1, true, true);
+ // @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);
else if (!empty($a_record['name']))
$result = $TARGET->search('name', $a_record['name'], 1, true, true);
else
@@ -114,7 +120,7 @@ foreach ($cids as $source => $cid)
}
}
-if ($success == 0)
+if (!$success)
$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 56118583c..3bb2ef500 100644
--- a/program/steps/addressbook/delete.inc
+++ b/program/steps/addressbook/delete.inc
@@ -68,48 +68,14 @@ foreach ($cids as $source => $cid)
$page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
// update saved search after data changed
-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;
-
+if (($records = rcmail_search_update(true)) !== false) {
// 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 15bf8b0d4..761f26b75 100644
--- a/program/steps/addressbook/export.inc
+++ b/program/steps/addressbook/export.inc
@@ -138,7 +138,9 @@ header('Content-Disposition: attachment; filename="contacts.vcf"');
while ($result && ($row = $result->next())) {
// we already have a vcard record
if ($row['vcard'] && $row['name']) {
- $row['vcard'] = preg_replace('/\r?\n/', rcube_vcard::$eol, $row['vcard']);
+ // 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
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index ffc0b3b92..8ec581f9a 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -167,7 +167,7 @@ function rcmail_set_sourcename($abook)
// get address book name (for display)
if ($abook && $_SESSION['addressbooks_count'] > 1) {
$name = $abook->get_name();
- if (!$name && $source == 0) {
+ if (!$name) {
$name = rcube_label('personaladrbook');
}
$OUTPUT->set_env('sourcename', html_entity_decode($name, ENT_COMPAT, 'UTF-8'));
@@ -183,7 +183,6 @@ function rcmail_directory_list($attrib)
$attrib['id'] = 'rcmdirectorylist';
$out = '';
- $local_id = '0';
$jsdata = array();
$line_templ = html::tag('li', array(
@@ -270,7 +269,6 @@ function rcmail_contact_groups($args)
$groups_html = '';
$groups = $RCMAIL->get_address_book($args['source'])->list_groups();
- $js_id = $RCMAIL->JQ($args['source']);
if (!empty($groups)) {
$line_templ = html::tag('li', array(
@@ -283,7 +281,6 @@ function rcmail_contact_groups($args)
$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),
@@ -297,7 +294,7 @@ function rcmail_contact_groups($args)
}
$args['out'] .= html::tag('ul',
- array('class' => 'groups', 'style' => ($is_collapsed ? "display:none;" : null)),
+ array('class' => 'groups', 'style' => ($is_collapsed || empty($groups) ? "display:none;" : null)),
$groups_html);
return $args;
@@ -310,7 +307,7 @@ function rcmail_contacts_list($attrib)
global $CONTACTS, $OUTPUT;
// define list of cols to be displayed
- $a_show_cols = array('name');
+ $a_show_cols = array('name','action');
// add id to message list table if not specified
if (!strlen($attrib['id']))
@@ -325,7 +322,7 @@ function rcmail_contacts_list($attrib)
$OUTPUT->include_script('list.js');
// add some labels to client
- $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'contactdeleting');
+ $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'movingcontact', 'contactdeleting');
return $out;
}
@@ -339,31 +336,73 @@ function rcmail_js_contacts_list($result, $prefix='')
return;
// define list of cols to be displayed
- $a_show_cols = array('name');
+ $a_show_cols = array('name','action');
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('person'); // org records will follow some day
+ $classes = array($row['_type'] ? $row['_type'] : 'person');
// 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 = $col == 'name' ? rcube_addressbook::compose_list_name($row) : $row[$col];
- $a_row_cols[$col] = Q($val);
+ $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;
}
if ($row['readonly'])
$classes[] = 'readonly';
- $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes));
+ $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)));
}
}
+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)
{
@@ -432,7 +471,7 @@ function rcmail_get_type_label($type)
function rcmail_contact_form($form, $record, $attrib = null)
{
- global $RCMAIL, $CONFIG;
+ global $RCMAIL;
// Allow plugins to modify contact form content
$plugin = $RCMAIL->plugins->exec_hook('contact_form', array(
@@ -441,7 +480,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' => $CONFIG['skin_path'] . $attrib['deleteicon'], 'alt' => rcube_label('delete'))) : rcube_label('delete');
+ $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => rcube_label('delete'))) : rcube_label('delete');
unset($attrib['deleteicon']);
$out = '';
@@ -554,22 +593,13 @@ 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 ($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;
+ 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;
}
+ // TODO: add $st to $select_subtype if missing ?
}
}
else {
@@ -707,12 +737,15 @@ function rcmail_contact_form($form, $record, $attrib = null)
function rcmail_contact_photo($attrib)
{
- global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL, $CONFIG;
+ global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL;
if ($result = $CONTACTS->get_result())
$record = $result->first();
- $photo_img = $attrib['placeholder'] ? $CONFIG['skin_path'] . $attrib['placeholder'] : 'program/resources/blank.gif';
+ $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']);
+
$RCMAIL->output->set_env('photo_placeholder', $photo_img);
unset($attrib['placeholder']);
@@ -746,6 +779,54 @@ 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
@@ -787,7 +868,7 @@ function rcmail_get_cids($filter = null)
}
}
else {
- if (substr($id, -($got_source+1)) == "-$source") {
+ if (substr($id, -($got_source+1)) === "-$source") {
$id = substr($id, 0, -($got_source+1));
}
$result[$source][] = $id;
@@ -803,6 +884,7 @@ $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')
diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc
index df07d64bc..915aac884 100644
--- a/program/steps/addressbook/import.inc
+++ b/program/steps/addressbook/import.inc
@@ -88,7 +88,7 @@ function rcmail_import_confirm($attrib)
$content = html::p(null, rcube_label(array(
'name' => 'importconfirm',
- 'nr' => $IMORT_STATS->inserted,
+ 'nr' => $IMPORT_STATS->inserted,
'vars' => $vars,
)) . ($IMPORT_STATS->names ? ':' : '.'));
@@ -98,7 +98,7 @@ function rcmail_import_confirm($attrib)
if ($IMPORT_STATS->skipped) {
$content .= html::p(null, rcube_label(array(
'name' => 'importconfirmskipped',
- 'nr' => $IMORT_STATS->skipped,
+ 'nr' => $IMPORT_STATS->skipped,
'vars' => $vars,
)) . ':');
$content .= html::p('em', join(', ', array_map('Q', $IMPORT_STATS->skipped_names)));
@@ -209,6 +209,15 @@ if (is_array($_FILES['_file'])) {
foreach ($vcards as $vcard) {
$a_record = $vcard->get_assoc();
+ // Generate contact's display name (must be before validation), the same we do in save.inc
+ 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())
+ if ($a_record['name'] == $a_record['email'][0]) {
+ $a_record['name'] = '';
+ }
+ }
+
// skip invalid (incomplete) entries
if (!$CONTACTS->validate($a_record, true)) {
$IMPORT_STATS->invalid++;
@@ -250,7 +259,7 @@ if (is_array($_FILES['_file'])) {
if ($success) {
$IMPORT_STATS->inserted++;
- $IMPORT_STATS->names[] = $vcard->displayname ? $vcard->displayname : $email;
+ $IMPORT_STATS->names[] = $a_record['name'] ? $a_record['name'] : $email;
}
else {
$IMPORT_STATS->errors++;
diff --git a/program/steps/addressbook/list.inc b/program/steps/addressbook/list.inc
index 1bb28658b..aca58d279 100644
--- a/program/steps/addressbook/list.inc
+++ b/program/steps/addressbook/list.inc
@@ -19,47 +19,20 @@
+-----------------------------------------------------------------------+
*/
-$afields = $RCMAIL->config->get('contactlist_fields');
+if (!empty($_GET['_page']))
+ $page = intval($_GET['_page']);
+else
+ $page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1;
-// Use search result
-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);
- }
+$_SESSION['page'] = $page;
+// Use search result
+if (($records = rcmail_search_update(true)) !== false) {
// 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);
@@ -72,6 +45,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
}
// List selected directory
else {
+ $afields = $RCMAIL->config->get('contactlist_fields');
$CONTACTS = rcmail_contact_source(null, true);
// get contacts for this user
@@ -81,6 +55,11 @@ 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/move.inc b/program/steps/addressbook/move.inc
new file mode 100644
index 000000000..f8204e9ee
--- /dev/null
+++ b/program/steps/addressbook/move.inc
@@ -0,0 +1,208 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/addressbook/move.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2007-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: |
+ | Move a contact record from one direcotry to another |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+// only process ajax requests
+if (!$OUTPUT->ajax_call) {
+ return;
+}
+
+$cids = rcmail_get_cids();
+$target = get_input_value('_to', RCUBE_INPUT_POST);
+$target_group = get_input_value('_togid', RCUBE_INPUT_POST);
+
+$all = 0;
+$deleted = 0;
+$success = 0;
+$errormsg = 'moveerror';
+$maxnum = $RCMAIL->config->get('max_group_members', 0);
+$page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1;
+
+foreach ($cids as $source => $source_cids) {
+ // Something wrong, target not specified
+ if (!strlen($target)) {
+ break;
+ }
+
+ // It maight happen when moving records from search result
+ // Do nothing, go to next source
+ if ((string)$target === (string)$source) {
+ continue;
+ }
+
+ $CONTACTS = $RCMAIL->get_address_book($source);
+ $TARGET = $RCMAIL->get_address_book($target);
+
+ if (!$TARGET || !$TARGET->ready || $TARGET->readonly) {
+ break;
+ }
+
+ if (!$CONTACTS || !$CONTACTS->ready || $CONTACTS->readonly) {
+ continue;
+ }
+
+ $ids = array();
+
+ foreach ($source_cids as $idx => $cid) {
+ $a_record = $CONTACTS->get_record($cid, true);
+
+ // avoid moving groups
+ if ($a_record['_type'] == 'group') {
+ unset($source_cids[$idx]);
+ 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);
+ else if (!empty($a_record['name']))
+ $result = $TARGET->search('name', $a_record['name'], 1, true, true);
+ else
+ $result = new rcube_result_set();
+
+ // insert contact record
+ if (!$result->count) {
+ $plugin = $RCMAIL->plugins->exec_hook('contact_create', array(
+ 'record' => $a_record, 'source' => $target, 'group' => $target_group));
+
+ if (!$plugin['abort']) {
+ if ($insert_id = $TARGET->insert($plugin['record'], false)) {
+ $ids[] = $insert_id;
+ $success++;
+ }
+ }
+ else if ($plugin['result']) {
+ $ids = array_merge($ids, $plugin['result']);
+ $success++;
+ }
+ }
+ else {
+ $record = $result->first();
+ $ids[] = $record['ID'];
+ $errormsg = empty($a_record['email']) ? 'contactnameexists' : 'contactexists';
+ }
+ }
+
+ // remove source contacts
+ if ($success && !empty($source_cids)) {
+ $all += count($source_cids);
+ $plugin = $RCMAIL->plugins->exec_hook('contact_delete', array(
+ 'id' => $source_cids, 'source' => $source));
+
+ $del_status = !$plugin['abort'] ? $CONTACTS->delete($source_cids) : $plugin['result'];
+
+ if ($del_status) {
+ $deleted += $del_status;
+ }
+ }
+
+ // assign to group
+ if ($target_group && $TARGET->groups && !empty($ids)) {
+ $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array(
+ 'group_id' => $target_group, 'ids' => $ids, 'source' => $target));
+
+ if (!$plugin['abort']) {
+ $TARGET->reset();
+ $TARGET->set_group($target_group);
+
+ if ($maxnum && ($TARGET->count()->count + count($plugin['ids']) > $maxnum)) {
+ $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum));
+ $OUTPUT->send();
+ }
+
+ if (($cnt = $TARGET->add_to_group($target_group, $plugin['ids'])) && $cnt > $success)
+ $success = $cnt;
+ }
+ else if ($plugin['result']) {
+ $success = $plugin['result'];
+ }
+
+ $errormsg = $plugin['message'] ? $plugin['message'] : 'moveerror';
+ }
+}
+
+if (!$deleted || $deleted != $all) {
+ // update saved search after data changed
+ if ($deleted) {
+ rcmail_search_update();
+ }
+ $OUTPUT->command('list_contacts');
+}
+else {
+ // update saved search after data changed
+ if (($records = rcmail_search_update(true)) !== false) {
+ // 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
+ if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
+ // sort the records
+ ksort($records, SORT_LOCALE_STRING);
+
+ $first += $PAGE_SIZE;
+ // create resultset object
+ $res = new rcube_result_set($count, $first - $deleted);
+
+ if ($PAGE_SIZE < $count) {
+ $records = array_slice($records, $first - $deleted, $deleted);
+ }
+
+ $res->records = array_values($records);
+ $records = $res;
+ }
+ else {
+ unset($records);
+ }
+ }
+ else {
+ // count contacts for this user
+ $result = $CONTACTS->count();
+ // get records from the next page to add to the list
+ $pages = ceil(($result->count + $deleted) / $PAGE_SIZE);
+
+ if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
+ $CONTACTS->set_page($page);
+ $records = $CONTACTS->list_records(null, -$deleted);
+ }
+ }
+
+ // update message count display
+ $OUTPUT->set_env('pagecount', ceil($result->count / $PAGE_SIZE));
+ $OUTPUT->command('set_rowcount', rcmail_get_rowcount_text($result));
+
+ // add new rows from next page (if any)
+ if (!empty($records)) {
+ rcmail_js_contacts_list($records);
+ }
+}
+
+if (!$success)
+ $OUTPUT->show_message($errormsg, 'error');
+else
+ $OUTPUT->show_message('movesuccess', 'notice', array('nr' => $success));
+
+// send response
+$OUTPUT->send();
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 8cab6e817..e7e5efc63 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -134,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', 'email') as $col)
+ foreach (array('name') 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);
+ $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record);
// show confirmation
$OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
@@ -192,7 +192,7 @@ else {
if (($maxnum = $RCMAIL->config->get('max_group_members', 0)) && ($counts->count + 1 > $maxnum))
$OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum));
- $CONTACTS->add_to_group($gid, $plugin['ids']);
+ $CONTACTS->add_to_group($plugin['group_id'], $plugin['ids']);
}
}
else
diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc
index 16be89f94..950764bb1 100644
--- a/program/steps/addressbook/show.inc
+++ b/program/steps/addressbook/show.inc
@@ -101,8 +101,6 @@ function rcmail_contact_head($attrib)
return false;
}
- $microformats = array('name' => 'fn', 'email' => 'email');
-
$form = array(
'head' => array( // section 'head' is magic!
'content' => array(
@@ -177,7 +175,7 @@ function rcmail_contact_details($attrib)
}
-function rcmail_render_email_value($email, $col)
+function rcmail_render_email_value($email)
{
return html::a(array(
'href' => 'mailto:' . $email,
@@ -188,7 +186,7 @@ function rcmail_render_email_value($email, $col)
}
-function rcmail_render_url_value($url, $col)
+function rcmail_render_url_value($url)
{
$prefix = preg_match('!^(http|ftp)s?://!', $url) ? '' : 'http://';
return html::a(array(
@@ -209,9 +207,8 @@ function rcmail_contact_record_groups($contact_id)
return '';
}
- $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
-
- $members = $CONTACTS->get_record_groups($contact_id);
+ $members = $CONTACTS->get_record_groups($contact_id);
+ $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
$checkbox = new html_checkbox(array('name' => '_gid[]',
'class' => 'groupmember', 'disabled' => $CONTACTS->readonly));
@@ -223,7 +220,7 @@ function rcmail_contact_record_groups($contact_id)
}
$hiddenfields = new html_hiddenfield(array('name' => '_source', 'value' => get_input_value('_source', RCUBE_INPUT_GPC)));
- $hiddenfields->add(array('name' => '_cid', 'value' => $record['ID']));
+ $hiddenfields->add(array('name' => '_cid', 'value' => $contact_id));
$form_start = $RCMAIL->output->request_form(array(
'name' => "form", 'method' => "post",
diff --git a/program/steps/addressbook/undo.inc b/program/steps/addressbook/undo.inc
index 9c171143c..c23bd1cb6 100644
--- a/program/steps/addressbook/undo.inc
+++ b/program/steps/addressbook/undo.inc
@@ -46,30 +46,7 @@ foreach ((array)$undo['data'] as $source => $cid)
}
// update saved search after data changed
-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_search_update();
$RCMAIL->session->remove('contact_undo');
diff --git a/program/steps/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc
index 55579814c..f9e8d71a4 100644
--- a/program/steps/mail/autocomplete.inc
+++ b/program/steps/mail/autocomplete.inc
@@ -102,7 +102,7 @@ if (!empty($book_types) && strlen($search)) {
// also list matching contact groups
if ($abook->groups && count($contacts) < $MAXNUM) {
- foreach ($abook->list_groups($search) as $group) {
+ foreach ($abook->list_groups($search, $mode) as $group) {
$abook->reset();
$abook->set_group($group['ID']);
$group_prop = $abook->get_group($group['ID']);
diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc
index 3649d148c..8c0b1ffc0 100644
--- a/program/steps/mail/check_recent.inc
+++ b/program/steps/mail/check_recent.inc
@@ -81,9 +81,10 @@ 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
+ // get overall message count; allow caching because rcube_storage::folder_status()
+ // did a refresh but only in list mode
$list_mode = $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL';
- $all_count = $RCMAIL->storage->count($mbox_name, $list_mode, false, false);
+ $all_count = $RCMAIL->storage->count($mbox_name, $list_mode, $list_mode == 'THREADS', 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 c166eb74e..9ffde8a57 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -139,12 +139,11 @@ if (!empty($CONFIG['drafts_mbox'])) {
}
// set current mailbox in client environment
$OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder());
-$OUTPUT->set_env('sig_above', $RCMAIL->config->get('sig_above', false));
$OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0);
$OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ',')));
// default font for HTML editor
-$font = rcube_fontdefs($RCMAIL->config->get('default_font', 'Verdana'));
+$font = rcube_fontdefs($RCMAIL->config->get('default_font'));
if ($font && !is_array($font)) {
$OUTPUT->set_env('default_font', $font);
}
@@ -152,6 +151,7 @@ if ($font && !is_array($font)) {
// get reference message and set compose mode
if ($msg_uid = $COMPOSE['param']['draft_uid']) {
$compose_mode = RCUBE_COMPOSE_DRAFT;
+ $OUTPUT->set_env('draft_id', $msg_uid);
$RCMAIL->storage->set_folder($CONFIG['drafts_mbox']);
}
else if ($msg_uid = $COMPOSE['param']['reply_uid']) {
@@ -170,6 +170,9 @@ $OUTPUT->set_env('compose_mode', $compose_mode);
$config_show_sig = $RCMAIL->config->get('show_sig', 1);
if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) {
// don't add signature in draft/edit mode, we'll also not remove the old-one
+ // but only on page display, later we should be able to change identity/sig (#1489229)
+ if ($config_show_sig == 1 || $config_show_sig == 2)
+ $OUTPUT->set_env('show_sig_later', true);
}
else if ($config_show_sig == 1)
$OUTPUT->set_env('show_sig', true);
@@ -219,10 +222,10 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment']))
$COMPOSE['param']['sent_mbox'] = $sent_folder;
}
}
- else if ($compose_mode == RCUBE_COMPOSE_DRAFT) {
- if ($MESSAGE->headers->others['x-draft-info']) {
+ else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) {
+ if ($compose_mode == RCUBE_COMPOSE_DRAFT && ($draft_info = $MESSAGE->headers->get('x-draft-info'))) {
// get reply_uid/forward_uid to flag the original message when sending
- $info = rcmail_draftinfo_decode($MESSAGE->headers->others['x-draft-info']);
+ $info = rcmail_draftinfo_decode($draft_info);
if ($info['type'] == 'reply')
$COMPOSE['reply_uid'] = $info['uid'];
@@ -239,10 +242,10 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment']))
}
}
- if ($MESSAGE->headers->in_reply_to)
- $COMPOSE['reply_msgid'] = '<'.$MESSAGE->headers->in_reply_to.'>';
+ if ($in_reply_to = $MESSAGE->headers->get('in-reply-to'))
+ $COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>';
- $COMPOSE['references'] = $MESSAGE->headers->references;
+ $COMPOSE['references'] = $MESSAGE->headers->references;
}
}
else {
@@ -327,6 +330,20 @@ foreach ($parts as $header) {
$fvalue .= $v;
if ($v = $MESSAGE->headers->cc)
$fvalue .= (!empty($fvalue) ? $separator : '') . $v;
+ // Use Sender header (#1489011)
+ if (($v = $MESSAGE->headers->get('Sender', false)) && strpos($v, '-bounces@') === false)
+ $fvalue .= (!empty($fvalue) ? $separator : '') . $v;
+
+ // When To: and Reply-To: are the same we add From: address to the list (#1489037)
+ if ($v = $MESSAGE->headers->from) {
+ $from = rcube_mime::decode_address_list($v, null, false, $MESSAGE->headers->charset, true);
+ $to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, false, $MESSAGE->headers->charset, true);
+ $replyto = rcube_mime::decode_address_list($MESSAGE->headers->replyto, null, false, $MESSAGE->headers->charset, true);
+
+ if (count($replyto) && !count(array_diff($to, $replyto)) && count(array_diff($from, $to))) {
+ $fvalue .= (!empty($fvalue) ? $separator : '') . $v;
+ }
+ }
}
}
else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) {
@@ -386,7 +403,7 @@ function rcmail_compose_headers($attrib)
{
global $MESSAGE;
- list($form_start, $form_end) = get_form_tags($attrib);
+ list($form_start,) = get_form_tags($attrib);
$out = '';
$part = strtolower($attrib['part']);
@@ -450,7 +467,7 @@ function rcmail_compose_headers($attrib)
function rcmail_compose_header_from($attrib)
{
- global $MESSAGE, $OUTPUT, $RCMAIL, $compose_mode;
+ global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode;
// pass the following attributes to the form class
$field_attrib = array('name' => '_from');
@@ -461,7 +478,8 @@ function rcmail_compose_header_from($attrib)
if (count($MESSAGE->identities))
{
$a_signatures = array();
- $separator = $RCMAIL->config->get('sig_above')
+ $identities = array();
+ $separator = intval($RCMAIL->config->get('reply_mode')) > 0
&& ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- ';
$field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)";
@@ -498,12 +516,21 @@ 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']);
+ $out = $select_from->show((int)$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 {
@@ -553,7 +580,7 @@ function rcmail_message_is_html()
function rcmail_prepare_message_body()
{
- global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $LINE_LENGTH, $HTML_MODE;
+ global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE;
// use posted message body
if (!empty($_POST['_message'])) {
@@ -571,16 +598,33 @@ function rcmail_prepare_message_body()
rcmail_write_forward_attachments();
}
// reply/edit/draft/forward
- else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || $RCMAIL->config->get('reply_mode') != -1)) {
- $isHtml = rcmail_compose_editor_mode();
+ else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || intval($RCMAIL->config->get('reply_mode')) != -1)) {
+ $isHtml = rcmail_compose_editor_mode();
+ $messages = array();
if (!empty($MESSAGE->parts)) {
+ // collect IDs of message/rfc822 parts
+ if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) {
+ foreach ($MESSAGE->attachments as $part) {
+ if ($part->mimetype == 'message/rfc822') {
+ $messages[] = $part->mime_id;
+ }
+ }
+ }
+
foreach ($MESSAGE->parts as $part) {
// skip no-content and attachment parts (#1488557)
if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) {
continue;
}
+ // skip all content parts inside the message/rfc822 part in DRAFT/EDIT mode
+ foreach ($messages as $mimeid) {
+ if (strpos($part->mime_id, $mimeid . '.') === 0) {
+ continue 2;
+ }
+ }
+
if ($part_body = rcmail_compose_part_body($part, $isHtml)) {
$body .= ($body ? ($isHtml ? '<br/>' : "\n") : '') . $part_body;
}
@@ -626,7 +670,7 @@ function rcmail_prepare_message_body()
function rcmail_compose_part_body($part, $isHtml = false)
{
- global $RCMAIL, $MESSAGE, $compose_mode;
+ global $RCMAIL, $MESSAGE, $LINE_LENGTH, $compose_mode;
// Check if we have enough memory to handle the message in it
// #1487424: we need up to 10x more memory than the body
@@ -663,6 +707,11 @@ 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) {
@@ -702,7 +751,7 @@ function rcmail_compose_part_body($part, $isHtml = false)
function rcmail_compose_body($attrib)
{
- global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $LINE_LENGTH, $HTML_MODE, $MESSAGE_BODY;
+ global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $HTML_MODE, $MESSAGE_BODY;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
@@ -886,8 +935,7 @@ 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'));
- $charset = $RCMAIL->output->get_charset();
+ $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long'));
if (!$bodyIsHtml) {
$prefix = "\n\n\n-------- " . rcube_label('originalmessage') . " --------\n";
@@ -941,7 +989,7 @@ function rcmail_create_forward_body($body, $bodyIsHtml)
function rcmail_create_draft_body($body, $bodyIsHtml)
{
- global $MESSAGE, $OUTPUT, $COMPOSE;
+ global $MESSAGE, $COMPOSE;
/**
* add attachments
@@ -989,39 +1037,50 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
global $RCMAIL, $COMPOSE, $compose_mode;
$loaded_attachments = array();
- foreach ((array)$COMPOSE['attachments'] as $id => $attachment) {
+ foreach ((array)$COMPOSE['attachments'] as $attachment) {
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
}
- $cid_map = $messages = array();
+ $cid_map = array();
+ $messages = array();
+
foreach ((array)$message->mime_parts as $pid => $part)
{
if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) {
- if (($part->ctype_primary == 'message' && $bodyIsHtml) || $part->ctype_primary == 'multipart') {
+ // skip parts that aren't valid attachments
+ if ($part->ctype_primary == 'multipart' || $part->mimetype == 'application/ms-tnef') {
continue;
}
- if ($part->mimetype == 'application/ms-tnef') {
+ // skip message attachments in reply mode
+ if ($part->ctype_primary == 'message' && $compose_mode == RCUBE_COMPOSE_REPLY) {
continue;
}
- // skip inline images when forwarding in plain text
- if ($part->content_id && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) {
+ // skip inline images when forwarding in text mode
+ if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) {
continue;
}
- $skip = false;
+ // skip message/rfc822 attachments on forwards (#1489214)
+ // Thunderbird when forwarding in inline mode displays such attachments
+ // and skips any attachments from inside of such part, this however
+ // skipped e.g. images used in HTML body or other attachments. So,
+ // better to skip .eml attachments but not their content (included files).
if ($part->mimetype == 'message/rfc822') {
+ if ($compose_mode == RCUBE_COMPOSE_FORWARD) {
+ continue;
+ }
$messages[] = $part->mime_id;
- } else if ($messages) {
+ }
+ else if ($compose_mode != RCUBE_COMPOSE_FORWARD) {
// skip attachments included in message/rfc822 attachment (#1486487)
foreach ($messages as $mimeid)
- if (strpos($part->mime_id, $mimeid.'.') === 0) {
- $skip = true;
- break;
+ if (strpos($part->mime_id, $mimeid . '.') === 0) {
+ continue 2;
}
}
- if (!$skip && (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype])
- || ($attachment = rcmail_save_attachment($message, $pid)))) {
+ if (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype])
+ || ($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',
@@ -1074,7 +1133,7 @@ function rcmail_write_forward_attachments()
$names = array();
$loaded_attachments = array();
- foreach ((array)$COMPOSE['attachments'] as $id => $attachment) {
+ foreach ((array)$COMPOSE['attachments'] as $attachment) {
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
}
@@ -1209,10 +1268,11 @@ function rcmail_save_image($path, $mimetype='')
// handle attachments in memory
$data = file_get_contents($path);
+ $name = rcmail_basename($path);
$attachment = array(
'group' => $COMPOSE['id'],
- 'name' => rcmail_basename($path),
+ 'name' => $name,
'mimetype' => $mimetype ? $mimetype : rc_mime_content_type($path, $name),
'data' => $data,
'size' => strlen($data),
@@ -1482,7 +1542,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;
@@ -1490,6 +1550,7 @@ function rcmail_editor_selector($attrib)
}
return $selector;
+*/
}
diff --git a/program/steps/mail/copy.inc b/program/steps/mail/copy.inc
index a72378b0e..876657485 100644
--- a/program/steps/mail/copy.inc
+++ b/program/steps/mail/copy.inc
@@ -24,10 +24,10 @@ if (!$OUTPUT->ajax_call)
return;
// move messages
-if (!empty($_POST['_uid']) && !empty($_POST['_target_mbox'])) {
- $uids = get_input_value('_uid', RCUBE_INPUT_POST);
+if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
+ $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);
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true);
$copied = $RCMAIL->storage->copy_message($uids, $target, $mbox);
@@ -47,7 +47,7 @@ if (!empty($_POST['_uid']) && !empty($_POST['_target_mbox'])) {
}
// unknown action or missing query param
else {
- exit;
+ $OUTPUT->show_message('internalerror', 'error');
}
// send response
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index da01e6cbf..ae23d4a6d 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -120,7 +120,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
if (!$OUTPUT->ajax_call)
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
- 'copy', 'move', 'quota');
+ 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait');
$pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
$pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
@@ -128,6 +128,40 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
$OUTPUT->set_pagetitle($pagetitle);
}
+// 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'.
@@ -224,7 +258,7 @@ function rcmail_message_list($attrib)
if (!in_array('threads', $a_show_cols))
array_unshift($a_show_cols, 'threads');
- $skin_path = $_SESSION['skin_path'] = $CONFIG['skin_path'];
+ $_SESSION['skin_path'] = $CONFIG['skin_path'];
// set client env
$OUTPUT->add_gui_object('messagelist', $attrib['id']);
@@ -236,15 +270,13 @@ function rcmail_message_list($attrib)
$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']);
+ $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']);
+ }
- 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 $table->show();
}
@@ -291,7 +323,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 (($f = array_search('fromto', $a_show_cols)) !== false) {
+ if (array_search('fromto', $a_show_cols) !== false) {
$smart_col = rcmail_message_list_smart_column_name();
}
@@ -307,7 +339,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
}
// loop through message headers
- foreach ($a_headers as $n => $header) {
+ foreach ($a_headers as $header) {
if (empty($header))
continue;
@@ -381,7 +413,6 @@ 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'];
@@ -417,7 +448,7 @@ function rcmail_message_list_head($attrib, $a_show_cols)
$cells = array();
// get name of smart From/To column in folder context
- if (($f = array_search('fromto', $a_show_cols)) !== false) {
+ if (array_search('fromto', $a_show_cols) !== false) {
$smart_col = rcmail_message_list_smart_column_name();
}
@@ -738,8 +769,13 @@ function rcmail_print_body($part, $p = array())
unset($data['body']);
// plaintext postprocessing
- if ($part->ctype_secondary == 'plain')
- $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed');
+ 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);
+ }
// allow post-processing of the message body
$data = $RCMAIL->plugins->exec_hook('message_part_after',
@@ -753,11 +789,10 @@ 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, $flowed=false)
+function rcmail_plain_body($body)
{
global $RCMAIL;
@@ -782,53 +817,17 @@ function rcmail_plain_body($body, $flowed=false)
if ($q > $quote_level) {
$body[$n] = $replacer->get_replacement($replacer->add(
str_repeat('<blockquote>', $q - $quote_level))) . $body[$n];
+ $last = $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;
- }
+ $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)
+ if ($quote_level > 0)
$body[$n] = $replacer->get_replacement($replacer->add(
str_repeat('</blockquote>', $quote_level))) . $body[$n];
}
@@ -898,8 +897,8 @@ function rcmail_washtml_callback($tagname, $attrib, $content, $washtml)
* return table with message headers
*/
function rcmail_message_headers($attrib, $headers=null)
- {
- global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
+{
+ global $MESSAGE, $PRINT_MODE, $RCMAIL;
static $sa_attrib;
// keep header table attrib
@@ -937,7 +936,7 @@ function rcmail_message_headers($attrib, $headers=null)
$value = $headers[$hkey];
else if ($headers['others'][$hkey])
$value = $headers['others'][$hkey];
- else
+ else if (!$attrib['valueof'])
continue;
if (in_array($hkey, $exclude_headers))
@@ -1084,7 +1083,7 @@ function rcmail_message_body($attrib)
$header_attrib[$regs[1]] = $value;
if (!empty($MESSAGE->parts)) {
- foreach ($MESSAGE->parts as $i => $part) {
+ foreach ($MESSAGE->parts as $part) {
if ($part->type == 'headers') {
$out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
}
@@ -1196,7 +1195,7 @@ function rcmail_message_body($attrib)
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',
+ 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image') . '&_thumb=1',
'title' => $attach_prop->filename,
'alt' => $attach_prop->filename,
'style' => sprintf('max-width:%dpx; max-height:%dpx', $thumbnail_size, $thumbnail_size),
@@ -1216,7 +1215,7 @@ function rcmail_message_body($attrib)
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),
+ 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image'),
'title' => $attach_prop->filename,
'alt' => $attach_prop->filename,
)))
@@ -1442,7 +1441,8 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
$c = count($a_parts);
$j = 0;
$out = '';
- $allvalues = array();
+ $allvalues = array();
+ $show_email = $RCMAIL->config->get('message_show_email');
if ($addicon && !isset($_SESSION['writeable_abook'])) {
$_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false;
@@ -1453,9 +1453,10 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
$name = $part['name'];
$mailto = $part['mailto'];
$string = $part['string'];
+ $valid = check_email($mailto, false);
// phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>"
- if ($name && $name != $mailto && strpos($name, '@')) {
+ if (!$show_email && $valid && $name && $name != $mailto && strpos($name, '@')) {
$name = '';
}
@@ -1471,15 +1472,23 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
// for printing we display all addresses
continue;
}
- else if (check_email($part['mailto'], false)) {
+ else if ($valid) {
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));
+ $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);
}
else {
$address = html::span(array('title' => $mailto, 'class' => "rcmContactAddress"),
@@ -1504,7 +1513,7 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
if ($name)
$address .= Q($name);
if ($mailto)
- $address .= (strlen($address) ? ' ' : '') . sprintf('&lt;%s&gt;', Q($mailto));
+ $address = trim($address . ' ' . Q($name ? sprintf('<%s>', $mailto) : $mailto));
}
$address = html::span('adr', $address);
@@ -1543,11 +1552,11 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
/**
* 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
+ * Finally add another quotation level by prepending the lines
* with >
*
* @param string Text to wrap
- * @param int The line width
+ * @param int The line width
* @return string The wrapped text
*/
function rcmail_wrap_and_quote($text, $length = 72)
@@ -1563,7 +1572,7 @@ function rcmail_wrap_and_quote($text, $length = 72)
$line = '>' . rtrim($line);
else if (mb_strlen($line) > $max) {
$newline = '';
- foreach(explode("\n", rc_wordwrap($line, $length - 2)) as $l) {
+ foreach (explode("\n", rc_wordwrap($line, $length - 2)) as $l) {
if (strlen($l))
$newline .= '> ' . $l . "\n";
else
@@ -1606,45 +1615,6 @@ 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
*/
@@ -1732,8 +1702,7 @@ 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;
}
@@ -1814,9 +1783,12 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
// 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;
+ $ident = str_replace('@', '=', $ident['email_ascii']) . '@';
+ foreach ((array)$return_path as $path) {
+ if (strpos($path, $ident) !== false) {
+ $from_idx = $idx;
+ break 2;
+ }
}
}
}
@@ -1851,8 +1823,7 @@ function rcmail_fix_mimetype($name)
// application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608
if (preg_match('/^application\/pdf.+/', $name))
$name = 'application/pdf';
-
- // treat image/pjpeg as image/jpeg
+ // treat image/pjpeg (image/pjpg, image/jpg) as image/jpeg (#1489097)
else if (preg_match('/^image\/p?jpe?g$/', $name))
$name = 'image/jpeg';
@@ -1899,13 +1870,15 @@ function rcmail_search_filter($attrib)
$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
- */
+ // 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);
+ }
$select_filter = new html_select($attrib);
$select_filter->add(rcube_label('all'), 'ALL');
@@ -1916,6 +1889,7 @@ 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');
@@ -1945,35 +1919,37 @@ function rcmail_message_error($uid=null)
$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'),
-));
+function rcmail_message_import_form($attrib = array())
+{
+ global $OUTPUT;
-// 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',
-));
+ // 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[]',
+ 'size' => $attrib['attachmentfieldsize'],
+ '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)"))
+ ) : '')
+ )
+ );
+
+ $OUTPUT->add_gui_object('importform', $attrib['id'].'Frm');
+ return $out;
+}
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index 23dc22b7c..a27e788a3 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -22,7 +22,7 @@
// show loading page
if (!empty($_GET['_preload'])) {
- $url = preg_replace('/([&?]+)_preload=/', '\\1_embed=', $_SERVER['REQUEST_URI']);
+ $url = preg_replace('/([&?]+)_preload=/', '\\1_mimewarning=1&_embed=', $_SERVER['REQUEST_URI']);
$message = rcube_label('loadingdata');
header('Content-Type: text/html; charset=' . RCMAIL_CHARSET);
@@ -38,19 +38,34 @@ 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(get_input_value('_uid', RCUBE_INPUT_GET));
+ $MESSAGE = new rcube_message($uid);
}
// 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 = get_input_value('_part', RCUBE_INPUT_GPC)) && ($part = $MESSAGE->mime_parts[$part_id])) {
- $OUTPUT->set_pagetitle(rcmail_attachment_name($part));
+ if ($part_id && ($part = $MESSAGE->mime_parts[$part_id])) {
+ $filename = rcmail_attachment_name($part);
+ $OUTPUT->set_pagetitle($filename);
}
+ // 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;
}
@@ -62,9 +77,10 @@ else if ($_GET['_thumb']) {
$thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240);
$temp_dir = $RCMAIL->config->get('temp_dir');
list(,$ext) = explode('/', $part->mimetype);
- $cache_basename = $temp_dir . '/' . md5($MESSAGE->headers->messageID . $part->mime_id . ':' . $RCMAIL->user->ID . ':' . $thumbnail_size);
- $cache_file = $cache_basename . '.' . $ext;
$mimetype = $part->mimetype;
+ $file_ident = $MESSAGE->headers->messageID . ':' . $part->mime_id . ':' . $part->size . ':' . $part->mimetype;
+ $cache_basename = $temp_dir . '/' . md5($file_ident . ':' . $RCMAIL->user->ID . ':' . $thumbnail_size);
+ $cache_file = $cache_basename . '.' . $ext;
// render thumbnail image if not done yet
if (!is_file($cache_file)) {
@@ -91,12 +107,9 @@ else if ($_GET['_thumb']) {
exit;
}
-else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
-
- if ($part = $MESSAGE->mime_parts[$pid]) {
- $ctype_primary = strtolower($part->ctype_primary);
- $ctype_secondary = strtolower($part->ctype_secondary);
- $mimetype = sprintf('%s/%s', $ctype_primary, $ctype_secondary);
+else if (strlen($part_id)) {
+ if ($part = $MESSAGE->mime_parts[$part_id]) {
+ $mimetype = rcmail_fix_mimetype($part->mimetype);
// allow post-processing of the message body
$plugin = $RCMAIL->plugins->exec_hook('message_part_get',
@@ -106,7 +119,7 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
exit;
// overwrite modified vars from plugin
- $mimetype = $plugin['mimetype'];
+ $mimetype = $plugin['mimetype'];
$extensions = rcube_mime::get_mime_extensions($mimetype);
if ($plugin['body'])
@@ -118,7 +131,7 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
$file_extension = strtolower(pathinfo($part->filename, PATHINFO_EXTENSION));
// 1. compare filename suffix with expected suffix derived from mimetype
- $valid = $file_extension && in_array($file_extension, (array)$extensions);
+ $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' || $mimetype == 'text/plain') {
@@ -145,6 +158,10 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
$extensions = rcube_mime::get_mime_extensions($real_mimetype);
$valid_extension = (!$file_extension || in_array($file_extension, (array)$extensions));
+ // ignore filename extension if mimeclass matches (#1489029)
+ if (!empty($_REQUEST['_mimeclass']) && $real_ctype_primary == $_REQUEST['_mimeclass'])
+ $valid_extension = true;
+
// fix mimetype for images wrongly declared as octet-stream
if ($mimetype == 'application/octet-stream' && strpos($real_mimetype, 'image/') === 0 && $valid_extension)
$mimetype = $real_mimetype;
@@ -157,22 +174,32 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
// show warning if validity checks failed
if (!$valid) {
- $OUTPUT = new rcmail_html_page();
- $OUTPUT->write(html::tag('html', null, html::tag('body', 'embed',
- html::div(array('class' => 'rcmail-inline-message rcmail-inline-warning'),
- rcube_label(array(
- 'name' => 'attachmentvalidationerror',
- 'vars' => array(
- 'expected' => $mimetype . ($file_extension ? "(.$file_extension)" : ''),
- 'detected' => $real_mimetype . ($extensions[0] ? "(.$extensions[0])" : ''),
+ // send blocked.gif for expected images
+ if (empty($_REQUEST['_mimewarning']) && strpos($mimetype, 'image/') === 0) {
+ // Do not cache. Failure might be the result of a misconfiguration, thus real content should be returned once fixed.
+ $OUTPUT->nocacheing_headers();
+ header("Content-Type: image/gif");
+ header("Content-Transfer-Encoding: binary");
+ readfile(INSTALL_PATH . 'program/resources/blocked.gif');
+ }
+ else { // html warning with a button to load the file anyway
+ $OUTPUT = new rcmail_html_page();
+ $OUTPUT->write(html::tag('html', null, html::tag('body', 'embed',
+ html::div(array('class' => 'rcmail-inline-message rcmail-inline-warning'),
+ rcube_label(array(
+ 'name' => 'attachmentvalidationerror',
+ 'vars' => array(
+ 'expected' => $mimetype . ($file_extension ? "(.$file_extension)" : ''),
+ 'detected' => $real_mimetype . ($extensions[0] ? "(.$extensions[0])" : ''),
+ )
+ )) .
+ html::p(array('class' => 'rcmail-inline-buttons'),
+ html::tag('button',
+ array('onclick' => "location.href='" . $RCMAIL->url(array_merge($_GET, array('_nocheck' => 1))) . "'"),
+ rcube_label('showanyway')))
)
- )) .
- html::p(array('class' => 'rcmail-inline-buttons'),
- html::tag('button',
- array('onclick' => "location.href='" . $RCMAIL->url(array_merge($_GET, array('_nocheck' => 1))) . "'"),
- rcube_label('showanyway')))
- )
- )));
+ )));
+ }
exit;
}
}
@@ -202,7 +229,6 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
header("Content-Type: text/$ctype_secondary; charset=" . ($part->charset ? $part->charset : RCMAIL_CHARSET));
}
else {
- $mimetype = rcmail_fix_mimetype($mimetype);
header("Content-Type: $mimetype");
header("Content-Transfer-Encoding: binary");
}
@@ -366,7 +392,9 @@ 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();
@@ -398,3 +426,49 @@ 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/import.inc b/program/steps/mail/import.inc
new file mode 100644
index 000000000..f7e7a3eb8
--- /dev/null
+++ b/program/steps/mail/import.inc
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/mail/import.inc |
+ | |
+ | This file is part 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. |
+ | |
+ | PURPOSE: |
+ | Save the uploaded file(s) as messages to the current IMAP folder |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+// clear all stored output properties (like scripts and env vars)
+$OUTPUT->reset();
+
+if (is_array($_FILES['_file'])) {
+ $imported = 0;
+
+ foreach ((array)$_FILES['_file']['tmp_name'] as $i => $filepath) {
+ // Process uploaded file if there is no error
+ $err = $_FILES['_file']['error'][$i];
+
+ if (!$err) {
+ // check file content type first
+ list($mtype_primary,) = explode('/', rc_mime_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i]));
+ if (!in_array($mtype_primary, array('text','message'))) {
+ $OUTPUT->show_message('importmessageerror', 'error');
+ continue;
+ }
+
+ // read the first few lines to detect header-like structure
+ $fp = fopen($filepath, 'r');
+ do { $line = fgets($fp); }
+ while ($line !== false && trim($line) == '');
+
+ if (!preg_match('/^From\s+-/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
+ $OUTPUT->show_message('importmessageerror', 'error');
+ continue;
+ }
+
+ $message = $lastline = '';
+ fseek($fp, 0);
+ while (($line = fgets($fp)) !== false) {
+ // importing mbox file, split by From - lines
+ if (preg_match('/^From\s+-/', $line) && $lastline == '') {
+ if (!empty($message)) {
+ if ($RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
+ else {
+ rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
+ }
+ $message = '';
+ }
+ continue;
+ }
+
+ $message .= $line;
+ $lastline = rtrim($line);
+ }
+
+ if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
+ }
+
+ 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 if ($err) {
+ $OUTPUT->show_message('fileuploaderror', 'error');
+ }
+ } // end foreach
+
+ if ($imported) {
+ $OUTPUT->show_message(rcube_label(array('name' => 'importmessagesuccess', 'nr' => $imported, 'vars' => array('nr' => $imported))), 'confirmation');
+ $OUTPUT->command('command', 'list');
+ }
+ else {
+ $OUTPUT->show_message('importmessageerror', 'error');
+ }
+}
+else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ // if filesize exceeds post_max_size then $_FILES array is empty,
+ // show filesizeerror instead of fileuploaderror
+ if ($maxsize = ini_get('post_max_size'))
+ $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize)))));
+ else
+ $msg = rcube_label('fileuploaderror');
+
+ $OUTPUT->command('display_message', $msg, 'error');
+}
+
+// send html page with JS calls as response
+$OUTPUT->send('iframe');
+
diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc
index 7e3b349cd..dab146431 100644
--- a/program/steps/mail/list_contacts.inc
+++ b/program/steps/mail/list_contacts.inc
@@ -19,10 +19,10 @@
+-----------------------------------------------------------------------+
*/
-$afields = $RCMAIL->config->get('contactlist_fields');
-$sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
-$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
-$page = max(1, intval($_GET['_page']));
+$afields = $RCMAIL->config->get('contactlist_fields');
+$addr_sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
+$list_page = max(1, intval($_GET['_page']));
// Use search result
if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) {
@@ -42,7 +42,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
while ($row = $result->next()) {
$row['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $key = rcube_addressbook::compose_contact_key($row, $addr_sort_col);
$records[$key] = $row;
}
unset($result);
@@ -53,7 +53,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
// create resultset object
$count = count($records);
- $first = ($page-1) * $page_size;
+ $first = ($list_page-1) * $page_size;
$result = new rcube_result_set($count, $first);
// we need only records for current page
@@ -71,10 +71,13 @@ else {
if ($CONTACTS && $CONTACTS->ready) {
// set list properties
$CONTACTS->set_pagesize($page_size);
- $CONTACTS->set_page($page);
+ $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)
- if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
+ else if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
foreach ($CONTACTS->list_groups() as $group) {
$CONTACTS->reset();
$CONTACTS->set_group($group['ID']);
@@ -89,6 +92,19 @@ 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'];
@@ -97,10 +113,12 @@ 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);
}
}
@@ -118,10 +136,13 @@ 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(
- 'contact' => html::span(array('title' => $email), Q($name ? $name : $email) .
+ $keyname => html::span(array('title' => $email), Q($name ? $name : $email) .
($name && count($emails) > 1 ? '&nbsp;' . html::span('email', Q($email)) : '')
- )), 'person');
+ )), $classname);
}
}
}
diff --git a/program/steps/mail/mark.inc b/program/steps/mail/mark.inc
index c220fc5c4..dfc892ea1 100644
--- a/program/steps/mail/mark.inc
+++ b/program/steps/mail/mark.inc
@@ -113,7 +113,7 @@ if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_va
$OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count), $mbox);
if ($threading) {
- $count = get_input_value('_count', RCUBE_INPUT_POST);
+ $count = get_input_value('_count', RCUBE_INPUT_POST);
}
// add new rows from next page (if any)
@@ -125,9 +125,9 @@ if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_va
}
}
}
-
- $OUTPUT->send();
+}
+else {
+ $OUTPUT->show_message('internalerror', 'error');
}
-exit;
-
+$OUTPUT->send();
diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc
index 3fc6ac5a7..f15cd2460 100644
--- a/program/steps/mail/move_del.inc
+++ b/program/steps/mail/move_del.inc
@@ -29,7 +29,7 @@ $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL');
$old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize());
// move messages
-if ($RCMAIL->action == 'moveto' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
+if ($RCMAIL->action == 'move' && !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);
@@ -74,6 +74,8 @@ else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) {
}
// unknown action or missing query param
else {
+ $OUTPUT->show_message('internalerror', 'error');
+ $OUTPUT->send();
exit;
}
@@ -124,7 +126,7 @@ else
rcmail_set_unseen_count($mbox, $unseen_count);
}
- if ($RCMAIL->action == 'moveto' && strlen($target)) {
+ if ($RCMAIL->action == 'move' && strlen($target)) {
rcmail_send_unread_count($target, true);
}
diff --git a/program/steps/mail/search_contacts.inc b/program/steps/mail/search_contacts.inc
index 2e6bb12f8..6a30ad1f5 100644
--- a/program/steps/mail/search_contacts.inc
+++ b/program/steps/mail/search_contacts.inc
@@ -19,16 +19,15 @@
+-----------------------------------------------------------------------+
*/
-$search = get_input_value('_q', RCUBE_INPUT_GPC, true);
-$sources = $RCMAIL->get_address_sources();
-$search_mode = (int) $RCMAIL->config->get('addressbook_search_mode');
-$sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
-$afields = $RCMAIL->config->get('contactlist_fields');
+$search = get_input_value('_q', RCUBE_INPUT_GPC, true);
+$sources = $RCMAIL->get_address_sources();
+$search_mode = (int) $RCMAIL->config->get('addressbook_search_mode');
+$addr_sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+$afields = $RCMAIL->config->get('contactlist_fields');
+$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
+$records = array();
+$search_set = array();
-$page = 1;
-$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
-
-$records = $search_set = array();
foreach ($sources as $s) {
$source = $RCMAIL->get_address_book($s['id']);
$source->set_page(1);
@@ -46,7 +45,7 @@ foreach ($sources as $s) {
while ($row = $result->next()) {
$row['sourceid'] = $s['id'];
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $key = rcube_addressbook::compose_contact_key($row, $addr_sort_col);
$records[$key] = $row;
}
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index eb0ba89c6..cf22a2af9 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -255,6 +255,33 @@ function rcmail_email_input_format($mailto, $count=false, $check=true)
}
+function rcmail_generic_message_footer($isHtml)
+{
+ global $CONFIG;
+
+ if ($isHtml && !empty($CONFIG['generic_message_footer_html'])) {
+ $file = $CONFIG['generic_message_footer_html'];
+ $html_footer = true;
+ }
+ else {
+ $file = $CONFIG['generic_message_footer'];
+ $html_footer = false;
+ }
+
+ if ($file && realpath($file)) {
+ // sanity check
+ if (!preg_match('/\.(php|ini|conf)$/', $file) && strpos($file, '/etc/') === false) {
+ $footer = file_get_contents($file);
+ if ($isHtml && !$html_footer)
+ $footer = '<pre>' . $footer . '</pre>';
+ return $footer;
+ }
+ }
+
+ return false;
+}
+
+
/****** compose message ********/
if (strlen($_POST['_draft_saveid']) > 3)
@@ -364,10 +391,6 @@ 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) {
@@ -385,9 +408,6 @@ 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'];
}
@@ -452,7 +472,7 @@ $isHtml = (bool) get_input_value('_is_html', RCUBE_INPUT_POST);
$message_body = get_input_value('_message', RCUBE_INPUT_POST, TRUE, $message_charset);
if ($isHtml) {
- $font = rcube_fontdefs($RCMAIL->config->get('default_font', 'Verdana'));
+ $font = rcube_fontdefs($RCMAIL->config->get('default_font'));
$bstyle = $font && is_string($font) ? " style='font-family: $font'" : '';
// append doctype and html/body wrappers
@@ -466,7 +486,7 @@ if (!$savedraft) {
$message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body);
// add inline css for blockquotes
- $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%';
+ $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px';
$message_body = preg_replace('/<blockquote>/',
'<blockquote type="cite" style="'.$bstyle.'">', $message_body);
}
@@ -490,19 +510,10 @@ if (!$savedraft) {
}
// generic footer for all messages
- if ($isHtml && !empty($CONFIG['generic_message_footer_html'])) {
- $footer = file_get_contents(realpath($CONFIG['generic_message_footer_html']));
- $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset);
- }
- else if (!empty($CONFIG['generic_message_footer'])) {
- $footer = file_get_contents(realpath($CONFIG['generic_message_footer']));
+ if ($footer = rcmail_generic_message_footer($isHtml)) {
$footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset);
- if ($isHtml)
- $footer = '<pre>'.$footer.'</pre>';
- }
-
- if ($footer)
$message_body .= "\r\n" . $footer;
+ }
}
if ($isHtml) {
@@ -820,6 +831,6 @@ else {
if ($store_folder && !$saved)
$OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'));
else
- $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'));
+ $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'), $store_target);
$OUTPUT->send('iframe');
}
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 552c180f5..59f4d55e1 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -109,14 +109,14 @@ if ($uid) {
$OUTPUT->set_env('skip_deleted', true);
if ($CONFIG['display_next'])
$OUTPUT->set_env('display_next', true);
- if ($MESSAGE->headers->others['list-post'])
+ if ($MESSAGE->headers->get('list-post', false))
$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');
+ 'movingmessage', 'deletingmessage', 'markingmessage', 'replyall', 'replylist');
$prefer_html = $RCMAIL->config->get('prefer_html');
if ($MESSAGE->has_html_part()) {
@@ -228,11 +228,11 @@ function rcmail_remote_objects_msg()
function rcmail_message_buttons()
{
- global $MESSAGE, $RCMAIL, $CONFIG;
+ global $RCMAIL;
$mbox = $RCMAIL->storage->get_folder();
$delim = $RCMAIL->storage->get_hierarchy_delimiter();
- $dbox = $CONFIG['drafts_mbox'];
+ $dbox = $RCMAIL->config->get('drafts_mbox');
// the message is not a draft
if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) {
@@ -275,9 +275,13 @@ function rcmail_contact_exists($email)
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;
+
+ if (is_object($CONTACTS)) {
+ $existing = $CONTACTS->search('email', $email, true, false);
+ if ($existing->count) {
+ return true;
+ }
+ }
}
return false;
diff --git a/program/steps/settings/about.inc b/program/steps/settings/about.inc
index 9b13402f1..0fdefddda 100644
--- a/program/steps/settings/about.inc
+++ b/program/steps/settings/about.inc
@@ -40,17 +40,28 @@ function rcmail_plugins_list($attrib)
$attrib['id'] = 'rcmpluginlist';
$plugins = array_filter((array) $RCMAIL->config->get('plugins'));
- $plugins = array_flip($plugins);
+ $plugin_info = array();
- foreach ($plugins as $name => $plugin) {
- rcube_plugin_data($name, $plugins);
+ foreach ($plugins as $name) {
+ if ($info = $RCMAIL->plugins->get_info($name))
+ $plugin_info[$name] = $info;
}
- if (empty($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)) {
return '';
}
- ksort($plugins, SORT_LOCALE_STRING);
+ ksort($plugin_info, SORT_LOCALE_STRING);
$table = new html_table($attrib);
@@ -60,8 +71,8 @@ function rcmail_plugins_list($attrib)
$table->add_header('license', rcube_label('license'));
$table->add_header('source', rcube_label('source'));
- foreach ($plugins as $name => $data) {
- $uri = $data['srcuri'] ? $data['srcuri'] : $data['uri'];
+ foreach ($plugin_info as $name => $data) {
+ $uri = $data['src_uri'] ? $data['src_uri'] : $data['uri'];
if ($uri && stripos($uri, 'http') !== 0) {
$uri = 'http://' . $uri;
}
@@ -78,48 +89,6 @@ 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 cd2372790..fdb38e602 100644
--- a/program/steps/settings/edit_folder.inc
+++ b/program/steps/settings/edit_folder.inc
@@ -78,7 +78,7 @@ function rcmail_folder_form($attrib)
// Location (name)
if ($options['protected']) {
- $foldername = Q(str_replace($delimiter, ' &raquo; ', rcmail_localize_folderpath($mbox_imap)));
+ $foldername = str_replace($delimiter, ' &raquo; ', Q(rcmail_localize_folderpath($mbox_imap)));
}
else if ($options['norename']) {
$foldername = Q($folder);
diff --git a/program/steps/settings/edit_prefs.inc b/program/steps/settings/edit_prefs.inc
index 971ed60b6..468e4994d 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 $idx => $block) {
+ foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $block) {
if (!empty($block['options'])) {
$table = new html_table(array('cols' => 2));
diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc
index 0c7d9063f..6d116e7d2 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,7 +283,6 @@ 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']);
@@ -292,7 +291,8 @@ function rcube_subscription_form($attrib)
$classes[] = 'virtual';
}
- if (!$protected) {
+ // Check \Noselect flag (of existing folder)
+ if (!$protected && in_array($folder['id'], $a_unsubscribed)) {
$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 ($a_threaded as $key => $val) {
+ foreach (array_keys($a_threaded) as $key) {
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 2f726c7e8..dbc9b3ce2 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -19,927 +19,1175 @@
+-----------------------------------------------------------------------+
*/
-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;
-
- $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 = $plugin['list'];
-
- $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();
-
- 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),
- );
- }
-
- // 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']),
- );
- }
+ global $RCMAIL;
- // 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));
+ $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'));
- $blocks['main']['options']['prettydate'] = array(
- 'title' => html::label($field_id, Q(rcube_label('prettydate'))),
- 'content' => $input_prettydate->show($config['prettydate']?1:0),
- );
- }
+ // hook + define list cols
+ $plugin = $RCMAIL->plugins->exec_hook('preferences_sections_list',
+ array('list' => $sections, 'cols' => array('section')));
- if (!isset($no_override['refresh_interval'])) {
- $field_id = 'rcmfd_refresh_interval';
- $select_refresh_interval = new html_select(array('name' => '_refresh_interval', 'id' => $field_id));
+ $sections = $plugin['list'];
+ $config = $RCMAIL->config->all();
+ $no_override = array_flip((array)$RCMAIL->config->get('dont_override'));
- $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);
+ foreach ($sections as $idx => $sect) {
+ if ($current && $sect['id'] != $current) {
+ continue;
}
- }
- $blocks['main']['options']['refresh_interval'] = array(
- 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
- 'content' => $select_refresh_interval->show($config['refresh_interval']/60),
- );
- }
-
- // 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 : ''))
- );
+ $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(
+ '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
+ '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")),
+ );
+ }
+
+ 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")),
+ );
+ }
+
+ 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")),
+ );
+ }
+
+ 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")),
+ );
+ }
+ 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),
+ );
+ }
}
- }
- }
-
- $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),
- );
- }
-
- // 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));
-
- $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));
+ $found = false;
+ $data = $RCMAIL->plugins->exec_hook('preferences_list',
+ array('section' => $sect['id'], 'blocks' => $blocks, 'current' => $current));
- $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));
-
- $blocks['main']['options']['mdn_default'] = array(
- 'title' => html::label($field_id, Q(rcube_label('reqmdn'))),
- 'content' => $input_mdn->show($config['mdn_default']?1:0),
- );
- }
-
- 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,
- 'onchange' => "\$('#rcmfd_sig_above').attr('disabled',this.selectedIndex<2)"));
- $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),
- );
+ // create output
+ foreach ($data['blocks'] as $block) {
+ if (!empty($block['content']) || !empty($block['options'])) {
+ $found = true;
+ break;
+ }
}
- }
- }
- 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 (!$found)
+ unset($sections[$idx]);
+ else
+ $sections[$idx]['blocks'] = $data['blocks'];
}
- if (!isset($no_override['sig_above'])) {
- $field_id = 'rcmfd_sig_above';
- $select_sigabove = new html_select(array('name' => '_sig_above', 'id' => $field_id, 'disabled' => $config['reply_mode'] < 1));
- $select_sigabove->add(rcube_label('belowquote'), 0);
- $select_sigabove->add(rcube_label('abovequote'), 1);
-
- $blocks['sig']['options']['sig_above'] = array(
- 'title' => html::label($field_id, Q(rcube_label('replysignaturepos'))),
- 'content' => $select_sigabove->show($config['sig_above']?1:0),
- );
- }
-
- 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();
- $default_font = $config['default_font'] ? $config['default_font'] : 'Verdana';
-
- $select = '<select name="_default_font" id="'.$field_id.'">';
- foreach ($fonts as $fname => $font)
- $select .= '<option value="'.$fname.'"'
- . ($fname == $default_font ? ' 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']),
- );
- }
-
- // 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']);
+ return array($sections, $plugin['cols']);
}
function rcmail_get_skins()
{
- $path = 'skins';
- $skins = array();
-
- $dir = opendir($path);
+ $path = RCUBE_INSTALL_PATH . 'skins';
+ $skins = array();
+ $dir = opendir($path);
- if (!$dir)
- return false;
+ if (!$dir) {
+ return false;
+ }
- while (($file = readdir($dir)) !== false)
- {
- $filename = $path.'/'.$file;
- if (!preg_match('/^\./', $file) && is_dir($filename) && is_readable($filename))
- $skins[] = $file;
- }
+ while (($file = readdir($dir)) !== false) {
+ $filename = $path.'/'.$file;
+ if (!preg_match('/^\./', $file) && is_dir($filename) && is_readable($filename)) {
+ $skins[] = $file;
+ }
+ }
- closedir($dir);
+ closedir($dir);
- return $skins;
+ return $skins;
}
@@ -989,9 +1237,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/save_prefs.inc b/program/steps/settings/save_prefs.inc
index 5daab0d24..19edb41d4 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -34,6 +34,7 @@ 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'],
);
@@ -60,6 +61,7 @@ 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,
@@ -86,7 +88,6 @@ switch ($CURR_SECTION)
'show_sig' => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 1,
'reply_mode' => isset($_POST['_reply_mode']) ? intval($_POST['_reply_mode']) : 0,
'strip_existing_sig' => isset($_POST['_strip_existing_sig']),
- 'sig_above' => !empty($_POST['_sig_above']) && $_POST['_reply_mode'] > 0,
'default_font' => get_input_value('_default_font', RCUBE_INPUT_POST),
'forward_attachment' => !empty($_POST['_forward_attachment']),
);
@@ -119,6 +120,8 @@ 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),
@@ -158,7 +161,7 @@ switch ($CURR_SECTION)
$a_user_prefs['timezone'] = (string) $a_user_prefs['timezone'];
if (isset($a_user_prefs['refresh_interval']) && !empty($CONFIG['min_refresh_interval'])) {
- if ($a_user_prefs['refresh_interval'] > $CONFIG['min_refresh_interval']) {
+ if ($a_user_prefs['refresh_interval'] < $CONFIG['min_refresh_interval']) {
$a_user_prefs['refresh_interval'] = $CONFIG['min_refresh_interval'];
}
}
diff --git a/program/steps/utils/save_pref.inc b/program/steps/utils/save_pref.inc
index b550ad7ef..7def8733d 100644
--- a/program/steps/utils/save_pref.inc
+++ b/program/steps/utils/save_pref.inc
@@ -21,6 +21,22 @@
$name = get_input_value('_name', RCUBE_INPUT_POST);
$value = get_input_value('_value', RCUBE_INPUT_POST);
+$whitelist = array(
+ 'preview_pane',
+ 'list_cols',
+ 'collapsed_folders',
+ 'collapsed_abooks',
+);
+
+if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs))) {
+ raise_error(array('code' => 500, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => sprintf("Hack attempt detected (user: %s)", $RCMAIL->get_user_name())),
+ true, false);
+
+ $OUTPUT->reset();
+ $OUTPUT->send();
+}
// save preference value
$RCMAIL->user->save_prefs(array($name => $value));
diff --git a/program/steps/utils/spell.inc b/program/steps/utils/spell.inc
index a0dd35d27..38e4ca285 100644
--- a/program/steps/utils/spell.inc
+++ b/program/steps/utils/spell.inc
@@ -42,6 +42,13 @@ else {
$result = $spellchecker->get_xml();
}
+if ($err = $spellchecker->error()) {
+ rcube::raise_error(array('code' => 500, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => sprintf("Spell check engine error: " . $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 861e4ba48..96b41e230 100644
--- a/program/steps/utils/spell_html.inc
+++ b/program/steps/utils/spell_html.inc
@@ -46,6 +46,11 @@ 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;
}