diff options
Diffstat (limited to 'plugins')
62 files changed, 2025 insertions, 222 deletions
diff --git a/plugins/acl/acl.js b/plugins/acl/acl.js index 14634534e..e6a84ff73 100644 --- a/plugins/acl/acl.js +++ b/plugins/acl/acl.js @@ -353,6 +353,7 @@ rcube_webmail.prototype.acl_init_form = function(id) id ? this.gettext('acl.editperms') : this.gettext('acl.newuser'), buttons, { + button_classes: ['mainaction'], modal: true, closeOnEscape: true, close: function(e, ui) { diff --git a/plugins/acl/localization/fr_FR.inc b/plugins/acl/localization/fr_FR.inc index ba0f1015d..b011fff3d 100644 --- a/plugins/acl/localization/fr_FR.inc +++ b/plugins/acl/localization/fr_FR.inc @@ -26,19 +26,19 @@ $labels['anyone'] = 'Tous les utilisateurs (n\'importe qui)'; $labels['anonymous'] = 'Invités (anonyme)'; $labels['identifier'] = 'Identifiant'; $labels['acll'] = 'Consultation'; -$labels['aclr'] = 'Lire les messages'; +$labels['aclr'] = 'Lire les courriels'; $labels['acls'] = 'Garder l\'état « vu »'; $labels['aclw'] = 'Drapeaux d\'écriture'; $labels['acli'] = 'Insérer (copier dans)'; $labels['aclp'] = 'Publier'; $labels['aclc'] = 'Créer des sous-dossiers'; $labels['aclk'] = 'Créer des sous-dossiers'; -$labels['acld'] = 'Supprimer des messages'; -$labels['aclt'] = 'Supprimer des messages'; +$labels['acld'] = 'Supprimer des courriels'; +$labels['aclt'] = 'Supprimer des courriels'; $labels['acle'] = 'Purger'; $labels['aclx'] = 'Supprimer un dossier'; $labels['acla'] = 'Administrer'; -$labels['acln'] = 'Annoter les messages'; +$labels['acln'] = 'Annoter les courriels'; $labels['aclfull'] = 'Contrôle total'; $labels['aclother'] = 'Autre'; $labels['aclread'] = 'Lecture'; @@ -64,22 +64,22 @@ $labels['shortaclwrite'] = 'Écriture'; $labels['shortacldelete'] = 'Supprimer'; $labels['longacll'] = 'Ce dossier est visible dans les listes et on peut s\'y abonner'; $labels['longaclr'] = 'Le dossier peut-être ouvert en lecture'; -$labels['longacls'] = 'Le drapeau Vu des messages peut-être changée'; -$labels['longaclw'] = 'Les drapeaux et mot-clefs des messages peuvent-être changés, sauf pour Vu et Supprimé'; -$labels['longacli'] = 'Les messages peuvent-être écrits ou copiés dans le dossier'; -$labels['longaclp'] = 'Les messages peuvent-être publiés dans ce dossier'; +$labels['longacls'] = 'Le drapeau Vu des courriels peut-être changée'; +$labels['longaclw'] = 'Les drapeaux et mot-clefs des courriels peuvent-être changés, sauf pour Vu et Supprimé'; +$labels['longacli'] = 'Les courriels peuvent-être écrits ou copiés dans le dossier'; +$labels['longaclp'] = 'Les courriels peuvent-être publiés dans ce dossier'; $labels['longaclc'] = 'Les dossiers peuvent-être créés (ou renommés) directement depuis ce dossier'; $labels['longaclk'] = 'Les dossiers peuvent-être créés (ou renommés) directement depuis ce dossier'; -$labels['longacld'] = 'Le drapeau de suppression des messages peut-être modifiée'; -$labels['longaclt'] = 'Le drapeau de suppression des messages peut-être modifiée'; -$labels['longacle'] = 'Les messages peuvent-être purgés'; +$labels['longacld'] = 'Le drapeau de suppression des courriels peut-être modifiée'; +$labels['longaclt'] = 'Le drapeau de suppression des courriels peut-être modifiée'; +$labels['longacle'] = 'Les courriels peuvent-être purgés'; $labels['longaclx'] = 'Le dossier peut-être supprimé ou renommé'; $labels['longacla'] = 'Les droits d\'accès du dossier peuvent être modifiés'; -$labels['longacln'] = 'Les métadonnées partagées par les messages (annotations) peuvent être changées'; +$labels['longacln'] = 'Les métadonnées partagées des courriels (annotations) peuvent être changées'; $labels['longaclfull'] = 'Contrôle total, incluant l\'administration des dossiers'; $labels['longaclread'] = 'Le dossier peut-être ouvert en lecture'; -$labels['longaclwrite'] = 'Les messages peuvent-être marqués, écrits ou copiés dans ce dossier'; -$labels['longacldelete'] = 'Les messages peuvent être supprimés'; +$labels['longaclwrite'] = 'Les courriels peuvent-être marqués, écrits ou copiés dans ce dossier'; +$labels['longacldelete'] = 'Les courriels peuvent être supprimés'; $labels['longaclother'] = 'Autres droits d\'accès'; $labels['ariasummaryacltable'] = 'Liste de droits d\'accès'; $labels['arialabelaclactions'] = 'Lister les actions'; diff --git a/plugins/acl/localization/fy_NL.inc b/plugins/acl/localization/fy_NL.inc new file mode 100644 index 000000000..340190af8 --- /dev/null +++ b/plugins/acl/localization/fy_NL.inc @@ -0,0 +1,19 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/acl/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail ACL plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-acl/ +*/ +$labels['username'] = 'Brûker:'; +?> diff --git a/plugins/acl/localization/ia.inc b/plugins/acl/localization/ia.inc new file mode 100644 index 000000000..c3627389d --- /dev/null +++ b/plugins/acl/localization/ia.inc @@ -0,0 +1,98 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/acl/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail ACL plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-acl/ +*/ +$labels['sharing'] = 'Uso in commun'; +$labels['myrights'] = 'Derectos de accesso'; +$labels['username'] = 'Usator:'; +$labels['advanced'] = 'Modo avantiate'; +$labels['newuser'] = 'Adder entrata'; +$labels['editperms'] = 'Modificar permissiones'; +$labels['actions'] = 'Actiones de derecto de accesso...'; +$labels['anyone'] = 'Tote le usatores (non importa qui)'; +$labels['anonymous'] = 'Hospites (anonyme)'; +$labels['identifier'] = 'Identificator'; +$labels['acll'] = 'Cercar'; +$labels['aclr'] = 'Leger messages'; +$labels['acls'] = 'Retener le stato Vidite'; +$labels['aclw'] = 'Signales de scriptura'; +$labels['acli'] = 'Inserer (copiar in)'; +$labels['aclp'] = 'Inviar'; +$labels['aclc'] = 'Crear subdossieres'; +$labels['aclk'] = 'Crear subdossieres'; +$labels['acld'] = 'Deler messages'; +$labels['aclt'] = 'Deler messages'; +$labels['acle'] = 'Expunger'; +$labels['aclx'] = 'Deler dossier'; +$labels['acla'] = 'Administrar'; +$labels['acln'] = 'Annotar messages'; +$labels['aclfull'] = 'Controlo total'; +$labels['aclother'] = 'Altere'; +$labels['aclread'] = 'Leger'; +$labels['aclwrite'] = 'Scriber'; +$labels['acldelete'] = 'Deler'; +$labels['shortacll'] = 'Cercar'; +$labels['shortaclr'] = 'Leger'; +$labels['shortacls'] = 'Retener'; +$labels['shortaclw'] = 'Scriber'; +$labels['shortacli'] = 'Inserer'; +$labels['shortaclp'] = 'Inviar'; +$labels['shortaclc'] = 'Crear'; +$labels['shortaclk'] = 'Crear'; +$labels['shortacld'] = 'Deler'; +$labels['shortaclt'] = 'Deler'; +$labels['shortacle'] = 'Expunger'; +$labels['shortaclx'] = 'Deletion de dossier'; +$labels['shortacla'] = 'Administrar'; +$labels['shortacln'] = 'Annotar'; +$labels['shortaclother'] = 'Altere'; +$labels['shortaclread'] = 'Leger'; +$labels['shortaclwrite'] = 'Scriber'; +$labels['shortacldelete'] = 'Deler'; +$labels['longacll'] = 'Le dossier es visibile in listas e on pote subscriber se a illo'; +$labels['longaclr'] = 'Le dossier pote esser aperite pro lectura'; +$labels['longacls'] = 'Le signal "Vidite" de messages pote esser cambiate'; +$labels['longaclw'] = 'Le signales e parolas-clave de messages pote esser cambiate, excepte "Vidite" e "Delite"'; +$labels['longacli'] = 'Messages pote esser scribite o copiate al dossier'; +$labels['longaclp'] = 'Messages pote esser inviate a iste dossier'; +$labels['longaclc'] = 'Dossieres pote esser create (o renominate) directemente sub iste dossier'; +$labels['longaclk'] = 'Dossieres pote esser create (o renominate) directemente sub iste dossier'; +$labels['longacld'] = 'Le signal "Deler" de messages pote esser cambiate'; +$labels['longaclt'] = 'Le signal "Deler" de messages pote esser cambiate'; +$labels['longacle'] = 'Messages pote esser expungite'; +$labels['longaclx'] = 'Le dossier pote esser delite o renominate'; +$labels['longacla'] = 'Le derectos de accesso del dossier pote esser cambiate'; +$labels['longacln'] = 'Le metadatos commun (annotationes) de messages pote esser cambiate'; +$labels['longaclfull'] = 'Controlo total incluse le administration de dossieres'; +$labels['longaclread'] = 'Le dossier pote esser aperite pro lectura'; +$labels['longaclwrite'] = 'Messages pote esser marcate, scribite o copiate al dossier'; +$labels['longacldelete'] = 'Messages pote esser delite'; +$labels['longaclother'] = 'Altere derectos de accesso'; +$labels['ariasummaryacltable'] = 'Lista de derectos de accesso'; +$labels['arialabelaclactions'] = 'Listar actiones'; +$labels['arialabelaclform'] = 'Formulario de derectos de accesso'; +$messages['deleting'] = 'A deler derectos de accesso...'; +$messages['saving'] = 'A salveguardar derectos de accesso...'; +$messages['updatesuccess'] = 'Le derectos de accesso ha essite cambiate'; +$messages['deletesuccess'] = 'Le derectos de accesso ha essite delite'; +$messages['createsuccess'] = 'Le derectos de accesso ha essite addite'; +$messages['updateerror'] = 'Impossibile actualisar le derectos de accesso'; +$messages['deleteerror'] = 'Impossibile deler derectos de accesso'; +$messages['createerror'] = 'Impossibile adder derectos de accesso'; +$messages['deleteconfirm'] = 'Es vos secur de voler remover le derectos de accesso del usator(es) seligite?'; +$messages['norights'] = 'Nulle derecto ha essite specificate.'; +$messages['nouser'] = 'Nulle nomine de usator ha essite specificate.'; +?> diff --git a/plugins/archive/localization/es_ES.inc b/plugins/archive/localization/es_ES.inc index 115751f67..75a80489f 100644 --- a/plugins/archive/localization/es_ES.inc +++ b/plugins/archive/localization/es_ES.inc @@ -17,15 +17,15 @@ */ $labels['buttontext'] = 'Archivo'; $labels['buttontitle'] = 'Archivar este mensaje'; -$labels['archived'] = 'Mensaje Archivado'; -$labels['archivedreload'] = 'Archivado con éxito. Recargue la página para ver las nuevas carpetas de archivo.'; -$labels['archiveerror'] = 'No se ha podido archivar algunos mensajes'; +$labels['archived'] = 'Archivado correctamente'; +$labels['archivedreload'] = 'Archivado correctamente. Recargue la página para ver las nuevas carpetas de archivo.'; +$labels['archiveerror'] = 'No se pudo archivar algunos mensajes'; $labels['archivefolder'] = 'Archivo'; $labels['settingstitle'] = 'Archivo'; $labels['archivetype'] = 'Dividir el archivo por'; $labels['archivetypeyear'] = 'Año (p.ej. Archivo/2012)'; $labels['archivetypemonth'] = 'Mes (p.ej. Archivo/2012/06)'; $labels['archivetypefolder'] = 'Bandeja original'; -$labels['archivetypesender'] = 'Email del remitente'; +$labels['archivetypesender'] = 'Correo electrónico del remitente'; $labels['unkownsender'] = 'desconocido'; ?> diff --git a/plugins/archive/localization/fr_FR.inc b/plugins/archive/localization/fr_FR.inc index 7fba1aa0e..fa6bb9d68 100644 --- a/plugins/archive/localization/fr_FR.inc +++ b/plugins/archive/localization/fr_FR.inc @@ -16,10 +16,10 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-archive/ */ $labels['buttontext'] = 'Archive'; -$labels['buttontitle'] = 'Archiver ce message'; -$labels['archived'] = 'Message archivé avec succès'; +$labels['buttontitle'] = 'Archiver ce courriel'; +$labels['archived'] = 'Archivé avec succès'; $labels['archivedreload'] = 'Archivé avec succès. Recharger la page pour voir les nouveaux dossiers d\'archives.'; -$labels['archiveerror'] = 'Certains messages n\'ont pas pu être archivés.'; +$labels['archiveerror'] = 'Certains courriels n\'ont pas pu être archivés.'; $labels['archivefolder'] = 'Archive'; $labels['settingstitle'] = 'Archive'; $labels['archivetype'] = 'Diviser l\'archive par'; diff --git a/plugins/archive/localization/ia.inc b/plugins/archive/localization/ia.inc new file mode 100644 index 000000000..3f0cb5707 --- /dev/null +++ b/plugins/archive/localization/ia.inc @@ -0,0 +1,31 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/archive/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Archive plugin | + | Copyright (C) 2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-archive/ +*/ +$labels['buttontext'] = 'Archivar'; +$labels['buttontitle'] = 'Archivar iste message'; +$labels['archived'] = 'Archivate con successo'; +$labels['archivedreload'] = 'Archivate con successo. Recarga le pagina pro vider le nove dossieres de archivo.'; +$labels['archiveerror'] = 'Alcun messages non poteva esser archivate'; +$labels['archivefolder'] = 'Archivo'; +$labels['settingstitle'] = 'Archivo'; +$labels['archivetype'] = 'Divider le archivo per'; +$labels['archivetypeyear'] = 'Anno (p.ex. Archivo/2012)'; +$labels['archivetypemonth'] = 'Mense (p.ex. Archivo/2012/06)'; +$labels['archivetypefolder'] = 'Dossier original'; +$labels['archivetypesender'] = 'E-mail del expeditor'; +$labels['unkownsender'] = 'incognite'; +?> diff --git a/plugins/attachment_reminder/localization/es_ES.inc b/plugins/attachment_reminder/localization/es_ES.inc index 7f6f29e6e..2e4ffdf28 100644 --- a/plugins/attachment_reminder/localization/es_ES.inc +++ b/plugins/attachment_reminder/localization/es_ES.inc @@ -17,4 +17,4 @@ */ $messages['forgotattachment'] = "¿Olvidó adjuntar un fichero al mensaje?"; $messages['reminderoption'] = "Recordatorio sobre adjuntos olvidados"; -$messages['keywords'] = "adjunto"; +$messages['keywords'] = "adjunto, archivo, adjuntar, unido, adjuntando, cerrado, CV, carta de presentación"; diff --git a/plugins/attachment_reminder/localization/fr_FR.inc b/plugins/attachment_reminder/localization/fr_FR.inc index 1d1af5a56..999affccb 100644 --- a/plugins/attachment_reminder/localization/fr_FR.inc +++ b/plugins/attachment_reminder/localization/fr_FR.inc @@ -16,5 +16,5 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-attachment_reminder/ */ $messages['forgotattachment'] = "Avez-vous oublié de joindre un fichier ?"; -$messages['reminderoption'] = "Rappeler les pièces jointes oubliées"; -$messages['keywords'] = "joins,joint,attaché,fichier,inclus,ci-inclus,CV"; +$messages['reminderoption'] = "Rappel sur les pièces jointes oubliées"; +$messages['keywords'] = "pièce jointe,fichier,joindre,joins,joint,attaché,inclus,ci-inclus,CV, lettre d'accompagnement"; diff --git a/plugins/attachment_reminder/localization/ia.inc b/plugins/attachment_reminder/localization/ia.inc new file mode 100644 index 000000000..3b7af087d --- /dev/null +++ b/plugins/attachment_reminder/localization/ia.inc @@ -0,0 +1,20 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/attachment_reminder/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Archive plugin | + | Copyright (C) 2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-attachment_reminder/ +*/ +$messages['forgotattachment'] = "Ha vos oblidate de attachar un file?"; +$messages['reminderoption'] = "Rememorar de attachamentos oblidate"; +$messages['keywords'] = "attachamento,file,attachar,attachate,attachante,annexo,annexe,annexate,CV,curriculo de vita"; diff --git a/plugins/attachment_reminder/localization/tr_TR.inc b/plugins/attachment_reminder/localization/tr_TR.inc index f03587d97..6d0d5c027 100644 --- a/plugins/attachment_reminder/localization/tr_TR.inc +++ b/plugins/attachment_reminder/localization/tr_TR.inc @@ -15,6 +15,6 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-attachment_reminder/ */ -$messages['forgotattachment'] = "Bir dosya eklemeyi unuttunuz mu?"; -$messages['reminderoption'] = "Unutulan dosya eklemelerini hatırlat"; -$messages['keywords'] = "ekleme,dosya,ek,eklenildi,ekleniliyor,konuldu,CV,kapak mektubu"; +$messages['forgotattachment'] = "Dosya eklemeyi mi unuttunuz?"; +$messages['reminderoption'] = "Dosya ek(ler)i unutulduysa hatırlat."; +$messages['keywords'] = "ekleme,dosya,ek,eklenildi,ekleniliyor,ekteki,CV,mektup"; diff --git a/plugins/help/help.php b/plugins/help/help.php index df08caf71..d71cd0ec6 100644 --- a/plugins/help/help.php +++ b/plugins/help/help.php @@ -82,8 +82,14 @@ class help extends rcube_plugin function tablink($attrib) { $rcmail = rcmail::get_instance(); + $attrib['name'] = 'helplink' . $attrib['action']; $attrib['href'] = $rcmail->url(array('_action' => $attrib['action'], '_extwin' => !empty($_REQUEST['_extwin']) ? 1 : null)); + + // title might be already translated here, so revert to it's initial value + // so button() will translate it correctly + $attrib['title'] = $attrib['label']; + return $rcmail->output->button($attrib); } diff --git a/plugins/help/localization/fy_NL.inc b/plugins/help/localization/fy_NL.inc new file mode 100644 index 000000000..3e852a7ce --- /dev/null +++ b/plugins/help/localization/fy_NL.inc @@ -0,0 +1,21 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/help/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Help plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-help/ +*/ +$labels['help'] = 'Help'; +$labels['about'] = 'Oer'; +$labels['license'] = 'Lisinsje'; +?> diff --git a/plugins/help/localization/ia.inc b/plugins/help/localization/ia.inc new file mode 100644 index 000000000..d097947c1 --- /dev/null +++ b/plugins/help/localization/ia.inc @@ -0,0 +1,21 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/help/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Help plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-help/ +*/ +$labels['help'] = 'Adjuta'; +$labels['about'] = 'A proposito'; +$labels['license'] = 'Licentia'; +?> diff --git a/plugins/help/skins/larry/help.css b/plugins/help/skins/larry/help.css index d9af6e15e..d42f4e00b 100644 --- a/plugins/help/skins/larry/help.css +++ b/plugins/help/skins/larry/help.css @@ -5,7 +5,7 @@ } #mainscreen .readtext { - margin: 0 auto; + margin: 20px; } #helptoolbar { diff --git a/plugins/hide_blockquote/localization/ia.inc b/plugins/hide_blockquote/localization/ia.inc new file mode 100644 index 000000000..0d7795cea --- /dev/null +++ b/plugins/hide_blockquote/localization/ia.inc @@ -0,0 +1,21 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/hide_blockquote/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Hide-Blockquote plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-hide_blockquote/ +*/ +$labels['hide'] = 'Celar'; +$labels['show'] = 'Monstrar'; +$labels['quotelimit'] = 'Celar le citation quando le numero de lineas es superior a'; +?> diff --git a/plugins/hide_blockquote/localization/tr_TR.inc b/plugins/hide_blockquote/localization/tr_TR.inc index db3d013e7..b9ac529cf 100644 --- a/plugins/hide_blockquote/localization/tr_TR.inc +++ b/plugins/hide_blockquote/localization/tr_TR.inc @@ -17,5 +17,5 @@ */ $labels['hide'] = 'Gizle'; $labels['show'] = 'Göster'; -$labels['quotelimit'] = 'Satır sayısı şu satır sayısındna fazla ile alıntıları gizle:'; +$labels['quotelimit'] = 'Satır sayısı şu satır sayısından fazla ise alıntıları gizle:'; ?> diff --git a/plugins/jqueryui/jqueryui.php b/plugins/jqueryui/jqueryui.php index 2dfa8add1..1511ac5cf 100644 --- a/plugins/jqueryui/jqueryui.php +++ b/plugins/jqueryui/jqueryui.php @@ -108,6 +108,27 @@ class jqueryui extends rcube_plugin $rcube->output->set_env('mscolors', self::get_color_values()); } + public static function tagedit() + { + if (in_array('tagedit', self::$features)) { + return; + } + + self::$features[] = 'tagedit'; + + $script = 'plugins/jqueryui/js/jquery.tagedit.js'; + $rcube = rcube::get_instance(); + $ui_theme = self::$ui_theme; + $css = "plugins/jqueryui/themes/$ui_theme/tagedit.css"; + + if (!file_exists(INSTALL_PATH . $css)) { + $css = "plugins/jqueryui/themes/larry/tagedit.css"; + } + + $rcube->output->include_css($css); + $rcube->output->add_header(html::tag('script', array('type' => "text/javascript", 'src' => $script))); + } + /** * Return a (limited) list of color values to be used for calendar and category coloring * diff --git a/plugins/jqueryui/js/jquery-ui-1.10.4.custom.min.js b/plugins/jqueryui/js/jquery-ui-1.10.4.custom.min.js index ea4edecb3..73248ecac 100755 --- a/plugins/jqueryui/js/jquery-ui-1.10.4.custom.min.js +++ b/plugins/jqueryui/js/jquery-ui-1.10.4.custom.min.js @@ -109,17 +109,23 @@ $.extend($.datepicker, { var that = this; // register additional keyboard events to control date selection with cursor keys - $(target).unbind('keyup.datepicker-extended').bind('keyup.datepicker-extended', function(event) { + $(target).unbind('keydown.datepicker-extended').bind('keydown.datepicker-extended', function(event) { var inc = 1; switch (event.keyCode) { case 109: + case 173: case 189: // "minus" inc = -1; + case 61: case 107: case 187: // "plus" + // do nothing if the input does not contain full date string + if (this.value.length < that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear).length) { + return true; + } that._adjustInstDate(inst, inc, 'D'); - that._selectDate(target, that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear)); - break; + that._selectDateRC(target, that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear)); + return false; case $.ui.keyCode.UP: case $.ui.keyCode.DOWN: @@ -222,8 +228,23 @@ $.extend($.datepicker, { inst.dpDiv.find('.ui-datepicker-calendar').focus(); inst._hasfocus = false; } - } + }, + _selectDateRC: function(id, dateStr) { + var target = $(id), inst = this._getInst(target[0]); + + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) { + inst.input.val(dateStr); + } + this._updateAlternate(inst); + if (inst.input) { + inst.input.trigger("change"); // fire the change event + } + if (inst.inline) { + this._updateDatepicker(inst); + } + } }); -}(jQuery));
\ No newline at end of file +}(jQuery)); diff --git a/plugins/jqueryui/js/jquery-ui-accessible-datepicker.js b/plugins/jqueryui/js/jquery-ui-accessible-datepicker.js index 1c79e13bd..ef7561c7b 100644 --- a/plugins/jqueryui/js/jquery-ui-accessible-datepicker.js +++ b/plugins/jqueryui/js/jquery-ui-accessible-datepicker.js @@ -94,17 +94,23 @@ $.extend($.datepicker, { var that = this; // register additional keyboard events to control date selection with cursor keys - $(target).unbind('keyup.datepicker-extended').bind('keyup.datepicker-extended', function(event) { + $(target).unbind('keydown.datepicker-extended').bind('keydown.datepicker-extended', function(event) { var inc = 1; switch (event.keyCode) { case 109: + case 173: case 189: // "minus" inc = -1; + case 61: case 107: case 187: // "plus" + // do nothing if the input does not contain full date string + if (this.value.length < that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear).length) { + return true; + } that._adjustInstDate(inst, inc, 'D'); - that._selectDate(target, that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear)); - break; + that._selectDateRC(target, that._formatDate(inst, inst.selectedDay, inst.selectedMonth, inst.selectedYear)); + return false; case $.ui.keyCode.UP: case $.ui.keyCode.DOWN: @@ -207,8 +213,23 @@ $.extend($.datepicker, { inst.dpDiv.find('.ui-datepicker-calendar').focus(); inst._hasfocus = false; } - } + }, + _selectDateRC: function(id, dateStr) { + var target = $(id), inst = this._getInst(target[0]); + + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) { + inst.input.val(dateStr); + } + this._updateAlternate(inst); + if (inst.input) { + inst.input.trigger("change"); // fire the change event + } + if (inst.inline) { + this._updateDatepicker(inst); + } + } }); -}(jQuery));
\ No newline at end of file +}(jQuery)); diff --git a/plugins/jqueryui/js/jquery.miniColors.min.js b/plugins/jqueryui/js/jquery.miniColors.min.js index 4b42ab7ed..487e6ade1 100644 --- a/plugins/jqueryui/js/jquery.miniColors.min.js +++ b/plugins/jqueryui/js/jquery.miniColors.min.js @@ -35,8 +35,8 @@ jQuery&&function(d){d.extend(d.fn,{miniColors:function(j,k){var x=function(a,b){var e=l(a.val());e||(e="FFFFFF");var c=p(e),e=d('<a class="miniColors-trigger" style="background-color: #'+e+'" href="#"></a>');e.insertAfter(a);a.addClass("miniColors").attr("maxlength",7).attr("autocomplete","off");a.data("trigger",e);a.data("hsb",c);b.change&&a.data("change",b.change);b.readonly&&a.attr("readonly",true);b.disabled&&q(a);b.colorValues&&a.data("colorValues",b.colorValues);e.bind("click.miniColors",function(b){b.preventDefault(); a.trigger("focus")});a.bind("focus.miniColors",function(){w(a)});a.bind("blur.miniColors",function(){var b=l(a.val());a.val(b?"#"+b:"")});a.bind("keydown.miniColors",function(b){b.keyCode===9&&i(a)});a.bind("keyup.miniColors",function(){var b=a.val().replace(/[^A-F0-9#]/ig,"");a.val(b);r(a)||a.data("trigger").css("backgroundColor","#FFF")});a.bind("paste.miniColors",function(){setTimeout(function(){a.trigger("keyup")},5)})},q=function(a){i(a);a.attr("disabled",true);a.data("trigger").css("opacity", 0.5)},w=function(a){if(a.attr("disabled"))return false;i();var b=d('<div class="miniColors-selector"></div>');b.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"></div></div>');b.append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>');b.css({top:a.is(":visible")?a.offset().top+a.outerHeight():a.data("trigger").offset().top+a.data("trigger").outerHeight(),left:a.is(":visible")?a.offset().left:a.data("trigger").offset().left, -display:"none"}).addClass(a.attr("class"));var e=a.data("colorValues");if(e&&e.length){var c,f='<div class="miniColors-presets">',g;for(g in e)c=l(e[g]),f+='<div class="miniColors-colorPreset" style="background-color:#'+c+'" rel="'+c+'"></div>';f+="</div>";b.append(f);c=Math.ceil(e.length/7)*24;b.css("width",b.width()+c+5+"px");b.find(".miniColors-presets").css("width",c+"px")}c=a.data("hsb");b.find(".miniColors-colors").css("backgroundColor","#"+n(m({h:c.h,s:100,b:100})));(f=a.data("colorPosition"))|| -(f=s(c));b.find(".miniColors-colorPicker").css("top",f.y+"px").css("left",f.x+"px");(f=a.data("huePosition"))||(f=t(c));b.find(".miniColors-huePicker").css("top",f.y+"px");a.data("selector",b);a.data("huePicker",b.find(".miniColors-huePicker"));a.data("colorPicker",b.find(".miniColors-colorPicker"));a.data("mousebutton",0);d("BODY").append(b);b.fadeIn(100);b.bind("selectstart",function(){return false});d(document).bind("mousedown.miniColors",function(b){a.data("mousebutton",1);d(b.target).parents().andSelf().hasClass("miniColors-colors")&& +display:"none"}).addClass(a.attr("class")).appendTo(d("BODY"));;var e=a.data("colorValues");if(e&&e.length){var c,f='<div class="miniColors-presets">',g;for(g in e)c=l(e[g]),f+='<div class="miniColors-colorPreset" style="background-color:#'+c+'" rel="'+c+'"></div>';f+="</div>";b.append(f);c=Math.ceil(e.length/7)*24;b.css("width",b.width()+c+5+"px");b.find(".miniColors-presets").css("width",c+"px")}c=a.data("hsb");b.find(".miniColors-colors").css("backgroundColor","#"+n(m({h:c.h,s:100,b:100})));(f=a.data("colorPosition"))|| +(f=s(c));b.find(".miniColors-colorPicker").css("top",f.y+"px").css("left",f.x+"px");(f=a.data("huePosition"))||(f=t(c));b.find(".miniColors-huePicker").css("top",f.y+"px");a.data("selector",b);a.data("huePicker",b.find(".miniColors-huePicker"));a.data("colorPicker",b.find(".miniColors-colorPicker"));a.data("mousebutton",0);b.fadeIn(100);b.bind("selectstart",function(){return false});d(document).bind("mousedown.miniColors",function(b){a.data("mousebutton",1);d(b.target).parents().andSelf().hasClass("miniColors-colors")&& (b.preventDefault(),a.data("moving","colors"),u(a,b));d(b.target).parents().andSelf().hasClass("miniColors-hues")&&(b.preventDefault(),a.data("moving","hues"),v(a,b));d(b.target).parents().andSelf().hasClass("miniColors-selector")?b.preventDefault():d(b.target).parents().andSelf().hasClass("miniColors")||i(a)});d(document).bind("mouseup.miniColors",function(){a.data("mousebutton",0);a.removeData("moving")});d(document).bind("mousemove.miniColors",function(b){a.data("mousebutton")===1&&(a.data("moving")=== "colors"&&u(a,b),a.data("moving")==="hues"&&v(a,b))});e&&(b.find(".miniColors-colorPreset").click(function(){a.val(d(this).attr("rel"));r(a)}),b.find('.miniColors-presets div[rel="'+a.val().replace(/#/,"")+'"]').addClass("miniColors-colorPreset-active"))},i=function(a){a||(a=".miniColors");d(a).each(function(){var a=d(this).data("selector");d(this).removeData("selector");d(a).fadeOut(100,function(){d(this).remove()})});d(document).unbind("mousedown.miniColors");d(document).unbind("mousemove.miniColors")}, u=function(a,b){var e=a.data("colorPicker");e.hide();var c={x:b.clientX-a.data("selector").find(".miniColors-colors").offset().left+d(document).scrollLeft()-5,y:b.clientY-a.data("selector").find(".miniColors-colors").offset().top+d(document).scrollTop()-5};if(c.x<=-5)c.x=-5;if(c.x>=144)c.x=144;if(c.y<=-5)c.y=-5;if(c.y>=144)c.y=144;a.data("colorPosition",c);e.css("left",c.x).css("top",c.y).show();e=Math.round((c.x+5)*0.67);e<0&&(e=0);e>100&&(e=100);c=100-Math.round((c.y+5)*0.67);c<0&&(c=0);c>100&& diff --git a/plugins/jqueryui/js/jquery.tagedit.js b/plugins/jqueryui/js/jquery.tagedit.js new file mode 100644 index 000000000..baab701cf --- /dev/null +++ b/plugins/jqueryui/js/jquery.tagedit.js @@ -0,0 +1,683 @@ +/* +* Tagedit - jQuery Plugin +* The Plugin can be used to edit tags from a database the easy way +* +* Examples and documentation at: tagedit.webwork-albrecht.de +* +* License: +* This work is licensed under a MIT License +* +* @licstart The following is the entire license notice for the +* JavaScript code in this file. +* +* Copyright (c) 2010 Oliver Albrecht <info@webwork-albrecht.de> +* Copyright (c) 2014 Thomas Brüderli <thomas@roundcube.net> +* +* Licensed under the MIT licenses +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +* @licend The above is the entire license notice +* for the JavaScript code in this file. +* +* @author Oliver Albrecht Mial: info@webwork-albrecht.de Twitter: @webworka +* @version 1.5.2 (06/2014) +* Requires: jQuery v1.4+, jQueryUI v1.8+, jQuerry.autoGrowInput +* +* Example of usage: +* +* $( "input.tag" ).tagedit(); +* +* Possible options: +* +* autocompleteURL: '', // url for a autocompletion +* deleteEmptyItems: true, // Deletes items with empty value +* deletedPostfix: '-d', // will be put to the Items that are marked as delete +* addedPostfix: '-a', // will be put to the Items that are choosem from the database +* additionalListClass: '', // put a classname here if the wrapper ul shoud receive a special class +* allowEdit: true, // Switch on/off edit entries +* allowDelete: true, // Switch on/off deletion of entries. Will be ignored if allowEdit = false +* allowAdd: true, // switch on/off the creation of new entries +* direction: 'ltr' // Sets the writing direction for Outputs and Inputs +* animSpeed: 500 // Sets the animation speed for effects +* autocompleteOptions: {}, // Setting Options for the jquery UI Autocomplete (http://jqueryui.com/demos/autocomplete/) +* breakKeyCodes: [ 13, 44 ], // Sets the characters to break on to parse the tags (defaults: return, comma) +* checkNewEntriesCaseSensitive: false, // If there is a new Entry, it is checked against the autocompletion list. This Flag controlls if the check is (in-)casesensitive +* texts: { // some texts +* removeLinkTitle: 'Remove from list.', +* saveEditLinkTitle: 'Save changes.', +* deleteLinkTitle: 'Delete this tag from database.', +* deleteConfirmation: 'Are you sure to delete this entry?', +* deletedElementTitle: 'This Element will be deleted.', +* breakEditLinkTitle: 'Cancel' +* } +*/ + +(function($) { + + $.fn.tagedit = function(options) { + /** + * Merge Options with defaults + */ + options = $.extend(true, { + // default options here + autocompleteURL: null, + checkToDeleteURL: null, + deletedPostfix: '-d', + addedPostfix: '-a', + additionalListClass: '', + allowEdit: true, + allowDelete: true, + allowAdd: true, + direction: 'ltr', + animSpeed: 500, + autocompleteOptions: { + select: function( event, ui ) { + $(this).val(ui.item.value).trigger('transformToTag', [ui.item.id]); + return false; + } + }, + breakKeyCodes: [ 13, 44 ], + checkNewEntriesCaseSensitive: false, + texts: { + removeLinkTitle: 'Remove from list.', + saveEditLinkTitle: 'Save changes.', + deleteLinkTitle: 'Delete this tag from database.', + deleteConfirmation: 'Are you sure to delete this entry?', + deletedElementTitle: 'This Element will be deleted.', + breakEditLinkTitle: 'Cancel', + forceDeleteConfirmation: 'There are more records using this tag, are you sure do you want to remove it?' + }, + tabindex: false + }, options || {}); + + // no action if there are no elements + if(this.length == 0) { + return; + } + + // set the autocompleteOptions source + if(options.autocompleteURL) { + options.autocompleteOptions.source = options.autocompleteURL; + } + + // Set the direction of the inputs + var direction= this.attr('dir'); + if(direction && direction.length > 0) { + options.direction = this.attr('dir'); + } + + var elements = this; + var focusItem = null; + + var baseNameRegexp = new RegExp("^(.*)\\[([0-9]*?("+options.deletedPostfix+"|"+options.addedPostfix+")?)?\]$", "i"); + + var baseName = elements.eq(0).attr('name').match(baseNameRegexp); + if(baseName && baseName.length == 4) { + baseName = baseName[1]; + } + else { + // Elementname does not match the expected format, exit + alert('elementname dows not match the expected format (regexp: '+baseNameRegexp+')') + return; + } + + // read tabindex from source element + var ti; + if (!options.tabindex && (ti = elements.eq(0).attr('tabindex'))) + options.tabindex = ti; + + // init elements + inputsToList(); + + /** + * Creates the tageditinput from a list of textinputs + * + */ + function inputsToList() { + var html = '<ul class="tagedit-list '+options.additionalListClass+'">'; + + elements.each(function(i) { + var element_name = $(this).attr('name').match(baseNameRegexp); + if(element_name && element_name.length == 4 && (options.deleteEmptyItems == false || $(this).val().length > 0)) { + if(element_name[1].length > 0) { + var elementId = typeof element_name[2] != 'undefined'? element_name[2]: '', + domId = 'tagedit-' + baseName + '-' + (elementId || i); + + html += '<li class="tagedit-listelement tagedit-listelement-old" aria-labelledby="'+domId+'">'; + html += '<span dir="'+options.direction+'" id="'+domId+'">' + $(this).val() + '</span>'; + html += '<input type="hidden" name="'+baseName+'['+elementId+']" value="'+$(this).val()+'" />'; + if (options.allowDelete) + html += '<a class="tagedit-close" title="'+options.texts.removeLinkTitle+'" aria-label="'+options.texts.removeLinkTitle+' '+$(this).val()+'">x</a>'; + html += '</li>'; + } + } + }); + + // replace Elements with the list and save the list in the local variable elements + elements.last().after(html) + var newList = elements.last().next(); + elements.remove(); + elements = newList; + + // Check if some of the elementshav to be marked as deleted + if(options.deletedPostfix.length > 0) { + elements.find('input[name$="'+options.deletedPostfix+'\]"]').each(function() { + markAsDeleted($(this).parent()); + }); + } + + // put an input field at the End + // Put an empty element at the end + html = '<li class="tagedit-listelement tagedit-listelement-new">'; + if (options.allowAdd) + html += '<input type="text" name="'+baseName+'[]" value="" id="tagedit-input" disabled="disabled" class="tagedit-input-disabled" dir="'+options.direction+'"/>'; + html += '</li>'; + html += '</ul>'; + + elements + .append(html) + .attr('tabindex', options.tabindex) // set tabindex to <ul> to recieve focus + + // Set function on the input + .find('#tagedit-input') + .attr('tabindex', options.tabindex) + .each(function() { + $(this).autoGrowInput({comfortZone: 15, minWidth: 15, maxWidth: 20000}); + + // Event is triggert in case of choosing an item from the autocomplete, or finish the input + $(this).bind('transformToTag', function(event, id) { + var oldValue = (typeof id != 'undefined' && (id.length > 0 || id > 0)); + + var checkAutocomplete = oldValue == true || options.autocompleteOptions.noCheck ? false : true; + // check if the Value ist new + var isNewResult = isNew($(this).val(), checkAutocomplete); + if(isNewResult[0] === true || (isNewResult[0] === false && typeof isNewResult[1] == 'string')) { + + if(oldValue == false && typeof isNewResult[1] == 'string') { + oldValue = true; + id = isNewResult[1]; + } + + if(options.allowAdd == true || oldValue) { + var domId = 'tagedit-' + baseName + '-' + id; + // Make a new tag in front the input + html = '<li class="tagedit-listelement tagedit-listelement-old" aria-labelledby="'+domId+'">'; + html += '<span dir="'+options.direction+'" id="'+domId+'">' + $(this).val() + '</span>'; + var name = oldValue? baseName + '['+id+options.addedPostfix+']' : baseName + '[]'; + html += '<input type="hidden" name="'+name+'" value="'+$(this).val()+'" />'; + html += '<a class="tagedit-close" title="'+options.texts.removeLinkTitle+'" aria-label="'+options.texts.removeLinkTitle+' '+$(this).val()+'">x</a>'; + html += '</li>'; + + $(this).parent().before(html); + } + } + $(this).val(''); + + // close autocomplete + if(options.autocompleteOptions.source) { + if($(this).is(':ui-autocomplete')) + $(this).autocomplete( "close" ); + } + + }) + .keydown(function(event) { + var code = event.keyCode > 0? event.keyCode : event.which; + + switch(code) { + case 46: + if (!focusItem) + break; + case 8: // BACKSPACE + if(focusItem) { + focusItem.fadeOut(options.animSpeed, function() { + $(this).remove(); + }) + unfocusItem(); + event.preventDefault(); + return false; + } + else if($(this).val().length == 0) { + // delete Last Tag + var elementToRemove = elements.find('li.tagedit-listelement-old').last(); + elementToRemove.fadeOut(options.animSpeed, function() {elementToRemove.remove();}) + event.preventDefault(); + return false; + } + break; + case 9: // TAB + if($(this).val().length > 0 && $('ul.ui-autocomplete #ui-active-menuitem').length == 0) { + $(this).trigger('transformToTag'); + event.preventDefault(); + return false; + } + break; + case 37: // LEFT + case 39: // RIGHT + if($(this).val().length == 0) { + // select previous Tag + var inc = code == 37 ? -1 : 1, + items = elements.find('li.tagedit-listelement-old') + x = items.length, next = 0; + items.each(function(i, elem) { + if ($(elem).hasClass('tagedit-listelement-focus')) { + x = i; + return true; + } + }); + unfocusItem(); + next = Math.max(0, x + inc); + if (items.get(next)) { + focusItem = items.eq(next).addClass('tagedit-listelement-focus'); + $(this).attr('aria-activedescendant', focusItem.attr('aria-labelledby')) + + if(options.autocompleteOptions.source != false) { + $(this).autocomplete('close').autocomplete('disable'); + } + } + event.preventDefault(); + return false; + } + break; + default: + // ignore input if an item is focused + if (focusItem !== null) { + event.preventDefault(); + event.bubble = false; + return false; + } + } + return true; + }) + .keypress(function(event) { + var code = event.keyCode > 0? event.keyCode : event.which; + if($.inArray(code, options.breakKeyCodes) > -1) { + if($(this).val().length > 0 && $('ul.ui-autocomplete #ui-active-menuitem').length == 0) { + $(this).trigger('transformToTag'); + } + event.preventDefault(); + return false; + } + else if($(this).val().length > 0){ + unfocusItem(); + } + return true; + }) + .bind('paste', function(e){ + var that = $(this); + if (e.type == 'paste'){ + setTimeout(function(){ + that.trigger('transformToTag'); + }, 1); + } + }) + .blur(function() { + if($(this).val().length == 0) { + // disable the field to prevent sending with the form + $(this).attr('disabled', 'disabled').addClass('tagedit-input-disabled'); + } + else { + // Delete entry after a timeout + var input = $(this); + $(this).data('blurtimer', window.setTimeout(function() {input.val('');}, 500)); + } + unfocusItem(); + // restore tabindex when widget looses focus + if (options.tabindex) + elements.attr('tabindex', options.tabindex); + }) + .focus(function() { + window.clearTimeout($(this).data('blurtimer')); + // remove tabindex on <ul> because #tagedit-input now has it + elements.attr('tabindex', '-1'); + }); + + if(options.autocompleteOptions.source != false) { + $(this).autocomplete(options.autocompleteOptions); + } + }) + .end() + .click(function(event) { + switch(event.target.tagName) { + case 'A': + $(event.target).parent().fadeOut(options.animSpeed, function() { + $(event.target).parent().remove(); + elements.find('#tagedit-input').focus(); + }); + break; + case 'INPUT': + case 'SPAN': + case 'LI': + if($(event.target).hasClass('tagedit-listelement-deleted') == false && + $(event.target).parent('li').hasClass('tagedit-listelement-deleted') == false) { + // Don't edit an deleted Items + return doEdit(event); + } + default: + $(this).find('#tagedit-input') + .removeAttr('disabled') + .removeClass('tagedit-input-disabled') + .focus(); + } + return false; + }) + // forward focus event (on tabbing through the form) + .focus(function(e){ $(this).click(); }) + } + + /** + * Remove class and reference to currently focused tag item + */ + function unfocusItem() { + if(focusItem){ + if(options.autocompleteOptions.source != false) { + elements.find('#tagedit-input').autocomplete('enable'); + } + focusItem.removeClass('tagedit-listelement-focus'); + focusItem = null; + elements.find('#tagedit-input').removeAttr('aria-activedescendant'); + } + } + + /** + * Sets all Actions and events for editing an Existing Tag. + * + * @param event {object} The original Event that was given + * return {boolean} + */ + function doEdit(event) { + if(options.allowEdit == false) { + // Do nothing + return; + } + + var element = event.target.tagName == 'SPAN'? $(event.target).parent() : $(event.target); + + var closeTimer = null; + + // Event that is fired if the User finishes the edit of a tag + element.bind('finishEdit', function(event, doReset) { + window.clearTimeout(closeTimer); + + var textfield = $(this).find(':text'); + var isNewResult = isNew(textfield.val(), true); + if(textfield.val().length > 0 && (typeof doReset == 'undefined' || doReset === false) && (isNewResult[0] == true)) { + // This is a new Value and we do not want to do a reset. Set the new value + $(this).find(':hidden').val(textfield.val()); + $(this).find('span').html(textfield.val()); + } + + textfield.remove(); + $(this).find('a.tagedit-save, a.tagedit-break, a.tagedit-delete').remove(); // Workaround. This normaly has to be done by autogrow Plugin + $(this).removeClass('tagedit-listelement-edit').unbind('finishEdit'); + return false; + }); + + var hidden = element.find(':hidden'); + html = '<input type="text" name="tmpinput" autocomplete="off" value="'+hidden.val()+'" class="tagedit-edit-input" dir="'+options.direction+'"/>'; + html += '<a class="tagedit-save" title="'+options.texts.saveEditLinkTitle+'">o</a>'; + html += '<a class="tagedit-break" title="'+options.texts.breakEditLinkTitle+'">x</a>'; + + // If the Element is one from the Database, it can be deleted + if(options.allowDelete == true && element.find(':hidden').length > 0 && + typeof element.find(':hidden').attr('name').match(baseNameRegexp)[3] != 'undefined') { + html += '<a class="tagedit-delete" title="'+options.texts.deleteLinkTitle+'">d</a>'; + } + + hidden.after(html); + element + .addClass('tagedit-listelement-edit') + .find('a.tagedit-save') + .click(function() { + $(this).parent().trigger('finishEdit'); + return false; + }) + .end() + .find('a.tagedit-break') + .click(function() { + $(this).parent().trigger('finishEdit', [true]); + return false; + }) + .end() + .find('a.tagedit-delete') + .click(function() { + window.clearTimeout(closeTimer); + if(confirm(options.texts.deleteConfirmation)) { + var canDelete = checkToDelete($(this).parent()); + if (!canDelete && confirm(options.texts.forceDeleteConfirmation)) { + markAsDeleted($(this).parent()); + } + + if(canDelete) { + markAsDeleted($(this).parent()); + } + + $(this).parent().find(':text').trigger('finishEdit', [true]); + } + else { + $(this).parent().find(':text').trigger('finishEdit', [true]); + } + return false; + }) + .end() + .find(':text') + .focus() + .autoGrowInput({comfortZone: 10, minWidth: 15, maxWidth: 20000}) + .keypress(function(event) { + switch(event.keyCode) { + case 13: // RETURN + event.preventDefault(); + $(this).parent().trigger('finishEdit'); + return false; + case 27: // ESC + event.preventDefault(); + $(this).parent().trigger('finishEdit', [true]); + return false; + } + return true; + }) + .blur(function() { + var that = $(this); + closeTimer = window.setTimeout(function() {that.parent().trigger('finishEdit', [true])}, 500); + }); + } + + /** + * Verifies if the tag select to be deleted is used by other records using an Ajax request. + * + * @param element + * @returns {boolean} + */ + function checkToDelete(element) { + // if no URL is provide will not verify + if(options.checkToDeleteURL === null) { + return false; + } + + var inputName = element.find('input:hidden').attr('name'); + var idPattern = new RegExp('\\d'); + var tagId = inputName.match(idPattern); + var checkResult = false; + + $.ajax({ + async : false, + url : options.checkToDeleteURL, + dataType: 'json', + type : 'POST', + data : { 'tagId' : tagId}, + complete: function (XMLHttpRequest, textStatus) { + + // Expected JSON Object: { "success": Boolean, "allowDelete": Boolean} + var result = $.parseJSON(XMLHttpRequest.responseText); + if(result.success === true){ + checkResult = result.allowDelete; + } + } + }); + + return checkResult; + } + + /** + * Marks a single Tag as deleted. + * + * @param element {object} + */ + function markAsDeleted(element) { + element + .trigger('finishEdit', [true]) + .addClass('tagedit-listelement-deleted') + .attr('title', options.deletedElementTitle); + element.find(':hidden').each(function() { + var nameEndRegexp = new RegExp('('+options.addedPostfix+'|'+options.deletedPostfix+')?\]'); + var name = $(this).attr('name').replace(nameEndRegexp, options.deletedPostfix+']'); + $(this).attr('name', name); + }); + + } + + /** + * Checks if a tag is already choosen. + * + * @param value {string} + * @param checkAutocomplete {boolean} optional Check also the autocomplet values + * @returns {Array} First item is a boolean, telling if the item should be put to the list, second is optional the ID from autocomplete list + */ + function isNew(value, checkAutocomplete) { + checkAutocomplete = typeof checkAutocomplete == 'undefined'? false : checkAutocomplete; + var autoCompleteId = null; + + var compareValue = options.checkNewEntriesCaseSensitive == true? value : value.toLowerCase(); + + var isNew = true; + elements.find('li.tagedit-listelement-old input:hidden').each(function() { + var elementValue = options.checkNewEntriesCaseSensitive == true? $(this).val() : $(this).val().toLowerCase(); + if(elementValue == compareValue) { + isNew = false; + } + }); + + if (isNew == true && checkAutocomplete == true && options.autocompleteOptions.source != false) { + var result = []; + if ($.isArray(options.autocompleteOptions.source)) { + result = options.autocompleteOptions.source; + } + else if ($.isFunction(options.autocompleteOptions.source)) { + options.autocompleteOptions.source({term: value}, function (data) {result = data}); + } + else if (typeof options.autocompleteOptions.source === "string") { + // Check also autocomplete values + var autocompleteURL = options.autocompleteOptions.source; + if (autocompleteURL.match(/\?/)) { + autocompleteURL += '&'; + } else { + autocompleteURL += '?'; + } + autocompleteURL += 'term=' + value; + $.ajax({ + async: false, + url: autocompleteURL, + dataType: 'json', + complete: function (XMLHttpRequest, textStatus) { + result = $.parseJSON(XMLHttpRequest.responseText); + } + }); + } + + // If there is an entry for that already in the autocomplete, don't use it (Check could be case sensitive or not) + for (var i = 0; i < result.length; i++) { + var resultValue = result[i].label? result[i].label : result[i]; + var label = options.checkNewEntriesCaseSensitive == true? resultValue : resultValue.toLowerCase(); + if (label == compareValue) { + isNew = false; + autoCompleteId = typeof result[i] == 'string' ? i : result[i].id; + break; + } + } + } + + return new Array(isNew, autoCompleteId); + } + } +})(jQuery); + +(function($){ + +// jQuery autoGrowInput plugin by James Padolsey +// See related thread: http://stackoverflow.com/questions/931207/is-there-a-jquery-autogrow-plugin-for-text-fields + +$.fn.autoGrowInput = function(o) { + + o = $.extend({ + maxWidth: 1000, + minWidth: 0, + comfortZone: 70 + }, o); + + this.filter('input:text').each(function(){ + + var minWidth = o.minWidth || $(this).width(), + val = '', + input = $(this), + testSubject = $('<tester/>').css({ + position: 'absolute', + top: -9999, + left: -9999, + width: 'auto', + fontSize: input.css('fontSize'), + fontFamily: input.css('fontFamily'), + fontWeight: input.css('fontWeight'), + letterSpacing: input.css('letterSpacing'), + whiteSpace: 'nowrap' + }), + check = function() { + + if (val === (val = input.val())) {return;} + + // Enter new content into testSubject + var escaped = val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>'); + testSubject.html(escaped); + + // Calculate new width + whether to change + var testerWidth = testSubject.width(), + newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth, + currentWidth = input.width(), + isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth) + || (newWidth > minWidth && newWidth < o.maxWidth); + + // Animate width + if (isValidWidthChange) { + input.width(newWidth); + } + + }; + + testSubject.insertAfter(input); + + $(this).bind('keyup keydown blur update', check); + + check(); + }); + + return this; + +}; + +})(jQuery);
\ No newline at end of file diff --git a/plugins/jqueryui/themes/larry/jquery-ui-1.10.4.custom.css b/plugins/jqueryui/themes/larry/jquery-ui-1.10.4.custom.css index 737f4771a..106e24305 100755 --- a/plugins/jqueryui/themes/larry/jquery-ui-1.10.4.custom.css +++ b/plugins/jqueryui/themes/larry/jquery-ui-1.10.4.custom.css @@ -1442,21 +1442,23 @@ body .ui-tooltip { display: none; } .ie10 .ui-datepicker .ui-datepicker-title select, -.webkit .ui-datepicker .ui-datepicker-title select, -.mozilla .ui-datepicker .ui-datepicker-title select { +.webkit .ui-datepicker .ui-datepicker-title select { background-image: url("images/ui-icons-datepicker.png"); background-position: right -18px; background-repeat: no-repeat; - padding-right: 14px; + padding-right: 16px; -webkit-appearance: none; - -moz-appearance: none; appearance: none; } -.mozilla .ui-datepicker .ui-datepicker-title select { - background-position: right -17px; - text-indent: 0.01px; - text-overflow: ''; - padding-right: 0; + +@supports (-moz-appearance:none) and (mask-type:alpha) { + .mozilla .ui-datepicker .ui-datepicker-title select { + background-image: url("images/ui-icons-datepicker.png"); + background-position: right -14px; + background-repeat: no-repeat; + padding-right: 16px; + -moz-appearance: none; + } } .ui-datepicker .ui-datepicker-month:focus, .ui-datepicker .ui-datepicker-year:focus { diff --git a/plugins/jqueryui/themes/larry/jquery-ui-css.diff b/plugins/jqueryui/themes/larry/jquery-ui-css.diff index cce990679..e3971ecdb 100644 --- a/plugins/jqueryui/themes/larry/jquery-ui-css.diff +++ b/plugins/jqueryui/themes/larry/jquery-ui-css.diff @@ -538,10 +538,10 @@ + appearance: none; +} +.mozilla .ui-datepicker .ui-datepicker-title select { -+ background-position: right -17px; ++ background-position: right -14px; + text-indent: 0.01px; + text-overflow: ''; -+ padding-right: 0; ++ padding-right: 10px; +} +.ui-datepicker .ui-datepicker-month:focus, +.ui-datepicker .ui-datepicker-year:focus { diff --git a/plugins/jqueryui/themes/larry/tagedit.css b/plugins/jqueryui/themes/larry/tagedit.css new file mode 100644 index 000000000..600481c61 --- /dev/null +++ b/plugins/jqueryui/themes/larry/tagedit.css @@ -0,0 +1,122 @@ +/** + * Styles of the tagedit inputsforms + */ +.tagedit-list { + width: 100%; + margin: 0; + padding: 4px 4px 0 5px; + overflow: auto; + min-height: 26px; + background: #fff; + border: 1px solid #b2b2b2; + border-radius: 4px; + box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1); + -moz-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1); + -webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1); + -o-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1); +} +.tagedit-list li.tagedit-listelement { + list-style-type: none; + float: left; + margin: 0 4px 4px 0; + padding: 0; +} + +/* New Item input */ +.tagedit-list li.tagedit-listelement-new input { + border: 0; + height: 100%; + padding: 4px 1px; + width: 15px; + background: #fff; + border-radius: 0; + box-shadow: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; +} +.tagedit-list li.tagedit-listelement-new input:focus { + box-shadow: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + outline: none; +} +.tagedit-list li.tagedit-listelement-new input.tagedit-input-disabled { + display: none; +} + +/* Item that is put to the List */ +.tagedit span.tag-element, +.tagedit-list li.tagedit-listelement-old { + padding: 3px 6px 1px 6px; + background: #ddeef5; + background: -moz-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#edf6fa), color-stop(100%,#d6e9f3)); + background: -o-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%); + background: -ms-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%); + background: linear-gradient(top, #edf6fa 0%, #d6e9f3 100%); + border: 1px solid #c2dae5; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + color: #0d5165; + line-height: 1.3em; +} + +.tagedit-list li.tagedit-listelement-focus { + border-color: #4787b1; + -moz-box-shadow: 0 0 3px 1px rgba(71,135,177, 0.8); + -webkit-box-shadow: 0 0 3px 1px rgba(71,135,177, 0.8); + -o-box-shadow: 0 0 3px 1px rgba(71,135,177, 0.8); + box-shadow: 0 0 3px 1px rgba(71,135,177, 0.8); +} + +.tagedit span.tag-element { + margin-right: 0.6em; + padding: 2px 6px; +/* cursor: pointer; */ +} + +.tagedit span.tag-element.inherit { + color: #666; + background: #f2f2f2; + border-color: #ddd; +} + +.tagedit-list li.tagedit-listelement-old a.tagedit-close, +.tagedit-list li.tagedit-listelement-old a.tagedit-break, +.tagedit-list li.tagedit-listelement-old a.tagedit-delete, +.tagedit-list li.tagedit-listelement-old a.tagedit-save { + text-indent: -2000px; + display: inline-block; + position: relative; + top: -1px; + width: 16px; + height: 16px; + margin: 0 -4px 0 6px; + background: url('data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAgUlEQVQoz2NgQAKzdxwWAOIEIG5AwiC+AAM2AJQIAOL3QPwfCwaJB6BrSMChGB0nwDQYwATP3nn4f+Ge4ygKQXyQOJKYAUjTepjAm09fwBimEUTDxJA0rWdANxWmaMXB0xiGwDADurthGkEAmwbqaCLFeWQFBOlBTlbkkp2MSE2wAA8R50rWvqeRAAAAAElFTkSuQmCC') left 1px no-repeat; + cursor: pointer; +} + +.tagedit-list li.tagedit-listelement-old span { + display: inline-block; + height: 15px; +} + +/** Special hacks for IE7 **/ + +html.ie7 .tagedit span.tag-element, +html.ie7 .tagedit-list li.tagedit-listelement-old { + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#edf6fa', endColorstr='#d6e9f3', GradientType=0); +} + +html.ie7 .tagedit-list li.tagedit-listelement span { + position: relative; + top: -3px; +} + +html.ie7 .tagedit-list li.tagedit-listelement-old a.tagedit-close { + left: 5px; +} + diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog index 3ac7741ad..8ce63c811 100644 --- a/plugins/managesieve/Changelog +++ b/plugins/managesieve/Changelog @@ -1,3 +1,12 @@ +- Fix PHP fatal error when visiting Vacation interface and there's no sieve script yet + +* version 8.2 [2015-01-14] +----------------------------------------------------------- +- Fix bug where actions without if/elseif/else in sieve scripts were skipped +- Support "not allof" test as a negation of all sub-tests +- Fix bug where vacation rule was saved to wrong script if managesieve_kolab_master=true +- Improve procedure of script selection to write a vacation rule + * version 8.1 [2014-12-09] ----------------------------------------------------------- - Added simple API to manage vacation rule diff --git a/plugins/managesieve/composer.json b/plugins/managesieve/composer.json index d8c8af4fe..6d640da08 100644 --- a/plugins/managesieve/composer.json +++ b/plugins/managesieve/composer.json @@ -3,7 +3,7 @@ "type": "roundcube-plugin", "description": "Adds a possibility to manage Sieve scripts (incoming mail filters). It's clickable interface which operates on text scripts and communicates with server using managesieve protocol. Adds Filters tab in Settings.", "license": "GPLv3+", - "version": "8.1", + "version": "8.2", "authors": [ { "name": "Aleksander Machniak", diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php index 25016c878..69ae4b8a6 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php @@ -63,7 +63,7 @@ class rcube_sieve_engine 1 => 'notifyimportancehigh' ); - const VERSION = '8.1'; + const VERSION = '8.2'; const PROGNAME = 'Roundcube (Managesieve)'; const PORT = 4190; @@ -220,14 +220,14 @@ class rcube_sieve_engine * * @return int Connection status: 0 on success, >0 on failure */ - public function load_script($script_name = null) + protected function load_script($script_name = null) { // Get list of scripts $list = $this->list_scripts(); if ($script_name === null || $script_name === '') { // get (first) active script - if (!empty($this->active[0])) { + if (!empty($this->active)) { $script_name = $this->active[0]; } else if ($list) { @@ -1270,8 +1270,11 @@ class rcube_sieve_engine $out .= $hiddenfields->show(); // 'any' flag - if (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not']) + if ((!isset($this->form) && empty($scr['tests']) && !empty($scr)) + || (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not']) + ) { $any = true; + } // filter name input $field_id = '_name'; @@ -1332,7 +1335,7 @@ class rcube_sieve_engine $out .= sprintf("%s<label for=\"%s\">%s</label>\n", $input_join, $field_id, rcube::Q($this->plugin->gettext('filterany'))); - $rows_num = isset($scr) ? sizeof($scr['tests']) : 1; + $rows_num = !empty($scr['tests']) ? sizeof($scr['tests']) : 1; $out .= '<div id="rules"'.($any ? ' style="display: none"' : '').'>'; for ($x=0; $x<$rows_num; $x++) @@ -1463,31 +1466,26 @@ class rcube_sieve_engine $select_op->add(rcube::Q($this->plugin->gettext('valuenotequals')), 'value-ne'); } + $test = self::rule_test($rule); + $target = ''; + // target(s) input if (in_array($rule['test'], array('header', 'address', 'envelope'))) { - $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is'); $target = $rule['arg2']; } else if (in_array($rule['test'], array('body', 'date', 'currentdate'))) { - $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is'); $target = $rule['arg']; } else if ($rule['test'] == 'size') { - $test = ''; - $target = ''; if (preg_match('/^([0-9]+)(K|M|G)?$/', $rule['arg'], $matches)) { $sizetarget = $matches[1]; - $sizeitem = $matches[2]; + $sizeitem = $matches[2]; } else { $sizetarget = $rule['arg']; - $sizeitem = $rule['item']; + $sizeitem = $rule['item']; } } - else { - $test = ($rule['not'] ? 'not' : '').$rule['test']; - $target = ''; - } // (current)date part select if (in_array('date', $this->exts) || in_array('currentdate', $this->exts)) { @@ -1637,6 +1635,43 @@ class rcube_sieve_engine return $out; } + private static function rule_test(&$rule) + { + // first modify value/count tests with 'not' keyword + // we'll revert the meaning of operators + if ($rule['not'] && preg_match('/^(count|value)-([gteqnl]{2})/', $rule['type'], $m)) { + $rule['not'] = false; + + switch ($m[2]) { + case 'gt': $rule['type'] = $m[1] . '-le'; break; + case 'ge': $rule['type'] = $m[1] . '-lt'; break; + case 'lt': $rule['type'] = $m[1] . '-ge'; break; + case 'le': $rule['type'] = $m[1] . '-gt'; break; + case 'eq': $rule['type'] = $m[1] . '-ne'; break; + case 'ne': $rule['type'] = $m[1] . '-eq'; break; + } + } + else if ($rule['not'] && $rule['test'] == 'size') { + $rule['not'] = false; + $rule['type'] = $rule['type'] == 'over' ? 'under' : 'over'; + } + + $set = array('header', 'address', 'envelope', 'body', 'date', 'currentdate'); + + // build test string supported by select element + if ($rule['size']) { + $test = $rule['type']; + } + else if (in_array($rule['test'], $set)) { + $test = ($rule['not'] ? 'not' : '') . ($rule['type'] ? $rule['type'] : 'is'); + } + else { + $test = ($rule['not'] ? 'not' : '') . $rule['test']; + } + + return $test; + } + function action_div($fid, $id, $div=true) { $action = isset($this->form) ? $this->form['actions'][$id] : $this->script[$fid]['actions'][$id]; @@ -2043,7 +2078,6 @@ class rcube_sieve_engine // Handle active script(s) and list of scripts according to Kolab's KEP:14 if ($this->rc->config->get('managesieve_kolab_master')) { - // Skip protected names foreach ((array)$this->list as $idx => $name) { $_name = strtoupper($name); @@ -2071,7 +2105,10 @@ class rcube_sieve_engine foreach ($rules['actions'] as $action) { if ($action['type'] == 'include' && empty($action['global'])) { $name = preg_replace($filename_regex, '', $action['target']); - $this->active[] = $name; + // make sure the script exist + if (in_array($name, $this->list)) { + $this->active[] = $name; + } } } } @@ -2105,6 +2142,11 @@ class rcube_sieve_engine } } + // reindex + if (!empty($this->list)) { + $this->list = array_values($this->list); + } + return $this->list; } @@ -2282,7 +2324,7 @@ class rcube_sieve_engine $i = 1; foreach ($this->script as $idx => $filter) { - if ($filter['type'] != 'if') { + if (empty($filter['actions'])) { continue; } $fname = $filter['name'] ? $filter['name'] : "#$i"; @@ -2302,12 +2344,12 @@ class rcube_sieve_engine */ protected function init_script() { - $this->script = $this->sieve->script->as_array(); - - if (!$this->script) { + if (!$this->sieve->script) { return; } + $this->script = $this->sieve->script->as_array(); + $headers = array(); $exceptions = array('date', 'currentdate', 'size', 'body'); diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php index bc62d2ff4..518d79d35 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php @@ -622,6 +622,7 @@ class rcube_sieve_script $disabled = false; $join = false; + $join_not = false; // disabled rule (false + comment): if false # ..... if (preg_match('/^\s*false\s+#/i', $content)) { @@ -650,15 +651,22 @@ class rcube_sieve_script $not = false; } + // we support "not allof" as a negation of allof sub-tests + if ($join_not) { + $not = !$not; + } + switch ($token) { case 'allof': - $join = true; + $join = true; + $join_not = $not; break; + case 'anyof': break; case 'size': - $test = array('test' => 'size', 'not' => $not); + $test = array('test' => 'size', 'not' => $not); $test['arg'] = array_pop($tokens); @@ -740,16 +748,16 @@ class rcube_sieve_script break; case 'exists': - $tests[] = array('test' => 'exists', 'not' => $not, + $tests[] = array('test' => 'exists', 'not' => $not, 'arg' => array_pop($tokens)); break; case 'true': - $tests[] = array('test' => 'true', 'not' => $not); + $tests[] = array('test' => 'true', 'not' => $not); break; case 'false': - $tests[] = array('test' => 'true', 'not' => !$not); + $tests[] = array('test' => 'true', 'not' => !$not); break; } diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php index 10aaea0e9..8d865008f 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php @@ -24,6 +24,8 @@ class rcube_sieve_vacation extends rcube_sieve_engine { protected $error; + protected $script_name; + protected $vacation = array(); function actions() { @@ -34,6 +36,7 @@ class rcube_sieve_vacation extends rcube_sieve_engine $this->vacation_rule(); $this->vacation_post(); } + $this->plugin->add_label('vacation.saving'); $this->rc->output->add_handlers(array( 'vacationform' => array($this, 'vacation_form'), @@ -43,15 +46,90 @@ class rcube_sieve_vacation extends rcube_sieve_engine $this->rc->output->send('managesieve.vacation'); } - private function vacation_rule() + /** + * Find and load sieve script with/for vacation rule + * + * @return int Connection status: 0 on success, >0 on failure + */ + protected function load_script() { - $this->vacation = array(); + if ($this->script_name !== null) { + return 0; + } + + $list = $this->list_scripts(); + $master = $this->rc->config->get('managesieve_kolab_master'); + $included = array(); + + $this->script_name = false; + + // first try the active script(s)... + if (!empty($this->active)) { + // Note: there can be more than one active script on KEP:14-enabled server + foreach ($this->active as $script) { + if ($this->sieve->load($script)) { + foreach ($this->sieve->script->as_array() as $rule) { + if (!empty($rule['actions'])) { + if ($rule['actions'][0]['type'] == 'vacation') { + $this->script_name = $script; + return 0; + } + else if (empty($master) && $rule['actions'][0]['type'] == 'include') { + $included[] = $rule['actions'][0]['target']; + } + } + } + } + } + + // ...else try scripts included in active script (not for KEP:14) + foreach ($included as $script) { + if ($this->sieve->load($script)) { + foreach ($this->sieve->script->as_array() as $rule) { + if (!empty($rule['actions']) && $rule['actions'][0]['type'] == 'vacation') { + $this->script_name = $script; + return 0; + } + } + } + } + } + + // try all other scripts + if (!empty($list)) { + // else try included scripts + foreach (array_diff($list, $included, $this->active) as $script) { + if ($this->sieve->load($script)) { + foreach ($this->sieve->script->as_array() as $rule) { + if (!empty($rule['actions']) && $rule['actions'][0]['type'] == 'vacation') { + $this->script_name = $script; + return 0; + } + } + } + } + + // none of the scripts contains existing vacation rule + // use any (first) active or just existing script (in that order) + if (!empty($this->active)) { + $this->sieve->load($this->script_name = $this->active[0]); + } + else { + $this->sieve->load($this->script_name = $list[0]); + } + } - if (empty($this->active)) { + return $this->sieve->error(); + } + + private function vacation_rule() + { + if ($this->script_name === false || $this->script_name === null || !$this->sieve->load($this->script_name)) { return; } - $list = array(); + $list = array(); + $active = in_array($this->script_name, $this->active); // find (first) vacation rule foreach ($this->script as $idx => $rule) { @@ -68,14 +146,14 @@ class rcube_sieve_vacation extends rcube_sieve_engine $this->vacation = array_merge($rule['actions'][0], array( 'idx' => $idx, - 'disabled' => $rule['disabled'], + 'disabled' => $rule['disabled'] || !$active, 'name' => $rule['name'], 'tests' => $rule['tests'], 'action' => $action ?: 'keep', 'target' => $target, )); } - else { + else if ($active) { $list[$idx] = $rule['name']; } } @@ -202,8 +280,6 @@ class rcube_sieve_vacation extends rcube_sieve_engine $vacation_tests = $this->rc->config->get('managesieve_vacation_test', array(array('test' => 'true'))); } - // @TODO: handle situation when there's no active script - if (!$error) { $rule = $this->vacation; $rule['type'] = 'if'; @@ -212,6 +288,7 @@ class rcube_sieve_vacation extends rcube_sieve_engine $rule['tests'] = $vacation_tests; $rule['join'] = $date_extension ? count($vacation_tests) > 1 : false; $rule['actions'] = array($vacation_action); + $rule['after'] = $after; if ($action && $action != 'keep') { $rule['actions'][] = array( @@ -221,40 +298,7 @@ class rcube_sieve_vacation extends rcube_sieve_engine ); } - // reset original vacation rule - if (isset($this->vacation['idx'])) { - $this->script[$this->vacation['idx']] = null; - } - - // re-order rules if needed - if (isset($after) && $after !== '') { - // add at target position - if ($after >= count($this->script) - 1) { - $this->script[] = $rule; - } - else { - $script = array(); - - foreach ($this->script as $idx => $r) { - if ($r) { - $script[] = $r; - } - - if ($idx == $after) { - $script[] = $rule; - } - } - - $this->script = $script; - } - } - else { - array_unshift($this->script, $rule); - } - - $this->sieve->script->content = array_values(array_filter($this->script)); - - if ($this->save_script()) { + if ($this->save_vacation_script($rule)) { $this->rc->output->show_message('managesieve.vacationsaved', 'confirmation'); $this->rc->output->send(); } @@ -507,6 +551,99 @@ class rcube_sieve_vacation extends rcube_sieve_engine } /** + * Saves vacation script (adding some variables) + */ + protected function save_vacation_script($rule) + { + // if script does not exist create a new one + if ($this->script_name === null || $this->script_name === false) { + $this->script_name = $this->rc->config->get('managesieve_script_name'); + if (empty($this->script_name)) { + $this->script_name = 'roundcube'; + } + + // use default script contents + if (!$this->rc->config->get('managesieve_kolab_master')) { + $script_file = $this->rc->config->get('managesieve_default'); + if ($script_file && is_readable($script_file)) { + $content = file_get_contents($script_file); + } + } + + // create and load script + if ($this->sieve->save_script($this->script_name, $content)) { + $this->sieve->load($this->script_name); + } + } + + $script_active = in_array($this->script_name, $this->active); + + // re-order rules if needed + if (isset($rule['after']) && $rule['after'] !== '') { + // reset original vacation rule + if (isset($this->vacation['idx'])) { + $this->script[$this->vacation['idx']] = null; + } + + // add at target position + if ($rule['after'] >= count($this->script) - 1) { + $this->script[] = $rule; + } + else { + $script = array(); + + foreach ($this->script as $idx => $r) { + if ($r) { + $script[] = $r; + } + + if ($idx == $rule['after']) { + $script[] = $rule; + } + } + + $this->script = $script; + } + + $this->script = array_values(array_filter($this->script)); + } + // update original vacation rule if it exists + else if (isset($this->vacation['idx'])) { + $this->script[$this->vacation['idx']] = $rule; + } + // otherwise put vacation rule on top + else { + array_unshift($this->script, $rule); + } + + // if the script was not active, we need to de-activate + // all rules except the vacation rule, but only if it is not disabled + if (!$script_active && !$rule['disabled']) { + foreach ($this->script as $idx => $r) { + if (empty($r['actions']) || $r['actions'][0]['type'] != 'vacation') { + $this->script[$idx]['disabled'] = true; + } + } + } + + if (!$this->sieve->script) { + return false; + } + + $this->sieve->script->content = $this->script; + + // save the script + $saved = $this->save_script($this->script_name); + + // activate the script + if ($saved && !$script_active && !$rule['disabled']) { + $this->activate_script($this->script_name); + } + + return $saved; + } + + /** * API: get vacation rule * * @return array Vacation rule information @@ -684,8 +821,6 @@ class rcube_sieve_vacation extends rcube_sieve_engine $vacation_tests = $this->rc->config->get('managesieve_vacation_test', array(array('test' => 'true'))); } - // @TODO: handle situation when there's no active script - $rule = $this->vacation; $rule['type'] = 'if'; $rule['name'] = $rule['name'] ?: 'Out-of-Office'; @@ -702,16 +837,7 @@ class rcube_sieve_vacation extends rcube_sieve_engine ); } - // reset original vacation rule - if (isset($this->vacation['idx'])) { - $this->script[$this->vacation['idx']] = null; - } - - array_unshift($this->script, $rule); - - $this->sieve->script->content = array_values(array_filter($this->script)); - - return $this->save_script(); + return $this->save_vacation_script($rule); } /** diff --git a/plugins/managesieve/localization/cs_CZ.inc b/plugins/managesieve/localization/cs_CZ.inc index 6db6bac91..21e8a6910 100644 --- a/plugins/managesieve/localization/cs_CZ.inc +++ b/plugins/managesieve/localization/cs_CZ.inc @@ -23,7 +23,7 @@ $labels['filteradd'] = 'Přidej filtr'; $labels['filterdel'] = 'Smaž filtr'; $labels['moveup'] = 'Posunout nahoru'; $labels['movedown'] = 'Posunout dolů'; -$labels['filterallof'] = 'Odpovídají všechny pravidla'; +$labels['filterallof'] = 'Odpovídají všechna pravidla'; $labels['filteranyof'] = 'Odpovídá kterékoliv pravidlo'; $labels['filterany'] = 'Všechny zprávy'; $labels['filtercontains'] = 'obsahuje'; diff --git a/plugins/managesieve/localization/es_ES.inc b/plugins/managesieve/localization/es_ES.inc index 62f357bae..2b319daf6 100644 --- a/plugins/managesieve/localization/es_ES.inc +++ b/plugins/managesieve/localization/es_ES.inc @@ -19,12 +19,12 @@ $labels['filters'] = 'Filtros'; $labels['managefilters'] = 'Administrar filtros de correo entrante'; $labels['filtername'] = 'Nombre del filtro'; $labels['newfilter'] = 'Nuevo filtro'; -$labels['filteradd'] = 'Agregar filtro'; +$labels['filteradd'] = 'Añadir filtro'; $labels['filterdel'] = 'Eliminar filtro'; $labels['moveup'] = 'Mover arriba'; $labels['movedown'] = 'Mover abajo'; -$labels['filterallof'] = 'coincidir con todas las reglas siguientes'; -$labels['filteranyof'] = 'coincidir con alguna de las reglas siguientes'; +$labels['filterallof'] = 'que coincida con todas las reglas siguientes'; +$labels['filteranyof'] = 'que coincida con cualquiera de las reglas siguientes'; $labels['filterany'] = 'todos los mensajes'; $labels['filtercontains'] = 'contiene'; $labels['filternotcontains'] = 'no contiene'; @@ -38,7 +38,7 @@ $labels['filterregex'] = 'coincide con la expresión regular'; $labels['filternotregex'] = 'no coincide con la expresión regular'; $labels['filterunder'] = 'bajo'; $labels['filterover'] = 'sobre'; -$labels['addrule'] = 'Agregar regla'; +$labels['addrule'] = 'Añadir regla'; $labels['delrule'] = 'Eliminar regla'; $labels['messagemoveto'] = 'Mover mensaje a'; $labels['messageredirect'] = 'Redirigir mensaje a'; @@ -50,7 +50,7 @@ $labels['messagediscard'] = 'Descartar con un mensaje'; $labels['messagekeep'] = 'Mantener el mensaje en la bandeja de entrada'; $labels['messagesrules'] = 'Para el correo entrante:'; $labels['messagesactions'] = '... ejecutar las siguientes acciones:'; -$labels['add'] = 'Agregar'; +$labels['add'] = 'Añadir'; $labels['del'] = 'Eliminar'; $labels['sender'] = 'Remitente'; $labels['recipient'] = 'Destinatario'; @@ -58,7 +58,7 @@ $labels['vacationaddr'] = 'Mis direcciones adicionales de correo electrónico:'; $labels['vacationdays'] = 'Cada cuánto enviar mensajes (en días):'; $labels['vacationinterval'] = 'Cada cuánto enviar mensajes:'; $labels['vacationreason'] = 'Cuerpo del mensaje (razón de vacaciones):'; -$labels['vacationsubject'] = 'Asunto del Mensaje:'; +$labels['vacationsubject'] = 'Asunto del mensaje:'; $labels['days'] = 'días'; $labels['seconds'] = 'segundos'; $labels['rulestop'] = 'Parar de evaluar reglas'; @@ -76,7 +76,7 @@ $labels['active'] = 'activo'; $labels['none'] = 'ninguno'; $labels['fromset'] = 'de conjunto'; $labels['fromfile'] = 'de archivo'; -$labels['filterdisabled'] = 'Filtro desactivado'; +$labels['filterdisabled'] = 'Filtro deshabilitado'; $labels['countisgreaterthan'] = 'contiene más que'; $labels['countisgreaterthanequal'] = 'contiene más o igual que'; $labels['countislessthan'] = 'contiene menos que'; @@ -91,7 +91,7 @@ $labels['valueequals'] = 'el valor es igual que'; $labels['valuenotequals'] = 'el valor no es igual a'; $labels['setflags'] = 'Etiquetar el mensaje'; $labels['addflags'] = 'Agregar etiquetas al mensaje'; -$labels['removeflags'] = 'Eliminar etiquetas al mensaje'; +$labels['removeflags'] = 'Eliminar etiquetas del mensaje'; $labels['flagread'] = 'Leído'; $labels['flagdeleted'] = 'Eliminado'; $labels['flaganswered'] = 'Respondido'; @@ -103,8 +103,8 @@ $labels['setvarvalue'] = 'Valor de la variable:'; $labels['setvarmodifiers'] = 'Modificadores'; $labels['varlower'] = 'minúsculas'; $labels['varupper'] = 'mayúsculas'; -$labels['varlowerfirst'] = 'inicial en minúsculas'; -$labels['varupperfirst'] = 'inicial en mayúsculas'; +$labels['varlowerfirst'] = 'primer caracter en minúsculas'; +$labels['varupperfirst'] = 'primer caracter en mayúsculas'; $labels['varquotewildcard'] = 'entrecomillar caracteres especiales'; $labels['varlength'] = 'longitud'; $labels['notify'] = 'Enviar notificación'; @@ -119,7 +119,7 @@ $labels['notifyimportancehigh'] = 'alta'; $labels['notifymethodmailto'] = 'Correo electrónico'; $labels['notifymethodtel'] = 'Teléfono'; $labels['notifymethodsms'] = 'SMS'; -$labels['filtercreate'] = 'Crear Filtro'; +$labels['filtercreate'] = 'Crear filtro'; $labels['usedata'] = 'Usar los siguientes datos en el filtro:'; $labels['nextstep'] = 'Siguiente paso'; $labels['...'] = '...'; @@ -187,38 +187,38 @@ $labels['ariasummaryfiltersetslist'] = 'Lista de paquetes de filtros'; $labels['filterstitle'] = 'Editar filtros de mensajes entrantes'; $labels['vacationtitle'] = 'Editar la regla fuera-de-la-oficina'; $messages['filterunknownerror'] = 'Error desconocido en el servidor.'; -$messages['filterconnerror'] = 'No se ha podido conectar con el servidor managesieve.'; -$messages['filterdeleteerror'] = 'No se ha podido borrar el filtro. Ha ocurrido un error en el servidor.'; -$messages['filterdeleted'] = 'Filtro borrado satisfactoriamente.'; -$messages['filtersaved'] = 'Filtro guardado satisfactoriamente.'; -$messages['filtersaveerror'] = 'No se ha podido guardar el filtro. Ha ocurrido un error en el servidor.'; +$messages['filterconnerror'] = 'No se pudo conectar con el servidor managesieve.'; +$messages['filterdeleteerror'] = 'No se pudo borrar el filtro. Ha ocurrido un error en el servidor.'; +$messages['filterdeleted'] = 'Filtro borrado correctamente.'; +$messages['filtersaved'] = 'Filtro guardado correctamente.'; +$messages['filtersaveerror'] = 'No se pudo guardar el filtro. Ha ocurrido un error en el servidor.'; $messages['filterdeleteconfirm'] = '¿Realmente desea borrar el filtro seleccionado?'; $messages['ruledeleteconfirm'] = '¿Está seguro de que desea borrar la regla seleccionada?'; $messages['actiondeleteconfirm'] = '¿Está seguro de que desea borrar la acción seleccionada?'; $messages['forbiddenchars'] = 'Caracteres prohibidos en el campo.'; $messages['cannotbeempty'] = 'El campo no puede estar vacío.'; $messages['ruleexist'] = 'Ya existe un filtro con el nombre especificado.'; -$messages['setactivateerror'] = 'No se ha podido activar el conjunto de filtros seleccionado. Ha ocurrido un error en el servidor.'; -$messages['setdeactivateerror'] = 'No se ha podido desactivar el conjunto de filtros seleccionado. Ha ocurrido un error en el servidor.'; -$messages['setdeleteerror'] = 'No se ha podido borrar el conjunto de filtros seleccionado. Ha ocurrido un error en el servidor.'; -$messages['setactivated'] = 'Conjunto de filtros activado satisfactoriamente.'; -$messages['setdeactivated'] = 'Conjunto de filtros desactivado satisfactoriamente.'; -$messages['setdeleted'] = 'Conjunto de filtros borrado satisfactoriamente.'; +$messages['setactivateerror'] = 'No se pudo activar el conjunto de filtros seleccionado. Ha ocurrido un error en el servidor.'; +$messages['setdeactivateerror'] = 'No se pudo desactivar el conjunto de filtros seleccionado. Ha ocurrido un error en el servidor.'; +$messages['setdeleteerror'] = 'No se pudo borrar el conjunto de filtros seleccionado. Ha ocurrido un error en el servidor.'; +$messages['setactivated'] = 'Conjunto de filtros activado correctamente.'; +$messages['setdeactivated'] = 'Conjunto de filtros desactivado correctamente.'; +$messages['setdeleted'] = 'Conjunto de filtros borrado correctamente.'; $messages['setdeleteconfirm'] = '¿Está seguro de que desea borrar el conjunto de filtros seleccionado?'; $messages['setcreateerror'] = 'No se ha podido crear el conjunto de filtros. Ha ocurrido un error en el servidor.'; -$messages['setcreated'] = 'Conjunto de filtros creado satisfactoriamente.'; -$messages['activateerror'] = 'No se han podido habilitar los filtros seleccionados. Ha ocurrido un error en el servidor.'; -$messages['deactivateerror'] = 'No se han podido deshabilitar los filtros seleccionados. Ha ocurrido un error en el servidor.'; +$messages['setcreated'] = 'Conjunto de filtros creado correctamente.'; +$messages['activateerror'] = 'No se pudo habilitar filtro(s) seleccionado(s). Ha ocurrido un error en el servidor.'; +$messages['deactivateerror'] = 'No se pudo deshabilitar filtro(s) seleccionado(s). Ha ocurrido un error en el servidor.'; $messages['deactivated'] = 'Filtro(s) deshabilitado(s) correctamente.'; $messages['activated'] = 'Filtro(s) habilitado(s) correctamente.'; $messages['moved'] = 'Filtro movido correctamente.'; -$messages['moveerror'] = 'No se ha podido mover el filtro seleccionado. Ha ocurrido un error en el servidor.'; +$messages['moveerror'] = 'No se pudo mover el filtro seleccionado. Ha ocurrido un error en el servidor.'; $messages['nametoolong'] = 'Nombre demasiado largo.'; $messages['namereserved'] = 'Nombre reservado.'; $messages['setexist'] = 'El conjunto ya existe.'; $messages['nodata'] = '¡Al menos una posición debe ser seleccionada!'; $messages['invaliddateformat'] = 'Fecha o formato de parte de la fecha no válido'; -$messages['saveerror'] = 'No fue posible guardar los datos. Ha ocurrido un error en el servidor.'; +$messages['saveerror'] = 'No se pudo guardar los datos. Ha ocurrido un error en el servidor.'; $messages['vacationsaved'] = 'Datos de vacaciones guardados correctamente.'; $messages['emptyvacationbody'] = '¡Hace falta un texto en el mensaje de vacaciones!'; ?> diff --git a/plugins/managesieve/localization/fr_FR.inc b/plugins/managesieve/localization/fr_FR.inc index 6377d12bd..a0a38b089 100644 --- a/plugins/managesieve/localization/fr_FR.inc +++ b/plugins/managesieve/localization/fr_FR.inc @@ -25,7 +25,7 @@ $labels['moveup'] = 'Monter'; $labels['movedown'] = 'Descendre'; $labels['filterallof'] = 'correspondant à toutes les règles suivantes'; $labels['filteranyof'] = 'valident au moins une des conditions suivantes'; -$labels['filterany'] = 'tous les messages'; +$labels['filterany'] = 'tous les courriels'; $labels['filtercontains'] = 'contient'; $labels['filternotcontains'] = 'ne contient pas'; $labels['filteris'] = 'est égal à'; @@ -40,14 +40,14 @@ $labels['filterunder'] = 'plus petit que'; $labels['filterover'] = 'plus grand que'; $labels['addrule'] = 'Ajouter une règle'; $labels['delrule'] = 'Supprimer une règle'; -$labels['messagemoveto'] = 'Déplacer le message vers'; -$labels['messageredirect'] = 'Rediriger le message à'; -$labels['messagecopyto'] = 'Copier le message vers'; -$labels['messagesendcopy'] = 'Envoyer une copie du message à'; -$labels['messagereply'] = 'Répondre avec le message'; -$labels['messagedelete'] = 'Supprimer le message'; -$labels['messagediscard'] = 'Rejeter avec le message'; -$labels['messagekeep'] = 'Conserver le message dans la boîte de réception'; +$labels['messagemoveto'] = 'Déplacer le courriel vers'; +$labels['messageredirect'] = 'Rediriger le courriel vers'; +$labels['messagecopyto'] = 'Copier le courriel vers'; +$labels['messagesendcopy'] = 'Envoyer une copie du courriel à'; +$labels['messagereply'] = 'Répondre avec le courriel'; +$labels['messagedelete'] = 'Supprimer le courriel'; +$labels['messagediscard'] = 'Rejeter avec le courriel'; +$labels['messagekeep'] = 'Conserver le courriel dans la boîte de réception'; $labels['messagesrules'] = 'Pour les courriels entrants :'; $labels['messagesactions'] = '...exécuter les actions suivantes :'; $labels['add'] = 'Ajouter'; @@ -55,10 +55,10 @@ $labels['del'] = 'Supprimer'; $labels['sender'] = 'Expéditeur'; $labels['recipient'] = 'Destinataire'; $labels['vacationaddr'] = 'Mes adresses courriel additionnelles :'; -$labels['vacationdays'] = 'Fréquence d\'envoi des messages (en jours) :'; -$labels['vacationinterval'] = 'Fréquence d\'envoi des messages :'; -$labels['vacationreason'] = 'Corps du message (raison de l\'absence) :'; -$labels['vacationsubject'] = 'Objet du message :'; +$labels['vacationdays'] = 'Fréquence d\'envoi des courriels (en jours) :'; +$labels['vacationinterval'] = 'Fréquence d\'envoi des courriels :'; +$labels['vacationreason'] = 'Corps du courriel (raison de l\'absence) :'; +$labels['vacationsubject'] = 'Objet du courriel :'; $labels['days'] = 'jours'; $labels['seconds'] = 'secondes'; $labels['rulestop'] = 'Arrêter l\'évaluation des règles'; @@ -89,9 +89,9 @@ $labels['valueislessthan'] = 'valeur inférieure à'; $labels['valueislessthanequal'] = 'valeur inférieure ou égale à'; $labels['valueequals'] = 'valeur égale à'; $labels['valuenotequals'] = 'la valeur n\'est pas égale à'; -$labels['setflags'] = 'Définir les drapeaux pour le message'; -$labels['addflags'] = 'Ajouter les drapeaux au message'; -$labels['removeflags'] = 'Supprimer les drapeaux du message'; +$labels['setflags'] = 'Définir les drapeaux pour le courriel'; +$labels['addflags'] = 'Ajouter les drapeaux au courriel'; +$labels['removeflags'] = 'Supprimer les drapeaux du courriel'; $labels['flagread'] = 'Lu'; $labels['flagdeleted'] = 'Supprimé'; $labels['flaganswered'] = 'Réponse envoyée'; @@ -109,7 +109,7 @@ $labels['varquotewildcard'] = 'citer les caractères spéciaux'; $labels['varlength'] = 'longueur'; $labels['notify'] = 'Envoyer la notification'; $labels['notifytarget'] = 'Cible de la notification :'; -$labels['notifymessage'] = 'Message de notification (optionnel) :'; +$labels['notifymessage'] = 'Courriel de notification (optionnel) :'; $labels['notifyoptions'] = 'Options de notification (optionnel) :'; $labels['notifyfrom'] = 'Expéditeur de la notification (optionnel) :'; $labels['notifyimportance'] = 'Importance :'; @@ -118,7 +118,7 @@ $labels['notifyimportancenormal'] = 'normale'; $labels['notifyimportancehigh'] = 'haute'; $labels['notifymethodmailto'] = 'Courriel'; $labels['notifymethodtel'] = 'Téléphone'; -$labels['notifymethodsms'] = 'Message texte'; +$labels['notifymethodsms'] = 'Texto'; $labels['filtercreate'] = 'Créer un filtre'; $labels['usedata'] = 'Utiliser les données suivantes dans le filtre :'; $labels['nextstep'] = 'Étape suivante'; @@ -161,7 +161,7 @@ $labels['asciinumeric'] = 'numérique (ascii-numeric)'; $labels['index'] = 'index :'; $labels['indexlast'] = 'à l\'envers'; $labels['vacation'] = 'Vacances'; -$labels['vacation.reply'] = 'Message de réponse'; +$labels['vacation.reply'] = 'Courriel de réponse'; $labels['vacation.advanced'] = 'Paramètres avancés'; $labels['vacation.subject'] = 'Objet'; $labels['vacation.body'] = 'Corps'; @@ -174,7 +174,7 @@ $labels['vacation.addresses'] = 'Mes adresses supplémentaires'; $labels['vacation.interval'] = 'Plage de réponse'; $labels['vacation.after'] = 'Mettre en place la règle de vacances après'; $labels['vacation.saving'] = 'Enregistrement des données...'; -$labels['vacation.action'] = 'Action pour message entrant'; +$labels['vacation.action'] = 'Action pour courriel entrant'; $labels['vacation.keep'] = 'Garder'; $labels['vacation.discard'] = 'Rejeter'; $labels['vacation.redirect'] = 'Réacheminer à'; @@ -220,5 +220,5 @@ $messages['nodata'] = 'Au moins un élément doit être sélectionné !'; $messages['invaliddateformat'] = 'Format de date ou d\'une partie de la date invalide'; $messages['saveerror'] = 'Impossible d\'enregistrer les données. Une erreur du serveur est survenue.'; $messages['vacationsaved'] = 'Les données de vacances ont été enregistrées avec succès.'; -$messages['emptyvacationbody'] = 'Le corps du message de vacances est nécessaire !'; +$messages['emptyvacationbody'] = 'Le corps du courriel de vacances est exigé !'; ?> diff --git a/plugins/managesieve/localization/fy_NL.inc b/plugins/managesieve/localization/fy_NL.inc new file mode 100644 index 000000000..d507cbf25 --- /dev/null +++ b/plugins/managesieve/localization/fy_NL.inc @@ -0,0 +1,39 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/managesieve/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Managesieve plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-managesieve/ +*/ +$labels['none'] = 'gjin'; +$labels['notifyimportance'] = 'Prioriteit:'; +$labels['notifymethodmailto'] = 'E-mail'; +$labels['notifymethodsms'] = 'SMS'; +$labels['...'] = '...'; +$labels['datetest'] = 'Date'; +$labels['year'] = 'jier'; +$labels['month'] = 'moanne'; +$labels['day'] = 'dei'; +$labels['hour'] = 'oerre'; +$labels['minute'] = 'minút'; +$labels['second'] = 'sekonde'; +$labels['time'] = 'tiid (oo:mm:ss)'; +$labels['iso8601'] = 'datum (ISO8601)'; +$labels['std11'] = 'datum (RFC2822)'; +$labels['zone'] = 'tiidsône'; +$labels['text'] = 'tekst'; +$labels['modtype'] = 'type:'; +$labels['domain'] = 'domein'; +$labels['user'] = 'brûker'; +$labels['vacation.status'] = 'Status'; +?> diff --git a/plugins/managesieve/localization/ia.inc b/plugins/managesieve/localization/ia.inc index c0177d055..2f417abb9 100644 --- a/plugins/managesieve/localization/ia.inc +++ b/plugins/managesieve/localization/ia.inc @@ -16,6 +16,209 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-managesieve/ */ $labels['filters'] = 'Filtros'; +$labels['managefilters'] = 'Gerer filtros de e-mail entrante'; +$labels['filtername'] = 'Nomine de filtro'; +$labels['newfilter'] = 'Nove filtro'; $labels['filteradd'] = 'Adder filtro'; $labels['filterdel'] = 'Deler filtro'; +$labels['moveup'] = 'Displaciar in alto'; +$labels['movedown'] = 'Displaciar a basso'; +$labels['filterallof'] = 'que satisface tote le sequente regulas'; +$labels['filteranyof'] = 'que satisface un del sequente regulas'; +$labels['filterany'] = 'tote le messages'; +$labels['filtercontains'] = 'contine'; +$labels['filternotcontains'] = 'non contine'; +$labels['filteris'] = 'es equal a'; +$labels['filterisnot'] = 'non es equal a'; +$labels['filterexists'] = 'existe'; +$labels['filternotexists'] = 'non existe'; +$labels['filtermatches'] = 'corresponde al expression'; +$labels['filternotmatches'] = 'non corresponde al expression'; +$labels['filterregex'] = 'corresponde al expression regular'; +$labels['filternotregex'] = 'non corresponde al expression regular'; +$labels['filterunder'] = 'sub'; +$labels['filterover'] = 'super'; +$labels['addrule'] = 'Adder regula'; +$labels['delrule'] = 'Deler regula'; +$labels['messagemoveto'] = 'Displaciar message a'; +$labels['messageredirect'] = 'Rediriger message a'; +$labels['messagecopyto'] = 'Copiar message a'; +$labels['messagesendcopy'] = 'Inviar copia del message a'; +$labels['messagereply'] = 'Responder con message'; +$labels['messagedelete'] = 'Deler message'; +$labels['messagediscard'] = 'Abandonar con message'; +$labels['messagekeep'] = 'Retener message in cassa de entrata'; +$labels['messagesrules'] = 'Pro messages entrante:'; +$labels['messagesactions'] = '...executar le sequente actiones:'; +$labels['add'] = 'Adder'; +$labels['del'] = 'Deler'; +$labels['sender'] = 'Expeditor'; +$labels['recipient'] = 'Destinatario'; +$labels['vacationaddr'] = 'Mi additional adresse(s) de e-mail:'; +$labels['vacationdays'] = 'Frequentia de invio de messages (in dies):'; +$labels['vacationinterval'] = 'Frequentia de invio de messages:'; +$labels['vacationreason'] = 'Texto del message (motivo del absentia):'; +$labels['vacationsubject'] = 'Subjecto del message:'; +$labels['days'] = 'dies'; +$labels['seconds'] = 'secundas'; +$labels['rulestop'] = 'Cessar de evalutar regulas'; +$labels['enable'] = 'Activar/Disactivar'; +$labels['filterset'] = 'Gruppo de filtros'; +$labels['filtersets'] = 'Gruppos de filtros'; +$labels['filtersetadd'] = 'Adder gruppo de filtros'; +$labels['filtersetdel'] = 'Deler le gruppo de filtros actual'; +$labels['filtersetact'] = 'Activar le gruppo de filtros actual'; +$labels['filtersetdeact'] = 'Disactivar le gruppo de filtros actual'; +$labels['filterdef'] = 'Definition del filtro'; +$labels['filtersetname'] = 'Nomine del gruppo de filtros'; +$labels['newfilterset'] = 'Nove gruppo de filtros'; +$labels['active'] = 'active'; +$labels['none'] = 'nulle'; +$labels['fromset'] = 'ab gruppo'; +$labels['fromfile'] = 'ab file'; +$labels['filterdisabled'] = 'Filtro disactivate'; +$labels['countisgreaterthan'] = 'numero es superior a'; +$labels['countisgreaterthanequal'] = 'numero es superior o equal a'; +$labels['countislessthan'] = 'numero es inferior a'; +$labels['countislessthanequal'] = 'numero es inferior o equal a'; +$labels['countequals'] = 'numero es equal a'; +$labels['countnotequals'] = 'numero non es equal a'; +$labels['valueisgreaterthan'] = 'valor es superior a'; +$labels['valueisgreaterthanequal'] = 'valor es superior o equal a'; +$labels['valueislessthan'] = 'valor es inferior a'; +$labels['valueislessthanequal'] = 'valor es inferior o equal a'; +$labels['valueequals'] = 'valor es equal a'; +$labels['valuenotequals'] = 'valor non es equal a'; +$labels['setflags'] = 'Mitter signales al message'; +$labels['addflags'] = 'Adder signales al message'; +$labels['removeflags'] = 'Remover signales del message'; +$labels['flagread'] = 'Legite'; +$labels['flagdeleted'] = 'Delite'; +$labels['flaganswered'] = 'Respondite'; +$labels['flagflagged'] = 'Signalate'; +$labels['flagdraft'] = 'Version provisori'; +$labels['setvariable'] = 'Definir variabile'; +$labels['setvarname'] = 'Nomine del variabile:'; +$labels['setvarvalue'] = 'Valor del variabile:'; +$labels['setvarmodifiers'] = 'Modificatores:'; +$labels['varlower'] = 'minusculas'; +$labels['varupper'] = 'majusculas'; +$labels['varlowerfirst'] = 'prime character es minuscula'; +$labels['varupperfirst'] = 'prime character es majuscula'; +$labels['varquotewildcard'] = 'mitter characteres special inter virgulettas'; +$labels['varlength'] = 'longitude'; +$labels['notify'] = 'Inviar notification'; +$labels['notifytarget'] = 'Scopo del notification:'; +$labels['notifymessage'] = 'Message del notification (optional):'; +$labels['notifyoptions'] = 'Optiones de notification (optional):'; +$labels['notifyfrom'] = 'Expeditor del notification (optional):'; +$labels['notifyimportance'] = 'Importantia:'; +$labels['notifyimportancelow'] = 'basse'; +$labels['notifyimportancenormal'] = 'normal'; +$labels['notifyimportancehigh'] = 'alte'; +$labels['notifymethodmailto'] = 'E-mail'; +$labels['notifymethodtel'] = 'Telephono'; +$labels['notifymethodsms'] = 'SMS'; +$labels['filtercreate'] = 'Crear filtro'; +$labels['usedata'] = 'Usar le sequente datos in le filtro:'; +$labels['nextstep'] = 'Proxime passo'; +$labels['...'] = '...'; +$labels['currdate'] = 'Data actual'; +$labels['datetest'] = 'Data'; +$labels['dateheader'] = 'capite:'; +$labels['year'] = 'anno'; +$labels['month'] = 'mense'; +$labels['day'] = 'die'; +$labels['date'] = 'data (aaaa-mm-dd)'; +$labels['julian'] = 'data (julian)'; +$labels['hour'] = 'hora'; +$labels['minute'] = 'minuta'; +$labels['second'] = 'secunda'; +$labels['time'] = 'hora (hh:mm:ss)'; +$labels['iso8601'] = 'data (ISO8601)'; +$labels['std11'] = 'data (RFC2822)'; +$labels['zone'] = 'fuso horari'; +$labels['weekday'] = 'die del septimana (0-6)'; +$labels['advancedopts'] = 'Optiones avantiate'; +$labels['body'] = 'Texto'; +$labels['address'] = 'adresse'; +$labels['envelope'] = 'inveloppe'; +$labels['modifier'] = 'modificator:'; +$labels['text'] = 'texto'; +$labels['undecoded'] = 'non decodificate (crude)'; +$labels['contenttype'] = 'typo de contento'; +$labels['modtype'] = 'typo:'; +$labels['allparts'] = 'totes'; +$labels['domain'] = 'dominio'; +$labels['localpart'] = 'parte local'; +$labels['user'] = 'usator'; +$labels['detail'] = 'detalio'; +$labels['comparator'] = 'comparator:'; +$labels['default'] = 'predefinite'; +$labels['octet'] = 'stricte (octetto)'; +$labels['asciicasemap'] = 'non sensibile al differentia inter majusculas e minusculas (ascii-casemap)'; +$labels['asciinumeric'] = 'numeric (ascii-numeric)'; +$labels['index'] = 'indice:'; +$labels['indexlast'] = 'a retro'; +$labels['vacation'] = 'Vacantias'; +$labels['vacation.reply'] = 'Message de responsa'; +$labels['vacation.advanced'] = 'Configuration avantiate'; +$labels['vacation.subject'] = 'Subjecto'; +$labels['vacation.body'] = 'Texto'; +$labels['vacation.start'] = 'Initio del vacantias'; +$labels['vacation.end'] = 'Fin del vacantias'; +$labels['vacation.status'] = 'Stato'; +$labels['vacation.on'] = 'Active'; +$labels['vacation.off'] = 'Non active'; +$labels['vacation.addresses'] = 'Mi adresses additional'; +$labels['vacation.interval'] = 'Intervallo de responsa'; +$labels['vacation.after'] = 'Mitter le regula de vacantias post'; +$labels['vacation.saving'] = 'A salveguardar datos...'; +$labels['vacation.action'] = 'Action pro message entrante'; +$labels['vacation.keep'] = 'Retener'; +$labels['vacation.discard'] = 'Abandonar'; +$labels['vacation.redirect'] = 'Rediriger a'; +$labels['vacation.copy'] = 'Inviar copia a'; +$labels['arialabelfiltersetactions'] = 'Actiones de gruppo de filtros'; +$labels['arialabelfilteractions'] = 'Actiones de filtro'; +$labels['arialabelfilterform'] = 'Proprietates de filtro'; +$labels['ariasummaryfilterslist'] = 'Lista de filtros'; +$labels['ariasummaryfiltersetslist'] = 'Lista de gruppos de filtros'; +$labels['filterstitle'] = 'Modificar filtros de e-mail entrante'; +$labels['vacationtitle'] = 'Modificar regula de absentia'; +$messages['filterunknownerror'] = 'Error de servitor incognite.'; +$messages['filterconnerror'] = 'Impossibile connecter al servitor.'; +$messages['filterdeleteerror'] = 'Impossibile deler le filtro. Un error de servitor ha occurrite.'; +$messages['filterdeleted'] = 'Le filtro ha essite delite.'; +$messages['filtersaved'] = 'Le filtro ha essite salveguardate.'; +$messages['filtersaveerror'] = 'Impossibile salveguardar le filtro. Un error de servitor ha occurrite.'; +$messages['filterdeleteconfirm'] = 'Es vos secur de voler deler le filtro seligite?'; +$messages['ruledeleteconfirm'] = 'Es vos secur de voler deler le regula seligite?'; +$messages['actiondeleteconfirm'] = 'Es vos secur de voler deler le action seligite?'; +$messages['forbiddenchars'] = 'Le campo contine characteres interdicte.'; +$messages['cannotbeempty'] = 'Le campo non pote esser vacue.'; +$messages['ruleexist'] = 'Un filtro con le nomine specificate jam existe.'; +$messages['setactivateerror'] = 'Impossibile activar le gruppo de filtros seligite. Un error de servitor ha occurrite.'; +$messages['setdeactivateerror'] = 'Impossibile disactivar le gruppo de filtros seligite. Un error de servitor ha occurrite.'; +$messages['setdeleteerror'] = 'Impossibile deler le gruppo de filtros seligite. Un error de servitor ha occurrite.'; +$messages['setactivated'] = 'Le gruppo de filtros ha essite activate.'; +$messages['setdeactivated'] = 'Le gruppo de filtros ha essite disactivate.'; +$messages['setdeleted'] = 'Le gruppo de filtros ha essite delite.'; +$messages['setdeleteconfirm'] = 'Es vos secur de voler deler le gruppo de filtros seligite?'; +$messages['setcreateerror'] = 'Impossibile crear le gruppo de filtros. Un error de servitor ha occurrite.'; +$messages['setcreated'] = 'Le gruppo de filtros ha essite create.'; +$messages['activateerror'] = 'Impossibile activar le filtro(s) seligite. Un error de servitor ha occurrite.'; +$messages['deactivateerror'] = 'Impossibile disactivar le filtro(s) seligite. Un error de servitor ha occurrite.'; +$messages['deactivated'] = 'Le filtro(s) ha essite disactivate.'; +$messages['activated'] = 'Le filtro(s) ha essite activate.'; +$messages['moved'] = 'Le filtro ha essite displaciate.'; +$messages['moveerror'] = 'Impossibile displaciar le filtro seligite. Un error de servitor ha occurrite.'; +$messages['nametoolong'] = 'Le nomine es troppo longe.'; +$messages['namereserved'] = 'Nomine reservate.'; +$messages['setexist'] = 'Le gruppo jam existe.'; +$messages['nodata'] = 'Al minus un position debe esser seligite.'; +$messages['invaliddateformat'] = 'Le formato del data o del parte de data non es valide'; +$messages['saveerror'] = 'Impossibile salveguardar le datos. Un error de servitor ha occurrite.'; +$messages['vacationsaved'] = 'Le datos del vacantias ha essite salveguardate.'; +$messages['emptyvacationbody'] = 'Le texto del message de vacantias es obligatori.'; ?> diff --git a/plugins/markasjunk/localization/es_ES.inc b/plugins/markasjunk/localization/es_ES.inc index e1f7f1750..eb7b2740e 100644 --- a/plugins/markasjunk/localization/es_ES.inc +++ b/plugins/markasjunk/localization/es_ES.inc @@ -17,5 +17,5 @@ */ $labels['buttontext'] = 'SPAM'; $labels['buttontitle'] = 'Marcar como SPAM'; -$labels['reportedasjunk'] = 'Mensaje informado como SPAM'; +$labels['reportedasjunk'] = 'Reportado como SPAM, correctamente'; ?>
\ No newline at end of file diff --git a/plugins/markasjunk/localization/fy_NL.inc b/plugins/markasjunk/localization/fy_NL.inc new file mode 100644 index 000000000..3291a962c --- /dev/null +++ b/plugins/markasjunk/localization/fy_NL.inc @@ -0,0 +1,19 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/markasjunk/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Mark-As-Junk plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-markasjunk/ +*/ +$labels['buttontext'] = 'Spam'; +?>
\ No newline at end of file diff --git a/plugins/markasjunk/localization/ia.inc b/plugins/markasjunk/localization/ia.inc new file mode 100644 index 000000000..d6f1c021d --- /dev/null +++ b/plugins/markasjunk/localization/ia.inc @@ -0,0 +1,21 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/markasjunk/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Mark-As-Junk plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-markasjunk/ +*/ +$labels['buttontext'] = 'Messages indesirate'; +$labels['buttontitle'] = 'Marcar como indesirate'; +$labels['reportedasjunk'] = 'Reportate como indesirate con successo'; +?>
\ No newline at end of file diff --git a/plugins/markasjunk/localization/tr_TR.inc b/plugins/markasjunk/localization/tr_TR.inc index c4230799f..4d46c0b37 100644 --- a/plugins/markasjunk/localization/tr_TR.inc +++ b/plugins/markasjunk/localization/tr_TR.inc @@ -16,6 +16,6 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-markasjunk/ */ $labels['buttontext'] = 'İstenmeyen'; -$labels['buttontitle'] = 'Çöp olarak işaretle'; +$labels['buttontitle'] = 'İstenmeyen olarak işaretle'; $labels['reportedasjunk'] = 'Spam olarak rapor edildi'; ?>
\ No newline at end of file diff --git a/plugins/new_user_dialog/localization/es_ES.inc b/plugins/new_user_dialog/localization/es_ES.inc index 45f55d8f3..b4275b541 100644 --- a/plugins/new_user_dialog/localization/es_ES.inc +++ b/plugins/new_user_dialog/localization/es_ES.inc @@ -15,6 +15,6 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-new_user_dialog/ */ -$labels['identitydialogtitle'] = 'Por favor, complete sus datos personales'; -$labels['identitydialoghint'] = 'Este diálogo sólo aparecerá la primera vez que se conecte al correo.'; +$labels['identitydialogtitle'] = 'Por favor, complete su identidad de remitente'; +$labels['identitydialoghint'] = 'Este diálogo sólo aparece la primera vez que inicia su sesión.'; ?>
\ No newline at end of file diff --git a/plugins/new_user_dialog/localization/ia.inc b/plugins/new_user_dialog/localization/ia.inc new file mode 100644 index 000000000..bf5b749f5 --- /dev/null +++ b/plugins/new_user_dialog/localization/ia.inc @@ -0,0 +1,20 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/new_user_dialog/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail New User Dialog plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-new_user_dialog/ +*/ +$labels['identitydialogtitle'] = 'Per favor, completa vostre identitate de expeditor'; +$labels['identitydialoghint'] = 'Iste quadro solmente appare un vice al prime apertura de session.'; +?>
\ No newline at end of file diff --git a/plugins/newmail_notifier/localization/es_ES.inc b/plugins/newmail_notifier/localization/es_ES.inc index 8809aa03c..ef1be741f 100644 --- a/plugins/newmail_notifier/localization/es_ES.inc +++ b/plugins/newmail_notifier/localization/es_ES.inc @@ -15,14 +15,14 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/ */ -$labels['basic'] = 'Mostrar notificaciones del navegador cuando llegue un nuevo mensaje'; -$labels['desktop'] = 'Mostrar notificaciones del escritorio cuando llegue un nuevo mensaje'; -$labels['sound'] = 'Reproducir sonido cuando llegue un nuevo mensaje'; +$labels['basic'] = 'Mostrar notificaciones del navegador al recibir un nuevo mensaje'; +$labels['desktop'] = 'Mostrar notificaciones de escritorio al recibir un nuevo mensaje'; +$labels['sound'] = 'Reproducir sonido al recibir un nuevo mensaje'; $labels['test'] = 'Prueba'; $labels['title'] = '¡Mensaje nuevo!'; -$labels['body'] = 'Has recibido un mensaje nuevo.'; -$labels['testbody'] = 'Esta es una notificación de pruebas.'; -$labels['desktopdisabled'] = 'Las notificaciones de escritorio están deshabilitadas en tu navegador.'; -$labels['desktopunsupported'] = 'Tu navegador no soporta notificaciones de escritorio.'; +$labels['body'] = 'Ha recibido un mensaje nuevo.'; +$labels['testbody'] = 'Esta es una notificación de prueba.'; +$labels['desktopdisabled'] = 'Las notificaciones de escritorio están deshabilitadas en su navegador.'; +$labels['desktopunsupported'] = 'Su navegador no soporta notificaciones de escritorio.'; $labels['desktoptimeout'] = 'Cerrar notificación de escritorio'; ?> diff --git a/plugins/newmail_notifier/localization/fr_FR.inc b/plugins/newmail_notifier/localization/fr_FR.inc index 92ec698c8..f493420d9 100644 --- a/plugins/newmail_notifier/localization/fr_FR.inc +++ b/plugins/newmail_notifier/localization/fr_FR.inc @@ -15,9 +15,9 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/ */ -$labels['basic'] = 'Afficher les notifications du navigateur pour les nouveaux messages'; -$labels['desktop'] = 'Afficher les notifications du navigateur pour les nouveaux messages'; -$labels['sound'] = 'Jouer un pour les nouveaux messages'; +$labels['basic'] = 'Afficher les notifications du navigateur pour les nouveaux courriels'; +$labels['desktop'] = 'Afficher les notifications du navigateur pour les nouveaux courriels'; +$labels['sound'] = 'Jouer le son pour les nouveaux courriels'; $labels['test'] = 'Test'; $labels['title'] = 'Nouveau courriel'; $labels['body'] = 'Vous avez reçu un nouveau courriel.'; diff --git a/plugins/newmail_notifier/localization/fy_NL.inc b/plugins/newmail_notifier/localization/fy_NL.inc new file mode 100644 index 000000000..53347df15 --- /dev/null +++ b/plugins/newmail_notifier/localization/fy_NL.inc @@ -0,0 +1,20 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/newmail_notifier/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail New Mail Notifier plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/ +*/ +$labels['test'] = 'Test'; +$labels['title'] = 'Nije e-mail!'; +?> diff --git a/plugins/newmail_notifier/localization/ia.inc b/plugins/newmail_notifier/localization/ia.inc index cf83712ec..d10c6b07d 100644 --- a/plugins/newmail_notifier/localization/ia.inc +++ b/plugins/newmail_notifier/localization/ia.inc @@ -15,8 +15,14 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/ */ -$labels['basic'] = 'Monstrar notificationes de navigator in cata nove message'; -$labels['test'] = 'Prova'; -$labels['title'] = 'Nove message!'; -$labels['testbody'] = 'Iste es un notification de prova.'; +$labels['basic'] = 'Presentar notificationes de navigator quando un nove message arriva'; +$labels['desktop'] = 'Presentar notificationes de scriptorio quando un nove message arriva'; +$labels['sound'] = 'Facer sonar un sono quando un nove message arriva'; +$labels['test'] = 'Test'; +$labels['title'] = 'Nove e-mail!'; +$labels['body'] = 'Vos ha recipite un nove message.'; +$labels['testbody'] = 'Iste es un notification de test.'; +$labels['desktopdisabled'] = 'Le notificationes de scriptorio ha essite disactivate in vostre navigator.'; +$labels['desktopunsupported'] = 'Vostre navigator non supporta le notificationes de scriptorio.'; +$labels['desktoptimeout'] = 'Clauder notification de scriptorio'; ?> diff --git a/plugins/newmail_notifier/localization/tr_TR.inc b/plugins/newmail_notifier/localization/tr_TR.inc index e59c05597..4e4d4ce77 100644 --- a/plugins/newmail_notifier/localization/tr_TR.inc +++ b/plugins/newmail_notifier/localization/tr_TR.inc @@ -15,12 +15,12 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/ */ -$labels['basic'] = 'Yeni mesajlarda web tarayıcı bildirimlerini göster'; -$labels['desktop'] = 'Yeni mesajlarda masa üstü bildirimlerini göster'; -$labels['sound'] = 'Yeni mesajlarda müzik çal'; +$labels['basic'] = 'Web tarayıcıda yeni mesajları bildir.'; +$labels['desktop'] = 'Masaüstünde yeni mesajları bildir.'; +$labels['sound'] = 'Yeni mesajlarda ses çal.'; $labels['test'] = 'Deneme'; $labels['title'] = 'Yeni E-posta!'; -$labels['body'] = 'Yeni bir mesaj aldınız'; +$labels['body'] = 'Yeni bir mesajınız var.'; $labels['testbody'] = 'Bu bir test bildirimidir.'; $labels['desktopdisabled'] = 'Web tarayıcınızda masaüstü bildirimi iptal edildi'; $labels['desktopunsupported'] = 'Web tarayıcınız masaüstü bildirimleri desteklemiyor'; diff --git a/plugins/password/drivers/dbmail.php b/plugins/password/drivers/dbmail.php index d76486021..120728395 100644 --- a/plugins/password/drivers/dbmail.php +++ b/plugins/password/drivers/dbmail.php @@ -35,10 +35,23 @@ class rcube_dbmail_password function save($currpass, $newpass) { $curdir = RCUBE_PLUGINS_DIR . 'password/helpers'; - $username = escapeshellcmd($_SESSION['username']); + $username = escapeshellarg($_SESSION['username']); + $password = escapeshellarg($newpass); $args = rcmail::get_instance()->config->get('password_dbmail_args', ''); + $command = "$curdir/chgdbmailusers -c $username -w $password $args"; - exec("$curdir/chgdbmailusers -c $username -w $newpass $args", $output, $returnvalue); + if (strlen($command) > 1024) { + rcube::raise_error(array( + 'code' => 600, + 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Password plugin: The command is too long." + ), true, false); + + return PASSWORD_ERROR; + } + + exec($command, $output, $returnvalue); if ($returnvalue == 0) { return PASSWORD_SUCCESS; diff --git a/plugins/password/helpers/chgdbmailusers.c b/plugins/password/helpers/chgdbmailusers.c index 22793857d..be237556e 100644 --- a/plugins/password/helpers/chgdbmailusers.c +++ b/plugins/password/helpers/chgdbmailusers.c @@ -16,7 +16,7 @@ main(int argc, char *argv[]) { int cnt,rc,cc; - char cmnd[255]; + char cmnd[1024]; strcpy(cmnd, CMD); diff --git a/plugins/password/localization/es_ES.inc b/plugins/password/localization/es_ES.inc index cededcd8b..2e97e6644 100644 --- a/plugins/password/localization/es_ES.inc +++ b/plugins/password/localization/es_ES.inc @@ -15,18 +15,18 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/ */ -$labels['changepasswd'] = 'Cambiar la contraseña'; +$labels['changepasswd'] = 'Cambiar contraseña'; $labels['curpasswd'] = 'Contraseña actual:'; $labels['newpasswd'] = 'Contraseña nueva:'; $labels['confpasswd'] = 'Confirmar contraseña:'; -$messages['nopassword'] = 'Por favor introduzca una contraseña nueva.'; -$messages['nocurpassword'] = 'Por favor introduzca la contraseña actual.'; +$messages['nopassword'] = 'Por favor, introduzca una contraseña nueva.'; +$messages['nocurpassword'] = 'Por favor, introduzca la contraseña actual.'; $messages['passwordincorrect'] = 'La contraseña actual es incorrecta.'; $messages['passwordinconsistency'] = 'Las contraseñas no coinciden. Por favor, inténtelo de nuevo.'; $messages['crypterror'] = 'No se pudo guardar la contraseña nueva. Falta la función de cifrado.'; $messages['connecterror'] = 'No se pudo guardar la contraseña nueva. Error de conexión.'; $messages['internalerror'] = 'No se pudo guardar la contraseña nueva.'; -$messages['passwordshort'] = 'La contraseña debe tener por lo menos $length caracteres.'; +$messages['passwordshort'] = 'La contraseña debe tener al menos $length caracteres.'; $messages['passwordweak'] = 'La contraseña debe incluir al menos un número y un signo de puntuación.'; $messages['passwordforbidden'] = 'La contraseña introducida contiene caracteres no permitidos.'; $messages['firstloginchange'] = 'Este es su primer inicio de sesión. Por favor, cambie su contraseña.'; diff --git a/plugins/password/localization/fy_NL.inc b/plugins/password/localization/fy_NL.inc new file mode 100644 index 000000000..413a80ce5 --- /dev/null +++ b/plugins/password/localization/fy_NL.inc @@ -0,0 +1,19 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/password/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Password plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/ +*/ +$labels['newpasswd'] = 'Nij wachtwurd:'; +?> diff --git a/plugins/password/localization/ia.inc b/plugins/password/localization/ia.inc new file mode 100644 index 000000000..45479634d --- /dev/null +++ b/plugins/password/localization/ia.inc @@ -0,0 +1,33 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/password/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Password plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/ +*/ +$labels['changepasswd'] = 'Cambiar contrasigno'; +$labels['curpasswd'] = 'Contrasigno actual:'; +$labels['newpasswd'] = 'Nove contrasigno:'; +$labels['confpasswd'] = 'Confirmar nove contrasigno:'; +$messages['nopassword'] = 'Entra un nove contrasigno.'; +$messages['nocurpassword'] = 'Entra le contrasigno actual.'; +$messages['passwordincorrect'] = 'Le contrasigno actual es incorrecte.'; +$messages['passwordinconsistency'] = 'Le contrasignos non es identic. Essaya lo de novo.'; +$messages['crypterror'] = 'Impossibile salveguardar le nove contrasigno. Le function de cryptographia manca.'; +$messages['connecterror'] = 'Impossibile salveguardar le nove contrasigno. Error de connexion.'; +$messages['internalerror'] = 'Impossibile salveguardar le nove contrasigno.'; +$messages['passwordshort'] = 'Le contrasigno debe haber al minus $length characteres.'; +$messages['passwordweak'] = 'Le contrasigno debe includer al minus un numero e un character de punctuation.'; +$messages['passwordforbidden'] = 'Le contrasigno contine characteres interdicte.'; +$messages['firstloginchange'] = 'Iste es vostre prime session. Per favor, cambia vostre contrasigno.'; +?> diff --git a/plugins/password/localization/tr_TR.inc b/plugins/password/localization/tr_TR.inc index 37c25c608..f74eed924 100644 --- a/plugins/password/localization/tr_TR.inc +++ b/plugins/password/localization/tr_TR.inc @@ -19,15 +19,15 @@ $labels['changepasswd'] = 'Parolayı değiştir'; $labels['curpasswd'] = 'Şimdiki Parola:'; $labels['newpasswd'] = 'Yeni Parola:'; $labels['confpasswd'] = 'Yeni Parolayı Onaylayın:'; -$messages['nopassword'] = 'Lütfen yeni parolayı girin.'; -$messages['nocurpassword'] = 'Lütfen şimdiki parolayı girin.'; +$messages['nopassword'] = 'Yeni parolayı giriniz.'; +$messages['nocurpassword'] = 'Şimdiki parolayı giriniz.'; $messages['passwordincorrect'] = 'Şimdiki parolayı yanlış girdiniz.'; -$messages['passwordinconsistency'] = 'Girdiğiniz parolalar uyuşmuyor. Lütfen tekrar deneyin.'; +$messages['passwordinconsistency'] = 'Girdiğiniz parolalar uyuşmuyor.Tekrar deneyiniz.'; $messages['crypterror'] = 'Yeni parola kaydedilemedi. Şifreleme fonksiyonu mevcut değil.'; -$messages['connecterror'] = 'Yeni parola kaydedilemedi. Bağlantı hatası.'; +$messages['connecterror'] = 'Yeni parola kaydedilemedi. Bağlantı hatası!...'; $messages['internalerror'] = 'Yeni parola kaydedilemedi.'; $messages['passwordshort'] = 'Parola en az $length karakterden oluşmalı.'; $messages['passwordweak'] = 'Parola en az bir sayı ve bir noktalama işareti içermeli.'; $messages['passwordforbidden'] = 'Parola uygunsuz karakter(ler) içeriyor.'; -$messages['firstloginchange'] = 'Bu ilk girişiniz. Lütfen parolanızı değiştirin.'; +$messages['firstloginchange'] = 'Bu ilk girişiniz. Parolanızı değiştiriniz.'; ?> diff --git a/plugins/subscriptions_option/localization/br.inc b/plugins/subscriptions_option/localization/br.inc new file mode 100644 index 000000000..315402fc5 --- /dev/null +++ b/plugins/subscriptions_option/localization/br.inc @@ -0,0 +1,19 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/subscriptions_option/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Subscriptions plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-subscriptions_option/ +*/ +$labels['useimapsubscriptions'] = 'Arverañ koumanantoù IMAP'; +?> diff --git a/plugins/subscriptions_option/localization/ia.inc b/plugins/subscriptions_option/localization/ia.inc new file mode 100644 index 000000000..9382a5078 --- /dev/null +++ b/plugins/subscriptions_option/localization/ia.inc @@ -0,0 +1,19 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/subscriptions_option/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Subscriptions plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-subscriptions_option/ +*/ +$labels['useimapsubscriptions'] = 'Usar subscriptiones IMAP'; +?> diff --git a/plugins/userinfo/localization/es_ES.inc b/plugins/userinfo/localization/es_ES.inc index 6dde3c59f..25e890058 100644 --- a/plugins/userinfo/localization/es_ES.inc +++ b/plugins/userinfo/localization/es_ES.inc @@ -17,6 +17,6 @@ */ $labels['userinfo'] = 'Información de usuario'; $labels['created'] = 'Creado'; -$labels['lastlogin'] = 'Última conexión'; +$labels['lastlogin'] = 'Último Ingreso'; $labels['defaultidentity'] = 'Identidad predeterminada'; ?>
\ No newline at end of file diff --git a/plugins/userinfo/localization/fy_NL.inc b/plugins/userinfo/localization/fy_NL.inc new file mode 100644 index 000000000..0ca51c51a --- /dev/null +++ b/plugins/userinfo/localization/fy_NL.inc @@ -0,0 +1,19 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/userinfo/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Userinfo plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-userinfo/ +*/ +$labels['userinfo'] = 'Brûkersynformaasje'; +?>
\ No newline at end of file diff --git a/plugins/userinfo/localization/ia.inc b/plugins/userinfo/localization/ia.inc index 4532d9459..89dff2b18 100644 --- a/plugins/userinfo/localization/ia.inc +++ b/plugins/userinfo/localization/ia.inc @@ -17,6 +17,6 @@ */ $labels['userinfo'] = 'Information de usator'; $labels['created'] = 'Create'; -$labels['lastlogin'] = 'Ultime initio de session'; -$labels['defaultidentity'] = 'Identitate predeterminate'; +$labels['lastlogin'] = 'Ultime session'; +$labels['defaultidentity'] = 'Identitate predefinite'; ?>
\ No newline at end of file diff --git a/plugins/vcard_attachments/localization/es_ES.inc b/plugins/vcard_attachments/localization/es_ES.inc index 8c777d2ed..28ea13e84 100644 --- a/plugins/vcard_attachments/localization/es_ES.inc +++ b/plugins/vcard_attachments/localization/es_ES.inc @@ -15,6 +15,6 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-vcard_attachments/ */ -$labels['addvcardmsg'] = 'Añadir la tarjeta a la libreta de direcciones'; -$labels['vcardsavefailed'] = 'No ha sido posible guardar la tarjeta'; +$labels['addvcardmsg'] = 'Añadir tarjeta vCard a la libreta de direcciones'; +$labels['vcardsavefailed'] = 'No se pudo guardar la tarjeta vCard'; ?>
\ No newline at end of file diff --git a/plugins/vcard_attachments/localization/ia.inc b/plugins/vcard_attachments/localization/ia.inc new file mode 100644 index 000000000..7b430f935 --- /dev/null +++ b/plugins/vcard_attachments/localization/ia.inc @@ -0,0 +1,20 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/vcard_attachments/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Vcard Attachments plugin | + | Copyright (C) 2012-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-vcard_attachments/ +*/ +$labels['addvcardmsg'] = 'Adder le vCard al adressario'; +$labels['vcardsavefailed'] = 'Impossibile salveguardar le vCard'; +?>
\ No newline at end of file diff --git a/plugins/zipdownload/localization/fr_FR.inc b/plugins/zipdownload/localization/fr_FR.inc index 6dd839ae6..57c8bf6ee 100644 --- a/plugins/zipdownload/localization/fr_FR.inc +++ b/plugins/zipdownload/localization/fr_FR.inc @@ -15,7 +15,7 @@ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-zipdownload/ */ -$labels['downloadall'] = 'Télécharger tous les fichiers joints'; +$labels['downloadall'] = 'Télécharger toutes les pièces jointes'; $labels['download'] = 'Télécharger...'; $labels['downloadmbox'] = 'Format mbox (.zip)'; $labels['downloadmaildir'] = 'Format maildir (.zip)'; diff --git a/plugins/zipdownload/localization/fy_NL.inc b/plugins/zipdownload/localization/fy_NL.inc new file mode 100644 index 000000000..96d69d0a7 --- /dev/null +++ b/plugins/zipdownload/localization/fy_NL.inc @@ -0,0 +1,18 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/zipdownload/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Zipdownload plugin | + | Copyright (C) 2012-2014, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-zipdownload/ +*/ +$labels['downloademl'] = 'Boarne (.eml)'; diff --git a/plugins/zipdownload/localization/ia.inc b/plugins/zipdownload/localization/ia.inc new file mode 100644 index 000000000..c35619a08 --- /dev/null +++ b/plugins/zipdownload/localization/ia.inc @@ -0,0 +1,22 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | plugins/zipdownload/localization/<lang>.inc | + | | + | Localization file of the Roundcube Webmail Zipdownload plugin | + | Copyright (C) 2012-2014, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + + For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-zipdownload/ +*/ +$labels['downloadall'] = 'Discargar tote le attachamentos'; +$labels['download'] = 'Discargar...'; +$labels['downloadmbox'] = 'Formato Mbox (.zip)'; +$labels['downloadmaildir'] = 'Formato Maildir (.zip)'; +$labels['downloademl'] = 'Fonte (.eml)'; |