]> git.donarmstrong.com Git - roundcube.git/commitdiff
Imported Upstream version 0.2.2
authorJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 15:02:56 +0000 (17:02 +0200)
committerJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 15:02:56 +0000 (17:02 +0200)
66 files changed:
CHANGELOG
config/main.inc.php.dist
index.php
installer/test.php
program/include/iniset.php
program/include/main.inc
program/include/rcmail.php
program/include/rcube_imap.php
program/include/rcube_shared.inc
program/include/rcube_user.php
program/js/app.js
program/js/app.js.src [new file with mode: 0644]
program/js/common.js
program/js/common.js.src [new file with mode: 0644]
program/js/googiespell.js
program/js/googiespell.js.src [new file with mode: 0644]
program/js/list.js
program/js/list.js.src [new file with mode: 0644]
program/lib/html2text.php
program/lib/imap.inc
program/lib/tnef_decoder.inc
program/localization/da_DK/labels.inc
program/localization/da_DK/messages.inc
program/localization/en_GB/labels.inc
program/localization/en_US/labels.inc
program/localization/et_EE/labels.inc
program/localization/gl_ES/labels.inc
program/localization/gl_ES/messages.inc
program/localization/hy_AM/labels.inc
program/localization/hy_AM/messages.inc
program/localization/id_ID/labels.inc
program/localization/index.inc
program/localization/it_IT/labels.inc
program/localization/ka_GE/labels.inc
program/localization/ka_GE/messages.inc
program/localization/lv_LV/labels.inc
program/localization/lv_LV/messages.inc
program/localization/nb_NO/labels.inc
program/localization/nb_NO/messages.inc
program/localization/nl_BE/labels.inc
program/localization/nl_NL/labels.inc
program/localization/pl_PL/labels.inc
program/localization/pt_BR/labels.inc
program/localization/pt_PT/labels.inc
program/localization/ro_RO/labels.inc
program/localization/ro_RO/messages.inc
program/localization/ru_RU/labels.inc
program/localization/sv_SE/labels.inc
program/localization/zh_TW/labels.inc
program/localization/zh_TW/messages.inc
program/steps/mail/attachments.inc
program/steps/mail/autocomplete.inc
program/steps/mail/compose.inc
program/steps/mail/func.inc
program/steps/mail/list.inc
program/steps/mail/sendmail.inc
program/steps/settings/edit_identity.inc
program/steps/settings/func.inc
program/steps/settings/save_identity.inc
skins/default/common.css
skins/default/mail.css
skins/default/print.css
skins/default/settings.css
skins/default/templates/addressbook.html
skins/default/templates/mail.html
skins/default/templates/managefolders.html

index 78bf9d4234b4d7a4456901707722f7219dc20917..ddf2027178a7064bb707441a1c303bd2f92298ba 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,31 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fix quicksearchbox look in Chrome and Konqueror (#1484841)
+- Fix UTF-8 byte-order mark removing (#1485514)
+- Fix folders subscribtions on Konqueror (#1484841) 
+- Fix debug console on Konqueror and Safari
+- Fix messagelist focus issue when modifying status of selected messages (#1485807)
+- Support STARTTLS in IMAP connection (#1485284)
+- Fix DEL key problem in search boxes (#1485528)
+- Support several e-mail addresses per user from virtuser_file (#1485678)
+- Fix drag&drop with scrolling on IE (#1485786)
+- Fix adding signature separator in html mode (#1485350)
+- Fix opening attachment marks message as read (#1485803)
+- Fix 'temp_dir' does not support relative path under Windows (#1484529)
+- Fix "Initialize Database" button missing from installer (#1485802)
+- Fix compose window doesn't fit 1024x768 window (#1485396)
+- Fix service not available error when pressing back from compose dialog (#1485552)
+- Fix using mail() on Windows (#1485779)
+- Fix word wrapping in message-part's <PRE>s for printing (#1485787)
+- Fix incorrect word wrapping in outgoing plaintext multibyte messages (#1485714)
+- Fix double footer in HTML message with embedded images
+- Fix TNEF implementation bug (#1485773)
+- Fix incorrect row id parsing for LDAP contacts list (#1485784) 
+- Fix 'mode' parameter in sqlite DSN (#1485772)
+
+RELEASE 0.2.1
+------------------
 - Use US-ASCII as failover when Unicode searching fails (#1485762)
 - Fix errors handling in IMAP command continuations (#1485762)
 - Fix FETCH result parsing for servers returning flags at the end of result (#1485763)
index 1870852b79bff258443fecdd153f93fe0c2a111a..42af34d6251ea25d1c2074c184a2102c9b90d06b 100644 (file)
@@ -51,7 +51,7 @@ $rcmail_config['auto_create_user'] = TRUE;
 // the mail host chosen to perform the log-in
 // leave blank to show a textbox at login, give a list of hosts
 // to display a pulldown menu or set one host as string.
-// To use SSL connection, enter ssl://hostname:993
+// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
 $rcmail_config['default_host'] = '';
 
 // TCP port used for IMAP connections
@@ -152,7 +152,7 @@ $rcmail_config['date_long'] = 'd.m.Y H:i';
 $rcmail_config['date_today'] = 'H:i';
 
 // add this user-agent to message headers when sending
-$rcmail_config['useragent'] = 'RoundCube Webmail/0.2.1';
+$rcmail_config['useragent'] = 'RoundCube Webmail/0.2.2';
 
 // use this name to compose page titles
 $rcmail_config['product_name'] = 'RoundCube Webmail';
index fa9ac50236717f8267785b9ff0d678fa4cc0ee73..a61ca2f5cf12b6f1c6ca1b0e880e9f333e751f3d 100644 (file)
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
 /*
  +-------------------------------------------------------------------------+
  | RoundCube Webmail IMAP Client                                           |
- | Version 0.2.1                                                           |
+ | Version 0.2.2                                                           |
  |                                                                         |
  | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                   |
  |                                                                         |
@@ -23,7 +23,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                          |
  +-------------------------------------------------------------------------+
 
- $Id: index.php 2348 2009-03-10 08:13:26Z thomasb $
+ $Id: index.php 2484 2009-05-15 10:24:09Z thomasb $
 
 */
 
index d66fe34f24381531ee42287890d4745d100abff9..5740a648958ff505eeee6afe73450d4c919cfb47 100644 (file)
@@ -159,7 +159,7 @@ if ($db_working && $_POST['initdb']) {
 // test database
 if ($db_working) {
     $db_read = $DB->query("SELECT count(*) FROM {$RCI->config['db_table_users']}");
-    if (!$db_read) {
+    if ($DB->db_error) {
         $RCI->fail('DB Schema', "Database not initialized");
         echo '<p><input type="submit" name="initdb" value="Initialize database" /></p>';
         $db_working = false;
index 7bcca4e2b3102e6b1569c076e91778ab34f2926a..5ca17ccf06dc553a9c538ebfee566ddf180cb2a1 100755 (executable)
@@ -22,7 +22,7 @@
 
 
 // application constants
-define('RCMAIL_VERSION', '0.2.1');
+define('RCMAIL_VERSION', '0.2.2');
 define('RCMAIL_CHARSET', 'UTF-8');
 define('JS_OBJECT_NAME', 'rcmail');
 
index c8bd137c4796b25e56eee400a9605efff2e5ae98..4c6ddffb272f764ef910c769af61dcbc4258c944 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: main.inc 2321 2009-03-01 08:14:14Z alec $
+ $Id: main.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -188,7 +188,7 @@ function rcube_charset_convert($str, $from, $to=NULL)
   if ($to == 'UNICODE-1-1-UTF-7')
     $to = 'UTF-7';
 
-  if ($from==$to || $str=='' || empty($from))
+  if ($from == $to || empty($str) || empty($from))
     return $str;
     
   $aliases = array(
@@ -242,6 +242,8 @@ function rcube_charset_convert($str, $from, $to=NULL)
   if ($from == 'UTF-7') {
     if ($_str = utf7_to_utf8($str))
       $str = $_str;
+    else
+      $error = true;
   }
   else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) {
     $str = utf8_encode($str);
@@ -250,7 +252,7 @@ function rcube_charset_convert($str, $from, $to=NULL)
     $conv->loadCharset($from);
     $str = $conv->strToUtf8($str);
   }
-  else if ($from != 'UTF-8') {}
+  else if ($from != 'UTF-8')
     $error = true;
 
   // encode string for output
@@ -274,7 +276,7 @@ function rcube_charset_convert($str, $from, $to=NULL)
       'code' => 500,
       'type' => 'php',
       'file' => __FILE__,
-      'message' => "Could not convert string charset. Make sure iconv is installed or lib/utf8.class is available"
+      'message' => "Could not convert string from $from to $to. Make sure iconv is installed or lib/utf8.class is available"
       ), true, false);
     
     $convert_warning = true;
index f109c16fd9520b4a0b7b6afe2589f7a33cada783..9aad25b2743fb3505063b0538e002d01e79f70bc 100644 (file)
@@ -436,11 +436,13 @@ class rcmail
     if ($a_host['host']) {
       $host = $a_host['host'];
       $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? $a_host['scheme'] : null;
-      $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : $config['default_port']);
+      if(!empty($a_host['port']))
+        $imap_port = $a_host['port'];
+      else if ($imap_ssl && $imap_ssl != 'tls')
+        $imap_port = 993;
     }
-    else
-      $imap_port = $config['default_port'];
-
+    
+    $imap_port = $imap_port ? $imap_port : $config['default_port'];
 
     /* Modify username with domain if required  
        Inspired by Marco <P0L0_notspam_binware.org>
@@ -453,9 +455,10 @@ class rcmail
         $username .= '@'.$config['username_domain'];
     }
 
-    // try to resolve email address from virtuser table    
-    if (!empty($config['virtuser_file']) && strpos($username, '@'))
-      $username = rcube_user::email2user($username);
+    // try to resolve email address from virtuser table
+    if (strpos($username, '@'))
+      if ($virtuser = rcube_user::email2user($username))
+        $username = $virtuser;
 
     // lowercase username if it's an e-mail address (#1484473)
     if (strpos($username, '@'))
index edbdb39d2f9a7e6c9d37d33301dcb4fa659d51fe..018bf7a5031879feb1eaeb19b3d017447dbdcc2a 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_imap.php 2335 2009-03-06 20:58:32Z alec $
+ $Id: rcube_imap.php 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -97,7 +97,7 @@ class rcube_imap
     global $ICL_SSL, $ICL_PORT, $IMAP_USE_INTERNAL_DATE;
     
     // check for Open-SSL support in PHP build
-    if ($use_ssl && in_array('openssl', get_loaded_extensions()))
+    if ($use_ssl && extension_loaded('openssl'))
       $ICL_SSL = $use_ssl == 'imaps' ? 'ssl' : $use_ssl;
     else if ($use_ssl)
       {
index 370b4bc33e3dae74d48d0ae8575872da869b265c..ccf30d2f61ca0e27a6642944c7d8b018e9088735 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_shared.inc 2313 2009-02-27 10:18:18Z thomasb $
+ $Id: rcube_shared.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -405,6 +405,54 @@ function rc_strrpos($haystack, $needle, $offset=0)
     return strrpos($haystack, $needle, $offset);
 }
 
+/**
+ * Wrapper function for wordwrap
+ */
+function rc_wordwrap($string, $width=75, $break="\n", $cut=false)
+{
+  if (!function_exists('mb_substr') || !function_exists('mb_strlen'))
+    return wordwrap($string, $width, $break, $cut);
+    
+  $para = explode($break, $string);
+  $string = '';
+  while (count($para)) {
+    $list = explode(' ', array_shift($para));
+    $len = 0;
+    while (count($list)) {
+      $line = array_shift($list);
+      $l = mb_strlen($line);
+      $newlen = $len + $l + ($len ? 1 : 0);
+
+      if ($newlen <= $width) {
+        $string .= ($len ? ' ' : '').$line;
+        $len += ($len ? 1 : 0) + $l;
+      } else {
+       if ($l > $width) {
+         if ($cut) {
+           $start = 0;
+           while ($l) {
+             $str = mb_substr($line, $start, $width);
+             $strlen = mb_strlen($str);
+             $string .= ($len ? $break : '').$str;
+             $start += $strlen;
+             $l -= $strlen;
+             $len = $strlen;
+           }
+         } else {
+            $string .= ($len ? $break : '').$line;
+           if (count($list)) $string .= $break;
+           $len = 0;
+         }
+       } else {
+          $string .= $break.$line;
+         $len = $l;
+        }
+      }
+    }
+    if (count($para)) $string .= $break;
+  }
+  return $string;
+}
 
 /**
  * Read a specific HTTP request header
index b8833b3c70b9726ca7a074b42c482b7e43ec3a2a..17debeb7ad056fb9b5421e5da95f5530f008c1eb 100644 (file)
@@ -350,10 +350,12 @@ class rcube_user
     $rcmail = rcmail::get_instance();
     $dbh = $rcmail->get_dbh();
 
-    // try to resolve user in virtusertable
-    if ($rcmail->config->get('virtuser_file') && !strpos($user, '@'))
-      $user_email = rcube_user::user2email($user);
-
+    // try to resolve user in virtuser table and file
+    if (!strpos($user, '@')) {
+      if ($email_list = self::user2email($user, false))
+        $user_email = $email_list[0];
+    }
+    
     $dbh->query(
       "INSERT INTO ".get_table_name('users')."
         (created, last_login, username, mail_host, alias, language)
@@ -372,35 +374,21 @@ class rcube_user
 
       $user_name = $user != $user_email ? $user : '';
 
-      // try to resolve the e-mail address from the virtuser table
-      if (($virtuser_query = $rcmail->config->get('virtuser_query'))
-       && ($sql_result = $dbh->query(preg_replace('/%u/', $dbh->escapeSimple($user), $virtuser_query)))
-       && ($dbh->num_rows() > 0))
-      {
-        $standard = 1;
-        while ($sql_arr = $dbh->fetch_array($sql_result))
-        {
-          $dbh->query(
+      if (empty($email_list))
+        $email_list[] = strip_newlines($user_email); 
+
+      // also create new identity records
+      $standard = 1;
+      foreach ($email_list as $email) {
+        $dbh->query(
             "INSERT INTO ".get_table_name('identities')."
               (user_id, del, standard, name, email)
              VALUES (?, 0, ?, ?, ?)",
             $user_id,
            $standard,
             strip_newlines($user_name),
-            preg_replace('/^@/', $user . '@', $sql_arr[0]));
-         $standard = 0;
-        }
-      }
-      else
-      {
-        // also create new identity records
-        $dbh->query(
-          "INSERT INTO ".get_table_name('identities')."
-            (user_id, del, standard, name, email)
-           VALUES (?, 0, 1, ?, ?)",
-          $user_id,
-          strip_newlines($user_name),
-          strip_newlines($user_email));
+            preg_replace('/^@/', $user . '@', $email));
+       $standard = 0;
       }
     }
     else
@@ -418,14 +406,13 @@ class rcube_user
   
   
   /**
-   * Resolve username using a virtuser table
+   * Resolve username using a virtuser file
    *
    * @param string E-mail address to resolve
    * @return string Resolved IMAP username
    */
   static function email2user($email)
   {
-    $user = $email;
     $r = self::findinvirtual('^' . quotemeta($email) . '[[:space:]]');
 
     for ($i=0; $i<count($r); $i++)
@@ -433,44 +420,57 @@ class rcube_user
       $data = trim($r[$i]);
       $arr = preg_split('/\s+/', $data);
       if (count($arr) > 0)
-      {
-        $user = trim($arr[count($arr)-1]);
-        break;
-      }
+        return trim($arr[count($arr)-1]);
     }
 
-    return $user;
+    return NULL;
   }
 
 
   /**
-   * Resolve e-mail address from virtuser table
+   * Resolve e-mail address from virtuser file/table
    *
    * @param string User name
-   * @return string Resolved e-mail address
+   * @param boolean If true returns first found entry
+   * @return mixed Resolved e-mail address string or array of strings
    */
-  static function user2email($user)
+  static function user2email($user, $first=true)
   {
-    $email = '';
-    $r = self::findinvirtual('[[:space:]]' . quotemeta($user) . '[[:space:]]*$');
+    $result = array();
+    $rcmail = rcmail::get_instance();
+    $dbh = $rcmail->get_dbh();
 
+    // SQL lookup
+    if ($virtuser_query = $rcmail->config->get('virtuser_query')) {
+      $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escapeSimple($user), $virtuser_query));
+      while ($sql_arr = $dbh->fetch_array($sql_result))
+        if (strpos($sql_arr[0], '@')) {
+          $result[] = $sql_arr[0];
+         if ($first)
+           return $result[0];
+       }
+    }
+    // File lookup
+    $r = self::findinvirtual('[[:space:]]' . quotemeta($user) . '[[:space:]]*$');
     for ($i=0; $i<count($r); $i++)
     {
       $data = $r[$i];
       $arr = preg_split('/\s+/', $data);
-      if (count($arr) > 0)
+      if (count($arr) > 0 && strpos($arr[0], '@'))
       {
-        $email = trim(str_replace('\\@', '@', $arr[0]));
-        break;
+        $result[] = trim(str_replace('\\@', '@', $arr[0]));
+
+       if ($first)
+          return $result[0];
       }
     }
-
-    return $email;
+    
+    return empty($result) ? NULL : $result;
   }
   
   
   /**
-   * Find matches of the given pattern in virtuser table
+   * Find matches of the given pattern in virtuser file
    * 
    * @param string Regular expression to search for
    * @return array Matching entries
@@ -500,7 +500,6 @@ class rcube_user
     return $result;
   }
 
-
 }
 
 
index e4f6a2a1b5eb4efe73bb22f8deb98cf89b24529d..da37e1287490e1bf9229b953d9e2afee61420b41 100644 (file)
-/*
- +-----------------------------------------------------------------------+
- | RoundCube Webmail Client Script                                       |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
- |          Charles McNulty <charles@charlesmcnulty.com>                 |
- +-----------------------------------------------------------------------+
- | Requires: common.js, list.js                                          |
- +-----------------------------------------------------------------------+
-
-  $Id: app.js 2318 2009-02-27 11:06:29Z thomasb $
-*/
-
-
 var rcube_webmail_client;
-
-function rcube_webmail()
-  {
-  this.env = new Object();
-  this.labels = new Object();
-  this.buttons = new Object();
-  this.gui_objects = new Object();
-  this.commands = new Object();
-  this.onloads = new Array();
-
-  // create protected reference to myself
-  rcube_webmail_client = this;
-  this.ref = 'rcube_webmail_client';
-  var ref = this;
-  // webmail client settings
-  this.dblclick_time = 500;
-  this.message_time = 3000;
-  
-  this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi');
-  
-  // mimetypes supported by the browser (default settings)
-  this.mimetypes = new Array('text/plain', 'text/html', 'text/xml',
-                             'image/jpeg', 'image/gif', 'image/png',
-                             'application/x-javascript', 'application/pdf',
-                             'application/x-shockwave-flash');
-
-  // default environment vars
-  this.env.keep_alive = 60;        // seconds
-  this.env.request_timeout = 180;  // seconds
-  this.env.draft_autosave = 0;     // seconds
-  this.env.comm_path = './';
-  this.env.bin_path = './bin/';
-  this.env.blankpage = 'program/blank.gif';
-
-
-  // set environment variable(s)
-  this.set_env = function(p, value)
-    {
-    if (p != null && typeof(p) == 'object' && !value)
-      for (var n in p)
-        this.env[n] = p[n];
-    else
-      this.env[p] = value;
-    };
-
-  // add a localized label to the client environment
-  this.add_label = function(key, value)
-    {
-    this.labels[key] = value;
-    };
-
-  // add a button to the button list
-  this.register_button = function(command, id, type, act, sel, over)
-    {
-    if (!this.buttons[command])
-      this.buttons[command] = new Array();
-      
-    var button_prop = {id:id, type:type};
-    if (act) button_prop.act = act;
-    if (sel) button_prop.sel = sel;
-    if (over) button_prop.over = over;
-
-    this.buttons[command][this.buttons[command].length] = button_prop;    
-    };
-
-  // register a specific gui object
-  this.gui_object = function(name, id)
-    {
-    this.gui_objects[name] = id;
-    };
-  
-  // execute the given script on load
-  this.add_onload = function(f)
-    {
-      this.onloads[this.onloads.length] = f;
-    };
-
-  // initialize webmail client
-  this.init = function()
-    {
-    var p = this;
-    this.task = this.env.task;
-    
-    // check browser
-    if (!bw.dom || !bw.xmlhttp_test())
-      {
-      this.goto_url('error', '_code=0x199');
-      return;
-      }
-    
-    // find all registered gui objects
-    for (var n in this.gui_objects)
-      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
-
-    // tell parent window that this frame is loaded
-    if (this.env.framed && parent.rcmail && parent.rcmail.set_busy)
-      parent.rcmail.set_busy(false);
-
-    // enable general commands
-    this.enable_command('logout', 'mail', 'addressbook', 'settings', true);
-    
-    if (this.env.permaurl)
-      this.enable_command('permaurl', true);
-    
-    switch (this.task)
-      {
-      case 'mail':
-        if (this.gui_objects.messagelist)
-          {
-          this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {multiselect:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time});
-          this.message_list.row_init = function(o){ p.init_message_row(o); };
-          this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); });
-          this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
-          this.message_list.addEventListener('select', function(o){ p.msglist_select(o); });
-          this.message_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
-          this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
-          this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; });
-
-          this.message_list.init();
-          this.enable_command('toggle_status', 'toggle_flag', true);
-          
-          if (this.gui_objects.mailcontframe)
-            {
-            this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); };
-            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-            }
-          else
-            this.message_list.focus();
-          }
-          
-        if (this.env.coltypes)
-          this.set_message_coltypes(this.env.coltypes);
-
-        // enable mail commands
-        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
-
-        if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
-          document.getElementById('quicksearchbox').value = this.env.search_text;
-        
-        if (this.env.action=='show' || this.env.action=='preview')
-          {
-          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', 'load-headers', true);
-          if (this.env.next_uid)
-            {
-            this.enable_command('nextmessage', true);
-            this.enable_command('lastmessage', true);
-            }
-          if (this.env.prev_uid)
-            {
-            this.enable_command('previousmessage', true);
-            this.enable_command('firstmessage', true);
-            }
-          }
-
-        if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox)
-          this.set_alttext('delete', 'movemessagetotrash');
-        
-        // make preview/message frame visible
-        if (this.env.action == 'preview' && this.env.framed && parent.rcmail)
-          {
-          this.enable_command('compose', 'add-contact', false);
-          parent.rcmail.show_contentframe(true);
-          }
-
-        if ((this.env.action=='show' || this.env.action=='preview') && this.env.blockedobjects)
-          {
-          if (this.gui_objects.remoteobjectsmsg)
-            this.gui_objects.remoteobjectsmsg.style.display = 'block';
-          this.enable_command('load-images', 'always-load', true);
-          }
-
-        if (this.env.action=='compose')
-          {
-          this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true);
-          if (this.env.spellcheck)
-            {
-            this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
-            this.set_spellcheck_state('ready');
-            if (rcube_find_object('_is_html').value == '1')
-              this.display_spellcheck_controls(false);
-            }
-          if (this.env.drafts_mailbox)
-            this.enable_command('savedraft', true);
-            
-          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-          }
-
-        if (this.env.messagecount)
-          this.enable_command('select-all', 'select-none', 'expunge', true);
-
-        if (this.purge_mailbox_test())
-          this.enable_command('purge', true);
-
-        this.set_page_buttons();
-
-        // init message compose form
-        if (this.env.action=='compose')
-          this.init_messageform();
-
-        // show printing dialog
-        if (this.env.action=='print')
-          window.print();
-
-        // get unread count for each mailbox
-        if (this.gui_objects.mailboxlist)
-        {
-          this.env.unread_counts = {};
-          this.gui_objects.folderlist = this.gui_objects.mailboxlist;
-          this.http_request('getunread', '');
-        }
-        
-        // ask user to send MDN
-        if (this.env.mdn_request && this.env.uid)
-        {
-          var mdnurl = '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox);
-          if (confirm(this.get_label('mdnrequest')))
-            this.http_post('sendmdn', mdnurl);
-          else
-            this.http_post('mark', mdnurl+'&_flag=mdnsent');
-        }
-
-        break;
-
-
-      case 'addressbook':
-        if (this.gui_objects.contactslist)
-          {
-          this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, {multiselect:true, draggable:true, keyboard:true});
-          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
-          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
-          this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
-          this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
-          this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; });
-          this.contact_list.init();
-
-          if (this.env.cid)
-            this.contact_list.highlight_row(this.env.cid);
-
-          if (this.gui_objects.contactslist.parentNode)
-            {
-            this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
-            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-            }
-          else
-            this.contact_list.focus();
-          }
-
-        this.set_page_buttons();
-        
-        if (this.env.address_sources && this.env.address_sources[this.env.source] && !this.env.address_sources[this.env.source].readonly)
-          this.enable_command('add', true);
-        
-        if (this.env.cid)
-          this.enable_command('show', 'edit', true);
-
-        if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform)
-          this.enable_command('save', true);
-        else
-          this.enable_command('search', 'reset-search', 'moveto', 'import', true);
-          
-        if (this.contact_list && this.contact_list.rowcount > 0)
-          this.enable_command('export', true);
-
-        this.enable_command('list', true);
-        break;
-
-
-      case 'settings':
-        this.enable_command('preferences', 'identities', 'save', 'folders', true);
-        
-        if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') {
-          this.enable_command('add', this.env.identities_level < 2);
-          this.enable_command('delete', 'edit', true);
-        }
-
-        if (this.env.action=='edit-identity' || this.env.action=='add-identity')
-          this.enable_command('save', true);
-          
-        if (this.env.action=='folders')
-          this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true);
-
-        if (this.gui_objects.identitieslist)
-          {
-          this.identity_list = new rcube_list_widget(this.gui_objects.identitieslist, {multiselect:false, draggable:false, keyboard:false});
-          this.identity_list.addEventListener('select', function(o){ p.identity_select(o); });
-          this.identity_list.init();
-          this.identity_list.focus();
-
-          if (this.env.iid)
-            this.identity_list.highlight_row(this.env.iid);
-          }
-
-        if (this.gui_objects.subscriptionlist)
-          this.init_subscription_list();
-
-        break;
-
-      case 'login':
-        var input_user = rcube_find_object('rcmloginuser');
-        var input_pass = rcube_find_object('rcmloginpwd');
-        var input_tz = rcube_find_object('rcmlogintz');
-
-        if (input_user)
-          input_user.onkeyup = function(e){ return rcmail.login_user_keyup(e); };
-        if (input_user && input_user.value=='')
-          input_user.focus();
-        else if (input_pass)
-          input_pass.focus();
-
-        // detect client timezone
-        if (input_tz)
-          input_tz.value = new Date().getTimezoneOffset() / -60;
-
-        this.enable_command('login', true);
-        break;
-      
-      default:
-        break;
-      }
-
-    // enable basic commands
-    this.enable_command('logout', true);
-
-    // flag object as complete
-    this.loaded = true;
-
-    // show message
-    if (this.pending_message)
-      this.display_message(this.pending_message[0], this.pending_message[1]);
-
-    // start keep-alive interval
-    this.start_keepalive();
-    
-    // execute all foreign onload scripts
-    for (var i=0; i<this.onloads.length; i++)
-      {
-      if (typeof(this.onloads[i]) == 'string')
-        eval(this.onloads[i]);
-      else if (typeof(this.onloads[i]) == 'function')
-        this.onloads[i]();
-      }
-    };
-
-  // start interval for keep-alive/recent_check signal
-  this.start_keepalive = function()
-    {
-    if (this.env.keep_alive && !this.env.framed && this.task=='mail' && this.gui_objects.mailboxlist)
-      this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000);
-    else if (this.env.keep_alive && !this.env.framed && this.task!='login')
-      this._int = setInterval(function(){ ref.send_keep_alive(); }, this.env.keep_alive * 1000);
-    }
-
-  this.init_message_row = function(row)
-  {
-    var uid = row.uid;
-    if (uid && this.env.messages[uid])
-      {
-      row.deleted = this.env.messages[uid].deleted ? true : false;
-      row.unread = this.env.messages[uid].unread ? true : false;
-      row.replied = this.env.messages[uid].replied ? true : false;
-      row.flagged = this.env.messages[uid].flagged ? true : false;
-      row.forwarded = this.env.messages[uid].forwarded ? true : false;
-      }
-
-    // set eventhandler to message icon
-    if ((row.icon = row.obj.cells[0].childNodes[0]) && row.icon.nodeName=='IMG')
-      {
-      var p = this;
-      row.icon.id = 'msgicn_'+row.uid;
-      row.icon._row = row.obj;
-      row.icon.onmousedown = function(e) { p.command('toggle_status', this); };
-      }
-
-    // global variable 'flagged_col' may be not defined yet
-    if (!this.env.flagged_col && this.env.coltypes)
-      {
-      var found;
-      if((found = find_in_array('flag', this.env.coltypes)) >= 0)
-          this.set_env('flagged_col', found+1);
-      }
-
-    // set eventhandler to flag icon, if icon found
-    if (this.env.flagged_col && (row.flagged_icon = row.obj.cells[this.env.flagged_col].childNodes[0]) 
-       && row.flagged_icon.nodeName=='IMG')
-      {
-      var p = this;
-      row.flagged_icon.id = 'flaggedicn_'+row.uid;
-      row.flagged_icon._row = row.obj;
-      row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); };
-      }
-  };
-
-  // init message compose form: set focus and eventhandlers
-  this.init_messageform = function()
-    {
-    if (!this.gui_objects.messageform)
-      return false;
-    
-    //this.messageform = this.gui_objects.messageform;
-    var input_from = rcube_find_object('_from');
-    var input_to = rcube_find_object('_to');
-    var input_cc = rcube_find_object('_cc');
-    var input_bcc = rcube_find_object('_bcc');
-    var input_replyto = rcube_find_object('_replyto');
-    var input_subject = rcube_find_object('_subject');
-    var input_message = rcube_find_object('_message');
-    var draftid = rcube_find_object('_draft_saveid');
-
-    // init live search events
-    if (input_to)
-      this.init_address_input_events(input_to);
-    if (input_cc)
-      this.init_address_input_events(input_cc);
-    if (input_bcc)
-      this.init_address_input_events(input_bcc);
-
-    // add signature according to selected identity
-    if (input_from && input_from.type=='select-one' && (!draftid || draftid.value=='')
-       // if we have HTML editor, signature is added in callback
-       && rcube_find_object('_is_html').value != '1')
-      {
-      this.change_identity(input_from);
-      }
-
-    if (input_to && input_to.value=='')
-      input_to.focus();
-    else if (input_subject && input_subject.value=='')
-      input_subject.focus();
-    else if (input_message)
-      this.set_caret2start(input_message);
-
-    // get summary of all field values
-    this.compose_field_hash(true);
-    // start the auto-save timer
-    this.auto_save_start();
-    };
-
-  this.init_address_input_events = function(obj)
-    {
-    var handler = function(e){ return ref.ksearch_keypress(e,this); };
-    
-    if (obj.addEventListener)
-      obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false);
-    else
-      obj.onkeydown = handler;
-
-    obj.setAttribute('autocomplete', 'off');
-    };
-
-
-  /*********************************************************/
-  /*********       client command interface        *********/
-  /*********************************************************/
-
-  // execute a specific command on the web client
-  this.command = function(command, props, obj)
-    {
-    if (obj && obj.blur)
-      obj.blur();
-
-    if (this.busy)
-      return false;
-
-    // command not supported or allowed
-    if (!this.commands[command])
-      {
-      // pass command to parent window
-      if (this.env.framed && parent.rcmail && parent.rcmail.command)
-        parent.rcmail.command(command, props);
-
-      return false;
-      }
-      
-   // check input before leaving compose step
-   if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings'))
-     {
-     if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
-        return false;
-     }
-
-    // process command
-    switch (command)
-      {
-      case 'login':
-        if (this.gui_objects.loginform)
-          this.gui_objects.loginform.submit();
-        break;
-
-      case 'logout':
-        this.goto_url('logout', '', true);
-        break;      
-
-      // commands to switch task
-      case 'mail':
-      case 'addressbook':
-      case 'settings':
-        this.switch_task(command);
-        break;
-
-      case 'permaurl':
-        if (obj && obj.href && obj.target)
-          return true;
-        else if (this.env.permaurl)
-          parent.location.href = this.env.permaurl;
-          break;
-
-      // misc list commands
-      case 'list':
-        if (this.task=='mail')
-          {
-          if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox)))
-            this.reset_qsearch();
-
-          this.list_mailbox(props);
-
-          if (this.env.trash_mailbox)
-            this.set_alttext('delete', this.env.mailbox != this.env.trash_mailbox ? 'movemessagetotrash' : 'deletemessage');
-          }
-        else if (this.task=='addressbook')
-          {
-          if (this.env.search_request<0 || (this.env.search_request && props != this.env.source))
-            this.reset_qsearch();
-
-          this.list_contacts(props);
-          this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly));
-          }
-        break;
-
-
-      case 'load-headers':
-        this.load_headers(obj);
-        break;
-
-
-      case 'sort':
-        // get the type of sorting
-        var a_sort = props.split('_');
-        var sort_col = a_sort[0];
-        var sort_order = a_sort[1] ? a_sort[1].toUpperCase() : null;
-        var header;
-
-        // no sort order specified: toggle
-        if (sort_order==null)
-          {
-          if (this.env.sort_col==sort_col)
-            sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
-          else
-            sort_order = this.env.sort_order;
-          }
-
-        if (this.env.sort_col==sort_col && this.env.sort_order==sort_order)
-          break;
-
-        // set table header class
-        if (header = document.getElementById('rcm'+this.env.sort_col))
-          this.set_classname(header, 'sorted'+(this.env.sort_order.toUpperCase()), false);
-        if (header = document.getElementById('rcm'+sort_col))
-          this.set_classname(header, 'sorted'+sort_order, true);
-
-        // save new sort properties
-        this.env.sort_col = sort_col;
-        this.env.sort_order = sort_order;
-
-        // reload message list
-        this.list_mailbox('', '', sort_col+'_'+sort_order);
-        break;
-
-      case 'nextpage':
-        this.list_page('next');
-        break;
-
-      case 'lastpage':
-        this.list_page('last');
-        break;
-
-      case 'previouspage':
-        this.list_page('prev');
-        break;
-
-      case 'firstpage':
-        this.list_page('first');
-        break;
-
-      case 'expunge':
-        if (this.env.messagecount)
-          this.expunge_mailbox(this.env.mailbox);
-        break;
-
-      case 'purge':
-      case 'empty-mailbox':
-        if (this.env.messagecount)
-          this.purge_mailbox(this.env.mailbox);
-        break;
-
-
-      // common commands used in multiple tasks
-      case 'show':
-        if (this.task=='mail')
-          {
-          var uid = this.get_single_uid();
-          if (uid && (!this.env.uid || uid != this.env.uid))
-            {
-            if (this.env.mailbox == this.env.drafts_mailbox)
-              this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
-            else
-              this.show_message(uid);
-            }
-          }
-        else if (this.task=='addressbook')
-          {
-          var cid = props ? props : this.get_single_cid();
-          if (cid && !(this.env.action=='show' && cid==this.env.cid))
-            this.load_contact(cid, 'show');
-          }
-        break;
-
-      case 'add':
-        if (this.task=='addressbook')
-          this.load_contact(0, 'add');
-        else if (this.task=='settings')
-          {
-          this.identity_list.clear_selection();
-          this.load_identity(0, 'add-identity');
-          }
-        break;
-
-      case 'edit':
-        var cid;
-        if (this.task=='addressbook' && (cid = this.get_single_cid()))
-          this.load_contact(cid, 'edit');
-        else if (this.task=='settings' && props)
-          this.load_identity(props, 'edit-identity');
-        break;
-
-      case 'save-identity':
-      case 'save':
-        if (this.gui_objects.editform)
-          {
-          var input_pagesize = rcube_find_object('_pagesize');
-          var input_name  = rcube_find_object('_name');
-          var input_email = rcube_find_object('_email');
-
-          // user prefs
-          if (input_pagesize && isNaN(parseInt(input_pagesize.value)))
-            {
-            alert(this.get_label('nopagesizewarning'));
-            input_pagesize.focus();
-            break;
-            }
-          // contacts/identities
-          else
-            {
-            if (input_name && input_name.value == '')
-              {
-              alert(this.get_label('nonamewarning'));
-              input_name.focus();
-              break;
-              }
-            else if (input_email && !rcube_check_email(input_email.value))
-              {
-              alert(this.get_label('noemailwarning'));
-              input_email.focus();
-              break;
-              }
-            }
-
-          this.gui_objects.editform.submit();
-          }
-        break;
-
-      case 'delete':
-        // mail task
-        if (this.task=='mail')
-          this.delete_messages();
-        // addressbook task
-        else if (this.task=='addressbook')
-          this.delete_contacts();
-        // user settings task
-        else if (this.task=='settings')
-          this.delete_identity();
-        break;
-
-
-      // mail task commands
-      case 'move':
-      case 'moveto':
-        if (this.task == 'mail')
-          this.move_messages(props);
-        else if (this.task == 'addressbook' && this.drag_active)
-          this.copy_contact(null, props);
-        break;
-
-      case 'mark':
-        if (props)
-          this.mark_message(props);
-        break;
-      
-      case 'toggle_status':
-        if (props && !props._row)
-          break;
-        
-        var uid;
-        var flag = 'read';
-        
-        if (props._row.uid)
-          {
-          uid = props._row.uid;
-          
-          // toggle read/unread
-          if (this.message_list.rows[uid].deleted) {
-            flag = 'undelete';
-          } else if (!this.message_list.rows[uid].unread)
-            flag = 'unread';
-          }
-          
-        this.mark_message(flag, uid);
-        break;
-        
-      case 'toggle_flag':
-        if (props && !props._row)
-          break;
-
-        var uid;
-        var flag = 'flagged';
-
-        if (props._row.uid)
-          {
-          uid = props._row.uid;
-          // toggle flagged/unflagged
-          if (this.message_list.rows[uid].flagged)
-            flag = 'unflagged';
-          }
-        this.mark_message(flag, uid);
-        break;
-
-      case 'always-load':
-        if (this.env.uid && this.env.sender) {
-          this.add_contact(urlencode(this.env.sender));
-          window.setTimeout(function(){ ref.command('load-images'); }, 300);
-          break;
-        }
-        
-      case 'load-images':
-        if (this.env.uid)
-          this.show_message(this.env.uid, true, this.env.action=='preview');
-        break;
-
-      case 'load-attachment':
-        var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part;
-        
-        // open attachment in frame if it's of a supported mimetype
-        if (this.env.uid && props.mimetype && find_in_array(props.mimetype, this.mimetypes)>=0)
-          {
-          if (props.mimetype == 'text/html')
-            qstring += '&_safe=1';
-          this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment');
-          if (this.attachment_win)
-            {
-            window.setTimeout(function(){ ref.attachment_win.focus(); }, 10);
-            break;
-            }
-          }
-
-        this.goto_url('get', qstring+'&_download=1', false);
-        break;
-        
-      case 'select-all':
-        this.message_list.select_all(props);
-        break;
-
-      case 'select-none':
-        this.message_list.clear_selection();
-        break;
-
-      case 'nextmessage':
-        if (this.env.next_uid)
-          this.show_message(this.env.next_uid, false, this.env.action=='preview');
-        break;
-
-      case 'lastmessage':
-        if (this.env.last_uid)
-          this.show_message(this.env.last_uid);
-        break;
-
-      case 'previousmessage':
-        if (this.env.prev_uid)
-          this.show_message(this.env.prev_uid, false, this.env.action=='preview');
-        break;
-
-      case 'firstmessage':
-        if (this.env.first_uid)
-          this.show_message(this.env.first_uid);
-        break;
-      
-      case 'checkmail':
-        this.check_for_recent(true);
-        break;
-      
-      case 'compose':
-        var url = this.env.comm_path+'&_action=compose';
-       
-        if (this.task=='mail')
-        {
-          url += '&_mbox='+urlencode(this.env.mailbox);
-          
-          if (this.env.mailbox==this.env.drafts_mailbox)
-          {
-            var uid;
-            if (uid = this.get_single_uid())
-              url += '&_draft_uid='+uid;
-          }
-          else if (props)
-             url += '&_to='+urlencode(props);
-        }
-        // modify url if we're in addressbook
-        else if (this.task=='addressbook')
-          {
-          // switch to mail compose step directly
-          if (props && props.indexOf('@') > 0)
-            {
-            url = this.get_task_url('mail', url);
-            this.redirect(url + '&_to='+urlencode(props));
-            break;
-            }
-          
-          // use contact_id passed as command parameter
-          var a_cids = new Array();
-          if (props)
-            a_cids[a_cids.length] = props;
-          // get selected contacts
-          else if (this.contact_list)
-            {
-            var selection = this.contact_list.get_selection();
-            for (var n=0; n<selection.length; n++)
-              a_cids[a_cids.length] = selection[n];
-            }
-            
-          if (a_cids.length)
-            this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
-
-          break;
-          }
-
-        // don't know if this is necessary...
-        url = url.replace(/&_framed=1/, "");
-
-        this.redirect(url);
-        break;
-        
-      case 'spellcheck':
-        if (window.tinyMCE && tinyMCE.get('compose-body')) {
-          tinyMCE.execCommand('mceSpellCheck', true);
-        }
-        else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) {
-          this.env.spellcheck.spellCheck(this.env.spellcheck.check_link);
-          this.set_spellcheck_state('checking');
-        }
-        break;
-
-      case 'savedraft':
-        // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
-
-        if (!this.gui_objects.messageform)
-          break;
-
-        // if saving Drafts is disabled in main.inc.php
-        // or if compose form did not change
-        if (!this.env.drafts_mailbox || this.cmp_hash == this.compose_field_hash())
-          break;
-
-        this.set_busy(true, 'savingmessage');
-        var form = this.gui_objects.messageform;
-        form.target = "savetarget";
-        form._draft.value = '1';
-        form.submit();
-        break;
-
-      case 'send':
-        if (!this.gui_objects.messageform)
-          break;
-
-        if (!this.check_compose_input())
-          break;
-
-        // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
-
-        // all checks passed, send message
-        this.set_busy(true, 'sendingmessage');
-        var form = this.gui_objects.messageform;
-        form.target = "savetarget";     
-        form._draft.value = '';
-        form.submit();
-        
-        // clear timeout (sending could take longer)
-        clearTimeout(this.request_timer);
-        break;
-
-      case 'add-attachment':
-        this.show_attachment_form(true);
-        
-      case 'send-attachment':
-        // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
-
-        this.upload_file(props)      
-        break;
-      
-      case 'remove-attachment':
-        this.remove_attachment(props);
-        break;
-
-      case 'reply-all':
-      case 'reply':
-        var uid;
-        if (uid = this.get_single_uid())
-          this.goto_url('compose', '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''), true);
-        break;      
-
-      case 'forward':
-        var uid;
-        if (uid = this.get_single_uid())
-          this.goto_url('compose', '_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
-        break;
-        
-      case 'print':
-        var uid;
-        if (uid = this.get_single_uid())
-        {
-          ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''));
-          if (this.printwin)
-          {
-            window.setTimeout(function(){ ref.printwin.focus(); }, 20);
-            if (this.env.action != 'show')
-              this.mark_message('read', uid);
-          }
-        }
-        break;
-
-      case 'viewsource':
-        var uid;
-        if (uid = this.get_single_uid())
-          {
-          ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox));
-          if (this.sourcewin)
-            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
-          }
-        break;
-
-      case 'add-contact':
-        this.add_contact(props);
-        break;
-      
-      // quicksearch
-      case 'search':
-        if (!props && this.gui_objects.qsearchbox)
-          props = this.gui_objects.qsearchbox.value;
-        if (props)
-        {
-          this.qsearch(props);
-          break;
-        }
-
-      // reset quicksearch
-      case 'reset-search':
-        var s = this.env.search_request;
-        this.reset_qsearch();
-        
-        if (s && this.env.mailbox)
-          this.list_mailbox(this.env.mailbox);
-        else if (s && this.task == 'addressbook')
-          this.list_contacts(this.env.source);
-        break;
-
-      case 'import':
-        if (this.env.action == 'import' && this.gui_objects.importform) {
-          var file = document.getElementById('rcmimportfile');
-          if (file && !file.value) {
-            alert(this.get_label('selectimportfile'));
-            break;
-          }
-          this.gui_objects.importform.submit();
-          this.set_busy(true, 'importwait');
-          this.lock_form(this.gui_objects.importform, true);
-        }
-        else
-          this.goto_url('import');
-        break;
-        
-      case 'export':
-        if (this.contact_list.rowcount > 0) {
-          var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : '');
-          if (this.env.search_request)
-            add_url += '_search='+this.env.search_request;
-        
-          this.goto_url('export', add_url);
-        }
-        break;
-
-      // collapse/expand folder
-      case 'collapse-folder':
-        if (props)
-          this.collapse_folder(props);
-        break;
-
-      // user settings commands
-      case 'preferences':
-        this.goto_url('');
-        break;
-
-      case 'identities':
-        this.goto_url('identities');
-        break;
-          
-      case 'delete-identity':
-        this.delete_identity();
-        
-      case 'folders':
-        this.goto_url('folders');
-        break;
-
-      case 'subscribe':
-        this.subscribe_folder(props);
-        break;
-
-      case 'unsubscribe':
-        this.unsubscribe_folder(props);
-        break;
-        
-      case 'create-folder':
-        this.create_folder(props);
-        break;
-
-      case 'rename-folder':
-        this.rename_folder(props);
-        break;
-
-      case 'delete-folder':
-        this.delete_folder(props);
-        break;
-
-      }
-
-    return obj ? false : true;
-    };
-
-  // set command enabled or disabled
-  this.enable_command = function()
-    {
-    var args = arguments;
-    if(!args.length) return -1;
-
-    var command;
-    var enable = args[args.length-1];
-    
-    for(var n=0; n<args.length-1; n++)
-      {
-      command = args[n];
-      this.commands[command] = enable;
-      this.set_button(command, (enable ? 'act' : 'pas'));
-      }
-      return true;
-    };
-
-  // lock/unlock interface
-  this.set_busy = function(a, message)
-    {
-    if (a && message)
-      {
-      var msg = this.get_label(message);
-      if (msg==message)        
-        msg = 'Loading...';
-
-      this.display_message(msg, 'loading', true);
-      }
-    else if (!a)
-      this.hide_message();
-
-    this.busy = a;
-    //document.body.style.cursor = a ? 'wait' : 'default';
-    
-    if (this.gui_objects.editform)
-      this.lock_form(this.gui_objects.editform, a);
-      
-    // clear pending timer
-    if (this.request_timer)
-      clearTimeout(this.request_timer);
-
-    // set timer for requests
-    if (a && this.env.request_timeout)
-      this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000);
-    };
-
-  // return a localized string
-  this.get_label = function(name)
-    {
-    if (this.labels[name])
-      return this.labels[name];
-    else
-      return name;
-    };
-
-  // switch to another application task
-  this.switch_task = function(task)
-    {
-    if (this.task===task && task!='mail')
-      return;
-
-    var url = this.get_task_url(task);
-    if (task=='mail')
-      url += '&_mbox=INBOX';
-
-    this.redirect(url);
-    };
-
-  this.get_task_url = function(task, url)
-    {
-    if (!url)
-      url = this.env.comm_path;
-
-    return url.replace(/_task=[a-z]+/, '_task='+task);
-    };
-    
-  // called when a request timed out
-  this.request_timed_out = function()
-    {
-    this.set_busy(false);
-    this.display_message('Request timed out!', 'error');
-    };
-
-
-  /*********************************************************/
-  /*********        event handling methods         *********/
-  /*********************************************************/
-
-  this.doc_mouse_up = function(e)
-  {
-    var model, li;
-    
-    if (this.message_list) {
-      this.message_list.blur();
-      model = this.env.mailboxes;
-    }
-    else if (this.contact_list) {
-      this.contact_list.blur();
-      model = this.env.address_sources;
-    }
-    else if (this.ksearch_value) {
-      this.ksearch_blur();
-    }
-    
-    // handle mouse release when dragging
-    if (this.drag_active && model && this.env.last_folder_target) {
-      this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false);
-      this.command('moveto', model[this.env.last_folder_target].id);
-      this.env.last_folder_target = null;
-    }
-  };
-
-  this.drag_start = function(list)
-  {
-    var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources;
-
-    this.drag_active = true;
-    if (this.preview_timer)
-      clearTimeout(this.preview_timer);
-    
-    // save folderlist and folders location/sizes for droptarget calculation in drag_move()
-    if (this.gui_objects.folderlist && model)
-      {
-      var li, pos, list, height;
-      list = rcube_find_object(this.task == 'mail' ? 'mailboxlist' : 'directorylist');
-      pos = rcube_get_object_pos(list);
-      this.env.folderlist_coords = {x1:pos.x, y1:pos.y, x2:pos.x + list.offsetWidth, y2:pos.y + list.offsetHeight};
-
-      this.env.folder_coords = new Array();
-      for (var k in model) {
-        if (li = this.get_folder_li(k))
-         {
-         pos = rcube_get_object_pos(li.firstChild);
-         // only visible folders
-         if (height = li.firstChild.offsetHeight)
-           this.env.folder_coords[k] = {x1:pos.x, y1:pos.y, x2:pos.x + li.firstChild.offsetWidth, y2:pos.y + height};
-          }
-        }
-      }
-  };
-
-  this.drag_move = function(e)
-    {
-    if (this.gui_objects.folderlist && this.env.folder_coords)
-      {
-      var li, pos, mouse;
-      mouse = rcube_event.get_mouse_pos(e);
-      pos = this.env.folderlist_coords;
-
-      // if mouse pointer is outside of folderlist
-      if (mouse.x < pos.x1 || mouse.x >= pos.x2 
-           || mouse.y < pos.y1 || mouse.y >= pos.y2)
-       {
-       if (this.env.last_folder_target) {
-         this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false);
-          this.env.last_folder_target = null;
-         }
-       return;
-        }
-
-      // over the folders
-      for (var k in this.env.folder_coords)
-        {
-       pos = this.env.folder_coords[k];
-       if (this.check_droptarget(k) && ((mouse.x >= pos.x1) && (mouse.x < pos.x2) 
-           && (mouse.y >= pos.y1) && (mouse.y < pos.y2)))
-         {
-          this.set_classname(this.get_folder_li(k), 'droptarget', true);
-         this.env.last_folder_target = k;
-         }
-       else
-         this.set_classname(this.get_folder_li(k), 'droptarget', false);
-        }
-      }
-    };
-  
-  this.collapse_folder = function(id)
-    {
-    var div;
-    if ((li = this.get_folder_li(id)) &&
-        (div = li.getElementsByTagName("div")[0]) &&
-        (div.className.match(/collapsed/) || div.className.match(/expanded/)))
-      {
-      var ul = li.getElementsByTagName("ul")[0];
-      if (div.className.match(/collapsed/))
-        {
-        ul.style.display = '';
-        this.set_classname(div, 'collapsed', false);
-        this.set_classname(div, 'expanded', true);
-        var reg = new RegExp('&'+urlencode(id)+'&');
-        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
-        }
-      else
-        {
-        ul.style.display = 'none';
-        this.set_classname(div, 'expanded', false);
-        this.set_classname(div, 'collapsed', true);
-        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&');
-
-        // select parent folder if one of its childs is currently selected
-        if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
-          this.command('list', id);
-        }
-
-      // Work around a bug in IE6 and IE7, see #1485309
-      if ((bw.ie6 || bw.ie7) &&
-          li.nextSibling &&
-          (li.nextSibling.getElementsByTagName("ul").length>0) &&
-          li.nextSibling.getElementsByTagName("ul")[0].style &&
-          (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none'))
-        {
-          li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none';
-          li.nextSibling.getElementsByTagName("ul")[0].style.display = '';
-        }
-
-      this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders));
-      this.set_unread_count_display(id, false);
-      }
-    }
-
-  this.click_on_list = function(e)
-    {
-    if (this.message_list)
-      this.message_list.focus();
-    else if (this.contact_list)
-        this.contact_list.focus();
-
-    var mbox_li;
-    if (mbox_li = this.get_folder_li())
-      this.set_classname(mbox_li, 'unfocused', true);
-
-    return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e);
-    };
-
-  this.msglist_select = function(list)
-    {
-    if (this.preview_timer)
-      clearTimeout(this.preview_timer);
-
-    var selected = list.selection.length==1;
-
-    // Hide certain command buttons when Drafts folder is selected
-    if (this.env.mailbox == this.env.drafts_mailbox)
-      {
-      this.enable_command('reply', 'reply-all', 'forward', false);
-      this.enable_command('show', 'print', selected);
-      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
-      }
-    else
-      {
-      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', selected);
-      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
-      }
-
-    // start timer for message preview (wait for double click)
-    if (selected && this.env.contentframe && !list.multi_selecting)
-      this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200);
-    else if (this.env.contentframe)
-      this.show_contentframe(false);
-    };
-
-  this.msglist_dbl_click = function(list)
-    {
-      if (this.preview_timer)
-        clearTimeout(this.preview_timer);
-
-    var uid = list.get_single_selection();
-    if (uid && this.env.mailbox == this.env.drafts_mailbox)
-      this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
-    else if (uid)
-      this.show_message(uid, false, false);
-    };
-
-  this.msglist_keypress = function(list)
-    {
-    if (list.key_pressed == list.ENTER_KEY)
-      this.command('show');
-    else if (list.key_pressed == list.DELETE_KEY)
-      this.command('delete');
-    else if (list.key_pressed == list.BACKSPACE_KEY)
-      this.command('delete');
-    else
-      list.shiftkey = false;
-    };
-
-  this.msglist_get_preview = function()
-  {
-    var uid = this.get_single_uid();
-    if (uid && this.env.contentframe && !this.drag_active)
-      this.show_message(uid, false, true);
-    else if (this.env.contentframe)
-      this.show_contentframe(false);
-  };
-  
-  this.check_droptarget = function(id)
-  {
-    if (this.task == 'mail')
-      return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual);
-    else if (this.task == 'addressbook')
-      return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly);
-    else if (this.task == 'settings')
-      return (id != this.env.folder);
-  };
-
-
-  /*********************************************************/
-  /*********     (message) list functionality      *********/
-  /*********************************************************/
-
-  // when user doble-clicks on a row
-  this.show_message = function(id, safe, preview)
-    {
-    if (!id) return;
-    
-    var add_url = '';
-    var action = preview ? 'preview': 'show';
-    var target = window;
-    
-    if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      target = window.frames[this.env.contentframe];
-      add_url = '&_framed=1';
-      }
-
-    if (safe)
-      add_url = '&_safe=1';
-
-    // also send search request to get the right messages
-    if (this.env.search_request)
-      add_url += '&_search='+this.env.search_request;
-    var url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url;
-    if (action == 'preview' && String(target.location.href).indexOf(url) >= 0)
-      this.show_contentframe(true);
-    else
-      {
-      this.set_busy(true, 'loading');
-      target.location.href = this.env.comm_path+url;
-      // mark as read and change mbox unread counter
-      if (action == 'preview' && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread)
-        {
-        this.set_message(id, 'unread', false);
-       if (this.env.unread_counts[this.env.mailbox])
-         {
-         this.env.unread_counts[this.env.mailbox] -= 1;
-         this.set_unread_count(this.env.mailbox, this.env.unread_counts[this.env.mailbox], this.env.mailbox == 'INBOX');
-         }
-       }
-      }
-    };
-
-  this.show_contentframe = function(show)
-    {
-    var frm;
-    if (this.env.contentframe && (frm = rcube_find_object(this.env.contentframe)))
-      {
-      if (!show && window.frames[this.env.contentframe])
-        {
-        if (window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0)
-          window.frames[this.env.contentframe].location.href = this.env.blankpage;
-        }
-      else if (!bw.safari)
-        frm.style.display = show ? 'block' : 'none';
-      }
-      
-    if (!show && this.busy)
-      this.set_busy(false);
-    };
-
-  // list a specific page
-  this.list_page = function(page)
-    {
-    if (page=='next')
-      page = this.env.current_page+1;
-    if (page=='last')
-      page = this.env.pagecount;
-    if (page=='prev' && this.env.current_page>1)
-      page = this.env.current_page-1;
-    if (page=='first' && this.env.current_page>1)
-      page = 1;
-      
-    if (page > 0 && page <= this.env.pagecount)
-      {
-      this.env.current_page = page;
-      
-      if (this.task=='mail')
-        this.list_mailbox(this.env.mailbox, page);
-      else if (this.task=='addressbook')
-        this.list_contacts(this.env.source, page);
-      }
-    };
-
-  // list messages of a specific mailbox using filter
-  this.filter_mailbox = function(filter)
-    {
-      var search;
-      if (this.gui_objects.qsearchbox)
-        search = this.gui_objects.qsearchbox.value;
-      
-      this.message_list.clear();
-
-      // reset vars
-      this.env.current_page = 1;
-      this.set_busy(true, 'searching');
-      this.http_request('search', '_filter='+filter
-           + (search ? '&_q='+urlencode(search) : '')
-           + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true);
-    }
-
-
-  // list messages of a specific mailbox
-  this.list_mailbox = function(mbox, page, sort)
-    {
-    this.last_selected = 0;
-    var add_url = '';
-    var target = window;
-
-    if (!mbox)
-      mbox = this.env.mailbox;
-
-    // add sort to url if set
-    if (sort)
-      add_url += '&_sort=' + sort;
-
-    // also send search request to get the right messages
-    if (this.env.search_request)
-      add_url += '&_search='+this.env.search_request;
-      
-    // set page=1 if changeing to another mailbox
-    if (!page && mbox != this.env.mailbox)
-      {
-      page = 1;
-      this.env.current_page = page;
-      if (this.message_list)
-        this.message_list.clear_selection();
-      this.show_contentframe(false);
-      }
-    
-    if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
-      add_url += '&_refresh=1';
-    
-    this.select_folder(mbox, this.env.mailbox);
-    this.env.mailbox = mbox;
-
-    // load message list remotely
-    if (this.gui_objects.messagelist)
-      {
-      this.list_mailbox_remote(mbox, page, add_url);
-      return;
-      }
-    
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      target = window.frames[this.env.contentframe];
-      add_url += '&_framed=1';
-      }
-
-    // load message list to target frame/window
-    if (mbox)
-      {
-      this.set_busy(true, 'loading');
-      target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url;
-      }
-    };
-
-  // send remote request to load message list
-  this.list_mailbox_remote = function(mbox, page, add_url)
-    {
-    // clear message list first
-    this.message_list.clear();
-
-    // send request to server
-    var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : '');
-    this.set_busy(true, 'loading');
-    this.http_request('list', url+add_url, true);
-    };
-
-  this.expunge_mailbox = function(mbox)
-    {
-    var lock = false;
-    var add_url = '';
-    
-    // lock interface if it's the active mailbox
-    if (mbox == this.env.mailbox)
-       {
-       lock = true;
-       this.set_busy(true, 'loading');
-       add_url = '&_reload=1';
-       }
-
-    // send request to server
-    var url = '_mbox='+urlencode(mbox);
-    this.http_post('expunge', url+add_url, lock);
-    };
-
-  this.purge_mailbox = function(mbox)
-    {
-    var lock = false;
-    var add_url = '';
-    
-    if (!confirm(this.get_label('purgefolderconfirm')))
-      return false;
-    
-    // lock interface if it's the active mailbox
-    if (mbox == this.env.mailbox)
-       {
-       lock = true;
-       this.set_busy(true, 'loading');
-       add_url = '&_reload=1';
-       }
-
-    // send request to server
-    var url = '_mbox='+urlencode(mbox);
-    this.http_post('purge', url+add_url, lock);
-    return true;
-    };
-
-  // test if purge command is allowed
-  this.purge_mailbox_test = function()
-  {
-    return (this.env.messagecount && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox 
-      || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter)) 
-      || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter))));
-  };
-
-  // set message icon
-  this.set_message_icon = function(uid)
-  {
-    var icn_src;
-    var rows = this.message_list.rows;
-
-    if (!rows[uid])
-      return false;
-
-    if (rows[uid].deleted && this.env.deletedicon)
-      icn_src = this.env.deletedicon;
-    else if (rows[uid].replied && this.env.repliedicon)
-      {
-      if (rows[uid].forwarded && this.env.forwardedrepliedicon)
-        icn_src = this.env.forwardedrepliedicon;
-      else
-        icn_src = this.env.repliedicon;
-      }
-    else if (rows[uid].forwarded && this.env.forwardedicon)
-      icn_src = this.env.forwardedicon;
-    else if (rows[uid].unread && this.env.unreadicon)
-      icn_src = this.env.unreadicon;
-    else if (this.env.messageicon)
-      icn_src = this.env.messageicon;
-      
-    if (icn_src && rows[uid].icon)
-      rows[uid].icon.src = icn_src;
-
-    icn_src = '';
-    
-    if (rows[uid].flagged && this.env.flaggedicon)
-      icn_src = this.env.flaggedicon;
-    else if (!rows[uid].flagged && this.env.unflaggedicon)
-      icn_src = this.env.unflaggedicon;
-
-    if (rows[uid].flagged_icon && icn_src)
-      rows[uid].flagged_icon.src = icn_src;
-  }
-
-  // set message status
-  this.set_message_status = function(uid, flag, status)
-    {
-    var rows = this.message_list.rows;
-
-    if (!rows[uid]) return false;
-
-    if (flag == 'unread')
-      rows[uid].unread = status;
-    else if(flag == 'deleted')
-      rows[uid].deleted = status;
-    else if (flag == 'replied')
-      rows[uid].replied = status;
-    else if (flag == 'forwarded')
-      rows[uid].forwarded = status;
-    else if (flag == 'flagged')
-      rows[uid].flagged = status;
-
-    this.env.messages[uid] = rows[uid];
-    }
-
-  // set message row status, class and icon
-  this.set_message = function(uid, flag, status)
-    {
-    var rows = this.message_list.rows;
-
-    if (!rows[uid]) return false;
-    
-    if (flag)
-      this.set_message_status(uid, flag, status);
-    
-    if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0)
-      {
-      rows[uid].classname += ' unread';
-      this.set_classname(rows[uid].obj, 'unread', true);
-      }
-    else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*unread/, '');
-      this.set_classname(rows[uid].obj, 'unread', false);
-      }
-    
-    if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0)
-      {
-      rows[uid].classname += ' deleted';
-      this.set_classname(rows[uid].obj, 'deleted', true);
-      }
-    else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
-      this.set_classname(rows[uid].obj, 'deleted', false);
-      }
-
-    if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0)
-      {
-      rows[uid].classname += ' flagged';
-      this.set_classname(rows[uid].obj, 'flagged', true);
-      }
-    else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, '');
-      this.set_classname(rows[uid].obj, 'flagged', false);
-      }
-
-    this.set_message_icon(uid);
-    }
-
-  // move selected messages to the specified mailbox
-  this.move_messages = function(mbox)
-    {
-    // exit if current or no mailbox specified or if selection is empty
-    if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)))
-      return;
-
-    var lock = false;
-    var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : '');
-
-    // show wait message
-    if (this.env.action=='show')
-      {
-      lock = true;
-      this.set_busy(true, 'movingmessage');
-      }
-    else if (!this.env.flag_for_deletion)
-      this.show_contentframe(false);
-
-    // Hide message command buttons until a message is selected
-    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', false);
-
-    this._with_selected_messages('moveto', lock, add_url, (this.env.flag_for_deletion ? false : true));
-    };
-
-  // delete selected messages from the current mailbox
-  this.delete_messages = function()
-    {
-    var selection = this.message_list ? this.message_list.get_selection() : new Array();
-
-    // exit if no mailbox specified or if selection is empty
-    if (!this.env.uid && !selection.length)
-        return;
-
-    // if there is a trash mailbox defined and we're not currently in it:
-    if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() != String(this.env.trash_mailbox).toLowerCase())
-      {
-      // if shift was pressed delete it immediately
-      if (this.message_list && this.message_list.shiftkey)
-        {
-        if (confirm(this.get_label('deletemessagesconfirm')))
-          this.permanently_remove_messages();
-        }
-      else
-        this.move_messages(this.env.trash_mailbox);
-      }
-    // if there is a trash mailbox defined but we *are* in it:
-    else if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase())
-      this.permanently_remove_messages();
-    // if there isn't a defined trash mailbox and the config is set to flag for deletion
-    else if (!this.env.trash_mailbox && this.env.flag_for_deletion)
-      {
-      this.mark_message('delete');
-      if(this.env.action=="show")
-        this.command('nextmessage','',this);
-      else if (selection.length == 1)
-        this.message_list.select_next();
-      }
-    // if there isn't a defined trash mailbox and the config is set NOT to flag for deletion
-    else if (!this.env.trash_mailbox) 
-      this.permanently_remove_messages();
-  };
-
-  // delete the selected messages permanently
-  this.permanently_remove_messages = function()
-    {
-    // exit if no mailbox specified or if selection is empty
-    if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))
-      return;
-      
-    this.show_contentframe(false);
-    this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''), true);
-    };
-
-  // Send a specifc request with UIDs of all selected messages
-  // @private
-  this._with_selected_messages = function(action, lock, add_url, remove)
-  {
-    var a_uids = new Array();
-
-    if (this.env.uid)
-      a_uids[0] = this.env.uid;
-    else
-    {
-      var selection = this.message_list.get_selection();
-      var rows = this.message_list.rows;
-      var id;
-      for (var n=0; n<selection.length; n++)
-        {
-        id = selection[n];
-        a_uids[a_uids.length] = id;
-
-        if (remove)
-          this.message_list.remove_row(id, (n == selection.length-1));
-        else
-        {
-          this.set_message_status(id, 'deleted', true);
-          if (this.env.read_when_deleted)
-           this.set_message_status(id, 'unread', false);
-         this.set_message(id);
-        }
-      }
-    }
-
-    // also send search request to get the right messages 
-    if (this.env.search_request) 
-      add_url += '&_search='+this.env.search_request;
-
-    // send request to server
-    this.http_post(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock);
-  };
-
-  // set a specific flag to one or more messages
-  this.mark_message = function(flag, uid)
-    {
-    var a_uids = new Array();
-    var r_uids = new Array();
-    var selection = this.message_list ? this.message_list.get_selection() : new Array();
-
-    if (uid)
-      a_uids[0] = uid;
-    else if (this.env.uid)
-      a_uids[0] = this.env.uid;
-    else if (this.message_list)
-      {
-      for (var n=0; n<selection.length; n++)
-        {
-          a_uids[a_uids.length] = selection[n];
-        }
-      }
-
-    if (!this.message_list)
-      r_uids = a_uids;
-    else
-      for (var id, n=0; n<a_uids.length; n++)
-      {
-        id = a_uids[n];
-        if ((flag=='read' && this.message_list.rows[id].unread) 
-            || (flag=='unread' && !this.message_list.rows[id].unread)
-            || (flag=='delete' && !this.message_list.rows[id].deleted)
-            || (flag=='undelete' && this.message_list.rows[id].deleted)
-            || (flag=='flagged' && !this.message_list.rows[id].flagged)
-            || (flag=='unflagged' && this.message_list.rows[id].flagged))
-        {
-          r_uids[r_uids.length] = id;
-        }
-      }
-
-    // nothing to do
-    if (!r_uids.length)
-      return;
-
-    switch (flag)
-      {
-        case 'read':
-        case 'unread':
-          this.toggle_read_status(flag, r_uids);
-          break;
-        case 'delete':
-        case 'undelete':
-          this.toggle_delete_status(r_uids);
-          break;
-        case 'flagged':
-        case 'unflagged':
-          this.toggle_flagged_status(flag, a_uids);
-          break;
-      }
-    };
-
-  // set class to read/unread
-  this.toggle_read_status = function(flag, a_uids)
-  {
-    // mark all message rows as read/unread
-    for (var i=0; i<a_uids.length; i++)
-      this.set_message(a_uids[i], 'unread', (flag=='unread' ? true : false));
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
-  };
-
-  // set image to flagged or unflagged
-  this.toggle_flagged_status = function(flag, a_uids)
-  {
-    // mark all message rows as flagged/unflagged
-    for (var i=0; i<a_uids.length; i++)
-      this.set_message(a_uids[i], 'flagged', (flag=='flagged' ? true : false));
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
-  };
-  
-  // mark all message rows as deleted/undeleted
-  this.toggle_delete_status = function(a_uids)
-  {
-    var rows = this.message_list ? this.message_list.rows : new Array();
-    
-    if (a_uids.length==1)
-    {
-      if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted))
-        this.flag_as_deleted(a_uids);
-      else
-        this.flag_as_undeleted(a_uids);
-
-      return true;
-    }
-    
-    var all_deleted = true;
-    for (var i=0; i<a_uids.length; i++)
-    {
-      uid = a_uids[i];
-      if (rows[uid]) {
-        if (!rows[uid].deleted)
-        {
-          all_deleted = false;
-          break;
-        }
-      }
-    }
-    
-    if (all_deleted)
-      this.flag_as_undeleted(a_uids);
-    else
-      this.flag_as_deleted(a_uids);
-    
-    return true;
-  };
-
-  this.flag_as_undeleted = function(a_uids)
-  {
-    for (var i=0; i<a_uids.length; i++)
-      this.set_message(a_uids[i], 'deleted', false);
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=undelete');
-    return true;
-  };
-
-  this.flag_as_deleted = function(a_uids)
-  {
-    var add_url = '';
-    var r_uids = new Array();
-    var rows = this.message_list ? this.message_list.rows : new Array();
-    
-    for (var i=0; i<a_uids.length; i++)
-      {
-      uid = a_uids[i];
-      if (rows[uid])
-        {
-       this.set_message(uid, 'deleted', true);
-        if (rows[uid].unread)
-          r_uids[r_uids.length] = uid;
-        }
-      }
-
-    if (r_uids.length)
-      add_url = '&_ruid='+r_uids.join(',');
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=delete'+add_url);
-    return true;  
-  };
-
-  // flag as read without mark request (called from backend)
-  // argument should be a coma-separated list of uids
-  this.flag_deleted_as_read = function(uids)
-  {
-    var icn_src;
-    var rows = this.message_list ? this.message_list.rows : new Array();
-    var str = String(uids);
-    var a_uids = new Array();
-
-    a_uids = str.split(',');
-
-    for (var uid, i=0; i<a_uids.length; i++)
-      {
-      uid = a_uids[i];
-      if (rows[uid])
-        this.set_message(uid, 'unread', false);
-      }
-  };
-  
-  
-  /*********************************************************/
-  /*********           login form methods          *********/
-  /*********************************************************/
-
-  // handler for keyboard events on the _user field
-  this.login_user_keyup = function(e)
-  {
-    var key = rcube_event.get_keycode(e);
-    var elm;
-
-    // enter
-    if ((key==13) && (elm = rcube_find_object('_pass')))
-    {
-      elm.focus();
-      return false;
-    }
-  };
-
-
-  /*********************************************************/
-  /*********        message compose methods        *********/
-  /*********************************************************/
-  
-  // checks the input fields before sending a message
-  this.check_compose_input = function()
-    {
-    // check input fields
-    var input_to = rcube_find_object('_to');
-    var input_cc = rcube_find_object('_cc');
-    var input_bcc = rcube_find_object('_bcc');
-    var input_from = rcube_find_object('_from');
-    var input_subject = rcube_find_object('_subject');
-    var input_message = rcube_find_object('_message');
-
-    // check sender (if have no identities)
-    if (input_from.type == 'text' && !rcube_check_email(input_from.value, true))
-      {
-      alert(this.get_label('nosenderwarning'));
-      input_from.focus();
-      return false;
-      }
-
-    // check for empty recipient
-    var recipients = input_to.value ? input_to.value : (input_cc.value ? input_cc.value : input_bcc.value);
-    if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true))
-      {
-      alert(this.get_label('norecipientwarning'));
-      input_to.focus();
-      return false;
-      }
-
-    // display localized warning for missing subject
-    if (input_subject && input_subject.value == '')
-      {
-      var subject = prompt(this.get_label('nosubjectwarning'), this.get_label('nosubject'));
-
-      // user hit cancel, so don't send
-      if (!subject && subject !== '')
-        {
-        input_subject.focus();
-        return false;
-        }
-      else
-        {
-        input_subject.value = subject ? subject : this.get_label('nosubject');            
-        }
-      }
-
-    // check for empty body
-    if ((!window.tinyMCE || !tinyMCE.get('compose-body')) && input_message.value == '' && !confirm(this.get_label('nobodywarning')))
-      {
-      input_message.focus();
-      return false;
-      }
-    else if (window.tinyMCE && tinyMCE.get('compose-body') && !tinyMCE.get('compose-body').getContent() && !confirm(this.get_label('nobodywarning')))
-      {
-      tinyMCE.get('compose-body').focus();
-      return false;
-      }
-
-    // Apply spellcheck changes if spell checker is active
-    this.stop_spellchecking();
-
-    return true;
-    };
-
-  this.stop_spellchecking = function()
-    {
-    if (this.env.spellcheck && !this.spellcheck_ready) {
-      exec_event(this.env.spellcheck.check_link, 'click');
-      this.set_spellcheck_state('ready');
-      }
-    };
-
-  this.display_spellcheck_controls = function(vis)
-    {
-    if (this.env.spellcheck) {
-      // stop spellchecking process
-      if (!vis)
-       this.stop_spellchecking();
-                             
-      this.env.spellcheck.check_link.style.visibility = vis ? 'visible' : 'hidden';
-      this.env.spellcheck.switch_lan_pic.style.visibility = vis ? 'visible' : 'hidden';
-      }
-    };
-
-  this.set_spellcheck_state = function(s)
-    {
-    this.spellcheck_ready = (s=='check_spelling' || s=='ready');
-    this.enable_command('spellcheck', this.spellcheck_ready);
-    };
-
-  this.set_draft_id = function(id)
-    {
-    var f;
-    if (f = rcube_find_object('_draft_saveid'))
-      f.value = id;
-    };
-
-  this.auto_save_start = function()
-    {
-    if (this.env.draft_autosave)
-      this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
-
-    // Unlock interface now that saving is complete
-    this.busy = false;
-    };
-
-  this.compose_field_hash = function(save)
-    {
-    // check input fields
-    var input_to = rcube_find_object('_to');
-    var input_cc = rcube_find_object('_cc');
-    var input_bcc = rcube_find_object('_bcc');
-    var input_subject = rcube_find_object('_subject');
-    var editor, input_message;
-    var str = '';
-    
-    if (input_to && input_to.value)
-      str += input_to.value+':';
-    if (input_cc && input_cc.value)
-      str += input_cc.value+':';
-    if (input_bcc && input_bcc.value)
-      str += input_bcc.value+':';
-    if (input_subject && input_subject.value)
-      str += input_subject.value+':';
-    
-    if (editor = tinyMCE.get('compose-body'))
-      str += editor.getContent();
-    else
-      {
-      input_message = rcube_find_object('_message');
-      str += input_message.value;
-      }
-    
-    if (save)
-      this.cmp_hash = str;
-    
-    return str;
-    };
-    
-  this.change_identity = function(obj)
-    {
-    if (!obj || !obj.options)
-      return false;
-
-    var id = obj.options[obj.selectedIndex].value;
-    var input_message = rcube_find_object('_message');
-    var message = input_message ? input_message.value : '';
-    var is_html = (rcube_find_object('_is_html').value == '1');
-    var sig, p;
-
-    if (!this.env.identity)
-      this.env.identity = id
-  
-    if (!is_html)
-      {
-      // remove the 'old' signature
-      if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
-        {
-        if (this.env.signatures[this.env.identity]['is_html'])
-          sig = this.env.signatures[this.env.identity]['plain_text'];
-        else
-         sig = this.env.signatures[this.env.identity]['text'];
-        
-       if (sig.indexOf('-- ')!=0)
-          sig = '-- \n'+sig;
-
-        p = message.lastIndexOf(sig);
-        if (p>=0)
-          message = message.substring(0, p-1) + message.substring(p+sig.length, message.length);
-        }
-
-      message = message.replace(/[\r\n]+$/, '');
-      
-      // add the new signature string
-      if (this.env.signatures && this.env.signatures[id])
-        {
-        sig = this.env.signatures[id]['text'];
-        if (this.env.signatures[id]['is_html'])
-          {
-          sig = this.env.signatures[id]['plain_text'];
-          }
-        if (sig.indexOf('-- ')!=0)
-          sig = '-- \n'+sig;
-        message += '\n\n'+sig;
-        }
-      }
-    else
-      {
-      var editor = tinyMCE.get('compose-body');
-
-      if (this.env.signatures)
-        {
-        // Append the signature as a div within the body
-        var sigElem = editor.dom.get('_rc_sig');
-       var newsig = '';
-       var htmlsig = true;
-
-        if (!sigElem)
-          {
-         // add empty line before signature on IE
-         if (bw.ie)
-            editor.getBody().appendChild(editor.getDoc().createElement('br'));
-
-         sigElem = editor.getDoc().createElement('div');
-          sigElem.setAttribute('id', '_rc_sig');
-          editor.getBody().appendChild(sigElem);
-          }
-
-       if (this.env.signatures[id])
-         {
-         newsig = this.env.signatures[id]['text'];
-         htmlsig = this.env.signatures[id]['is_html'];
-         }
-
-        if (htmlsig)
-          sigElem.innerHTML = newsig;
-        else
-          sigElem.innerHTML = '<pre>' + newsig + '</pre>';
-        }
-      }
-
-    if (input_message)
-      input_message.value = message;
-
-    this.env.identity = id;
-    return true;
-    };
-
-  this.show_attachment_form = function(a)
-    {
-    if (!this.gui_objects.uploadbox)
-      return false;
-      
-    var elm, list;
-    if (elm = this.gui_objects.uploadbox)
-      {
-      if (a &&  (list = this.gui_objects.attachmentlist))
-        {
-        var pos = rcube_get_object_pos(list);
-        var left = pos.x;
-        var top = pos.y + list.offsetHeight + 10;
-      
-        elm.style.top = top+'px';
-        elm.style.left = left+'px';
-        }
-      
-      elm.style.visibility = a ? 'visible' : 'hidden';
-      }
-      
-    // clear upload form
-       try {
-      if (!a && this.gui_objects.attachmentform != this.gui_objects.messageform)
-       this.gui_objects.attachmentform.reset();
-       }
-       catch(e){}  // ignore errors
-    
-    return true;  
-    };
-
-  // upload attachment file
-  this.upload_file = function(form)
-    {
-    if (!form)
-      return false;
-      
-    // get file input fields
-    var send = false;
-    for (var n=0; n<form.elements.length; n++)
-      if (form.elements[n].type=='file' && form.elements[n].value)
-        {
-        send = true;
-        break;
-        }
-    
-    // create hidden iframe and post upload form
-    if (send)
-      {
-      var ts = new Date().getTime();
-      var frame_name = 'rcmupload'+ts;
-
-      // have to do it this way for IE
-      // otherwise the form will be posted to a new window
-      if(document.all)
-        {
-        var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>';
-        document.body.insertAdjacentHTML('BeforeEnd',html);
-        }
-      else  // for standards-compilant browsers
-        {
-        var frame = document.createElement('IFRAME');
-        frame.name = frame_name;
-        frame.style.border = 'none';
-        frame.style.width = 0;
-        frame.style.height = 0;
-        frame.style.visibility = 'hidden';
-        document.body.appendChild(frame);
-        }
-
-      form.target = frame_name;
-      form.action = this.env.comm_path+'&_action=upload';
-      form.setAttribute('enctype', 'multipart/form-data');
-      form.submit();
-      }
-    
-    // set reference to the form object
-    this.gui_objects.attachmentform = form;
-    return true;
-    };
-
-  // add file name to attachment list
-  // called from upload page
-  this.add2attachment_list = function(name, content)
-    {
-    if (!this.gui_objects.attachmentlist)
-      return false;
-      
-    var li = document.createElement('LI');
-    li.id = name;
-    li.innerHTML = content;
-    this.gui_objects.attachmentlist.appendChild(li);
-    return true;
-    };
-
-  this.remove_from_attachment_list = function(name)
-    {
-    if (!this.gui_objects.attachmentlist)
-      return false;
-
-    var list = this.gui_objects.attachmentlist.getElementsByTagName("li");
-    for (i=0;i<list.length;i++)
-      if (list[i].id == name)
-        this.gui_objects.attachmentlist.removeChild(list[i]);
-    };
-
-  this.remove_attachment = function(name)
-    {
-    if (name)
-      this.http_post('remove-attachment', '_file='+urlencode(name));
-
-    return true;
-    };
-
-  // send remote request to add a new contact
-  this.add_contact = function(value)
-    {
-    if (value)
-      this.http_post('addcontact', '_address='+value);
-    
-    return true;
-    };
-
-  // send remote request to search mail or contacts
-  this.qsearch = function(value, addurl)
-    {
-    if (value != '')
-      {
-      if (this.message_list)
-        this.message_list.clear();
-      else if (this.contact_list) {
-        this.contact_list.clear(true);
-        this.show_contentframe(false);
-        }
-
-      if (this.gui_objects.search_filter)
-      addurl = '&_filter=' + this.gui_objects.search_filter.value;
-
-      // reset vars
-      this.env.current_page = 1;
-      this.set_busy(true, 'searching');
-      this.http_request('search', '_q='+urlencode(value)
-        + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '')
-        + (this.env.source ? '&_source='+urlencode(this.env.source) : '')
-        + (addurl ? addurl : ''), true);
-      }
-    return true;
-    };
-
-  // reset quick-search form
-  this.reset_qsearch = function()
-    {
-    if (this.gui_objects.qsearchbox)
-      this.gui_objects.qsearchbox.value = '';
-      
-    this.env.search_request = null;
-    return true;
-    };
-
-  this.sent_successfully = function(type, msg)
-    {
-    this.list_mailbox();
-    this.display_message(msg, type, true);
-    }
-
-
-  /*********************************************************/
-  /*********     keyboard live-search methods      *********/
-  /*********************************************************/
-
-  // handler for keyboard events on address-fields
-  this.ksearch_keypress = function(e, obj)
-  {
-    if (this.ksearch_timer)
-      clearTimeout(this.ksearch_timer);
-
-    var highlight;
-    var key = rcube_event.get_keycode(e);
-    var mod = rcube_event.get_modifier(e);
-
-    switch (key)
-      {
-      case 38:  // key up
-      case 40:  // key down
-        if (!this.ksearch_pane)
-          break;
-          
-        var dir = key==38 ? 1 : 0;
-        
-        highlight = document.getElementById('rcmksearchSelected');
-        if (!highlight)
-          highlight = this.ksearch_pane.ul.firstChild;
-        
-        if (highlight)
-          this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling);
-
-        return rcube_event.cancel(e);
-
-      case 9:  // tab
-        if(mod == SHIFT_KEY)
-          break;
-
-      case 13:  // enter
-        if (this.ksearch_selected===null || !this.ksearch_input || !this.ksearch_value)
-          break;
-
-        // insert selected address and hide ksearch pane
-        this.insert_recipient(this.ksearch_selected);
-        this.ksearch_hide();
-
-        return rcube_event.cancel(e);
-
-      case 27:  // escape
-        this.ksearch_hide();
-        break;
-
-      }
-
-    // start timer
-    this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(); }, 200);
-    this.ksearch_input = obj;
-    
-    return true;
-  };
-  
-  this.ksearch_select = function(node)
-  {
-    var current = document.getElementById('rcmksearchSelected');
-    if (current && node) {
-      current.removeAttribute('id');
-      this.set_classname(current, 'selected', false);
-    }
-
-    if (node) {
-      node.setAttribute('id', 'rcmksearchSelected');
-      this.set_classname(node, 'selected', true);
-      this.ksearch_selected = node._rcm_id;
-    }
-  };
-
-  this.insert_recipient = function(id)
-  {
-    if (!this.env.contacts[id] || !this.ksearch_input)
-      return;
-    
-    // get cursor pos
-    var inp_value = this.ksearch_input.value.toLowerCase();
-    var cpos = this.get_caret_pos(this.ksearch_input);
-    var p = inp_value.lastIndexOf(this.ksearch_value, cpos);
-
-    // replace search string with full address
-    var pre = this.ksearch_input.value.substring(0, p);
-    var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length);
-    var insert  = this.env.contacts[id]+', ';
-    this.ksearch_input.value = pre + insert + end;
-
-    // set caret to insert pos
-    cpos = p+insert.length;
-    if (this.ksearch_input.setSelectionRange)
-      this.ksearch_input.setSelectionRange(cpos, cpos);
-  };
-
-  // address search processor
-  this.ksearch_get_results = function()
-  {
-    var inp_value = this.ksearch_input ? this.ksearch_input.value : null;
-    if (inp_value === null)
-      return;
-      
-    if (this.ksearch_pane && this.ksearch_pane.visible)
-      this.ksearch_pane.show(0);
-
-    // get string from current cursor pos to last comma
-    var cpos = this.get_caret_pos(this.ksearch_input);
-    var p = inp_value.lastIndexOf(',', cpos-1);
-    var q = inp_value.substring(p+1, cpos);
-
-    // trim query string
-    q = q.replace(/(^\s+|\s+$)/g, '').toLowerCase();
-
-    // Don't (re-)search if string is empty or if the last results are still active
-    if (!q.length || q == this.ksearch_value)
-        return;
-
-    this.ksearch_value = q;
-    
-    this.display_message(this.get_label('searching'), 'loading', true);
-    this.http_post('autocomplete', '_search='+q);
-  };
-
-  this.ksearch_query_results = function(results, search)
-  {
-    // ignore this outdated search response
-    if (search != this.ksearch_value)
-      return;
-      
-    this.hide_message();
-    this.env.contacts = results ? results : [];
-
-    var result_ids = new Array();
-    var c=0;
-    for (var i=0; i < this.env.contacts.length; i++) {
-      result_ids[c++] = i;
-      if (c == 15)  // limit search results
-        break;
-    }
-    
-    this.ksearch_display_results(this.env.contacts, result_ids, c);
-  };
-
-  this.ksearch_display_results = function (a_results, a_result_ids, c)
-  {
-    // display search results
-    if (c && a_results.length && this.ksearch_input) {
-      var p, ul, li;
-      
-      // create results pane if not present
-      if (!this.ksearch_pane) {
-        ul = document.createElement('UL');
-        this.ksearch_pane = new rcube_layer('rcmKSearchpane', {vis:0, zindex:30000});
-        this.ksearch_pane.elm.appendChild(ul);
-        this.ksearch_pane.ul = ul;
-      }
-      else
-        ul = this.ksearch_pane.ul;
-
-      // remove all search results
-      ul.innerHTML = '';
-            
-      // add each result line to list
-      for (i=0; i<a_results.length; i++) {
-        li = document.createElement('LI');
-        li.innerHTML = a_results[i].replace(new RegExp('('+this.ksearch_value+')', 'ig'), '##$1%%').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/##([^%]+)%%/g, '<b>$1</b>');
-        li.onmouseover = function(){ ref.ksearch_select(this); };
-        li.onmouseup = function(){ ref.ksearch_click(this) };
-        li._rcm_id = a_result_ids[i];
-        ul.appendChild(li);
-      }
-
-      // check if last selected item is still in result list
-      if (this.ksearch_selected !== null) {
-        p = find_in_array(this.ksearch_selected, a_result_ids);
-        if (p >= 0 && ul.childNodes) {
-          ul.childNodes[p].setAttribute('id', 'rcmksearchSelected');
-          this.set_classname(ul.childNodes[p], 'selected', true);
-        }
-        else
-          this.ksearch_selected = null;
-      }
-      
-      // if no item selected, select the first one
-      if (this.ksearch_selected === null) {
-        ul.firstChild.setAttribute('id', 'rcmksearchSelected');
-        this.set_classname(ul.firstChild, 'selected', true);
-        this.ksearch_selected = a_result_ids[0];
-      }
-
-      // move the results pane right under the input box and make it visible
-      var pos = rcube_get_object_pos(this.ksearch_input);
-      this.ksearch_pane.move(pos.x, pos.y+this.ksearch_input.offsetHeight);
-      this.ksearch_pane.show(1);
-    }
-    // hide results pane
-    else
-      this.ksearch_hide();
-  };
-  
-  this.ksearch_click = function(node)
-  {
-    if (this.ksearch_input)
-      this.ksearch_input.focus();
-
-    this.insert_recipient(node._rcm_id);
-    this.ksearch_hide();
-  };
-
-  this.ksearch_blur = function()
-    {
-    if (this.ksearch_timer)
-      clearTimeout(this.ksearch_timer);
-
-    this.ksearch_value = '';
-    this.ksearch_input = null;
-    
-    this.ksearch_hide();
-    };
-
-
-  this.ksearch_hide = function()
-    {
-    this.ksearch_selected = null;
-    
-    if (this.ksearch_pane)
-      this.ksearch_pane.show(0);
-    };
-
-
-  /*********************************************************/
-  /*********         address book methods          *********/
-  /*********************************************************/
-
-  this.contactlist_keypress = function(list)
-    {
-      if (list.key_pressed == list.DELETE_KEY)
-        this.command('delete');
-    };
-
-  this.contactlist_select = function(list)
-    {
-      if (this.preview_timer)
-        clearTimeout(this.preview_timer);
-
-      var id, frame, ref = this;
-      if (id = list.get_single_selection())
-        this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
-      else if (this.env.contentframe)
-        this.show_contentframe(false);
-
-      this.enable_command('compose', list.selection.length > 0);
-      this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false);
-      this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly);
-
-      return false;
-    };
-
-  this.list_contacts = function(src, page)
-    {
-    var add_url = '';
-    var target = window;
-    
-    if (!src)
-      src = this.env.source;
-    
-    if (page && this.current_page==page && src == this.env.source)
-      return false;
-      
-    if (src != this.env.source)
-      {
-      page = 1;
-      this.env.current_page = page;
-      this.reset_qsearch();
-      }
-
-    this.select_folder(src, this.env.source);
-    this.env.source = src;
-
-    // load contacts remotely
-    if (this.gui_objects.contactslist)
-      {
-      this.list_contacts_remote(src, page);
-      return;
-      }
-
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      target = window.frames[this.env.contentframe];
-      add_url = '&_framed=1';
-      }
-
-    // also send search request to get the correct listing
-    if (this.env.search_request)
-      add_url += '&_search='+this.env.search_request;
-
-    this.set_busy(true, 'loading');
-    target.location.href = this.env.comm_path+(src ? '&_source='+urlencode(src) : '')+(page ? '&_page='+page : '')+add_url;
-    };
-
-  // send remote request to load contacts list
-  this.list_contacts_remote = function(src, page)
-    {
-    // clear message list first
-    this.contact_list.clear(true);
-    this.show_contentframe(false);
-    this.enable_command('delete', 'compose', false);
-
-    // send request to server
-    var url = (src ? '_source='+urlencode(src) : '') + (page ? (src?'&':'') + '_page='+page : '');
-    this.env.source = src;
-    
-    // also send search request to get the right messages 
-    if (this.env.search_request) 
-      url += '&_search='+this.env.search_request;
-
-    this.set_busy(true, 'loading');
-    this.http_request('list', url, true);
-    };
-
-  // load contact record
-  this.load_contact = function(cid, action, framed)
-    {
-    var add_url = '';
-    var target = window;
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      add_url = '&_framed=1';
-      target = window.frames[this.env.contentframe];
-      this.show_contentframe(true);
-      }
-    else if (framed)
-      return false;
-      
-    if (action && (cid || action=='add') && !this.drag_active)
-      {
-      this.set_busy(true);
-      target.location.href = this.env.comm_path+'&_action='+action+'&_source='+urlencode(this.env.source)+'&_cid='+urlencode(cid) + add_url;
-      }
-    return true;
-    };
-
-  // copy a contact to the specified target (group or directory)
-  this.copy_contact = function(cid, to)
-    {
-    if (!cid)
-      cid = this.contact_list.get_selection().join(',');
-
-    if (to != this.env.source && cid && this.env.address_sources[to] && !this.env.address_sources[to].readonly)
-      this.http_post('copy', '_cid='+urlencode(cid)+'&_source='+urlencode(this.env.source)+'&_to='+urlencode(to));
-    };
-
-
-  this.delete_contacts = function()
-    {
-    // exit if no mailbox specified or if selection is empty
-    var selection = this.contact_list.get_selection();
-    if (!(selection.length || this.env.cid) || !confirm(this.get_label('deletecontactconfirm')))
-      return;
-      
-    var a_cids = new Array();
-    var qs = '';
-
-    if (this.env.cid)
-      a_cids[a_cids.length] = this.env.cid;
-    else
-      {
-      var id;
-      for (var n=0; n<selection.length; n++)
-        {
-        id = selection[n];
-        a_cids[a_cids.length] = id;
-        this.contact_list.remove_row(id, (n == selection.length-1));
-        }
-
-      // hide content frame if we delete the currently displayed contact
-      if (selection.length == 1)
-        this.show_contentframe(false);
-      }
-
-    // also send search request to get the right records from the next page
-    if (this.env.search_request) 
-      qs += '&_search='+this.env.search_request;
-
-    // send request to server
-    this.http_post('delete', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source)+'&_from='+(this.env.action ? this.env.action : '')+qs);
-    return true;
-    };
-
-  // update a contact record in the list
-  this.update_contact_row = function(cid, cols_arr)
-    {
-    var row;
-    if (this.contact_list.rows[cid] && (row = this.contact_list.rows[cid].obj))
-      {
-      for (var c=0; c<cols_arr.length; c++)
-        if (row.cells[c])
-          row.cells[c].innerHTML = cols_arr[c];
-
-      return true;
-      }
-
-    return false;
-    };
-
-
-  /*********************************************************/
-  /*********        user settings methods          *********/
-  /*********************************************************/
-
-  this.init_subscription_list = function()
-    {
-    var p = this;
-    this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist, {multiselect:false, draggable:true, keyboard:false, toggleselect:true});
-    this.subscription_list.addEventListener('select', function(o){ p.subscription_select(o); });
-    this.subscription_list.addEventListener('dragstart', function(o){ p.drag_active = true; });
-    this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); });
-    this.subscription_list.row_init = function (row)
-      {
-      var anchors = row.obj.getElementsByTagName('A');
-      if (anchors[0])
-        anchors[0].onclick = function() { p.rename_folder(row.id); return false; };
-      if (anchors[1])
-        anchors[1].onclick = function() { p.delete_folder(row.id); return false; };
-      row.obj.onmouseover = function() { p.focus_subscription(row.id); };
-      row.obj.onmouseout = function() { p.unfocus_subscription(row.id); };
-      }
-    this.subscription_list.init();
-    }
-
-  this.identity_select = function(list)
-    {
-    var id;
-    if (id = list.get_single_selection())
-      this.load_identity(id, 'edit-identity');
-    };
-
-  // load contact record
-  this.load_identity = function(id, action)
-    {
-    if (action=='edit-identity' && (!id || id==this.env.iid))
-      return false;
-
-    var add_url = '';
-    var target = window;
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      add_url = '&_framed=1';
-      target = window.frames[this.env.contentframe];
-      document.getElementById(this.env.contentframe).style.visibility = 'inherit';
-      }
-
-    if (action && (id || action=='add-identity'))
-      {
-      this.set_busy(true);
-      target.location.href = this.env.comm_path+'&_action='+action+'&_iid='+id+add_url;
-      }
-    return true;
-    };
-
-  this.delete_identity = function(id)
-    {
-    // exit if no mailbox specified or if selection is empty
-    var selection = this.identity_list.get_selection();
-    if (!(selection.length || this.env.iid))
-      return;
-    
-    if (!id)
-      id = this.env.iid ? this.env.iid : selection[0];
-
-    // if (this.env.framed && id)
-    this.goto_url('delete-identity', '_iid='+id, true);
-    return true;
-    };
-
-  this.focus_subscription = function(id)
-    {
-    var row, folder;
-    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
-
-    if (this.drag_active && this.env.folder && (row = document.getElementById(id)))
-      if (this.env.subscriptionrows[id] &&
-          (folder = this.env.subscriptionrows[id][0]))
-        {
-        if (this.check_droptarget(folder) &&
-           !this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2] &&    
-           (folder != this.env.folder.replace(reg, '')) &&
-            (!folder.match(new RegExp('^'+RegExp.escape(this.env.folder+this.env.delimiter)))))
-          {
-          this.set_env('dstfolder', folder);
-          this.set_classname(row, 'droptarget', true);
-          }
-        }
-      else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter))))
-        {
-        this.set_env('dstfolder', this.env.delimiter);
-        this.set_classname(this.subscription_list.frame, 'droptarget', true);
-        }
-    }
-
-  this.unfocus_subscription = function(id)
-    {
-      var row;
-      this.set_env('dstfolder', null);
-      if (this.env.subscriptionrows[id] &&
-          (row = document.getElementById(id)))
-        this.set_classname(row, 'droptarget', false);
-      else
-        this.set_classname(this.subscription_list.frame, 'droptarget', false);
-    }
-
-  this.subscription_select = function(list)
-    {
-    var id, folder;
-    if ((id = list.get_single_selection()) &&
-        this.env.subscriptionrows['rcmrow'+id] &&
-        (folder = this.env.subscriptionrows['rcmrow'+id][0]))
-      this.set_env('folder', folder);
-    else
-      this.set_env('folder', null);
-      
-    if (this.gui_objects.createfolderhint)
-      this.gui_objects.createfolderhint.innerHTML = this.env.folder ? this.get_label('addsubfolderhint') : '';
-    };
-
-  this.subscription_move_folder = function(list)
-    {
-    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
-    if (this.env.folder && this.env.dstfolder && (this.env.dstfolder != this.env.folder) &&
-        (this.env.dstfolder != this.env.folder.replace(reg, '')))
-      {
-      var reg = new RegExp('[^'+RegExp.escape(this.env.delimiter)+']*['+RegExp.escape(this.env.delimiter)+']', 'g');
-      var basename = this.env.folder.replace(reg, '');
-      var newname = this.env.dstfolder==this.env.delimiter ? basename : this.env.dstfolder+this.env.delimiter+basename;
-
-      this.set_busy(true, 'foldermoving');
-      this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.folder)+'&_folder_newname='+urlencode(newname), true);
-      }
-    this.drag_active = false;
-    this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
-    };
-
-  // tell server to create and subscribe a new mailbox
-  this.create_folder = function(name)
-    {
-    if (this.edit_folder)
-      this.reset_folder_rename();
-
-    var form;
-    if ((form = this.gui_objects.editform) && form.elements['_folder_name'])
-      {
-      name = form.elements['_folder_name'].value;
-
-      if (name.indexOf(this.env.delimiter)>=0)
-        {
-        alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
-        return false;
-        }
-
-      if (this.env.folder && name != '')
-        name = this.env.folder+this.env.delimiter+name;
-
-      this.set_busy(true, 'foldercreating');
-      this.http_post('create-folder', '_name='+urlencode(name), true);
-      }
-    else if (form.elements['_folder_name'])
-      form.elements['_folder_name'].focus();
-    };
-
-  // start renaming the mailbox name.
-  // this will replace the name string with an input field
-  this.rename_folder = function(id)
-    {
-    var temp, row, form;
-
-    // reset current renaming
-    if (temp = this.edit_folder)
-      {
-      this.reset_folder_rename();
-      if (temp == id)
-        return;
-      }
-
-    if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id)))
-      {
-      var reg = new RegExp('.*['+RegExp.escape(this.env.delimiter)+']');
-      this.name_input = document.createElement('INPUT');
-      this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, '');
-      this.name_input.style.width = '100%';
-
-      reg = new RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
-      this.name_input.__parent = this.env.subscriptionrows[id][0].replace(reg, '');
-      this.name_input.onkeypress = function(e){ rcmail.name_input_keypress(e); };
-      
-      row.cells[0].replaceChild(this.name_input, row.cells[0].firstChild);
-      this.edit_folder = id;
-      this.name_input.select();
-      
-      if (form = this.gui_objects.editform)
-        form.onsubmit = function(){ return false; };
-      }
-    };
-
-  // remove the input field and write the current mailbox name to the table cell
-  this.reset_folder_rename = function()
-    {
-    var cell = this.name_input ? this.name_input.parentNode : null;
-
-    if (cell && this.edit_folder && this.env.subscriptionrows[this.edit_folder])
-      cell.innerHTML = this.env.subscriptionrows[this.edit_folder][1];
-      
-    this.edit_folder = null;
-    };
-
-  // handler for keyboard events on the input field
-  this.name_input_keypress = function(e)
-    {
-    var key = rcube_event.get_keycode(e);
-
-    // enter
-    if (key==13)
-      {
-      var newname = this.name_input ? this.name_input.value : null;
-      if (this.edit_folder && newname)
-        {
-        if (newname.indexOf(this.env.delimiter)>=0)
-          {
-          alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
-          return false;
-          }
-
-        if (this.name_input.__parent)
-          newname = this.name_input.__parent + this.env.delimiter + newname;
-
-        this.set_busy(true, 'folderrenaming');
-        this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname), true);
-        }
-      }
-    // escape
-    else if (key==27)
-      this.reset_folder_rename();
-    };
-
-  // delete a specific mailbox with all its messages
-  this.delete_folder = function(id)
-    {
-    var folder = this.env.subscriptionrows[id][0];
-
-    if (this.edit_folder)
-      this.reset_folder_rename();
-
-    if (folder && confirm(this.get_label('deletefolderconfirm')))
-      {
-      this.set_busy(true, 'folderdeleting');
-      this.http_post('delete-folder', '_mboxes='+urlencode(folder), true);
-      this.set_env('folder', null);
-
-      if (this.gui_objects.createfolderhint)
-        this.gui_objects.createfolderhint.innerHTML = '';
-      }
-    };
-
-  // add a new folder to the subscription list by cloning a folder row
-  this.add_folder_row = function(name, display_name, replace, before)
-    {
-    if (!this.gui_objects.subscriptionlist)
-      return false;
-
-    // find not protected folder    
-    for (var refid in this.env.subscriptionrows)
-      if (this.env.subscriptionrows[refid]!=null && !this.env.subscriptionrows[refid][2])
-        break;
-
-    var refrow, form;
-    var tbody = this.gui_objects.subscriptionlist.tBodies[0];
-    var id = 'rcmrow'+(tbody.childNodes.length+1);
-    var selection = this.subscription_list.get_single_selection();
-    
-    if (replace && replace.id)
-    {
-      id = replace.id;
-      refid = replace.id;
-    }
-
-    if (!id || !(refrow = document.getElementById(refid)))
-      {
-      // Refresh page if we don't have a table row to clone
-      this.goto_url('folders');
-      }
-    else
-      {
-      // clone a table row if there are existing rows
-      var row = this.clone_table_row(refrow);
-      row.id = id;
-
-      if (before && (before = this.get_folder_row_id(before)))
-        tbody.insertBefore(row, document.getElementById(before));
-      else
-        tbody.appendChild(row);
-      
-      if (replace)
-        tbody.removeChild(replace);
-      }
-
-    // add to folder/row-ID map
-    this.env.subscriptionrows[row.id] = [name, display_name, 0];
-
-    // set folder name
-    row.cells[0].innerHTML = display_name;
-    
-    // set messages count to zero
-    if (!replace)
-      row.cells[1].innerHTML = '*';
-    
-    if (!replace && row.cells[2] && row.cells[2].firstChild.tagName=='INPUT')
-      {
-      row.cells[2].firstChild.value = name;
-      row.cells[2].firstChild.checked = true;
-      }
-    
-    // add new folder to rename-folder list and clear input field
-    if (!replace && (form = this.gui_objects.editform))
-      {
-      if (form.elements['_folder_oldname'])
-        form.elements['_folder_oldname'].options[form.elements['_folder_oldname'].options.length] = new Option(name,name);
-      if (form.elements['_folder_name'])
-        form.elements['_folder_name'].value = ''; 
-      }
-
-    this.init_subscription_list();
-    if (selection && document.getElementById('rcmrow'+selection))
-      this.subscription_list.select_row(selection);
-
-    if (document.getElementById(id).scrollIntoView)
-      document.getElementById(id).scrollIntoView();
-    };
-
-  // replace an existing table row with a new folder line
-  this.replace_folder_row = function(oldfolder, newfolder, display_name, before)
-    {
-    var id = this.get_folder_row_id(oldfolder);
-    var row = document.getElementById(id);
-    
-    // replace an existing table row (if found)
-    this.add_folder_row(newfolder, display_name, row, before);
-    
-    // rename folder in rename-folder dropdown
-    var form, elm;
-    if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname']))
-      {
-      for (var i=0;i<elm.options.length;i++)
-        {
-        if (elm.options[i].value == oldfolder)
-          {
-          elm.options[i].text = display_name;
-          elm.options[i].value = newfolder;
-          break;
-          }
-        }
-
-      form.elements['_folder_newname'].value = '';
-      }
-    };
-
-  // remove the table row of a specific mailbox from the table
-  // (the row will not be removed, just hidden)
-  this.remove_folder_row = function(folder)
-    {
-    var row;
-    var id = this.get_folder_row_id(folder);
-    if (id && (row = document.getElementById(id)))
-      row.style.display = 'none';
-
-    // remove folder from rename-folder list
-    var form;
-    if ((form = this.gui_objects.editform) && form.elements['_folder_oldname'])
-      {
-      for (var i=0;i<form.elements['_folder_oldname'].options.length;i++)
-        {
-        if (form.elements['_folder_oldname'].options[i].value == folder) 
-          {
-          form.elements['_folder_oldname'].options[i] = null;
-          break;
-          }
-        }
-      }
-    
-    if (form && form.elements['_folder_newname'])
-      form.elements['_folder_newname'].value = '';
-    };
-
-  this.subscribe_folder = function(folder)
-    {
-    if (folder)
-      this.http_post('subscribe', '_mbox='+urlencode(folder));
-    };
-
-  this.unsubscribe_folder = function(folder)
-    {
-    if (folder)
-      this.http_post('unsubscribe', '_mbox='+urlencode(folder));
-    };
-    
-  // helper method to find a specific mailbox row ID
-  this.get_folder_row_id = function(folder)
-    {
-    for (var id in this.env.subscriptionrows)
-      if (this.env.subscriptionrows[id] && this.env.subscriptionrows[id][0] == folder)
-        break;
-        
-    return id;
-    };
-
-  // duplicate a specific table row
-  this.clone_table_row = function(row)
-    {
-    var cell, td;
-    var new_row = document.createElement('TR');
-    for(var n=0; n<row.cells.length; n++)
-      {
-      cell = row.cells[n];
-      td = document.createElement('TD');
-
-      if (cell.className)
-        td.className = cell.className;
-      if (cell.align)
-        td.setAttribute('align', cell.align);
-        
-      td.innerHTML = cell.innerHTML;
-      new_row.appendChild(td);
-      }
-    
-    return new_row;
-    };
-
-
-  /*********************************************************/
-  /*********           GUI functionality           *********/
-  /*********************************************************/
-
-  // eable/disable buttons for page shifting
-  this.set_page_buttons = function()
-    {
-    this.enable_command('nextpage', (this.env.pagecount > this.env.current_page));
-    this.enable_command('lastpage', (this.env.pagecount > this.env.current_page));
-    this.enable_command('previouspage', (this.env.current_page > 1));
-    this.enable_command('firstpage', (this.env.current_page > 1));
-    }
-
-  // set button to a specific state
-  this.set_button = function(command, state)
-    {
-    var a_buttons = this.buttons[command];
-    var button, obj;
-
-    if(!a_buttons || !a_buttons.length)
-      return false;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      obj = document.getElementById(button.id);
-
-      // get default/passive setting of the button
-      if (obj && button.type=='image' && !button.status) {
-        button.pas = obj._original_src ? obj._original_src : obj.src;
-        // respect PNG fix on IE browsers
-        if (obj.runtimeStyle && obj.runtimeStyle.filter && obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))
-          button.pas = RegExp.$1;
-      }
-      else if (obj && !button.status)
-        button.pas = String(obj.className);
-
-      // set image according to button state
-      if (obj && button.type=='image' && button[state])
-        {
-        button.status = state;        
-        obj.src = button[state];
-        }
-      // set class name according to button state
-      else if (obj && typeof(button[state])!='undefined')
-        {
-        button.status = state;        
-        obj.className = button[state];        
-        }
-      // disable/enable input buttons
-      if (obj && button.type=='input')
-        {
-        button.status = state;
-        obj.disabled = !state;
-        }
-      }
-    };
-
-  // display a specific alttext
-  this.set_alttext = function(command, label)
-    {
-      if (!this.buttons[command] || !this.buttons[command].length)
-        return;
-      
-      var button, obj, link;
-      for (var n=0; n<this.buttons[command].length; n++)
-      {
-        button = this.buttons[command][n];
-        obj = document.getElementById(button.id);
-        
-        if (button.type=='image' && obj)
-        {
-          obj.setAttribute('alt', this.get_label(label));
-          if ((link = obj.parentNode) && link.tagName == 'A')
-            link.setAttribute('title', this.get_label(label));
-        }
-        else if (obj)
-          obj.setAttribute('title', this.get_label(label));
-      }
-    };
-
-  // mouse over button
-  this.button_over = function(command, id)
-    {
-    var a_buttons = this.buttons[command];
-    var button, img;
-
-    if(!a_buttons || !a_buttons.length)
-      return false;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      if(button.id==id && button.status=='act')
-        {
-        img = document.getElementById(button.id);
-        if (img && button.over)
-          img.src = button.over;
-        }
-      }
-      
-    };
-
-  // mouse down on button
-  this.button_sel = function(command, id)
-    {
-    var a_buttons = this.buttons[command];
-    var button, img;
-
-    if(!a_buttons || !a_buttons.length)
-      return;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      if(button.id==id && button.status=='act')
-        {
-        img = document.getElementById(button.id);
-        if (img && button.sel)
-          img.src = button.sel;
-        }
-      }
-    };
-
-  // mouse out of button
-  this.button_out = function(command, id)
-    {
-    var a_buttons = this.buttons[command];
-    var button, img;
-
-    if(!a_buttons || !a_buttons.length)
-      return;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      if(button.id==id && button.status=='act')
-        {
-        img = document.getElementById(button.id);
-        if (img && button.act)
-          img.src = button.act;
-        }
-      }
-    };
-
-  // set/unset a specific class name
-  this.set_classname = function(obj, classname, set)
-    {
-    var reg = new RegExp('\s*'+classname, 'i');
-    if (!set && obj.className.match(reg))
-      obj.className = obj.className.replace(reg, '');
-    else if (set && !obj.className.match(reg))
-      obj.className += ' '+classname;
-    };
-
-  // write to the document/window title
-  this.set_pagetitle = function(title)
-  {
-    if (title && document.title)
-      document.title = title;
-  }
-
-  // display a system message
-  this.display_message = function(msg, type, hold)
-    {
-    if (!this.loaded)  // save message in order to display after page loaded
-      {
-      this.pending_message = new Array(msg, type);
-      return true;
-      }
-
-    // pass command to parent window
-    if (this.env.framed && parent.rcmail)
-      return parent.rcmail.display_message(msg, type, hold);
-
-    if (!this.gui_objects.message)
-      return false;
-
-    if (this.message_timer)
-      clearTimeout(this.message_timer);
-    
-    var cont = msg;
-    if (type)
-      cont = '<div class="'+type+'">'+cont+'</div>';
-
-    var _rcube = this;
-    this.gui_objects.message.innerHTML = cont;
-    this.gui_objects.message.style.display = 'block';
-    
-    if (type!='loading')
-      this.gui_objects.message.onmousedown = function(){ _rcube.hide_message(); return true; };
-    
-    if (!hold)
-      this.message_timer = window.setTimeout(function(){ ref.hide_message(); }, this.message_time);
-    };
-
-  // make a message row disapear
-  this.hide_message = function()
-    {
-    if (this.gui_objects.message)
-      {
-      this.gui_objects.message.style.display = 'none';
-      this.gui_objects.message.onmousedown = null;
-      }
-    };
-
-  // mark a mailbox as selected and set environment variable
-  this.select_folder = function(name, old)
-  {
-    if (this.gui_objects.folderlist)
-    {
-      var current_li, target_li;
-      
-      if ((current_li = this.get_folder_li(old)))
-      {
-        this.set_classname(current_li, 'selected', false);
-        this.set_classname(current_li, 'unfocused', false);
-      }
-
-      if ((target_li = this.get_folder_li(name)))
-      {
-        this.set_classname(target_li, 'unfocused', false);
-        this.set_classname(target_li, 'selected', true);
-      }
-    }
-  };
-
-  // helper method to find a folder list item
-  this.get_folder_li = function(name)
-  {
-    if (this.gui_objects.folderlist)
-    {
-      name = String(name).replace(this.identifier_expr, '');
-      return document.getElementById('rcmli'+name);
-    }
-
-    return null;
-  };
-
-  // for reordering column array, Konqueror workaround
-  this.set_message_coltypes = function(coltypes) 
-  { 
-    this.coltypes = coltypes;
-    
-    // set correct list titles
-    var cell, col;
-    var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null;
-    for (var n=0; thead && n<this.coltypes.length; n++) 
-      {
-      col = this.coltypes[n];
-      if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to'))
-        {
-        // if we have links for sorting, it's a bit more complicated...
-        if (cell.firstChild && cell.firstChild.tagName=='A')
-          {
-          cell.firstChild.innerHTML = this.get_label(this.coltypes[n]);
-          cell.firstChild.onclick = function(){ return rcmail.command('sort', this.__col, this); };
-          cell.firstChild.__col = col;
-          }
-        else
-          cell.innerHTML = this.get_label(this.coltypes[n]);
-
-        cell.id = 'rcm'+col;
-        }
-      else if (col == 'subject' && this.message_list)
-        this.message_list.subject_col = n+1;
-      }
-  };
-
-  // create a table row in the message list
-  this.add_message_row = function(uid, cols, flags, attachment, attop)
-    {
-    if (!this.gui_objects.messagelist || !this.message_list)
-      return false;
-
-    var tbody = this.gui_objects.messagelist.tBodies[0];
-    var rowcount = tbody.rows.length;
-    var even = rowcount%2;
-    
-    this.env.messages[uid] = {deleted:flags.deleted?1:0,
-                              replied:flags.replied?1:0,
-                              unread:flags.unread?1:0,
-                             forwarded:flags.forwarded?1:0,
-                              flagged:flags.flagged?1:0};
-    
-    var row = document.createElement('TR');
-    row.id = 'rcmrow'+uid;
-    row.className = 'message'
-       + (even ? ' even' : ' odd')
-        + (flags.unread ? ' unread' : '')
-       + (flags.deleted ? ' deleted' : '')
-       + (flags.flagged ? ' flagged' : '');                
-
-    if (this.message_list.in_selection(uid))
-      row.className += ' selected';
-
-    var icon = this.env.messageicon;
-    if (flags.deleted && this.env.deletedicon)
-      icon = this.env.deletedicon;
-    else if (flags.replied && this.env.repliedicon)
-      {
-      if (flags.forwarded && this.env.forwardedrepliedicon)
-        icon = this.env.forwardedrepliedicon;
-      else
-        icon = this.env.repliedicon;
-      }
-    else if (flags.forwarded && this.env.forwardedicon)
-      icon = this.env.forwardedicon;
-    else if(flags.unread && this.env.unreadicon)
-      icon = this.env.unreadicon;
-    
-    var col = document.createElement('TD');
-    col.className = 'icon';
-    col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : '';
-    row.appendChild(col);
-
-    // add each submitted col
-    for (var n = 0; n < this.coltypes.length; n++) 
-      { 
-      var c = this.coltypes[n];
-      col = document.createElement('TD');
-      col.className = String(c).toLowerCase();
-      
-      if (c=='flag')
-        {
-        if (flags.flagged && this.env.flaggedicon)
-          col.innerHTML = '<img src="'+this.env.flaggedicon+'" alt="" />';
-        else if(!flags.flagged && this.env.unflaggedicon)
-          col.innerHTML = '<img src="'+this.env.unflaggedicon+'" alt="" />';
-      }
-      else if (c=='attachment')
-        col.innerHTML = attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" />' : '&nbsp;';
-      else
-        col.innerHTML = cols[c];
-
-      row.appendChild(col);
-      }
-
-    this.message_list.insert_row(row, attop);
-
-    // remove 'old' row
-    if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize)
-      {
-       var uid = this.message_list.get_last_row();
-        this.message_list.remove_row(uid);
-       this.message_list.clear_selection(uid);
-      }
-    };
-
-  // replace content of row count display
-  this.set_rowcount = function(text)
-    {
-    if (this.gui_objects.countdisplay)
-      this.gui_objects.countdisplay.innerHTML = text;
-
-    // update page navigation buttons
-    this.set_page_buttons();
-    };
-
-  // replace content of mailboxname display
-  this.set_mailboxname = function(content)
-    {
-    if (this.gui_objects.mailboxname && content)
-      this.gui_objects.mailboxname.innerHTML = content;
-    };
-
-  // replace content of quota display
-  this.set_quota = function(content)
-    {
-    if (this.gui_objects.quotadisplay && content)
-      this.gui_objects.quotadisplay.innerHTML = content;
-    };
-
-  // update the mailboxlist
-  this.set_unread_count = function(mbox, count, set_title)
-    {
-    if (!this.gui_objects.mailboxlist)
-      return false;
-
-    this.env.unread_counts[mbox] = count;
-    this.set_unread_count_display(mbox, set_title);
-    }
-
-  // update the mailbox count display
-  this.set_unread_count_display = function(mbox, set_title)
-    {
-    var reg, text_obj, item, mycount, childcount, div;
-    if (item = this.get_folder_li(mbox))
-      {
-      mycount = this.env.unread_counts[mbox] ? this.env.unread_counts[mbox] : 0;
-      text_obj = item.getElementsByTagName('a')[0];
-      reg = /\s+\([0-9]+\)$/i;
-
-      childcount = 0;
-      if ((div = item.getElementsByTagName('div')[0]) &&
-          div.className.match(/collapsed/))
-        {
-        // add children's counters
-        for (var k in this.env.unread_counts) 
-          if (k.indexOf(mbox + this.env.delimiter) == 0) {
-            childcount += this.env.unread_counts[k];
-         }
-        }
-
-      if (mycount && text_obj.innerHTML.match(reg))
-        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+mycount+')');
-      else if (mycount)
-        text_obj.innerHTML += ' ('+mycount+')';
-      else
-        text_obj.innerHTML = text_obj.innerHTML.replace(reg, '');
-
-      // set parent's display
-      reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+$');
-      if (mbox.match(reg))
-        this.set_unread_count_display(mbox.replace(reg, ''), false);
-
-      // set the right classes
-      this.set_classname(item, 'unread', (mycount+childcount)>0 ? true : false);
-      }
-
-    // set unread count to window title
-    reg = /^\([0-9]+\)\s+/i;
-    if (set_title && document.title)
-      {
-      var doc_title = String(document.title);
-      var new_title = "";
-
-      if (mycount && doc_title.match(reg))
-        new_title = doc_title.replace(reg, '('+mycount+') ');
-      else if (mycount)
-        new_title = '('+mycount+') '+doc_title;
-      else
-        new_title = doc_title.replace(reg, '');
-        
-      this.set_pagetitle(new_title);
-      }
-    };
-
-  // notifies that a new message(s) has hit the mailbox
-  this.new_message_focus = function()
-    {
-    // focus main window
-    if (this.env.framed && window.parent)
-      window.parent.focus();
-    else
-      window.focus();
-    }
-
-  // add row to contacts list
-  this.add_contact_row = function(cid, cols, select)
-    {
-    if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0])
-      return false;
-    
-    var tbody = this.gui_objects.contactslist.tBodies[0];
-    var rowcount = tbody.rows.length;
-    var even = rowcount%2;
-    
-    var row = document.createElement('TR');
-    row.id = 'rcmrow'+cid;
-    row.className = 'contact '+(even ? 'even' : 'odd');
-    
-    if (this.contact_list.in_selection(cid))
-      row.className += ' selected';
-
-    // add each submitted col
-    for (var c in cols)
-      {
-      col = document.createElement('TD');
-      col.className = String(c).toLowerCase();
-      col.innerHTML = cols[c];
-      row.appendChild(col);
-      }
-    
-    this.contact_list.insert_row(row);
-    this.enable_command('export', (this.contact_list.rowcount > 0));
-    };
-
-  this.toggle_prefer_html = function(checkbox)
-    {
-    var addrbook_show_images;
-    if (addrbook_show_images = document.getElementById('rcmfd_addrbook_show_images'))
-      addrbook_show_images.disabled = !checkbox.checked;
-    }
-
-  // display fetched raw headers
-  this.set_headers = function(content)
-    {
-    if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content)
-      {
-      var box = this.gui_objects.all_headers_box;
-      box.innerHTML = content;
-      box.style.display = 'block';
-
-      if (this.env.framed && parent.rcmail)
-       parent.rcmail.set_busy(false);
-      else
-        this.set_busy(false);
-      }
-    };
-
-  // display all-headers row and fetch raw message headers
-  this.load_headers = function(elem)
-    {
-    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid)
-      return;
-    
-    this.set_classname(elem, 'show-headers', false);
-    this.set_classname(elem, 'hide-headers', true);
-    this.gui_objects.all_headers_row.style.display = bw.ie ? 'block' : 'table-row';
-    elem.onclick = function() { rcmail.hide_headers(elem); }
-
-    // fetch headers only once
-    if (!this.gui_objects.all_headers_box.innerHTML)
-      {
-      this.display_message(this.get_label('loading'), 'loading', true); 
-      this.http_post('headers', '_uid='+this.env.uid);
-      }
-    }
-
-  // hide all-headers row
-  this.hide_headers = function(elem)
-    {
-    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box)
-      return;
-
-    this.set_classname(elem, 'hide-headers', false);
-    this.set_classname(elem, 'show-headers', true);
-    this.gui_objects.all_headers_row.style.display = 'none';
-    elem.onclick = function() { rcmail.load_headers(elem); }
-    }
-
-
-  /********************************************************/
-  /*********  html to text conversion functions   *********/
-  /********************************************************/
-
-  this.html2plain = function(htmlText, id)
-    {
-    var http_request = new rcube_http_request();
-    var url = this.env.bin_path+'html2text.php';
-    var rcmail = this;
-
-    this.set_busy(true, 'converting');
-    console.log('HTTP POST: '+url);
-
-    http_request.onerror = function(o) { rcmail.http_error(o); };
-    http_request.oncomplete = function(o) { rcmail.set_text_value(o, id); };
-    http_request.POST(url, htmlText, 'application/octet-stream');
-    }
-
-  this.set_text_value = function(httpRequest, id)
-    {
-    this.set_busy(false);
-    document.getElementById(id).value = httpRequest.get_text();
-    console.log(httpRequest.get_text());
-    }
-
-
-  /********************************************************/
-  /*********        remote request methods        *********/
-  /********************************************************/
-
-  this.redirect = function(url, lock)
-    {
-    if (lock || lock === null)
-      this.set_busy(true);
-
-    if (this.env.framed && window.parent)
-      parent.location.href = url;
-    else  
-      location.href = url;
-    };
-
-  this.goto_url = function(action, query, lock)
-    {
-    var querystring = query ? '&'+query : '';
-    this.redirect(this.env.comm_path+'&_action='+action+querystring, lock);
-    };
-
-  this.http_sockets = new Array();
-  
-  // find a non-busy socket or create a new one
-  this.get_request_obj = function()
-    {
-    for (var n=0; n<this.http_sockets.length; n++)
-      {
-      if (!this.http_sockets[n].busy)
-        return this.http_sockets[n];
-      }
-    
-    // create a new XMLHTTP object
-    var i = this.http_sockets.length;
-    this.http_sockets[i] = new rcube_http_request();
-
-    return this.http_sockets[i];
-    };
-  
-  // send a http request to the server
-  this.http_request = function(action, querystring, lock)
-    {
-    var request_obj = this.get_request_obj();
-    querystring += (querystring ? '&' : '') + '_remote=1';
-    
-    // add timestamp to request url to avoid cacheing problems in Safari
-    if (bw.safari)
-      querystring += '&_ts='+(new Date().getTime());
-
-    // send request
-    if (request_obj)
-      {
-      console.log('HTTP request: '+this.env.comm_path+'&_action='+action+'&'+querystring);
-
-      if (lock)
-        this.set_busy(true);
-
-      var rcm = this;
-      request_obj.__lock = lock ? true : false;
-      request_obj.__action = action;
-      request_obj.onerror = function(o){ ref.http_error(o); };
-      request_obj.oncomplete = function(o){ ref.http_response(o); };
-      request_obj.GET(this.env.comm_path+'&_action='+action+'&'+querystring);
-      }
-    };
-
-    // send a http POST request to the server
-    this.http_post = function(action, postdata, lock)
-      {
-      var request_obj;
-      if (postdata && typeof(postdata) == 'object')
-        postdata._remote = 1;
-      else
-        postdata += (postdata ? '&' : '') + '_remote=1';
-
-      // send request
-      if (request_obj = this.get_request_obj())
-        {
-        console.log('HTTP POST: '+this.env.comm_path+'&_action='+action);
-
-        if (lock)
-          this.set_busy(true);
-
-        var rcm = this;
-        request_obj.__lock = lock ? true : false;
-        request_obj.__action = action;
-        request_obj.onerror = function(o){ rcm.http_error(o); };
-        request_obj.oncomplete = function(o){ rcm.http_response(o); };
-        request_obj.POST(this.env.comm_path+'&_action='+action, postdata);
-        }
-      };
-
-  // handle HTTP response
-  this.http_response = function(request_obj)
-    {
-    var ctype = request_obj.get_header('Content-Type');
-    if (ctype)
-      {
-      ctype = String(ctype).toLowerCase();
-      var ctype_array=ctype.split(";");
-      ctype = ctype_array[0];
-      }
-
-    if (request_obj.__lock)
-      this.set_busy(false);
-
-    console.log(request_obj.get_text());
-
-    // if we get javascript code from server -> execute it
-    if (request_obj.get_text() && (ctype=='text/javascript' || ctype=='application/x-javascript'))
-      eval(request_obj.get_text());
-
-    // process the response data according to the sent action
-    switch (request_obj.__action) {
-      case 'delete':
-        if (this.task == 'addressbook') {
-          var uid = this.contact_list.get_selection();
-          this.enable_command('compose', (uid && this.contact_list.rows[uid]));
-          this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && this.env.address_sources && !this.env.address_sources[this.env.source].readonly));
-          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
-        }
-      
-      case 'moveto':
-        if (this.env.action == 'show')
-          this.command('list');
-        else if (this.message_list)
-          this.message_list.init();
-        break;
-        
-      case 'purge':
-      case 'expunge':      
-        if (!this.env.messagecount && this.task == 'mail') {
-          // clear preview pane content
-          if (this.env.contentframe)
-            this.show_contentframe(false);
-          // disable commands useless when mailbox is empty
-          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource',
-            'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false);
-        }
-        break;
-
-      case 'check-recent':
-      case 'getunread':
-      case 'list':
-        if (this.task == 'mail') {
-          if (this.message_list && request_obj.__action == 'list')
-            this.msglist_select(this.message_list);
-          this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0));
-          this.enable_command('purge', this.purge_mailbox_test());
-        }
-        else if (this.task == 'addressbook')
-          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
-
-        break;
-      }
-
-    request_obj.reset();
-    };
-
-  // handle HTTP request errors
-  this.http_error = function(request_obj)
-    {
-    //alert('Error sending request: '+request_obj.url+' => HTTP '+request_obj.xmlhttp.status);
-    if (request_obj.__lock)
-      this.set_busy(false);
-
-    request_obj.reset();
-    request_obj.__lock = false;
-    this.display_message('Unknown Server Error!', 'error');
-    };
-
-  // use an image to send a keep-alive siganl to the server
-  this.send_keep_alive = function()
-    {
-    var d = new Date();
-    this.http_request('keep-alive', '_t='+d.getTime());
-    };
-
-  // send periodic request to check for recent messages
-  this.check_for_recent = function(setbusy)
-    {
-    if (this.busy)
-      return;
-
-    if (setbusy)
-      this.set_busy(true, 'checkingmail');
-
-    var addurl = '_t=' + (new Date().getTime());
-
-    if (this.gui_objects.messagelist)
-      addurl += '&_list=1';
-    if (this.gui_objects.quotadisplay)
-      addurl += '&_quota=1';
-    if (this.env.search_request)
-      addurl += '&_search=' + this.env.search_request;
-
-    this.http_request('check-recent', addurl, true);
-    };
-
-
-  /********************************************************/
-  /*********            helper methods            *********/
-  /********************************************************/
-  
-  // check if we're in show mode or if we have a unique selection
-  // and return the message uid
-  this.get_single_uid = function()
-    {
-    return this.env.uid ? this.env.uid : (this.message_list ? this.message_list.get_single_selection() : null);
-    };
-
-  // same as above but for contacts
-  this.get_single_cid = function()
-    {
-    return this.env.cid ? this.env.cid : (this.contact_list ? this.contact_list.get_single_selection() : null);
-    };
-
-
-  this.get_caret_pos = function(obj)
-    {
-    if (typeof(obj.selectionEnd)!='undefined')
-      return obj.selectionEnd;
-    else if (document.selection && document.selection.createRange)
-      {
-      var range = document.selection.createRange();
-      if (range.parentElement()!=obj)
-        return 0;
-
-      var gm = range.duplicate();
-      if (obj.tagName=='TEXTAREA')
-        gm.moveToElementText(obj);
-      else
-        gm.expand('textedit');
-      
-      gm.setEndPoint('EndToStart', range);
-      var p = gm.text.length;
-
-      return p<=obj.value.length ? p : -1;
-      }
-    else
-      return obj.value.length;
-    };
-
-  this.set_caret2start = function(obj)
-    {
-    if (obj.createTextRange)
-      {
-      var range = obj.createTextRange();
-      range.collapse(true);
-      range.select();
-      }
-    else if (obj.setSelectionRange)
-      obj.setSelectionRange(0,0);
-
-    obj.focus();
-    };
-
-  // set all fields of a form disabled
-  this.lock_form = function(form, lock)
-    {
-    if (!form || !form.elements)
-      return;
-    
-    var type;
-    for (var n=0; n<form.elements.length; n++)
-      {
-      type = form.elements[n];
-      if (type=='hidden')
-        continue;
-        
-      form.elements[n].disabled = lock;
-      }
-    };
-    
-  }  // end object rcube_webmail
-
-
-/**
- * Class for sending HTTP requests
- * @constructor
- */
-function rcube_http_request()
-  {
-  this.url = '';
-  this.busy = false;
-  this.xmlhttp = null;
-
-  // reset object properties
-  this.reset = function()
-    {
-    // set unassigned event handlers
-    this.onloading = function(){ };
-    this.onloaded = function(){ };
-    this.oninteractive = function(){ };
-    this.oncomplete = function(){ };
-    this.onabort = function(){ };
-    this.onerror = function(){ };
-    
-    this.url = '';
-    this.busy = false;
-    this.xmlhttp = null;
-    }
-
-  // create HTMLHTTP object
-  this.build = function()
-    {
-    if (window.XMLHttpRequest)
-      this.xmlhttp = new XMLHttpRequest();
-    else if (window.ActiveXObject)
-      {
-      try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
-      catch(e) { this.xmlhttp = null; }
-      }
-    else
-      {
-      
-      }
-    }
-
-  // send GET request
-  this.GET = function(url)
-    {
-    this.build();
-
-    if (!this.xmlhttp)
-      {
-      this.onerror(this);
-      return false;
-      }
-
-    var _ref = this;
-    this.url = url;
-    this.busy = true;
-
-    this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); };
-    this.xmlhttp.open('GET', url, true);
-    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
-    this.xmlhttp.send(null);
-    };
-
-  this.POST = function(url, body, contentType)
-    {
-    // default value for contentType if not provided
-    if (typeof(contentType) == 'undefined')
-      contentType = 'application/x-www-form-urlencoded';
-
-    this.build();
-    
-    if (!this.xmlhttp)
-    {
-       this.onerror(this);
-       return false;
-    }
-    
-    var req_body = body;
-    if (typeof(body) == 'object')
-    {
-      req_body = '';
-      for (var p in body)
-        req_body += (req_body ? '&' : '') + p+'='+urlencode(body[p]);
-    }
-
-    var ref = this;
-    this.url = url;
-    this.busy = true;
-    
-    this.xmlhttp.onreadystatechange = function() { ref.xmlhttp_onreadystatechange(); };
-    this.xmlhttp.open('POST', url, true);
-    this.xmlhttp.setRequestHeader('Content-Type', contentType);
-    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
-    this.xmlhttp.send(req_body);
-    };
-
-  // handle onreadystatechange event
-  this.xmlhttp_onreadystatechange = function()
-    {
-    if(this.xmlhttp.readyState == 1)
-      this.onloading(this);
-
-    else if(this.xmlhttp.readyState == 2)
-      this.onloaded(this);
-
-    else if(this.xmlhttp.readyState == 3)
-      this.oninteractive(this);
-
-    else if(this.xmlhttp.readyState == 4)
-      {
-      try {
-        if (this.xmlhttp.status == 0)
-          this.onabort(this);
-        else if(this.xmlhttp.status == 200)
-          this.oncomplete(this);
-        else
-          this.onerror(this);
-
-        this.busy = false;
-        }
-      catch(err)
-        {
-        this.onerror(this);
-        this.busy = false;
-        }
-      }
-    }
-
-  // getter method for HTTP headers
-  this.get_header = function(name)
-    {
-    return this.xmlhttp.getResponseHeader(name);
-    };
-
-  this.get_text = function()
-    {
-    return this.xmlhttp.responseText;
-    };
-
-  this.get_xml = function()
-    {
-    return this.xmlhttp.responseXML;
-    };
-
-  this.reset();
-  
-  }  // end class rcube_http_request
-
-// helper function to call the init method with a delay
-function call_init(o)
-  {
-    window.setTimeout('if (window[\''+o+'\'] && window[\''+o+'\'].init) { '+o+'.init(); }',
-        bw.win ? 500 : 200);
-  }
+function rcube_webmail(){
+this.env=new Object();
+this.labels=new Object();
+this.buttons=new Object();
+this.gui_objects=new Object();
+this.commands=new Object();
+this.onloads=new Array();
+rcube_webmail_client=this;
+this.ref="rcube_webmail_client";
+var _1=this;
+this.dblclick_time=500;
+this.message_time=3000;
+this.identifier_expr=new RegExp("[^0-9a-z-_]","gi");
+this.mimetypes=new Array("text/plain","text/html","text/xml","image/jpeg","image/gif","image/png","application/x-javascript","application/pdf","application/x-shockwave-flash");
+this.env.keep_alive=60;
+this.env.request_timeout=180;
+this.env.draft_autosave=0;
+this.env.comm_path="./";
+this.env.bin_path="./bin/";
+this.env.blankpage="program/blank.gif";
+this.set_env=function(p,_3){
+if(p!=null&&typeof (p)=="object"&&!_3){
+for(var n in p){
+this.env[n]=p[n];
+}
+}else{
+this.env[p]=_3;
+}
+};
+this.add_label=function(_5,_6){
+this.labels[_5]=_6;
+};
+this.register_button=function(_7,id,_9,_a,_b,_c){
+if(!this.buttons[_7]){
+this.buttons[_7]=new Array();
+}
+var _d={id:id,type:_9};
+if(_a){
+_d.act=_a;
+}
+if(_b){
+_d.sel=_b;
+}
+if(_c){
+_d.over=_c;
+}
+this.buttons[_7][this.buttons[_7].length]=_d;
+};
+this.gui_object=function(_e,id){
+this.gui_objects[_e]=id;
+};
+this.add_onload=function(f){
+this.onloads[this.onloads.length]=f;
+};
+this.init=function(){
+var p=this;
+this.task=this.env.task;
+if(!bw.dom||!bw.xmlhttp_test()){
+this.goto_url("error","_code=0x199");
+return;
+}
+for(var n in this.gui_objects){
+this.gui_objects[n]=rcube_find_object(this.gui_objects[n]);
+}
+if(this.env.framed&&parent.rcmail&&parent.rcmail.set_busy){
+parent.rcmail.set_busy(false);
+}
+this.enable_command("logout","mail","addressbook","settings",true);
+if(this.env.permaurl){
+this.enable_command("permaurl",true);
+}
+switch(this.task){
+case "mail":
+if(this.gui_objects.messagelist){
+this.message_list=new rcube_list_widget(this.gui_objects.messagelist,{multiselect:true,draggable:true,keyboard:true,dblclick_time:this.dblclick_time});
+this.message_list.row_init=function(o){
+p.init_message_row(o);
+};
+this.message_list.addEventListener("dblclick",function(o){
+p.msglist_dbl_click(o);
+});
+this.message_list.addEventListener("keypress",function(o){
+p.msglist_keypress(o);
+});
+this.message_list.addEventListener("select",function(o){
+p.msglist_select(o);
+});
+this.message_list.addEventListener("dragstart",function(o){
+p.drag_start(o);
+});
+this.message_list.addEventListener("dragmove",function(o,e){
+p.drag_move(e);
+});
+this.message_list.addEventListener("dragend",function(o){
+p.drag_active=false;
+});
+this.message_list.init();
+this.enable_command("toggle_status","toggle_flag",true);
+if(this.gui_objects.mailcontframe){
+this.gui_objects.mailcontframe.onmousedown=function(e){
+return p.click_on_list(e);
+};
+document.onmouseup=function(e){
+return p.doc_mouse_up(e);
+};
+}else{
+this.message_list.focus();
+}
+}
+if(this.env.coltypes){
+this.set_message_coltypes(this.env.coltypes);
+}
+this.enable_command("list","checkmail","compose","add-contact","search","reset-search","collapse-folder",true);
+if(this.env.search_text!=null&&document.getElementById("quicksearchbox")!=null){
+document.getElementById("quicksearchbox").value=this.env.search_text;
+}
+if(this.env.action=="show"||this.env.action=="preview"){
+this.enable_command("show","reply","reply-all","forward","moveto","delete","mark","viewsource","print","load-attachment","load-headers",true);
+if(this.env.next_uid){
+this.enable_command("nextmessage",true);
+this.enable_command("lastmessage",true);
+}
+if(this.env.prev_uid){
+this.enable_command("previousmessage",true);
+this.enable_command("firstmessage",true);
+}
+}
+if(this.env.trash_mailbox&&this.env.mailbox!=this.env.trash_mailbox){
+this.set_alttext("delete","movemessagetotrash");
+}
+if(this.env.action=="preview"&&this.env.framed&&parent.rcmail){
+this.enable_command("compose","add-contact",false);
+parent.rcmail.show_contentframe(true);
+}
+if((this.env.action=="show"||this.env.action=="preview")&&this.env.blockedobjects){
+if(this.gui_objects.remoteobjectsmsg){
+this.gui_objects.remoteobjectsmsg.style.display="block";
+}
+this.enable_command("load-images","always-load",true);
+}
+if(this.env.action=="compose"){
+this.enable_command("add-attachment","send-attachment","remove-attachment","send",true);
+if(this.env.spellcheck){
+this.env.spellcheck.spelling_state_observer=function(s){
+_1.set_spellcheck_state(s);
+};
+this.set_spellcheck_state("ready");
+if(rcube_find_object("_is_html").value=="1"){
+this.display_spellcheck_controls(false);
+}
+}
+if(this.env.drafts_mailbox){
+this.enable_command("savedraft",true);
+}
+document.onmouseup=function(e){
+return p.doc_mouse_up(e);
+};
+}
+if(this.env.messagecount){
+this.enable_command("select-all","select-none","expunge",true);
+}
+if(this.purge_mailbox_test()){
+this.enable_command("purge",true);
+}
+this.set_page_buttons();
+if(this.env.action=="compose"){
+this.init_messageform();
+}
+if(this.env.action=="print"){
+window.print();
+}
+if(this.gui_objects.mailboxlist){
+this.env.unread_counts={};
+this.gui_objects.folderlist=this.gui_objects.mailboxlist;
+this.http_request("getunread","");
+}
+if(this.env.mdn_request&&this.env.uid){
+var _1f="_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox);
+if(confirm(this.get_label("mdnrequest"))){
+this.http_post("sendmdn",_1f);
+}else{
+this.http_post("mark",_1f+"&_flag=mdnsent");
+}
+}
+break;
+case "addressbook":
+if(this.gui_objects.contactslist){
+this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:true,draggable:true,keyboard:true});
+this.contact_list.addEventListener("keypress",function(o){
+p.contactlist_keypress(o);
+});
+this.contact_list.addEventListener("select",function(o){
+p.contactlist_select(o);
+});
+this.contact_list.addEventListener("dragstart",function(o){
+p.drag_start(o);
+});
+this.contact_list.addEventListener("dragmove",function(o,e){
+p.drag_move(e);
+});
+this.contact_list.addEventListener("dragend",function(o){
+p.drag_active=false;
+});
+this.contact_list.init();
+if(this.env.cid){
+this.contact_list.highlight_row(this.env.cid);
+}
+if(this.gui_objects.contactslist.parentNode){
+this.gui_objects.contactslist.parentNode.onmousedown=function(e){
+return p.click_on_list(e);
+};
+document.onmouseup=function(e){
+return p.doc_mouse_up(e);
+};
+}else{
+this.contact_list.focus();
+}
+}
+this.set_page_buttons();
+if(this.env.address_sources&&this.env.address_sources[this.env.source]&&!this.env.address_sources[this.env.source].readonly){
+this.enable_command("add",true);
+}
+if(this.env.cid){
+this.enable_command("show","edit",true);
+}
+if((this.env.action=="add"||this.env.action=="edit")&&this.gui_objects.editform){
+this.enable_command("save",true);
+}else{
+this.enable_command("search","reset-search","moveto","import",true);
+}
+if(this.contact_list&&this.contact_list.rowcount>0){
+this.enable_command("export",true);
+}
+this.enable_command("list",true);
+break;
+case "settings":
+this.enable_command("preferences","identities","save","folders",true);
+if(this.env.action=="identities"||this.env.action=="edit-identity"||this.env.action=="add-identity"){
+this.enable_command("add",this.env.identities_level<2);
+this.enable_command("delete","edit",true);
+}
+if(this.env.action=="edit-identity"||this.env.action=="add-identity"){
+this.enable_command("save",true);
+}
+if(this.env.action=="folders"){
+this.enable_command("subscribe","unsubscribe","create-folder","rename-folder","delete-folder",true);
+}
+if(this.gui_objects.identitieslist){
+this.identity_list=new rcube_list_widget(this.gui_objects.identitieslist,{multiselect:false,draggable:false,keyboard:false});
+this.identity_list.addEventListener("select",function(o){
+p.identity_select(o);
+});
+this.identity_list.init();
+this.identity_list.focus();
+if(this.env.iid){
+this.identity_list.highlight_row(this.env.iid);
+}
+}
+if(this.gui_objects.subscriptionlist){
+this.init_subscription_list();
+}
+break;
+case "login":
+var _29=rcube_find_object("rcmloginuser");
+var _2a=rcube_find_object("rcmloginpwd");
+var _2b=rcube_find_object("rcmlogintz");
+if(_29){
+_29.onkeyup=function(e){
+return rcmail.login_user_keyup(e);
+};
+}
+if(_29&&_29.value==""){
+_29.focus();
+}else{
+if(_2a){
+_2a.focus();
+}
+}
+if(_2b){
+_2b.value=new Date().getTimezoneOffset()/-60;
+}
+this.enable_command("login",true);
+break;
+default:
+break;
+}
+this.enable_command("logout",true);
+this.loaded=true;
+if(this.pending_message){
+this.display_message(this.pending_message[0],this.pending_message[1]);
+}
+this.start_keepalive();
+for(var i=0;i<this.onloads.length;i++){
+if(typeof (this.onloads[i])=="string"){
+eval(this.onloads[i]);
+}else{
+if(typeof (this.onloads[i])=="function"){
+this.onloads[i]();
+}
+}
+}
+};
+this.start_keepalive=function(){
+if(this.env.keep_alive&&!this.env.framed&&this.task=="mail"&&this.gui_objects.mailboxlist){
+this._int=setInterval(function(){
+_1.check_for_recent(false);
+},this.env.keep_alive*1000);
+}else{
+if(this.env.keep_alive&&!this.env.framed&&this.task!="login"){
+this._int=setInterval(function(){
+_1.send_keep_alive();
+},this.env.keep_alive*1000);
+}
+}
+};
+this.init_message_row=function(row){
+var uid=row.uid;
+if(uid&&this.env.messages[uid]){
+row.deleted=this.env.messages[uid].deleted?true:false;
+row.unread=this.env.messages[uid].unread?true:false;
+row.replied=this.env.messages[uid].replied?true:false;
+row.flagged=this.env.messages[uid].flagged?true:false;
+row.forwarded=this.env.messages[uid].forwarded?true:false;
+}
+if((row.icon=row.obj.cells[0].childNodes[0])&&row.icon.nodeName=="IMG"){
+var p=this;
+row.icon.id="msgicn_"+row.uid;
+row.icon._row=row.obj;
+row.icon.onmousedown=function(e){
+p.command("toggle_status",this);
+};
+}
+if(!this.env.flagged_col&&this.env.coltypes){
+var _32;
+if((_32=find_in_array("flag",this.env.coltypes))>=0){
+this.set_env("flagged_col",_32+1);
+}
+}
+if(this.env.flagged_col&&(row.flagged_icon=row.obj.cells[this.env.flagged_col].childNodes[0])&&row.flagged_icon.nodeName=="IMG"){
+var p=this;
+row.flagged_icon.id="flaggedicn_"+row.uid;
+row.flagged_icon._row=row.obj;
+row.flagged_icon.onmousedown=function(e){
+p.command("toggle_flag",this);
+};
+}
+};
+this.init_messageform=function(){
+if(!this.gui_objects.messageform){
+return false;
+}
+var _34=rcube_find_object("_from");
+var _35=rcube_find_object("_to");
+var _36=rcube_find_object("_cc");
+var _37=rcube_find_object("_bcc");
+var _38=rcube_find_object("_replyto");
+var _39=rcube_find_object("_subject");
+var _3a=rcube_find_object("_message");
+var _3b=rcube_find_object("_draft_saveid");
+if(_35){
+this.init_address_input_events(_35);
+}
+if(_36){
+this.init_address_input_events(_36);
+}
+if(_37){
+this.init_address_input_events(_37);
+}
+if(_34&&_34.type=="select-one"&&(!_3b||_3b.value=="")&&rcube_find_object("_is_html").value!="1"){
+this.change_identity(_34);
+}
+if(_35&&_35.value==""){
+_35.focus();
+}else{
+if(_39&&_39.value==""){
+_39.focus();
+}else{
+if(_3a){
+this.set_caret2start(_3a);
+}
+}
+}
+this.compose_field_hash(true);
+this.auto_save_start();
+};
+this.init_address_input_events=function(obj){
+var _3d=function(e){
+return _1.ksearch_keypress(e,this);
+};
+if(obj.addEventListener){
+obj.addEventListener(bw.safari?"keydown":"keypress",_3d,false);
+}else{
+obj.onkeydown=_3d;
+}
+obj.setAttribute("autocomplete","off");
+};
+this.command=function(_3f,_40,obj){
+if(obj&&obj.blur){
+obj.blur();
+}
+if(this.busy){
+return false;
+}
+if(!this.commands[_3f]){
+if(this.env.framed&&parent.rcmail&&parent.rcmail.command){
+parent.rcmail.command(_3f,_40);
+}
+return false;
+}
+if(this.task=="mail"&&this.env.action=="compose"&&(_3f=="list"||_3f=="mail"||_3f=="addressbook"||_3f=="settings")){
+if(this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning"))){
+return false;
+}
+}
+switch(_3f){
+case "login":
+if(this.gui_objects.loginform){
+this.gui_objects.loginform.submit();
+}
+break;
+case "logout":
+this.goto_url("logout","",true);
+break;
+case "mail":
+case "addressbook":
+case "settings":
+this.switch_task(_3f);
+break;
+case "permaurl":
+if(obj&&obj.href&&obj.target){
+return true;
+}else{
+if(this.env.permaurl){
+parent.location.href=this.env.permaurl;
+}
+}
+break;
+case "list":
+if(this.task=="mail"){
+if(this.env.search_request<0||(_40!=""&&(this.env.search_request&&_40!=this.env.mailbox))){
+this.reset_qsearch();
+}
+this.list_mailbox(_40);
+if(this.env.trash_mailbox){
+this.set_alttext("delete",this.env.mailbox!=this.env.trash_mailbox?"movemessagetotrash":"deletemessage");
+}
+}else{
+if(this.task=="addressbook"){
+if(this.env.search_request<0||(this.env.search_request&&_40!=this.env.source)){
+this.reset_qsearch();
+}
+this.list_contacts(_40);
+this.enable_command("add",(this.env.address_sources&&!this.env.address_sources[_40].readonly));
+}
+}
+break;
+case "load-headers":
+this.load_headers(obj);
+break;
+case "sort":
+var _42=_40.split("_");
+var _43=_42[0];
+var _44=_42[1]?_42[1].toUpperCase():null;
+var _45;
+if(_44==null){
+if(this.env.sort_col==_43){
+_44=this.env.sort_order=="ASC"?"DESC":"ASC";
+}else{
+_44=this.env.sort_order;
+}
+}
+if(this.env.sort_col==_43&&this.env.sort_order==_44){
+break;
+}
+if(_45=document.getElementById("rcm"+this.env.sort_col)){
+this.set_classname(_45,"sorted"+(this.env.sort_order.toUpperCase()),false);
+}
+if(_45=document.getElementById("rcm"+_43)){
+this.set_classname(_45,"sorted"+_44,true);
+}
+this.env.sort_col=_43;
+this.env.sort_order=_44;
+this.list_mailbox("","",_43+"_"+_44);
+break;
+case "nextpage":
+this.list_page("next");
+break;
+case "lastpage":
+this.list_page("last");
+break;
+case "previouspage":
+this.list_page("prev");
+break;
+case "firstpage":
+this.list_page("first");
+break;
+case "expunge":
+if(this.env.messagecount){
+this.expunge_mailbox(this.env.mailbox);
+}
+break;
+case "purge":
+case "empty-mailbox":
+if(this.env.messagecount){
+this.purge_mailbox(this.env.mailbox);
+}
+break;
+case "show":
+if(this.task=="mail"){
+var uid=this.get_single_uid();
+if(uid&&(!this.env.uid||uid!=this.env.uid)){
+if(this.env.mailbox==this.env.drafts_mailbox){
+this.goto_url("compose","_draft_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true);
+}else{
+this.show_message(uid);
+}
+}
+}else{
+if(this.task=="addressbook"){
+var cid=_40?_40:this.get_single_cid();
+if(cid&&!(this.env.action=="show"&&cid==this.env.cid)){
+this.load_contact(cid,"show");
+}
+}
+}
+break;
+case "add":
+if(this.task=="addressbook"){
+this.load_contact(0,"add");
+}else{
+if(this.task=="settings"){
+this.identity_list.clear_selection();
+this.load_identity(0,"add-identity");
+}
+}
+break;
+case "edit":
+var cid;
+if(this.task=="addressbook"&&(cid=this.get_single_cid())){
+this.load_contact(cid,"edit");
+}else{
+if(this.task=="settings"&&_40){
+this.load_identity(_40,"edit-identity");
+}
+}
+break;
+case "save-identity":
+case "save":
+if(this.gui_objects.editform){
+var _48=rcube_find_object("_pagesize");
+var _49=rcube_find_object("_name");
+var _4a=rcube_find_object("_email");
+if(_48&&isNaN(parseInt(_48.value))){
+alert(this.get_label("nopagesizewarning"));
+_48.focus();
+break;
+}else{
+if(_49&&_49.value==""){
+alert(this.get_label("nonamewarning"));
+_49.focus();
+break;
+}else{
+if(_4a&&!rcube_check_email(_4a.value)){
+alert(this.get_label("noemailwarning"));
+_4a.focus();
+break;
+}
+}
+}
+this.gui_objects.editform.submit();
+}
+break;
+case "delete":
+if(this.task=="mail"){
+this.delete_messages();
+}else{
+if(this.task=="addressbook"){
+this.delete_contacts();
+}else{
+if(this.task=="settings"){
+this.delete_identity();
+}
+}
+}
+break;
+case "move":
+case "moveto":
+if(this.task=="mail"){
+this.move_messages(_40);
+}else{
+if(this.task=="addressbook"&&this.drag_active){
+this.copy_contact(null,_40);
+}
+}
+break;
+case "mark":
+if(_40){
+this.mark_message(_40);
+}
+break;
+case "toggle_status":
+if(_40&&!_40._row){
+break;
+}
+var uid;
+var _4b="read";
+if(_40._row.uid){
+uid=_40._row.uid;
+if(this.message_list.rows[uid].deleted){
+_4b="undelete";
+}else{
+if(!this.message_list.rows[uid].unread){
+_4b="unread";
+}
+}
+}
+this.mark_message(_4b,uid);
+break;
+case "toggle_flag":
+if(_40&&!_40._row){
+break;
+}
+var uid;
+var _4b="flagged";
+if(_40._row.uid){
+uid=_40._row.uid;
+if(this.message_list.rows[uid].flagged){
+_4b="unflagged";
+}
+}
+this.mark_message(_4b,uid);
+break;
+case "always-load":
+if(this.env.uid&&this.env.sender){
+this.add_contact(urlencode(this.env.sender));
+window.setTimeout(function(){
+_1.command("load-images");
+},300);
+break;
+}
+case "load-images":
+if(this.env.uid){
+this.show_message(this.env.uid,true,this.env.action=="preview");
+}
+break;
+case "load-attachment":
+var _4c="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+_40.part;
+if(this.env.uid&&_40.mimetype&&find_in_array(_40.mimetype,this.mimetypes)>=0){
+if(_40.mimetype=="text/html"){
+_4c+="&_safe=1";
+}
+this.attachment_win=window.open(this.env.comm_path+"&_action=get&"+_4c+"&_frame=1","rcubemailattachment");
+if(this.attachment_win){
+window.setTimeout(function(){
+_1.attachment_win.focus();
+},10);
+break;
+}
+}
+this.goto_url("get",_4c+"&_download=1",false);
+break;
+case "select-all":
+this.message_list.select_all(_40);
+break;
+case "select-none":
+this.message_list.clear_selection();
+break;
+case "nextmessage":
+if(this.env.next_uid){
+this.show_message(this.env.next_uid,false,this.env.action=="preview");
+}
+break;
+case "lastmessage":
+if(this.env.last_uid){
+this.show_message(this.env.last_uid);
+}
+break;
+case "previousmessage":
+if(this.env.prev_uid){
+this.show_message(this.env.prev_uid,false,this.env.action=="preview");
+}
+break;
+case "firstmessage":
+if(this.env.first_uid){
+this.show_message(this.env.first_uid);
+}
+break;
+case "checkmail":
+this.check_for_recent(true);
+break;
+case "compose":
+var url=this.env.comm_path+"&_action=compose";
+if(this.task=="mail"){
+url+="&_mbox="+urlencode(this.env.mailbox);
+if(this.env.mailbox==this.env.drafts_mailbox){
+var uid;
+if(uid=this.get_single_uid()){
+url+="&_draft_uid="+uid;
+}
+}else{
+if(_40){
+url+="&_to="+urlencode(_40);
+}
+}
+}else{
+if(this.task=="addressbook"){
+if(_40&&_40.indexOf("@")>0){
+url=this.get_task_url("mail",url);
+this.redirect(url+"&_to="+urlencode(_40));
+break;
+}
+var _4e=new Array();
+if(_40){
+_4e[_4e.length]=_40;
+}else{
+if(this.contact_list){
+var _4f=this.contact_list.get_selection();
+for(var n=0;n<_4f.length;n++){
+_4e[_4e.length]=_4f[n];
+}
+}
+}
+if(_4e.length){
+this.http_request("mailto","_cid="+urlencode(_4e.join(","))+"&_source="+urlencode(this.env.source),true);
+}
+break;
+}
+}
+url=url.replace(/&_framed=1/,"");
+this.redirect(url);
+break;
+case "spellcheck":
+if(window.tinyMCE&&tinyMCE.get("compose-body")){
+tinyMCE.execCommand("mceSpellCheck",true);
+}else{
+if(this.env.spellcheck&&this.env.spellcheck.spellCheck&&this.spellcheck_ready){
+this.env.spellcheck.spellCheck(this.env.spellcheck.check_link);
+this.set_spellcheck_state("checking");
+}
+}
+break;
+case "savedraft":
+self.clearTimeout(this.save_timer);
+if(!this.gui_objects.messageform){
+break;
+}
+if(!this.env.drafts_mailbox||this.cmp_hash==this.compose_field_hash()){
+break;
+}
+this.set_busy(true,"savingmessage");
+var _51=this.gui_objects.messageform;
+_51.target="savetarget";
+_51._draft.value="1";
+_51.submit();
+break;
+case "send":
+if(!this.gui_objects.messageform){
+break;
+}
+if(!this.check_compose_input()){
+break;
+}
+self.clearTimeout(this.save_timer);
+this.set_busy(true,"sendingmessage");
+var _51=this.gui_objects.messageform;
+_51.target="savetarget";
+_51._draft.value="";
+_51.submit();
+clearTimeout(this.request_timer);
+break;
+case "add-attachment":
+this.show_attachment_form(true);
+case "send-attachment":
+self.clearTimeout(this.save_timer);
+this.upload_file(_40);
+break;
+case "remove-attachment":
+this.remove_attachment(_40);
+break;
+case "reply-all":
+case "reply":
+var uid;
+if(uid=this.get_single_uid()){
+this.goto_url("compose","_reply_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(_3f=="reply-all"?"&_all=1":""),true);
+}
+break;
+case "forward":
+var uid;
+if(uid=this.get_single_uid()){
+this.goto_url("compose","_forward_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true);
+}
+break;
+case "print":
+var uid;
+if(uid=this.get_single_uid()){
+_1.printwin=window.open(this.env.comm_path+"&_action=print&_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(this.env.safemode?"&_safe=1":""));
+if(this.printwin){
+window.setTimeout(function(){
+_1.printwin.focus();
+},20);
+if(this.env.action!="show"){
+this.mark_message("read",uid);
+}
+}
+}
+break;
+case "viewsource":
+var uid;
+if(uid=this.get_single_uid()){
+_1.sourcewin=window.open(this.env.comm_path+"&_action=viewsource&_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox));
+if(this.sourcewin){
+window.setTimeout(function(){
+_1.sourcewin.focus();
+},20);
+}
+}
+break;
+case "add-contact":
+this.add_contact(_40);
+break;
+case "search":
+if(!_40&&this.gui_objects.qsearchbox){
+_40=this.gui_objects.qsearchbox.value;
+}
+if(_40){
+this.qsearch(_40);
+break;
+}
+case "reset-search":
+var s=this.env.search_request;
+this.reset_qsearch();
+if(s&&this.env.mailbox){
+this.list_mailbox(this.env.mailbox);
+}else{
+if(s&&this.task=="addressbook"){
+this.list_contacts(this.env.source);
+}
+}
+break;
+case "import":
+if(this.env.action=="import"&&this.gui_objects.importform){
+var _53=document.getElementById("rcmimportfile");
+if(_53&&!_53.value){
+alert(this.get_label("selectimportfile"));
+break;
+}
+this.gui_objects.importform.submit();
+this.set_busy(true,"importwait");
+this.lock_form(this.gui_objects.importform,true);
+}else{
+this.goto_url("import");
+}
+break;
+case "export":
+if(this.contact_list.rowcount>0){
+var _54=(this.env.source?"_source="+urlencode(this.env.source)+"&":"");
+if(this.env.search_request){
+_54+="_search="+this.env.search_request;
+}
+this.goto_url("export",_54);
+}
+break;
+case "collapse-folder":
+if(_40){
+this.collapse_folder(_40);
+}
+break;
+case "preferences":
+this.goto_url("");
+break;
+case "identities":
+this.goto_url("identities");
+break;
+case "delete-identity":
+this.delete_identity();
+case "folders":
+this.goto_url("folders");
+break;
+case "subscribe":
+this.subscribe_folder(_40);
+break;
+case "unsubscribe":
+this.unsubscribe_folder(_40);
+break;
+case "create-folder":
+this.create_folder(_40);
+break;
+case "rename-folder":
+this.rename_folder(_40);
+break;
+case "delete-folder":
+this.delete_folder(_40);
+break;
+}
+return obj?false:true;
+};
+this.enable_command=function(){
+var _55=arguments;
+if(!_55.length){
+return -1;
+}
+var _56;
+var _57=_55[_55.length-1];
+for(var n=0;n<_55.length-1;n++){
+_56=_55[n];
+this.commands[_56]=_57;
+this.set_button(_56,(_57?"act":"pas"));
+}
+return true;
+};
+this.set_busy=function(a,_5a){
+if(a&&_5a){
+var msg=this.get_label(_5a);
+if(msg==_5a){
+msg="Loading...";
+}
+this.display_message(msg,"loading",true);
+}else{
+if(!a){
+this.hide_message();
+}
+}
+this.busy=a;
+if(this.gui_objects.editform){
+this.lock_form(this.gui_objects.editform,a);
+}
+if(this.request_timer){
+clearTimeout(this.request_timer);
+}
+if(a&&this.env.request_timeout){
+this.request_timer=window.setTimeout(function(){
+_1.request_timed_out();
+},this.env.request_timeout*1000);
+}
+};
+this.get_label=function(_5c){
+if(this.labels[_5c]){
+return this.labels[_5c];
+}else{
+return _5c;
+}
+};
+this.switch_task=function(_5d){
+if(this.task===_5d&&_5d!="mail"){
+return;
+}
+var url=this.get_task_url(_5d);
+if(_5d=="mail"){
+url+="&_mbox=INBOX";
+}
+this.redirect(url);
+};
+this.get_task_url=function(_5f,url){
+if(!url){
+url=this.env.comm_path;
+}
+return url.replace(/_task=[a-z]+/,"_task="+_5f);
+};
+this.request_timed_out=function(){
+this.set_busy(false);
+this.display_message("Request timed out!","error");
+};
+this.doc_mouse_up=function(e){
+var _62,li;
+if(this.message_list){
+if(!rcube_mouse_is_over(e,this.message_list.list)){
+this.message_list.blur();
+}
+_62=this.env.mailboxes;
+}else{
+if(this.contact_list){
+if(!rcube_mouse_is_over(e,this.contact_list.list)){
+this.contact_list.blur();
+}
+_62=this.env.address_sources;
+}else{
+if(this.ksearch_value){
+this.ksearch_blur();
+}
+}
+}
+if(this.drag_active&&_62&&this.env.last_folder_target){
+this.set_classname(this.get_folder_li(this.env.last_folder_target),"droptarget",false);
+this.command("moveto",_62[this.env.last_folder_target].id);
+this.env.last_folder_target=null;
+}
+};
+this.drag_start=function(_64){
+this.initialBodyScrollTop=bw.ie?0:window.pageYOffset;
+this.initialMailBoxScrollTop=document.getElementById("mailboxlist-container").scrollTop;
+var _65=this.task=="mail"?this.env.mailboxes:this.env.address_sources;
+this.drag_active=true;
+if(this.preview_timer){
+clearTimeout(this.preview_timer);
+}
+if(this.gui_objects.folderlist&&_65){
+var li,pos,_64,_68;
+_64=rcube_find_object(this.task=="mail"?"mailboxlist":"directorylist");
+pos=rcube_get_object_pos(_64);
+this.env.folderlist_coords={x1:pos.x,y1:pos.y,x2:pos.x+_64.offsetWidth,y2:pos.y+_64.offsetHeight};
+this.env.folder_coords=new Array();
+for(var k in _65){
+if(li=this.get_folder_li(k)){
+pos=rcube_get_object_pos(li.firstChild);
+if(_68=li.firstChild.offsetHeight){
+this.env.folder_coords[k]={x1:pos.x,y1:pos.y,x2:pos.x+li.firstChild.offsetWidth,y2:pos.y+_68};
+}
+}
+}
+}
+};
+this.drag_move=function(e){
+if(this.gui_objects.folderlist&&this.env.folder_coords){
+var _6b=bw.ie?-document.documentElement.scrollTop:this.initialBodyScrollTop;
+var _6c=this.initialMailBoxScrollTop-document.getElementById("mailboxlist-container").scrollTop;
+var _6d=-_6c-_6b;
+var li,pos,_70;
+_70=rcube_event.get_mouse_pos(e);
+pos=this.env.folderlist_coords;
+_70.y+=_6d;
+if(_70.x<pos.x1||_70.x>=pos.x2||_70.y<pos.y1||_70.y>=pos.y2){
+if(this.env.last_folder_target){
+this.set_classname(this.get_folder_li(this.env.last_folder_target),"droptarget",false);
+this.env.last_folder_target=null;
+}
+return;
+}
+for(var k in this.env.folder_coords){
+pos=this.env.folder_coords[k];
+if(this.check_droptarget(k)&&((_70.x>=pos.x1)&&(_70.x<pos.x2)&&(_70.y>=pos.y1)&&(_70.y<pos.y2))){
+this.set_classname(this.get_folder_li(k),"droptarget",true);
+this.env.last_folder_target=k;
+}else{
+this.set_classname(this.get_folder_li(k),"droptarget",false);
+}
+}
+}
+};
+this.collapse_folder=function(id){
+var div;
+if((li=this.get_folder_li(id))&&(div=li.getElementsByTagName("div")[0])&&(div.className.match(/collapsed/)||div.className.match(/expanded/))){
+var ul=li.getElementsByTagName("ul")[0];
+if(div.className.match(/collapsed/)){
+ul.style.display="";
+this.set_classname(div,"collapsed",false);
+this.set_classname(div,"expanded",true);
+var reg=new RegExp("&"+urlencode(id)+"&");
+this.set_env("collapsed_folders",this.env.collapsed_folders.replace(reg,""));
+}else{
+ul.style.display="none";
+this.set_classname(div,"expanded",false);
+this.set_classname(div,"collapsed",true);
+this.set_env("collapsed_folders",this.env.collapsed_folders+"&"+urlencode(id)+"&");
+if(this.env.mailbox.indexOf(id+this.env.delimiter)==0){
+this.command("list",id);
+}
+}
+if((bw.ie6||bw.ie7)&&li.nextSibling&&(li.nextSibling.getElementsByTagName("ul").length>0)&&li.nextSibling.getElementsByTagName("ul")[0].style&&(li.nextSibling.getElementsByTagName("ul")[0].style.display!="none")){
+li.nextSibling.getElementsByTagName("ul")[0].style.display="none";
+li.nextSibling.getElementsByTagName("ul")[0].style.display="";
+}
+this.http_post("save-pref","_name=collapsed_folders&_value="+urlencode(this.env.collapsed_folders));
+this.set_unread_count_display(id,false);
+}
+};
+this.click_on_list=function(e){
+if(this.gui_objects.qsearchbox){
+this.gui_objects.qsearchbox.blur();
+}
+if(this.message_list){
+this.message_list.focus();
+}else{
+if(this.contact_list){
+this.contact_list.focus();
+}
+}
+var _77;
+if(_77=this.get_folder_li()){
+this.set_classname(_77,"unfocused",true);
+}
+return rcube_event.get_button(e)==2?true:rcube_event.cancel(e);
+};
+this.msglist_select=function(_78){
+if(this.preview_timer){
+clearTimeout(this.preview_timer);
+}
+var _79=_78.selection.length==1;
+if(this.env.mailbox==this.env.drafts_mailbox){
+this.enable_command("reply","reply-all","forward",false);
+this.enable_command("show","print",_79);
+this.enable_command("delete","moveto","mark",(_78.selection.length>0?true:false));
+}else{
+this.enable_command("show","reply","reply-all","forward","print",_79);
+this.enable_command("delete","moveto","mark",(_78.selection.length>0?true:false));
+}
+if(_79&&this.env.contentframe&&!_78.multi_selecting){
+this.preview_timer=window.setTimeout(function(){
+_1.msglist_get_preview();
+},200);
+}else{
+if(this.env.contentframe){
+this.show_contentframe(false);
+}
+}
+};
+this.msglist_dbl_click=function(_7a){
+if(this.preview_timer){
+clearTimeout(this.preview_timer);
+}
+var uid=_7a.get_single_selection();
+if(uid&&this.env.mailbox==this.env.drafts_mailbox){
+this.goto_url("compose","_draft_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true);
+}else{
+if(uid){
+this.show_message(uid,false,false);
+}
+}
+};
+this.msglist_keypress=function(_7c){
+if(_7c.key_pressed==_7c.ENTER_KEY){
+this.command("show");
+}else{
+if(_7c.key_pressed==_7c.DELETE_KEY){
+this.command("delete");
+}else{
+if(_7c.key_pressed==_7c.BACKSPACE_KEY){
+this.command("delete");
+}else{
+_7c.shiftkey=false;
+}
+}
+}
+};
+this.msglist_get_preview=function(){
+var uid=this.get_single_uid();
+if(uid&&this.env.contentframe&&!this.drag_active){
+this.show_message(uid,false,true);
+}else{
+if(this.env.contentframe){
+this.show_contentframe(false);
+}
+}
+};
+this.check_droptarget=function(id){
+if(this.task=="mail"){
+return (this.env.mailboxes[id]&&this.env.mailboxes[id].id!=this.env.mailbox&&!this.env.mailboxes[id].virtual);
+}else{
+if(this.task=="addressbook"){
+return (id!=this.env.source&&this.env.address_sources[id]&&!this.env.address_sources[id].readonly);
+}else{
+if(this.task=="settings"){
+return (id!=this.env.folder);
+}
+}
+}
+};
+this.show_message=function(id,_80,_81){
+if(!id){
+return;
+}
+var _82="";
+var _83=_81?"preview":"show";
+var _84=window;
+if(_81&&this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_84=window.frames[this.env.contentframe];
+_82="&_framed=1";
+}
+if(_80){
+_82="&_safe=1";
+}
+if(this.env.search_request){
+_82+="&_search="+this.env.search_request;
+}
+var url="&_action="+_83+"&_uid="+id+"&_mbox="+urlencode(this.env.mailbox)+_82;
+if(_83=="preview"&&String(_84.location.href).indexOf(url)>=0){
+this.show_contentframe(true);
+}else{
+this.set_busy(true,"loading");
+_84.location.href=this.env.comm_path+url;
+if(_83=="preview"&&this.message_list&&this.message_list.rows[id]&&this.message_list.rows[id].unread){
+this.set_message(id,"unread",false);
+if(this.env.unread_counts[this.env.mailbox]){
+this.env.unread_counts[this.env.mailbox]-=1;
+this.set_unread_count(this.env.mailbox,this.env.unread_counts[this.env.mailbox],this.env.mailbox=="INBOX");
+}
+}
+}
+};
+this.show_contentframe=function(_86){
+var frm;
+if(this.env.contentframe&&(frm=rcube_find_object(this.env.contentframe))){
+if(!_86&&window.frames[this.env.contentframe]){
+if(window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0){
+window.frames[this.env.contentframe].location.href=this.env.blankpage;
+}
+}else{
+if(!bw.safari&&!bw.konq){
+frm.style.display=_86?"block":"none";
+}
+}
+}
+if(!_86&&this.busy){
+this.set_busy(false);
+}
+};
+this.list_page=function(_88){
+if(_88=="next"){
+_88=this.env.current_page+1;
+}
+if(_88=="last"){
+_88=this.env.pagecount;
+}
+if(_88=="prev"&&this.env.current_page>1){
+_88=this.env.current_page-1;
+}
+if(_88=="first"&&this.env.current_page>1){
+_88=1;
+}
+if(_88>0&&_88<=this.env.pagecount){
+this.env.current_page=_88;
+if(this.task=="mail"){
+this.list_mailbox(this.env.mailbox,_88);
+}else{
+if(this.task=="addressbook"){
+this.list_contacts(this.env.source,_88);
+}
+}
+}
+};
+this.filter_mailbox=function(_89){
+var _8a;
+if(this.gui_objects.qsearchbox){
+_8a=this.gui_objects.qsearchbox.value;
+}
+this.message_list.clear();
+this.env.current_page=1;
+this.set_busy(true,"searching");
+this.http_request("search","_filter="+_89+(_8a?"&_q="+urlencode(_8a):"")+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):""),true);
+};
+this.list_mailbox=function(_8b,_8c,_8d){
+this.last_selected=0;
+var _8e="";
+var _8f=window;
+if(!_8b){
+_8b=this.env.mailbox;
+}
+if(_8d){
+_8e+="&_sort="+_8d;
+}
+if(this.env.search_request){
+_8e+="&_search="+this.env.search_request;
+}
+if(!_8c&&_8b!=this.env.mailbox){
+_8c=1;
+this.env.current_page=_8c;
+if(this.message_list){
+this.message_list.clear_selection();
+}
+this.show_contentframe(false);
+}
+if(_8b!=this.env.mailbox||(_8b==this.env.mailbox&&!_8c&&!_8d)){
+_8e+="&_refresh=1";
+}
+this.select_folder(_8b,this.env.mailbox);
+this.env.mailbox=_8b;
+if(this.gui_objects.messagelist){
+this.list_mailbox_remote(_8b,_8c,_8e);
+return;
+}
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_8f=window.frames[this.env.contentframe];
+_8e+="&_framed=1";
+}
+if(_8b){
+this.set_busy(true,"loading");
+_8f.location.href=this.env.comm_path+"&_mbox="+urlencode(_8b)+(_8c?"&_page="+_8c:"")+_8e;
+}
+};
+this.list_mailbox_remote=function(_90,_91,_92){
+this.message_list.clear();
+var url="_mbox="+urlencode(_90)+(_91?"&_page="+_91:"");
+this.set_busy(true,"loading");
+this.http_request("list",url+_92,true);
+};
+this.expunge_mailbox=function(_94){
+var _95=false;
+var _96="";
+if(_94==this.env.mailbox){
+_95=true;
+this.set_busy(true,"loading");
+_96="&_reload=1";
+}
+var url="_mbox="+urlencode(_94);
+this.http_post("expunge",url+_96,_95);
+};
+this.purge_mailbox=function(_98){
+var _99=false;
+var _9a="";
+if(!confirm(this.get_label("purgefolderconfirm"))){
+return false;
+}
+if(_98==this.env.mailbox){
+_99=true;
+this.set_busy(true,"loading");
+_9a="&_reload=1";
+}
+var url="_mbox="+urlencode(_98);
+this.http_post("purge",url+_9a,_99);
+return true;
+};
+this.purge_mailbox_test=function(){
+return (this.env.messagecount&&(this.env.mailbox==this.env.trash_mailbox||this.env.mailbox==this.env.junk_mailbox||this.env.mailbox.match("^"+RegExp.escape(this.env.trash_mailbox)+RegExp.escape(this.env.delimiter))||this.env.mailbox.match("^"+RegExp.escape(this.env.junk_mailbox)+RegExp.escape(this.env.delimiter))));
+};
+this.set_message_icon=function(uid){
+var _9d;
+var _9e=this.message_list.rows;
+if(!_9e[uid]){
+return false;
+}
+if(_9e[uid].deleted&&this.env.deletedicon){
+_9d=this.env.deletedicon;
+}else{
+if(_9e[uid].replied&&this.env.repliedicon){
+if(_9e[uid].forwarded&&this.env.forwardedrepliedicon){
+_9d=this.env.forwardedrepliedicon;
+}else{
+_9d=this.env.repliedicon;
+}
+}else{
+if(_9e[uid].forwarded&&this.env.forwardedicon){
+_9d=this.env.forwardedicon;
+}else{
+if(_9e[uid].unread&&this.env.unreadicon){
+_9d=this.env.unreadicon;
+}else{
+if(this.env.messageicon){
+_9d=this.env.messageicon;
+}
+}
+}
+}
+}
+if(_9d&&_9e[uid].icon){
+_9e[uid].icon.src=_9d;
+}
+_9d="";
+if(_9e[uid].flagged&&this.env.flaggedicon){
+_9d=this.env.flaggedicon;
+}else{
+if(!_9e[uid].flagged&&this.env.unflaggedicon){
+_9d=this.env.unflaggedicon;
+}
+}
+if(_9e[uid].flagged_icon&&_9d){
+_9e[uid].flagged_icon.src=_9d;
+}
+};
+this.set_message_status=function(uid,_a0,_a1){
+var _a2=this.message_list.rows;
+if(!_a2[uid]){
+return false;
+}
+if(_a0=="unread"){
+_a2[uid].unread=_a1;
+}else{
+if(_a0=="deleted"){
+_a2[uid].deleted=_a1;
+}else{
+if(_a0=="replied"){
+_a2[uid].replied=_a1;
+}else{
+if(_a0=="forwarded"){
+_a2[uid].forwarded=_a1;
+}else{
+if(_a0=="flagged"){
+_a2[uid].flagged=_a1;
+}
+}
+}
+}
+}
+this.env.messages[uid]=_a2[uid];
+};
+this.set_message=function(uid,_a4,_a5){
+var _a6=this.message_list.rows;
+if(!_a6[uid]){
+return false;
+}
+if(_a4){
+this.set_message_status(uid,_a4,_a5);
+}
+if(_a6[uid].unread&&_a6[uid].classname.indexOf("unread")<0){
+_a6[uid].classname+=" unread";
+this.set_classname(_a6[uid].obj,"unread",true);
+}else{
+if(!_a6[uid].unread&&_a6[uid].classname.indexOf("unread")>=0){
+_a6[uid].classname=_a6[uid].classname.replace(/\s*unread/,"");
+this.set_classname(_a6[uid].obj,"unread",false);
+}
+}
+if(_a6[uid].deleted&&_a6[uid].classname.indexOf("deleted")<0){
+_a6[uid].classname+=" deleted";
+this.set_classname(_a6[uid].obj,"deleted",true);
+}else{
+if(!_a6[uid].deleted&&_a6[uid].classname.indexOf("deleted")>=0){
+_a6[uid].classname=_a6[uid].classname.replace(/\s*deleted/,"");
+this.set_classname(_a6[uid].obj,"deleted",false);
+}
+}
+if(_a6[uid].flagged&&_a6[uid].classname.indexOf("flagged")<0){
+_a6[uid].classname+=" flagged";
+this.set_classname(_a6[uid].obj,"flagged",true);
+}else{
+if(!_a6[uid].flagged&&_a6[uid].classname.indexOf("flagged")>=0){
+_a6[uid].classname=_a6[uid].classname.replace(/\s*flagged/,"");
+this.set_classname(_a6[uid].obj,"flagged",false);
+}
+}
+this.set_message_icon(uid);
+};
+this.move_messages=function(_a7){
+if(!_a7||_a7==this.env.mailbox||(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){
+return;
+}
+var _a8=false;
+var _a9="&_target_mbox="+urlencode(_a7)+"&_from="+(this.env.action?this.env.action:"");
+if(this.env.action=="show"){
+_a8=true;
+this.set_busy(true,"movingmessage");
+}else{
+if(!this.env.flag_for_deletion){
+this.show_contentframe(false);
+}
+}
+this.enable_command("reply","reply-all","forward","delete","mark","print",false);
+this._with_selected_messages("moveto",_a8,_a9,(this.env.flag_for_deletion?false:true));
+};
+this.delete_messages=function(){
+var _aa=this.message_list?this.message_list.get_selection():new Array();
+if(!this.env.uid&&!_aa.length){
+return;
+}
+if(this.env.trash_mailbox&&String(this.env.mailbox).toLowerCase()!=String(this.env.trash_mailbox).toLowerCase()){
+if(this.message_list&&this.message_list.shiftkey){
+if(confirm(this.get_label("deletemessagesconfirm"))){
+this.permanently_remove_messages();
+}
+}else{
+this.move_messages(this.env.trash_mailbox);
+}
+}else{
+if(this.env.trash_mailbox&&String(this.env.mailbox).toLowerCase()==String(this.env.trash_mailbox).toLowerCase()){
+this.permanently_remove_messages();
+}else{
+if(!this.env.trash_mailbox&&this.env.flag_for_deletion){
+this.mark_message("delete");
+if(this.env.action=="show"){
+this.command("nextmessage","",this);
+}else{
+if(_aa.length==1){
+this.message_list.select_next();
+}
+}
+}else{
+if(!this.env.trash_mailbox){
+this.permanently_remove_messages();
+}
+}
+}
+}
+};
+this.permanently_remove_messages=function(){
+if(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length)){
+return;
+}
+this.show_contentframe(false);
+this._with_selected_messages("delete",false,"&_from="+(this.env.action?this.env.action:""),true);
+};
+this._with_selected_messages=function(_ab,_ac,_ad,_ae){
+var _af=new Array();
+if(this.env.uid){
+_af[0]=this.env.uid;
+}else{
+var _b0=this.message_list.get_selection();
+var _b1=this.message_list.rows;
+var id;
+for(var n=0;n<_b0.length;n++){
+id=_b0[n];
+_af[_af.length]=id;
+if(_ae){
+this.message_list.remove_row(id,(n==_b0.length-1));
+}else{
+this.set_message_status(id,"deleted",true);
+if(this.env.read_when_deleted){
+this.set_message_status(id,"unread",false);
+}
+this.set_message(id);
+}
+}
+}
+if(this.env.search_request){
+_ad+="&_search="+this.env.search_request;
+}
+this.http_post(_ab,"_uid="+_af.join(",")+"&_mbox="+urlencode(this.env.mailbox)+_ad,_ac);
+};
+this.mark_message=function(_b4,uid){
+var _b6=new Array();
+var _b7=new Array();
+var _b8=this.message_list?this.message_list.get_selection():new Array();
+if(uid){
+_b6[0]=uid;
+}else{
+if(this.env.uid){
+_b6[0]=this.env.uid;
+}else{
+if(this.message_list){
+for(var n=0;n<_b8.length;n++){
+_b6[_b6.length]=_b8[n];
+}
+}
+}
+}
+if(!this.message_list){
+_b7=_b6;
+}else{
+for(var id,n=0;n<_b6.length;n++){
+id=_b6[n];
+if((_b4=="read"&&this.message_list.rows[id].unread)||(_b4=="unread"&&!this.message_list.rows[id].unread)||(_b4=="delete"&&!this.message_list.rows[id].deleted)||(_b4=="undelete"&&this.message_list.rows[id].deleted)||(_b4=="flagged"&&!this.message_list.rows[id].flagged)||(_b4=="unflagged"&&this.message_list.rows[id].flagged)){
+_b7[_b7.length]=id;
+}
+}
+}
+if(!_b7.length){
+return;
+}
+switch(_b4){
+case "read":
+case "unread":
+this.toggle_read_status(_b4,_b7);
+break;
+case "delete":
+case "undelete":
+this.toggle_delete_status(_b7);
+break;
+case "flagged":
+case "unflagged":
+this.toggle_flagged_status(_b4,_b6);
+break;
+}
+};
+this.toggle_read_status=function(_bb,_bc){
+for(var i=0;i<_bc.length;i++){
+this.set_message(_bc[i],"unread",(_bb=="unread"?true:false));
+}
+this.http_post("mark","_uid="+_bc.join(",")+"&_flag="+_bb);
+};
+this.toggle_flagged_status=function(_be,_bf){
+for(var i=0;i<_bf.length;i++){
+this.set_message(_bf[i],"flagged",(_be=="flagged"?true:false));
+}
+this.http_post("mark","_uid="+_bf.join(",")+"&_flag="+_be);
+};
+this.toggle_delete_status=function(_c1){
+var _c2=this.message_list?this.message_list.rows:new Array();
+if(_c1.length==1){
+if(!_c2.length||(_c2[_c1[0]]&&!_c2[_c1[0]].deleted)){
+this.flag_as_deleted(_c1);
+}else{
+this.flag_as_undeleted(_c1);
+}
+return true;
+}
+var _c3=true;
+for(var i=0;i<_c1.length;i++){
+uid=_c1[i];
+if(_c2[uid]){
+if(!_c2[uid].deleted){
+_c3=false;
+break;
+}
+}
+}
+if(_c3){
+this.flag_as_undeleted(_c1);
+}else{
+this.flag_as_deleted(_c1);
+}
+return true;
+};
+this.flag_as_undeleted=function(_c5){
+for(var i=0;i<_c5.length;i++){
+this.set_message(_c5[i],"deleted",false);
+}
+this.http_post("mark","_uid="+_c5.join(",")+"&_flag=undelete");
+return true;
+};
+this.flag_as_deleted=function(_c7){
+var _c8="";
+var _c9=new Array();
+var _ca=this.message_list?this.message_list.rows:new Array();
+for(var i=0;i<_c7.length;i++){
+uid=_c7[i];
+if(_ca[uid]){
+this.set_message(uid,"deleted",true);
+if(_ca[uid].unread){
+_c9[_c9.length]=uid;
+}
+}
+}
+if(_c9.length){
+_c8="&_ruid="+_c9.join(",");
+}
+this.http_post("mark","_uid="+_c7.join(",")+"&_flag=delete"+_c8);
+return true;
+};
+this.flag_deleted_as_read=function(_cc){
+var _cd;
+var _ce=this.message_list?this.message_list.rows:new Array();
+var str=String(_cc);
+var _d0=new Array();
+_d0=str.split(",");
+for(var uid,i=0;i<_d0.length;i++){
+uid=_d0[i];
+if(_ce[uid]){
+this.set_message(uid,"unread",false);
+}
+}
+};
+this.login_user_keyup=function(e){
+var key=rcube_event.get_keycode(e);
+var elm;
+if((key==13)&&(elm=rcube_find_object("_pass"))){
+elm.focus();
+return false;
+}
+};
+this.check_compose_input=function(){
+var _d6=rcube_find_object("_to");
+var _d7=rcube_find_object("_cc");
+var _d8=rcube_find_object("_bcc");
+var _d9=rcube_find_object("_from");
+var _da=rcube_find_object("_subject");
+var _db=rcube_find_object("_message");
+if(_d9.type=="text"&&!rcube_check_email(_d9.value,true)){
+alert(this.get_label("nosenderwarning"));
+_d9.focus();
+return false;
+}
+var _dc=_d6.value?_d6.value:(_d7.value?_d7.value:_d8.value);
+if(!rcube_check_email(_dc.replace(/^\s+/,"").replace(/[\s,;]+$/,""),true)){
+alert(this.get_label("norecipientwarning"));
+_d6.focus();
+return false;
+}
+if(_da&&_da.value==""){
+var _dd=prompt(this.get_label("nosubjectwarning"),this.get_label("nosubject"));
+if(!_dd&&_dd!==""){
+_da.focus();
+return false;
+}else{
+_da.value=_dd?_dd:this.get_label("nosubject");
+}
+}
+if((!window.tinyMCE||!tinyMCE.get("compose-body"))&&_db.value==""&&!confirm(this.get_label("nobodywarning"))){
+_db.focus();
+return false;
+}else{
+if(window.tinyMCE&&tinyMCE.get("compose-body")&&!tinyMCE.get("compose-body").getContent()&&!confirm(this.get_label("nobodywarning"))){
+tinyMCE.get("compose-body").focus();
+return false;
+}
+}
+this.stop_spellchecking();
+return true;
+};
+this.stop_spellchecking=function(){
+if(this.env.spellcheck&&!this.spellcheck_ready){
+exec_event(this.env.spellcheck.check_link,"click");
+this.set_spellcheck_state("ready");
+}
+};
+this.display_spellcheck_controls=function(vis){
+if(this.env.spellcheck){
+if(!vis){
+this.stop_spellchecking();
+}
+this.env.spellcheck.check_link.style.visibility=vis?"visible":"hidden";
+this.env.spellcheck.switch_lan_pic.style.visibility=vis?"visible":"hidden";
+}
+};
+this.set_spellcheck_state=function(s){
+this.spellcheck_ready=(s=="check_spelling"||s=="ready");
+this.enable_command("spellcheck",this.spellcheck_ready);
+};
+this.set_draft_id=function(id){
+var f;
+if(f=rcube_find_object("_draft_saveid")){
+f.value=id;
+}
+};
+this.auto_save_start=function(){
+if(this.env.draft_autosave){
+this.save_timer=self.setTimeout(function(){
+_1.command("savedraft");
+},this.env.draft_autosave*1000);
+}
+this.busy=false;
+};
+this.compose_field_hash=function(_e2){
+var _e3=rcube_find_object("_to");
+var _e4=rcube_find_object("_cc");
+var _e5=rcube_find_object("_bcc");
+var _e6=rcube_find_object("_subject");
+var _e7,_e8;
+var str="";
+if(_e3&&_e3.value){
+str+=_e3.value+":";
+}
+if(_e4&&_e4.value){
+str+=_e4.value+":";
+}
+if(_e5&&_e5.value){
+str+=_e5.value+":";
+}
+if(_e6&&_e6.value){
+str+=_e6.value+":";
+}
+if(_e7=tinyMCE.get("compose-body")){
+str+=_e7.getContent();
+}else{
+_e8=rcube_find_object("_message");
+str+=_e8.value;
+}
+if(_e2){
+this.cmp_hash=str;
+}
+return str;
+};
+this.change_identity=function(obj){
+if(!obj||!obj.options){
+return false;
+}
+var id=obj.options[obj.selectedIndex].value;
+var _ec=rcube_find_object("_message");
+var _ed=_ec?_ec.value:"";
+var _ee=(rcube_find_object("_is_html").value=="1");
+var sig,p;
+if(!this.env.identity){
+this.env.identity=id;
+}
+if(!_ee){
+if(this.env.identity&&this.env.signatures&&this.env.signatures[this.env.identity]){
+if(this.env.signatures[this.env.identity]["is_html"]){
+sig=this.env.signatures[this.env.identity]["plain_text"];
+}else{
+sig=this.env.signatures[this.env.identity]["text"];
+}
+if(sig.indexOf("-- ")!=0){
+sig="-- \n"+sig;
+}
+p=_ed.lastIndexOf(sig);
+if(p>=0){
+_ed=_ed.substring(0,p-1)+_ed.substring(p+sig.length,_ed.length);
+}
+}
+_ed=_ed.replace(/[\r\n]+$/,"");
+if(this.env.signatures&&this.env.signatures[id]){
+sig=this.env.signatures[id]["text"];
+if(this.env.signatures[id]["is_html"]){
+sig=this.env.signatures[id]["plain_text"];
+}
+if(sig.indexOf("-- ")!=0){
+sig="-- \n"+sig;
+}
+_ed+="\n\n"+sig;
+}
+}else{
+var _f1=tinyMCE.get("compose-body");
+if(this.env.signatures){
+var _f2=_f1.dom.get("_rc_sig");
+var _f3="";
+var _f4=true;
+if(!_f2){
+if(bw.ie){
+_f1.getBody().appendChild(_f1.getDoc().createElement("br"));
+}
+_f2=_f1.getDoc().createElement("div");
+_f2.setAttribute("id","_rc_sig");
+_f1.getBody().appendChild(_f2);
+}
+if(this.env.signatures[id]){
+_f3=this.env.signatures[id]["text"];
+_f4=this.env.signatures[id]["is_html"];
+if(_f3){
+if(_f4&&this.env.signatures[id]["plain_text"].indexOf("-- ")!=0){
+_f3="<p>-- </p>"+_f3;
+}else{
+if(!_f4&&_f3.indexOf("-- ")!=0){
+_f3="-- \n"+_f3;
+}
+}
+}
+}
+if(_f4){
+_f2.innerHTML=_f3;
+}else{
+_f2.innerHTML="<pre>"+_f3+"</pre>";
+}
+}
+}
+if(_ec){
+_ec.value=_ed;
+}
+this.env.identity=id;
+return true;
+};
+this.show_attachment_form=function(a){
+if(!this.gui_objects.uploadbox){
+return false;
+}
+var elm,_f7;
+if(elm=this.gui_objects.uploadbox){
+if(a&&(_f7=this.gui_objects.attachmentlist)){
+var pos=rcube_get_object_pos(_f7);
+var _f9=pos.x;
+var top=pos.y+_f7.offsetHeight+10;
+elm.style.top=top+"px";
+elm.style.left=_f9+"px";
+}
+elm.style.visibility=a?"visible":"hidden";
+}
+try{
+if(!a&&this.gui_objects.attachmentform!=this.gui_objects.messageform){
+this.gui_objects.attachmentform.reset();
+}
+}
+catch(e){
+}
+return true;
+};
+this.upload_file=function(_fb){
+if(!_fb){
+return false;
+}
+var _fc=false;
+for(var n=0;n<_fb.elements.length;n++){
+if(_fb.elements[n].type=="file"&&_fb.elements[n].value){
+_fc=true;
+break;
+}
+}
+if(_fc){
+var ts=new Date().getTime();
+var _ff="rcmupload"+ts;
+if(document.all){
+var html="<iframe name=\""+_ff+"\" src=\"program/blank.gif\" style=\"width:0;height:0;visibility:hidden;\"></iframe>";
+document.body.insertAdjacentHTML("BeforeEnd",html);
+}else{
+var _101=document.createElement("IFRAME");
+_101.name=_ff;
+_101.style.border="none";
+_101.style.width=0;
+_101.style.height=0;
+_101.style.visibility="hidden";
+document.body.appendChild(_101);
+}
+_fb.target=_ff;
+_fb.action=this.env.comm_path+"&_action=upload";
+_fb.setAttribute("enctype","multipart/form-data");
+_fb.submit();
+}
+this.gui_objects.attachmentform=_fb;
+return true;
+};
+this.add2attachment_list=function(name,_103){
+if(!this.gui_objects.attachmentlist){
+return false;
+}
+var li=document.createElement("LI");
+li.id=name;
+li.innerHTML=_103;
+this.gui_objects.attachmentlist.appendChild(li);
+return true;
+};
+this.remove_from_attachment_list=function(name){
+if(!this.gui_objects.attachmentlist){
+return false;
+}
+var list=this.gui_objects.attachmentlist.getElementsByTagName("li");
+for(i=0;i<list.length;i++){
+if(list[i].id==name){
+this.gui_objects.attachmentlist.removeChild(list[i]);
+}
+}
+};
+this.remove_attachment=function(name){
+if(name){
+this.http_post("remove-attachment","_file="+urlencode(name));
+}
+return true;
+};
+this.add_contact=function(_108){
+if(_108){
+this.http_post("addcontact","_address="+_108);
+}
+return true;
+};
+this.qsearch=function(_109,_10a){
+if(_109!=""){
+if(this.message_list){
+this.message_list.clear();
+}else{
+if(this.contact_list){
+this.contact_list.clear(true);
+this.show_contentframe(false);
+}
+}
+if(this.gui_objects.search_filter){
+_10a="&_filter="+this.gui_objects.search_filter.value;
+}
+this.env.current_page=1;
+this.set_busy(true,"searching");
+this.http_request("search","_q="+urlencode(_109)+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):"")+(this.env.source?"&_source="+urlencode(this.env.source):"")+(_10a?_10a:""),true);
+}
+return true;
+};
+this.reset_qsearch=function(){
+if(this.gui_objects.qsearchbox){
+this.gui_objects.qsearchbox.value="";
+}
+this.env.search_request=null;
+return true;
+};
+this.sent_successfully=function(type,msg){
+this.list_mailbox();
+this.display_message(msg,type,true);
+};
+this.ksearch_keypress=function(e,obj){
+if(this.ksearch_timer){
+clearTimeout(this.ksearch_timer);
+}
+var _10f;
+var key=rcube_event.get_keycode(e);
+var mod=rcube_event.get_modifier(e);
+switch(key){
+case 38:
+case 40:
+if(!this.ksearch_pane){
+break;
+}
+var dir=key==38?1:0;
+_10f=document.getElementById("rcmksearchSelected");
+if(!_10f){
+_10f=this.ksearch_pane.ul.firstChild;
+}
+if(_10f){
+this.ksearch_select(dir?_10f.previousSibling:_10f.nextSibling);
+}
+return rcube_event.cancel(e);
+case 9:
+if(mod==SHIFT_KEY){
+break;
+}
+case 13:
+if(this.ksearch_selected===null||!this.ksearch_input||!this.ksearch_value){
+break;
+}
+this.insert_recipient(this.ksearch_selected);
+this.ksearch_hide();
+return rcube_event.cancel(e);
+case 27:
+this.ksearch_hide();
+break;
+case 37:
+case 39:
+if(mod!=SHIFT_KEY){
+return;
+}
+}
+this.ksearch_timer=window.setTimeout(function(){
+_1.ksearch_get_results();
+},200);
+this.ksearch_input=obj;
+return true;
+};
+this.ksearch_select=function(node){
+var _114=document.getElementById("rcmksearchSelected");
+if(_114&&node){
+_114.removeAttribute("id");
+this.set_classname(_114,"selected",false);
+}
+if(node){
+node.setAttribute("id","rcmksearchSelected");
+this.set_classname(node,"selected",true);
+this.ksearch_selected=node._rcm_id;
+}
+};
+this.insert_recipient=function(id){
+if(!this.env.contacts[id]||!this.ksearch_input){
+return;
+}
+var _116=this.ksearch_input.value.toLowerCase();
+var cpos=this.get_caret_pos(this.ksearch_input);
+var p=_116.lastIndexOf(this.ksearch_value,cpos);
+var pre=this.ksearch_input.value.substring(0,p);
+var end=this.ksearch_input.value.substring(p+this.ksearch_value.length,this.ksearch_input.value.length);
+var _11b=this.env.contacts[id]+", ";
+this.ksearch_input.value=pre+_11b+end;
+cpos=p+_11b.length;
+if(this.ksearch_input.setSelectionRange){
+this.ksearch_input.setSelectionRange(cpos,cpos);
+}
+};
+this.ksearch_get_results=function(){
+var _11c=this.ksearch_input?this.ksearch_input.value:null;
+if(_11c===null){
+return;
+}
+if(this.ksearch_pane&&this.ksearch_pane.visible){
+this.ksearch_pane.show(0);
+}
+var cpos=this.get_caret_pos(this.ksearch_input);
+var p=_11c.lastIndexOf(",",cpos-1);
+var q=_11c.substring(p+1,cpos);
+q=q.replace(/(^\s+|\s+$)/g,"").toLowerCase();
+if(!q.length||q==this.ksearch_value){
+return;
+}
+this.ksearch_value=q;
+this.display_message(this.get_label("searching"),"loading",true);
+this.http_post("autocomplete","_search="+q);
+};
+this.ksearch_query_results=function(_120,_121){
+if(_121!=this.ksearch_value){
+return;
+}
+this.hide_message();
+this.env.contacts=_120?_120:[];
+this.ksearch_display_results(this.env.contacts);
+};
+this.ksearch_display_results=function(_122){
+if(_122.length&&this.ksearch_input){
+var p,ul,li;
+if(!this.ksearch_pane){
+ul=document.createElement("UL");
+this.ksearch_pane=new rcube_layer("rcmKSearchpane",{vis:0,zindex:30000});
+this.ksearch_pane.elm.appendChild(ul);
+this.ksearch_pane.ul=ul;
+}else{
+ul=this.ksearch_pane.ul;
+}
+ul.innerHTML="";
+for(i=0;i<_122.length;i++){
+li=document.createElement("LI");
+li.innerHTML=_122[i].replace(new RegExp("("+this.ksearch_value+")","ig"),"##$1%%").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/##([^%]+)%%/g,"<b>$1</b>");
+li.onmouseover=function(){
+_1.ksearch_select(this);
+};
+li.onmouseup=function(){
+_1.ksearch_click(this);
+};
+li._rcm_id=i;
+ul.appendChild(li);
+}
+ul.firstChild.setAttribute("id","rcmksearchSelected");
+this.set_classname(ul.firstChild,"selected",true);
+this.ksearch_selected=0;
+var pos=rcube_get_object_pos(this.ksearch_input);
+this.ksearch_pane.move(pos.x,pos.y+this.ksearch_input.offsetHeight);
+this.ksearch_pane.show(1);
+}else{
+this.ksearch_hide();
+}
+};
+this.ksearch_click=function(node){
+if(this.ksearch_input){
+this.ksearch_input.focus();
+}
+this.insert_recipient(node._rcm_id);
+this.ksearch_hide();
+};
+this.ksearch_blur=function(){
+if(this.ksearch_timer){
+clearTimeout(this.ksearch_timer);
+}
+this.ksearch_value="";
+this.ksearch_input=null;
+this.ksearch_hide();
+};
+this.ksearch_hide=function(){
+this.ksearch_selected=null;
+if(this.ksearch_pane){
+this.ksearch_pane.show(0);
+}
+};
+this.contactlist_keypress=function(list){
+if(list.key_pressed==list.DELETE_KEY){
+this.command("delete");
+}
+};
+this.contactlist_select=function(list){
+if(this.preview_timer){
+clearTimeout(this.preview_timer);
+}
+var id,_12b,_1=this;
+if(id=list.get_single_selection()){
+this.preview_timer=window.setTimeout(function(){
+_1.load_contact(id,"show");
+},200);
+}else{
+if(this.env.contentframe){
+this.show_contentframe(false);
+}
+}
+this.enable_command("compose",list.selection.length>0);
+this.enable_command("edit",(id&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly)?true:false);
+this.enable_command("delete",list.selection.length&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly);
+return false;
+};
+this.list_contacts=function(src,page){
+var _12e="";
+var _12f=window;
+if(!src){
+src=this.env.source;
+}
+if(page&&this.current_page==page&&src==this.env.source){
+return false;
+}
+if(src!=this.env.source){
+page=1;
+this.env.current_page=page;
+this.reset_qsearch();
+}
+this.select_folder(src,this.env.source);
+this.env.source=src;
+if(this.gui_objects.contactslist){
+this.list_contacts_remote(src,page);
+return;
+}
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_12f=window.frames[this.env.contentframe];
+_12e="&_framed=1";
+}
+if(this.env.search_request){
+_12e+="&_search="+this.env.search_request;
+}
+this.set_busy(true,"loading");
+_12f.location.href=this.env.comm_path+(src?"&_source="+urlencode(src):"")+(page?"&_page="+page:"")+_12e;
+};
+this.list_contacts_remote=function(src,page){
+this.contact_list.clear(true);
+this.show_contentframe(false);
+this.enable_command("delete","compose",false);
+var url=(src?"_source="+urlencode(src):"")+(page?(src?"&":"")+"_page="+page:"");
+this.env.source=src;
+if(this.env.search_request){
+url+="&_search="+this.env.search_request;
+}
+this.set_busy(true,"loading");
+this.http_request("list",url,true);
+};
+this.load_contact=function(cid,_134,_135){
+var _136="";
+var _137=window;
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_136="&_framed=1";
+_137=window.frames[this.env.contentframe];
+this.show_contentframe(true);
+}else{
+if(_135){
+return false;
+}
+}
+if(_134&&(cid||_134=="add")&&!this.drag_active){
+this.set_busy(true);
+_137.location.href=this.env.comm_path+"&_action="+_134+"&_source="+urlencode(this.env.source)+"&_cid="+urlencode(cid)+_136;
+}
+return true;
+};
+this.copy_contact=function(cid,to){
+if(!cid){
+cid=this.contact_list.get_selection().join(",");
+}
+if(to!=this.env.source&&cid&&this.env.address_sources[to]&&!this.env.address_sources[to].readonly){
+this.http_post("copy","_cid="+urlencode(cid)+"&_source="+urlencode(this.env.source)+"&_to="+urlencode(to));
+}
+};
+this.delete_contacts=function(){
+var _13a=this.contact_list.get_selection();
+if(!(_13a.length||this.env.cid)||!confirm(this.get_label("deletecontactconfirm"))){
+return;
+}
+var _13b=new Array();
+var qs="";
+if(this.env.cid){
+_13b[_13b.length]=this.env.cid;
+}else{
+var id;
+for(var n=0;n<_13a.length;n++){
+id=_13a[n];
+_13b[_13b.length]=id;
+this.contact_list.remove_row(id,(n==_13a.length-1));
+}
+if(_13a.length==1){
+this.show_contentframe(false);
+}
+}
+if(this.env.search_request){
+qs+="&_search="+this.env.search_request;
+}
+this.http_post("delete","_cid="+urlencode(_13b.join(","))+"&_source="+urlencode(this.env.source)+"&_from="+(this.env.action?this.env.action:"")+qs);
+return true;
+};
+this.update_contact_row=function(cid,_140){
+var row;
+if(this.contact_list.rows[cid]&&(row=this.contact_list.rows[cid].obj)){
+for(var c=0;c<_140.length;c++){
+if(row.cells[c]){
+row.cells[c].innerHTML=_140[c];
+}
+}
+return true;
+}
+return false;
+};
+this.init_subscription_list=function(){
+var p=this;
+this.subscription_list=new rcube_list_widget(this.gui_objects.subscriptionlist,{multiselect:false,draggable:true,keyboard:false,toggleselect:true});
+this.subscription_list.addEventListener("select",function(o){
+p.subscription_select(o);
+});
+this.subscription_list.addEventListener("dragstart",function(o){
+p.drag_active=true;
+});
+this.subscription_list.addEventListener("dragend",function(o){
+p.subscription_move_folder(o);
+});
+this.subscription_list.row_init=function(row){
+var _148=row.obj.getElementsByTagName("A");
+if(_148[0]){
+_148[0].onclick=function(){
+p.rename_folder(row.id);
+return false;
+};
+}
+if(_148[1]){
+_148[1].onclick=function(){
+p.delete_folder(row.id);
+return false;
+};
+}
+row.obj.onmouseover=function(){
+p.focus_subscription(row.id);
+};
+row.obj.onmouseout=function(){
+p.unfocus_subscription(row.id);
+};
+};
+this.subscription_list.init();
+};
+this.identity_select=function(list){
+var id;
+if(id=list.get_single_selection()){
+this.load_identity(id,"edit-identity");
+}
+};
+this.load_identity=function(id,_14c){
+if(_14c=="edit-identity"&&(!id||id==this.env.iid)){
+return false;
+}
+var _14d="";
+var _14e=window;
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_14d="&_framed=1";
+_14e=window.frames[this.env.contentframe];
+document.getElementById(this.env.contentframe).style.visibility="inherit";
+}
+if(_14c&&(id||_14c=="add-identity")){
+this.set_busy(true);
+_14e.location.href=this.env.comm_path+"&_action="+_14c+"&_iid="+id+_14d;
+}
+return true;
+};
+this.delete_identity=function(id){
+var _150=this.identity_list.get_selection();
+if(!(_150.length||this.env.iid)){
+return;
+}
+if(!id){
+id=this.env.iid?this.env.iid:_150[0];
+}
+this.goto_url("delete-identity","_iid="+id,true);
+return true;
+};
+this.focus_subscription=function(id){
+var row,_153;
+var reg=RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$");
+if(this.drag_active&&this.env.folder&&(row=document.getElementById(id))){
+if(this.env.subscriptionrows[id]&&(_153=this.env.subscriptionrows[id][0])){
+if(this.check_droptarget(_153)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2]&&(_153!=this.env.folder.replace(reg,""))&&(!_153.match(new RegExp("^"+RegExp.escape(this.env.folder+this.env.delimiter))))){
+this.set_env("dstfolder",_153);
+this.set_classname(row,"droptarget",true);
+}
+}else{
+if(this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter)))){
+this.set_env("dstfolder",this.env.delimiter);
+this.set_classname(this.subscription_list.frame,"droptarget",true);
+}
+}
+}
+};
+this.unfocus_subscription=function(id){
+var row;
+this.set_env("dstfolder",null);
+if(this.env.subscriptionrows[id]&&(row=document.getElementById(id))){
+this.set_classname(row,"droptarget",false);
+}else{
+this.set_classname(this.subscription_list.frame,"droptarget",false);
+}
+};
+this.subscription_select=function(list){
+var id,_159;
+if((id=list.get_single_selection())&&this.env.subscriptionrows["rcmrow"+id]&&(_159=this.env.subscriptionrows["rcmrow"+id][0])){
+this.set_env("folder",_159);
+}else{
+this.set_env("folder",null);
+}
+if(this.gui_objects.createfolderhint){
+this.gui_objects.createfolderhint.innerHTML=this.env.folder?this.get_label("addsubfolderhint"):"";
+}
+};
+this.subscription_move_folder=function(list){
+var reg=RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$");
+if(this.env.folder&&this.env.dstfolder&&(this.env.dstfolder!=this.env.folder)&&(this.env.dstfolder!=this.env.folder.replace(reg,""))){
+var reg=new RegExp("[^"+RegExp.escape(this.env.delimiter)+"]*["+RegExp.escape(this.env.delimiter)+"]","g");
+var _15c=this.env.folder.replace(reg,"");
+var _15d=this.env.dstfolder==this.env.delimiter?_15c:this.env.dstfolder+this.env.delimiter+_15c;
+this.set_busy(true,"foldermoving");
+this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.folder)+"&_folder_newname="+urlencode(_15d),true);
+}
+this.drag_active=false;
+this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
+};
+this.create_folder=function(name){
+if(this.edit_folder){
+this.reset_folder_rename();
+}
+var form;
+if((form=this.gui_objects.editform)&&form.elements["_folder_name"]){
+name=form.elements["_folder_name"].value;
+if(name.indexOf(this.env.delimiter)>=0){
+alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")");
+return false;
+}
+if(this.env.folder&&name!=""){
+name=this.env.folder+this.env.delimiter+name;
+}
+this.set_busy(true,"foldercreating");
+this.http_post("create-folder","_name="+urlencode(name),true);
+}else{
+if(form.elements["_folder_name"]){
+form.elements["_folder_name"].focus();
+}
+}
+};
+this.rename_folder=function(id){
+var temp,row,form;
+if(temp=this.edit_folder){
+this.reset_folder_rename();
+if(temp==id){
+return;
+}
+}
+if(id&&this.env.subscriptionrows[id]&&(row=document.getElementById(id))){
+var reg=new RegExp(".*["+RegExp.escape(this.env.delimiter)+"]");
+this.name_input=document.createElement("INPUT");
+this.name_input.value=this.env.subscriptionrows[id][0].replace(reg,"");
+this.name_input.style.width="100%";
+reg=new RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$");
+this.name_input.__parent=this.env.subscriptionrows[id][0].replace(reg,"");
+this.name_input.onkeypress=function(e){
+rcmail.name_input_keypress(e);
+};
+row.cells[0].replaceChild(this.name_input,row.cells[0].firstChild);
+this.edit_folder=id;
+this.name_input.select();
+if(form=this.gui_objects.editform){
+form.onsubmit=function(){
+return false;
+};
+}
+}
+};
+this.reset_folder_rename=function(){
+var cell=this.name_input?this.name_input.parentNode:null;
+if(cell&&this.edit_folder&&this.env.subscriptionrows[this.edit_folder]){
+cell.innerHTML=this.env.subscriptionrows[this.edit_folder][1];
+}
+this.edit_folder=null;
+};
+this.name_input_keypress=function(e){
+var key=rcube_event.get_keycode(e);
+if(key==13){
+var _169=this.name_input?this.name_input.value:null;
+if(this.edit_folder&&_169){
+if(_169.indexOf(this.env.delimiter)>=0){
+alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")");
+return false;
+}
+if(this.name_input.__parent){
+_169=this.name_input.__parent+this.env.delimiter+_169;
+}
+this.set_busy(true,"folderrenaming");
+this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.subscriptionrows[this.edit_folder][0])+"&_folder_newname="+urlencode(_169),true);
+}
+}else{
+if(key==27){
+this.reset_folder_rename();
+}
+}
+};
+this.delete_folder=function(id){
+var _16b=this.env.subscriptionrows[id][0];
+if(this.edit_folder){
+this.reset_folder_rename();
+}
+if(_16b&&confirm(this.get_label("deletefolderconfirm"))){
+this.set_busy(true,"folderdeleting");
+this.http_post("delete-folder","_mboxes="+urlencode(_16b),true);
+this.set_env("folder",null);
+if(this.gui_objects.createfolderhint){
+this.gui_objects.createfolderhint.innerHTML="";
+}
+}
+};
+this.add_folder_row=function(name,_16d,_16e,_16f){
+if(!this.gui_objects.subscriptionlist){
+return false;
+}
+for(var _170 in this.env.subscriptionrows){
+if(this.env.subscriptionrows[_170]!=null&&!this.env.subscriptionrows[_170][2]){
+break;
+}
+}
+var _171,form;
+var _173=this.gui_objects.subscriptionlist.tBodies[0];
+var id="rcmrow"+(_173.childNodes.length+1);
+var _175=this.subscription_list.get_single_selection();
+if(_16e&&_16e.id){
+id=_16e.id;
+_170=_16e.id;
+}
+if(!id||!(_171=document.getElementById(_170))){
+this.goto_url("folders");
+}else{
+var row=this.clone_table_row(_171);
+row.id=id;
+if(_16f&&(_16f=this.get_folder_row_id(_16f))){
+_173.insertBefore(row,document.getElementById(_16f));
+}else{
+_173.appendChild(row);
+}
+if(_16e){
+_173.removeChild(_16e);
+}
+}
+this.env.subscriptionrows[row.id]=[name,_16d,0];
+row.cells[0].innerHTML=_16d;
+if(!_16e){
+row.cells[1].innerHTML="*";
+}
+if(!_16e&&row.cells[2]&&row.cells[2].firstChild.tagName=="INPUT"){
+row.cells[2].firstChild.value=name;
+row.cells[2].firstChild.checked=true;
+}
+if(!_16e&&(form=this.gui_objects.editform)){
+if(form.elements["_folder_oldname"]){
+form.elements["_folder_oldname"].options[form.elements["_folder_oldname"].options.length]=new Option(name,name);
+}
+if(form.elements["_folder_name"]){
+form.elements["_folder_name"].value="";
+}
+}
+this.init_subscription_list();
+if(_175&&document.getElementById("rcmrow"+_175)){
+this.subscription_list.select_row(_175);
+}
+if(document.getElementById(id).scrollIntoView){
+document.getElementById(id).scrollIntoView();
+}
+};
+this.replace_folder_row=function(_177,_178,_179,_17a){
+var id=this.get_folder_row_id(_177);
+var row=document.getElementById(id);
+this.add_folder_row(_178,_179,row,_17a);
+var form,elm;
+if((form=this.gui_objects.editform)&&(elm=form.elements["_folder_oldname"])){
+for(var i=0;i<elm.options.length;i++){
+if(elm.options[i].value==_177){
+elm.options[i].text=_179;
+elm.options[i].value=_178;
+break;
+}
+}
+form.elements["_folder_newname"].value="";
+}
+};
+this.remove_folder_row=function(_180){
+var row;
+var id=this.get_folder_row_id(_180);
+if(id&&(row=document.getElementById(id))){
+row.style.display="none";
+}
+var form;
+if((form=this.gui_objects.editform)&&form.elements["_folder_oldname"]){
+for(var i=0;i<form.elements["_folder_oldname"].options.length;i++){
+if(form.elements["_folder_oldname"].options[i].value==_180){
+form.elements["_folder_oldname"].options[i]=null;
+break;
+}
+}
+}
+if(form&&form.elements["_folder_newname"]){
+form.elements["_folder_newname"].value="";
+}
+};
+this.subscribe_folder=function(_185){
+if(_185){
+this.http_post("subscribe","_mbox="+urlencode(_185));
+}
+};
+this.unsubscribe_folder=function(_186){
+if(_186){
+this.http_post("unsubscribe","_mbox="+urlencode(_186));
+}
+};
+this.get_folder_row_id=function(_187){
+for(var id in this.env.subscriptionrows){
+if(this.env.subscriptionrows[id]&&this.env.subscriptionrows[id][0]==_187){
+break;
+}
+}
+return id;
+};
+this.clone_table_row=function(row){
+var cell,td;
+var _18c=document.createElement("TR");
+for(var n=0;n<row.cells.length;n++){
+cell=row.cells[n];
+td=document.createElement("TD");
+if(cell.className){
+td.className=cell.className;
+}
+if(cell.align){
+td.setAttribute("align",cell.align);
+}
+td.innerHTML=cell.innerHTML;
+_18c.appendChild(td);
+}
+return _18c;
+};
+this.set_page_buttons=function(){
+this.enable_command("nextpage",(this.env.pagecount>this.env.current_page));
+this.enable_command("lastpage",(this.env.pagecount>this.env.current_page));
+this.enable_command("previouspage",(this.env.current_page>1));
+this.enable_command("firstpage",(this.env.current_page>1));
+};
+this.set_button=function(_18e,_18f){
+var _190=this.buttons[_18e];
+var _191,obj;
+if(!_190||!_190.length){
+return false;
+}
+for(var n=0;n<_190.length;n++){
+_191=_190[n];
+obj=document.getElementById(_191.id);
+if(obj&&_191.type=="image"&&!_191.status){
+_191.pas=obj._original_src?obj._original_src:obj.src;
+if(obj.runtimeStyle&&obj.runtimeStyle.filter&&obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/)){
+_191.pas=RegExp.$1;
+}
+}else{
+if(obj&&!_191.status){
+_191.pas=String(obj.className);
+}
+}
+if(obj&&_191.type=="image"&&_191[_18f]){
+_191.status=_18f;
+obj.src=_191[_18f];
+}else{
+if(obj&&typeof (_191[_18f])!="undefined"){
+_191.status=_18f;
+obj.className=_191[_18f];
+}
+}
+if(obj&&_191.type=="input"){
+_191.status=_18f;
+obj.disabled=!_18f;
+}
+}
+};
+this.set_alttext=function(_194,_195){
+if(!this.buttons[_194]||!this.buttons[_194].length){
+return;
+}
+var _196,obj,link;
+for(var n=0;n<this.buttons[_194].length;n++){
+_196=this.buttons[_194][n];
+obj=document.getElementById(_196.id);
+if(_196.type=="image"&&obj){
+obj.setAttribute("alt",this.get_label(_195));
+if((link=obj.parentNode)&&link.tagName=="A"){
+link.setAttribute("title",this.get_label(_195));
+}
+}else{
+if(obj){
+obj.setAttribute("title",this.get_label(_195));
+}
+}
+}
+};
+this.button_over=function(_19a,id){
+var _19c=this.buttons[_19a];
+var _19d,img;
+if(!_19c||!_19c.length){
+return false;
+}
+for(var n=0;n<_19c.length;n++){
+_19d=_19c[n];
+if(_19d.id==id&&_19d.status=="act"){
+img=document.getElementById(_19d.id);
+if(img&&_19d.over){
+img.src=_19d.over;
+}
+}
+}
+};
+this.button_sel=function(_1a0,id){
+var _1a2=this.buttons[_1a0];
+var _1a3,img;
+if(!_1a2||!_1a2.length){
+return;
+}
+for(var n=0;n<_1a2.length;n++){
+_1a3=_1a2[n];
+if(_1a3.id==id&&_1a3.status=="act"){
+img=document.getElementById(_1a3.id);
+if(img&&_1a3.sel){
+img.src=_1a3.sel;
+}
+}
+}
+};
+this.button_out=function(_1a6,id){
+var _1a8=this.buttons[_1a6];
+var _1a9,img;
+if(!_1a8||!_1a8.length){
+return;
+}
+for(var n=0;n<_1a8.length;n++){
+_1a9=_1a8[n];
+if(_1a9.id==id&&_1a9.status=="act"){
+img=document.getElementById(_1a9.id);
+if(img&&_1a9.act){
+img.src=_1a9.act;
+}
+}
+}
+};
+this.set_classname=function(obj,_1ad,set){
+var reg=new RegExp("s*"+_1ad,"i");
+if(!set&&obj.className.match(reg)){
+obj.className=obj.className.replace(reg,"");
+}else{
+if(set&&!obj.className.match(reg)){
+obj.className+=" "+_1ad;
+}
+}
+};
+this.set_pagetitle=function(_1b0){
+if(_1b0&&document.title){
+document.title=_1b0;
+}
+};
+this.display_message=function(msg,type,hold){
+if(!this.loaded){
+this.pending_message=new Array(msg,type);
+return true;
+}
+if(this.env.framed&&parent.rcmail){
+return parent.rcmail.display_message(msg,type,hold);
+}
+if(!this.gui_objects.message){
+return false;
+}
+if(this.message_timer){
+clearTimeout(this.message_timer);
+}
+var cont=msg;
+if(type){
+cont="<div class=\""+type+"\">"+cont+"</div>";
+}
+var _1b5=this;
+this.gui_objects.message.innerHTML=cont;
+this.gui_objects.message.style.display="block";
+if(type!="loading"){
+this.gui_objects.message.onmousedown=function(){
+_1b5.hide_message();
+return true;
+};
+}
+if(!hold){
+this.message_timer=window.setTimeout(function(){
+_1.hide_message();
+},this.message_time);
+}
+};
+this.hide_message=function(){
+if(this.gui_objects.message){
+this.gui_objects.message.style.display="none";
+this.gui_objects.message.onmousedown=null;
+}
+};
+this.select_folder=function(name,old){
+if(this.gui_objects.folderlist){
+var _1b8,_1b9;
+if((_1b8=this.get_folder_li(old))){
+this.set_classname(_1b8,"selected",false);
+this.set_classname(_1b8,"unfocused",false);
+}
+if((_1b9=this.get_folder_li(name))){
+this.set_classname(_1b9,"unfocused",false);
+this.set_classname(_1b9,"selected",true);
+}
+}
+};
+this.get_folder_li=function(name){
+if(this.gui_objects.folderlist){
+name=String(name).replace(this.identifier_expr,"");
+return document.getElementById("rcmli"+name);
+}
+return null;
+};
+this.set_message_coltypes=function(_1bb){
+this.coltypes=_1bb;
+var cell,col;
+var _1be=this.gui_objects.messagelist?this.gui_objects.messagelist.tHead:null;
+for(var n=0;_1be&&n<this.coltypes.length;n++){
+col=this.coltypes[n];
+if((cell=_1be.rows[0].cells[n+1])&&(col=="from"||col=="to")){
+if(cell.firstChild&&cell.firstChild.tagName=="A"){
+cell.firstChild.innerHTML=this.get_label(this.coltypes[n]);
+cell.firstChild.onclick=function(){
+return rcmail.command("sort",this.__col,this);
+};
+cell.firstChild.__col=col;
+}else{
+cell.innerHTML=this.get_label(this.coltypes[n]);
+}
+cell.id="rcm"+col;
+}else{
+if(col=="subject"&&this.message_list){
+this.message_list.subject_col=n+1;
+}
+}
+}
+};
+this.add_message_row=function(uid,cols,_1c2,_1c3,_1c4){
+if(!this.gui_objects.messagelist||!this.message_list){
+return false;
+}
+var _1c5=this.gui_objects.messagelist.tBodies[0];
+var _1c6=_1c5.rows.length;
+var even=_1c6%2;
+this.env.messages[uid]={deleted:_1c2.deleted?1:0,replied:_1c2.replied?1:0,unread:_1c2.unread?1:0,forwarded:_1c2.forwarded?1:0,flagged:_1c2.flagged?1:0};
+var row=document.createElement("TR");
+row.id="rcmrow"+uid;
+row.className="message"+(even?" even":" odd")+(_1c2.unread?" unread":"")+(_1c2.deleted?" deleted":"")+(_1c2.flagged?" flagged":"");
+if(this.message_list.in_selection(uid)){
+row.className+=" selected";
+}
+var icon=this.env.messageicon;
+if(_1c2.deleted&&this.env.deletedicon){
+icon=this.env.deletedicon;
+}else{
+if(_1c2.replied&&this.env.repliedicon){
+if(_1c2.forwarded&&this.env.forwardedrepliedicon){
+icon=this.env.forwardedrepliedicon;
+}else{
+icon=this.env.repliedicon;
+}
+}else{
+if(_1c2.forwarded&&this.env.forwardedicon){
+icon=this.env.forwardedicon;
+}else{
+if(_1c2.unread&&this.env.unreadicon){
+icon=this.env.unreadicon;
+}
+}
+}
+}
+var col=document.createElement("TD");
+col.className="icon";
+col.innerHTML=icon?"<img src=\""+icon+"\" alt=\"\" />":"";
+row.appendChild(col);
+for(var n=0;n<this.coltypes.length;n++){
+var c=this.coltypes[n];
+col=document.createElement("TD");
+col.className=String(c).toLowerCase();
+if(c=="flag"){
+if(_1c2.flagged&&this.env.flaggedicon){
+col.innerHTML="<img src=\""+this.env.flaggedicon+"\" alt=\"\" />";
+}else{
+if(!_1c2.flagged&&this.env.unflaggedicon){
+col.innerHTML="<img src=\""+this.env.unflaggedicon+"\" alt=\"\" />";
+}
+}
+}else{
+if(c=="attachment"){
+col.innerHTML=_1c3&&this.env.attachmenticon?"<img src=\""+this.env.attachmenticon+"\" alt=\"\" />":"&nbsp;";
+}else{
+col.innerHTML=cols[c];
+}
+}
+row.appendChild(col);
+}
+this.message_list.insert_row(row,_1c4);
+if(_1c4&&this.env.pagesize&&this.message_list.rowcount>this.env.pagesize){
+var uid=this.message_list.get_last_row();
+this.message_list.remove_row(uid);
+this.message_list.clear_selection(uid);
+}
+};
+this.set_rowcount=function(text){
+if(this.gui_objects.countdisplay){
+this.gui_objects.countdisplay.innerHTML=text;
+}
+this.set_page_buttons();
+};
+this.set_mailboxname=function(_1ce){
+if(this.gui_objects.mailboxname&&_1ce){
+this.gui_objects.mailboxname.innerHTML=_1ce;
+}
+};
+this.set_quota=function(_1cf){
+if(this.gui_objects.quotadisplay&&_1cf){
+this.gui_objects.quotadisplay.innerHTML=_1cf;
+}
+};
+this.set_unread_count=function(mbox,_1d1,_1d2){
+if(!this.gui_objects.mailboxlist){
+return false;
+}
+this.env.unread_counts[mbox]=_1d1;
+this.set_unread_count_display(mbox,_1d2);
+};
+this.set_unread_count_display=function(mbox,_1d4){
+var reg,_1d6,item,_1d8,_1d9,div;
+if(item=this.get_folder_li(mbox)){
+_1d8=this.env.unread_counts[mbox]?this.env.unread_counts[mbox]:0;
+_1d6=item.getElementsByTagName("a")[0];
+reg=/\s+\([0-9]+\)$/i;
+_1d9=0;
+if((div=item.getElementsByTagName("div")[0])&&div.className.match(/collapsed/)){
+for(var k in this.env.unread_counts){
+if(k.indexOf(mbox+this.env.delimiter)==0){
+_1d9+=this.env.unread_counts[k];
+}
+}
+}
+if(_1d8&&_1d6.innerHTML.match(reg)){
+_1d6.innerHTML=_1d6.innerHTML.replace(reg," ("+_1d8+")");
+}else{
+if(_1d8){
+_1d6.innerHTML+=" ("+_1d8+")";
+}else{
+_1d6.innerHTML=_1d6.innerHTML.replace(reg,"");
+}
+}
+reg=new RegExp(RegExp.escape(this.env.delimiter)+"[^"+RegExp.escape(this.env.delimiter)+"]+$");
+if(mbox.match(reg)){
+this.set_unread_count_display(mbox.replace(reg,""),false);
+}
+this.set_classname(item,"unread",(_1d8+_1d9)>0?true:false);
+}
+reg=/^\([0-9]+\)\s+/i;
+if(_1d4&&document.title){
+var _1dc=String(document.title);
+var _1dd="";
+if(_1d8&&_1dc.match(reg)){
+_1dd=_1dc.replace(reg,"("+_1d8+") ");
+}else{
+if(_1d8){
+_1dd="("+_1d8+") "+_1dc;
+}else{
+_1dd=_1dc.replace(reg,"");
+}
+}
+this.set_pagetitle(_1dd);
+}
+};
+this.new_message_focus=function(){
+if(this.env.framed&&window.parent){
+window.parent.focus();
+}else{
+window.focus();
+}
+};
+this.add_contact_row=function(cid,cols,_1e0){
+if(!this.gui_objects.contactslist||!this.gui_objects.contactslist.tBodies[0]){
+return false;
+}
+var _1e1=this.gui_objects.contactslist.tBodies[0];
+var _1e2=_1e1.rows.length;
+var even=_1e2%2;
+var row=document.createElement("TR");
+row.id="rcmrow"+cid;
+row.className="contact "+(even?"even":"odd");
+if(this.contact_list.in_selection(cid)){
+row.className+=" selected";
+}
+for(var c in cols){
+col=document.createElement("TD");
+col.className=String(c).toLowerCase();
+col.innerHTML=cols[c];
+row.appendChild(col);
+}
+this.contact_list.insert_row(row);
+this.enable_command("export",(this.contact_list.rowcount>0));
+};
+this.toggle_prefer_html=function(_1e6){
+var _1e7;
+if(_1e7=document.getElementById("rcmfd_addrbook_show_images")){
+_1e7.disabled=!_1e6.checked;
+}
+};
+this.set_headers=function(_1e8){
+if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&_1e8){
+var box=this.gui_objects.all_headers_box;
+box.innerHTML=_1e8;
+box.style.display="block";
+if(this.env.framed&&parent.rcmail){
+parent.rcmail.set_busy(false);
+}else{
+this.set_busy(false);
+}
+}
+};
+this.load_headers=function(elem){
+if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box||!this.env.uid){
+return;
+}
+this.set_classname(elem,"show-headers",false);
+this.set_classname(elem,"hide-headers",true);
+this.gui_objects.all_headers_row.style.display=bw.ie?"block":"table-row";
+elem.onclick=function(){
+rcmail.hide_headers(elem);
+};
+if(!this.gui_objects.all_headers_box.innerHTML){
+this.display_message(this.get_label("loading"),"loading",true);
+this.http_post("headers","_uid="+this.env.uid);
+}
+};
+this.hide_headers=function(elem){
+if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box){
+return;
+}
+this.set_classname(elem,"hide-headers",false);
+this.set_classname(elem,"show-headers",true);
+this.gui_objects.all_headers_row.style.display="none";
+elem.onclick=function(){
+rcmail.load_headers(elem);
+};
+};
+this.html2plain=function(_1ec,id){
+var _1ee=new rcube_http_request();
+var url=this.env.bin_path+"html2text.php";
+var _1f0=this;
+this.set_busy(true,"converting");
+console.log("HTTP POST: "+url);
+_1ee.onerror=function(o){
+_1f0.http_error(o);
+};
+_1ee.oncomplete=function(o){
+_1f0.set_text_value(o,id);
+};
+_1ee.POST(url,_1ec,"application/octet-stream");
+};
+this.set_text_value=function(_1f3,id){
+this.set_busy(false);
+document.getElementById(id).value=_1f3.get_text();
+console.log(_1f3.get_text());
+};
+this.redirect=function(url,lock){
+if(lock||lock===null){
+this.set_busy(true);
+}
+if(this.env.framed&&window.parent){
+parent.location.href=url;
+}else{
+location.href=url;
+}
+};
+this.goto_url=function(_1f7,_1f8,lock){
+var _1fa=_1f8?"&"+_1f8:"";
+this.redirect(this.env.comm_path+"&_action="+_1f7+_1fa,lock);
+};
+this.http_sockets=new Array();
+this.get_request_obj=function(){
+for(var n=0;n<this.http_sockets.length;n++){
+if(!this.http_sockets[n].busy){
+return this.http_sockets[n];
+}
+}
+var i=this.http_sockets.length;
+this.http_sockets[i]=new rcube_http_request();
+return this.http_sockets[i];
+};
+this.http_request=function(_1fd,_1fe,lock){
+var _200=this.get_request_obj();
+_1fe+=(_1fe?"&":"")+"_remote=1";
+if(bw.safari){
+_1fe+="&_ts="+(new Date().getTime());
+}
+if(_200){
+console.log("HTTP request: "+this.env.comm_path+"&_action="+_1fd+"&"+_1fe);
+if(lock){
+this.set_busy(true);
+}
+var rcm=this;
+_200.__lock=lock?true:false;
+_200.__action=_1fd;
+_200.onerror=function(o){
+_1.http_error(o);
+};
+_200.oncomplete=function(o){
+_1.http_response(o);
+};
+_200.GET(this.env.comm_path+"&_action="+_1fd+"&"+_1fe);
+}
+};
+this.http_post=function(_204,_205,lock){
+var _207;
+if(_205&&typeof (_205)=="object"){
+_205._remote=1;
+}else{
+_205+=(_205?"&":"")+"_remote=1";
+}
+if(_207=this.get_request_obj()){
+console.log("HTTP POST: "+this.env.comm_path+"&_action="+_204);
+if(lock){
+this.set_busy(true);
+}
+var rcm=this;
+_207.__lock=lock?true:false;
+_207.__action=_204;
+_207.onerror=function(o){
+rcm.http_error(o);
+};
+_207.oncomplete=function(o){
+rcm.http_response(o);
+};
+_207.POST(this.env.comm_path+"&_action="+_204,_205);
+}
+};
+this.http_response=function(_20b){
+var _20c=_20b.get_header("Content-Type");
+if(_20c){
+_20c=String(_20c).toLowerCase();
+var _20d=_20c.split(";");
+_20c=_20d[0];
+}
+if(_20b.__lock){
+this.set_busy(false);
+}
+console.log(_20b.get_text());
+if(_20b.get_text()&&(_20c=="text/javascript"||_20c=="application/x-javascript")){
+eval(_20b.get_text());
+}
+switch(_20b.__action){
+case "delete":
+if(this.task=="addressbook"){
+var uid=this.contact_list.get_selection();
+this.enable_command("compose",(uid&&this.contact_list.rows[uid]));
+this.enable_command("delete","edit",(uid&&this.contact_list.rows[uid]&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly));
+this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0));
+}
+case "moveto":
+if(this.env.action=="show"){
+this.command("list");
+}else{
+if(this.message_list){
+this.message_list.init();
+}
+}
+break;
+case "purge":
+case "expunge":
+if(!this.env.messagecount&&this.task=="mail"){
+if(this.env.contentframe){
+this.show_contentframe(false);
+}
+this.enable_command("show","reply","reply-all","forward","moveto","delete","mark","viewsource","print","load-attachment","purge","expunge","select-all","select-none","sort",false);
+}
+break;
+case "check-recent":
+case "getunread":
+case "list":
+if(this.task=="mail"){
+if(this.message_list&&_20b.__action=="list"){
+this.msglist_select(this.message_list);
+}
+this.enable_command("show","expunge","select-all","select-none","sort",(this.env.messagecount>0));
+this.enable_command("purge",this.purge_mailbox_test());
+}else{
+if(this.task=="addressbook"){
+this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0));
+}
+}
+break;
+}
+_20b.reset();
+};
+this.http_error=function(_20f){
+if(_20f.__lock){
+this.set_busy(false);
+}
+_20f.reset();
+_20f.__lock=false;
+this.display_message("Unknown Server Error!","error");
+};
+this.send_keep_alive=function(){
+var d=new Date();
+this.http_request("keep-alive","_t="+d.getTime());
+};
+this.check_for_recent=function(_211){
+if(this.busy){
+return;
+}
+if(_211){
+this.set_busy(true,"checkingmail");
+}
+var _212="_t="+(new Date().getTime());
+if(this.gui_objects.messagelist){
+_212+="&_list=1";
+}
+if(this.gui_objects.quotadisplay){
+_212+="&_quota=1";
+}
+if(this.env.search_request){
+_212+="&_search="+this.env.search_request;
+}
+this.http_request("check-recent",_212,true);
+};
+this.get_single_uid=function(){
+return this.env.uid?this.env.uid:(this.message_list?this.message_list.get_single_selection():null);
+};
+this.get_single_cid=function(){
+return this.env.cid?this.env.cid:(this.contact_list?this.contact_list.get_single_selection():null);
+};
+this.get_caret_pos=function(obj){
+if(typeof (obj.selectionEnd)!="undefined"){
+return obj.selectionEnd;
+}else{
+if(document.selection&&document.selection.createRange){
+var _214=document.selection.createRange();
+if(_214.parentElement()!=obj){
+return 0;
+}
+var gm=_214.duplicate();
+if(obj.tagName=="TEXTAREA"){
+gm.moveToElementText(obj);
+}else{
+gm.expand("textedit");
+}
+gm.setEndPoint("EndToStart",_214);
+var p=gm.text.length;
+return p<=obj.value.length?p:-1;
+}else{
+return obj.value.length;
+}
+}
+};
+this.set_caret2start=function(obj){
+if(obj.createTextRange){
+var _218=obj.createTextRange();
+_218.collapse(true);
+_218.select();
+}else{
+if(obj.setSelectionRange){
+obj.setSelectionRange(0,0);
+}
+}
+obj.focus();
+};
+this.lock_form=function(form,lock){
+if(!form||!form.elements){
+return;
+}
+var type;
+for(var n=0;n<form.elements.length;n++){
+type=form.elements[n];
+if(type=="hidden"){
+continue;
+}
+form.elements[n].disabled=lock;
+}
+};
+};
+function rcube_http_request(){
+this.url="";
+this.busy=false;
+this.xmlhttp=null;
+this.reset=function(){
+this.onloading=function(){
+};
+this.onloaded=function(){
+};
+this.oninteractive=function(){
+};
+this.oncomplete=function(){
+};
+this.onabort=function(){
+};
+this.onerror=function(){
+};
+this.url="";
+this.busy=false;
+this.xmlhttp=null;
+};
+this.build=function(){
+if(window.XMLHttpRequest){
+this.xmlhttp=new XMLHttpRequest();
+}else{
+if(window.ActiveXObject){
+try{
+this.xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
+}
+catch(e){
+this.xmlhttp=null;
+}
+}else{
+}
+}
+};
+this.GET=function(url){
+this.build();
+if(!this.xmlhttp){
+this.onerror(this);
+return false;
+}
+var _ref=this;
+this.url=url;
+this.busy=true;
+this.xmlhttp.onreadystatechange=function(){
+_ref.xmlhttp_onreadystatechange();
+};
+this.xmlhttp.open("GET",url,true);
+this.xmlhttp.setRequestHeader("X-RoundCube-Referer",bw.get_cookie("roundcube_sessid"));
+this.xmlhttp.send(null);
+};
+this.POST=function(url,body,_221){
+if(typeof (_221)=="undefined"){
+_221="application/x-www-form-urlencoded";
+}
+this.build();
+if(!this.xmlhttp){
+this.onerror(this);
+return false;
+}
+var _222=body;
+if(typeof (body)=="object"){
+_222="";
+for(var p in body){
+_222+=(_222?"&":"")+p+"="+urlencode(body[p]);
+}
+}
+var ref=this;
+this.url=url;
+this.busy=true;
+this.xmlhttp.onreadystatechange=function(){
+ref.xmlhttp_onreadystatechange();
+};
+this.xmlhttp.open("POST",url,true);
+this.xmlhttp.setRequestHeader("Content-Type",_221);
+this.xmlhttp.setRequestHeader("X-RoundCube-Referer",bw.get_cookie("roundcube_sessid"));
+this.xmlhttp.send(_222);
+};
+this.xmlhttp_onreadystatechange=function(){
+if(this.xmlhttp.readyState==1){
+this.onloading(this);
+}else{
+if(this.xmlhttp.readyState==2){
+this.onloaded(this);
+}else{
+if(this.xmlhttp.readyState==3){
+this.oninteractive(this);
+}else{
+if(this.xmlhttp.readyState==4){
+try{
+if(this.xmlhttp.status==0){
+this.onabort(this);
+}else{
+if(this.xmlhttp.status==200){
+this.oncomplete(this);
+}else{
+this.onerror(this);
+}
+}
+this.busy=false;
+}
+catch(err){
+this.onerror(this);
+this.busy=false;
+}
+}
+}
+}
+}
+};
+this.get_header=function(name){
+return this.xmlhttp.getResponseHeader(name);
+};
+this.get_text=function(){
+return this.xmlhttp.responseText;
+};
+this.get_xml=function(){
+return this.xmlhttp.responseXML;
+};
+this.reset();
+};
+function call_init(o){
+window.setTimeout("if (window['"+o+"'] && window['"+o+"'].init) { "+o+".init(); }",bw.win?500:200);
+};
 
diff --git a/program/js/app.js.src b/program/js/app.js.src
new file mode 100644 (file)
index 0000000..fcffdbc
--- /dev/null
@@ -0,0 +1,4226 @@
+/*
+ +-----------------------------------------------------------------------+
+ | RoundCube Webmail Client Script                                       |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
+ |          Charles McNulty <charles@charlesmcnulty.com>                 |
+ +-----------------------------------------------------------------------+
+ | Requires: common.js, list.js                                          |
+ +-----------------------------------------------------------------------+
+
+  $Id: app.js 2483 2009-05-15 10:22:29Z thomasb $
+*/
+
+
+var rcube_webmail_client;
+
+function rcube_webmail()
+  {
+  this.env = new Object();
+  this.labels = new Object();
+  this.buttons = new Object();
+  this.gui_objects = new Object();
+  this.commands = new Object();
+  this.onloads = new Array();
+
+  // create protected reference to myself
+  rcube_webmail_client = this;
+  this.ref = 'rcube_webmail_client';
+  var ref = this;
+  // webmail client settings
+  this.dblclick_time = 500;
+  this.message_time = 3000;
+  
+  this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi');
+  
+  // mimetypes supported by the browser (default settings)
+  this.mimetypes = new Array('text/plain', 'text/html', 'text/xml',
+                             'image/jpeg', 'image/gif', 'image/png',
+                             'application/x-javascript', 'application/pdf',
+                             'application/x-shockwave-flash');
+
+  // default environment vars
+  this.env.keep_alive = 60;        // seconds
+  this.env.request_timeout = 180;  // seconds
+  this.env.draft_autosave = 0;     // seconds
+  this.env.comm_path = './';
+  this.env.bin_path = './bin/';
+  this.env.blankpage = 'program/blank.gif';
+
+  // set environment variable(s)
+  this.set_env = function(p, value)
+    {
+    if (p != null && typeof(p) == 'object' && !value)
+      for (var n in p)
+        this.env[n] = p[n];
+    else
+      this.env[p] = value;
+    };
+
+  // add a localized label to the client environment
+  this.add_label = function(key, value)
+    {
+    this.labels[key] = value;
+    };
+
+  // add a button to the button list
+  this.register_button = function(command, id, type, act, sel, over)
+    {
+    if (!this.buttons[command])
+      this.buttons[command] = new Array();
+      
+    var button_prop = {id:id, type:type};
+    if (act) button_prop.act = act;
+    if (sel) button_prop.sel = sel;
+    if (over) button_prop.over = over;
+
+    this.buttons[command][this.buttons[command].length] = button_prop;    
+    };
+
+  // register a specific gui object
+  this.gui_object = function(name, id)
+    {
+    this.gui_objects[name] = id;
+    };
+  
+  // execute the given script on load
+  this.add_onload = function(f)
+    {
+      this.onloads[this.onloads.length] = f;
+    };
+
+  // initialize webmail client
+  this.init = function()
+    {
+    var p = this;
+    this.task = this.env.task;
+    
+    // check browser
+    if (!bw.dom || !bw.xmlhttp_test())
+      {
+      this.goto_url('error', '_code=0x199');
+      return;
+      }
+    
+    // find all registered gui objects
+    for (var n in this.gui_objects)
+      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
+
+    // tell parent window that this frame is loaded
+    if (this.env.framed && parent.rcmail && parent.rcmail.set_busy)
+      parent.rcmail.set_busy(false);
+
+    // enable general commands
+    this.enable_command('logout', 'mail', 'addressbook', 'settings', true);
+    
+    if (this.env.permaurl)
+      this.enable_command('permaurl', true);
+    
+    switch (this.task)
+      {
+      case 'mail':
+        if (this.gui_objects.messagelist)
+          {
+          this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {multiselect:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time});
+          this.message_list.row_init = function(o){ p.init_message_row(o); };
+          this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); });
+          this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
+          this.message_list.addEventListener('select', function(o){ p.msglist_select(o); });
+          this.message_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
+          this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
+          this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; });
+
+          this.message_list.init();
+          this.enable_command('toggle_status', 'toggle_flag', true);
+          
+          if (this.gui_objects.mailcontframe)
+            {
+            this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); };
+            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+            }
+          else
+            this.message_list.focus();
+          }
+          
+        if (this.env.coltypes)
+          this.set_message_coltypes(this.env.coltypes);
+
+        // enable mail commands
+        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
+
+        if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
+          document.getElementById('quicksearchbox').value = this.env.search_text;
+        
+        if (this.env.action=='show' || this.env.action=='preview')
+          {
+          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', 'load-headers', true);
+          if (this.env.next_uid)
+            {
+            this.enable_command('nextmessage', true);
+            this.enable_command('lastmessage', true);
+            }
+          if (this.env.prev_uid)
+            {
+            this.enable_command('previousmessage', true);
+            this.enable_command('firstmessage', true);
+            }
+          }
+
+        if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox)
+          this.set_alttext('delete', 'movemessagetotrash');
+        
+        // make preview/message frame visible
+        if (this.env.action == 'preview' && this.env.framed && parent.rcmail)
+          {
+          this.enable_command('compose', 'add-contact', false);
+          parent.rcmail.show_contentframe(true);
+          }
+
+        if ((this.env.action=='show' || this.env.action=='preview') && this.env.blockedobjects)
+          {
+          if (this.gui_objects.remoteobjectsmsg)
+            this.gui_objects.remoteobjectsmsg.style.display = 'block';
+          this.enable_command('load-images', 'always-load', true);
+          }
+
+        if (this.env.action=='compose')
+          {
+          this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true);
+          if (this.env.spellcheck)
+            {
+            this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
+            this.set_spellcheck_state('ready');
+            if (rcube_find_object('_is_html').value == '1')
+              this.display_spellcheck_controls(false);
+            }
+          if (this.env.drafts_mailbox)
+            this.enable_command('savedraft', true);
+            
+          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+          }
+
+        if (this.env.messagecount)
+          this.enable_command('select-all', 'select-none', 'expunge', true);
+
+        if (this.purge_mailbox_test())
+          this.enable_command('purge', true);
+
+        this.set_page_buttons();
+
+        // init message compose form
+        if (this.env.action=='compose')
+          this.init_messageform();
+
+        // show printing dialog
+        if (this.env.action=='print')
+          window.print();
+
+        // get unread count for each mailbox
+        if (this.gui_objects.mailboxlist)
+        {
+          this.env.unread_counts = {};
+          this.gui_objects.folderlist = this.gui_objects.mailboxlist;
+          this.http_request('getunread', '');
+        }
+        
+        // ask user to send MDN
+        if (this.env.mdn_request && this.env.uid)
+        {
+          var mdnurl = '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox);
+          if (confirm(this.get_label('mdnrequest')))
+            this.http_post('sendmdn', mdnurl);
+          else
+            this.http_post('mark', mdnurl+'&_flag=mdnsent');
+        }
+
+        break;
+
+
+      case 'addressbook':
+        if (this.gui_objects.contactslist)
+          {
+          this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, {multiselect:true, draggable:true, keyboard:true});
+          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
+          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
+          this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
+          this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
+          this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; });
+          this.contact_list.init();
+
+          if (this.env.cid)
+            this.contact_list.highlight_row(this.env.cid);
+
+          if (this.gui_objects.contactslist.parentNode)
+            {
+            this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
+            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+            }
+          else
+            this.contact_list.focus();
+          }
+
+        this.set_page_buttons();
+        
+        if (this.env.address_sources && this.env.address_sources[this.env.source] && !this.env.address_sources[this.env.source].readonly)
+          this.enable_command('add', true);
+        
+        if (this.env.cid)
+          this.enable_command('show', 'edit', true);
+
+        if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform)
+          this.enable_command('save', true);
+        else
+          this.enable_command('search', 'reset-search', 'moveto', 'import', true);
+          
+        if (this.contact_list && this.contact_list.rowcount > 0)
+          this.enable_command('export', true);
+
+        this.enable_command('list', true);
+        break;
+
+
+      case 'settings':
+        this.enable_command('preferences', 'identities', 'save', 'folders', true);
+        
+        if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') {
+          this.enable_command('add', this.env.identities_level < 2);
+          this.enable_command('delete', 'edit', true);
+        }
+
+        if (this.env.action=='edit-identity' || this.env.action=='add-identity')
+          this.enable_command('save', true);
+          
+        if (this.env.action=='folders')
+          this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true);
+
+        if (this.gui_objects.identitieslist)
+          {
+          this.identity_list = new rcube_list_widget(this.gui_objects.identitieslist, {multiselect:false, draggable:false, keyboard:false});
+          this.identity_list.addEventListener('select', function(o){ p.identity_select(o); });
+          this.identity_list.init();
+          this.identity_list.focus();
+
+          if (this.env.iid)
+            this.identity_list.highlight_row(this.env.iid);
+          }
+
+        if (this.gui_objects.subscriptionlist)
+          this.init_subscription_list();
+
+        break;
+
+      case 'login':
+        var input_user = rcube_find_object('rcmloginuser');
+        var input_pass = rcube_find_object('rcmloginpwd');
+        var input_tz = rcube_find_object('rcmlogintz');
+
+        if (input_user)
+          input_user.onkeyup = function(e){ return rcmail.login_user_keyup(e); };
+        if (input_user && input_user.value=='')
+          input_user.focus();
+        else if (input_pass)
+          input_pass.focus();
+
+        // detect client timezone
+        if (input_tz)
+          input_tz.value = new Date().getTimezoneOffset() / -60;
+
+        this.enable_command('login', true);
+        break;
+      
+      default:
+        break;
+      }
+
+    // enable basic commands
+    this.enable_command('logout', true);
+
+    // flag object as complete
+    this.loaded = true;
+
+    // show message
+    if (this.pending_message)
+      this.display_message(this.pending_message[0], this.pending_message[1]);
+
+    // start keep-alive interval
+    this.start_keepalive();
+    
+    // execute all foreign onload scripts
+    for (var i=0; i<this.onloads.length; i++)
+      {
+      if (typeof(this.onloads[i]) == 'string')
+        eval(this.onloads[i]);
+      else if (typeof(this.onloads[i]) == 'function')
+        this.onloads[i]();
+      }
+    };
+
+  // start interval for keep-alive/recent_check signal
+  this.start_keepalive = function()
+    {
+    if (this.env.keep_alive && !this.env.framed && this.task=='mail' && this.gui_objects.mailboxlist)
+      this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000);
+    else if (this.env.keep_alive && !this.env.framed && this.task!='login')
+      this._int = setInterval(function(){ ref.send_keep_alive(); }, this.env.keep_alive * 1000);
+    }
+
+  this.init_message_row = function(row)
+  {
+    var uid = row.uid;
+    if (uid && this.env.messages[uid])
+      {
+      row.deleted = this.env.messages[uid].deleted ? true : false;
+      row.unread = this.env.messages[uid].unread ? true : false;
+      row.replied = this.env.messages[uid].replied ? true : false;
+      row.flagged = this.env.messages[uid].flagged ? true : false;
+      row.forwarded = this.env.messages[uid].forwarded ? true : false;
+      }
+
+    // set eventhandler to message icon
+    if ((row.icon = row.obj.cells[0].childNodes[0]) && row.icon.nodeName=='IMG')
+      {
+      var p = this;
+      row.icon.id = 'msgicn_'+row.uid;
+      row.icon._row = row.obj;
+      row.icon.onmousedown = function(e) { p.command('toggle_status', this); };
+      }
+
+    // global variable 'flagged_col' may be not defined yet
+    if (!this.env.flagged_col && this.env.coltypes)
+      {
+      var found;
+      if((found = find_in_array('flag', this.env.coltypes)) >= 0)
+          this.set_env('flagged_col', found+1);
+      }
+
+    // set eventhandler to flag icon, if icon found
+    if (this.env.flagged_col && (row.flagged_icon = row.obj.cells[this.env.flagged_col].childNodes[0]) 
+       && row.flagged_icon.nodeName=='IMG')
+      {
+      var p = this;
+      row.flagged_icon.id = 'flaggedicn_'+row.uid;
+      row.flagged_icon._row = row.obj;
+      row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); };
+      }
+  };
+
+  // init message compose form: set focus and eventhandlers
+  this.init_messageform = function()
+    {
+    if (!this.gui_objects.messageform)
+      return false;
+    
+    //this.messageform = this.gui_objects.messageform;
+    var input_from = rcube_find_object('_from');
+    var input_to = rcube_find_object('_to');
+    var input_cc = rcube_find_object('_cc');
+    var input_bcc = rcube_find_object('_bcc');
+    var input_replyto = rcube_find_object('_replyto');
+    var input_subject = rcube_find_object('_subject');
+    var input_message = rcube_find_object('_message');
+    var draftid = rcube_find_object('_draft_saveid');
+
+    // init live search events
+    if (input_to)
+      this.init_address_input_events(input_to);
+    if (input_cc)
+      this.init_address_input_events(input_cc);
+    if (input_bcc)
+      this.init_address_input_events(input_bcc);
+
+    // add signature according to selected identity
+    if (input_from && input_from.type=='select-one' && (!draftid || draftid.value=='')
+       // if we have HTML editor, signature is added in callback
+       && rcube_find_object('_is_html').value != '1')
+      {
+      this.change_identity(input_from);
+      }
+
+    if (input_to && input_to.value=='')
+      input_to.focus();
+    else if (input_subject && input_subject.value=='')
+      input_subject.focus();
+    else if (input_message)
+      this.set_caret2start(input_message);
+
+    // get summary of all field values
+    this.compose_field_hash(true);
+    // start the auto-save timer
+    this.auto_save_start();
+    };
+
+  this.init_address_input_events = function(obj)
+    {
+    var handler = function(e){ return ref.ksearch_keypress(e,this); };
+    
+    if (obj.addEventListener)
+      obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false);
+    else
+      obj.onkeydown = handler;
+
+    obj.setAttribute('autocomplete', 'off');
+    };
+
+
+  /*********************************************************/
+  /*********       client command interface        *********/
+  /*********************************************************/
+
+  // execute a specific command on the web client
+  this.command = function(command, props, obj)
+    {
+    if (obj && obj.blur)
+      obj.blur();
+
+    if (this.busy)
+      return false;
+
+    // command not supported or allowed
+    if (!this.commands[command])
+      {
+      // pass command to parent window
+      if (this.env.framed && parent.rcmail && parent.rcmail.command)
+        parent.rcmail.command(command, props);
+
+      return false;
+      }
+      
+   // check input before leaving compose step
+   if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings'))
+     {
+     if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
+        return false;
+     }
+
+    // process command
+    switch (command)
+      {
+      case 'login':
+        if (this.gui_objects.loginform)
+          this.gui_objects.loginform.submit();
+        break;
+
+      case 'logout':
+        this.goto_url('logout', '', true);
+        break;      
+
+      // commands to switch task
+      case 'mail':
+      case 'addressbook':
+      case 'settings':
+        this.switch_task(command);
+        break;
+
+      case 'permaurl':
+        if (obj && obj.href && obj.target)
+          return true;
+        else if (this.env.permaurl)
+          parent.location.href = this.env.permaurl;
+          break;
+
+      // misc list commands
+      case 'list':
+        if (this.task=='mail')
+          {
+          if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox)))
+            this.reset_qsearch();
+
+          this.list_mailbox(props);
+
+          if (this.env.trash_mailbox)
+            this.set_alttext('delete', this.env.mailbox != this.env.trash_mailbox ? 'movemessagetotrash' : 'deletemessage');
+          }
+        else if (this.task=='addressbook')
+          {
+          if (this.env.search_request<0 || (this.env.search_request && props != this.env.source))
+            this.reset_qsearch();
+
+          this.list_contacts(props);
+          this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly));
+          }
+        break;
+
+
+      case 'load-headers':
+        this.load_headers(obj);
+        break;
+
+
+      case 'sort':
+        // get the type of sorting
+        var a_sort = props.split('_');
+        var sort_col = a_sort[0];
+        var sort_order = a_sort[1] ? a_sort[1].toUpperCase() : null;
+        var header;
+
+        // no sort order specified: toggle
+        if (sort_order==null)
+          {
+          if (this.env.sort_col==sort_col)
+            sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
+          else
+            sort_order = this.env.sort_order;
+          }
+
+        if (this.env.sort_col==sort_col && this.env.sort_order==sort_order)
+          break;
+
+        // set table header class
+        if (header = document.getElementById('rcm'+this.env.sort_col))
+          this.set_classname(header, 'sorted'+(this.env.sort_order.toUpperCase()), false);
+        if (header = document.getElementById('rcm'+sort_col))
+          this.set_classname(header, 'sorted'+sort_order, true);
+
+        // save new sort properties
+        this.env.sort_col = sort_col;
+        this.env.sort_order = sort_order;
+
+        // reload message list
+        this.list_mailbox('', '', sort_col+'_'+sort_order);
+        break;
+
+      case 'nextpage':
+        this.list_page('next');
+        break;
+
+      case 'lastpage':
+        this.list_page('last');
+        break;
+
+      case 'previouspage':
+        this.list_page('prev');
+        break;
+
+      case 'firstpage':
+        this.list_page('first');
+        break;
+
+      case 'expunge':
+        if (this.env.messagecount)
+          this.expunge_mailbox(this.env.mailbox);
+        break;
+
+      case 'purge':
+      case 'empty-mailbox':
+        if (this.env.messagecount)
+          this.purge_mailbox(this.env.mailbox);
+        break;
+
+
+      // common commands used in multiple tasks
+      case 'show':
+        if (this.task=='mail')
+          {
+          var uid = this.get_single_uid();
+          if (uid && (!this.env.uid || uid != this.env.uid))
+            {
+            if (this.env.mailbox == this.env.drafts_mailbox)
+              this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
+            else
+              this.show_message(uid);
+            }
+          }
+        else if (this.task=='addressbook')
+          {
+          var cid = props ? props : this.get_single_cid();
+          if (cid && !(this.env.action=='show' && cid==this.env.cid))
+            this.load_contact(cid, 'show');
+          }
+        break;
+
+      case 'add':
+        if (this.task=='addressbook')
+          this.load_contact(0, 'add');
+        else if (this.task=='settings')
+          {
+          this.identity_list.clear_selection();
+          this.load_identity(0, 'add-identity');
+          }
+        break;
+
+      case 'edit':
+        var cid;
+        if (this.task=='addressbook' && (cid = this.get_single_cid()))
+          this.load_contact(cid, 'edit');
+        else if (this.task=='settings' && props)
+          this.load_identity(props, 'edit-identity');
+        break;
+
+      case 'save-identity':
+      case 'save':
+        if (this.gui_objects.editform)
+          {
+          var input_pagesize = rcube_find_object('_pagesize');
+          var input_name  = rcube_find_object('_name');
+          var input_email = rcube_find_object('_email');
+
+          // user prefs
+          if (input_pagesize && isNaN(parseInt(input_pagesize.value)))
+            {
+            alert(this.get_label('nopagesizewarning'));
+            input_pagesize.focus();
+            break;
+            }
+          // contacts/identities
+          else
+            {
+            if (input_name && input_name.value == '')
+              {
+              alert(this.get_label('nonamewarning'));
+              input_name.focus();
+              break;
+              }
+            else if (input_email && !rcube_check_email(input_email.value))
+              {
+              alert(this.get_label('noemailwarning'));
+              input_email.focus();
+              break;
+              }
+            }
+
+          this.gui_objects.editform.submit();
+          }
+        break;
+
+      case 'delete':
+        // mail task
+        if (this.task=='mail')
+          this.delete_messages();
+        // addressbook task
+        else if (this.task=='addressbook')
+          this.delete_contacts();
+        // user settings task
+        else if (this.task=='settings')
+          this.delete_identity();
+        break;
+
+
+      // mail task commands
+      case 'move':
+      case 'moveto':
+        if (this.task == 'mail')
+          this.move_messages(props);
+        else if (this.task == 'addressbook' && this.drag_active)
+          this.copy_contact(null, props);
+        break;
+
+      case 'mark':
+        if (props)
+          this.mark_message(props);
+        break;
+      
+      case 'toggle_status':
+        if (props && !props._row)
+          break;
+        
+        var uid;
+        var flag = 'read';
+        
+        if (props._row.uid)
+          {
+          uid = props._row.uid;
+          
+          // toggle read/unread
+          if (this.message_list.rows[uid].deleted) {
+            flag = 'undelete';
+          } else if (!this.message_list.rows[uid].unread)
+            flag = 'unread';
+          }
+          
+        this.mark_message(flag, uid);
+        break;
+        
+      case 'toggle_flag':
+        if (props && !props._row)
+          break;
+
+        var uid;
+        var flag = 'flagged';
+
+        if (props._row.uid)
+          {
+          uid = props._row.uid;
+          // toggle flagged/unflagged
+          if (this.message_list.rows[uid].flagged)
+            flag = 'unflagged';
+          }
+        this.mark_message(flag, uid);
+        break;
+
+      case 'always-load':
+        if (this.env.uid && this.env.sender) {
+          this.add_contact(urlencode(this.env.sender));
+          window.setTimeout(function(){ ref.command('load-images'); }, 300);
+          break;
+        }
+        
+      case 'load-images':
+        if (this.env.uid)
+          this.show_message(this.env.uid, true, this.env.action=='preview');
+        break;
+
+      case 'load-attachment':
+        var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part;
+        
+        // open attachment in frame if it's of a supported mimetype
+        if (this.env.uid && props.mimetype && find_in_array(props.mimetype, this.mimetypes)>=0)
+          {
+          if (props.mimetype == 'text/html')
+            qstring += '&_safe=1';
+          this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment');
+          if (this.attachment_win)
+            {
+            window.setTimeout(function(){ ref.attachment_win.focus(); }, 10);
+            break;
+            }
+          }
+
+        this.goto_url('get', qstring+'&_download=1', false);
+        break;
+        
+      case 'select-all':
+        this.message_list.select_all(props);
+        break;
+
+      case 'select-none':
+        this.message_list.clear_selection();
+        break;
+
+      case 'nextmessage':
+        if (this.env.next_uid)
+          this.show_message(this.env.next_uid, false, this.env.action=='preview');
+        break;
+
+      case 'lastmessage':
+        if (this.env.last_uid)
+          this.show_message(this.env.last_uid);
+        break;
+
+      case 'previousmessage':
+        if (this.env.prev_uid)
+          this.show_message(this.env.prev_uid, false, this.env.action=='preview');
+        break;
+
+      case 'firstmessage':
+        if (this.env.first_uid)
+          this.show_message(this.env.first_uid);
+        break;
+      
+      case 'checkmail':
+        this.check_for_recent(true);
+        break;
+      
+      case 'compose':
+        var url = this.env.comm_path+'&_action=compose';
+       
+        if (this.task=='mail')
+        {
+          url += '&_mbox='+urlencode(this.env.mailbox);
+          
+          if (this.env.mailbox==this.env.drafts_mailbox)
+          {
+            var uid;
+            if (uid = this.get_single_uid())
+              url += '&_draft_uid='+uid;
+          }
+          else if (props)
+             url += '&_to='+urlencode(props);
+        }
+        // modify url if we're in addressbook
+        else if (this.task=='addressbook')
+          {
+          // switch to mail compose step directly
+          if (props && props.indexOf('@') > 0)
+            {
+            url = this.get_task_url('mail', url);
+            this.redirect(url + '&_to='+urlencode(props));
+            break;
+            }
+          
+          // use contact_id passed as command parameter
+          var a_cids = new Array();
+          if (props)
+            a_cids[a_cids.length] = props;
+          // get selected contacts
+          else if (this.contact_list)
+            {
+            var selection = this.contact_list.get_selection();
+            for (var n=0; n<selection.length; n++)
+              a_cids[a_cids.length] = selection[n];
+            }
+            
+          if (a_cids.length)
+            this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
+
+          break;
+          }
+
+        // don't know if this is necessary...
+        url = url.replace(/&_framed=1/, "");
+
+        this.redirect(url);
+        break;
+        
+      case 'spellcheck':
+        if (window.tinyMCE && tinyMCE.get('compose-body')) {
+          tinyMCE.execCommand('mceSpellCheck', true);
+        }
+        else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) {
+          this.env.spellcheck.spellCheck(this.env.spellcheck.check_link);
+          this.set_spellcheck_state('checking');
+        }
+        break;
+
+      case 'savedraft':
+        // Reset the auto-save timer
+        self.clearTimeout(this.save_timer);
+
+        if (!this.gui_objects.messageform)
+          break;
+
+        // if saving Drafts is disabled in main.inc.php
+        // or if compose form did not change
+        if (!this.env.drafts_mailbox || this.cmp_hash == this.compose_field_hash())
+          break;
+
+        this.set_busy(true, 'savingmessage');
+        var form = this.gui_objects.messageform;
+        form.target = "savetarget";
+        form._draft.value = '1';
+        form.submit();
+        break;
+
+      case 'send':
+        if (!this.gui_objects.messageform)
+          break;
+
+        if (!this.check_compose_input())
+          break;
+
+        // Reset the auto-save timer
+        self.clearTimeout(this.save_timer);
+
+        // all checks passed, send message
+        this.set_busy(true, 'sendingmessage');
+        var form = this.gui_objects.messageform;
+        form.target = "savetarget";     
+        form._draft.value = '';
+        form.submit();
+        
+        // clear timeout (sending could take longer)
+        clearTimeout(this.request_timer);
+        break;
+
+      case 'add-attachment':
+        this.show_attachment_form(true);
+        
+      case 'send-attachment':
+        // Reset the auto-save timer
+        self.clearTimeout(this.save_timer);
+
+        this.upload_file(props)      
+        break;
+      
+      case 'remove-attachment':
+        this.remove_attachment(props);
+        break;
+
+      case 'reply-all':
+      case 'reply':
+        var uid;
+        if (uid = this.get_single_uid())
+          this.goto_url('compose', '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''), true);
+        break;      
+
+      case 'forward':
+        var uid;
+        if (uid = this.get_single_uid())
+          this.goto_url('compose', '_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
+        break;
+        
+      case 'print':
+        var uid;
+        if (uid = this.get_single_uid())
+        {
+          ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''));
+          if (this.printwin)
+          {
+            window.setTimeout(function(){ ref.printwin.focus(); }, 20);
+            if (this.env.action != 'show')
+              this.mark_message('read', uid);
+          }
+        }
+        break;
+
+      case 'viewsource':
+        var uid;
+        if (uid = this.get_single_uid())
+          {
+          ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox));
+          if (this.sourcewin)
+            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
+          }
+        break;
+
+      case 'add-contact':
+        this.add_contact(props);
+        break;
+      
+      // quicksearch
+      case 'search':
+        if (!props && this.gui_objects.qsearchbox)
+          props = this.gui_objects.qsearchbox.value;
+        if (props)
+        {
+          this.qsearch(props);
+          break;
+        }
+
+      // reset quicksearch
+      case 'reset-search':
+        var s = this.env.search_request;
+        this.reset_qsearch();
+        
+        if (s && this.env.mailbox)
+          this.list_mailbox(this.env.mailbox);
+        else if (s && this.task == 'addressbook')
+          this.list_contacts(this.env.source);
+        break;
+
+      case 'import':
+        if (this.env.action == 'import' && this.gui_objects.importform) {
+          var file = document.getElementById('rcmimportfile');
+          if (file && !file.value) {
+            alert(this.get_label('selectimportfile'));
+            break;
+          }
+          this.gui_objects.importform.submit();
+          this.set_busy(true, 'importwait');
+          this.lock_form(this.gui_objects.importform, true);
+        }
+        else
+          this.goto_url('import');
+        break;
+        
+      case 'export':
+        if (this.contact_list.rowcount > 0) {
+          var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : '');
+          if (this.env.search_request)
+            add_url += '_search='+this.env.search_request;
+        
+          this.goto_url('export', add_url);
+        }
+        break;
+
+      // collapse/expand folder
+      case 'collapse-folder':
+        if (props)
+          this.collapse_folder(props);
+        break;
+
+      // user settings commands
+      case 'preferences':
+        this.goto_url('');
+        break;
+
+      case 'identities':
+        this.goto_url('identities');
+        break;
+          
+      case 'delete-identity':
+        this.delete_identity();
+        
+      case 'folders':
+        this.goto_url('folders');
+        break;
+
+      case 'subscribe':
+        this.subscribe_folder(props);
+        break;
+
+      case 'unsubscribe':
+        this.unsubscribe_folder(props);
+        break;
+        
+      case 'create-folder':
+        this.create_folder(props);
+        break;
+
+      case 'rename-folder':
+        this.rename_folder(props);
+        break;
+
+      case 'delete-folder':
+        this.delete_folder(props);
+        break;
+
+      }
+
+    return obj ? false : true;
+    };
+
+  // set command enabled or disabled
+  this.enable_command = function()
+    {
+    var args = arguments;
+    if(!args.length) return -1;
+
+    var command;
+    var enable = args[args.length-1];
+    
+    for(var n=0; n<args.length-1; n++)
+      {
+      command = args[n];
+      this.commands[command] = enable;
+      this.set_button(command, (enable ? 'act' : 'pas'));
+      }
+      return true;
+    };
+
+  // lock/unlock interface
+  this.set_busy = function(a, message)
+    {
+    if (a && message)
+      {
+      var msg = this.get_label(message);
+      if (msg==message)        
+        msg = 'Loading...';
+
+      this.display_message(msg, 'loading', true);
+      }
+    else if (!a)
+      this.hide_message();
+
+    this.busy = a;
+    //document.body.style.cursor = a ? 'wait' : 'default';
+    
+    if (this.gui_objects.editform)
+      this.lock_form(this.gui_objects.editform, a);
+      
+    // clear pending timer
+    if (this.request_timer)
+      clearTimeout(this.request_timer);
+
+    // set timer for requests
+    if (a && this.env.request_timeout)
+      this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000);
+    };
+
+  // return a localized string
+  this.get_label = function(name)
+    {
+    if (this.labels[name])
+      return this.labels[name];
+    else
+      return name;
+    };
+
+  // switch to another application task
+  this.switch_task = function(task)
+    {
+    if (this.task===task && task!='mail')
+      return;
+
+    var url = this.get_task_url(task);
+    if (task=='mail')
+      url += '&_mbox=INBOX';
+
+    this.redirect(url);
+    };
+
+  this.get_task_url = function(task, url)
+    {
+    if (!url)
+      url = this.env.comm_path;
+
+    return url.replace(/_task=[a-z]+/, '_task='+task);
+    };
+    
+  // called when a request timed out
+  this.request_timed_out = function()
+    {
+    this.set_busy(false);
+    this.display_message('Request timed out!', 'error');
+    };
+
+
+  /*********************************************************/
+  /*********        event handling methods         *********/
+  /*********************************************************/
+
+  this.doc_mouse_up = function(e)
+  {
+    var model, li;
+
+    if (this.message_list) {
+      if (!rcube_mouse_is_over(e, this.message_list.list))
+        this.message_list.blur();
+      model = this.env.mailboxes;
+    }
+    else if (this.contact_list) {
+      if (!rcube_mouse_is_over(e, this.contact_list.list))
+        this.contact_list.blur();
+      model = this.env.address_sources;
+    }
+    else if (this.ksearch_value) {
+      this.ksearch_blur();
+    }
+
+    // handle mouse release when dragging
+    if (this.drag_active && model && this.env.last_folder_target) {
+      this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false);
+      this.command('moveto', model[this.env.last_folder_target].id);
+      this.env.last_folder_target = null;
+    }
+  };
+
+  this.drag_start = function(list)
+  {
+    this.initialBodyScrollTop = bw.ie ? 0 : window.pageYOffset;
+    this.initialMailBoxScrollTop = document.getElementById("mailboxlist-container").scrollTop;
+
+    var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources;
+
+    this.drag_active = true;
+    if (this.preview_timer)
+      clearTimeout(this.preview_timer);
+    
+    // save folderlist and folders location/sizes for droptarget calculation in drag_move()
+    if (this.gui_objects.folderlist && model)
+      {
+      var li, pos, list, height;
+      list = rcube_find_object(this.task == 'mail' ? 'mailboxlist' : 'directorylist');
+      pos = rcube_get_object_pos(list);
+      this.env.folderlist_coords = {x1:pos.x, y1:pos.y, x2:pos.x + list.offsetWidth, y2:pos.y + list.offsetHeight};
+
+      this.env.folder_coords = new Array();
+      for (var k in model) {
+        if (li = this.get_folder_li(k))
+         {
+         pos = rcube_get_object_pos(li.firstChild);
+         // only visible folders
+         if (height = li.firstChild.offsetHeight)
+           this.env.folder_coords[k] = {x1:pos.x, y1:pos.y, x2:pos.x + li.firstChild.offsetWidth, y2:pos.y + height};
+          }
+        }
+      }
+  };
+
+  this.drag_move = function(e)
+    {
+    if (this.gui_objects.folderlist && this.env.folder_coords)
+      {
+      // offsets to compensate for scrolling while dragging a message
+      var boffset = bw.ie ? -document.documentElement.scrollTop : this.initialBodyScrollTop;
+      var moffset = this.initialMailBoxScrollTop-document.getElementById('mailboxlist-container').scrollTop;
+      var toffset = -moffset-boffset;
+
+      var li, pos, mouse;
+      mouse = rcube_event.get_mouse_pos(e);
+      pos = this.env.folderlist_coords;
+
+      mouse.y += toffset;
+
+      // if mouse pointer is outside of folderlist
+      if (mouse.x < pos.x1 || mouse.x >= pos.x2 
+           || mouse.y < pos.y1 || mouse.y >= pos.y2)
+       {
+       if (this.env.last_folder_target) {
+         this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false);
+          this.env.last_folder_target = null;
+         }
+       return;
+        }
+
+      // over the folders
+      for (var k in this.env.folder_coords)
+        {
+       pos = this.env.folder_coords[k];
+       if (this.check_droptarget(k) && ((mouse.x >= pos.x1) && (mouse.x < pos.x2) 
+           && (mouse.y >= pos.y1) && (mouse.y < pos.y2)))
+         {
+          this.set_classname(this.get_folder_li(k), 'droptarget', true);
+         this.env.last_folder_target = k;
+         }
+       else
+         this.set_classname(this.get_folder_li(k), 'droptarget', false);
+        }
+      }
+    };
+  
+  this.collapse_folder = function(id)
+    {
+    var div;
+    if ((li = this.get_folder_li(id)) &&
+        (div = li.getElementsByTagName("div")[0]) &&
+        (div.className.match(/collapsed/) || div.className.match(/expanded/)))
+      {
+      var ul = li.getElementsByTagName("ul")[0];
+      if (div.className.match(/collapsed/))
+        {
+        ul.style.display = '';
+        this.set_classname(div, 'collapsed', false);
+        this.set_classname(div, 'expanded', true);
+        var reg = new RegExp('&'+urlencode(id)+'&');
+        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
+        }
+      else
+        {
+        ul.style.display = 'none';
+        this.set_classname(div, 'expanded', false);
+        this.set_classname(div, 'collapsed', true);
+        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&');
+
+        // select parent folder if one of its childs is currently selected
+        if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
+          this.command('list', id);
+        }
+
+      // Work around a bug in IE6 and IE7, see #1485309
+      if ((bw.ie6 || bw.ie7) &&
+          li.nextSibling &&
+          (li.nextSibling.getElementsByTagName("ul").length>0) &&
+          li.nextSibling.getElementsByTagName("ul")[0].style &&
+          (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none'))
+        {
+          li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none';
+          li.nextSibling.getElementsByTagName("ul")[0].style.display = '';
+        }
+
+      this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders));
+      this.set_unread_count_display(id, false);
+      }
+    }
+
+  this.click_on_list = function(e)
+    {
+    if (this.gui_objects.qsearchbox)
+      this.gui_objects.qsearchbox.blur();
+
+    if (this.message_list)
+      this.message_list.focus();
+    else if (this.contact_list)
+      this.contact_list.focus();
+
+    var mbox_li;
+    if (mbox_li = this.get_folder_li())
+      this.set_classname(mbox_li, 'unfocused', true);
+
+    return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e);
+    };
+
+  this.msglist_select = function(list)
+    {
+    if (this.preview_timer)
+      clearTimeout(this.preview_timer);
+
+    var selected = list.selection.length==1;
+
+    // Hide certain command buttons when Drafts folder is selected
+    if (this.env.mailbox == this.env.drafts_mailbox)
+      {
+      this.enable_command('reply', 'reply-all', 'forward', false);
+      this.enable_command('show', 'print', selected);
+      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
+      }
+    else
+      {
+      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', selected);
+      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
+      }
+
+    // start timer for message preview (wait for double click)
+    if (selected && this.env.contentframe && !list.multi_selecting)
+      this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200);
+    else if (this.env.contentframe)
+      this.show_contentframe(false);
+    };
+
+  this.msglist_dbl_click = function(list)
+    {
+      if (this.preview_timer)
+        clearTimeout(this.preview_timer);
+
+    var uid = list.get_single_selection();
+    if (uid && this.env.mailbox == this.env.drafts_mailbox)
+      this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
+    else if (uid)
+      this.show_message(uid, false, false);
+    };
+
+  this.msglist_keypress = function(list)
+    {
+    if (list.key_pressed == list.ENTER_KEY)
+      this.command('show');
+    else if (list.key_pressed == list.DELETE_KEY)
+      this.command('delete');
+    else if (list.key_pressed == list.BACKSPACE_KEY)
+      this.command('delete');
+    else
+      list.shiftkey = false;
+    };
+
+  this.msglist_get_preview = function()
+  {
+    var uid = this.get_single_uid();
+    if (uid && this.env.contentframe && !this.drag_active)
+      this.show_message(uid, false, true);
+    else if (this.env.contentframe)
+      this.show_contentframe(false);
+  };
+  
+  this.check_droptarget = function(id)
+  {
+    if (this.task == 'mail')
+      return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual);
+    else if (this.task == 'addressbook')
+      return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly);
+    else if (this.task == 'settings')
+      return (id != this.env.folder);
+  };
+
+
+  /*********************************************************/
+  /*********     (message) list functionality      *********/
+  /*********************************************************/
+
+  // when user doble-clicks on a row
+  this.show_message = function(id, safe, preview)
+    {
+    if (!id) return;
+    
+    var add_url = '';
+    var action = preview ? 'preview': 'show';
+    var target = window;
+    
+    if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      add_url = '&_framed=1';
+      }
+
+    if (safe)
+      add_url = '&_safe=1';
+
+    // also send search request to get the right messages
+    if (this.env.search_request)
+      add_url += '&_search='+this.env.search_request;
+    var url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url;
+    if (action == 'preview' && String(target.location.href).indexOf(url) >= 0)
+      this.show_contentframe(true);
+    else
+      {
+      this.set_busy(true, 'loading');
+      target.location.href = this.env.comm_path+url;
+
+      // mark as read and change mbox unread counter
+      if (action == 'preview' && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread)
+        {
+        this.set_message(id, 'unread', false);
+       if (this.env.unread_counts[this.env.mailbox])
+         {
+         this.env.unread_counts[this.env.mailbox] -= 1;
+         this.set_unread_count(this.env.mailbox, this.env.unread_counts[this.env.mailbox], this.env.mailbox == 'INBOX');
+         }
+       }
+      }
+    };
+
+  this.show_contentframe = function(show)
+    {
+    var frm;
+    if (this.env.contentframe && (frm = rcube_find_object(this.env.contentframe)))
+      {
+      if (!show && window.frames[this.env.contentframe])
+        {
+        if (window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0)
+          window.frames[this.env.contentframe].location.href = this.env.blankpage;
+        }
+      else if (!bw.safari && !bw.konq)
+        frm.style.display = show ? 'block' : 'none';
+      }
+
+    if (!show && this.busy)
+      this.set_busy(false);
+    };
+
+  // list a specific page
+  this.list_page = function(page)
+    {
+    if (page=='next')
+      page = this.env.current_page+1;
+    if (page=='last')
+      page = this.env.pagecount;
+    if (page=='prev' && this.env.current_page>1)
+      page = this.env.current_page-1;
+    if (page=='first' && this.env.current_page>1)
+      page = 1;
+      
+    if (page > 0 && page <= this.env.pagecount)
+      {
+      this.env.current_page = page;
+      
+      if (this.task=='mail')
+        this.list_mailbox(this.env.mailbox, page);
+      else if (this.task=='addressbook')
+        this.list_contacts(this.env.source, page);
+      }
+    };
+
+  // list messages of a specific mailbox using filter
+  this.filter_mailbox = function(filter)
+    {
+      var search;
+      if (this.gui_objects.qsearchbox)
+        search = this.gui_objects.qsearchbox.value;
+      
+      this.message_list.clear();
+
+      // reset vars
+      this.env.current_page = 1;
+      this.set_busy(true, 'searching');
+      this.http_request('search', '_filter='+filter
+           + (search ? '&_q='+urlencode(search) : '')
+           + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true);
+    }
+
+
+  // list messages of a specific mailbox
+  this.list_mailbox = function(mbox, page, sort)
+    {
+    this.last_selected = 0;
+    var add_url = '';
+    var target = window;
+
+    if (!mbox)
+      mbox = this.env.mailbox;
+
+    // add sort to url if set
+    if (sort)
+      add_url += '&_sort=' + sort;
+
+    // also send search request to get the right messages
+    if (this.env.search_request)
+      add_url += '&_search='+this.env.search_request;
+      
+    // set page=1 if changeing to another mailbox
+    if (!page && mbox != this.env.mailbox)
+      {
+      page = 1;
+      this.env.current_page = page;
+      if (this.message_list)
+        this.message_list.clear_selection();
+      this.show_contentframe(false);
+      }
+    
+    if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
+      add_url += '&_refresh=1';
+    
+    this.select_folder(mbox, this.env.mailbox);
+    this.env.mailbox = mbox;
+
+    // load message list remotely
+    if (this.gui_objects.messagelist)
+      {
+      this.list_mailbox_remote(mbox, page, add_url);
+      return;
+      }
+    
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      add_url += '&_framed=1';
+      }
+
+    // load message list to target frame/window
+    if (mbox)
+      {
+      this.set_busy(true, 'loading');
+      target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url;
+      }
+    };
+
+  // send remote request to load message list
+  this.list_mailbox_remote = function(mbox, page, add_url)
+    {
+    // clear message list first
+    this.message_list.clear();
+
+    // send request to server
+    var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : '');
+    this.set_busy(true, 'loading');
+    this.http_request('list', url+add_url, true);
+    };
+
+  this.expunge_mailbox = function(mbox)
+    {
+    var lock = false;
+    var add_url = '';
+    
+    // lock interface if it's the active mailbox
+    if (mbox == this.env.mailbox)
+       {
+       lock = true;
+       this.set_busy(true, 'loading');
+       add_url = '&_reload=1';
+       }
+
+    // send request to server
+    var url = '_mbox='+urlencode(mbox);
+    this.http_post('expunge', url+add_url, lock);
+    };
+
+  this.purge_mailbox = function(mbox)
+    {
+    var lock = false;
+    var add_url = '';
+    
+    if (!confirm(this.get_label('purgefolderconfirm')))
+      return false;
+    
+    // lock interface if it's the active mailbox
+    if (mbox == this.env.mailbox)
+       {
+       lock = true;
+       this.set_busy(true, 'loading');
+       add_url = '&_reload=1';
+       }
+
+    // send request to server
+    var url = '_mbox='+urlencode(mbox);
+    this.http_post('purge', url+add_url, lock);
+    return true;
+    };
+
+  // test if purge command is allowed
+  this.purge_mailbox_test = function()
+  {
+    return (this.env.messagecount && (this.env.mailbox == this.env.trash_mailbox || this.env.mailbox == this.env.junk_mailbox 
+      || this.env.mailbox.match('^' + RegExp.escape(this.env.trash_mailbox) + RegExp.escape(this.env.delimiter)) 
+      || this.env.mailbox.match('^' + RegExp.escape(this.env.junk_mailbox) + RegExp.escape(this.env.delimiter))));
+  };
+
+  // set message icon
+  this.set_message_icon = function(uid)
+  {
+    var icn_src;
+    var rows = this.message_list.rows;
+
+    if (!rows[uid])
+      return false;
+
+    if (rows[uid].deleted && this.env.deletedicon)
+      icn_src = this.env.deletedicon;
+    else if (rows[uid].replied && this.env.repliedicon)
+      {
+      if (rows[uid].forwarded && this.env.forwardedrepliedicon)
+        icn_src = this.env.forwardedrepliedicon;
+      else
+        icn_src = this.env.repliedicon;
+      }
+    else if (rows[uid].forwarded && this.env.forwardedicon)
+      icn_src = this.env.forwardedicon;
+    else if (rows[uid].unread && this.env.unreadicon)
+      icn_src = this.env.unreadicon;
+    else if (this.env.messageicon)
+      icn_src = this.env.messageicon;
+      
+    if (icn_src && rows[uid].icon)
+      rows[uid].icon.src = icn_src;
+
+    icn_src = '';
+    
+    if (rows[uid].flagged && this.env.flaggedicon)
+      icn_src = this.env.flaggedicon;
+    else if (!rows[uid].flagged && this.env.unflaggedicon)
+      icn_src = this.env.unflaggedicon;
+
+    if (rows[uid].flagged_icon && icn_src)
+      rows[uid].flagged_icon.src = icn_src;
+  }
+
+  // set message status
+  this.set_message_status = function(uid, flag, status)
+    {
+    var rows = this.message_list.rows;
+
+    if (!rows[uid]) return false;
+
+    if (flag == 'unread')
+      rows[uid].unread = status;
+    else if(flag == 'deleted')
+      rows[uid].deleted = status;
+    else if (flag == 'replied')
+      rows[uid].replied = status;
+    else if (flag == 'forwarded')
+      rows[uid].forwarded = status;
+    else if (flag == 'flagged')
+      rows[uid].flagged = status;
+
+    this.env.messages[uid] = rows[uid];
+    }
+
+  // set message row status, class and icon
+  this.set_message = function(uid, flag, status)
+    {
+    var rows = this.message_list.rows;
+
+    if (!rows[uid]) return false;
+    
+    if (flag)
+      this.set_message_status(uid, flag, status);
+    
+    if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0)
+      {
+      rows[uid].classname += ' unread';
+      this.set_classname(rows[uid].obj, 'unread', true);
+      }
+    else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*unread/, '');
+      this.set_classname(rows[uid].obj, 'unread', false);
+      }
+    
+    if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0)
+      {
+      rows[uid].classname += ' deleted';
+      this.set_classname(rows[uid].obj, 'deleted', true);
+      }
+    else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
+      this.set_classname(rows[uid].obj, 'deleted', false);
+      }
+
+    if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0)
+      {
+      rows[uid].classname += ' flagged';
+      this.set_classname(rows[uid].obj, 'flagged', true);
+      }
+    else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, '');
+      this.set_classname(rows[uid].obj, 'flagged', false);
+      }
+
+    this.set_message_icon(uid);
+    }
+
+  // move selected messages to the specified mailbox
+  this.move_messages = function(mbox)
+    {
+    // exit if current or no mailbox specified or if selection is empty
+    if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)))
+      return;
+
+    var lock = false;
+    var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : '');
+
+    // show wait message
+    if (this.env.action=='show')
+      {
+      lock = true;
+      this.set_busy(true, 'movingmessage');
+      }
+    else if (!this.env.flag_for_deletion)
+      this.show_contentframe(false);
+
+    // Hide message command buttons until a message is selected
+    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', false);
+
+    this._with_selected_messages('moveto', lock, add_url, (this.env.flag_for_deletion ? false : true));
+    };
+
+  // delete selected messages from the current mailbox
+  this.delete_messages = function()
+    {
+    var selection = this.message_list ? this.message_list.get_selection() : new Array();
+
+    // exit if no mailbox specified or if selection is empty
+    if (!this.env.uid && !selection.length)
+        return;
+
+    // if there is a trash mailbox defined and we're not currently in it:
+    if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() != String(this.env.trash_mailbox).toLowerCase())
+      {
+      // if shift was pressed delete it immediately
+      if (this.message_list && this.message_list.shiftkey)
+        {
+        if (confirm(this.get_label('deletemessagesconfirm')))
+          this.permanently_remove_messages();
+        }
+      else
+        this.move_messages(this.env.trash_mailbox);
+      }
+    // if there is a trash mailbox defined but we *are* in it:
+    else if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase())
+      this.permanently_remove_messages();
+    // if there isn't a defined trash mailbox and the config is set to flag for deletion
+    else if (!this.env.trash_mailbox && this.env.flag_for_deletion)
+      {
+      this.mark_message('delete');
+      if(this.env.action=="show")
+        this.command('nextmessage','',this);
+      else if (selection.length == 1)
+        this.message_list.select_next();
+      }
+    // if there isn't a defined trash mailbox and the config is set NOT to flag for deletion
+    else if (!this.env.trash_mailbox) 
+      this.permanently_remove_messages();
+  };
+
+  // delete the selected messages permanently
+  this.permanently_remove_messages = function()
+    {
+    // exit if no mailbox specified or if selection is empty
+    if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))
+      return;
+      
+    this.show_contentframe(false);
+    this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''), true);
+    };
+
+  // Send a specifc request with UIDs of all selected messages
+  // @private
+  this._with_selected_messages = function(action, lock, add_url, remove)
+  {
+    var a_uids = new Array();
+
+    if (this.env.uid)
+      a_uids[0] = this.env.uid;
+    else
+    {
+      var selection = this.message_list.get_selection();
+      var rows = this.message_list.rows;
+      var id;
+      for (var n=0; n<selection.length; n++)
+        {
+        id = selection[n];
+        a_uids[a_uids.length] = id;
+
+        if (remove)
+          this.message_list.remove_row(id, (n == selection.length-1));
+        else
+        {
+          this.set_message_status(id, 'deleted', true);
+          if (this.env.read_when_deleted)
+           this.set_message_status(id, 'unread', false);
+         this.set_message(id);
+        }
+      }
+    }
+
+    // also send search request to get the right messages 
+    if (this.env.search_request) 
+      add_url += '&_search='+this.env.search_request;
+
+    // send request to server
+    this.http_post(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock);
+  };
+
+  // set a specific flag to one or more messages
+  this.mark_message = function(flag, uid)
+    {
+    var a_uids = new Array();
+    var r_uids = new Array();
+    var selection = this.message_list ? this.message_list.get_selection() : new Array();
+
+    if (uid)
+      a_uids[0] = uid;
+    else if (this.env.uid)
+      a_uids[0] = this.env.uid;
+    else if (this.message_list)
+      {
+      for (var n=0; n<selection.length; n++)
+        {
+          a_uids[a_uids.length] = selection[n];
+        }
+      }
+
+    if (!this.message_list)
+      r_uids = a_uids;
+    else
+      for (var id, n=0; n<a_uids.length; n++)
+      {
+        id = a_uids[n];
+        if ((flag=='read' && this.message_list.rows[id].unread) 
+            || (flag=='unread' && !this.message_list.rows[id].unread)
+            || (flag=='delete' && !this.message_list.rows[id].deleted)
+            || (flag=='undelete' && this.message_list.rows[id].deleted)
+            || (flag=='flagged' && !this.message_list.rows[id].flagged)
+            || (flag=='unflagged' && this.message_list.rows[id].flagged))
+        {
+          r_uids[r_uids.length] = id;
+        }
+      }
+
+    // nothing to do
+    if (!r_uids.length)
+      return;
+
+    switch (flag)
+      {
+        case 'read':
+        case 'unread':
+          this.toggle_read_status(flag, r_uids);
+          break;
+        case 'delete':
+        case 'undelete':
+          this.toggle_delete_status(r_uids);
+          break;
+        case 'flagged':
+        case 'unflagged':
+          this.toggle_flagged_status(flag, a_uids);
+          break;
+      }
+    };
+
+  // set class to read/unread
+  this.toggle_read_status = function(flag, a_uids)
+  {
+    // mark all message rows as read/unread
+    for (var i=0; i<a_uids.length; i++)
+      this.set_message(a_uids[i], 'unread', (flag=='unread' ? true : false));
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
+  };
+
+  // set image to flagged or unflagged
+  this.toggle_flagged_status = function(flag, a_uids)
+  {
+    // mark all message rows as flagged/unflagged
+    for (var i=0; i<a_uids.length; i++)
+      this.set_message(a_uids[i], 'flagged', (flag=='flagged' ? true : false));
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
+  };
+  
+  // mark all message rows as deleted/undeleted
+  this.toggle_delete_status = function(a_uids)
+  {
+    var rows = this.message_list ? this.message_list.rows : new Array();
+    
+    if (a_uids.length==1)
+    {
+      if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted))
+        this.flag_as_deleted(a_uids);
+      else
+        this.flag_as_undeleted(a_uids);
+
+      return true;
+    }
+    
+    var all_deleted = true;
+    for (var i=0; i<a_uids.length; i++)
+    {
+      uid = a_uids[i];
+      if (rows[uid]) {
+        if (!rows[uid].deleted)
+        {
+          all_deleted = false;
+          break;
+        }
+      }
+    }
+    
+    if (all_deleted)
+      this.flag_as_undeleted(a_uids);
+    else
+      this.flag_as_deleted(a_uids);
+    
+    return true;
+  };
+
+  this.flag_as_undeleted = function(a_uids)
+  {
+    for (var i=0; i<a_uids.length; i++)
+      this.set_message(a_uids[i], 'deleted', false);
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=undelete');
+    return true;
+  };
+
+  this.flag_as_deleted = function(a_uids)
+  {
+    var add_url = '';
+    var r_uids = new Array();
+    var rows = this.message_list ? this.message_list.rows : new Array();
+    
+    for (var i=0; i<a_uids.length; i++)
+      {
+      uid = a_uids[i];
+      if (rows[uid])
+        {
+       this.set_message(uid, 'deleted', true);
+        if (rows[uid].unread)
+          r_uids[r_uids.length] = uid;
+        }
+      }
+
+    if (r_uids.length)
+      add_url = '&_ruid='+r_uids.join(',');
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=delete'+add_url);
+    return true;  
+  };
+
+  // flag as read without mark request (called from backend)
+  // argument should be a coma-separated list of uids
+  this.flag_deleted_as_read = function(uids)
+  {
+    var icn_src;
+    var rows = this.message_list ? this.message_list.rows : new Array();
+    var str = String(uids);
+    var a_uids = new Array();
+
+    a_uids = str.split(',');
+
+    for (var uid, i=0; i<a_uids.length; i++)
+      {
+      uid = a_uids[i];
+      if (rows[uid])
+        this.set_message(uid, 'unread', false);
+      }
+  };
+  
+  
+  /*********************************************************/
+  /*********           login form methods          *********/
+  /*********************************************************/
+
+  // handler for keyboard events on the _user field
+  this.login_user_keyup = function(e)
+  {
+    var key = rcube_event.get_keycode(e);
+    var elm;
+
+    // enter
+    if ((key==13) && (elm = rcube_find_object('_pass')))
+    {
+      elm.focus();
+      return false;
+    }
+  };
+
+
+  /*********************************************************/
+  /*********        message compose methods        *********/
+  /*********************************************************/
+  
+  // checks the input fields before sending a message
+  this.check_compose_input = function()
+    {
+    // check input fields
+    var input_to = rcube_find_object('_to');
+    var input_cc = rcube_find_object('_cc');
+    var input_bcc = rcube_find_object('_bcc');
+    var input_from = rcube_find_object('_from');
+    var input_subject = rcube_find_object('_subject');
+    var input_message = rcube_find_object('_message');
+
+    // check sender (if have no identities)
+    if (input_from.type == 'text' && !rcube_check_email(input_from.value, true))
+      {
+      alert(this.get_label('nosenderwarning'));
+      input_from.focus();
+      return false;
+      }
+
+    // check for empty recipient
+    var recipients = input_to.value ? input_to.value : (input_cc.value ? input_cc.value : input_bcc.value);
+    if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true))
+      {
+      alert(this.get_label('norecipientwarning'));
+      input_to.focus();
+      return false;
+      }
+
+    // display localized warning for missing subject
+    if (input_subject && input_subject.value == '')
+      {
+      var subject = prompt(this.get_label('nosubjectwarning'), this.get_label('nosubject'));
+
+      // user hit cancel, so don't send
+      if (!subject && subject !== '')
+        {
+        input_subject.focus();
+        return false;
+        }
+      else
+        {
+        input_subject.value = subject ? subject : this.get_label('nosubject');            
+        }
+      }
+
+    // check for empty body
+    if ((!window.tinyMCE || !tinyMCE.get('compose-body')) && input_message.value == '' && !confirm(this.get_label('nobodywarning')))
+      {
+      input_message.focus();
+      return false;
+      }
+    else if (window.tinyMCE && tinyMCE.get('compose-body') && !tinyMCE.get('compose-body').getContent() && !confirm(this.get_label('nobodywarning')))
+      {
+      tinyMCE.get('compose-body').focus();
+      return false;
+      }
+
+    // Apply spellcheck changes if spell checker is active
+    this.stop_spellchecking();
+
+    return true;
+    };
+
+  this.stop_spellchecking = function()
+    {
+    if (this.env.spellcheck && !this.spellcheck_ready) {
+      exec_event(this.env.spellcheck.check_link, 'click');
+      this.set_spellcheck_state('ready');
+      }
+    };
+
+  this.display_spellcheck_controls = function(vis)
+    {
+    if (this.env.spellcheck) {
+      // stop spellchecking process
+      if (!vis)
+       this.stop_spellchecking();
+                             
+      this.env.spellcheck.check_link.style.visibility = vis ? 'visible' : 'hidden';
+      this.env.spellcheck.switch_lan_pic.style.visibility = vis ? 'visible' : 'hidden';
+      }
+    };
+
+  this.set_spellcheck_state = function(s)
+    {
+    this.spellcheck_ready = (s=='check_spelling' || s=='ready');
+    this.enable_command('spellcheck', this.spellcheck_ready);
+    };
+
+  this.set_draft_id = function(id)
+    {
+    var f;
+    if (f = rcube_find_object('_draft_saveid'))
+      f.value = id;
+    };
+
+  this.auto_save_start = function()
+    {
+    if (this.env.draft_autosave)
+      this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
+
+    // Unlock interface now that saving is complete
+    this.busy = false;
+    };
+
+  this.compose_field_hash = function(save)
+    {
+    // check input fields
+    var input_to = rcube_find_object('_to');
+    var input_cc = rcube_find_object('_cc');
+    var input_bcc = rcube_find_object('_bcc');
+    var input_subject = rcube_find_object('_subject');
+    var editor, input_message;
+    var str = '';
+    
+    if (input_to && input_to.value)
+      str += input_to.value+':';
+    if (input_cc && input_cc.value)
+      str += input_cc.value+':';
+    if (input_bcc && input_bcc.value)
+      str += input_bcc.value+':';
+    if (input_subject && input_subject.value)
+      str += input_subject.value+':';
+    
+    if (editor = tinyMCE.get('compose-body'))
+      str += editor.getContent();
+    else
+      {
+      input_message = rcube_find_object('_message');
+      str += input_message.value;
+      }
+    
+    if (save)
+      this.cmp_hash = str;
+    
+    return str;
+    };
+    
+  this.change_identity = function(obj)
+    {
+    if (!obj || !obj.options)
+      return false;
+
+    var id = obj.options[obj.selectedIndex].value;
+    var input_message = rcube_find_object('_message');
+    var message = input_message ? input_message.value : '';
+    var is_html = (rcube_find_object('_is_html').value == '1');
+    var sig, p;
+
+    if (!this.env.identity)
+      this.env.identity = id
+  
+    if (!is_html)
+      {
+      // remove the 'old' signature
+      if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
+        {
+        if (this.env.signatures[this.env.identity]['is_html'])
+          sig = this.env.signatures[this.env.identity]['plain_text'];
+        else
+         sig = this.env.signatures[this.env.identity]['text'];
+        
+       if (sig.indexOf('-- ')!=0)
+          sig = '-- \n'+sig;
+
+        p = message.lastIndexOf(sig);
+        if (p>=0)
+          message = message.substring(0, p-1) + message.substring(p+sig.length, message.length);
+        }
+
+      message = message.replace(/[\r\n]+$/, '');
+      
+      // add the new signature string
+      if (this.env.signatures && this.env.signatures[id])
+        {
+        sig = this.env.signatures[id]['text'];
+        if (this.env.signatures[id]['is_html'])
+          {
+          sig = this.env.signatures[id]['plain_text'];
+          }
+        if (sig.indexOf('-- ')!=0)
+          sig = '-- \n'+sig;
+        message += '\n\n'+sig;
+        }
+      }
+    else
+      {
+      var editor = tinyMCE.get('compose-body');
+
+      if (this.env.signatures)
+        {
+        // Append the signature as a div within the body
+        var sigElem = editor.dom.get('_rc_sig');
+       var newsig = '';
+       var htmlsig = true;
+
+        if (!sigElem)
+          {
+         // add empty line before signature on IE
+         if (bw.ie)
+            editor.getBody().appendChild(editor.getDoc().createElement('br'));
+
+         sigElem = editor.getDoc().createElement('div');
+          sigElem.setAttribute('id', '_rc_sig');
+          editor.getBody().appendChild(sigElem);
+          }
+
+       if (this.env.signatures[id])
+         {
+         newsig = this.env.signatures[id]['text'];
+         htmlsig = this.env.signatures[id]['is_html'];
+        
+         if (newsig) {
+           if (htmlsig && this.env.signatures[id]['plain_text'].indexOf('-- ')!=0)
+              newsig = '<p>-- </p>' + newsig;
+           else if (!htmlsig && newsig.indexOf('-- ')!=0)
+              newsig = '-- \n' + newsig;
+           }
+         }
+
+        if (htmlsig)
+          sigElem.innerHTML = newsig;
+        else
+          sigElem.innerHTML = '<pre>' + newsig + '</pre>';
+        }
+      }
+
+    if (input_message)
+      input_message.value = message;
+
+    this.env.identity = id;
+    return true;
+    };
+
+  this.show_attachment_form = function(a)
+    {
+    if (!this.gui_objects.uploadbox)
+      return false;
+      
+    var elm, list;
+    if (elm = this.gui_objects.uploadbox)
+      {
+      if (a &&  (list = this.gui_objects.attachmentlist))
+        {
+        var pos = rcube_get_object_pos(list);
+        var left = pos.x;
+        var top = pos.y + list.offsetHeight + 10;
+      
+        elm.style.top = top+'px';
+        elm.style.left = left+'px';
+        }
+      
+      elm.style.visibility = a ? 'visible' : 'hidden';
+      }
+      
+    // clear upload form
+       try {
+      if (!a && this.gui_objects.attachmentform != this.gui_objects.messageform)
+       this.gui_objects.attachmentform.reset();
+       }
+       catch(e){}  // ignore errors
+    
+    return true;  
+    };
+
+  // upload attachment file
+  this.upload_file = function(form)
+    {
+    if (!form)
+      return false;
+      
+    // get file input fields
+    var send = false;
+    for (var n=0; n<form.elements.length; n++)
+      if (form.elements[n].type=='file' && form.elements[n].value)
+        {
+        send = true;
+        break;
+        }
+    
+    // create hidden iframe and post upload form
+    if (send)
+      {
+      var ts = new Date().getTime();
+      var frame_name = 'rcmupload'+ts;
+
+      // have to do it this way for IE
+      // otherwise the form will be posted to a new window
+      if(document.all)
+        {
+        var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>';
+        document.body.insertAdjacentHTML('BeforeEnd',html);
+        }
+      else  // for standards-compilant browsers
+        {
+        var frame = document.createElement('IFRAME');
+        frame.name = frame_name;
+        frame.style.border = 'none';
+        frame.style.width = 0;
+        frame.style.height = 0;
+        frame.style.visibility = 'hidden';
+        document.body.appendChild(frame);
+        }
+
+      form.target = frame_name;
+      form.action = this.env.comm_path+'&_action=upload';
+      form.setAttribute('enctype', 'multipart/form-data');
+      form.submit();
+      }
+    
+    // set reference to the form object
+    this.gui_objects.attachmentform = form;
+    return true;
+    };
+
+  // add file name to attachment list
+  // called from upload page
+  this.add2attachment_list = function(name, content)
+    {
+    if (!this.gui_objects.attachmentlist)
+      return false;
+      
+    var li = document.createElement('LI');
+    li.id = name;
+    li.innerHTML = content;
+    this.gui_objects.attachmentlist.appendChild(li);
+    return true;
+    };
+
+  this.remove_from_attachment_list = function(name)
+    {
+    if (!this.gui_objects.attachmentlist)
+      return false;
+
+    var list = this.gui_objects.attachmentlist.getElementsByTagName("li");
+    for (i=0;i<list.length;i++)
+      if (list[i].id == name)
+        this.gui_objects.attachmentlist.removeChild(list[i]);
+    };
+
+  this.remove_attachment = function(name)
+    {
+    if (name)
+      this.http_post('remove-attachment', '_file='+urlencode(name));
+
+    return true;
+    };
+
+  // send remote request to add a new contact
+  this.add_contact = function(value)
+    {
+    if (value)
+      this.http_post('addcontact', '_address='+value);
+    
+    return true;
+    };
+
+  // send remote request to search mail or contacts
+  this.qsearch = function(value, addurl)
+    {
+    if (value != '')
+      {
+      if (this.message_list)
+        this.message_list.clear();
+      else if (this.contact_list) {
+        this.contact_list.clear(true);
+        this.show_contentframe(false);
+        }
+
+      if (this.gui_objects.search_filter)
+      addurl = '&_filter=' + this.gui_objects.search_filter.value;
+
+      // reset vars
+      this.env.current_page = 1;
+      this.set_busy(true, 'searching');
+      this.http_request('search', '_q='+urlencode(value)
+        + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '')
+        + (this.env.source ? '&_source='+urlencode(this.env.source) : '')
+        + (addurl ? addurl : ''), true);
+      }
+    return true;
+    };
+
+  // reset quick-search form
+  this.reset_qsearch = function()
+    {
+    if (this.gui_objects.qsearchbox)
+      this.gui_objects.qsearchbox.value = '';
+      
+    this.env.search_request = null;
+    return true;
+    };
+
+  this.sent_successfully = function(type, msg)
+    {
+    this.list_mailbox();
+    this.display_message(msg, type, true);
+    }
+
+
+  /*********************************************************/
+  /*********     keyboard live-search methods      *********/
+  /*********************************************************/
+
+  // handler for keyboard events on address-fields
+  this.ksearch_keypress = function(e, obj)
+  {
+    if (this.ksearch_timer)
+      clearTimeout(this.ksearch_timer);
+
+    var highlight;
+    var key = rcube_event.get_keycode(e);
+    var mod = rcube_event.get_modifier(e);
+
+    switch (key)
+      {
+      case 38:  // key up
+      case 40:  // key down
+        if (!this.ksearch_pane)
+          break;
+          
+        var dir = key==38 ? 1 : 0;
+        
+        highlight = document.getElementById('rcmksearchSelected');
+        if (!highlight)
+          highlight = this.ksearch_pane.ul.firstChild;
+        
+        if (highlight)
+          this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling);
+
+        return rcube_event.cancel(e);
+
+      case 9:  // tab
+        if(mod == SHIFT_KEY)
+          break;
+
+      case 13:  // enter
+        if (this.ksearch_selected===null || !this.ksearch_input || !this.ksearch_value)
+          break;
+
+        // insert selected address and hide ksearch pane
+        this.insert_recipient(this.ksearch_selected);
+        this.ksearch_hide();
+
+        return rcube_event.cancel(e);
+
+      case 27:  // escape
+        this.ksearch_hide();
+        break;
+      
+      case 37:  // left
+      case 39:  // right
+        if (mod != SHIFT_KEY)
+         return;
+      }
+
+    // start timer
+    this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(); }, 200);
+    this.ksearch_input = obj;
+    
+    return true;
+  };
+  
+  this.ksearch_select = function(node)
+  {
+    var current = document.getElementById('rcmksearchSelected');
+    if (current && node) {
+      current.removeAttribute('id');
+      this.set_classname(current, 'selected', false);
+    }
+
+    if (node) {
+      node.setAttribute('id', 'rcmksearchSelected');
+      this.set_classname(node, 'selected', true);
+      this.ksearch_selected = node._rcm_id;
+    }
+  };
+
+  this.insert_recipient = function(id)
+  {
+    if (!this.env.contacts[id] || !this.ksearch_input)
+      return;
+    
+    // get cursor pos
+    var inp_value = this.ksearch_input.value.toLowerCase();
+    var cpos = this.get_caret_pos(this.ksearch_input);
+    var p = inp_value.lastIndexOf(this.ksearch_value, cpos);
+
+    // replace search string with full address
+    var pre = this.ksearch_input.value.substring(0, p);
+    var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length);
+    var insert  = this.env.contacts[id]+', ';
+    this.ksearch_input.value = pre + insert + end;
+
+    // set caret to insert pos
+    cpos = p+insert.length;
+    if (this.ksearch_input.setSelectionRange)
+      this.ksearch_input.setSelectionRange(cpos, cpos);
+  };
+
+  // address search processor
+  this.ksearch_get_results = function()
+  {
+    var inp_value = this.ksearch_input ? this.ksearch_input.value : null;
+    if (inp_value === null)
+      return;
+      
+    if (this.ksearch_pane && this.ksearch_pane.visible)
+      this.ksearch_pane.show(0);
+
+    // get string from current cursor pos to last comma
+    var cpos = this.get_caret_pos(this.ksearch_input);
+    var p = inp_value.lastIndexOf(',', cpos-1);
+    var q = inp_value.substring(p+1, cpos);
+
+    // trim query string
+    q = q.replace(/(^\s+|\s+$)/g, '').toLowerCase();
+
+    // Don't (re-)search if string is empty or if the last results are still active
+    if (!q.length || q == this.ksearch_value)
+      return;
+
+    this.ksearch_value = q;
+    
+    this.display_message(this.get_label('searching'), 'loading', true);
+    this.http_post('autocomplete', '_search='+q);
+  };
+
+  this.ksearch_query_results = function(results, search)
+  {
+    // ignore this outdated search response
+    if (search != this.ksearch_value)
+      return;
+      
+    this.hide_message();
+    this.env.contacts = results ? results : [];
+    this.ksearch_display_results(this.env.contacts);
+  };
+
+  this.ksearch_display_results = function (a_results)
+  {
+    // display search results
+    if (a_results.length && this.ksearch_input) {
+      var p, ul, li;
+      
+      // create results pane if not present
+      if (!this.ksearch_pane) {
+        ul = document.createElement('UL');
+        this.ksearch_pane = new rcube_layer('rcmKSearchpane', {vis:0, zindex:30000});
+        this.ksearch_pane.elm.appendChild(ul);
+        this.ksearch_pane.ul = ul;
+      }
+      else
+        ul = this.ksearch_pane.ul;
+
+      // remove all search results
+      ul.innerHTML = '';
+            
+      // add each result line to list
+      for (i=0; i<a_results.length; i++) {
+        li = document.createElement('LI');
+        li.innerHTML = a_results[i].replace(new RegExp('('+this.ksearch_value+')', 'ig'), '##$1%%').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/##([^%]+)%%/g, '<b>$1</b>');
+        li.onmouseover = function(){ ref.ksearch_select(this); };
+        li.onmouseup = function(){ ref.ksearch_click(this) };
+        li._rcm_id = i;
+        ul.appendChild(li);
+      }
+
+      // select the first
+      ul.firstChild.setAttribute('id', 'rcmksearchSelected');
+      this.set_classname(ul.firstChild, 'selected', true);
+      this.ksearch_selected = 0;
+
+      // move the results pane right under the input box and make it visible
+      var pos = rcube_get_object_pos(this.ksearch_input);
+      this.ksearch_pane.move(pos.x, pos.y+this.ksearch_input.offsetHeight);
+      this.ksearch_pane.show(1);
+    }
+    // hide results pane
+    else
+      this.ksearch_hide();
+  };
+  
+  this.ksearch_click = function(node)
+  {
+    if (this.ksearch_input)
+      this.ksearch_input.focus();
+
+    this.insert_recipient(node._rcm_id);
+    this.ksearch_hide();
+  };
+
+  this.ksearch_blur = function()
+    {
+    if (this.ksearch_timer)
+      clearTimeout(this.ksearch_timer);
+
+    this.ksearch_value = '';
+    this.ksearch_input = null;
+    
+    this.ksearch_hide();
+    };
+
+
+  this.ksearch_hide = function()
+    {
+    this.ksearch_selected = null;
+    
+    if (this.ksearch_pane)
+      this.ksearch_pane.show(0);
+    };
+
+
+  /*********************************************************/
+  /*********         address book methods          *********/
+  /*********************************************************/
+
+  this.contactlist_keypress = function(list)
+    {
+      if (list.key_pressed == list.DELETE_KEY)
+        this.command('delete');
+    };
+
+  this.contactlist_select = function(list)
+    {
+      if (this.preview_timer)
+        clearTimeout(this.preview_timer);
+
+      var id, frame, ref = this;
+      if (id = list.get_single_selection())
+        this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
+      else if (this.env.contentframe)
+        this.show_contentframe(false);
+
+      this.enable_command('compose', list.selection.length > 0);
+      this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false);
+      this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly);
+
+      return false;
+    };
+
+  this.list_contacts = function(src, page)
+    {
+    var add_url = '';
+    var target = window;
+    
+    if (!src)
+      src = this.env.source;
+    
+    if (page && this.current_page==page && src == this.env.source)
+      return false;
+      
+    if (src != this.env.source)
+      {
+      page = 1;
+      this.env.current_page = page;
+      this.reset_qsearch();
+      }
+
+    this.select_folder(src, this.env.source);
+    this.env.source = src;
+
+    // load contacts remotely
+    if (this.gui_objects.contactslist)
+      {
+      this.list_contacts_remote(src, page);
+      return;
+      }
+
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      add_url = '&_framed=1';
+      }
+
+    // also send search request to get the correct listing
+    if (this.env.search_request)
+      add_url += '&_search='+this.env.search_request;
+
+    this.set_busy(true, 'loading');
+    target.location.href = this.env.comm_path+(src ? '&_source='+urlencode(src) : '')+(page ? '&_page='+page : '')+add_url;
+    };
+
+  // send remote request to load contacts list
+  this.list_contacts_remote = function(src, page)
+    {
+    // clear message list first
+    this.contact_list.clear(true);
+    this.show_contentframe(false);
+    this.enable_command('delete', 'compose', false);
+
+    // send request to server
+    var url = (src ? '_source='+urlencode(src) : '') + (page ? (src?'&':'') + '_page='+page : '');
+    this.env.source = src;
+    
+    // also send search request to get the right messages 
+    if (this.env.search_request) 
+      url += '&_search='+this.env.search_request;
+
+    this.set_busy(true, 'loading');
+    this.http_request('list', url, true);
+    };
+
+  // load contact record
+  this.load_contact = function(cid, action, framed)
+    {
+    var add_url = '';
+    var target = window;
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      add_url = '&_framed=1';
+      target = window.frames[this.env.contentframe];
+      this.show_contentframe(true);
+      }
+    else if (framed)
+      return false;
+      
+    if (action && (cid || action=='add') && !this.drag_active)
+      {
+      this.set_busy(true);
+      target.location.href = this.env.comm_path+'&_action='+action+'&_source='+urlencode(this.env.source)+'&_cid='+urlencode(cid) + add_url;
+      }
+    return true;
+    };
+
+  // copy a contact to the specified target (group or directory)
+  this.copy_contact = function(cid, to)
+    {
+    if (!cid)
+      cid = this.contact_list.get_selection().join(',');
+
+    if (to != this.env.source && cid && this.env.address_sources[to] && !this.env.address_sources[to].readonly)
+      this.http_post('copy', '_cid='+urlencode(cid)+'&_source='+urlencode(this.env.source)+'&_to='+urlencode(to));
+    };
+
+
+  this.delete_contacts = function()
+    {
+    // exit if no mailbox specified or if selection is empty
+    var selection = this.contact_list.get_selection();
+    if (!(selection.length || this.env.cid) || !confirm(this.get_label('deletecontactconfirm')))
+      return;
+      
+    var a_cids = new Array();
+    var qs = '';
+
+    if (this.env.cid)
+      a_cids[a_cids.length] = this.env.cid;
+    else
+      {
+      var id;
+      for (var n=0; n<selection.length; n++)
+        {
+        id = selection[n];
+        a_cids[a_cids.length] = id;
+        this.contact_list.remove_row(id, (n == selection.length-1));
+        }
+
+      // hide content frame if we delete the currently displayed contact
+      if (selection.length == 1)
+        this.show_contentframe(false);
+      }
+
+    // also send search request to get the right records from the next page
+    if (this.env.search_request) 
+      qs += '&_search='+this.env.search_request;
+
+    // send request to server
+    this.http_post('delete', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source)+'&_from='+(this.env.action ? this.env.action : '')+qs);
+    return true;
+    };
+
+  // update a contact record in the list
+  this.update_contact_row = function(cid, cols_arr)
+    {
+    var row;
+    if (this.contact_list.rows[cid] && (row = this.contact_list.rows[cid].obj))
+      {
+      for (var c=0; c<cols_arr.length; c++)
+        if (row.cells[c])
+          row.cells[c].innerHTML = cols_arr[c];
+
+      return true;
+      }
+
+    return false;
+    };
+
+
+  /*********************************************************/
+  /*********        user settings methods          *********/
+  /*********************************************************/
+
+  this.init_subscription_list = function()
+    {
+    var p = this;
+    this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist, {multiselect:false, draggable:true, keyboard:false, toggleselect:true});
+    this.subscription_list.addEventListener('select', function(o){ p.subscription_select(o); });
+    this.subscription_list.addEventListener('dragstart', function(o){ p.drag_active = true; });
+    this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); });
+    this.subscription_list.row_init = function (row)
+      {
+      var anchors = row.obj.getElementsByTagName('A');
+      if (anchors[0])
+        anchors[0].onclick = function() { p.rename_folder(row.id); return false; };
+      if (anchors[1])
+        anchors[1].onclick = function() { p.delete_folder(row.id); return false; };
+      row.obj.onmouseover = function() { p.focus_subscription(row.id); };
+      row.obj.onmouseout = function() { p.unfocus_subscription(row.id); };
+      }
+    this.subscription_list.init();
+    }
+
+  this.identity_select = function(list)
+    {
+    var id;
+    if (id = list.get_single_selection())
+      this.load_identity(id, 'edit-identity');
+    };
+
+  // load contact record
+  this.load_identity = function(id, action)
+    {
+    if (action=='edit-identity' && (!id || id==this.env.iid))
+      return false;
+
+    var add_url = '';
+    var target = window;
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      add_url = '&_framed=1';
+      target = window.frames[this.env.contentframe];
+      document.getElementById(this.env.contentframe).style.visibility = 'inherit';
+      }
+
+    if (action && (id || action=='add-identity'))
+      {
+      this.set_busy(true);
+      target.location.href = this.env.comm_path+'&_action='+action+'&_iid='+id+add_url;
+      }
+    return true;
+    };
+
+  this.delete_identity = function(id)
+    {
+    // exit if no mailbox specified or if selection is empty
+    var selection = this.identity_list.get_selection();
+    if (!(selection.length || this.env.iid))
+      return;
+    
+    if (!id)
+      id = this.env.iid ? this.env.iid : selection[0];
+
+    // if (this.env.framed && id)
+    this.goto_url('delete-identity', '_iid='+id, true);
+    return true;
+    };
+
+  this.focus_subscription = function(id)
+    {
+    var row, folder;
+    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
+
+    if (this.drag_active && this.env.folder && (row = document.getElementById(id)))
+      if (this.env.subscriptionrows[id] &&
+          (folder = this.env.subscriptionrows[id][0]))
+        {
+        if (this.check_droptarget(folder) &&
+           !this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2] &&    
+           (folder != this.env.folder.replace(reg, '')) &&
+            (!folder.match(new RegExp('^'+RegExp.escape(this.env.folder+this.env.delimiter)))))
+          {
+          this.set_env('dstfolder', folder);
+          this.set_classname(row, 'droptarget', true);
+          }
+        }
+      else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter))))
+        {
+        this.set_env('dstfolder', this.env.delimiter);
+        this.set_classname(this.subscription_list.frame, 'droptarget', true);
+        }
+    }
+
+  this.unfocus_subscription = function(id)
+    {
+      var row;
+      this.set_env('dstfolder', null);
+      if (this.env.subscriptionrows[id] &&
+          (row = document.getElementById(id)))
+        this.set_classname(row, 'droptarget', false);
+      else
+        this.set_classname(this.subscription_list.frame, 'droptarget', false);
+    }
+
+  this.subscription_select = function(list)
+    {
+    var id, folder;
+    if ((id = list.get_single_selection()) &&
+        this.env.subscriptionrows['rcmrow'+id] &&
+        (folder = this.env.subscriptionrows['rcmrow'+id][0]))
+      this.set_env('folder', folder);
+    else
+      this.set_env('folder', null);
+      
+    if (this.gui_objects.createfolderhint)
+      this.gui_objects.createfolderhint.innerHTML = this.env.folder ? this.get_label('addsubfolderhint') : '';
+    };
+
+  this.subscription_move_folder = function(list)
+    {
+    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
+    if (this.env.folder && this.env.dstfolder && (this.env.dstfolder != this.env.folder) &&
+        (this.env.dstfolder != this.env.folder.replace(reg, '')))
+      {
+      var reg = new RegExp('[^'+RegExp.escape(this.env.delimiter)+']*['+RegExp.escape(this.env.delimiter)+']', 'g');
+      var basename = this.env.folder.replace(reg, '');
+      var newname = this.env.dstfolder==this.env.delimiter ? basename : this.env.dstfolder+this.env.delimiter+basename;
+
+      this.set_busy(true, 'foldermoving');
+      this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.folder)+'&_folder_newname='+urlencode(newname), true);
+      }
+    this.drag_active = false;
+    this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
+    };
+
+  // tell server to create and subscribe a new mailbox
+  this.create_folder = function(name)
+    {
+    if (this.edit_folder)
+      this.reset_folder_rename();
+
+    var form;
+    if ((form = this.gui_objects.editform) && form.elements['_folder_name'])
+      {
+      name = form.elements['_folder_name'].value;
+
+      if (name.indexOf(this.env.delimiter)>=0)
+        {
+        alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
+        return false;
+        }
+
+      if (this.env.folder && name != '')
+        name = this.env.folder+this.env.delimiter+name;
+
+      this.set_busy(true, 'foldercreating');
+      this.http_post('create-folder', '_name='+urlencode(name), true);
+      }
+    else if (form.elements['_folder_name'])
+      form.elements['_folder_name'].focus();
+    };
+
+  // start renaming the mailbox name.
+  // this will replace the name string with an input field
+  this.rename_folder = function(id)
+    {
+    var temp, row, form;
+
+    // reset current renaming
+    if (temp = this.edit_folder)
+      {
+      this.reset_folder_rename();
+      if (temp == id)
+        return;
+      }
+
+    if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id)))
+      {
+      var reg = new RegExp('.*['+RegExp.escape(this.env.delimiter)+']');
+      this.name_input = document.createElement('INPUT');
+      this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, '');
+      this.name_input.style.width = '100%';
+
+      reg = new RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
+      this.name_input.__parent = this.env.subscriptionrows[id][0].replace(reg, '');
+      this.name_input.onkeypress = function(e){ rcmail.name_input_keypress(e); };
+      
+      row.cells[0].replaceChild(this.name_input, row.cells[0].firstChild);
+      this.edit_folder = id;
+      this.name_input.select();
+      
+      if (form = this.gui_objects.editform)
+        form.onsubmit = function(){ return false; };
+      }
+    };
+
+  // remove the input field and write the current mailbox name to the table cell
+  this.reset_folder_rename = function()
+    {
+    var cell = this.name_input ? this.name_input.parentNode : null;
+
+    if (cell && this.edit_folder && this.env.subscriptionrows[this.edit_folder])
+      cell.innerHTML = this.env.subscriptionrows[this.edit_folder][1];
+      
+    this.edit_folder = null;
+    };
+
+  // handler for keyboard events on the input field
+  this.name_input_keypress = function(e)
+    {
+    var key = rcube_event.get_keycode(e);
+
+    // enter
+    if (key==13)
+      {
+      var newname = this.name_input ? this.name_input.value : null;
+      if (this.edit_folder && newname)
+        {
+        if (newname.indexOf(this.env.delimiter)>=0)
+          {
+          alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
+          return false;
+          }
+
+        if (this.name_input.__parent)
+          newname = this.name_input.__parent + this.env.delimiter + newname;
+
+        this.set_busy(true, 'folderrenaming');
+        this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname), true);
+        }
+      }
+    // escape
+    else if (key==27)
+      this.reset_folder_rename();
+    };
+
+  // delete a specific mailbox with all its messages
+  this.delete_folder = function(id)
+    {
+    var folder = this.env.subscriptionrows[id][0];
+
+    if (this.edit_folder)
+      this.reset_folder_rename();
+
+    if (folder && confirm(this.get_label('deletefolderconfirm')))
+      {
+      this.set_busy(true, 'folderdeleting');
+      this.http_post('delete-folder', '_mboxes='+urlencode(folder), true);
+      this.set_env('folder', null);
+
+      if (this.gui_objects.createfolderhint)
+        this.gui_objects.createfolderhint.innerHTML = '';
+      }
+    };
+
+  // add a new folder to the subscription list by cloning a folder row
+  this.add_folder_row = function(name, display_name, replace, before)
+    {
+    if (!this.gui_objects.subscriptionlist)
+      return false;
+
+    // find not protected folder    
+    for (var refid in this.env.subscriptionrows)
+      if (this.env.subscriptionrows[refid]!=null && !this.env.subscriptionrows[refid][2])
+        break;
+
+    var refrow, form;
+    var tbody = this.gui_objects.subscriptionlist.tBodies[0];
+    var id = 'rcmrow'+(tbody.childNodes.length+1);
+    var selection = this.subscription_list.get_single_selection();
+    
+    if (replace && replace.id)
+    {
+      id = replace.id;
+      refid = replace.id;
+    }
+
+    if (!id || !(refrow = document.getElementById(refid)))
+      {
+      // Refresh page if we don't have a table row to clone
+      this.goto_url('folders');
+      }
+    else
+      {
+      // clone a table row if there are existing rows
+      var row = this.clone_table_row(refrow);
+      row.id = id;
+
+      if (before && (before = this.get_folder_row_id(before)))
+        tbody.insertBefore(row, document.getElementById(before));
+      else
+        tbody.appendChild(row);
+      
+      if (replace)
+        tbody.removeChild(replace);
+      }
+
+    // add to folder/row-ID map
+    this.env.subscriptionrows[row.id] = [name, display_name, 0];
+
+    // set folder name
+    row.cells[0].innerHTML = display_name;
+    
+    // set messages count to zero
+    if (!replace)
+      row.cells[1].innerHTML = '*';
+    
+    if (!replace && row.cells[2] && row.cells[2].firstChild.tagName=='INPUT')
+      {
+      row.cells[2].firstChild.value = name;
+      row.cells[2].firstChild.checked = true;
+      }
+    
+    // add new folder to rename-folder list and clear input field
+    if (!replace && (form = this.gui_objects.editform))
+      {
+      if (form.elements['_folder_oldname'])
+        form.elements['_folder_oldname'].options[form.elements['_folder_oldname'].options.length] = new Option(name,name);
+      if (form.elements['_folder_name'])
+        form.elements['_folder_name'].value = ''; 
+      }
+
+    this.init_subscription_list();
+    if (selection && document.getElementById('rcmrow'+selection))
+      this.subscription_list.select_row(selection);
+
+    if (document.getElementById(id).scrollIntoView)
+      document.getElementById(id).scrollIntoView();
+    };
+
+  // replace an existing table row with a new folder line
+  this.replace_folder_row = function(oldfolder, newfolder, display_name, before)
+    {
+    var id = this.get_folder_row_id(oldfolder);
+    var row = document.getElementById(id);
+    
+    // replace an existing table row (if found)
+    this.add_folder_row(newfolder, display_name, row, before);
+    
+    // rename folder in rename-folder dropdown
+    var form, elm;
+    if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname']))
+      {
+      for (var i=0;i<elm.options.length;i++)
+        {
+        if (elm.options[i].value == oldfolder)
+          {
+          elm.options[i].text = display_name;
+          elm.options[i].value = newfolder;
+          break;
+          }
+        }
+
+      form.elements['_folder_newname'].value = '';
+      }
+    };
+
+  // remove the table row of a specific mailbox from the table
+  // (the row will not be removed, just hidden)
+  this.remove_folder_row = function(folder)
+    {
+    var row;
+    var id = this.get_folder_row_id(folder);
+    if (id && (row = document.getElementById(id)))
+      row.style.display = 'none';
+
+    // remove folder from rename-folder list
+    var form;
+    if ((form = this.gui_objects.editform) && form.elements['_folder_oldname'])
+      {
+      for (var i=0;i<form.elements['_folder_oldname'].options.length;i++)
+        {
+        if (form.elements['_folder_oldname'].options[i].value == folder) 
+          {
+          form.elements['_folder_oldname'].options[i] = null;
+          break;
+          }
+        }
+      }
+    
+    if (form && form.elements['_folder_newname'])
+      form.elements['_folder_newname'].value = '';
+    };
+
+  this.subscribe_folder = function(folder)
+    {
+    if (folder)
+      this.http_post('subscribe', '_mbox='+urlencode(folder));
+    };
+
+  this.unsubscribe_folder = function(folder)
+    {
+    if (folder)
+      this.http_post('unsubscribe', '_mbox='+urlencode(folder));
+    };
+    
+  // helper method to find a specific mailbox row ID
+  this.get_folder_row_id = function(folder)
+    {
+    for (var id in this.env.subscriptionrows)
+      if (this.env.subscriptionrows[id] && this.env.subscriptionrows[id][0] == folder)
+        break;
+        
+    return id;
+    };
+
+  // duplicate a specific table row
+  this.clone_table_row = function(row)
+    {
+    var cell, td;
+    var new_row = document.createElement('TR');
+    for(var n=0; n<row.cells.length; n++)
+      {
+      cell = row.cells[n];
+      td = document.createElement('TD');
+
+      if (cell.className)
+        td.className = cell.className;
+      if (cell.align)
+        td.setAttribute('align', cell.align);
+        
+      td.innerHTML = cell.innerHTML;
+      new_row.appendChild(td);
+      }
+    
+    return new_row;
+    };
+
+
+  /*********************************************************/
+  /*********           GUI functionality           *********/
+  /*********************************************************/
+
+  // eable/disable buttons for page shifting
+  this.set_page_buttons = function()
+    {
+    this.enable_command('nextpage', (this.env.pagecount > this.env.current_page));
+    this.enable_command('lastpage', (this.env.pagecount > this.env.current_page));
+    this.enable_command('previouspage', (this.env.current_page > 1));
+    this.enable_command('firstpage', (this.env.current_page > 1));
+    }
+
+  // set button to a specific state
+  this.set_button = function(command, state)
+    {
+    var a_buttons = this.buttons[command];
+    var button, obj;
+
+    if(!a_buttons || !a_buttons.length)
+      return false;
+
+    for(var n=0; n<a_buttons.length; n++)
+      {
+      button = a_buttons[n];
+      obj = document.getElementById(button.id);
+
+      // get default/passive setting of the button
+      if (obj && button.type=='image' && !button.status) {
+        button.pas = obj._original_src ? obj._original_src : obj.src;
+        // respect PNG fix on IE browsers
+        if (obj.runtimeStyle && obj.runtimeStyle.filter && obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))
+          button.pas = RegExp.$1;
+      }
+      else if (obj && !button.status)
+        button.pas = String(obj.className);
+
+      // set image according to button state
+      if (obj && button.type=='image' && button[state])
+        {
+        button.status = state;        
+        obj.src = button[state];
+        }
+      // set class name according to button state
+      else if (obj && typeof(button[state])!='undefined')
+        {
+        button.status = state;        
+        obj.className = button[state];        
+        }
+      // disable/enable input buttons
+      if (obj && button.type=='input')
+        {
+        button.status = state;
+        obj.disabled = !state;
+        }
+      }
+    };
+
+  // display a specific alttext
+  this.set_alttext = function(command, label)
+    {
+      if (!this.buttons[command] || !this.buttons[command].length)
+        return;
+      
+      var button, obj, link;
+      for (var n=0; n<this.buttons[command].length; n++)
+      {
+        button = this.buttons[command][n];
+        obj = document.getElementById(button.id);
+        
+        if (button.type=='image' && obj)
+        {
+          obj.setAttribute('alt', this.get_label(label));
+          if ((link = obj.parentNode) && link.tagName == 'A')
+            link.setAttribute('title', this.get_label(label));
+        }
+        else if (obj)
+          obj.setAttribute('title', this.get_label(label));
+      }
+    };
+
+  // mouse over button
+  this.button_over = function(command, id)
+    {
+    var a_buttons = this.buttons[command];
+    var button, img;
+
+    if(!a_buttons || !a_buttons.length)
+      return false;
+
+    for(var n=0; n<a_buttons.length; n++)
+      {
+      button = a_buttons[n];
+      if(button.id==id && button.status=='act')
+        {
+        img = document.getElementById(button.id);
+        if (img && button.over)
+          img.src = button.over;
+        }
+      }
+      
+    };
+
+  // mouse down on button
+  this.button_sel = function(command, id)
+    {
+    var a_buttons = this.buttons[command];
+    var button, img;
+
+    if(!a_buttons || !a_buttons.length)
+      return;
+
+    for(var n=0; n<a_buttons.length; n++)
+      {
+      button = a_buttons[n];
+      if(button.id==id && button.status=='act')
+        {
+        img = document.getElementById(button.id);
+        if (img && button.sel)
+          img.src = button.sel;
+        }
+      }
+    };
+
+  // mouse out of button
+  this.button_out = function(command, id)
+    {
+    var a_buttons = this.buttons[command];
+    var button, img;
+
+    if(!a_buttons || !a_buttons.length)
+      return;
+
+    for(var n=0; n<a_buttons.length; n++)
+      {
+      button = a_buttons[n];
+      if(button.id==id && button.status=='act')
+        {
+        img = document.getElementById(button.id);
+        if (img && button.act)
+          img.src = button.act;
+        }
+      }
+    };
+
+  // set/unset a specific class name
+  this.set_classname = function(obj, classname, set)
+    {
+    var reg = new RegExp('\s*'+classname, 'i');
+    if (!set && obj.className.match(reg))
+      obj.className = obj.className.replace(reg, '');
+    else if (set && !obj.className.match(reg))
+      obj.className += ' '+classname;
+    };
+
+  // write to the document/window title
+  this.set_pagetitle = function(title)
+  {
+    if (title && document.title)
+      document.title = title;
+  }
+
+  // display a system message
+  this.display_message = function(msg, type, hold)
+    {
+    if (!this.loaded)  // save message in order to display after page loaded
+      {
+      this.pending_message = new Array(msg, type);
+      return true;
+      }
+
+    // pass command to parent window
+    if (this.env.framed && parent.rcmail)
+      return parent.rcmail.display_message(msg, type, hold);
+
+    if (!this.gui_objects.message)
+      return false;
+
+    if (this.message_timer)
+      clearTimeout(this.message_timer);
+    
+    var cont = msg;
+    if (type)
+      cont = '<div class="'+type+'">'+cont+'</div>';
+
+    var _rcube = this;
+    this.gui_objects.message.innerHTML = cont;
+    this.gui_objects.message.style.display = 'block';
+    
+    if (type!='loading')
+      this.gui_objects.message.onmousedown = function(){ _rcube.hide_message(); return true; };
+    
+    if (!hold)
+      this.message_timer = window.setTimeout(function(){ ref.hide_message(); }, this.message_time);
+    };
+
+  // make a message row disapear
+  this.hide_message = function()
+    {
+    if (this.gui_objects.message)
+      {
+      this.gui_objects.message.style.display = 'none';
+      this.gui_objects.message.onmousedown = null;
+      }
+    };
+
+  // mark a mailbox as selected and set environment variable
+  this.select_folder = function(name, old)
+  {
+    if (this.gui_objects.folderlist)
+    {
+      var current_li, target_li;
+      
+      if ((current_li = this.get_folder_li(old)))
+      {
+        this.set_classname(current_li, 'selected', false);
+        this.set_classname(current_li, 'unfocused', false);
+      }
+
+      if ((target_li = this.get_folder_li(name)))
+      {
+        this.set_classname(target_li, 'unfocused', false);
+        this.set_classname(target_li, 'selected', true);
+      }
+    }
+  };
+
+  // helper method to find a folder list item
+  this.get_folder_li = function(name)
+  {
+    if (this.gui_objects.folderlist)
+    {
+      name = String(name).replace(this.identifier_expr, '');
+      return document.getElementById('rcmli'+name);
+    }
+
+    return null;
+  };
+
+  // for reordering column array, Konqueror workaround
+  this.set_message_coltypes = function(coltypes) 
+  { 
+    this.coltypes = coltypes;
+    
+    // set correct list titles
+    var cell, col;
+    var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null;
+    for (var n=0; thead && n<this.coltypes.length; n++) 
+      {
+      col = this.coltypes[n];
+      if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to'))
+        {
+        // if we have links for sorting, it's a bit more complicated...
+        if (cell.firstChild && cell.firstChild.tagName=='A')
+          {
+          cell.firstChild.innerHTML = this.get_label(this.coltypes[n]);
+          cell.firstChild.onclick = function(){ return rcmail.command('sort', this.__col, this); };
+          cell.firstChild.__col = col;
+          }
+        else
+          cell.innerHTML = this.get_label(this.coltypes[n]);
+
+        cell.id = 'rcm'+col;
+        }
+      else if (col == 'subject' && this.message_list)
+        this.message_list.subject_col = n+1;
+      }
+  };
+
+  // create a table row in the message list
+  this.add_message_row = function(uid, cols, flags, attachment, attop)
+    {
+    if (!this.gui_objects.messagelist || !this.message_list)
+      return false;
+
+    var tbody = this.gui_objects.messagelist.tBodies[0];
+    var rowcount = tbody.rows.length;
+    var even = rowcount%2;
+    
+    this.env.messages[uid] = {deleted:flags.deleted?1:0,
+                              replied:flags.replied?1:0,
+                              unread:flags.unread?1:0,
+                             forwarded:flags.forwarded?1:0,
+                              flagged:flags.flagged?1:0};
+    
+    var row = document.createElement('TR');
+    row.id = 'rcmrow'+uid;
+    row.className = 'message'
+       + (even ? ' even' : ' odd')
+        + (flags.unread ? ' unread' : '')
+       + (flags.deleted ? ' deleted' : '')
+       + (flags.flagged ? ' flagged' : '');                
+
+    if (this.message_list.in_selection(uid))
+      row.className += ' selected';
+
+    var icon = this.env.messageicon;
+    if (flags.deleted && this.env.deletedicon)
+      icon = this.env.deletedicon;
+    else if (flags.replied && this.env.repliedicon)
+      {
+      if (flags.forwarded && this.env.forwardedrepliedicon)
+        icon = this.env.forwardedrepliedicon;
+      else
+        icon = this.env.repliedicon;
+      }
+    else if (flags.forwarded && this.env.forwardedicon)
+      icon = this.env.forwardedicon;
+    else if(flags.unread && this.env.unreadicon)
+      icon = this.env.unreadicon;
+    
+    var col = document.createElement('TD');
+    col.className = 'icon';
+    col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : '';
+    row.appendChild(col);
+
+    // add each submitted col
+    for (var n = 0; n < this.coltypes.length; n++) 
+      { 
+      var c = this.coltypes[n];
+      col = document.createElement('TD');
+      col.className = String(c).toLowerCase();
+      
+      if (c=='flag')
+        {
+        if (flags.flagged && this.env.flaggedicon)
+          col.innerHTML = '<img src="'+this.env.flaggedicon+'" alt="" />';
+        else if(!flags.flagged && this.env.unflaggedicon)
+          col.innerHTML = '<img src="'+this.env.unflaggedicon+'" alt="" />';
+      }
+      else if (c=='attachment')
+        col.innerHTML = attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" />' : '&nbsp;';
+      else
+        col.innerHTML = cols[c];
+
+      row.appendChild(col);
+      }
+
+    this.message_list.insert_row(row, attop);
+
+    // remove 'old' row
+    if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize)
+      {
+       var uid = this.message_list.get_last_row();
+        this.message_list.remove_row(uid);
+       this.message_list.clear_selection(uid);
+      }
+    };
+
+  // replace content of row count display
+  this.set_rowcount = function(text)
+    {
+    if (this.gui_objects.countdisplay)
+      this.gui_objects.countdisplay.innerHTML = text;
+
+    // update page navigation buttons
+    this.set_page_buttons();
+    };
+
+  // replace content of mailboxname display
+  this.set_mailboxname = function(content)
+    {
+    if (this.gui_objects.mailboxname && content)
+      this.gui_objects.mailboxname.innerHTML = content;
+    };
+
+  // replace content of quota display
+  this.set_quota = function(content)
+    {
+    if (this.gui_objects.quotadisplay && content)
+      this.gui_objects.quotadisplay.innerHTML = content;
+    };
+
+  // update the mailboxlist
+  this.set_unread_count = function(mbox, count, set_title)
+    {
+    if (!this.gui_objects.mailboxlist)
+      return false;
+
+    this.env.unread_counts[mbox] = count;
+    this.set_unread_count_display(mbox, set_title);
+    }
+
+  // update the mailbox count display
+  this.set_unread_count_display = function(mbox, set_title)
+    {
+    var reg, text_obj, item, mycount, childcount, div;
+    if (item = this.get_folder_li(mbox))
+      {
+      mycount = this.env.unread_counts[mbox] ? this.env.unread_counts[mbox] : 0;
+      text_obj = item.getElementsByTagName('a')[0];
+      reg = /\s+\([0-9]+\)$/i;
+
+      childcount = 0;
+      if ((div = item.getElementsByTagName('div')[0]) &&
+          div.className.match(/collapsed/))
+        {
+        // add children's counters
+        for (var k in this.env.unread_counts) 
+          if (k.indexOf(mbox + this.env.delimiter) == 0) {
+            childcount += this.env.unread_counts[k];
+         }
+        }
+
+      if (mycount && text_obj.innerHTML.match(reg))
+        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+mycount+')');
+      else if (mycount)
+        text_obj.innerHTML += ' ('+mycount+')';
+      else
+        text_obj.innerHTML = text_obj.innerHTML.replace(reg, '');
+
+      // set parent's display
+      reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+$');
+      if (mbox.match(reg))
+        this.set_unread_count_display(mbox.replace(reg, ''), false);
+
+      // set the right classes
+      this.set_classname(item, 'unread', (mycount+childcount)>0 ? true : false);
+      }
+
+    // set unread count to window title
+    reg = /^\([0-9]+\)\s+/i;
+    if (set_title && document.title)
+      {
+      var doc_title = String(document.title);
+      var new_title = "";
+
+      if (mycount && doc_title.match(reg))
+        new_title = doc_title.replace(reg, '('+mycount+') ');
+      else if (mycount)
+        new_title = '('+mycount+') '+doc_title;
+      else
+        new_title = doc_title.replace(reg, '');
+        
+      this.set_pagetitle(new_title);
+      }
+    };
+
+  // notifies that a new message(s) has hit the mailbox
+  this.new_message_focus = function()
+    {
+    // focus main window
+    if (this.env.framed && window.parent)
+      window.parent.focus();
+    else
+      window.focus();
+    }
+
+  // add row to contacts list
+  this.add_contact_row = function(cid, cols, select)
+    {
+    if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0])
+      return false;
+    
+    var tbody = this.gui_objects.contactslist.tBodies[0];
+    var rowcount = tbody.rows.length;
+    var even = rowcount%2;
+    
+    var row = document.createElement('TR');
+    row.id = 'rcmrow'+cid;
+    row.className = 'contact '+(even ? 'even' : 'odd');
+    
+    if (this.contact_list.in_selection(cid))
+      row.className += ' selected';
+
+    // add each submitted col
+    for (var c in cols)
+      {
+      col = document.createElement('TD');
+      col.className = String(c).toLowerCase();
+      col.innerHTML = cols[c];
+      row.appendChild(col);
+      }
+    
+    this.contact_list.insert_row(row);
+    this.enable_command('export', (this.contact_list.rowcount > 0));
+    };
+
+  this.toggle_prefer_html = function(checkbox)
+    {
+    var addrbook_show_images;
+    if (addrbook_show_images = document.getElementById('rcmfd_addrbook_show_images'))
+      addrbook_show_images.disabled = !checkbox.checked;
+    }
+
+  // display fetched raw headers
+  this.set_headers = function(content)
+    {
+    if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content)
+      {
+      var box = this.gui_objects.all_headers_box;
+      box.innerHTML = content;
+      box.style.display = 'block';
+
+      if (this.env.framed && parent.rcmail)
+       parent.rcmail.set_busy(false);
+      else
+        this.set_busy(false);
+      }
+    };
+
+  // display all-headers row and fetch raw message headers
+  this.load_headers = function(elem)
+    {
+    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid)
+      return;
+    
+    this.set_classname(elem, 'show-headers', false);
+    this.set_classname(elem, 'hide-headers', true);
+    this.gui_objects.all_headers_row.style.display = bw.ie ? 'block' : 'table-row';
+    elem.onclick = function() { rcmail.hide_headers(elem); }
+
+    // fetch headers only once
+    if (!this.gui_objects.all_headers_box.innerHTML)
+      {
+      this.display_message(this.get_label('loading'), 'loading', true); 
+      this.http_post('headers', '_uid='+this.env.uid);
+      }
+    }
+
+  // hide all-headers row
+  this.hide_headers = function(elem)
+    {
+    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box)
+      return;
+
+    this.set_classname(elem, 'hide-headers', false);
+    this.set_classname(elem, 'show-headers', true);
+    this.gui_objects.all_headers_row.style.display = 'none';
+    elem.onclick = function() { rcmail.load_headers(elem); }
+    }
+
+
+  /********************************************************/
+  /*********  html to text conversion functions   *********/
+  /********************************************************/
+
+  this.html2plain = function(htmlText, id)
+    {
+    var http_request = new rcube_http_request();
+    var url = this.env.bin_path+'html2text.php';
+    var rcmail = this;
+
+    this.set_busy(true, 'converting');
+    console.log('HTTP POST: '+url);
+
+    http_request.onerror = function(o) { rcmail.http_error(o); };
+    http_request.oncomplete = function(o) { rcmail.set_text_value(o, id); };
+    http_request.POST(url, htmlText, 'application/octet-stream');
+    }
+
+  this.set_text_value = function(httpRequest, id)
+    {
+    this.set_busy(false);
+    document.getElementById(id).value = httpRequest.get_text();
+    console.log(httpRequest.get_text());
+    }
+
+
+  /********************************************************/
+  /*********        remote request methods        *********/
+  /********************************************************/
+
+  this.redirect = function(url, lock)
+    {
+    if (lock || lock === null)
+      this.set_busy(true);
+
+    if (this.env.framed && window.parent)
+      parent.location.href = url;
+    else  
+      location.href = url;
+    };
+
+  this.goto_url = function(action, query, lock)
+    {
+    var querystring = query ? '&'+query : '';
+    this.redirect(this.env.comm_path+'&_action='+action+querystring, lock);
+    };
+
+  this.http_sockets = new Array();
+  
+  // find a non-busy socket or create a new one
+  this.get_request_obj = function()
+    {
+    for (var n=0; n<this.http_sockets.length; n++)
+      {
+      if (!this.http_sockets[n].busy)
+        return this.http_sockets[n];
+      }
+    
+    // create a new XMLHTTP object
+    var i = this.http_sockets.length;
+    this.http_sockets[i] = new rcube_http_request();
+
+    return this.http_sockets[i];
+    };
+  
+  // send a http request to the server
+  this.http_request = function(action, querystring, lock)
+    {
+    var request_obj = this.get_request_obj();
+    querystring += (querystring ? '&' : '') + '_remote=1';
+    
+    // add timestamp to request url to avoid cacheing problems in Safari
+    if (bw.safari)
+      querystring += '&_ts='+(new Date().getTime());
+
+    // send request
+    if (request_obj)
+      {
+      console.log('HTTP request: '+this.env.comm_path+'&_action='+action+'&'+querystring);
+
+      if (lock)
+        this.set_busy(true);
+
+      var rcm = this;
+      request_obj.__lock = lock ? true : false;
+      request_obj.__action = action;
+      request_obj.onerror = function(o){ ref.http_error(o); };
+      request_obj.oncomplete = function(o){ ref.http_response(o); };
+      request_obj.GET(this.env.comm_path+'&_action='+action+'&'+querystring);
+      }
+    };
+
+    // send a http POST request to the server
+    this.http_post = function(action, postdata, lock)
+      {
+      var request_obj;
+      if (postdata && typeof(postdata) == 'object')
+        postdata._remote = 1;
+      else
+        postdata += (postdata ? '&' : '') + '_remote=1';
+
+      // send request
+      if (request_obj = this.get_request_obj())
+        {
+        console.log('HTTP POST: '+this.env.comm_path+'&_action='+action);
+
+        if (lock)
+          this.set_busy(true);
+
+        var rcm = this;
+        request_obj.__lock = lock ? true : false;
+        request_obj.__action = action;
+        request_obj.onerror = function(o){ rcm.http_error(o); };
+        request_obj.oncomplete = function(o){ rcm.http_response(o); };
+        request_obj.POST(this.env.comm_path+'&_action='+action, postdata);
+        }
+      };
+
+  // handle HTTP response
+  this.http_response = function(request_obj)
+    {
+    var ctype = request_obj.get_header('Content-Type');
+    if (ctype)
+      {
+      ctype = String(ctype).toLowerCase();
+      var ctype_array=ctype.split(";");
+      ctype = ctype_array[0];
+      }
+
+    if (request_obj.__lock)
+      this.set_busy(false);
+
+    console.log(request_obj.get_text());
+
+    // if we get javascript code from server -> execute it
+    if (request_obj.get_text() && (ctype=='text/javascript' || ctype=='application/x-javascript'))
+      eval(request_obj.get_text());
+
+    // process the response data according to the sent action
+    switch (request_obj.__action) {
+      case 'delete':
+        if (this.task == 'addressbook') {
+          var uid = this.contact_list.get_selection();
+          this.enable_command('compose', (uid && this.contact_list.rows[uid]));
+          this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && this.env.address_sources && !this.env.address_sources[this.env.source].readonly));
+          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
+        }
+      
+      case 'moveto':
+        if (this.env.action == 'show')
+          this.command('list');
+        else if (this.message_list)
+          this.message_list.init();
+        break;
+        
+      case 'purge':
+      case 'expunge':      
+        if (!this.env.messagecount && this.task == 'mail') {
+          // clear preview pane content
+          if (this.env.contentframe)
+            this.show_contentframe(false);
+          // disable commands useless when mailbox is empty
+          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource',
+            'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false);
+        }
+        break;
+
+      case 'check-recent':
+      case 'getunread':
+      case 'list':
+        if (this.task == 'mail') {
+          if (this.message_list && request_obj.__action == 'list')
+            this.msglist_select(this.message_list);
+          this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0));
+          this.enable_command('purge', this.purge_mailbox_test());
+        }
+        else if (this.task == 'addressbook')
+          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
+
+        break;
+      }
+
+    request_obj.reset();
+    };
+
+  // handle HTTP request errors
+  this.http_error = function(request_obj)
+    {
+    //alert('Error sending request: '+request_obj.url+' => HTTP '+request_obj.xmlhttp.status);
+    if (request_obj.__lock)
+      this.set_busy(false);
+
+    request_obj.reset();
+    request_obj.__lock = false;
+    this.display_message('Unknown Server Error!', 'error');
+    };
+
+  // use an image to send a keep-alive siganl to the server
+  this.send_keep_alive = function()
+    {
+    var d = new Date();
+    this.http_request('keep-alive', '_t='+d.getTime());
+    };
+
+  // send periodic request to check for recent messages
+  this.check_for_recent = function(setbusy)
+    {
+    if (this.busy)
+      return;
+
+    if (setbusy)
+      this.set_busy(true, 'checkingmail');
+
+    var addurl = '_t=' + (new Date().getTime());
+
+    if (this.gui_objects.messagelist)
+      addurl += '&_list=1';
+    if (this.gui_objects.quotadisplay)
+      addurl += '&_quota=1';
+    if (this.env.search_request)
+      addurl += '&_search=' + this.env.search_request;
+
+    this.http_request('check-recent', addurl, true);
+    };
+
+
+  /********************************************************/
+  /*********            helper methods            *********/
+  /********************************************************/
+  
+  // check if we're in show mode or if we have a unique selection
+  // and return the message uid
+  this.get_single_uid = function()
+    {
+    return this.env.uid ? this.env.uid : (this.message_list ? this.message_list.get_single_selection() : null);
+    };
+
+  // same as above but for contacts
+  this.get_single_cid = function()
+    {
+    return this.env.cid ? this.env.cid : (this.contact_list ? this.contact_list.get_single_selection() : null);
+    };
+
+
+  this.get_caret_pos = function(obj)
+    {
+    if (typeof(obj.selectionEnd)!='undefined')
+      return obj.selectionEnd;
+    else if (document.selection && document.selection.createRange)
+      {
+      var range = document.selection.createRange();
+      if (range.parentElement()!=obj)
+        return 0;
+
+      var gm = range.duplicate();
+      if (obj.tagName=='TEXTAREA')
+        gm.moveToElementText(obj);
+      else
+        gm.expand('textedit');
+      
+      gm.setEndPoint('EndToStart', range);
+      var p = gm.text.length;
+
+      return p<=obj.value.length ? p : -1;
+      }
+    else
+      return obj.value.length;
+    };
+
+  this.set_caret2start = function(obj)
+    {
+    if (obj.createTextRange)
+      {
+      var range = obj.createTextRange();
+      range.collapse(true);
+      range.select();
+      }
+    else if (obj.setSelectionRange)
+      obj.setSelectionRange(0,0);
+
+    obj.focus();
+    };
+
+  // set all fields of a form disabled
+  this.lock_form = function(form, lock)
+    {
+    if (!form || !form.elements)
+      return;
+    
+    var type;
+    for (var n=0; n<form.elements.length; n++)
+      {
+      type = form.elements[n];
+      if (type=='hidden')
+        continue;
+        
+      form.elements[n].disabled = lock;
+      }
+    };
+    
+  }  // end object rcube_webmail
+
+
+/**
+ * Class for sending HTTP requests
+ * @constructor
+ */
+function rcube_http_request()
+  {
+  this.url = '';
+  this.busy = false;
+  this.xmlhttp = null;
+
+  // reset object properties
+  this.reset = function()
+    {
+    // set unassigned event handlers
+    this.onloading = function(){ };
+    this.onloaded = function(){ };
+    this.oninteractive = function(){ };
+    this.oncomplete = function(){ };
+    this.onabort = function(){ };
+    this.onerror = function(){ };
+    
+    this.url = '';
+    this.busy = false;
+    this.xmlhttp = null;
+    }
+
+  // create HTMLHTTP object
+  this.build = function()
+    {
+    if (window.XMLHttpRequest)
+      this.xmlhttp = new XMLHttpRequest();
+    else if (window.ActiveXObject)
+      {
+      try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
+      catch(e) { this.xmlhttp = null; }
+      }
+    else
+      {
+      
+      }
+    }
+
+  // send GET request
+  this.GET = function(url)
+    {
+    this.build();
+
+    if (!this.xmlhttp)
+      {
+      this.onerror(this);
+      return false;
+      }
+
+    var _ref = this;
+    this.url = url;
+    this.busy = true;
+
+    this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); };
+    this.xmlhttp.open('GET', url, true);
+    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
+    this.xmlhttp.send(null);
+    };
+
+  this.POST = function(url, body, contentType)
+    {
+    // default value for contentType if not provided
+    if (typeof(contentType) == 'undefined')
+      contentType = 'application/x-www-form-urlencoded';
+
+    this.build();
+    
+    if (!this.xmlhttp)
+    {
+       this.onerror(this);
+       return false;
+    }
+    
+    var req_body = body;
+    if (typeof(body) == 'object')
+    {
+      req_body = '';
+      for (var p in body)
+        req_body += (req_body ? '&' : '') + p+'='+urlencode(body[p]);
+    }
+
+    var ref = this;
+    this.url = url;
+    this.busy = true;
+    
+    this.xmlhttp.onreadystatechange = function() { ref.xmlhttp_onreadystatechange(); };
+    this.xmlhttp.open('POST', url, true);
+    this.xmlhttp.setRequestHeader('Content-Type', contentType);
+    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
+    this.xmlhttp.send(req_body);
+    };
+
+  // handle onreadystatechange event
+  this.xmlhttp_onreadystatechange = function()
+    {
+    if(this.xmlhttp.readyState == 1)
+      this.onloading(this);
+
+    else if(this.xmlhttp.readyState == 2)
+      this.onloaded(this);
+
+    else if(this.xmlhttp.readyState == 3)
+      this.oninteractive(this);
+
+    else if(this.xmlhttp.readyState == 4)
+      {
+      try {
+        if (this.xmlhttp.status == 0)
+          this.onabort(this);
+        else if(this.xmlhttp.status == 200)
+          this.oncomplete(this);
+        else
+          this.onerror(this);
+
+        this.busy = false;
+        }
+      catch(err)
+        {
+        this.onerror(this);
+        this.busy = false;
+        }
+      }
+    }
+
+  // getter method for HTTP headers
+  this.get_header = function(name)
+    {
+    return this.xmlhttp.getResponseHeader(name);
+    };
+
+  this.get_text = function()
+    {
+    return this.xmlhttp.responseText;
+    };
+
+  this.get_xml = function()
+    {
+    return this.xmlhttp.responseXML;
+    };
+
+  this.reset();
+  
+  }  // end class rcube_http_request
+
+// helper function to call the init method with a delay
+function call_init(o)
+  {
+    window.setTimeout('if (window[\''+o+'\'] && window[\''+o+'\'].init) { '+o+'.init(); }',
+        bw.win ? 500 : 200);
+  }
+
index 7610e5786e6c0a425a943c62f0b7a99414f7116c..f6ab5692987937270897b02636d65e9b43cda8f3 100644 (file)
-/*
- +-----------------------------------------------------------------------+
- | RoundCube common js library                                           |
- |                                                                       |
- | This file is part of the RoundCube web development suite              |
- | Copyright (C) 2005-2007, RoundCube Dev, - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com>                        |
- +-----------------------------------------------------------------------+
- $Id: common.js 2150 2008-12-14 19:00:09Z alec $
-*/
-
-// Constants
-var CONTROL_KEY = 1;
-var SHIFT_KEY = 2;
-var CONTROL_SHIFT_KEY = 3;
-
-
-/**
- * Default browser check class
- * @construcotr
- */
-function roundcube_browser()
-  {
-  this.ver = parseFloat(navigator.appVersion);
-  this.appver = navigator.appVersion;
-  this.agent = navigator.userAgent;
-  this.name = navigator.appName;
-  this.vendor = navigator.vendor ? navigator.vendor : '';
-  this.vendver = navigator.vendorSub ? parseFloat(navigator.vendorSub) : 0;
-  this.product = navigator.product ? navigator.product : '';
-  this.platform = String(navigator.platform).toLowerCase();
-  this.lang = (navigator.language) ? navigator.language.substring(0,2) :
-              (navigator.browserLanguage) ? navigator.browserLanguage.substring(0,2) :
-              (navigator.systemLanguage) ? navigator.systemLanguage.substring(0,2) : 'en';
-
-  this.win = (this.platform.indexOf('win')>=0) ? true : false;
-  this.mac = (this.platform.indexOf('mac')>=0) ? true : false;
-  this.linux = (this.platform.indexOf('linux')>=0) ? true : false;
-  this.unix = (this.platform.indexOf('unix')>=0) ? true : false;
-
-  this.dom = document.getElementById ? true : false;
-  this.dom2 = (document.addEventListener && document.removeEventListener);
-
-  this.ie = (document.all) ? true : false;
-  this.ie4 = (this.ie && !this.dom);
-  this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0);
-  this.ie6 = (this.dom && this.appver.indexOf('MSIE 6')>0);
-  this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0);
-
-  this.mz = (this.dom && this.ver>=5);  // (this.dom && this.product=='Gecko')
-  this.ns = ((this.ver<5 && this.name=='Netscape') || (this.ver>=5 && this.vendor.indexOf('Netscape')>=0));
-  this.ns6 = (this.ns && parseInt(this.vendver)==6);  // (this.mz && this.ns) ? true : false;
-  this.ns7 = (this.ns && parseInt(this.vendver)==7);  // this.agent.indexOf('Netscape/7')>0);
-  this.safari = (this.agent.toLowerCase().indexOf('safari')>0 || this.agent.toLowerCase().indexOf('applewebkit')>0);
-  this.konq   = (this.agent.toLowerCase().indexOf('konqueror')>0);
-
-  this.opera = (window.opera) ? true : false;
-
-  if(this.opera && window.RegExp)
-    this.vendver = (/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent)) ? parseFloat(RegExp.$2) : -1;
-  else if(!this.vendver && this.safari)
-    this.vendver = (/(safari|applewebkit)\/([0-9]+)/i.test(this.agent)) ? parseInt(RegExp.$2) : 0;
-  else if((!this.vendver && this.mz) || this.agent.indexOf('Camino')>0)
-    this.vendver = (/rv:([0-9\.]+)/.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
-  else if(this.ie && window.RegExp)
-    this.vendver = (/msie\s+([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
-  else if(this.konq && window.RegExp)
-    this.vendver = (/khtml\/([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
-
-
-  // get real language out of safari's user agent
-  if(this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent)))
-    this.lang = RegExp.$1;
-
-  this.dhtml = ((this.ie4 && this.win) || this.ie5 || this.ie6 || this.ns4 || this.mz);
-  this.vml = (this.win && this.ie && this.dom && !this.opera);
-  this.pngalpha = (this.mz || (this.opera && this.vendver>=6) || (this.ie && this.mac && this.vendver>=5) ||
-                   (this.ie && this.win && this.vendver>=5.5) || this.safari);
-  this.opacity = (this.mz || (this.ie && this.vendver>=5.5 && !this.opera) || (this.safari && this.vendver>=100));
-  this.cookies = navigator.cookieEnabled;
-  
-  // test for XMLHTTP support
-  this.xmlhttp_test = function()
-    {
-    var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
-    this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())) ? true : false;
-    return this.xmlhttp;
-    }
-  }
-
-
-// static functions for event handling
-var rcube_event = {
-
-/**
- * returns the event target element
- */
-get_target: function(e)
-{
-  e = e || window.event;
-  return e && e.target ? e.target : e.srcElement;
-},
-
-/**
- * returns the event key code
- */
-get_keycode: function(e)
-{
-  e = e || window.event;
-  return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns the event key code
- */
-get_button: function(e)
-{
-  e = e || window.event;
-  return e && (typeof e.button != 'undefined') ? e.button : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns modifier key (constants defined at top of file)
- */
-get_modifier: function(e)
-{
-  var opcode = 0;
-  e = e || window.event;
-
-  if (bw.mac && e)
-    {
-    opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
-    return opcode;    
-    }
-  if (e)
-    {
-    opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
-    return opcode;
-    }
-},
-
-/**
- * Return absolute mouse position of an event
- */
-get_mouse_pos: function(e)
-{
-  if (!e) e = window.event;
-  var mX = (e.pageX) ? e.pageX : e.clientX;
-  var mY = (e.pageY) ? e.pageY : e.clientY;
-
-  if (document.body && document.all)
-  {
-    mX += document.body.scrollLeft;
-    mY += document.body.scrollTop;
-  }
-
-  if (e._offset) {
-    mX += e._offset.x;
-    mY += e._offset.y;
-  }
-
-  return { x:mX, y:mY };
-},
-
-/**
- * Add an object method as event listener to a certain element
- */
-add_listener: function(p)
-{
-  if (!p.object || !p.method)  // not enough arguments
-    return;
-  if (!p.element)
-    p.element = document;
-
-  if (!p.object._rc_events)
-    p.object._rc_events = [];
-  
-  var key = p.event + '*' + p.method;
-  if (!p.object._rc_events[key])
-    p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
-
-  if (p.element.addEventListener)
-    p.element.addEventListener(p.event, p.object._rc_events[key], false);
-  else if (p.element.attachEvent)
-    {
-    // IE allows multiple events with the same function to be applied to the same object
-    // forcibly detach the event, then attach
-    p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
-    p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
-    }
-  else
-    p.element['on'+p.event] = p.object._rc_events[key];
-},
-
-/**
- * Remove event listener
- */
-remove_listener: function(p)
-{
-  if (!p.element)
-    p.element = document;
-
-  var key = p.event + '*' + p.method;
-  if (p.object && p.object._rc_events && p.object._rc_events[key]) {
-    if (p.element.removeEventListener)
-      p.element.removeEventListener(p.event, p.object._rc_events[key], false);
-    else if (p.element.detachEvent)
-      p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
-    else
-      p.element['on'+p.event] = null;
-  }
-},
-
-/**
- * Prevent event propagation and bubbeling
- */
-cancel: function(evt)
-{
-  var e = evt ? evt : window.event;
-  if (e.preventDefault)
-    e.preventDefault();
-  if (e.stopPropagation)
-    e.stopPropagation();
-
-  e.cancelBubble = true;
-  e.returnValue = false;
-  return false;
+var CONTROL_KEY=1;
+var SHIFT_KEY=2;
+var CONTROL_SHIFT_KEY=3;
+function roundcube_browser(){
+this.ver=parseFloat(navigator.appVersion);
+this.appver=navigator.appVersion;
+this.agent=navigator.userAgent;
+this.name=navigator.appName;
+this.vendor=navigator.vendor?navigator.vendor:"";
+this.vendver=navigator.vendorSub?parseFloat(navigator.vendorSub):0;
+this.product=navigator.product?navigator.product:"";
+this.platform=String(navigator.platform).toLowerCase();
+this.lang=(navigator.language)?navigator.language.substring(0,2):(navigator.browserLanguage)?navigator.browserLanguage.substring(0,2):(navigator.systemLanguage)?navigator.systemLanguage.substring(0,2):"en";
+this.win=(this.platform.indexOf("win")>=0)?true:false;
+this.mac=(this.platform.indexOf("mac")>=0)?true:false;
+this.linux=(this.platform.indexOf("linux")>=0)?true:false;
+this.unix=(this.platform.indexOf("unix")>=0)?true:false;
+this.dom=document.getElementById?true:false;
+this.dom2=(document.addEventListener&&document.removeEventListener);
+this.ie=(document.all)?true:false;
+this.ie4=(this.ie&&!this.dom);
+this.ie5=(this.dom&&this.appver.indexOf("MSIE 5")>0);
+this.ie6=(this.dom&&this.appver.indexOf("MSIE 6")>0);
+this.ie7=(this.dom&&this.appver.indexOf("MSIE 7")>0);
+this.mz=(this.dom&&this.ver>=5);
+this.ns=((this.ver<5&&this.name=="Netscape")||(this.ver>=5&&this.vendor.indexOf("Netscape")>=0));
+this.ns6=(this.ns&&parseInt(this.vendver)==6);
+this.ns7=(this.ns&&parseInt(this.vendver)==7);
+this.safari=(this.agent.toLowerCase().indexOf("safari")>0||this.agent.toLowerCase().indexOf("applewebkit")>0);
+this.konq=(this.agent.toLowerCase().indexOf("konqueror")>0);
+this.opera=(window.opera)?true:false;
+if(this.opera&&window.RegExp){
+this.vendver=(/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent))?parseFloat(RegExp.$2):-1;
+}else{
+if(!this.vendver&&this.safari){
+this.vendver=(/(safari|applewebkit)\/([0-9]+)/i.test(this.agent))?parseInt(RegExp.$2):0;
+}else{
+if((!this.vendver&&this.mz)||this.agent.indexOf("Camino")>0){
+this.vendver=(/rv:([0-9\.]+)/.test(this.agent))?parseFloat(RegExp.$1):0;
+}else{
+if(this.ie&&window.RegExp){
+this.vendver=(/msie\s+([0-9\.]+)/i.test(this.agent))?parseFloat(RegExp.$1):0;
+}else{
+if(this.konq&&window.RegExp){
+this.vendver=(/khtml\/([0-9\.]+)/i.test(this.agent))?parseFloat(RegExp.$1):0;
 }
-
+}
+}
+}
+}
+if(this.safari&&(/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent))){
+this.lang=RegExp.$1;
+}
+this.dhtml=((this.ie4&&this.win)||this.ie5||this.ie6||this.ns4||this.mz);
+this.vml=(this.win&&this.ie&&this.dom&&!this.opera);
+this.pngalpha=(this.mz||(this.opera&&this.vendver>=6)||(this.ie&&this.mac&&this.vendver>=5)||(this.ie&&this.win&&this.vendver>=5.5)||this.safari);
+this.opacity=(this.mz||(this.ie&&this.vendver>=5.5&&!this.opera)||(this.safari&&this.vendver>=100));
+this.cookies=navigator.cookieEnabled;
+this.xmlhttp_test=function(){
+var _1=new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
+this.xmlhttp=(window.XMLHttpRequest||(window.ActiveXObject&&_1()))?true:false;
+return this.xmlhttp;
 };
-
-
-var rcube_layer_objects = new Array();
-
-
-/**
- * RoundCube generic layer (floating box) class
- *
- * @constructor
- */
-function rcube_layer(id, attributes)
-  {
-  this.name = id;
-  
-  // create a new layer in the current document
-  this.create = function(arg)
-    {
-    var l = (arg.x) ? arg.x : 0;
-    var t = (arg.y) ? arg.y : 0;
-    var w = arg.width;
-    var h = arg.height;
-    var z = arg.zindex;
-    var vis = arg.vis;
-    var parent = arg.parent;
-    var obj;
-
-    obj = document.createElement('DIV');
-
-    with(obj)
-      {
-      id = this.name;
-      with(style)
-        {
-       position = 'absolute';
-        visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
-        left = l+'px';
-        top = t+'px';
-        if (w)
-         width = w.toString().match(/\%$/) ? w : w+'px';
-        if (h)
-         height = h.toString().match(/\%$/) ? h : h+'px';
-        if(z) zIndex = z;
-       }
-      }
-
-    if (parent)
-      parent.appendChild(obj);
-    else
-      document.body.appendChild(obj);
-
-    this.elm = obj;
-    };
-
-
-  // create new layer
-  if(attributes!=null)
-    {
-    this.create(attributes);
-    this.name = this.elm.id;
-    }
-  else  // just refer to the object
-    this.elm = document.getElementById(id);
-
-
-  if(!this.elm)
-    return false;
-
-
-  // ********* layer object properties *********
-
-  this.css = this.elm.style;
-  this.event = this.elm;
-  this.width = this.elm.offsetWidth;
-  this.height = this.elm.offsetHeight;
-  this.x = parseInt(this.elm.offsetLeft);
-  this.y = parseInt(this.elm.offsetTop);
-  this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false;
-
-  this.id = rcube_layer_objects.length;
-  this.obj = 'rcube_layer_objects['+this.id+']';
-  rcube_layer_objects[this.id] = this;
-
-
-  // ********* layer object methods *********
-
-
-  // move the layer to a specific position
-  this.move = function(x, y)
-    {
-    this.x = x;
-    this.y = y;
-    this.css.left = Math.round(this.x)+'px';
-    this.css.top = Math.round(this.y)+'px';
-    }
-
-
-  // move the layer for a specific step
-  this.shift = function(x,y)
-    {
-    x = Math.round(x*100)/100;
-    y = Math.round(y*100)/100;
-    this.move(this.x+x, this.y+y);
-    }
-
-
-  // change the layers width and height
-  this.resize = function(w,h)
-    {
-    this.css.width  = w+'px';
-    this.css.height = h+'px';
-    this.width = w;
-    this.height = h;
-    }
-
-
-  // cut the layer (top,width,height,left)
-  this.clip = function(t,w,h,l)
-    {
-    this.css.clip='rect('+t+' '+w+' '+h+' '+l+')';
-    this.clip_height = h;
-    this.clip_width = w;
-    }
-
-
-  // show or hide the layer
-  this.show = function(a)
-    {
-    if(a==1)
-      {
-      this.css.visibility = 'visible';
-      this.visible = true;
-      }
-    else if(a==2)
-      {
-      this.css.visibility = 'inherit';
-      this.visible = true;
-      }
-    else
-      {
-      this.css.visibility = 'hidden';
-      this.visible = false;
-      }
-    }
-
-
-  // write new content into a Layer
-  this.write = function(cont)
-    {
-    this.elm.innerHTML = cont;
-    }
-
-
-  // set the given color to the layer background
-  this.set_bgcolor = function(c)
-    {
-    if(!c || c=='#')
-      c = 'transparent';
-
-    this.css.backgroundColor = c;
-    }
-
-
-  // set the opacity of a layer to the given ammount (in %)
-  this.set_opacity = function(v)
-    {
-    if(!bw.opacity)
-      return;
-
-    var op = v<=1 ? Math.round(v*100) : parseInt(v);
-
-    if(bw.ie)
-      this.css.filter = 'alpha(opacity:'+op+')';
-    else if(bw.safari)
-      {
-      this.css.opacity = op/100;
-      this.css.KhtmlOpacity = op/100;
-      }
-    else if(bw.mz)
-      this.css.MozOpacity = op/100;
-    }
-  }
-
-
-// check if input is a valid email address
-// By Cal Henderson <cal@iamcal.com>
-// http://code.iamcal.com/php/rfc822/
-function rcube_check_email(input, inline)
-  {
-  if (input && window.RegExp)
-    {
-    var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
-    var dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
-    var atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
-    var quoted_pair = '\\x5c[\\x00-\\x7f]';
-    var domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d';
-    var quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22';
-    var sub_domain = '('+atom+'|'+domain_literal+')';
-    var word = '('+atom+'|'+quoted_string+')';
-    var domain = sub_domain+'(\\x2e'+sub_domain+')*';
-    var local_part = word+'(\\x2e'+word+')*';
-    var addr_spec = local_part+'\\x40'+domain;
-    var delim = '[,;\s\n]';
-    var reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');
-    return reg1.test(input) ? true : false;
-    }
-  return false;
-  }
-  
-
-// find a value in a specific array and returns the index
-function find_in_array()
-  {
-  var args = find_in_array.arguments;
-  if(!args.length) return -1;
-
-  var haystack = typeof(args[0])=='object' ? args[0] : args.length>1 && typeof(args[1])=='object' ? args[1] : new Array();
-  var needle = typeof(args[0])!='object' ? args[0] : args.length>1 && typeof(args[1])!='object' ? args[1] : '';
-  var nocase = args.length==3 ? args[2] : false;
-
-  if(!haystack.length) return -1;
-
-  for(var i=0; i<haystack.length; i++)
-    if(nocase && haystack[i].toLowerCase()==needle.toLowerCase())
-      return i;
-    else if(haystack[i]==needle)
-      return i;
-
-  return -1;
-  }
-
-
-// make a string URL safe
-function urlencode(str)
-{
-  return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
+};
+var rcube_event={get_target:function(e){
+e=e||window.event;
+return e&&e.target?e.target:e.srcElement;
+},get_keycode:function(e){
+e=e||window.event;
+return e&&e.keyCode?e.keyCode:(e&&e.which?e.which:0);
+},get_button:function(e){
+e=e||window.event;
+return e&&(typeof e.button!="undefined")?e.button:(e&&e.which?e.which:0);
+},get_modifier:function(e){
+var _6=0;
+e=e||window.event;
+if(bw.mac&&e){
+_6+=(e.metaKey&&CONTROL_KEY)+(e.shiftKey&&SHIFT_KEY);
+return _6;
 }
-
-
-// get any type of html objects by id/name
-function rcube_find_object(id, d)
-  {
-  var n, f, obj, e;
-  if(!d) d = document;
-
-  if(d.getElementsByName && (e = d.getElementsByName(id)))
-    obj = e[0];
-  if(!obj && d.getElementById)
-    obj = d.getElementById(id);
-  if(!obj && d.all)
-    obj = d.all[id];
-
-  if(!obj && d.images.length)
-    obj = d.images[id];
-
-  if(!obj && d.forms.length)
-    for(f=0; f<d.forms.length; f++)
-      {
-      if(d.forms[f].name == id)
-        obj = d.forms[f];
-      else if(d.forms[f].elements[id])
-        obj = d.forms[f].elements[id];
-      }
-
-  if(!obj && d.layers)
-    {
-    if(d.layers[id]) obj = d.layers[id];
-    for(n=0; !obj && n<d.layers.length; n++)
-      obj = rcube_find_object(id, d.layers[n].document);
-    }
-
-  return obj;
-  }
-
-
-// return the absolute position of an object within the document
-function rcube_get_object_pos(obj, relative)
-  {
-  if(typeof(obj)=='string')
-    obj = rcube_find_object(obj);
-
-  if(!obj) return {x:0, y:0};
-
-  var iX = (bw.layers) ? obj.x : obj.offsetLeft;
-  var iY = (bw.layers) ? obj.y : obj.offsetTop;
-
-  if(!relative && (bw.ie || bw.mz))
-    {
-    var elm = obj.offsetParent;
-    while(elm && elm!=null)
-      {
-      iX += elm.offsetLeft - (elm.parentNode && elm.parentNode.scrollLeft ? elm.parentNode.scrollLeft : 0);
-      iY += elm.offsetTop - (elm.parentNode && elm.parentNode.scrollTop ? elm.parentNode.scrollTop : 0);
-      elm = elm.offsetParent;
-      }
-    }
-
-  return {x:iX, y:iY};
-  }
-
-// determine whether the mouse is over the given object or not
-function rcube_mouse_is_over(ev, obj)
-{
-  var mouse = rcube_event.get_mouse_pos(ev);
-  var pos = rcube_get_object_pos(obj);
-  
-  return ((mouse.x >= pos.x) && (mouse.x < (pos.x + obj.offsetWidth)) &&
-    (mouse.y >= pos.y) && (mouse.y < (pos.y + obj.offsetHeight)));
+if(e){
+_6+=(e.ctrlKey&&CONTROL_KEY)+(e.shiftKey&&SHIFT_KEY);
+return _6;
 }
-
-
-/**
- * Return the currently applied value of a css property
- *
- * @param {Object} html_element  Node reference
- * @param {String} css_property  Property name to read in Javascript notation (eg. 'textAlign')
- * @param {String} mozilla_equivalent  Equivalent property name in CSS notation (eg. 'text-align')
- * @return CSS property value
- * @type String
- */
-function get_elements_computed_style(html_element, css_property, mozilla_equivalent)
-  {
-  if (arguments.length==2)
-    mozilla_equivalent = css_property;
-
-  var el = html_element;
-  if (typeof(html_element)=='string')
-    el = rcube_find_object(html_element);
-
-  if (el && el.currentStyle)
-    return el.currentStyle[css_property];
-  else if (el && document.defaultView && document.defaultView.getComputedStyle)
-    return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozilla_equivalent);
-  else
-    return false;
-  }
-  
-
-// cookie functions by GoogieSpell
-function setCookie(name, value, expires, path, domain, secure)
-  {
-  var curCookie = name + "=" + escape(value) +
-      (expires ? "; expires=" + expires.toGMTString() : "") +
-      (path ? "; path=" + path : "") +
-      (domain ? "; domain=" + domain : "") +
-      (secure ? "; secure" : "");
-  document.cookie = curCookie;
-  }
-
-roundcube_browser.prototype.set_cookie = setCookie;
-
-function getCookie(name)
-  {
-  var dc = document.cookie;
-  var prefix = name + "=";
-  var begin = dc.indexOf("; " + prefix);
-  if (begin == -1)
-    {
-    begin = dc.indexOf(prefix);
-    if (begin != 0) return null;
-    }
-  else
-    begin += 2;  
-  var end = document.cookie.indexOf(";", begin);
-  if (end == -1)
-    end = dc.length;
-  return unescape(dc.substring(begin + prefix.length, end));
-  }
-
-roundcube_browser.prototype.get_cookie = getCookie;
-
-
-// tiny replacement for Firebox functionality
-function rcube_console()
-{
-  this.log = function(msg)
-  {
-    box = rcube_find_object('console');
-
-    if (box)
-      if (msg.charAt(msg.length-1)=='\n')
-        box.value += msg+'--------------------------------------\n';
-      else
-        box.value += msg+'\n--------------------------------------\n';
-  };
-
-  this.reset = function()
-  {
-    box = rcube_find_object('console');
-    if (box)
-      box.value = '';
-  };
+},get_mouse_pos:function(e){
+if(!e){
+e=window.event;
 }
-
-var bw = new roundcube_browser();
-
-if (!window.console)
-  console = new rcube_console();
-
-
-// Add escape() method to RegExp object
-// http://dev.rubyonrails.org/changeset/7271
-RegExp.escape = function(str)
-  {
-  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
-  }
-
-
-// Make getElementById() case-sensitive on IE
-if (bw.ie)
-  {
-  document._getElementById = document.getElementById;
-  document.getElementById = function(id)
-    {
-    var i = 0;
-    var o = document._getElementById(id);
-
-    if (!o || o.id != id)
-      while ((o = document.all[i]) && o.id != id)
-        i++;
-
-    return o;
-    }
-  }
-
-
-// Fire event on specified element
-function exec_event(element,event)
-{  
-  if (document.createEventObject) {
-    // dispatch for IE  
-    var evt = document.createEventObject();
-    return element.fireEvent('on'+event,evt)
-  }
-  else {  
-    // dispatch for firefox + others  
-    var evt = document.createEvent("HTMLEvents");
-    evt.initEvent(event, true, true); // event type,bubbling,cancelable
-    return !element.dispatchEvent(evt);
-   }
+var mX=(e.pageX)?e.pageX:e.clientX;
+var mY=(e.pageY)?e.pageY:e.clientY;
+if(document.body&&document.all){
+mX+=document.body.scrollLeft;
+mY+=document.body.scrollTop;
+}
+if(e._offset){
+mX+=e._offset.x;
+mY+=e._offset.y;
+}
+return {x:mX,y:mY};
+},add_listener:function(p){
+if(!p.object||!p.method){
+return;
+}
+if(!p.element){
+p.element=document;
+}
+if(!p.object._rc_events){
+p.object._rc_events=[];
+}
+var _b=p.event+"*"+p.method;
+if(!p.object._rc_events[_b]){
+p.object._rc_events[_b]=function(e){
+return p.object[p.method](e);
+};
+}
+if(p.element.addEventListener){
+p.element.addEventListener(p.event,p.object._rc_events[_b],false);
+}else{
+if(p.element.attachEvent){
+p.element.detachEvent("on"+p.event,p.object._rc_events[_b]);
+p.element.attachEvent("on"+p.event,p.object._rc_events[_b]);
+}else{
+p.element["on"+p.event]=p.object._rc_events[_b];
+}
+}
+},remove_listener:function(p){
+if(!p.element){
+p.element=document;
+}
+var _e=p.event+"*"+p.method;
+if(p.object&&p.object._rc_events&&p.object._rc_events[_e]){
+if(p.element.removeEventListener){
+p.element.removeEventListener(p.event,p.object._rc_events[_e],false);
+}else{
+if(p.element.detachEvent){
+p.element.detachEvent("on"+p.event,p.object._rc_events[_e]);
+}else{
+p.element["on"+p.event]=null;
+}
+}
+}
+},cancel:function(_f){
+var e=_f?_f:window.event;
+if(e.preventDefault){
+e.preventDefault();
+}
+if(e.stopPropagation){
+e.stopPropagation();
+}
+e.cancelBubble=true;
+e.returnValue=false;
+return false;
+}};
+var rcube_layer_objects=new Array();
+function rcube_layer(id,_12){
+this.name=id;
+this.create=function(arg){
+var l=(arg.x)?arg.x:0;
+var t=(arg.y)?arg.y:0;
+var w=arg.width;
+var h=arg.height;
+var z=arg.zindex;
+var vis=arg.vis;
+var _1a=arg.parent;
+var obj;
+obj=document.createElement("DIV");
+with(obj){
+id=this.name;
+with(style){
+position="absolute";
+visibility=(vis)?(vis==2)?"inherit":"visible":"hidden";
+left=l+"px";
+top=t+"px";
+if(w){
+width=w.toString().match(/\%$/)?w:w+"px";
+}
+if(h){
+height=h.toString().match(/\%$/)?h:h+"px";
+}
+if(z){
+zIndex=z;
+}
+}
+}
+if(_1a){
+_1a.appendChild(obj);
+}else{
+document.body.appendChild(obj);
+}
+this.elm=obj;
+};
+if(_12!=null){
+this.create(_12);
+this.name=this.elm.id;
+}else{
+this.elm=document.getElementById(id);
+}
+if(!this.elm){
+return false;
+}
+this.css=this.elm.style;
+this.event=this.elm;
+this.width=this.elm.offsetWidth;
+this.height=this.elm.offsetHeight;
+this.x=parseInt(this.elm.offsetLeft);
+this.y=parseInt(this.elm.offsetTop);
+this.visible=(this.css.visibility=="visible"||this.css.visibility=="show"||this.css.visibility=="inherit")?true:false;
+this.id=rcube_layer_objects.length;
+this.obj="rcube_layer_objects["+this.id+"]";
+rcube_layer_objects[this.id]=this;
+this.move=function(x,y){
+this.x=x;
+this.y=y;
+this.css.left=Math.round(this.x)+"px";
+this.css.top=Math.round(this.y)+"px";
+};
+this.shift=function(x,y){
+x=Math.round(x*100)/100;
+y=Math.round(y*100)/100;
+this.move(this.x+x,this.y+y);
+};
+this.resize=function(w,h){
+this.css.width=w+"px";
+this.css.height=h+"px";
+this.width=w;
+this.height=h;
+};
+this.clip=function(t,w,h,l){
+this.css.clip="rect("+t+" "+w+" "+h+" "+l+")";
+this.clip_height=h;
+this.clip_width=w;
+};
+this.show=function(a){
+if(a==1){
+this.css.visibility="visible";
+this.visible=true;
+}else{
+if(a==2){
+this.css.visibility="inherit";
+this.visible=true;
+}else{
+this.css.visibility="hidden";
+this.visible=false;
+}
+}
+};
+this.write=function(_27){
+this.elm.innerHTML=_27;
+};
+this.set_bgcolor=function(c){
+if(!c||c=="#"){
+c="transparent";
+}
+this.css.backgroundColor=c;
+};
+this.set_opacity=function(v){
+if(!bw.opacity){
+return;
+}
+var op=v<=1?Math.round(v*100):parseInt(v);
+if(bw.ie){
+this.css.filter="alpha(opacity:"+op+")";
+}else{
+if(bw.safari){
+this.css.opacity=op/100;
+this.css.KhtmlOpacity=op/100;
+}else{
+if(bw.mz){
+this.css.MozOpacity=op/100;
+}
+}
+}
+};
+};
+function rcube_check_email(_2b,_2c){
+if(_2b&&window.RegExp){
+var _2d="[^\\x0d\\x22\\x5c\\x80-\\xff]";
+var _2e="[^\\x0d\\x5b-\\x5d\\x80-\\xff]";
+var _2f="[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+";
+var _30="\\x5c[\\x00-\\x7f]";
+var _31="\\x5b("+_2e+"|"+_30+")*\\x5d";
+var _32="\\x22("+_2d+"|"+_30+")*\\x22";
+var _33="("+_2f+"|"+_31+")";
+var _34="("+_2f+"|"+_32+")";
+var _35=_33+"(\\x2e"+_33+")*";
+var _36=_34+"(\\x2e"+_34+")*";
+var _37=_36+"\\x40"+_35;
+var _38="[,;s\n]";
+var _39=_2c?new RegExp("(^|<|"+_38+")"+_37+"($|>|"+_38+")","i"):new RegExp("^"+_37+"$","i");
+return _39.test(_2b)?true:false;
 }
+return false;
+};
+function find_in_array(){
+var _3a=find_in_array.arguments;
+if(!_3a.length){
+return -1;
+}
+var _3b=typeof (_3a[0])=="object"?_3a[0]:_3a.length>1&&typeof (_3a[1])=="object"?_3a[1]:new Array();
+var _3c=typeof (_3a[0])!="object"?_3a[0]:_3a.length>1&&typeof (_3a[1])!="object"?_3a[1]:"";
+var _3d=_3a.length==3?_3a[2]:false;
+if(!_3b.length){
+return -1;
+}
+for(var i=0;i<_3b.length;i++){
+if(_3d&&_3b[i].toLowerCase()==_3c.toLowerCase()){
+return i;
+}else{
+if(_3b[i]==_3c){
+return i;
+}
+}
+}
+return -1;
+};
+function urlencode(str){
+return window.encodeURIComponent?encodeURIComponent(str):escape(str);
+};
+function rcube_find_object(id,d){
+var n,f,obj,e;
+if(!d){
+d=document;
+}
+if(d.getElementsByName&&(e=d.getElementsByName(id))){
+obj=e[0];
+}
+if(!obj&&d.getElementById){
+obj=d.getElementById(id);
+}
+if(!obj&&d.all){
+obj=d.all[id];
+}
+if(!obj&&d.images.length){
+obj=d.images[id];
+}
+if(!obj&&d.forms.length){
+for(f=0;f<d.forms.length;f++){
+if(d.forms[f].name==id){
+obj=d.forms[f];
+}else{
+if(d.forms[f].elements[id]){
+obj=d.forms[f].elements[id];
+}
+}
+}
+}
+if(!obj&&d.layers){
+if(d.layers[id]){
+obj=d.layers[id];
+}
+for(n=0;!obj&&n<d.layers.length;n++){
+obj=rcube_find_object(id,d.layers[n].document);
+}
+}
+return obj;
+};
+function rcube_get_object_pos(obj,_47){
+if(typeof (obj)=="string"){
+obj=rcube_find_object(obj);
+}
+if(!obj){
+return {x:0,y:0};
+}
+var iX=(bw.layers)?obj.x:obj.offsetLeft;
+var iY=(bw.layers)?obj.y:obj.offsetTop;
+if(!_47&&(bw.ie||bw.mz)){
+var elm=obj.offsetParent;
+while(elm&&elm!=null){
+iX+=elm.offsetLeft-(elm.parentNode&&elm.parentNode.scrollLeft?elm.parentNode.scrollLeft:0);
+iY+=elm.offsetTop-(elm.parentNode&&elm.parentNode.scrollTop?elm.parentNode.scrollTop:0);
+elm=elm.offsetParent;
+}
+}
+return {x:iX,y:iY};
+};
+function rcube_mouse_is_over(ev,obj){
+var _4d=rcube_event.get_mouse_pos(ev);
+var pos=rcube_get_object_pos(obj);
+return ((_4d.x>=pos.x)&&(_4d.x<(pos.x+obj.offsetWidth))&&(_4d.y>=pos.y)&&(_4d.y<(pos.y+obj.offsetHeight)));
+};
+function get_elements_computed_style(_4f,_50,_51){
+if(arguments.length==2){
+_51=_50;
+}
+var el=_4f;
+if(typeof (_4f)=="string"){
+el=rcube_find_object(_4f);
+}
+if(el&&el.currentStyle){
+return el.currentStyle[_50];
+}else{
+if(el&&document.defaultView&&document.defaultView.getComputedStyle){
+return document.defaultView.getComputedStyle(el,null).getPropertyValue(_51);
+}else{
+return false;
+}
+}
+};
+function setCookie(_53,_54,_55,_56,_57,_58){
+var _59=_53+"="+escape(_54)+(_55?"; expires="+_55.toGMTString():"")+(_56?"; path="+_56:"")+(_57?"; domain="+_57:"")+(_58?"; secure":"");
+document.cookie=_59;
+};
+roundcube_browser.prototype.set_cookie=setCookie;
+function getCookie(_5a){
+var dc=document.cookie;
+var _5c=_5a+"=";
+var _5d=dc.indexOf("; "+_5c);
+if(_5d==-1){
+_5d=dc.indexOf(_5c);
+if(_5d!=0){
+return null;
+}
+}else{
+_5d+=2;
+}
+var end=document.cookie.indexOf(";",_5d);
+if(end==-1){
+end=dc.length;
+}
+return unescape(dc.substring(_5d+_5c.length,end));
+};
+roundcube_browser.prototype.get_cookie=getCookie;
+function rcube_console(){
+this.log=function(msg){
+var box=rcube_find_object("console");
+if(box){
+if(msg.charAt(msg.length-1)=="\n"){
+msg+="--------------------------------------\n";
+}else{
+msg+="\n--------------------------------------\n";
+}
+if(bw.konq){
+box.innerText+=msg;
+box.value=box.innerText;
+}else{
+box.value+=msg;
+}
+}
+};
+this.reset=function(){
+var box=rcube_find_object("console");
+if(box){
+box.innerText=box.value="";
+}
+};
+};
+var bw=new roundcube_browser();
+if(!window.console){
+var console=new rcube_console();
+}
+RegExp.escape=function(str){
+return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1");
+};
+if(bw.ie){
+document._getElementById=document.getElementById;
+document.getElementById=function(id){
+var i=0;
+var o=document._getElementById(id);
+if(!o||o.id!=id){
+while((o=document.all[i])&&o.id!=id){
+i++;
+}
+}
+return o;
+};
+}
+function exec_event(_66,_67){
+if(document.createEventObject){
+var evt=document.createEventObject();
+return _66.fireEvent("on"+_67,evt);
+}else{
+var evt=document.createEvent("HTMLEvents");
+evt.initEvent(_67,true,true);
+return !_66.dispatchEvent(evt);
+}
+};
+
diff --git a/program/js/common.js.src b/program/js/common.js.src
new file mode 100644 (file)
index 0000000..3f00fa4
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ +-----------------------------------------------------------------------+
+ | RoundCube common js library                                           |
+ |                                                                       |
+ | This file is part of the RoundCube web development suite              |
+ | Copyright (C) 2005-2007, RoundCube Dev, - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+ $Id: common.js 2483 2009-05-15 10:22:29Z thomasb $
+*/
+
+// Constants
+var CONTROL_KEY = 1;
+var SHIFT_KEY = 2;
+var CONTROL_SHIFT_KEY = 3;
+
+
+/**
+ * Default browser check class
+ * @construcotr
+ */
+function roundcube_browser()
+  {
+  this.ver = parseFloat(navigator.appVersion);
+  this.appver = navigator.appVersion;
+  this.agent = navigator.userAgent;
+  this.name = navigator.appName;
+  this.vendor = navigator.vendor ? navigator.vendor : '';
+  this.vendver = navigator.vendorSub ? parseFloat(navigator.vendorSub) : 0;
+  this.product = navigator.product ? navigator.product : '';
+  this.platform = String(navigator.platform).toLowerCase();
+  this.lang = (navigator.language) ? navigator.language.substring(0,2) :
+              (navigator.browserLanguage) ? navigator.browserLanguage.substring(0,2) :
+              (navigator.systemLanguage) ? navigator.systemLanguage.substring(0,2) : 'en';
+
+  this.win = (this.platform.indexOf('win')>=0) ? true : false;
+  this.mac = (this.platform.indexOf('mac')>=0) ? true : false;
+  this.linux = (this.platform.indexOf('linux')>=0) ? true : false;
+  this.unix = (this.platform.indexOf('unix')>=0) ? true : false;
+
+  this.dom = document.getElementById ? true : false;
+  this.dom2 = (document.addEventListener && document.removeEventListener);
+
+  this.ie = (document.all) ? true : false;
+  this.ie4 = (this.ie && !this.dom);
+  this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0);
+  this.ie6 = (this.dom && this.appver.indexOf('MSIE 6')>0);
+  this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0);
+
+  this.mz = (this.dom && this.ver>=5);  // (this.dom && this.product=='Gecko')
+  this.ns = ((this.ver<5 && this.name=='Netscape') || (this.ver>=5 && this.vendor.indexOf('Netscape')>=0));
+  this.ns6 = (this.ns && parseInt(this.vendver)==6);  // (this.mz && this.ns) ? true : false;
+  this.ns7 = (this.ns && parseInt(this.vendver)==7);  // this.agent.indexOf('Netscape/7')>0);
+  this.safari = (this.agent.toLowerCase().indexOf('safari')>0 || this.agent.toLowerCase().indexOf('applewebkit')>0);
+  this.konq   = (this.agent.toLowerCase().indexOf('konqueror')>0);
+
+  this.opera = (window.opera) ? true : false;
+
+  if(this.opera && window.RegExp)
+    this.vendver = (/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent)) ? parseFloat(RegExp.$2) : -1;
+  else if(!this.vendver && this.safari)
+    this.vendver = (/(safari|applewebkit)\/([0-9]+)/i.test(this.agent)) ? parseInt(RegExp.$2) : 0;
+  else if((!this.vendver && this.mz) || this.agent.indexOf('Camino')>0)
+    this.vendver = (/rv:([0-9\.]+)/.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
+  else if(this.ie && window.RegExp)
+    this.vendver = (/msie\s+([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
+  else if(this.konq && window.RegExp)
+    this.vendver = (/khtml\/([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
+
+
+  // get real language out of safari's user agent
+  if(this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent)))
+    this.lang = RegExp.$1;
+
+  this.dhtml = ((this.ie4 && this.win) || this.ie5 || this.ie6 || this.ns4 || this.mz);
+  this.vml = (this.win && this.ie && this.dom && !this.opera);
+  this.pngalpha = (this.mz || (this.opera && this.vendver>=6) || (this.ie && this.mac && this.vendver>=5) ||
+                   (this.ie && this.win && this.vendver>=5.5) || this.safari);
+  this.opacity = (this.mz || (this.ie && this.vendver>=5.5 && !this.opera) || (this.safari && this.vendver>=100));
+  this.cookies = navigator.cookieEnabled;
+  
+  // test for XMLHTTP support
+  this.xmlhttp_test = function()
+    {
+    var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
+    this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())) ? true : false;
+    return this.xmlhttp;
+    }
+  }
+
+
+// static functions for event handling
+var rcube_event = {
+
+/**
+ * returns the event target element
+ */
+get_target: function(e)
+{
+  e = e || window.event;
+  return e && e.target ? e.target : e.srcElement;
+},
+
+/**
+ * returns the event key code
+ */
+get_keycode: function(e)
+{
+  e = e || window.event;
+  return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
+},
+
+/**
+ * returns the event key code
+ */
+get_button: function(e)
+{
+  e = e || window.event;
+  return e && (typeof e.button != 'undefined') ? e.button : (e && e.which ? e.which : 0);
+},
+
+/**
+ * returns modifier key (constants defined at top of file)
+ */
+get_modifier: function(e)
+{
+  var opcode = 0;
+  e = e || window.event;
+
+  if (bw.mac && e)
+    {
+    opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
+    return opcode;    
+    }
+  if (e)
+    {
+    opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
+    return opcode;
+    }
+},
+
+/**
+ * Return absolute mouse position of an event
+ */
+get_mouse_pos: function(e)
+{
+  if (!e) e = window.event;
+  var mX = (e.pageX) ? e.pageX : e.clientX;
+  var mY = (e.pageY) ? e.pageY : e.clientY;
+
+  if (document.body && document.all)
+  {
+    mX += document.body.scrollLeft;
+    mY += document.body.scrollTop;
+  }
+
+  if (e._offset) {
+    mX += e._offset.x;
+    mY += e._offset.y;
+  }
+
+  return { x:mX, y:mY };
+},
+
+/**
+ * Add an object method as event listener to a certain element
+ */
+add_listener: function(p)
+{
+  if (!p.object || !p.method)  // not enough arguments
+    return;
+  if (!p.element)
+    p.element = document;
+
+  if (!p.object._rc_events)
+    p.object._rc_events = [];
+  
+  var key = p.event + '*' + p.method;
+  if (!p.object._rc_events[key])
+    p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
+
+  if (p.element.addEventListener)
+    p.element.addEventListener(p.event, p.object._rc_events[key], false);
+  else if (p.element.attachEvent)
+    {
+    // IE allows multiple events with the same function to be applied to the same object
+    // forcibly detach the event, then attach
+    p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
+    p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
+    }
+  else
+    p.element['on'+p.event] = p.object._rc_events[key];
+},
+
+/**
+ * Remove event listener
+ */
+remove_listener: function(p)
+{
+  if (!p.element)
+    p.element = document;
+
+  var key = p.event + '*' + p.method;
+  if (p.object && p.object._rc_events && p.object._rc_events[key]) {
+    if (p.element.removeEventListener)
+      p.element.removeEventListener(p.event, p.object._rc_events[key], false);
+    else if (p.element.detachEvent)
+      p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
+    else
+      p.element['on'+p.event] = null;
+  }
+},
+
+/**
+ * Prevent event propagation and bubbeling
+ */
+cancel: function(evt)
+{
+  var e = evt ? evt : window.event;
+  if (e.preventDefault)
+    e.preventDefault();
+  if (e.stopPropagation)
+    e.stopPropagation();
+
+  e.cancelBubble = true;
+  e.returnValue = false;
+  return false;
+}
+
+};
+
+
+var rcube_layer_objects = new Array();
+
+
+/**
+ * RoundCube generic layer (floating box) class
+ *
+ * @constructor
+ */
+function rcube_layer(id, attributes)
+  {
+  this.name = id;
+  
+  // create a new layer in the current document
+  this.create = function(arg)
+    {
+    var l = (arg.x) ? arg.x : 0;
+    var t = (arg.y) ? arg.y : 0;
+    var w = arg.width;
+    var h = arg.height;
+    var z = arg.zindex;
+    var vis = arg.vis;
+    var parent = arg.parent;
+    var obj;
+
+    obj = document.createElement('DIV');
+
+    with(obj)
+      {
+      id = this.name;
+      with(style)
+        {
+       position = 'absolute';
+        visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
+        left = l+'px';
+        top = t+'px';
+        if (w)
+         width = w.toString().match(/\%$/) ? w : w+'px';
+        if (h)
+         height = h.toString().match(/\%$/) ? h : h+'px';
+        if(z) zIndex = z;
+       }
+      }
+
+    if (parent)
+      parent.appendChild(obj);
+    else
+      document.body.appendChild(obj);
+
+    this.elm = obj;
+    };
+
+
+  // create new layer
+  if(attributes!=null)
+    {
+    this.create(attributes);
+    this.name = this.elm.id;
+    }
+  else  // just refer to the object
+    this.elm = document.getElementById(id);
+
+
+  if(!this.elm)
+    return false;
+
+
+  // ********* layer object properties *********
+
+  this.css = this.elm.style;
+  this.event = this.elm;
+  this.width = this.elm.offsetWidth;
+  this.height = this.elm.offsetHeight;
+  this.x = parseInt(this.elm.offsetLeft);
+  this.y = parseInt(this.elm.offsetTop);
+  this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false;
+
+  this.id = rcube_layer_objects.length;
+  this.obj = 'rcube_layer_objects['+this.id+']';
+  rcube_layer_objects[this.id] = this;
+
+
+  // ********* layer object methods *********
+
+
+  // move the layer to a specific position
+  this.move = function(x, y)
+    {
+    this.x = x;
+    this.y = y;
+    this.css.left = Math.round(this.x)+'px';
+    this.css.top = Math.round(this.y)+'px';
+    }
+
+
+  // move the layer for a specific step
+  this.shift = function(x,y)
+    {
+    x = Math.round(x*100)/100;
+    y = Math.round(y*100)/100;
+    this.move(this.x+x, this.y+y);
+    }
+
+
+  // change the layers width and height
+  this.resize = function(w,h)
+    {
+    this.css.width  = w+'px';
+    this.css.height = h+'px';
+    this.width = w;
+    this.height = h;
+    }
+
+
+  // cut the layer (top,width,height,left)
+  this.clip = function(t,w,h,l)
+    {
+    this.css.clip='rect('+t+' '+w+' '+h+' '+l+')';
+    this.clip_height = h;
+    this.clip_width = w;
+    }
+
+
+  // show or hide the layer
+  this.show = function(a)
+    {
+    if(a==1)
+      {
+      this.css.visibility = 'visible';
+      this.visible = true;
+      }
+    else if(a==2)
+      {
+      this.css.visibility = 'inherit';
+      this.visible = true;
+      }
+    else
+      {
+      this.css.visibility = 'hidden';
+      this.visible = false;
+      }
+    }
+
+
+  // write new content into a Layer
+  this.write = function(cont)
+    {
+    this.elm.innerHTML = cont;
+    }
+
+
+  // set the given color to the layer background
+  this.set_bgcolor = function(c)
+    {
+    if(!c || c=='#')
+      c = 'transparent';
+
+    this.css.backgroundColor = c;
+    }
+
+
+  // set the opacity of a layer to the given ammount (in %)
+  this.set_opacity = function(v)
+    {
+    if(!bw.opacity)
+      return;
+
+    var op = v<=1 ? Math.round(v*100) : parseInt(v);
+
+    if(bw.ie)
+      this.css.filter = 'alpha(opacity:'+op+')';
+    else if(bw.safari)
+      {
+      this.css.opacity = op/100;
+      this.css.KhtmlOpacity = op/100;
+      }
+    else if(bw.mz)
+      this.css.MozOpacity = op/100;
+    }
+  }
+
+
+// check if input is a valid email address
+// By Cal Henderson <cal@iamcal.com>
+// http://code.iamcal.com/php/rfc822/
+function rcube_check_email(input, inline)
+  {
+  if (input && window.RegExp)
+    {
+    var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
+    var dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
+    var atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
+    var quoted_pair = '\\x5c[\\x00-\\x7f]';
+    var domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d';
+    var quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22';
+    var sub_domain = '('+atom+'|'+domain_literal+')';
+    var word = '('+atom+'|'+quoted_string+')';
+    var domain = sub_domain+'(\\x2e'+sub_domain+')*';
+    var local_part = word+'(\\x2e'+word+')*';
+    var addr_spec = local_part+'\\x40'+domain;
+    var delim = '[,;\s\n]';
+    var reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');
+    return reg1.test(input) ? true : false;
+    }
+  return false;
+  }
+  
+
+// find a value in a specific array and returns the index
+function find_in_array()
+  {
+  var args = find_in_array.arguments;
+  if(!args.length) return -1;
+
+  var haystack = typeof(args[0])=='object' ? args[0] : args.length>1 && typeof(args[1])=='object' ? args[1] : new Array();
+  var needle = typeof(args[0])!='object' ? args[0] : args.length>1 && typeof(args[1])!='object' ? args[1] : '';
+  var nocase = args.length==3 ? args[2] : false;
+
+  if(!haystack.length) return -1;
+
+  for(var i=0; i<haystack.length; i++)
+    if(nocase && haystack[i].toLowerCase()==needle.toLowerCase())
+      return i;
+    else if(haystack[i]==needle)
+      return i;
+
+  return -1;
+  }
+
+
+// make a string URL safe
+function urlencode(str)
+{
+  return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
+}
+
+
+// get any type of html objects by id/name
+function rcube_find_object(id, d)
+  {
+  var n, f, obj, e;
+  if(!d) d = document;
+
+  if(d.getElementsByName && (e = d.getElementsByName(id)))
+    obj = e[0];
+  if(!obj && d.getElementById)
+    obj = d.getElementById(id);
+  if(!obj && d.all)
+    obj = d.all[id];
+
+  if(!obj && d.images.length)
+    obj = d.images[id];
+
+  if(!obj && d.forms.length)
+    for(f=0; f<d.forms.length; f++)
+      {
+      if(d.forms[f].name == id)
+        obj = d.forms[f];
+      else if(d.forms[f].elements[id])
+        obj = d.forms[f].elements[id];
+      }
+
+  if(!obj && d.layers)
+    {
+    if(d.layers[id]) obj = d.layers[id];
+    for(n=0; !obj && n<d.layers.length; n++)
+      obj = rcube_find_object(id, d.layers[n].document);
+    }
+
+  return obj;
+  }
+
+
+// return the absolute position of an object within the document
+function rcube_get_object_pos(obj, relative)
+  {
+  if(typeof(obj)=='string')
+    obj = rcube_find_object(obj);
+
+  if(!obj) return {x:0, y:0};
+
+  var iX = (bw.layers) ? obj.x : obj.offsetLeft;
+  var iY = (bw.layers) ? obj.y : obj.offsetTop;
+
+  if(!relative && (bw.ie || bw.mz))
+    {
+    var elm = obj.offsetParent;
+    while(elm && elm!=null)
+      {
+      iX += elm.offsetLeft - (elm.parentNode && elm.parentNode.scrollLeft ? elm.parentNode.scrollLeft : 0);
+      iY += elm.offsetTop - (elm.parentNode && elm.parentNode.scrollTop ? elm.parentNode.scrollTop : 0);
+      elm = elm.offsetParent;
+      }
+    }
+
+  return {x:iX, y:iY};
+  }
+
+// determine whether the mouse is over the given object or not
+function rcube_mouse_is_over(ev, obj)
+{
+  var mouse = rcube_event.get_mouse_pos(ev);
+  var pos = rcube_get_object_pos(obj);
+  
+  return ((mouse.x >= pos.x) && (mouse.x < (pos.x + obj.offsetWidth)) &&
+    (mouse.y >= pos.y) && (mouse.y < (pos.y + obj.offsetHeight)));
+}
+
+
+/**
+ * Return the currently applied value of a css property
+ *
+ * @param {Object} html_element  Node reference
+ * @param {String} css_property  Property name to read in Javascript notation (eg. 'textAlign')
+ * @param {String} mozilla_equivalent  Equivalent property name in CSS notation (eg. 'text-align')
+ * @return CSS property value
+ * @type String
+ */
+function get_elements_computed_style(html_element, css_property, mozilla_equivalent)
+  {
+  if (arguments.length==2)
+    mozilla_equivalent = css_property;
+
+  var el = html_element;
+  if (typeof(html_element)=='string')
+    el = rcube_find_object(html_element);
+
+  if (el && el.currentStyle)
+    return el.currentStyle[css_property];
+  else if (el && document.defaultView && document.defaultView.getComputedStyle)
+    return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozilla_equivalent);
+  else
+    return false;
+  }
+  
+
+// cookie functions by GoogieSpell
+function setCookie(name, value, expires, path, domain, secure)
+  {
+  var curCookie = name + "=" + escape(value) +
+      (expires ? "; expires=" + expires.toGMTString() : "") +
+      (path ? "; path=" + path : "") +
+      (domain ? "; domain=" + domain : "") +
+      (secure ? "; secure" : "");
+  document.cookie = curCookie;
+  }
+
+roundcube_browser.prototype.set_cookie = setCookie;
+
+function getCookie(name)
+  {
+  var dc = document.cookie;
+  var prefix = name + "=";
+  var begin = dc.indexOf("; " + prefix);
+  if (begin == -1)
+    {
+    begin = dc.indexOf(prefix);
+    if (begin != 0) return null;
+    }
+  else
+    begin += 2;  
+  var end = document.cookie.indexOf(";", begin);
+  if (end == -1)
+    end = dc.length;
+  return unescape(dc.substring(begin + prefix.length, end));
+  }
+
+roundcube_browser.prototype.get_cookie = getCookie;
+
+// tiny replacement for Firebox functionality
+function rcube_console()
+{
+  this.log = function(msg)
+  {
+    var box = rcube_find_object('console');
+
+    if (box) {
+      if (msg.charAt(msg.length-1)=='\n')
+       msg += '--------------------------------------\n';
+      else
+        msg += '\n--------------------------------------\n';
+
+      // Konqueror doesn't allows to just change value of hidden element
+      if (bw.konq) {
+        box.innerText += msg;
+        box.value = box.innerText;
+      } else
+        box.value += msg;
+    }
+  };
+
+  this.reset = function()
+  {
+    var box = rcube_find_object('console');
+    if (box)
+      box.innerText = box.value = '';
+  };
+}
+
+var bw = new roundcube_browser();
+if (!window.console)
+  var console = new rcube_console();
+
+
+// Add escape() method to RegExp object
+// http://dev.rubyonrails.org/changeset/7271
+RegExp.escape = function(str)
+{
+  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+}
+
+
+// Make getElementById() case-sensitive on IE
+if (bw.ie)
+  {
+  document._getElementById = document.getElementById;
+  document.getElementById = function(id)
+    {
+    var i = 0;
+    var o = document._getElementById(id);
+
+    if (!o || o.id != id)
+      while ((o = document.all[i]) && o.id != id)
+        i++;
+
+    return o;
+    }
+  }
+
+
+// Fire event on specified element
+function exec_event(element,event)
+{  
+  if (document.createEventObject) {
+    // dispatch for IE  
+    var evt = document.createEventObject();
+    return element.fireEvent('on'+event,evt)
+  }
+  else {  
+    // dispatch for firefox + others  
+    var evt = document.createEvent("HTMLEvents");
+    evt.initEvent(event, true, true); // event type,bubbling,cancelable
+    return !element.dispatchEvent(evt);
+   }
+}
index 8b9d1cc716cb33b5c653cbfccb0b7e235dc044ec..eb103e7acef938d3753c7a3b40b8b52874d8fc96 100644 (file)
-/*
-Last Modified: 28/04/06 16:28:09
-
-  AmiJs library
-    A very small library with DOM and Ajax functions.
-    For a much larger script look on http://www.mochikit.com/
-  AUTHOR
-    4mir Salihefendic (http://amix.dk) - amix@amix.dk
-  LICENSE
-    Copyright (c) 2006 Amir Salihefendic. All rights reserved.
-    Copyright (c) 2005 Bob Ippolito. All rights reserved.
-    http://www.opensource.org/licenses/mit-license.php
-  VERSION
-    2.1
-  SITE
-    http://amix.dk/amijs
-**/
-
-var AJS = {
-////
-// Accessor functions
-////
-  /**
-   * @returns The element with the id
-   */
-  getElement: function(id) {
-    if(typeof(id) == "string") 
-      return document.getElementById(id);
-    else
-      return id;
-  },
-
-  /**
-   * @returns The elements with the ids
-   */
-  getElements: function(/*id1, id2, id3*/) {
-    var elements = new Array();
-      for (var i = 0; i < arguments.length; i++) {
-        var element = this.getElement(arguments[i]);
-        elements.push(element);
-      }
-      return elements;
-  },
-
-  /**
-   * @returns The GET query argument
-   */
-  getQueryArgument: function(var_name) {
-    var query = window.location.search.substring(1);
-    var vars = query.split("&");
-    for (var i=0;i<vars.length;i++) {
-      var pair = vars[i].split("=");
-      if (pair[0] == var_name) {
-        return pair[1];
-      }
-    }
-    return null;
-  },
-
-  /**
-   * @returns If the browser is Internet Explorer
-   */
-  isIe: function() {
-    return (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1);
-  },
-
-  /**
-   * @returns The document body   
-   */
-  getBody: function() {
-    return this.getElementsByTagAndClassName('body')[0] 
-  },
-
-  /**
-   * @returns All the elements that have a specific tag name or class name
-   */
-  getElementsByTagAndClassName: function(tag_name, class_name, /*optional*/ parent) {
-    var class_elements = new Array();
-    if(!this.isDefined(parent))
-      parent = document;
-    if(!this.isDefined(tag_name))
-      tag_name = '*';
-
-    var els = parent.getElementsByTagName(tag_name);
-    var els_len = els.length;
-    var pattern = new RegExp("(^|\\s)" + class_name + "(\\s|$)");
-
-    for (i = 0, j = 0; i < els_len; i++) {
-      if ( pattern.test(els[i].className) || class_name == null ) {
-        class_elements[j] = els[i];
-        j++;
-      }
-    }
-    return class_elements;
-  },
-
-
-////
-// DOM manipulation
-////
-  /**
-   * Appends some nodes to a node
-   */
-  appendChildNodes: function(node/*, nodes...*/) {
-    if(arguments.length >= 2) {
-      for(var i=1; i < arguments.length; i++) {
-        var n = arguments[i];
-        if(typeof(n) == "string")
-          n = document.createTextNode(n);
-        if(this.isDefined(n))
-          node.appendChild(n);
-      }
-    }
-    return node;
-  },
-
-  /**
-   * Replaces a nodes children with another node(s)
-   */
-  replaceChildNodes: function(node/*, nodes...*/) {
-    var child;
-    while ((child = node.firstChild)) {
-      node.removeChild(child);
-    }
-    if (arguments.length < 2) {
-      return node;
-    } else {
-      return this.appendChildNodes.apply(this, arguments);
-    }
-  },
-
-  /**
-   * Insert a node after another node
-   */
-  insertAfter: function(node, referenceNode) {
-    referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
-  },
-  
-  /**
-   * Insert a node before another node
-   */
-  insertBefore: function(node, referenceNode) {
-    referenceNode.parentNode.insertBefore(node, referenceNode);
-  },
-  
-  /**
-   * Shows the element
-   */
-  showElement: function(elm) {
-    elm.style.display = '';
-  },
-  
-  /**
-   * Hides the element
-   */
-  hideElement: function(elm) {
-    elm.style.display = 'none';
-  },
-
-  isElementHidden: function(elm) {
-    return elm.style.visibility == "hidden";
-  },
-  
-  /**
-   * Swaps one element with another. To delete use swapDOM(elm, null)
-   */
-  swapDOM: function(dest, src) {
-    dest = this.getElement(dest);
-    var parent = dest.parentNode;
-    if (src) {
-      src = this.getElement(src);
-      parent.replaceChild(src, dest);
-    } else {
-      parent.removeChild(dest);
-    }
-    return src;
-  },
-
-  /**
-   * Removes an element from the world
-   */
-  removeElement: function(elm) {
-    this.swapDOM(elm, null);
-  },
-
-  /**
-   * @returns Is an object a dictionary?
-   */
-  isDict: function(o) {
-    var str_repr = String(o);
-    return str_repr.indexOf(" Object") != -1;
-  },
-  
-  /**
-   * Creates a DOM element
-   * @param {String} name The elements DOM name
-   * @param {Dict} attrs Attributes sent to the function
-   */
-  createDOM: function(name, attrs) {
-    var i=0;
-    elm = document.createElement(name);
-
-    if(this.isDict(attrs[i])) {
-      for(k in attrs[0]) {
-        if(k == "style")
-          elm.style.cssText = attrs[0][k];
-        else if(k == "class")
-          elm.className = attrs[0][k];
-        else
-          elm.setAttribute(k, attrs[0][k]);
-      }
-      i++;
-    }
-
-    if(attrs[0] == null)
-      i = 1;
-
-    for(i; i < attrs.length; i++) {
-      var n = attrs[i];
-      if(this.isDefined(n)) {
-        if(typeof(n) == "string")
-          n = document.createTextNode(n);
-        elm.appendChild(n);
-      }
-    }
-    return elm;
-  },
-
-  UL: function() { return this.createDOM.apply(this, ["ul", arguments]); },
-  LI: function() { return this.createDOM.apply(this, ["li", arguments]); },
-  TD: function() { return this.createDOM.apply(this, ["td", arguments]); },
-  TR: function() { return this.createDOM.apply(this, ["tr", arguments]); },
-  TH: function() { return this.createDOM.apply(this, ["th", arguments]); },
-  TBODY: function() { return this.createDOM.apply(this, ["tbody", arguments]); },
-  TABLE: function() { return this.createDOM.apply(this, ["table", arguments]); },
-  INPUT: function() { return this.createDOM.apply(this, ["input", arguments]); },
-  SPAN: function() { return this.createDOM.apply(this, ["span", arguments]); },
-  B: function() { return this.createDOM.apply(this, ["b", arguments]); },
-  A: function() { return this.createDOM.apply(this, ["a", arguments]); },
-  DIV: function() { return this.createDOM.apply(this, ["div", arguments]); },
-  IMG: function() { return this.createDOM.apply(this, ["img", arguments]); },
-  BUTTON: function() { return this.createDOM.apply(this, ["button", arguments]); },
-  H1: function() { return this.createDOM.apply(this, ["h1", arguments]); },
-  H2: function() { return this.createDOM.apply(this, ["h2", arguments]); },
-  H3: function() { return this.createDOM.apply(this, ["h3", arguments]); },
-  BR: function() { return this.createDOM.apply(this, ["br", arguments]); },
-  TEXTAREA: function() { return this.createDOM.apply(this, ["textarea", arguments]); },
-  FORM: function() { return this.createDOM.apply(this, ["form", arguments]); },
-  P: function() { return this.createDOM.apply(this, ["p", arguments]); },
-  SELECT: function() { return this.createDOM.apply(this, ["select", arguments]); },
-  OPTION: function() { return this.createDOM.apply(this, ["option", arguments]); },
-  TN: function(text) { return document.createTextNode(text); },
-  IFRAME: function() { return this.createDOM.apply(this, ["iframe", arguments]); },
-  SCRIPT: function() { return this.createDOM.apply(this, ["script", arguments]); },
-
-////
-// Ajax functions
-////
-  /**
-   * @returns A new XMLHttpRequest object 
-   */
-  getXMLHttpRequest: function() {
-    var try_these = [
-      function () { return new XMLHttpRequest(); },
-      function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
-      function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
-      function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
-      function () { throw "Browser does not support XMLHttpRequest"; }
-    ];
-    for (var i = 0; i < try_these.length; i++) {
-      var func = try_these[i];
-      try {
-        return func();
-      } catch (e) {
-      }
-    }
-  },
-  
-  /**
-   * Use this function to do a simple HTTP Request
-   */
-  doSimpleXMLHttpRequest: function(url) {
-    var req = this.getXMLHttpRequest();
-    req.open("GET", url, true);
-    return this.sendXMLHttpRequest(req);
-  },
-
-  getRequest: function(url, data) {
-    var req = this.getXMLHttpRequest();
-    req.open("POST", url, true);
-    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
-    return this.sendXMLHttpRequest(req);
-  },
-
-  /**
-   * Send a XMLHttpRequest
-   */
-  sendXMLHttpRequest: function(req, data) {
-    var d = new AJSDeferred(req);
-
-    var onreadystatechange = function () {
-      if (req.readyState == 4) {
-        try {
-          var status = req.status;
-        }
-        catch(e) {};
-        if(status == 200 || status == 304 || req.responseText == null) {
-          d.callback(req, data);
-        }
-        else {
-          d.errback();
-        }
-      }
-    }
-    req.onreadystatechange = onreadystatechange;
-    return d;
-  },
-  
-  /**
-   * Represent an object as a string
-   */
-  reprString: function(o) {
-    return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
-    ).replace(/[\f]/g, "\\f"
-    ).replace(/[\b]/g, "\\b"
-    ).replace(/[\n]/g, "\\n"
-    ).replace(/[\t]/g, "\\t"
-    ).replace(/[\r]/g, "\\r");
-  },
-  
-  /**
-   * Serialize an object to JSON notation
-   */
-  serializeJSON: function(o) {
-    var objtype = typeof(o);
-    if (objtype == "undefined") {
-      return "undefined";
-    } else if (objtype == "number" || objtype == "boolean") {
-      return o + "";
-    } else if (o === null) {
-      return "null";
-    }
-    if (objtype == "string") {
-      return this.reprString(o);
-    }
-    var me = arguments.callee;
-    var newObj;
-    if (typeof(o.__json__) == "function") {
-      newObj = o.__json__();
-      if (o !== newObj) {
-        return me(newObj);
-      }
-    }
-    if (typeof(o.json) == "function") {
-      newObj = o.json();
-      if (o !== newObj) {
-        return me(newObj);
-      }
-    }
-    if (objtype != "function" && typeof(o.length) == "number") {
-      var res = [];
-      for (var i = 0; i < o.length; i++) {
-        var val = me(o[i]);
-        if (typeof(val) != "string") {
-          val = "undefined";
-        }
-        res.push(val);
-      }
-      return "[" + res.join(",") + "]";
-    }
-    res = [];
-    for (var k in o) {
-      var useKey;
-      if (typeof(k) == "number") {
-        useKey = '"' + k + '"';
-      } else if (typeof(k) == "string") {
-        useKey = this.reprString(k);
-      } else {
-        // skip non-string or number keys
-        continue;
-      }
-      val = me(o[k]);
-      if (typeof(val) != "string") {
-        // skip non-serializable values
-        continue;
-      }
-      res.push(useKey + ":" + val);
-    }
-    return "{" + res.join(",") + "}";
-  },
-
-  /**
-   * Send and recive JSON using GET
-   */
-  loadJSONDoc: function(url) {
-    var d = this.getRequest(url);
-    var eval_req = function(req) {
-      var text = req.responseText;
-      return eval('(' + text + ')');
-    };
-    d.addCallback(eval_req);
-    return d;
-  },
-  
-  
-////
-// Misc.
-////
-  /**
-   * Alert the objects key attrs 
-   */
-  keys: function(obj) {
-    var rval = [];
-    for (var prop in obj) {
-      rval.push(prop);
-    }
-    return rval;
-  },
-
-  urlencode: function(str) {
-    return encodeURIComponent(str.toString());
-  },
-
-  /**
-   * @returns True if the object is defined, otherwise false
-   */
-  isDefined: function(o) {
-    return (o != "undefined" && o != null)
-  },
-  
-  /**
-   * @returns True if an object is a array, false otherwise
-   */
-  isArray: function(obj) {
-    try { return (typeof(obj.length) == "undefined") ? false : true; }
-    catch(e)
-    { return false; }
-  },
-
-  isObject: function(obj) {
-    return (obj && typeof obj == 'object');
-  },
-
-  /**
-   * Export DOM elements to the global namespace
-   */
-  exportDOMElements: function() {
-    UL = this.UL;
-    LI = this.LI;
-    TD = this.TD;
-    TR = this.TR;
-    TH = this.TH;
-    TBODY = this.TBODY;
-    TABLE = this.TABLE;
-    INPUT = this.INPUT;
-    SPAN = this.SPAN;
-    B = this.B;
-    A = this.A;
-    DIV = this.DIV;
-    IMG = this.IMG;
-    BUTTON = this.BUTTON;
-    H1 = this.H1;
-    H2 = this.H2;
-    H3 = this.H3;
-    BR = this.BR;
-    TEXTAREA = this.TEXTAREA;
-    FORM = this.FORM;
-    P = this.P;
-    SELECT = this.SELECT;
-    OPTION = this.OPTION;
-    TN = this.TN;
-    IFRAME = this.IFRAME;
-    SCRIPT = this.SCRIPT;
-  },
-
-  /**
-   * Export AmiJS functions to the global namespace
-   */
-  exportToGlobalScope: function() {
-    getElement = this.getElement;
-    getQueryArgument = this.getQueryArgument;
-    isIe = this.isIe;
-    $ = this.getElement;
-    getElements = this.getElements;
-    getBody = this.getBody;
-    getElementsByTagAndClassName = this.getElementsByTagAndClassName;
-    appendChildNodes = this.appendChildNodes;
-    ACN = appendChildNodes;
-    replaceChildNodes = this.replaceChildNodes;
-    RCN = replaceChildNodes;
-    insertAfter = this.insertAfter;
-    insertBefore = this.insertBefore;
-    showElement = this.showElement;
-    hideElement = this.hideElement;
-    isElementHidden = this.isElementHidden;
-    swapDOM = this.swapDOM;
-    removeElement = this.removeElement;
-    isDict = this.isDict;
-    createDOM = this.createDOM;
-    this.exportDOMElements();
-    getXMLHttpRequest = this.getXMLHttpRequest;
-    doSimpleXMLHttpRequest = this.doSimpleXMLHttpRequest;
-    getRequest = this.getRequest;
-    sendXMLHttpRequest = this.sendXMLHttpRequest;
-    reprString = this.reprString;
-    serializeJSON = this.serializeJSON;
-    loadJSONDoc = this.loadJSONDoc;
-    keys = this.keys;
-    isDefined = this.isDefined;
-    isArray = this.isArray;
-  }
-}
-
-
-
-AJSDeferred = function(req) {
-  this.callbacks = [];
-  this.req = req;
-
-  this.callback = function (res) {
-    while (this.callbacks.length > 0) {
-      var fn = this.callbacks.pop();
-      res = fn(res);
-    }
-  };
-
-  this.errback = function(e){
-    alert("Error encountered:\n" + e);
-  };
-
-  this.addErrback = function(fn) {
-    this.errback = fn;
-  };
-
-  this.addCallback = function(fn) {
-    this.callbacks.unshift(fn);
-  };
-
-  this.addCallbacks = function(fn1, fn2) {
-    this.addCallback(fn1);
-    this.addErrback(fn2);
-  };
-
-  this.sendReq = function(data) {
-    if(AJS.isObject(data)) {
-      var post_data = [];
-      for(k in data) {
-        post_data.push(k + "=" + AJS.urlencode(data[k]));
-      }
-      post_data = post_data.join("&");
-      this.req.send(post_data);
-    }
-    else if(AJS.isDefined(data))
-      this.req.send(data);
-    else {
-      this.req.send("");
-    }
-  };
-};
-AJSDeferred.prototype = new AJSDeferred();
-
-
-
-
-
-
-/****
-Last Modified: 28/04/06 15:26:06
-
- GoogieSpell
-   Google spell checker for your own web-apps :)
-   Copyright Amir Salihefendic 2006
- LICENSE
-  GPL (see gpl.txt for more information)
-  This basically means that you can't use this script with/in proprietary software!
-  There is another license that permits you to use this script with proprietary software. Check out:... for more info.
-  AUTHOR
-   4mir Salihefendic (http://amix.dk) - amix@amix.dk
- VERSION
-        3.22
-****/
-var GOOGIE_CUR_LANG = "en";
-
-function GoogieSpell(img_dir, server_url) {
-  var cookie_value;
-  var lang;
-  cookie_value = getCookie('language');
-
-  if(cookie_value != null)
-    GOOGIE_CUR_LANG = cookie_value;
-
-  this.img_dir = img_dir;
-  this.server_url = server_url;
-
-  this.lang_to_word = {"da": "Dansk", "de": "Deutsch", "en": "English",
-                       "es": "Espa&#241;ol", "fr": "Fran&#231;ais", "it": "Italiano", 
-                       "nl": "Nederlands", "pl": "Polski", "pt": "Portugu&#234;s",
-                       "fi": "Suomi", "sv": "Svenska"};
-  this.langlist_codes = AJS.keys(this.lang_to_word);
-
-  this.show_change_lang_pic = true;
-
-  this.lang_state_observer = null;
-
-  this.spelling_state_observer = null;
-
-  this.request = null;
-  this.error_window = null;
-  this.language_window = null;
-  this.edit_layer = null;
-  this.orginal_text = null;
-  this.results = null;
-  this.text_area = null;
-  this.gselm = null;
-  this.ta_scroll_top = 0;
-  this.el_scroll_top = 0;
-
-  this.lang_chck_spell = "Check spelling";
-  this.lang_rsm_edt = "Resume editing";
-  this.lang_close = "Close";
-  this.lang_no_error_found = "No spelling errors found";
-  this.lang_revert = "Revert to";
-  this.show_spell_img = false;  // modified by roundcube
-}
-
-GoogieSpell.prototype.setStateChanged = function(current_state) {
-  if(this.spelling_state_observer != null)
-    this.spelling_state_observer(current_state);
-}
-
-GoogieSpell.item_onmouseover = function(e) {
-  var elm = GoogieSpell.getEventElm(e);
-  if(elm.className != "googie_list_close" && elm.className != "googie_list_revert")
-    elm.className = "googie_list_onhover";
-  else
-    elm.parentNode.className = "googie_list_onhover";
-}
-
-GoogieSpell.item_onmouseout = function(e) {
-  var elm = GoogieSpell.getEventElm(e);
-  if(elm.className != "googie_list_close" && elm.className != "googie_list_revert")
-    elm.className = "googie_list_onout";
-  else
-    elm.parentNode.className = "googie_list_onout";
-}
-
-GoogieSpell.prototype.getGoogleUrl = function() {
-  return this.server_url + GOOGIE_CUR_LANG;
-}
-
-GoogieSpell.prototype.spellCheck = function(elm, name) {
-  this.ta_scroll_top = this.text_area.scrollTop;
-
-  this.appendIndicator(elm);
-
-  try {
-    this.hideLangWindow();
-  }
-  catch(e) {}
-  
-  this.gselm = elm;
-
-  this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
-
-  this.createErrorWindow();
-  AJS.getBody().appendChild(this.error_window);
-
-  try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 
-  catch (e) { }
-
-  this.gselm.onclick = null;
-
-  this.orginal_text = this.text_area.value;
-  var me = this;
-
-  //Create request
-  var d = AJS.getRequest(this.getGoogleUrl());
-  var reqdone = function(req) {
-    var r_text = req.responseText;
-    if(r_text.match(/<c.*>/) != null) {
-      var results = GoogieSpell.parseResult(r_text);
-      //Before parsing be sure that errors were found
-      me.results = results;
-      me.showErrorsInIframe(results);
-      me.resumeEditingState();
-    }
-    else {
-      me.flashNoSpellingErrorState();
-    }
-    me.removeIndicator();
-  };
-
-  var reqfailed = function(req) {
-    alert("An error was encountered on the server. Please try again later.");
-    AJS.removeElement(me.gselm);
-    me.checkSpellingState();
-    me.removeIndicator();
-  };
-  
-  d.addCallback(reqdone);
-  d.addErrback(reqfailed);
-
-  var req_text = GoogieSpell.escapeSepcial(this.orginal_text);
-  d.sendReq(GoogieSpell.createXMLReq(req_text));
-}
-
-GoogieSpell.escapeSepcial = function(val) {
-  return val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
-}
-
-GoogieSpell.createXMLReq = function (text) {
-  return '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' + text + '</text></spellrequest>';
-}
-
-//Retunrs an array
-//result[item] -> ['attrs']
-//                ['suggestions']
-GoogieSpell.parseResult = function(r_text) {
-  var re_split_attr_c = /\w="\d+"/g;
-  var re_split_text = /\t/g;
-
-  var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g);
-  var results = new Array();
-  
-  for(var i=0; i < matched_c.length; i++) {
-    var item = new Array();
-
-    //Get attributes
-    item['attrs'] = new Array();
-    var split_c = matched_c[i].match(re_split_attr_c);
-    for(var j=0; j < split_c.length; j++) {
-      var c_attr = split_c[j].split(/=/);
-      item['attrs'][c_attr[0]] = parseInt(c_attr[1].replace('"', ''));
-    }
-
-    //Get suggestions
-    item['suggestions'] = new Array();
-    var only_text = matched_c[i].replace(/<[^>]*>/g, "");
-    var split_t = only_text.split(re_split_text);
-    for(var k=0; k < split_t.length; k++) {
-    if(split_t[k] != "")
-      item['suggestions'].push(split_t[k]);
-    }
-    results.push(item);
-  }
-  return results;
-}
-
-/****
- Error window (the drop-down window)
-****/
-GoogieSpell.prototype.createErrorWindow = function() {
-  this.error_window = AJS.DIV();
-  this.error_window.className = "googie_window";
-}
-
-GoogieSpell.prototype.hideErrorWindow = function() {
-  this.error_window.style.visibility = "hidden";
+var AJS={getElement:function(id){
+if(typeof (id)=="string"){
+return document.getElementById(id);
+}else{
+return id;
+}
+},getElements:function(){
+var _2=new Array();
+for(var i=0;i<arguments.length;i++){
+var _4=this.getElement(arguments[i]);
+_2.push(_4);
+}
+return _2;
+},getQueryArgument:function(_5){
+var _6=window.location.search.substring(1);
+var _7=_6.split("&");
+for(var i=0;i<_7.length;i++){
+var _9=_7[i].split("=");
+if(_9[0]==_5){
+return _9[1];
+}
+}
+return null;
+},isIe:function(){
+return (navigator.userAgent.toLowerCase().indexOf("msie")!=-1&&navigator.userAgent.toLowerCase().indexOf("opera")==-1);
+},getBody:function(){
+return this.getElementsByTagAndClassName("body")[0];
+},getElementsByTagAndClassName:function(_a,_b,_c){
+var _d=new Array();
+if(!this.isDefined(_c)){
+_c=document;
+}
+if(!this.isDefined(_a)){
+_a="*";
+}
+var _e=_c.getElementsByTagName(_a);
+var _f=_e.length;
+var _10=new RegExp("(^|\\s)"+_b+"(\\s|$)");
+for(i=0,j=0;i<_f;i++){
+if(_10.test(_e[i].className)||_b==null){
+_d[j]=_e[i];
+j++;
+}
+}
+return _d;
+},appendChildNodes:function(_11){
+if(arguments.length>=2){
+for(var i=1;i<arguments.length;i++){
+var n=arguments[i];
+if(typeof (n)=="string"){
+n=document.createTextNode(n);
+}
+if(this.isDefined(n)){
+_11.appendChild(n);
+}
+}
+}
+return _11;
+},replaceChildNodes:function(_14){
+var _15;
+while((_15=_14.firstChild)){
+_14.removeChild(_15);
+}
+if(arguments.length<2){
+return _14;
+}else{
+return this.appendChildNodes.apply(this,arguments);
+}
+},insertAfter:function(_16,_17){
+_17.parentNode.insertBefore(_16,_17.nextSibling);
+},insertBefore:function(_18,_19){
+_19.parentNode.insertBefore(_18,_19);
+},showElement:function(elm){
+elm.style.display="";
+},hideElement:function(elm){
+elm.style.display="none";
+},isElementHidden:function(elm){
+return elm.style.visibility=="hidden";
+},swapDOM:function(_1d,src){
+_1d=this.getElement(_1d);
+var _1f=_1d.parentNode;
+if(src){
+src=this.getElement(src);
+_1f.replaceChild(src,_1d);
+}else{
+_1f.removeChild(_1d);
+}
+return src;
+},removeElement:function(elm){
+this.swapDOM(elm,null);
+},isDict:function(o){
+var _22=String(o);
+return _22.indexOf(" Object")!=-1;
+},createDOM:function(_23,_24){
+var i=0;
+elm=document.createElement(_23);
+if(this.isDict(_24[i])){
+for(k in _24[0]){
+if(k=="style"){
+elm.style.cssText=_24[0][k];
+}else{
+if(k=="class"){
+elm.className=_24[0][k];
+}else{
+elm.setAttribute(k,_24[0][k]);
+}
+}
+}
+i++;
+}
+if(_24[0]==null){
+i=1;
+}
+for(i;i<_24.length;i++){
+var n=_24[i];
+if(this.isDefined(n)){
+if(typeof (n)=="string"){
+n=document.createTextNode(n);
+}
+elm.appendChild(n);
+}
+}
+return elm;
+},UL:function(){
+return this.createDOM.apply(this,["ul",arguments]);
+},LI:function(){
+return this.createDOM.apply(this,["li",arguments]);
+},TD:function(){
+return this.createDOM.apply(this,["td",arguments]);
+},TR:function(){
+return this.createDOM.apply(this,["tr",arguments]);
+},TH:function(){
+return this.createDOM.apply(this,["th",arguments]);
+},TBODY:function(){
+return this.createDOM.apply(this,["tbody",arguments]);
+},TABLE:function(){
+return this.createDOM.apply(this,["table",arguments]);
+},INPUT:function(){
+return this.createDOM.apply(this,["input",arguments]);
+},SPAN:function(){
+return this.createDOM.apply(this,["span",arguments]);
+},B:function(){
+return this.createDOM.apply(this,["b",arguments]);
+},A:function(){
+return this.createDOM.apply(this,["a",arguments]);
+},DIV:function(){
+return this.createDOM.apply(this,["div",arguments]);
+},IMG:function(){
+return this.createDOM.apply(this,["img",arguments]);
+},BUTTON:function(){
+return this.createDOM.apply(this,["button",arguments]);
+},H1:function(){
+return this.createDOM.apply(this,["h1",arguments]);
+},H2:function(){
+return this.createDOM.apply(this,["h2",arguments]);
+},H3:function(){
+return this.createDOM.apply(this,["h3",arguments]);
+},BR:function(){
+return this.createDOM.apply(this,["br",arguments]);
+},TEXTAREA:function(){
+return this.createDOM.apply(this,["textarea",arguments]);
+},FORM:function(){
+return this.createDOM.apply(this,["form",arguments]);
+},P:function(){
+return this.createDOM.apply(this,["p",arguments]);
+},SELECT:function(){
+return this.createDOM.apply(this,["select",arguments]);
+},OPTION:function(){
+return this.createDOM.apply(this,["option",arguments]);
+},TN:function(_27){
+return document.createTextNode(_27);
+},IFRAME:function(){
+return this.createDOM.apply(this,["iframe",arguments]);
+},SCRIPT:function(){
+return this.createDOM.apply(this,["script",arguments]);
+},getXMLHttpRequest:function(){
+var _28=[function(){
+return new XMLHttpRequest();
+},function(){
+return new ActiveXObject("Msxml2.XMLHTTP");
+},function(){
+return new ActiveXObject("Microsoft.XMLHTTP");
+},function(){
+return new ActiveXObject("Msxml2.XMLHTTP.4.0");
+},function(){
+throw "Browser does not support XMLHttpRequest";
+}];
+for(var i=0;i<_28.length;i++){
+var _2a=_28[i];
+try{
+return _2a();
+}
+catch(e){
+}
+}
+},doSimpleXMLHttpRequest:function(url){
+var req=this.getXMLHttpRequest();
+req.open("GET",url,true);
+return this.sendXMLHttpRequest(req);
+},getRequest:function(url,_2e){
+var req=this.getXMLHttpRequest();
+req.open("POST",url,true);
+req.setRequestHeader("Content-type","application/x-www-form-urlencoded");
+return this.sendXMLHttpRequest(req);
+},sendXMLHttpRequest:function(req,_31){
+var d=new AJSDeferred(req);
+var _33=function(){
+if(req.readyState==4){
+try{
+var _34=req.status;
+}
+catch(e){
+}
+if(_34==200||_34==304||req.responseText==null){
+d.callback(req,_31);
+}else{
+d.errback();
 }
-
-GoogieSpell.prototype.updateOrginalText = function(offset, old_value, new_value, id) {
-  var part_1 = this.orginal_text.substring(0, offset);
-  var part_2 = this.orginal_text.substring(offset+old_value.length);
-  this.orginal_text = part_1 + new_value + part_2;
-  var add_2_offset = new_value.length - old_value.length;
-  for(var j=0; j < this.results.length; j++) {
-    //Don't edit the offset of the current item
-    if(j != id && j > id){
-      this.results[j]['attrs']['o'] += add_2_offset;
-    }
-  }
 }
-
-GoogieSpell.prototype.saveOldValue = function (id, old_value) {
-  this.results[id]['is_changed'] = true;
-  this.results[id]['old_value'] = old_value;
+};
+req.onreadystatechange=_33;
+return d;
+},reprString:function(o){
+return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
+},serializeJSON:function(o){
+var _37=typeof (o);
+if(_37=="undefined"){
+return "undefined";
+}else{
+if(_37=="number"||_37=="boolean"){
+return o+"";
+}else{
+if(o===null){
+return "null";
+}
+}
+}
+if(_37=="string"){
+return this.reprString(o);
+}
+var me=arguments.callee;
+var _39;
+if(typeof (o.__json__)=="function"){
+_39=o.__json__();
+if(o!==_39){
+return me(_39);
+}
+}
+if(typeof (o.json)=="function"){
+_39=o.json();
+if(o!==_39){
+return me(_39);
+}
+}
+if(_37!="function"&&typeof (o.length)=="number"){
+var res=[];
+for(var i=0;i<o.length;i++){
+var val=me(o[i]);
+if(typeof (val)!="string"){
+val="undefined";
+}
+res.push(val);
+}
+return "["+res.join(",")+"]";
+}
+res=[];
+for(var k in o){
+var _3e;
+if(typeof (k)=="number"){
+_3e="\""+k+"\"";
+}else{
+if(typeof (k)=="string"){
+_3e=this.reprString(k);
+}else{
+continue;
+}
+}
+val=me(o[k]);
+if(typeof (val)!="string"){
+continue;
+}
+res.push(_3e+":"+val);
+}
+return "{"+res.join(",")+"}";
+},loadJSONDoc:function(url){
+var d=this.getRequest(url);
+var _41=function(req){
+var _43=req.responseText;
+return eval("("+_43+")");
+};
+d.addCallback(_41);
+return d;
+},keys:function(obj){
+var _45=[];
+for(var _46 in obj){
+_45.push(_46);
+}
+return _45;
+},urlencode:function(str){
+return encodeURIComponent(str.toString());
+},isDefined:function(o){
+return (o!="undefined"&&o!=null);
+},isArray:function(obj){
+try{
+return (typeof (obj.length)=="undefined")?false:true;
+}
+catch(e){
+return false;
+}
+},isObject:function(obj){
+return (obj&&typeof obj=="object");
+},exportDOMElements:function(){
+UL=this.UL;
+LI=this.LI;
+TD=this.TD;
+TR=this.TR;
+TH=this.TH;
+TBODY=this.TBODY;
+TABLE=this.TABLE;
+INPUT=this.INPUT;
+SPAN=this.SPAN;
+B=this.B;
+A=this.A;
+DIV=this.DIV;
+IMG=this.IMG;
+BUTTON=this.BUTTON;
+H1=this.H1;
+H2=this.H2;
+H3=this.H3;
+BR=this.BR;
+TEXTAREA=this.TEXTAREA;
+FORM=this.FORM;
+P=this.P;
+SELECT=this.SELECT;
+OPTION=this.OPTION;
+TN=this.TN;
+IFRAME=this.IFRAME;
+SCRIPT=this.SCRIPT;
+},exportToGlobalScope:function(){
+getElement=this.getElement;
+getQueryArgument=this.getQueryArgument;
+isIe=this.isIe;
+$=this.getElement;
+getElements=this.getElements;
+getBody=this.getBody;
+getElementsByTagAndClassName=this.getElementsByTagAndClassName;
+appendChildNodes=this.appendChildNodes;
+ACN=appendChildNodes;
+replaceChildNodes=this.replaceChildNodes;
+RCN=replaceChildNodes;
+insertAfter=this.insertAfter;
+insertBefore=this.insertBefore;
+showElement=this.showElement;
+hideElement=this.hideElement;
+isElementHidden=this.isElementHidden;
+swapDOM=this.swapDOM;
+removeElement=this.removeElement;
+isDict=this.isDict;
+createDOM=this.createDOM;
+this.exportDOMElements();
+getXMLHttpRequest=this.getXMLHttpRequest;
+doSimpleXMLHttpRequest=this.doSimpleXMLHttpRequest;
+getRequest=this.getRequest;
+sendXMLHttpRequest=this.sendXMLHttpRequest;
+reprString=this.reprString;
+serializeJSON=this.serializeJSON;
+loadJSONDoc=this.loadJSONDoc;
+keys=this.keys;
+isDefined=this.isDefined;
+isArray=this.isArray;
+}};
+AJSDeferred=function(req){
+this.callbacks=[];
+this.req=req;
+this.callback=function(res){
+while(this.callbacks.length>0){
+var fn=this.callbacks.pop();
+res=fn(res);
 }
-
-GoogieSpell.prototype.showErrorWindow = function(elm, id) {
-  var me = this;
-
-  var abs_pos = GoogieSpell.absolutePosition(elm);
-  abs_pos.y -= this.edit_layer.scrollTop;
-  this.error_window.style.visibility = "visible";
-  this.error_window.style.top = (abs_pos.y+20) + "px";
-  this.error_window.style.left = (abs_pos.x) + "px";
-  this.error_window.innerHTML = "";
-
-  //Build up the result list
-  var table = AJS.TABLE({'class': 'googie_list'});
-  var list = AJS.TBODY();
-
-  var suggestions = this.results[id]['suggestions'];
-  var offset = this.results[id]['attrs']['o'];
-  var len = this.results[id]['attrs']['l'];
-
-  if(suggestions.length == 0) {
-    var row = AJS.TR();
-    var item = AJS.TD();
-    var dummy = AJS.SPAN();
-    item.appendChild(AJS.TN("No suggestions :("));
-    row.appendChild(item);
-    list.appendChild(row);
-  }
-
-  for(i=0; i < suggestions.length; i++) {
-    var row = AJS.TR();
-    var item = AJS.TD();
-    var dummy = AJS.SPAN();
-    dummy.innerHTML = suggestions[i];
-    item.appendChild(AJS.TN(dummy.innerHTML));
-    
-    item.onclick = function(e) {
-      var l_elm = GoogieSpell.getEventElm(e);
-      var old_value = elm.innerHTML;
-      var new_value = l_elm.innerHTML;
-
-      elm.style.color = "green";
-      elm.innerHTML = l_elm.innerHTML;
-      me.hideErrorWindow();
-
-      me.updateOrginalText(offset, old_value, new_value, id);
-
-      //Update to the new length
-      me.results[id]['attrs']['l'] = new_value.length;
-      me.saveOldValue(id, old_value);
-    };
-    item.onmouseover = GoogieSpell.item_onmouseover;
-    item.onmouseout = GoogieSpell.item_onmouseout;
-    row.appendChild(item);
-    list.appendChild(row);
-  }
-  
-  //The element is changed, append the revert
-  if(this.results[id]['is_changed']) {
-    var old_value = this.results[id]['old_value'];
-    var offset = this.results[id]['attrs']['o'];
-    var revert_row = AJS.TR();
-    var revert = AJS.TD();
-
-    revert.onmouseover = GoogieSpell.item_onmouseover;
-    revert.onmouseout = GoogieSpell.item_onmouseout;
-    var rev_span = AJS.SPAN({'class': 'googie_list_revert'});
-    rev_span.innerHTML = this.lang_revert + " " + old_value;
-    revert.appendChild(rev_span);
-
-    revert.onclick = function(e) { 
-      me.updateOrginalText(offset, elm.innerHTML, old_value, id);
-      elm.style.color = "#b91414";
-      elm.innerHTML = old_value;
-      me.hideErrorWindow();
-    };
-
-    revert_row.appendChild(revert);
-    list.appendChild(revert_row);
-  }
-
-  //Append the edit box
-  var edit_row = AJS.TR();
-  var edit = AJS.TD();
-
-  var edit_input = AJS.INPUT({'style': 'width: 120px; margin:0; padding:0'});
-
-  var onsub = function () {
-    if(edit_input.value != "") {
-      me.saveOldValue(id, elm.innerHTML);
-      me.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
-      elm.style.color = "green"
-      elm.innerHTML = edit_input.value;
-      
-      me.hideErrorWindow();
-      return false;
-    }
-  };
-  
-  var ok_pic = AJS.IMG({'src': this.img_dir + "ok.gif", 'style': 'width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;'});
-  var edit_form = AJS.FORM({'style': 'margin: 0; padding: 0'}, edit_input, ok_pic);
-  ok_pic.onclick = onsub;
-  edit_form.onsubmit = onsub;
-  
-  edit.appendChild(edit_form);
-  edit_row.appendChild(edit);
-  list.appendChild(edit_row);
-
-  //Close button
-  var close_row = AJS.TR();
-  var close = AJS.TD();
-
-  close.onmouseover = GoogieSpell.item_onmouseover;
-  close.onmouseout = GoogieSpell.item_onmouseout;
-
-  var spn_close = AJS.SPAN({'class': 'googie_list_close'});
-  spn_close.innerHTML = this.lang_close;
-  close.appendChild(spn_close);
-  close.onclick = function() { me.hideErrorWindow()};
-  close_row.appendChild(close);
-  list.appendChild(close_row);
-
-  table.appendChild(list);
-  this.error_window.appendChild(table);
+};
+this.errback=function(e){
+alert("Error encountered:\n"+e);
+};
+this.addErrback=function(fn){
+this.errback=fn;
+};
+this.addCallback=function(fn){
+this.callbacks.unshift(fn);
+};
+this.addCallbacks=function(fn1,fn2){
+this.addCallback(fn1);
+this.addErrback(fn2);
+};
+this.sendReq=function(_53){
+if(AJS.isObject(_53)){
+var _54=[];
+for(k in _53){
+_54.push(k+"="+AJS.urlencode(_53[k]));
 }
-
-
-/****
-  Edit layer (the layer where the suggestions are stored)
-****/
-GoogieSpell.prototype.createEditLayer = function(width, height) {
-  this.edit_layer = AJS.DIV({'class': 'googie_edit_layer'});
-  
-  //Set the style so it looks like edit areas
-  this.edit_layer.className = this.text_area.className;
-  this.edit_layer.style.border = "1px solid #999";
-  this.edit_layer.style.overflow = "auto";
-  this.edit_layer.style.backgroundColor = "#F1EDFE";
-  this.edit_layer.style.padding = "3px";
-
-  this.edit_layer.style.width = (width-8) + "px";
-  this.edit_layer.style.height = height + "px";
+_54=_54.join("&");
+this.req.send(_54);
+}else{
+if(AJS.isDefined(_53)){
+this.req.send(_53);
+}else{
+this.req.send("");
 }
-
-GoogieSpell.prototype.resumeEditing = function(e, me) {
-  this.setStateChanged("check_spelling");
-  me.switch_lan_pic.style.display = "inline";
-
-  this.el_scroll_top = me.edit_layer.scrollTop;
-
-  var elm = GoogieSpell.getEventElm(e);
-  AJS.replaceChildNodes(elm, this.createSpellDiv());
-
-  elm.onclick = function(e) {
-    me.spellCheck(elm, me.text_area.id);
-  };
-  me.hideErrorWindow();
-
-  //Remove the EDIT_LAYER
-  me.edit_layer.parentNode.removeChild(me.edit_layer);
-
-  me.text_area.value = me.orginal_text;
-  AJS.showElement(me.text_area);
-  me.gselm.className = "googie_no_style";
-
-  me.text_area.scrollTop = this.el_scroll_top;
-
-  elm.onmouseout = null;
 }
-
-GoogieSpell.prototype.createErrorLink = function(text, id) {
-  var elm = AJS.SPAN({'class': 'googie_link'});
-  var me = this;
-  elm.onclick = function () {
-    me.showErrorWindow(elm, id);
-  };
-  elm.innerHTML = text;
-  return elm;
+};
+};
+AJSDeferred.prototype=new AJSDeferred();
+var GOOGIE_CUR_LANG="en";
+function GoogieSpell(_55,_56){
+var _57;
+var _58;
+_57=getCookie("language");
+if(_57!=null){
+GOOGIE_CUR_LANG=_57;
+}
+this.img_dir=_55;
+this.server_url=_56;
+this.lang_to_word={"da":"Dansk","de":"Deutsch","en":"English","es":"Espa&#241;ol","fr":"Fran&#231;ais","it":"Italiano","nl":"Nederlands","pl":"Polski","pt":"Portugu&#234;s","fi":"Suomi","sv":"Svenska"};
+this.langlist_codes=AJS.keys(this.lang_to_word);
+this.show_change_lang_pic=true;
+this.lang_state_observer=null;
+this.spelling_state_observer=null;
+this.request=null;
+this.error_window=null;
+this.language_window=null;
+this.edit_layer=null;
+this.orginal_text=null;
+this.results=null;
+this.text_area=null;
+this.gselm=null;
+this.ta_scroll_top=0;
+this.el_scroll_top=0;
+this.lang_chck_spell="Check spelling";
+this.lang_rsm_edt="Resume editing";
+this.lang_close="Close";
+this.lang_no_error_found="No spelling errors found";
+this.lang_revert="Revert to";
+this.show_spell_img=false;
+};
+GoogieSpell.prototype.setStateChanged=function(_59){
+if(this.spelling_state_observer!=null){
+this.spelling_state_observer(_59);
 }
-
-GoogieSpell.createPart = function(txt_part) {
-  if(txt_part == " ")
-    return AJS.TN(" ");
-  var result = AJS.SPAN();
-
-  var is_first = true;
-  var is_safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1);
-
-  var part = AJS.SPAN();
-  txt_part = GoogieSpell.escapeSepcial(txt_part);
-  txt_part = txt_part.replace(/\n/g, "<br>");
-  txt_part = txt_part.replace(/  /g, " &nbsp;");
-  txt_part = txt_part.replace(/^ /g, "&nbsp;");
-  txt_part = txt_part.replace(/ $/g, "&nbsp;");
-  
-  part.innerHTML = txt_part;
-
-  return part;
+};
+GoogieSpell.item_onmouseover=function(e){
+var elm=GoogieSpell.getEventElm(e);
+if(elm.className!="googie_list_close"&&elm.className!="googie_list_revert"){
+elm.className="googie_list_onhover";
+}else{
+elm.parentNode.className="googie_list_onhover";
 }
-
-GoogieSpell.prototype.showErrorsInIframe = function(results) {
-  var output = AJS.DIV();
-  output.style.textAlign = "left";
-  var pointer = 0;
-  for(var i=0; i < results.length; i++) {
-    var offset = results[i]['attrs']['o'];
-    var len = results[i]['attrs']['l'];
-    
-    var part_1_text = this.orginal_text.substring(pointer, offset);
-    var part_1 = GoogieSpell.createPart(part_1_text);
-    output.appendChild(part_1);
-    pointer += offset - pointer;
-    
-    //If the last child was an error, then insert some space
-    output.appendChild(this.createErrorLink(this.orginal_text.substr(offset, len), i));
-    pointer += len;
-  }
-  //Insert the rest of the orginal text
-  var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length);
-
-  var part_2 = GoogieSpell.createPart(part_2_text);
-  output.appendChild(part_2);
-
-  this.edit_layer.appendChild(output);
-
-  //Hide text area
-  AJS.hideElement(this.text_area);
-  this.text_area.parentNode.insertBefore(this.edit_layer, this.text_area.nextSibling);
-  this.edit_layer.scrollTop = this.ta_scroll_top;
+};
+GoogieSpell.item_onmouseout=function(e){
+var elm=GoogieSpell.getEventElm(e);
+if(elm.className!="googie_list_close"&&elm.className!="googie_list_revert"){
+elm.className="googie_list_onout";
+}else{
+elm.parentNode.className="googie_list_onout";
 }
-
-GoogieSpell.Position = function(x, y) {
-  this.x = x;
-  this.y = y;
-}      
-
-//Get the absolute position of menu_slide
-GoogieSpell.absolutePosition = function(element) {
-  //Create a new object that has elements y and x pos...
-  var posObj = new GoogieSpell.Position(element.offsetLeft, element.offsetTop);
-
-  //Check if the element has an offsetParent - if it has .. loop until it has not
-  if(element.offsetParent) {
-    var temp_pos =     GoogieSpell.absolutePosition(element.offsetParent);
-    posObj.x += temp_pos.x;
-    posObj.y += temp_pos.y;
-  }
-  return posObj;
+};
+GoogieSpell.prototype.getGoogleUrl=function(){
+return this.server_url+GOOGIE_CUR_LANG;
+};
+GoogieSpell.prototype.spellCheck=function(elm,_5f){
+this.ta_scroll_top=this.text_area.scrollTop;
+this.appendIndicator(elm);
+try{
+this.hideLangWindow();
+}
+catch(e){
+}
+this.gselm=elm;
+this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight);
+this.createErrorWindow();
+AJS.getBody().appendChild(this.error_window);
+try{
+netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+}
+catch(e){
+}
+this.gselm.onclick=null;
+this.orginal_text=this.text_area.value;
+var me=this;
+var d=AJS.getRequest(this.getGoogleUrl());
+var _62=function(req){
+var _64=req.responseText;
+if(_64.match(/<c.*>/)!=null){
+var _65=GoogieSpell.parseResult(_64);
+me.results=_65;
+me.showErrorsInIframe(_65);
+me.resumeEditingState();
+}else{
+me.flashNoSpellingErrorState();
+}
+me.removeIndicator();
+};
+var _66=function(req){
+alert("An error was encountered on the server. Please try again later.");
+AJS.removeElement(me.gselm);
+me.checkSpellingState();
+me.removeIndicator();
+};
+d.addCallback(_62);
+d.addErrback(_66);
+var _68=GoogieSpell.escapeSepcial(this.orginal_text);
+d.sendReq(GoogieSpell.createXMLReq(_68));
+};
+GoogieSpell.escapeSepcial=function(val){
+return val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
+};
+GoogieSpell.createXMLReq=function(_6a){
+return "<?xml version=\"1.0\" encoding=\"utf-8\" ?><spellrequest textalreadyclipped=\"0\" ignoredups=\"0\" ignoredigits=\"1\" ignoreallcaps=\"1\"><text>"+_6a+"</text></spellrequest>";
+};
+GoogieSpell.parseResult=function(_6b){
+var _6c=/\w="\d+"/g;
+var _6d=/\t/g;
+var _6e=_6b.match(/<c[^>]*>[^<]*<\/c>/g);
+var _6f=new Array();
+for(var i=0;i<_6e.length;i++){
+var _71=new Array();
+_71["attrs"]=new Array();
+var _72=_6e[i].match(_6c);
+for(var j=0;j<_72.length;j++){
+var _74=_72[j].split(/=/);
+_71["attrs"][_74[0]]=parseInt(_74[1].replace("\"",""));
+}
+_71["suggestions"]=new Array();
+var _75=_6e[i].replace(/<[^>]*>/g,"");
+var _76=_75.split(_6d);
+for(var k=0;k<_76.length;k++){
+if(_76[k]!=""){
+_71["suggestions"].push(_76[k]);
+}
+}
+_6f.push(_71);
+}
+return _6f;
+};
+GoogieSpell.prototype.createErrorWindow=function(){
+this.error_window=AJS.DIV();
+this.error_window.className="googie_window";
+};
+GoogieSpell.prototype.hideErrorWindow=function(){
+this.error_window.style.visibility="hidden";
+};
+GoogieSpell.prototype.updateOrginalText=function(_78,_79,_7a,id){
+var _7c=this.orginal_text.substring(0,_78);
+var _7d=this.orginal_text.substring(_78+_79.length);
+this.orginal_text=_7c+_7a+_7d;
+var _7e=_7a.length-_79.length;
+for(var j=0;j<this.results.length;j++){
+if(j!=id&&j>id){
+this.results[j]["attrs"]["o"]+=_7e;
 }
-
-GoogieSpell.getEventElm = function(e) {
-       var targ;
-       if (!e) var e = window.event;
-       if (e.target) targ = e.target;
-       else if (e.srcElement) targ = e.srcElement;
-       if (targ.nodeType == 3) // defeat Safari bug
-               targ = targ.parentNode;
-  return targ;
 }
-
-GoogieSpell.prototype.removeIndicator = function(elm) {
-  // modified by roundcube
-  if (window.rcube_webmail_client)
-    rcube_webmail_client.set_busy(false);
-  //AJS.removeElement(this.indicator);
+};
+GoogieSpell.prototype.saveOldValue=function(id,_81){
+this.results[id]["is_changed"]=true;
+this.results[id]["old_value"]=_81;
+};
+GoogieSpell.prototype.showErrorWindow=function(elm,id){
+var me=this;
+var _85=GoogieSpell.absolutePosition(elm);
+_85.y-=this.edit_layer.scrollTop;
+this.error_window.style.visibility="visible";
+this.error_window.style.top=(_85.y+20)+"px";
+this.error_window.style.left=(_85.x)+"px";
+this.error_window.innerHTML="";
+var _86=AJS.TABLE({"class":"googie_list"});
+var _87=AJS.TBODY();
+var _88=this.results[id]["suggestions"];
+var _89=this.results[id]["attrs"]["o"];
+var len=this.results[id]["attrs"]["l"];
+if(_88.length==0){
+var row=AJS.TR();
+var _8c=AJS.TD();
+var _8d=AJS.SPAN();
+_8c.appendChild(AJS.TN("No suggestions :("));
+row.appendChild(_8c);
+_87.appendChild(row);
+}
+for(i=0;i<_88.length;i++){
+var row=AJS.TR();
+var _8c=AJS.TD();
+var _8d=AJS.SPAN();
+_8d.innerHTML=_88[i];
+_8c.appendChild(AJS.TN(_8d.innerHTML));
+_8c.onclick=function(e){
+var _8f=GoogieSpell.getEventElm(e);
+var _90=elm.innerHTML;
+var _91=_8f.innerHTML;
+elm.style.color="green";
+elm.innerHTML=_8f.innerHTML;
+me.hideErrorWindow();
+me.updateOrginalText(_89,_90,_91,id);
+me.results[id]["attrs"]["l"]=_91.length;
+me.saveOldValue(id,_90);
+};
+_8c.onmouseover=GoogieSpell.item_onmouseover;
+_8c.onmouseout=GoogieSpell.item_onmouseout;
+row.appendChild(_8c);
+_87.appendChild(row);
+}
+if(this.results[id]["is_changed"]){
+var _92=this.results[id]["old_value"];
+var _89=this.results[id]["attrs"]["o"];
+var _93=AJS.TR();
+var _94=AJS.TD();
+_94.onmouseover=GoogieSpell.item_onmouseover;
+_94.onmouseout=GoogieSpell.item_onmouseout;
+var _95=AJS.SPAN({"class":"googie_list_revert"});
+_95.innerHTML=this.lang_revert+" "+_92;
+_94.appendChild(_95);
+_94.onclick=function(e){
+me.updateOrginalText(_89,elm.innerHTML,_92,id);
+elm.style.color="#b91414";
+elm.innerHTML=_92;
+me.hideErrorWindow();
+};
+_93.appendChild(_94);
+_87.appendChild(_93);
+}
+var _97=AJS.TR();
+var _98=AJS.TD();
+var _99=AJS.INPUT({"style":"width: 120px; margin:0; padding:0"});
+var _9a=function(){
+if(_99.value!=""){
+me.saveOldValue(id,elm.innerHTML);
+me.updateOrginalText(_89,elm.innerHTML,_99.value,id);
+elm.style.color="green";
+elm.innerHTML=_99.value;
+me.hideErrorWindow();
+return false;
 }
-
-GoogieSpell.prototype.appendIndicator = function(elm) {
-  // modified by roundcube
-  if (window.rcube_webmail_client)
-    rcube_webmail_client.set_busy(true, 'checking');
-/*
-  var img = AJS.IMG({'src': this.img_dir + 'indicator.gif', 'style': 'margin-right: 5px;'});
-  img.style.width = "16px";
-  img.style.height = "16px";
-  this.indicator = img;
-  img.style.textDecoration = "none";
-  AJS.insertBefore(img, elm);
-  */
+};
+var _9b=AJS.IMG({"src":this.img_dir+"ok.gif","style":"width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;"});
+var _9c=AJS.FORM({"style":"margin: 0; padding: 0"},_99,_9b);
+_9b.onclick=_9a;
+_9c.onsubmit=_9a;
+_98.appendChild(_9c);
+_97.appendChild(_98);
+_87.appendChild(_97);
+var _9d=AJS.TR();
+var _9e=AJS.TD();
+_9e.onmouseover=GoogieSpell.item_onmouseover;
+_9e.onmouseout=GoogieSpell.item_onmouseout;
+var _9f=AJS.SPAN({"class":"googie_list_close"});
+_9f.innerHTML=this.lang_close;
+_9e.appendChild(_9f);
+_9e.onclick=function(){
+me.hideErrorWindow();
+};
+_9d.appendChild(_9e);
+_87.appendChild(_9d);
+_86.appendChild(_87);
+this.error_window.appendChild(_86);
+};
+GoogieSpell.prototype.createEditLayer=function(_a0,_a1){
+this.edit_layer=AJS.DIV({"class":"googie_edit_layer"});
+this.edit_layer.className=this.text_area.className;
+this.edit_layer.style.border="1px solid #999";
+this.edit_layer.style.overflow="auto";
+this.edit_layer.style.backgroundColor="#F1EDFE";
+this.edit_layer.style.padding="3px";
+this.edit_layer.style.width=(_a0-8)+"px";
+this.edit_layer.style.height=_a1+"px";
+};
+GoogieSpell.prototype.resumeEditing=function(e,me){
+this.setStateChanged("check_spelling");
+me.switch_lan_pic.style.display="inline";
+this.el_scroll_top=me.edit_layer.scrollTop;
+var elm=GoogieSpell.getEventElm(e);
+AJS.replaceChildNodes(elm,this.createSpellDiv());
+elm.onclick=function(e){
+me.spellCheck(elm,me.text_area.id);
+};
+me.hideErrorWindow();
+me.edit_layer.parentNode.removeChild(me.edit_layer);
+me.text_area.value=me.orginal_text;
+AJS.showElement(me.text_area);
+me.gselm.className="googie_no_style";
+me.text_area.scrollTop=this.el_scroll_top;
+elm.onmouseout=null;
+};
+GoogieSpell.prototype.createErrorLink=function(_a6,id){
+var elm=AJS.SPAN({"class":"googie_link"});
+var me=this;
+elm.onclick=function(){
+me.showErrorWindow(elm,id);
+};
+elm.innerHTML=_a6;
+return elm;
+};
+GoogieSpell.createPart=function(_aa){
+if(_aa==" "){
+return AJS.TN(" ");
+}
+var _ab=AJS.SPAN();
+var _ac=true;
+var _ad=(navigator.userAgent.toLowerCase().indexOf("safari")!=-1);
+var _ae=AJS.SPAN();
+_aa=GoogieSpell.escapeSepcial(_aa);
+_aa=_aa.replace(/\n/g,"<br>");
+_aa=_aa.replace(/  /g," &nbsp;");
+_aa=_aa.replace(/^ /g,"&nbsp;");
+_aa=_aa.replace(/ $/g,"&nbsp;");
+_ae.innerHTML=_aa;
+return _ae;
+};
+GoogieSpell.prototype.showErrorsInIframe=function(_af){
+var _b0=AJS.DIV();
+_b0.style.textAlign="left";
+var _b1=0;
+for(var i=0;i<_af.length;i++){
+var _b3=_af[i]["attrs"]["o"];
+var len=_af[i]["attrs"]["l"];
+var _b5=this.orginal_text.substring(_b1,_b3);
+var _b6=GoogieSpell.createPart(_b5);
+_b0.appendChild(_b6);
+_b1+=_b3-_b1;
+_b0.appendChild(this.createErrorLink(this.orginal_text.substr(_b3,len),i));
+_b1+=len;
+}
+var _b7=this.orginal_text.substr(_b1,this.orginal_text.length);
+var _b8=GoogieSpell.createPart(_b7);
+_b0.appendChild(_b8);
+this.edit_layer.appendChild(_b0);
+AJS.hideElement(this.text_area);
+this.text_area.parentNode.insertBefore(this.edit_layer,this.text_area.nextSibling);
+this.edit_layer.scrollTop=this.ta_scroll_top;
+};
+GoogieSpell.Position=function(x,y){
+this.x=x;
+this.y=y;
+};
+GoogieSpell.absolutePosition=function(_bb){
+var _bc=new GoogieSpell.Position(_bb.offsetLeft,_bb.offsetTop);
+if(_bb.offsetParent){
+var _bd=GoogieSpell.absolutePosition(_bb.offsetParent);
+_bc.x+=_bd.x;
+_bc.y+=_bd.y;
+}
+return _bc;
+};
+GoogieSpell.getEventElm=function(e){
+var _bf;
+if(!e){
+var e=window.event;
 }
-
-/****
- Choose language
-****/
-GoogieSpell.prototype.createLangWindow = function() {
-  this.language_window = AJS.DIV({'class': 'googie_window'});
-  this.language_window.style.width = "130px";
-
-  //Build up the result list
-  var table = AJS.TABLE({'class': 'googie_list'});
-  var list = AJS.TBODY();
-
-  this.lang_elms = new Array();
-
-  for(i=0; i < this.langlist_codes.length; i++) {
-    var row = AJS.TR();
-    var item = AJS.TD();
-    item.googieId = this.langlist_codes[i];
-    this.lang_elms.push(item);
-    var lang_span = AJS.SPAN();
-    lang_span.innerHTML = this.lang_to_word[this.langlist_codes[i]];
-    item.appendChild(AJS.TN(lang_span.innerHTML));
-
-    var me = this;
-    
-    item.onclick = function(e) {
-      var elm = GoogieSpell.getEventElm(e);
-      me.deHighlightCurSel();
-
-      me.setCurrentLanguage(elm.googieId);
-
-      if(me.lang_state_observer != null) {
-        me.lang_state_observer();
-      }
-
-      me.highlightCurSel();
-      me.hideLangWindow();
-    };
-
-    item.onmouseover = function(e) { 
-      var i_it = GoogieSpell.getEventElm(e);
-      if(i_it.className != "googie_list_selected")
-        i_it.className = "googie_list_onhover";
-    };
-    item.onmouseout = function(e) { 
-      var i_it = GoogieSpell.getEventElm(e);
-      if(i_it.className != "googie_list_selected")
-        i_it.className = "googie_list_onout"; 
-    };
-
-    row.appendChild(item);
-    list.appendChild(row);
-  }
-
-  this.highlightCurSel();
-
-  //Close button
-  var close_row = AJS.TR();
-  var close = AJS.TD();
-  close.onmouseover = GoogieSpell.item_onmouseover;
-  close.onmouseout = GoogieSpell.item_onmouseout;
-  var spn_close = AJS.SPAN({'class': 'googie_list_close'});
-  spn_close.innerHTML = this.lang_close;
-  close.appendChild(spn_close);
-  var me = this;
-  close.onclick = function(e) {
-    me.hideLangWindow(); GoogieSpell.item_onmouseout(e);
-  };
-  close_row.appendChild(close);
-  list.appendChild(close_row);
-
-  table.appendChild(list);
-  this.language_window.appendChild(table);
+if(e.target){
+_bf=e.target;
+}else{
+if(e.srcElement){
+_bf=e.srcElement;
 }
-
-GoogieSpell.prototype.setCurrentLanguage = function(lan_code) {
-  GOOGIE_CUR_LANG = lan_code;
-
-  //Set cookie
-  var now = new Date();
-  now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
-  setCookie('language', lan_code, now);
 }
-
-GoogieSpell.prototype.hideLangWindow = function() {
-  this.language_window.style.visibility = "hidden";
-  this.switch_lan_pic.className = "googie_lang_3d_on";
+if(_bf.nodeType==3){
+_bf=_bf.parentNode;
 }
-
-GoogieSpell.prototype.deHighlightCurSel = function() {
-  this.lang_cur_elm.className = "googie_list_onout";
+return _bf;
+};
+GoogieSpell.prototype.removeIndicator=function(elm){
+if(window.rcube_webmail_client){
+rcube_webmail_client.set_busy(false);
 }
-
-GoogieSpell.prototype.highlightCurSel = function() {
-  for(var i=0; i < this.lang_elms.length; i++) {
-    if(this.lang_elms[i].googieId == GOOGIE_CUR_LANG) {
-      this.lang_elms[i].className = "googie_list_selected";
-      this.lang_cur_elm = this.lang_elms[i];
-    }
-    else {
-      this.lang_elms[i].className = "googie_list_onout";
-    }
-  }
+};
+GoogieSpell.prototype.appendIndicator=function(elm){
+if(window.rcube_webmail_client){
+rcube_webmail_client.set_busy(true,"checking");
 }
-
-GoogieSpell.prototype.showLangWindow = function(elm, ofst_top, ofst_left) {
-  if(!AJS.isDefined(ofst_top))
-    ofst_top = 20;
-  if(!AJS.isDefined(ofst_left))
-    ofst_left = 50;
-
-  this.createLangWindow();
-  AJS.getBody().appendChild(this.language_window);
-
-  var abs_pos = GoogieSpell.absolutePosition(elm);
-  AJS.showElement(this.language_window);
-  this.language_window.style.top = (abs_pos.y+ofst_top) + "px";
-  this.language_window.style.left = (abs_pos.x+ofst_left-this.language_window.offsetWidth) + "px";
-  this.highlightCurSel();
-  this.language_window.style.visibility = "visible";
+};
+GoogieSpell.prototype.createLangWindow=function(){
+this.language_window=AJS.DIV({"class":"googie_window"});
+this.language_window.style.width="130px";
+var _c2=AJS.TABLE({"class":"googie_list"});
+var _c3=AJS.TBODY();
+this.lang_elms=new Array();
+for(i=0;i<this.langlist_codes.length;i++){
+var row=AJS.TR();
+var _c5=AJS.TD();
+_c5.googieId=this.langlist_codes[i];
+this.lang_elms.push(_c5);
+var _c6=AJS.SPAN();
+_c6.innerHTML=this.lang_to_word[this.langlist_codes[i]];
+_c5.appendChild(AJS.TN(_c6.innerHTML));
+var me=this;
+_c5.onclick=function(e){
+var elm=GoogieSpell.getEventElm(e);
+me.deHighlightCurSel();
+me.setCurrentLanguage(elm.googieId);
+if(me.lang_state_observer!=null){
+me.lang_state_observer();
+}
+me.highlightCurSel();
+me.hideLangWindow();
+};
+_c5.onmouseover=function(e){
+var _cb=GoogieSpell.getEventElm(e);
+if(_cb.className!="googie_list_selected"){
+_cb.className="googie_list_onhover";
 }
-
-GoogieSpell.prototype.flashNoSpellingErrorState = function() {
-  this.setStateChanged("no_error_found");
-  var me = this;
-  AJS.hideElement(this.switch_lan_pic);
-  this.gselm.innerHTML = this.lang_no_error_found;
-  this.gselm.className = "googie_check_spelling_ok";
-  this.gselm.style.textDecoration = "none";
-  this.gselm.style.cursor = "default";
-  var fu = function() {
-    AJS.removeElement(me.gselm);
-    me.checkSpellingState();
-  };
-  setTimeout(fu, 1000);
+};
+_c5.onmouseout=function(e){
+var _cd=GoogieSpell.getEventElm(e);
+if(_cd.className!="googie_list_selected"){
+_cd.className="googie_list_onout";
 }
-
-GoogieSpell.prototype.resumeEditingState = function() {
-  this.setStateChanged("resume_editing");
-  var me = this;
-  AJS.hideElement(me.switch_lan_pic);
-
-  //Change link text to resume
-  me.gselm.innerHTML = this.lang_rsm_edt;
-  me.gselm.onclick = function(e) {
-    me.resumeEditing(e, me);
-  }
-  me.gselm.className = "googie_check_spelling_ok";
-  me.edit_layer.scrollTop = me.ta_scroll_top;
+};
+row.appendChild(_c5);
+_c3.appendChild(row);
+}
+this.highlightCurSel();
+var _ce=AJS.TR();
+var _cf=AJS.TD();
+_cf.onmouseover=GoogieSpell.item_onmouseover;
+_cf.onmouseout=GoogieSpell.item_onmouseout;
+var _d0=AJS.SPAN({"class":"googie_list_close"});
+_d0.innerHTML=this.lang_close;
+_cf.appendChild(_d0);
+var me=this;
+_cf.onclick=function(e){
+me.hideLangWindow();
+GoogieSpell.item_onmouseout(e);
+};
+_ce.appendChild(_cf);
+_c3.appendChild(_ce);
+_c2.appendChild(_c3);
+this.language_window.appendChild(_c2);
+};
+GoogieSpell.prototype.setCurrentLanguage=function(_d2){
+GOOGIE_CUR_LANG=_d2;
+var now=new Date();
+now.setTime(now.getTime()+365*24*60*60*1000);
+setCookie("language",_d2,now);
+};
+GoogieSpell.prototype.hideLangWindow=function(){
+this.language_window.style.visibility="hidden";
+this.switch_lan_pic.className="googie_lang_3d_on";
+};
+GoogieSpell.prototype.deHighlightCurSel=function(){
+this.lang_cur_elm.className="googie_list_onout";
+};
+GoogieSpell.prototype.highlightCurSel=function(){
+for(var i=0;i<this.lang_elms.length;i++){
+if(this.lang_elms[i].googieId==GOOGIE_CUR_LANG){
+this.lang_elms[i].className="googie_list_selected";
+this.lang_cur_elm=this.lang_elms[i];
+}else{
+this.lang_elms[i].className="googie_list_onout";
 }
-
-GoogieSpell.prototype.createChangeLangPic = function() {
-  var switch_lan = AJS.A({'class': 'googie_lang_3d_on', 'style': 'padding-left: 6px;'}, AJS.IMG({'src': this.img_dir + 'change_lang.gif', 'alt': "Change language"}));
-  switch_lan.onmouseover = function() {
-    if(this.className != "googie_lang_3d_click")
-      this.className = "googie_lang_3d_on";
-  }
-
-  var me = this;
-  switch_lan.onclick = function() {
-    if(this.className == "googie_lang_3d_click") {
-      me.hideLangWindow();
-    }
-    else {
-      me.showLangWindow(switch_lan);
-      this.className = "googie_lang_3d_click";
-    }
-  }
-  return switch_lan;
 }
-
-GoogieSpell.prototype.createSpellDiv = function() {
-  var chk_spell = AJS.SPAN({'class': 'googie_check_spelling_link'});
-  chk_spell.innerHTML = this.lang_chck_spell;
-  var spell_img = null;
-  if(this.show_spell_img)
-    spell_img = AJS.IMG({'src': this.img_dir + "spellc.gif"});
-  return AJS.SPAN(spell_img, " ", chk_spell);
+};
+GoogieSpell.prototype.showLangWindow=function(elm,_d6,_d7){
+if(!AJS.isDefined(_d6)){
+_d6=20;
+}
+if(!AJS.isDefined(_d7)){
+_d7=50;
+}
+this.createLangWindow();
+AJS.getBody().appendChild(this.language_window);
+var _d8=GoogieSpell.absolutePosition(elm);
+AJS.showElement(this.language_window);
+this.language_window.style.top=(_d8.y+_d6)+"px";
+this.language_window.style.left=(_d8.x+_d7-this.language_window.offsetWidth)+"px";
+this.highlightCurSel();
+this.language_window.style.visibility="visible";
+};
+GoogieSpell.prototype.flashNoSpellingErrorState=function(){
+this.setStateChanged("no_error_found");
+var me=this;
+AJS.hideElement(this.switch_lan_pic);
+this.gselm.innerHTML=this.lang_no_error_found;
+this.gselm.className="googie_check_spelling_ok";
+this.gselm.style.textDecoration="none";
+this.gselm.style.cursor="default";
+var fu=function(){
+AJS.removeElement(me.gselm);
+me.checkSpellingState();
+};
+setTimeout(fu,1000);
+};
+GoogieSpell.prototype.resumeEditingState=function(){
+this.setStateChanged("resume_editing");
+var me=this;
+AJS.hideElement(me.switch_lan_pic);
+me.gselm.innerHTML=this.lang_rsm_edt;
+me.gselm.onclick=function(e){
+me.resumeEditing(e,me);
+};
+me.gselm.className="googie_check_spelling_ok";
+me.edit_layer.scrollTop=me.ta_scroll_top;
+};
+GoogieSpell.prototype.createChangeLangPic=function(){
+var _dd=AJS.A({"class":"googie_lang_3d_on","style":"padding-left: 6px;"},AJS.IMG({"src":this.img_dir+"change_lang.gif","alt":"Change language"}));
+_dd.onmouseover=function(){
+if(this.className!="googie_lang_3d_click"){
+this.className="googie_lang_3d_on";
 }
-
-GoogieSpell.prototype.checkSpellingState = function() {
-  this.setStateChanged("check_spelling");
-  var me = this;
-  if(this.show_change_lang_pic)
-    this.switch_lan_pic = this.createChangeLangPic();
-  else
-    this.switch_lan_pic = AJS.SPAN();
-
-  var span_chck = this.createSpellDiv();
-  span_chck.onclick = function() {
-    me.spellCheck(span_chck);
-  }
-  AJS.appendChildNodes(this.spell_container, span_chck, " ", this.switch_lan_pic);
-  // modified by roundcube
-  this.check_link = span_chck;
+};
+var me=this;
+_dd.onclick=function(){
+if(this.className=="googie_lang_3d_click"){
+me.hideLangWindow();
+}else{
+me.showLangWindow(_dd);
+this.className="googie_lang_3d_click";
 }
-
-GoogieSpell.prototype.setLanguages = function(lang_dict) {
-  this.lang_to_word = lang_dict;
-  this.langlist_codes = AJS.keys(lang_dict);
+};
+return _dd;
+};
+GoogieSpell.prototype.createSpellDiv=function(){
+var _df=AJS.SPAN({"class":"googie_check_spelling_link"});
+_df.innerHTML=this.lang_chck_spell;
+var _e0=null;
+if(this.show_spell_img){
+_e0=AJS.IMG({"src":this.img_dir+"spellc.gif"});
+}
+return AJS.SPAN(_e0," ",_df);
+};
+GoogieSpell.prototype.checkSpellingState=function(){
+this.setStateChanged("check_spelling");
+var me=this;
+if(this.show_change_lang_pic){
+this.switch_lan_pic=this.createChangeLangPic();
+}else{
+this.switch_lan_pic=AJS.SPAN();
+}
+var _e2=this.createSpellDiv();
+_e2.onclick=function(){
+me.spellCheck(_e2);
+};
+AJS.appendChildNodes(this.spell_container,_e2," ",this.switch_lan_pic);
+this.check_link=_e2;
+};
+GoogieSpell.prototype.setLanguages=function(_e3){
+this.lang_to_word=_e3;
+this.langlist_codes=AJS.keys(_e3);
+};
+GoogieSpell.prototype.decorateTextarea=function(id,_e5,_e6){
+var me=this;
+if(typeof (id)=="string"){
+this.text_area=AJS.getElement(id);
+}else{
+this.text_area=id;
+}
+var _e8;
+if(this.text_area!=null){
+if(AJS.isDefined(_e5)){
+if(typeof (_e5)=="string"){
+this.spell_container=AJS.getElement(_e5);
+}else{
+this.spell_container=_e5;
+}
+}else{
+var _e9=AJS.TABLE();
+var _ea=AJS.TBODY();
+var tr=AJS.TR();
+if(AJS.isDefined(_e6)){
+_e8=_e6;
+}else{
+_e8=this.text_area.offsetWidth+"px";
+}
+var _ec=AJS.TD();
+this.spell_container=_ec;
+tr.appendChild(_ec);
+_ea.appendChild(tr);
+_e9.appendChild(_ea);
+AJS.insertBefore(_e9,this.text_area);
+_e9.style.width="100%";
+_ec.style.width=_e8;
+_ec.style.textAlign="right";
+}
+this.checkSpellingState();
+}else{
+alert("Text area not found");
 }
+};
 
-GoogieSpell.prototype.decorateTextarea = function(id, /*optional*/spell_container_id, force_width) {
-  var me = this;
-
-  if(typeof(id) == "string")
-    this.text_area = AJS.getElement(id);
-  else
-    this.text_area = id;
-
-  var r_width;
-
-  if(this.text_area != null) {
-    if(AJS.isDefined(spell_container_id)) {
-      if(typeof(spell_container_id) == "string")
-        this.spell_container = AJS.getElement(spell_container_id);
-      else
-        this.spell_container = spell_container_id;
-    }
-    else {
-      var table = AJS.TABLE();
-      var tbody = AJS.TBODY();
-      var tr = AJS.TR();
-      if(AJS.isDefined(force_width)) {
-        r_width = force_width;
-      }
-      else {
-        r_width = this.text_area.offsetWidth + "px";
-      }
-
-      var spell_container = AJS.TD();
-      this.spell_container = spell_container;
-
-      tr.appendChild(spell_container);
-
-      tbody.appendChild(tr);
-      table.appendChild(tbody);
-
-      AJS.insertBefore(table, this.text_area);
-
-      //Set width
-      table.style.width = '100%';  // modified by roundcube (old: r_width)
-      spell_container.style.width = r_width;
-      spell_container.style.textAlign = "right";
-    }
-
-    this.checkSpellingState();
-  }
-  else {
-    alert("Text area not found");
-  }
-}
diff --git a/program/js/googiespell.js.src b/program/js/googiespell.js.src
new file mode 100644 (file)
index 0000000..8b9d1cc
--- /dev/null
@@ -0,0 +1,1308 @@
+/*
+Last Modified: 28/04/06 16:28:09
+
+  AmiJs library
+    A very small library with DOM and Ajax functions.
+    For a much larger script look on http://www.mochikit.com/
+  AUTHOR
+    4mir Salihefendic (http://amix.dk) - amix@amix.dk
+  LICENSE
+    Copyright (c) 2006 Amir Salihefendic. All rights reserved.
+    Copyright (c) 2005 Bob Ippolito. All rights reserved.
+    http://www.opensource.org/licenses/mit-license.php
+  VERSION
+    2.1
+  SITE
+    http://amix.dk/amijs
+**/
+
+var AJS = {
+////
+// Accessor functions
+////
+  /**
+   * @returns The element with the id
+   */
+  getElement: function(id) {
+    if(typeof(id) == "string") 
+      return document.getElementById(id);
+    else
+      return id;
+  },
+
+  /**
+   * @returns The elements with the ids
+   */
+  getElements: function(/*id1, id2, id3*/) {
+    var elements = new Array();
+      for (var i = 0; i < arguments.length; i++) {
+        var element = this.getElement(arguments[i]);
+        elements.push(element);
+      }
+      return elements;
+  },
+
+  /**
+   * @returns The GET query argument
+   */
+  getQueryArgument: function(var_name) {
+    var query = window.location.search.substring(1);
+    var vars = query.split("&");
+    for (var i=0;i<vars.length;i++) {
+      var pair = vars[i].split("=");
+      if (pair[0] == var_name) {
+        return pair[1];
+      }
+    }
+    return null;
+  },
+
+  /**
+   * @returns If the browser is Internet Explorer
+   */
+  isIe: function() {
+    return (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1);
+  },
+
+  /**
+   * @returns The document body   
+   */
+  getBody: function() {
+    return this.getElementsByTagAndClassName('body')[0] 
+  },
+
+  /**
+   * @returns All the elements that have a specific tag name or class name
+   */
+  getElementsByTagAndClassName: function(tag_name, class_name, /*optional*/ parent) {
+    var class_elements = new Array();
+    if(!this.isDefined(parent))
+      parent = document;
+    if(!this.isDefined(tag_name))
+      tag_name = '*';
+
+    var els = parent.getElementsByTagName(tag_name);
+    var els_len = els.length;
+    var pattern = new RegExp("(^|\\s)" + class_name + "(\\s|$)");
+
+    for (i = 0, j = 0; i < els_len; i++) {
+      if ( pattern.test(els[i].className) || class_name == null ) {
+        class_elements[j] = els[i];
+        j++;
+      }
+    }
+    return class_elements;
+  },
+
+
+////
+// DOM manipulation
+////
+  /**
+   * Appends some nodes to a node
+   */
+  appendChildNodes: function(node/*, nodes...*/) {
+    if(arguments.length >= 2) {
+      for(var i=1; i < arguments.length; i++) {
+        var n = arguments[i];
+        if(typeof(n) == "string")
+          n = document.createTextNode(n);
+        if(this.isDefined(n))
+          node.appendChild(n);
+      }
+    }
+    return node;
+  },
+
+  /**
+   * Replaces a nodes children with another node(s)
+   */
+  replaceChildNodes: function(node/*, nodes...*/) {
+    var child;
+    while ((child = node.firstChild)) {
+      node.removeChild(child);
+    }
+    if (arguments.length < 2) {
+      return node;
+    } else {
+      return this.appendChildNodes.apply(this, arguments);
+    }
+  },
+
+  /**
+   * Insert a node after another node
+   */
+  insertAfter: function(node, referenceNode) {
+    referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
+  },
+  
+  /**
+   * Insert a node before another node
+   */
+  insertBefore: function(node, referenceNode) {
+    referenceNode.parentNode.insertBefore(node, referenceNode);
+  },
+  
+  /**
+   * Shows the element
+   */
+  showElement: function(elm) {
+    elm.style.display = '';
+  },
+  
+  /**
+   * Hides the element
+   */
+  hideElement: function(elm) {
+    elm.style.display = 'none';
+  },
+
+  isElementHidden: function(elm) {
+    return elm.style.visibility == "hidden";
+  },
+  
+  /**
+   * Swaps one element with another. To delete use swapDOM(elm, null)
+   */
+  swapDOM: function(dest, src) {
+    dest = this.getElement(dest);
+    var parent = dest.parentNode;
+    if (src) {
+      src = this.getElement(src);
+      parent.replaceChild(src, dest);
+    } else {
+      parent.removeChild(dest);
+    }
+    return src;
+  },
+
+  /**
+   * Removes an element from the world
+   */
+  removeElement: function(elm) {
+    this.swapDOM(elm, null);
+  },
+
+  /**
+   * @returns Is an object a dictionary?
+   */
+  isDict: function(o) {
+    var str_repr = String(o);
+    return str_repr.indexOf(" Object") != -1;
+  },
+  
+  /**
+   * Creates a DOM element
+   * @param {String} name The elements DOM name
+   * @param {Dict} attrs Attributes sent to the function
+   */
+  createDOM: function(name, attrs) {
+    var i=0;
+    elm = document.createElement(name);
+
+    if(this.isDict(attrs[i])) {
+      for(k in attrs[0]) {
+        if(k == "style")
+          elm.style.cssText = attrs[0][k];
+        else if(k == "class")
+          elm.className = attrs[0][k];
+        else
+          elm.setAttribute(k, attrs[0][k]);
+      }
+      i++;
+    }
+
+    if(attrs[0] == null)
+      i = 1;
+
+    for(i; i < attrs.length; i++) {
+      var n = attrs[i];
+      if(this.isDefined(n)) {
+        if(typeof(n) == "string")
+          n = document.createTextNode(n);
+        elm.appendChild(n);
+      }
+    }
+    return elm;
+  },
+
+  UL: function() { return this.createDOM.apply(this, ["ul", arguments]); },
+  LI: function() { return this.createDOM.apply(this, ["li", arguments]); },
+  TD: function() { return this.createDOM.apply(this, ["td", arguments]); },
+  TR: function() { return this.createDOM.apply(this, ["tr", arguments]); },
+  TH: function() { return this.createDOM.apply(this, ["th", arguments]); },
+  TBODY: function() { return this.createDOM.apply(this, ["tbody", arguments]); },
+  TABLE: function() { return this.createDOM.apply(this, ["table", arguments]); },
+  INPUT: function() { return this.createDOM.apply(this, ["input", arguments]); },
+  SPAN: function() { return this.createDOM.apply(this, ["span", arguments]); },
+  B: function() { return this.createDOM.apply(this, ["b", arguments]); },
+  A: function() { return this.createDOM.apply(this, ["a", arguments]); },
+  DIV: function() { return this.createDOM.apply(this, ["div", arguments]); },
+  IMG: function() { return this.createDOM.apply(this, ["img", arguments]); },
+  BUTTON: function() { return this.createDOM.apply(this, ["button", arguments]); },
+  H1: function() { return this.createDOM.apply(this, ["h1", arguments]); },
+  H2: function() { return this.createDOM.apply(this, ["h2", arguments]); },
+  H3: function() { return this.createDOM.apply(this, ["h3", arguments]); },
+  BR: function() { return this.createDOM.apply(this, ["br", arguments]); },
+  TEXTAREA: function() { return this.createDOM.apply(this, ["textarea", arguments]); },
+  FORM: function() { return this.createDOM.apply(this, ["form", arguments]); },
+  P: function() { return this.createDOM.apply(this, ["p", arguments]); },
+  SELECT: function() { return this.createDOM.apply(this, ["select", arguments]); },
+  OPTION: function() { return this.createDOM.apply(this, ["option", arguments]); },
+  TN: function(text) { return document.createTextNode(text); },
+  IFRAME: function() { return this.createDOM.apply(this, ["iframe", arguments]); },
+  SCRIPT: function() { return this.createDOM.apply(this, ["script", arguments]); },
+
+////
+// Ajax functions
+////
+  /**
+   * @returns A new XMLHttpRequest object 
+   */
+  getXMLHttpRequest: function() {
+    var try_these = [
+      function () { return new XMLHttpRequest(); },
+      function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
+      function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
+      function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
+      function () { throw "Browser does not support XMLHttpRequest"; }
+    ];
+    for (var i = 0; i < try_these.length; i++) {
+      var func = try_these[i];
+      try {
+        return func();
+      } catch (e) {
+      }
+    }
+  },
+  
+  /**
+   * Use this function to do a simple HTTP Request
+   */
+  doSimpleXMLHttpRequest: function(url) {
+    var req = this.getXMLHttpRequest();
+    req.open("GET", url, true);
+    return this.sendXMLHttpRequest(req);
+  },
+
+  getRequest: function(url, data) {
+    var req = this.getXMLHttpRequest();
+    req.open("POST", url, true);
+    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+    return this.sendXMLHttpRequest(req);
+  },
+
+  /**
+   * Send a XMLHttpRequest
+   */
+  sendXMLHttpRequest: function(req, data) {
+    var d = new AJSDeferred(req);
+
+    var onreadystatechange = function () {
+      if (req.readyState == 4) {
+        try {
+          var status = req.status;
+        }
+        catch(e) {};
+        if(status == 200 || status == 304 || req.responseText == null) {
+          d.callback(req, data);
+        }
+        else {
+          d.errback();
+        }
+      }
+    }
+    req.onreadystatechange = onreadystatechange;
+    return d;
+  },
+  
+  /**
+   * Represent an object as a string
+   */
+  reprString: function(o) {
+    return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+    ).replace(/[\f]/g, "\\f"
+    ).replace(/[\b]/g, "\\b"
+    ).replace(/[\n]/g, "\\n"
+    ).replace(/[\t]/g, "\\t"
+    ).replace(/[\r]/g, "\\r");
+  },
+  
+  /**
+   * Serialize an object to JSON notation
+   */
+  serializeJSON: function(o) {
+    var objtype = typeof(o);
+    if (objtype == "undefined") {
+      return "undefined";
+    } else if (objtype == "number" || objtype == "boolean") {
+      return o + "";
+    } else if (o === null) {
+      return "null";
+    }
+    if (objtype == "string") {
+      return this.reprString(o);
+    }
+    var me = arguments.callee;
+    var newObj;
+    if (typeof(o.__json__) == "function") {
+      newObj = o.__json__();
+      if (o !== newObj) {
+        return me(newObj);
+      }
+    }
+    if (typeof(o.json) == "function") {
+      newObj = o.json();
+      if (o !== newObj) {
+        return me(newObj);
+      }
+    }
+    if (objtype != "function" && typeof(o.length) == "number") {
+      var res = [];
+      for (var i = 0; i < o.length; i++) {
+        var val = me(o[i]);
+        if (typeof(val) != "string") {
+          val = "undefined";
+        }
+        res.push(val);
+      }
+      return "[" + res.join(",") + "]";
+    }
+    res = [];
+    for (var k in o) {
+      var useKey;
+      if (typeof(k) == "number") {
+        useKey = '"' + k + '"';
+      } else if (typeof(k) == "string") {
+        useKey = this.reprString(k);
+      } else {
+        // skip non-string or number keys
+        continue;
+      }
+      val = me(o[k]);
+      if (typeof(val) != "string") {
+        // skip non-serializable values
+        continue;
+      }
+      res.push(useKey + ":" + val);
+    }
+    return "{" + res.join(",") + "}";
+  },
+
+  /**
+   * Send and recive JSON using GET
+   */
+  loadJSONDoc: function(url) {
+    var d = this.getRequest(url);
+    var eval_req = function(req) {
+      var text = req.responseText;
+      return eval('(' + text + ')');
+    };
+    d.addCallback(eval_req);
+    return d;
+  },
+  
+  
+////
+// Misc.
+////
+  /**
+   * Alert the objects key attrs 
+   */
+  keys: function(obj) {
+    var rval = [];
+    for (var prop in obj) {
+      rval.push(prop);
+    }
+    return rval;
+  },
+
+  urlencode: function(str) {
+    return encodeURIComponent(str.toString());
+  },
+
+  /**
+   * @returns True if the object is defined, otherwise false
+   */
+  isDefined: function(o) {
+    return (o != "undefined" && o != null)
+  },
+  
+  /**
+   * @returns True if an object is a array, false otherwise
+   */
+  isArray: function(obj) {
+    try { return (typeof(obj.length) == "undefined") ? false : true; }
+    catch(e)
+    { return false; }
+  },
+
+  isObject: function(obj) {
+    return (obj && typeof obj == 'object');
+  },
+
+  /**
+   * Export DOM elements to the global namespace
+   */
+  exportDOMElements: function() {
+    UL = this.UL;
+    LI = this.LI;
+    TD = this.TD;
+    TR = this.TR;
+    TH = this.TH;
+    TBODY = this.TBODY;
+    TABLE = this.TABLE;
+    INPUT = this.INPUT;
+    SPAN = this.SPAN;
+    B = this.B;
+    A = this.A;
+    DIV = this.DIV;
+    IMG = this.IMG;
+    BUTTON = this.BUTTON;
+    H1 = this.H1;
+    H2 = this.H2;
+    H3 = this.H3;
+    BR = this.BR;
+    TEXTAREA = this.TEXTAREA;
+    FORM = this.FORM;
+    P = this.P;
+    SELECT = this.SELECT;
+    OPTION = this.OPTION;
+    TN = this.TN;
+    IFRAME = this.IFRAME;
+    SCRIPT = this.SCRIPT;
+  },
+
+  /**
+   * Export AmiJS functions to the global namespace
+   */
+  exportToGlobalScope: function() {
+    getElement = this.getElement;
+    getQueryArgument = this.getQueryArgument;
+    isIe = this.isIe;
+    $ = this.getElement;
+    getElements = this.getElements;
+    getBody = this.getBody;
+    getElementsByTagAndClassName = this.getElementsByTagAndClassName;
+    appendChildNodes = this.appendChildNodes;
+    ACN = appendChildNodes;
+    replaceChildNodes = this.replaceChildNodes;
+    RCN = replaceChildNodes;
+    insertAfter = this.insertAfter;
+    insertBefore = this.insertBefore;
+    showElement = this.showElement;
+    hideElement = this.hideElement;
+    isElementHidden = this.isElementHidden;
+    swapDOM = this.swapDOM;
+    removeElement = this.removeElement;
+    isDict = this.isDict;
+    createDOM = this.createDOM;
+    this.exportDOMElements();
+    getXMLHttpRequest = this.getXMLHttpRequest;
+    doSimpleXMLHttpRequest = this.doSimpleXMLHttpRequest;
+    getRequest = this.getRequest;
+    sendXMLHttpRequest = this.sendXMLHttpRequest;
+    reprString = this.reprString;
+    serializeJSON = this.serializeJSON;
+    loadJSONDoc = this.loadJSONDoc;
+    keys = this.keys;
+    isDefined = this.isDefined;
+    isArray = this.isArray;
+  }
+}
+
+
+
+AJSDeferred = function(req) {
+  this.callbacks = [];
+  this.req = req;
+
+  this.callback = function (res) {
+    while (this.callbacks.length > 0) {
+      var fn = this.callbacks.pop();
+      res = fn(res);
+    }
+  };
+
+  this.errback = function(e){
+    alert("Error encountered:\n" + e);
+  };
+
+  this.addErrback = function(fn) {
+    this.errback = fn;
+  };
+
+  this.addCallback = function(fn) {
+    this.callbacks.unshift(fn);
+  };
+
+  this.addCallbacks = function(fn1, fn2) {
+    this.addCallback(fn1);
+    this.addErrback(fn2);
+  };
+
+  this.sendReq = function(data) {
+    if(AJS.isObject(data)) {
+      var post_data = [];
+      for(k in data) {
+        post_data.push(k + "=" + AJS.urlencode(data[k]));
+      }
+      post_data = post_data.join("&");
+      this.req.send(post_data);
+    }
+    else if(AJS.isDefined(data))
+      this.req.send(data);
+    else {
+      this.req.send("");
+    }
+  };
+};
+AJSDeferred.prototype = new AJSDeferred();
+
+
+
+
+
+
+/****
+Last Modified: 28/04/06 15:26:06
+
+ GoogieSpell
+   Google spell checker for your own web-apps :)
+   Copyright Amir Salihefendic 2006
+ LICENSE
+  GPL (see gpl.txt for more information)
+  This basically means that you can't use this script with/in proprietary software!
+  There is another license that permits you to use this script with proprietary software. Check out:... for more info.
+  AUTHOR
+   4mir Salihefendic (http://amix.dk) - amix@amix.dk
+ VERSION
+        3.22
+****/
+var GOOGIE_CUR_LANG = "en";
+
+function GoogieSpell(img_dir, server_url) {
+  var cookie_value;
+  var lang;
+  cookie_value = getCookie('language');
+
+  if(cookie_value != null)
+    GOOGIE_CUR_LANG = cookie_value;
+
+  this.img_dir = img_dir;
+  this.server_url = server_url;
+
+  this.lang_to_word = {"da": "Dansk", "de": "Deutsch", "en": "English",
+                       "es": "Espa&#241;ol", "fr": "Fran&#231;ais", "it": "Italiano", 
+                       "nl": "Nederlands", "pl": "Polski", "pt": "Portugu&#234;s",
+                       "fi": "Suomi", "sv": "Svenska"};
+  this.langlist_codes = AJS.keys(this.lang_to_word);
+
+  this.show_change_lang_pic = true;
+
+  this.lang_state_observer = null;
+
+  this.spelling_state_observer = null;
+
+  this.request = null;
+  this.error_window = null;
+  this.language_window = null;
+  this.edit_layer = null;
+  this.orginal_text = null;
+  this.results = null;
+  this.text_area = null;
+  this.gselm = null;
+  this.ta_scroll_top = 0;
+  this.el_scroll_top = 0;
+
+  this.lang_chck_spell = "Check spelling";
+  this.lang_rsm_edt = "Resume editing";
+  this.lang_close = "Close";
+  this.lang_no_error_found = "No spelling errors found";
+  this.lang_revert = "Revert to";
+  this.show_spell_img = false;  // modified by roundcube
+}
+
+GoogieSpell.prototype.setStateChanged = function(current_state) {
+  if(this.spelling_state_observer != null)
+    this.spelling_state_observer(current_state);
+}
+
+GoogieSpell.item_onmouseover = function(e) {
+  var elm = GoogieSpell.getEventElm(e);
+  if(elm.className != "googie_list_close" && elm.className != "googie_list_revert")
+    elm.className = "googie_list_onhover";
+  else
+    elm.parentNode.className = "googie_list_onhover";
+}
+
+GoogieSpell.item_onmouseout = function(e) {
+  var elm = GoogieSpell.getEventElm(e);
+  if(elm.className != "googie_list_close" && elm.className != "googie_list_revert")
+    elm.className = "googie_list_onout";
+  else
+    elm.parentNode.className = "googie_list_onout";
+}
+
+GoogieSpell.prototype.getGoogleUrl = function() {
+  return this.server_url + GOOGIE_CUR_LANG;
+}
+
+GoogieSpell.prototype.spellCheck = function(elm, name) {
+  this.ta_scroll_top = this.text_area.scrollTop;
+
+  this.appendIndicator(elm);
+
+  try {
+    this.hideLangWindow();
+  }
+  catch(e) {}
+  
+  this.gselm = elm;
+
+  this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
+
+  this.createErrorWindow();
+  AJS.getBody().appendChild(this.error_window);
+
+  try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 
+  catch (e) { }
+
+  this.gselm.onclick = null;
+
+  this.orginal_text = this.text_area.value;
+  var me = this;
+
+  //Create request
+  var d = AJS.getRequest(this.getGoogleUrl());
+  var reqdone = function(req) {
+    var r_text = req.responseText;
+    if(r_text.match(/<c.*>/) != null) {
+      var results = GoogieSpell.parseResult(r_text);
+      //Before parsing be sure that errors were found
+      me.results = results;
+      me.showErrorsInIframe(results);
+      me.resumeEditingState();
+    }
+    else {
+      me.flashNoSpellingErrorState();
+    }
+    me.removeIndicator();
+  };
+
+  var reqfailed = function(req) {
+    alert("An error was encountered on the server. Please try again later.");
+    AJS.removeElement(me.gselm);
+    me.checkSpellingState();
+    me.removeIndicator();
+  };
+  
+  d.addCallback(reqdone);
+  d.addErrback(reqfailed);
+
+  var req_text = GoogieSpell.escapeSepcial(this.orginal_text);
+  d.sendReq(GoogieSpell.createXMLReq(req_text));
+}
+
+GoogieSpell.escapeSepcial = function(val) {
+  return val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
+}
+
+GoogieSpell.createXMLReq = function (text) {
+  return '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' + text + '</text></spellrequest>';
+}
+
+//Retunrs an array
+//result[item] -> ['attrs']
+//                ['suggestions']
+GoogieSpell.parseResult = function(r_text) {
+  var re_split_attr_c = /\w="\d+"/g;
+  var re_split_text = /\t/g;
+
+  var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g);
+  var results = new Array();
+  
+  for(var i=0; i < matched_c.length; i++) {
+    var item = new Array();
+
+    //Get attributes
+    item['attrs'] = new Array();
+    var split_c = matched_c[i].match(re_split_attr_c);
+    for(var j=0; j < split_c.length; j++) {
+      var c_attr = split_c[j].split(/=/);
+      item['attrs'][c_attr[0]] = parseInt(c_attr[1].replace('"', ''));
+    }
+
+    //Get suggestions
+    item['suggestions'] = new Array();
+    var only_text = matched_c[i].replace(/<[^>]*>/g, "");
+    var split_t = only_text.split(re_split_text);
+    for(var k=0; k < split_t.length; k++) {
+    if(split_t[k] != "")
+      item['suggestions'].push(split_t[k]);
+    }
+    results.push(item);
+  }
+  return results;
+}
+
+/****
+ Error window (the drop-down window)
+****/
+GoogieSpell.prototype.createErrorWindow = function() {
+  this.error_window = AJS.DIV();
+  this.error_window.className = "googie_window";
+}
+
+GoogieSpell.prototype.hideErrorWindow = function() {
+  this.error_window.style.visibility = "hidden";
+}
+
+GoogieSpell.prototype.updateOrginalText = function(offset, old_value, new_value, id) {
+  var part_1 = this.orginal_text.substring(0, offset);
+  var part_2 = this.orginal_text.substring(offset+old_value.length);
+  this.orginal_text = part_1 + new_value + part_2;
+  var add_2_offset = new_value.length - old_value.length;
+  for(var j=0; j < this.results.length; j++) {
+    //Don't edit the offset of the current item
+    if(j != id && j > id){
+      this.results[j]['attrs']['o'] += add_2_offset;
+    }
+  }
+}
+
+GoogieSpell.prototype.saveOldValue = function (id, old_value) {
+  this.results[id]['is_changed'] = true;
+  this.results[id]['old_value'] = old_value;
+}
+
+GoogieSpell.prototype.showErrorWindow = function(elm, id) {
+  var me = this;
+
+  var abs_pos = GoogieSpell.absolutePosition(elm);
+  abs_pos.y -= this.edit_layer.scrollTop;
+  this.error_window.style.visibility = "visible";
+  this.error_window.style.top = (abs_pos.y+20) + "px";
+  this.error_window.style.left = (abs_pos.x) + "px";
+  this.error_window.innerHTML = "";
+
+  //Build up the result list
+  var table = AJS.TABLE({'class': 'googie_list'});
+  var list = AJS.TBODY();
+
+  var suggestions = this.results[id]['suggestions'];
+  var offset = this.results[id]['attrs']['o'];
+  var len = this.results[id]['attrs']['l'];
+
+  if(suggestions.length == 0) {
+    var row = AJS.TR();
+    var item = AJS.TD();
+    var dummy = AJS.SPAN();
+    item.appendChild(AJS.TN("No suggestions :("));
+    row.appendChild(item);
+    list.appendChild(row);
+  }
+
+  for(i=0; i < suggestions.length; i++) {
+    var row = AJS.TR();
+    var item = AJS.TD();
+    var dummy = AJS.SPAN();
+    dummy.innerHTML = suggestions[i];
+    item.appendChild(AJS.TN(dummy.innerHTML));
+    
+    item.onclick = function(e) {
+      var l_elm = GoogieSpell.getEventElm(e);
+      var old_value = elm.innerHTML;
+      var new_value = l_elm.innerHTML;
+
+      elm.style.color = "green";
+      elm.innerHTML = l_elm.innerHTML;
+      me.hideErrorWindow();
+
+      me.updateOrginalText(offset, old_value, new_value, id);
+
+      //Update to the new length
+      me.results[id]['attrs']['l'] = new_value.length;
+      me.saveOldValue(id, old_value);
+    };
+    item.onmouseover = GoogieSpell.item_onmouseover;
+    item.onmouseout = GoogieSpell.item_onmouseout;
+    row.appendChild(item);
+    list.appendChild(row);
+  }
+  
+  //The element is changed, append the revert
+  if(this.results[id]['is_changed']) {
+    var old_value = this.results[id]['old_value'];
+    var offset = this.results[id]['attrs']['o'];
+    var revert_row = AJS.TR();
+    var revert = AJS.TD();
+
+    revert.onmouseover = GoogieSpell.item_onmouseover;
+    revert.onmouseout = GoogieSpell.item_onmouseout;
+    var rev_span = AJS.SPAN({'class': 'googie_list_revert'});
+    rev_span.innerHTML = this.lang_revert + " " + old_value;
+    revert.appendChild(rev_span);
+
+    revert.onclick = function(e) { 
+      me.updateOrginalText(offset, elm.innerHTML, old_value, id);
+      elm.style.color = "#b91414";
+      elm.innerHTML = old_value;
+      me.hideErrorWindow();
+    };
+
+    revert_row.appendChild(revert);
+    list.appendChild(revert_row);
+  }
+
+  //Append the edit box
+  var edit_row = AJS.TR();
+  var edit = AJS.TD();
+
+  var edit_input = AJS.INPUT({'style': 'width: 120px; margin:0; padding:0'});
+
+  var onsub = function () {
+    if(edit_input.value != "") {
+      me.saveOldValue(id, elm.innerHTML);
+      me.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
+      elm.style.color = "green"
+      elm.innerHTML = edit_input.value;
+      
+      me.hideErrorWindow();
+      return false;
+    }
+  };
+  
+  var ok_pic = AJS.IMG({'src': this.img_dir + "ok.gif", 'style': 'width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;'});
+  var edit_form = AJS.FORM({'style': 'margin: 0; padding: 0'}, edit_input, ok_pic);
+  ok_pic.onclick = onsub;
+  edit_form.onsubmit = onsub;
+  
+  edit.appendChild(edit_form);
+  edit_row.appendChild(edit);
+  list.appendChild(edit_row);
+
+  //Close button
+  var close_row = AJS.TR();
+  var close = AJS.TD();
+
+  close.onmouseover = GoogieSpell.item_onmouseover;
+  close.onmouseout = GoogieSpell.item_onmouseout;
+
+  var spn_close = AJS.SPAN({'class': 'googie_list_close'});
+  spn_close.innerHTML = this.lang_close;
+  close.appendChild(spn_close);
+  close.onclick = function() { me.hideErrorWindow()};
+  close_row.appendChild(close);
+  list.appendChild(close_row);
+
+  table.appendChild(list);
+  this.error_window.appendChild(table);
+}
+
+
+/****
+  Edit layer (the layer where the suggestions are stored)
+****/
+GoogieSpell.prototype.createEditLayer = function(width, height) {
+  this.edit_layer = AJS.DIV({'class': 'googie_edit_layer'});
+  
+  //Set the style so it looks like edit areas
+  this.edit_layer.className = this.text_area.className;
+  this.edit_layer.style.border = "1px solid #999";
+  this.edit_layer.style.overflow = "auto";
+  this.edit_layer.style.backgroundColor = "#F1EDFE";
+  this.edit_layer.style.padding = "3px";
+
+  this.edit_layer.style.width = (width-8) + "px";
+  this.edit_layer.style.height = height + "px";
+}
+
+GoogieSpell.prototype.resumeEditing = function(e, me) {
+  this.setStateChanged("check_spelling");
+  me.switch_lan_pic.style.display = "inline";
+
+  this.el_scroll_top = me.edit_layer.scrollTop;
+
+  var elm = GoogieSpell.getEventElm(e);
+  AJS.replaceChildNodes(elm, this.createSpellDiv());
+
+  elm.onclick = function(e) {
+    me.spellCheck(elm, me.text_area.id);
+  };
+  me.hideErrorWindow();
+
+  //Remove the EDIT_LAYER
+  me.edit_layer.parentNode.removeChild(me.edit_layer);
+
+  me.text_area.value = me.orginal_text;
+  AJS.showElement(me.text_area);
+  me.gselm.className = "googie_no_style";
+
+  me.text_area.scrollTop = this.el_scroll_top;
+
+  elm.onmouseout = null;
+}
+
+GoogieSpell.prototype.createErrorLink = function(text, id) {
+  var elm = AJS.SPAN({'class': 'googie_link'});
+  var me = this;
+  elm.onclick = function () {
+    me.showErrorWindow(elm, id);
+  };
+  elm.innerHTML = text;
+  return elm;
+}
+
+GoogieSpell.createPart = function(txt_part) {
+  if(txt_part == " ")
+    return AJS.TN(" ");
+  var result = AJS.SPAN();
+
+  var is_first = true;
+  var is_safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1);
+
+  var part = AJS.SPAN();
+  txt_part = GoogieSpell.escapeSepcial(txt_part);
+  txt_part = txt_part.replace(/\n/g, "<br>");
+  txt_part = txt_part.replace(/  /g, " &nbsp;");
+  txt_part = txt_part.replace(/^ /g, "&nbsp;");
+  txt_part = txt_part.replace(/ $/g, "&nbsp;");
+  
+  part.innerHTML = txt_part;
+
+  return part;
+}
+
+GoogieSpell.prototype.showErrorsInIframe = function(results) {
+  var output = AJS.DIV();
+  output.style.textAlign = "left";
+  var pointer = 0;
+  for(var i=0; i < results.length; i++) {
+    var offset = results[i]['attrs']['o'];
+    var len = results[i]['attrs']['l'];
+    
+    var part_1_text = this.orginal_text.substring(pointer, offset);
+    var part_1 = GoogieSpell.createPart(part_1_text);
+    output.appendChild(part_1);
+    pointer += offset - pointer;
+    
+    //If the last child was an error, then insert some space
+    output.appendChild(this.createErrorLink(this.orginal_text.substr(offset, len), i));
+    pointer += len;
+  }
+  //Insert the rest of the orginal text
+  var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length);
+
+  var part_2 = GoogieSpell.createPart(part_2_text);
+  output.appendChild(part_2);
+
+  this.edit_layer.appendChild(output);
+
+  //Hide text area
+  AJS.hideElement(this.text_area);
+  this.text_area.parentNode.insertBefore(this.edit_layer, this.text_area.nextSibling);
+  this.edit_layer.scrollTop = this.ta_scroll_top;
+}
+
+GoogieSpell.Position = function(x, y) {
+  this.x = x;
+  this.y = y;
+}      
+
+//Get the absolute position of menu_slide
+GoogieSpell.absolutePosition = function(element) {
+  //Create a new object that has elements y and x pos...
+  var posObj = new GoogieSpell.Position(element.offsetLeft, element.offsetTop);
+
+  //Check if the element has an offsetParent - if it has .. loop until it has not
+  if(element.offsetParent) {
+    var temp_pos =     GoogieSpell.absolutePosition(element.offsetParent);
+    posObj.x += temp_pos.x;
+    posObj.y += temp_pos.y;
+  }
+  return posObj;
+}
+
+GoogieSpell.getEventElm = function(e) {
+       var targ;
+       if (!e) var e = window.event;
+       if (e.target) targ = e.target;
+       else if (e.srcElement) targ = e.srcElement;
+       if (targ.nodeType == 3) // defeat Safari bug
+               targ = targ.parentNode;
+  return targ;
+}
+
+GoogieSpell.prototype.removeIndicator = function(elm) {
+  // modified by roundcube
+  if (window.rcube_webmail_client)
+    rcube_webmail_client.set_busy(false);
+  //AJS.removeElement(this.indicator);
+}
+
+GoogieSpell.prototype.appendIndicator = function(elm) {
+  // modified by roundcube
+  if (window.rcube_webmail_client)
+    rcube_webmail_client.set_busy(true, 'checking');
+/*
+  var img = AJS.IMG({'src': this.img_dir + 'indicator.gif', 'style': 'margin-right: 5px;'});
+  img.style.width = "16px";
+  img.style.height = "16px";
+  this.indicator = img;
+  img.style.textDecoration = "none";
+  AJS.insertBefore(img, elm);
+  */
+}
+
+/****
+ Choose language
+****/
+GoogieSpell.prototype.createLangWindow = function() {
+  this.language_window = AJS.DIV({'class': 'googie_window'});
+  this.language_window.style.width = "130px";
+
+  //Build up the result list
+  var table = AJS.TABLE({'class': 'googie_list'});
+  var list = AJS.TBODY();
+
+  this.lang_elms = new Array();
+
+  for(i=0; i < this.langlist_codes.length; i++) {
+    var row = AJS.TR();
+    var item = AJS.TD();
+    item.googieId = this.langlist_codes[i];
+    this.lang_elms.push(item);
+    var lang_span = AJS.SPAN();
+    lang_span.innerHTML = this.lang_to_word[this.langlist_codes[i]];
+    item.appendChild(AJS.TN(lang_span.innerHTML));
+
+    var me = this;
+    
+    item.onclick = function(e) {
+      var elm = GoogieSpell.getEventElm(e);
+      me.deHighlightCurSel();
+
+      me.setCurrentLanguage(elm.googieId);
+
+      if(me.lang_state_observer != null) {
+        me.lang_state_observer();
+      }
+
+      me.highlightCurSel();
+      me.hideLangWindow();
+    };
+
+    item.onmouseover = function(e) { 
+      var i_it = GoogieSpell.getEventElm(e);
+      if(i_it.className != "googie_list_selected")
+        i_it.className = "googie_list_onhover";
+    };
+    item.onmouseout = function(e) { 
+      var i_it = GoogieSpell.getEventElm(e);
+      if(i_it.className != "googie_list_selected")
+        i_it.className = "googie_list_onout"; 
+    };
+
+    row.appendChild(item);
+    list.appendChild(row);
+  }
+
+  this.highlightCurSel();
+
+  //Close button
+  var close_row = AJS.TR();
+  var close = AJS.TD();
+  close.onmouseover = GoogieSpell.item_onmouseover;
+  close.onmouseout = GoogieSpell.item_onmouseout;
+  var spn_close = AJS.SPAN({'class': 'googie_list_close'});
+  spn_close.innerHTML = this.lang_close;
+  close.appendChild(spn_close);
+  var me = this;
+  close.onclick = function(e) {
+    me.hideLangWindow(); GoogieSpell.item_onmouseout(e);
+  };
+  close_row.appendChild(close);
+  list.appendChild(close_row);
+
+  table.appendChild(list);
+  this.language_window.appendChild(table);
+}
+
+GoogieSpell.prototype.setCurrentLanguage = function(lan_code) {
+  GOOGIE_CUR_LANG = lan_code;
+
+  //Set cookie
+  var now = new Date();
+  now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
+  setCookie('language', lan_code, now);
+}
+
+GoogieSpell.prototype.hideLangWindow = function() {
+  this.language_window.style.visibility = "hidden";
+  this.switch_lan_pic.className = "googie_lang_3d_on";
+}
+
+GoogieSpell.prototype.deHighlightCurSel = function() {
+  this.lang_cur_elm.className = "googie_list_onout";
+}
+
+GoogieSpell.prototype.highlightCurSel = function() {
+  for(var i=0; i < this.lang_elms.length; i++) {
+    if(this.lang_elms[i].googieId == GOOGIE_CUR_LANG) {
+      this.lang_elms[i].className = "googie_list_selected";
+      this.lang_cur_elm = this.lang_elms[i];
+    }
+    else {
+      this.lang_elms[i].className = "googie_list_onout";
+    }
+  }
+}
+
+GoogieSpell.prototype.showLangWindow = function(elm, ofst_top, ofst_left) {
+  if(!AJS.isDefined(ofst_top))
+    ofst_top = 20;
+  if(!AJS.isDefined(ofst_left))
+    ofst_left = 50;
+
+  this.createLangWindow();
+  AJS.getBody().appendChild(this.language_window);
+
+  var abs_pos = GoogieSpell.absolutePosition(elm);
+  AJS.showElement(this.language_window);
+  this.language_window.style.top = (abs_pos.y+ofst_top) + "px";
+  this.language_window.style.left = (abs_pos.x+ofst_left-this.language_window.offsetWidth) + "px";
+  this.highlightCurSel();
+  this.language_window.style.visibility = "visible";
+}
+
+GoogieSpell.prototype.flashNoSpellingErrorState = function() {
+  this.setStateChanged("no_error_found");
+  var me = this;
+  AJS.hideElement(this.switch_lan_pic);
+  this.gselm.innerHTML = this.lang_no_error_found;
+  this.gselm.className = "googie_check_spelling_ok";
+  this.gselm.style.textDecoration = "none";
+  this.gselm.style.cursor = "default";
+  var fu = function() {
+    AJS.removeElement(me.gselm);
+    me.checkSpellingState();
+  };
+  setTimeout(fu, 1000);
+}
+
+GoogieSpell.prototype.resumeEditingState = function() {
+  this.setStateChanged("resume_editing");
+  var me = this;
+  AJS.hideElement(me.switch_lan_pic);
+
+  //Change link text to resume
+  me.gselm.innerHTML = this.lang_rsm_edt;
+  me.gselm.onclick = function(e) {
+    me.resumeEditing(e, me);
+  }
+  me.gselm.className = "googie_check_spelling_ok";
+  me.edit_layer.scrollTop = me.ta_scroll_top;
+}
+
+GoogieSpell.prototype.createChangeLangPic = function() {
+  var switch_lan = AJS.A({'class': 'googie_lang_3d_on', 'style': 'padding-left: 6px;'}, AJS.IMG({'src': this.img_dir + 'change_lang.gif', 'alt': "Change language"}));
+  switch_lan.onmouseover = function() {
+    if(this.className != "googie_lang_3d_click")
+      this.className = "googie_lang_3d_on";
+  }
+
+  var me = this;
+  switch_lan.onclick = function() {
+    if(this.className == "googie_lang_3d_click") {
+      me.hideLangWindow();
+    }
+    else {
+      me.showLangWindow(switch_lan);
+      this.className = "googie_lang_3d_click";
+    }
+  }
+  return switch_lan;
+}
+
+GoogieSpell.prototype.createSpellDiv = function() {
+  var chk_spell = AJS.SPAN({'class': 'googie_check_spelling_link'});
+  chk_spell.innerHTML = this.lang_chck_spell;
+  var spell_img = null;
+  if(this.show_spell_img)
+    spell_img = AJS.IMG({'src': this.img_dir + "spellc.gif"});
+  return AJS.SPAN(spell_img, " ", chk_spell);
+}
+
+GoogieSpell.prototype.checkSpellingState = function() {
+  this.setStateChanged("check_spelling");
+  var me = this;
+  if(this.show_change_lang_pic)
+    this.switch_lan_pic = this.createChangeLangPic();
+  else
+    this.switch_lan_pic = AJS.SPAN();
+
+  var span_chck = this.createSpellDiv();
+  span_chck.onclick = function() {
+    me.spellCheck(span_chck);
+  }
+  AJS.appendChildNodes(this.spell_container, span_chck, " ", this.switch_lan_pic);
+  // modified by roundcube
+  this.check_link = span_chck;
+}
+
+GoogieSpell.prototype.setLanguages = function(lang_dict) {
+  this.lang_to_word = lang_dict;
+  this.langlist_codes = AJS.keys(lang_dict);
+}
+
+GoogieSpell.prototype.decorateTextarea = function(id, /*optional*/spell_container_id, force_width) {
+  var me = this;
+
+  if(typeof(id) == "string")
+    this.text_area = AJS.getElement(id);
+  else
+    this.text_area = id;
+
+  var r_width;
+
+  if(this.text_area != null) {
+    if(AJS.isDefined(spell_container_id)) {
+      if(typeof(spell_container_id) == "string")
+        this.spell_container = AJS.getElement(spell_container_id);
+      else
+        this.spell_container = spell_container_id;
+    }
+    else {
+      var table = AJS.TABLE();
+      var tbody = AJS.TBODY();
+      var tr = AJS.TR();
+      if(AJS.isDefined(force_width)) {
+        r_width = force_width;
+      }
+      else {
+        r_width = this.text_area.offsetWidth + "px";
+      }
+
+      var spell_container = AJS.TD();
+      this.spell_container = spell_container;
+
+      tr.appendChild(spell_container);
+
+      tbody.appendChild(tr);
+      table.appendChild(tbody);
+
+      AJS.insertBefore(table, this.text_area);
+
+      //Set width
+      table.style.width = '100%';  // modified by roundcube (old: r_width)
+      spell_container.style.width = r_width;
+      spell_container.style.textAlign = "right";
+    }
+
+    this.checkSpellingState();
+  }
+  else {
+    alert("Text area not found");
+  }
+}
index 51e2041ad3f48bf8e77720182c9f98a9d9f0a572..32fb917c8c2659131c7d43404be420ed1b1b62e6 100644 (file)
-/*
- +-----------------------------------------------------------------------+
- | RoundCube List Widget                                                 |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2006-2009, RoundCube Dev, - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
- |          Charles McNulty <charles@charlesmcnulty.com>                 |
- +-----------------------------------------------------------------------+
- | Requires: common.js                                                   |
- +-----------------------------------------------------------------------+
-
-  $Id: list.js 2277 2009-02-06 14:42:39Z alec $
-*/
-
-
-/**
- * RoundCube List Widget class
- * @contructor
- */
-function rcube_list_widget(list, p)
-  {
-  // static contants
-  this.ENTER_KEY = 13;
-  this.DELETE_KEY = 46;
-  this.BACKSPACE_KEY = 8;
-  
-  this.list = list ? list : null;
-  this.frame = null;
-  this.rows = [];
-  this.selection = [];
-  this.rowcount = 0;
-  
-  this.subject_col = -1;
-  this.shiftkey = false;
-  this.multiselect = false;
-  this.multi_selecting = false;
-  this.draggable = false;
-  this.keyboard = false;
-  this.toggleselect = false;
-  
-  this.dont_select = false;
-  this.drag_active = false;
-  this.last_selected = 0;
-  this.shift_start = 0;
-  this.in_selection_before = false;
-  this.focused = false;
-  this.drag_mouse_start = null;
-  this.dblclick_time = 600;
-  this.row_init = function(){};
-  this.events = { click:[], dblclick:[], select:[], keypress:[], dragstart:[], dragmove:[], dragend:[] };
-  
-  // overwrite default paramaters
-  if (p && typeof(p)=='object')
-    for (var n in p)
-      this[n] = p[n];
-  }
-
-
-rcube_list_widget.prototype = {
-
-
-/**
- * get all message rows from HTML table and init each row
- */
-init: function()
-{
-  if (this.list && this.list.tBodies[0])
-  {
-    this.rows = new Array();
-    this.rowcount = 0;
-
-    var row;
-    for(var r=0; r<this.list.tBodies[0].childNodes.length; r++)
-    {
-      row = this.list.tBodies[0].childNodes[r];
-      while (row && (row.nodeType != 1 || row.style.display == 'none'))
-      {
-        row = row.nextSibling;
-        r++;
-      }
-
-      this.init_row(row);
-      this.rowcount++;
-    }
-
-    this.frame = this.list.parentNode;
-
-    // set body events
-    if (this.keyboard) {
-      rcube_event.add_listener({element:document, event:'keyup', object:this, method:'key_press'});
-      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
-    }
-  }
-},
-
-
-/**
- *
- */
-init_row: function(row)
-{
-  // make references in internal array and set event handlers
-  if (row && String(row.id).match(/rcmrow([a-z0-9\-_=]+)/i))
-  {
-    var p = this;
-    var uid = RegExp.$1;
-    row.uid = uid;
-    this.rows[uid] = {uid:uid, id:row.id, obj:row, classname:row.className};
-
-    // set eventhandlers to table row
-    row.onmousedown = function(e){ return p.drag_row(e, this.uid); };
-    row.onmouseup = function(e){ return p.click_row(e, this.uid); };
-
-    if (document.all)
-      row.onselectstart = function() { return false; };
-
-    this.row_init(this.rows[uid]);
-  }
-},
-
-
-/**
- *
- */
-clear: function(sel)
-{
-  var tbody = document.createElement('TBODY');
-  this.list.insertBefore(tbody, this.list.tBodies[0]);
-  this.list.removeChild(this.list.tBodies[1]);
-  this.rows = new Array();
-  this.rowcount = 0;
-  
-  if (sel) this.clear_selection();
-},
-
-
-/**
- * 'remove' message row from list (just hide it)
- */
-remove_row: function(uid, sel_next)
-{
-  if (this.rows[uid].obj)
-    this.rows[uid].obj.style.display = 'none';
-
-  if (sel_next)
-    this.select_next();
-
-  this.rows[uid] = null;
-  this.rowcount--;
-},
-
-
-/**
- *
- */
-insert_row: function(row, attop)
-{
-  var tbody = this.list.tBodies[0];
-
-  if (attop && tbody.rows.length)
-    tbody.insertBefore(row, tbody.firstChild);
-  else
-    tbody.appendChild(row);
-
-  this.init_row(row);
-  this.rowcount++;
-},
-
-
-
-/**
- * Set focus to the list
- */
-focus: function(e)
-{
-  this.focused = true;
-  for (var n=0; n<this.selection.length; n++)
-  {
-    id = this.selection[n];
-    if (this.rows[id] && this.rows[id].obj)
-    {
-      this.set_classname(this.rows[id].obj, 'selected', true);
-      this.set_classname(this.rows[id].obj, 'unfocused', false);
-    }
-  }
-
-  if (e || (e = window.event))
-    rcube_event.cancel(e);
-},
-
-
-/**
- * remove focus from the list
- */
-blur: function()
-{
-  var id;
-  this.focused = false;
-  for (var n=0; n<this.selection.length; n++)
-  {
-    id = this.selection[n];
-    if (this.rows[id] && this.rows[id].obj)
-    {
-      this.set_classname(this.rows[id].obj, 'selected', false);
-      this.set_classname(this.rows[id].obj, 'unfocused', true);
-    }
-  }
-},
-
-
-/**
- * onmousedown-handler of message list row
- */
-drag_row: function(e, id)
-{
-  // don't do anything (another action processed before)
-  var evtarget = rcube_event.get_target(e);
-  if (this.dont_select || (evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG')))
-    return false;
-    
-  // accept right-clicks
-  if (rcube_event.get_button(e) == 2)
-    return true;
-  
-  this.in_selection_before = this.in_selection(id) ? id : false;
-
-  // selects currently unselected row
-  if (!this.in_selection_before)
-  {
-    var mod_key = rcube_event.get_modifier(e);
-    this.select_row(id, mod_key, false);
-  }
-
-  if (this.draggable && this.selection.length)
-  {
-    this.drag_start = true;
-    this.drag_mouse_start = rcube_event.get_mouse_pos(e);
-    rcube_event.add_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
-    rcube_event.add_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
-
-    // add listener for iframes
-    var iframes = document.getElementsByTagName('IFRAME');
-    this.iframe_events = Object();
-    for (var n in iframes)
-    {
-      var iframedoc = null;
-      if (iframes[n].contentDocument)
-        iframedoc = iframes[n].contentDocument;
-      else if (iframes[n].contentWindow)
-       iframedoc = iframes[n].contentWindow.document;
-      else if (iframes[n].document)
-        iframedoc = iframes[n].document;
-
-      if (iframedoc)
-      {
-       var list = this;
-       var pos = rcube_get_object_pos(document.getElementById(iframes[n].id));
-       this.iframe_events[n] = function(e) { e._offset = pos; return list.drag_mouse_move(e); }
-       
-       if (iframedoc.addEventListener)
-         iframedoc.addEventListener('mousemove', this.iframe_events[n], false);
-       else if (iframes[n].attachEvent)
-         iframedoc.attachEvent('onmousemove', this.iframe_events[n]);
-       else
-         iframedoc['onmousemove'] = this.iframe_events[n];
-
-        rcube_event.add_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
-      }
-    }                                                            
-  }
-
-  return false;
-},
-
-
-/**
- * onmouseup-handler of message list row
- */
-click_row: function(e, id)
-{
-  var now = new Date().getTime();
-  var mod_key = rcube_event.get_modifier(e);
-  var evtarget = rcube_event.get_target(e);
-  
-  if ((evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG')))
-    return false;
-  
-  // don't do anything (another action processed before)
-  if (this.dont_select)
-    {
-    this.dont_select = false;
-    return false;
-    }
-    
-  var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
-
-  // unselects currently selected row
-  if (!this.drag_active && this.in_selection_before == id && !dblclicked)
-    this.select_row(id, mod_key, false);
-
-  this.drag_start = false;
-  this.in_selection_before = false;
-
-  // row was double clicked
-  if (this.rows && dblclicked && this.in_selection(id))
-    this.trigger_event('dblclick');
-  else
-    this.trigger_event('click');
-
-  if (!this.drag_active)
-    rcube_event.cancel(e);
-
-  this.rows[id].clicked = now;
-  return false;
-},
-
-
-/**
- * get next/previous/last rows that are not hidden
- */
-get_next_row: function()
-{
-  if (!this.rows)
-    return false;
-
-  var last_selected_row = this.rows[this.last_selected];
-  var new_row = last_selected_row ? last_selected_row.obj.nextSibling : null;
-  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
-    new_row = new_row.nextSibling;
-
-  return new_row;
-},
-
-get_prev_row: function()
-{
-  if (!this.rows)
-    return false;
-
-  var last_selected_row = this.rows[this.last_selected];
-  var new_row = last_selected_row ? last_selected_row.obj.previousSibling : null;
-  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
-    new_row = new_row.previousSibling;
-
-  return new_row;
-},
-
-get_last_row: function()
-{
-  if (this.rowcount)
-    {
-    var rows = this.list.tBodies[0].rows;
-
-    for(var i=rows.length-1; i>=0; i--)
-      if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=]+)/i) && this.rows[RegExp.$1] != null)
-       return RegExp.$1;
-    }
-
-  return null;
-},
-
-
-/**
- * selects or unselects the proper row depending on the modifier key pressed
- */
-select_row: function(id, mod_key, with_mouse)
-{
-  var select_before = this.selection.join(',');
-  if (!this.multiselect)
-    mod_key = 0;
-    
-  if (!this.shift_start)
-    this.shift_start = id
-
-  if (!mod_key)
-  {
-    this.shift_start = id;
-    this.highlight_row(id, false);
-    this.multi_selecting = false;
-  }
-  else
-  {
-    switch (mod_key)
-    {
-      case SHIFT_KEY:
-        this.shift_select(id, false);
-        break;
-
-      case CONTROL_KEY:
-        if (!with_mouse)
-          this.highlight_row(id, true);
-        break; 
-
-      case CONTROL_SHIFT_KEY:
-        this.shift_select(id, true);
-        break;
-
-      default:
-        this.highlight_row(id, false);
-        break;
-    }
-    this.multi_selecting = true;
-  }
-
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.trigger_event('select');
-
-  if (this.last_selected != 0 && this.rows[this.last_selected])
-    this.set_classname(this.rows[this.last_selected].obj, 'focused', false);
-
-  // unselect if toggleselect is active and the same row was clicked again
-  if (this.toggleselect && this.last_selected == id)
-  {
-    this.clear_selection();
-    id = null;
-  }
-  else
-    this.set_classname(this.rows[id].obj, 'focused', true);
-
-  if (!this.selection.length)
-    this.shift_start = null;
-
-  this.last_selected = id;
-},
-
-
-/**
- * Alias method for select_row
- */
-select: function(id)
-{
-  this.select_row(id, false);
-  this.scrollto(id);
-},
-
-
-/**
- * Select row next to the last selected one.
- * Either below or above.
- */
-select_next: function()
-{
-  var next_row = this.get_next_row();
-  var prev_row = this.get_prev_row();
-  var new_row = (next_row) ? next_row : prev_row;
-  if (new_row)
-    this.select_row(new_row.uid, false, false);  
-},
-
-
-/**
- * Perform selection when shift key is pressed
- */
-shift_select: function(id, control)
-{
-  if (!this.rows[this.shift_start] || !this.selection.length)
-    this.shift_start = id;
-
-  var from_rowIndex = this.rows[this.shift_start].obj.rowIndex;
-  var to_rowIndex = this.rows[id].obj.rowIndex;
-
-  var i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex);
-  var j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex);
-
-  // iterate through the entire message list
-  for (var n in this.rows)
-  {
-    if ((this.rows[n].obj.rowIndex >= i) && (this.rows[n].obj.rowIndex <= j))
-    {
-      if (!this.in_selection(n))
-        this.highlight_row(n, true);
-    }
-    else
-    {
-      if  (this.in_selection(n) && !control)
-        this.highlight_row(n, true);
-    }
-  }
-},
-
-
-/**
- * Check if given id is part of the current selection
- */
-in_selection: function(id)
-{
-  for(var n in this.selection)
-    if (this.selection[n]==id)
-      return true;
-
-  return false;    
-},
-
-
-/**
- * Select each row in list
- */
-select_all: function(filter)
-{
-  if (!this.rows || !this.rows.length)
-    return false;
-
-  // reset but remember selection first
-  var select_before = this.selection.join(',');
-  this.selection = new Array();
-  
-  for (var n in this.rows)
-  {
-    if (!filter || (this.rows[n] && this.rows[n][filter] == true))
-    {
-      this.last_selected = n;
-      this.highlight_row(n, true);
-    }
-    else if (this.rows[n])
-    {
-      this.set_classname(this.rows[n].obj, 'selected', false);
-      this.set_classname(this.rows[n].obj, 'unfocused', false);
-    }
-  }
-
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.trigger_event('select');
-
-  this.focus();
-
-  return true;
-},
-
-
-/**
- * Unselect selected row(s)
- */
-clear_selection: function(id)
-{
-  var num_select = this.selection.length;
-
-  // one row
-  if (id)
-    {
-    for (var n=0; n<this.selection.length; n++)
-      if (this.selection[n] == id)
-        {
-       this.selection.splice(n,1);
-       break;
-       }
-    }
-  // all rows
-  else
-    {
-    for (var n=0; n<this.selection.length; n++)
-      if (this.rows[this.selection[n]])
-        {
-        this.set_classname(this.rows[this.selection[n]].obj, 'selected', false);
-        this.set_classname(this.rows[this.selection[n]].obj, 'unfocused', false);
-        }
-    
-    this.selection = new Array();
-    }
-
-  if (num_select && !this.selection.length)
-    this.trigger_event('select');
-},
-
-
-/**
- * Getter for the selection array
- */
-get_selection: function()
-{
-  return this.selection;
-},
-
-
-/**
- * Return the ID if only one row is selected
- */
-get_single_selection: function()
-{
-  if (this.selection.length == 1)
-    return this.selection[0];
-  else
-    return null;
-},
-
-
-/**
- * Highlight/unhighlight a row
- */
-highlight_row: function(id, multiple)
-{
-  if (this.rows[id] && !multiple)
-  {
-    if (this.selection.length > 1 || !this.in_selection(id))
-    {
-      this.clear_selection();
-      this.selection[0] = id;
-      this.set_classname(this.rows[id].obj, 'selected', true);
-    }
-  }
-  else if (this.rows[id])
-  {
-    if (!this.in_selection(id))  // select row
-    {
-      this.selection[this.selection.length] = id;
-      this.set_classname(this.rows[id].obj, 'selected', true);
-    }
-    else  // unselect row
-    {
-      var p = find_in_array(id, this.selection);
-      var a_pre = this.selection.slice(0, p);
-      var a_post = this.selection.slice(p+1, this.selection.length);
-      this.selection = a_pre.concat(a_post);
-      this.set_classname(this.rows[id].obj, 'selected', false);
-      this.set_classname(this.rows[id].obj, 'unfocused', false);
-    }
-  }
-},
-
-
-/**
- * Handler for keyboard events
- */
-key_press: function(e)
-{
-  if (this.focused != true)
-    return true;
-
-  var keyCode = rcube_event.get_keycode(e);
-  var mod_key = rcube_event.get_modifier(e);
-  switch (keyCode)
-  {
-    case 40:
-    case 38: 
-    case 63233: // "down", in safari keypress
-    case 63232: // "up", in safari keypress
-      // Stop propagation so that the browser doesn't scroll
-      rcube_event.cancel(e);
-      return this.use_arrow_key(keyCode, mod_key);
-    default:
-      this.shiftkey = e.shiftKey;
-      this.key_pressed = keyCode;
-      this.trigger_event('keypress');
-      
-      if (this.key_pressed == this.BACKSPACE_KEY)
-        return rcube_event.cancel(e);
-  }
-  
-  return true;
-},
-
-/**
- * Handler for keydown events
- */
-key_down: function(e)
-{
-  switch (rcube_event.get_keycode(e))
-  {
-    case 40:
-    case 38: 
-    case 63233:
-    case 63232:
-      if (!rcube_event.get_modifier(e) && this.focused)
-        return rcube_event.cancel(e);
-        
-    default:
-  }
-  
-  return true;
-},
-
-
-/**
- * Special handling method for arrow keys
- */
-use_arrow_key: function(keyCode, mod_key)
-{
-  var new_row;
-  // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
-  // using the keypress event (but not the keydown or keyup event).
-  if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
-    new_row = this.get_next_row();
-  else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
-    new_row = this.get_prev_row();
-
-  if (new_row)
-  {
-    this.select_row(new_row.uid, mod_key, true);
-    this.scrollto(new_row.uid);
-  }
-
-  return false;
-},
-
-
-/**
- * Try to scroll the list to make the specified row visible
- */
-scrollto: function(id)
-{
-  var row = this.rows[id].obj;
-  if (row && this.frame)
-  {
-    var scroll_to = Number(row.offsetTop);
-
-    if (scroll_to < Number(this.frame.scrollTop))
-      this.frame.scrollTop = scroll_to;
-    else if (scroll_to + Number(row.offsetHeight) > Number(this.frame.scrollTop) + Number(this.frame.offsetHeight))
-      this.frame.scrollTop = (scroll_to + Number(row.offsetHeight)) - Number(this.frame.offsetHeight);
-  }
-},
-
-
-/**
- * Handler for mouse move events
- */
-drag_mouse_move: function(e)
-{
-  if (this.drag_start)
-  {
-    // check mouse movement, of less than 3 pixels, don't start dragging
-    var m = rcube_event.get_mouse_pos(e);
-
-    if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3))
-      return false;
-  
-    if (!this.draglayer)
-      this.draglayer = new rcube_layer('rcmdraglayer', {x:0, y:0, vis:0, zindex:2000});
-  
-    // get subjects of selectedd messages
-    var names = '';
-    var c, i, node, subject, obj;
-    for(var n=0; n<this.selection.length; n++)
-    {
-      if (n>12)  // only show 12 lines
-      {
-        names += '...';
-        break;
-      }
-
-      if (this.rows[this.selection[n]].obj)
-      {
-        obj = this.rows[this.selection[n]].obj;
-        subject = '';
-
-        for(c=0, i=0; i<obj.childNodes.length; i++)
-        {
-          if (obj.childNodes[i].nodeName == 'TD')
-          {
-            if (((node = obj.childNodes[i].firstChild) && (node.nodeType==3 || node.nodeName=='A')) &&
-              (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)))
-            {
-              subject = node.nodeType==3 ? node.data : node.innerHTML;
-              names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />';
-              break;
-            }
-            c++;
-          }
-        }
-      }
-    }
-
-    this.draglayer.write(names);
-    this.draglayer.show(1);
-
-    this.drag_active = true;
-    this.trigger_event('dragstart');
-  }
-
-  if (this.drag_active && this.draglayer)
-  {
-    var pos = rcube_event.get_mouse_pos(e);
-    this.draglayer.move(pos.x+20, pos.y-5);
-    this.trigger_event('dragmove', e);
-  }
-
-  this.drag_start = false;
-
-  return false;
-},
-
-
-/**
- * Handler for mouse up events
- */
-drag_mouse_up: function(e)
-{
-  document.onmousemove = null;
-
-  if (this.draglayer && this.draglayer.visible)
-    this.draglayer.show(0);
-
-  this.drag_active = false;
-  this.trigger_event('dragend');
-
-  rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
-  rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
-
-  var iframes = document.getElementsByTagName('IFRAME');
-  for (var n in iframes) {
-    var iframedoc;
-    
-    if (iframes[n].contentDocument)
-      iframedoc = iframes[n].contentDocument;
-    else if (iframes[n].contentWindow)
-      iframedoc = iframes[n].contentWindow.document;
-    else if (iframes[n].document)
-      iframedoc = iframes[n].document;
-
-    if (iframedoc) {
-      if (this.iframe_events[n]) {
-       if (iframedoc.removeEventListener)
-         iframedoc.removeEventListener('mousemove', this.iframe_events[n], false);
-       else if (iframedoc.detachEvent)
-         iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
-       else
-         iframedoc['onmousemove'] = null;
-       }
-      rcube_event.remove_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
-      }
-    }
-
-  this.focus();
-  
-  return rcube_event.cancel(e);
-},
-
-
-
-/**
- * set/unset a specific class name
- */
-set_classname: function(obj, classname, set)
-{
-  var reg = new RegExp('\s*'+classname, 'i');
-  if (!set && obj.className.match(reg))
-    obj.className = obj.className.replace(reg, '');
-  else if (set && !obj.className.match(reg))
-    obj.className += ' '+classname;
-},
-
-
-/**
- * Setter for object event handlers
- *
- * @param {String}   Event name
- * @param {Function} Handler function
- * @return Listener ID (used to remove this handler later on)
- */
-addEventListener: function(evt, handler)
-{
-  if (this.events[evt]) {
-    var handle = this.events[evt].length;
-    this.events[evt][handle] = handler;
-    return handle;
-  }
-  else
-    return false;
-},
-
-
-/**
- * Removes a specific event listener
- *
- * @param {String} Event name
- * @param {Int}    Listener ID to remove
- */
-removeEventListener: function(evt, handle)
-{
-  if (this.events[evt] && this.events[evt][handle])
-    this.events[evt][handle] = null;
-},
-
-
-/**
- * This will execute all registered event handlers
- * @private
- */
-trigger_event: function(evt, p)
-{
-  if (this.events[evt] && this.events[evt].length) {
-    for (var i=0; i<this.events[evt].length; i++)
-      if (typeof(this.events[evt][i]) == 'function')
-        this.events[evt][i](this, p);
-  }
+function rcube_list_widget(_1,p){
+this.ENTER_KEY=13;
+this.DELETE_KEY=46;
+this.BACKSPACE_KEY=8;
+this.list=_1?_1:null;
+this.frame=null;
+this.rows=[];
+this.selection=[];
+this.rowcount=0;
+this.subject_col=-1;
+this.shiftkey=false;
+this.multiselect=false;
+this.multi_selecting=false;
+this.draggable=false;
+this.keyboard=false;
+this.toggleselect=false;
+this.dont_select=false;
+this.drag_active=false;
+this.last_selected=0;
+this.shift_start=0;
+this.in_selection_before=false;
+this.focused=false;
+this.drag_mouse_start=null;
+this.dblclick_time=600;
+this.row_init=function(){
+};
+this.events={click:[],dblclick:[],select:[],keypress:[],dragstart:[],dragmove:[],dragend:[]};
+if(p&&typeof (p)=="object"){
+for(var n in p){
+this[n]=p[n];
 }
-
-
+}
+};
+rcube_list_widget.prototype={init:function(){
+if(this.list&&this.list.tBodies[0]){
+this.rows=new Array();
+this.rowcount=0;
+var _4;
+for(var r=0;r<this.list.tBodies[0].childNodes.length;r++){
+_4=this.list.tBodies[0].childNodes[r];
+while(_4&&(_4.nodeType!=1||_4.style.display=="none")){
+_4=_4.nextSibling;
+r++;
+}
+this.init_row(_4);
+this.rowcount++;
+}
+this.frame=this.list.parentNode;
+if(this.keyboard){
+rcube_event.add_listener({element:document,event:"keyup",object:this,method:"key_press"});
+rcube_event.add_listener({element:document,event:"keydown",object:this,method:"key_down"});
+}
+}
+},init_row:function(_6){
+if(_6&&String(_6.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)){
+var p=this;
+var _8=RegExp.$1;
+_6.uid=_8;
+this.rows[_8]={uid:_8,id:_6.id,obj:_6,classname:_6.className};
+_6.onmousedown=function(e){
+return p.drag_row(e,this.uid);
+};
+_6.onmouseup=function(e){
+return p.click_row(e,this.uid);
+};
+if(document.all){
+_6.onselectstart=function(){
+return false;
 };
+}
+this.row_init(this.rows[_8]);
+}
+},clear:function(_b){
+var _c=document.createElement("TBODY");
+this.list.insertBefore(_c,this.list.tBodies[0]);
+this.list.removeChild(this.list.tBodies[1]);
+this.rows=new Array();
+this.rowcount=0;
+if(_b){
+this.clear_selection();
+}
+},remove_row:function(_d,_e){
+if(this.rows[_d].obj){
+this.rows[_d].obj.style.display="none";
+}
+if(_e){
+this.select_next();
+}
+this.rows[_d]=null;
+this.rowcount--;
+},insert_row:function(_f,_10){
+var _11=this.list.tBodies[0];
+if(_10&&_11.rows.length){
+_11.insertBefore(_f,_11.firstChild);
+}else{
+_11.appendChild(_f);
+}
+this.init_row(_f);
+this.rowcount++;
+},focus:function(e){
+this.focused=true;
+for(var n=0;n<this.selection.length;n++){
+id=this.selection[n];
+if(this.rows[id]&&this.rows[id].obj){
+this.set_classname(this.rows[id].obj,"selected",true);
+this.set_classname(this.rows[id].obj,"unfocused",false);
+}
+}
+if(e||(e=window.event)){
+rcube_event.cancel(e);
+}
+},blur:function(){
+var id;
+this.focused=false;
+for(var n=0;n<this.selection.length;n++){
+id=this.selection[n];
+if(this.rows[id]&&this.rows[id].obj){
+this.set_classname(this.rows[id].obj,"selected",false);
+this.set_classname(this.rows[id].obj,"unfocused",true);
+}
+}
+},drag_row:function(e,id){
+var _18=rcube_event.get_target(e);
+if(this.dont_select||(_18&&(_18.tagName=="INPUT"||_18.tagName=="IMG"))){
+return true;
+}
+if(rcube_event.get_button(e)==2){
+return true;
+}
+this.in_selection_before=this.in_selection(id)?id:false;
+if(!this.in_selection_before){
+var _19=rcube_event.get_modifier(e);
+this.select_row(id,_19,false);
+}
+if(this.draggable&&this.selection.length){
+this.drag_start=true;
+this.drag_mouse_start=rcube_event.get_mouse_pos(e);
+rcube_event.add_listener({element:document,event:"mousemove",object:this,method:"drag_mouse_move"});
+rcube_event.add_listener({element:document,event:"mouseup",object:this,method:"drag_mouse_up"});
+var _1a=document.getElementsByTagName("IFRAME");
+this.iframe_events=Object();
+for(var n in _1a){
+var _1c=null;
+if(_1a[n].contentDocument){
+_1c=_1a[n].contentDocument;
+}else{
+if(_1a[n].contentWindow){
+_1c=_1a[n].contentWindow.document;
+}else{
+if(_1a[n].document){
+_1c=_1a[n].document;
+}
+}
+}
+if(_1c){
+var _1d=this;
+var pos=rcube_get_object_pos(document.getElementById(_1a[n].id));
+this.iframe_events[n]=function(e){
+e._offset=pos;
+return _1d.drag_mouse_move(e);
+};
+if(_1c.addEventListener){
+_1c.addEventListener("mousemove",this.iframe_events[n],false);
+}else{
+if(_1a[n].attachEvent){
+_1c.attachEvent("onmousemove",this.iframe_events[n]);
+}else{
+_1c["onmousemove"]=this.iframe_events[n];
+}
+}
+rcube_event.add_listener({element:_1c,event:"mouseup",object:this,method:"drag_mouse_up"});
+}
+}
+}
+return false;
+},click_row:function(e,id){
+var now=new Date().getTime();
+var _23=rcube_event.get_modifier(e);
+var _24=rcube_event.get_target(e);
+if((_24&&(_24.tagName=="INPUT"||_24.tagName=="IMG"))){
+return true;
+}
+if(this.dont_select){
+this.dont_select=false;
+return false;
+}
+var _25=now-this.rows[id].clicked<this.dblclick_time;
+if(!this.drag_active&&this.in_selection_before==id&&!_25){
+this.select_row(id,_23,false);
+}
+this.drag_start=false;
+this.in_selection_before=false;
+if(this.rows&&_25&&this.in_selection(id)){
+this.trigger_event("dblclick");
+}else{
+this.trigger_event("click");
+}
+if(!this.drag_active){
+rcube_event.cancel(e);
+}
+this.rows[id].clicked=now;
+return false;
+},get_next_row:function(){
+if(!this.rows){
+return false;
+}
+var _26=this.rows[this.last_selected];
+var _27=_26?_26.obj.nextSibling:null;
+while(_27&&(_27.nodeType!=1||_27.style.display=="none")){
+_27=_27.nextSibling;
+}
+return _27;
+},get_prev_row:function(){
+if(!this.rows){
+return false;
+}
+var _28=this.rows[this.last_selected];
+var _29=_28?_28.obj.previousSibling:null;
+while(_29&&(_29.nodeType!=1||_29.style.display=="none")){
+_29=_29.previousSibling;
+}
+return _29;
+},get_last_row:function(){
+if(this.rowcount){
+var _2a=this.list.tBodies[0].rows;
+for(var i=_2a.length-1;i>=0;i--){
+if(_2a[i].id&&String(_2a[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null){
+return RegExp.$1;
+}
+}
+}
+return null;
+},select_row:function(id,_2d,_2e){
+var _2f=this.selection.join(",");
+if(!this.multiselect){
+_2d=0;
+}
+if(!this.shift_start){
+this.shift_start=id;
+}
+if(!_2d){
+this.shift_start=id;
+this.highlight_row(id,false);
+this.multi_selecting=false;
+}else{
+switch(_2d){
+case SHIFT_KEY:
+this.shift_select(id,false);
+break;
+case CONTROL_KEY:
+if(!_2e){
+this.highlight_row(id,true);
+}
+break;
+case CONTROL_SHIFT_KEY:
+this.shift_select(id,true);
+break;
+default:
+this.highlight_row(id,false);
+break;
+}
+this.multi_selecting=true;
+}
+if(this.selection.join(",")!=_2f){
+this.trigger_event("select");
+}
+if(this.last_selected!=0&&this.rows[this.last_selected]){
+this.set_classname(this.rows[this.last_selected].obj,"focused",false);
+}
+if(this.toggleselect&&this.last_selected==id){
+this.clear_selection();
+id=null;
+}else{
+this.set_classname(this.rows[id].obj,"focused",true);
+}
+if(!this.selection.length){
+this.shift_start=null;
+}
+this.last_selected=id;
+},select:function(id){
+this.select_row(id,false);
+this.scrollto(id);
+},select_next:function(){
+var _31=this.get_next_row();
+var _32=this.get_prev_row();
+var _33=(_31)?_31:_32;
+if(_33){
+this.select_row(_33.uid,false,false);
+}
+},shift_select:function(id,_35){
+if(!this.rows[this.shift_start]||!this.selection.length){
+this.shift_start=id;
+}
+var _36=this.rows[this.shift_start].obj.rowIndex;
+var _37=this.rows[id].obj.rowIndex;
+var i=((_36<_37)?_36:_37);
+var j=((_36>_37)?_36:_37);
+for(var n in this.rows){
+if((this.rows[n].obj.rowIndex>=i)&&(this.rows[n].obj.rowIndex<=j)){
+if(!this.in_selection(n)){
+this.highlight_row(n,true);
+}
+}else{
+if(this.in_selection(n)&&!_35){
+this.highlight_row(n,true);
+}
+}
+}
+},in_selection:function(id){
+for(var n in this.selection){
+if(this.selection[n]==id){
+return true;
+}
+}
+return false;
+},select_all:function(_3d){
+if(!this.rows||!this.rows.length){
+return false;
+}
+var _3e=this.selection.join(",");
+this.selection=new Array();
+for(var n in this.rows){
+if(!_3d||(this.rows[n]&&this.rows[n][_3d]==true)){
+this.last_selected=n;
+this.highlight_row(n,true);
+}else{
+if(this.rows[n]){
+this.set_classname(this.rows[n].obj,"selected",false);
+this.set_classname(this.rows[n].obj,"unfocused",false);
+}
+}
+}
+if(this.selection.join(",")!=_3e){
+this.trigger_event("select");
+}
+this.focus();
+return true;
+},clear_selection:function(id){
+var _41=this.selection.length;
+if(id){
+for(var n=0;n<this.selection.length;n++){
+if(this.selection[n]==id){
+this.selection.splice(n,1);
+break;
+}
+}
+}else{
+for(var n=0;n<this.selection.length;n++){
+if(this.rows[this.selection[n]]){
+this.set_classname(this.rows[this.selection[n]].obj,"selected",false);
+this.set_classname(this.rows[this.selection[n]].obj,"unfocused",false);
+}
+}
+this.selection=new Array();
+}
+if(_41&&!this.selection.length){
+this.trigger_event("select");
+}
+},get_selection:function(){
+return this.selection;
+},get_single_selection:function(){
+if(this.selection.length==1){
+return this.selection[0];
+}else{
+return null;
+}
+},highlight_row:function(id,_44){
+if(this.rows[id]&&!_44){
+if(this.selection.length>1||!this.in_selection(id)){
+this.clear_selection();
+this.selection[0]=id;
+this.set_classname(this.rows[id].obj,"selected",true);
+}
+}else{
+if(this.rows[id]){
+if(!this.in_selection(id)){
+this.selection[this.selection.length]=id;
+this.set_classname(this.rows[id].obj,"selected",true);
+}else{
+var p=find_in_array(id,this.selection);
+var _46=this.selection.slice(0,p);
+var _47=this.selection.slice(p+1,this.selection.length);
+this.selection=_46.concat(_47);
+this.set_classname(this.rows[id].obj,"selected",false);
+this.set_classname(this.rows[id].obj,"unfocused",false);
+}
+}
+}
+},key_press:function(e){
+if(this.focused!=true){
+return true;
+}
+var _49=rcube_event.get_keycode(e);
+var _4a=rcube_event.get_modifier(e);
+switch(_49){
+case 40:
+case 38:
+case 63233:
+case 63232:
+rcube_event.cancel(e);
+return this.use_arrow_key(_49,_4a);
+default:
+this.shiftkey=e.shiftKey;
+this.key_pressed=_49;
+this.trigger_event("keypress");
+if(this.key_pressed==this.BACKSPACE_KEY){
+return rcube_event.cancel(e);
+}
+}
+return true;
+},key_down:function(e){
+switch(rcube_event.get_keycode(e)){
+case 40:
+case 38:
+case 63233:
+case 63232:
+if(!rcube_event.get_modifier(e)&&this.focused){
+return rcube_event.cancel(e);
+}
+default:
+}
+return true;
+},use_arrow_key:function(_4c,_4d){
+var _4e;
+if(_4c==40||_4c==63233){
+_4e=this.get_next_row();
+}else{
+if(_4c==38||_4c==63232){
+_4e=this.get_prev_row();
+}
+}
+if(_4e){
+this.select_row(_4e.uid,_4d,true);
+this.scrollto(_4e.uid);
+}
+return false;
+},scrollto:function(id){
+var row=this.rows[id].obj;
+if(row&&this.frame){
+var _51=Number(row.offsetTop);
+if(_51<Number(this.frame.scrollTop)){
+this.frame.scrollTop=_51;
+}else{
+if(_51+Number(row.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight)){
+this.frame.scrollTop=(_51+Number(row.offsetHeight))-Number(this.frame.offsetHeight);
+}
+}
+}
+},drag_mouse_move:function(e){
+if(this.drag_start){
+var m=rcube_event.get_mouse_pos(e);
+if(!this.drag_mouse_start||(Math.abs(m.x-this.drag_mouse_start.x)<3&&Math.abs(m.y-this.drag_mouse_start.y)<3)){
+return false;
+}
+if(!this.draglayer){
+this.draglayer=new rcube_layer("rcmdraglayer",{x:0,y:0,vis:0,zindex:2000});
+}
+var _54="";
+var c,i,_57,_58,obj;
+for(var n=0;n<this.selection.length;n++){
+if(n>12){
+_54+="...";
+break;
+}
+if(this.rows[this.selection[n]].obj){
+obj=this.rows[this.selection[n]].obj;
+_58="";
+for(c=0,i=0;i<obj.childNodes.length;i++){
+if(obj.childNodes[i].nodeName=="TD"){
+if(((_57=obj.childNodes[i].firstChild)&&(_57.nodeType==3||_57.nodeName=="A"))&&(this.subject_col<0||(this.subject_col>=0&&this.subject_col==c))){
+_58=_57.nodeType==3?_57.data:_57.innerHTML;
+_58=_58.replace(/^\s+/i,"");
+_54+=(_58.length>50?_58.substring(0,50)+"...":_58)+"<br />";
+break;
+}
+c++;
+}
+}
+}
+}
+this.draglayer.write(_54);
+this.draglayer.show(1);
+this.drag_active=true;
+this.trigger_event("dragstart");
+}
+if(this.drag_active&&this.draglayer){
+var pos=rcube_event.get_mouse_pos(e);
+this.draglayer.move(pos.x+20,bw.ie?pos.y-5+document.documentElement.scrollTop:pos.y-5);
+this.trigger_event("dragmove",e);
+}
+this.drag_start=false;
+return false;
+},drag_mouse_up:function(e){
+document.onmousemove=null;
+if(this.draglayer&&this.draglayer.visible){
+this.draglayer.show(0);
+}
+this.drag_active=false;
+this.trigger_event("dragend");
+rcube_event.remove_listener({element:document,event:"mousemove",object:this,method:"drag_mouse_move"});
+rcube_event.remove_listener({element:document,event:"mouseup",object:this,method:"drag_mouse_up"});
+var _5d=document.getElementsByTagName("IFRAME");
+for(var n in _5d){
+var _5f;
+if(_5d[n].contentDocument){
+_5f=_5d[n].contentDocument;
+}else{
+if(_5d[n].contentWindow){
+_5f=_5d[n].contentWindow.document;
+}else{
+if(_5d[n].document){
+_5f=_5d[n].document;
+}
+}
+}
+if(_5f){
+if(this.iframe_events[n]){
+if(_5f.removeEventListener){
+_5f.removeEventListener("mousemove",this.iframe_events[n],false);
+}else{
+if(_5f.detachEvent){
+_5f.detachEvent("onmousemove",this.iframe_events[n]);
+}else{
+_5f["onmousemove"]=null;
+}
+}
+}
+rcube_event.remove_listener({element:_5f,event:"mouseup",object:this,method:"drag_mouse_up"});
+}
+}
+return rcube_event.cancel(e);
+},set_classname:function(obj,_61,set){
+var reg=new RegExp("s*"+_61,"i");
+if(!set&&obj.className.match(reg)){
+obj.className=obj.className.replace(reg,"");
+}else{
+if(set&&!obj.className.match(reg)){
+obj.className+=" "+_61;
+}
+}
+},addEventListener:function(evt,_65){
+if(this.events[evt]){
+var _66=this.events[evt].length;
+this.events[evt][_66]=_65;
+return _66;
+}else{
+return false;
+}
+},removeEventListener:function(evt,_68){
+if(this.events[evt]&&this.events[evt][_68]){
+this.events[evt][_68]=null;
+}
+},trigger_event:function(evt,p){
+if(this.events[evt]&&this.events[evt].length){
+for(var i=0;i<this.events[evt].length;i++){
+if(typeof (this.events[evt][i])=="function"){
+this.events[evt][i](this,p);
+}
+}
+}
+}};
 
diff --git a/program/js/list.js.src b/program/js/list.js.src
new file mode 100644 (file)
index 0000000..5a1c35a
--- /dev/null
@@ -0,0 +1,895 @@
+/*
+ +-----------------------------------------------------------------------+
+ | RoundCube List Widget                                                 |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2006-2009, RoundCube Dev, - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
+ |          Charles McNulty <charles@charlesmcnulty.com>                 |
+ +-----------------------------------------------------------------------+
+ | Requires: common.js                                                   |
+ +-----------------------------------------------------------------------+
+
+  $Id: list.js 2483 2009-05-15 10:22:29Z thomasb $
+*/
+
+
+/**
+ * RoundCube List Widget class
+ * @contructor
+ */
+function rcube_list_widget(list, p)
+  {
+  // static contants
+  this.ENTER_KEY = 13;
+  this.DELETE_KEY = 46;
+  this.BACKSPACE_KEY = 8;
+  
+  this.list = list ? list : null;
+  this.frame = null;
+  this.rows = [];
+  this.selection = [];
+  this.rowcount = 0;
+  
+  this.subject_col = -1;
+  this.shiftkey = false;
+  this.multiselect = false;
+  this.multi_selecting = false;
+  this.draggable = false;
+  this.keyboard = false;
+  this.toggleselect = false;
+  
+  this.dont_select = false;
+  this.drag_active = false;
+  this.last_selected = 0;
+  this.shift_start = 0;
+  this.in_selection_before = false;
+  this.focused = false;
+  this.drag_mouse_start = null;
+  this.dblclick_time = 600;
+  this.row_init = function(){};
+  this.events = { click:[], dblclick:[], select:[], keypress:[], dragstart:[], dragmove:[], dragend:[] };
+  
+  // overwrite default paramaters
+  if (p && typeof(p)=='object')
+    for (var n in p)
+      this[n] = p[n];
+  }
+
+
+rcube_list_widget.prototype = {
+
+
+/**
+ * get all message rows from HTML table and init each row
+ */
+init: function()
+{
+  if (this.list && this.list.tBodies[0])
+  {
+    this.rows = new Array();
+    this.rowcount = 0;
+
+    var row;
+    for(var r=0; r<this.list.tBodies[0].childNodes.length; r++)
+    {
+      row = this.list.tBodies[0].childNodes[r];
+      while (row && (row.nodeType != 1 || row.style.display == 'none'))
+      {
+        row = row.nextSibling;
+        r++;
+      }
+
+      this.init_row(row);
+      this.rowcount++;
+    }
+
+    this.frame = this.list.parentNode;
+
+    // set body events
+    if (this.keyboard) {
+      rcube_event.add_listener({element:document, event:'keyup', object:this, method:'key_press'});
+      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
+    }
+  }
+},
+
+
+/**
+ *
+ */
+init_row: function(row)
+{
+  // make references in internal array and set event handlers
+  if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i))
+  {
+    var p = this;
+    var uid = RegExp.$1;
+    row.uid = uid;
+    this.rows[uid] = {uid:uid, id:row.id, obj:row, classname:row.className};
+
+    // set eventhandlers to table row
+    row.onmousedown = function(e){ return p.drag_row(e, this.uid); };
+    row.onmouseup = function(e){ return p.click_row(e, this.uid); };
+
+    if (document.all)
+      row.onselectstart = function() { return false; };
+
+    this.row_init(this.rows[uid]);
+  }
+},
+
+
+/**
+ *
+ */
+clear: function(sel)
+{
+  var tbody = document.createElement('TBODY');
+  this.list.insertBefore(tbody, this.list.tBodies[0]);
+  this.list.removeChild(this.list.tBodies[1]);
+  this.rows = new Array();
+  this.rowcount = 0;
+  
+  if (sel) this.clear_selection();
+},
+
+
+/**
+ * 'remove' message row from list (just hide it)
+ */
+remove_row: function(uid, sel_next)
+{
+  if (this.rows[uid].obj)
+    this.rows[uid].obj.style.display = 'none';
+
+  if (sel_next)
+    this.select_next();
+
+  this.rows[uid] = null;
+  this.rowcount--;
+},
+
+
+/**
+ *
+ */
+insert_row: function(row, attop)
+{
+  var tbody = this.list.tBodies[0];
+
+  if (attop && tbody.rows.length)
+    tbody.insertBefore(row, tbody.firstChild);
+  else
+    tbody.appendChild(row);
+
+  this.init_row(row);
+  this.rowcount++;
+},
+
+
+
+/**
+ * Set focus to the list
+ */
+focus: function(e)
+{
+  this.focused = true;
+  for (var n=0; n<this.selection.length; n++)
+  {
+    id = this.selection[n];
+    if (this.rows[id] && this.rows[id].obj)
+    {
+      this.set_classname(this.rows[id].obj, 'selected', true);
+      this.set_classname(this.rows[id].obj, 'unfocused', false);
+    }
+  }
+
+  if (e || (e = window.event))
+    rcube_event.cancel(e);
+},
+
+
+/**
+ * remove focus from the list
+ */
+blur: function()
+{
+  var id;
+  this.focused = false;
+  for (var n=0; n<this.selection.length; n++)
+  {
+    id = this.selection[n];
+    if (this.rows[id] && this.rows[id].obj)
+    {
+      this.set_classname(this.rows[id].obj, 'selected', false);
+      this.set_classname(this.rows[id].obj, 'unfocused', true);
+    }
+  }
+},
+
+
+/**
+ * onmousedown-handler of message list row
+ */
+drag_row: function(e, id)
+{
+  // don't do anything (another action processed before)
+  var evtarget = rcube_event.get_target(e);
+  if (this.dont_select || (evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG')))
+    return true;
+    
+  // accept right-clicks
+  if (rcube_event.get_button(e) == 2)
+    return true;
+  
+  this.in_selection_before = this.in_selection(id) ? id : false;
+
+  // selects currently unselected row
+  if (!this.in_selection_before)
+  {
+    var mod_key = rcube_event.get_modifier(e);
+    this.select_row(id, mod_key, false);
+  }
+
+  if (this.draggable && this.selection.length)
+  {
+    this.drag_start = true;
+    this.drag_mouse_start = rcube_event.get_mouse_pos(e);
+    rcube_event.add_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
+    rcube_event.add_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
+
+    // add listener for iframes
+    var iframes = document.getElementsByTagName('IFRAME');
+    this.iframe_events = Object();
+    for (var n in iframes)
+    {
+      var iframedoc = null;
+      if (iframes[n].contentDocument)
+        iframedoc = iframes[n].contentDocument;
+      else if (iframes[n].contentWindow)
+       iframedoc = iframes[n].contentWindow.document;
+      else if (iframes[n].document)
+        iframedoc = iframes[n].document;
+
+      if (iframedoc)
+      {
+       var list = this;
+       var pos = rcube_get_object_pos(document.getElementById(iframes[n].id));
+       this.iframe_events[n] = function(e) { e._offset = pos; return list.drag_mouse_move(e); }
+       
+       if (iframedoc.addEventListener)
+         iframedoc.addEventListener('mousemove', this.iframe_events[n], false);
+       else if (iframes[n].attachEvent)
+         iframedoc.attachEvent('onmousemove', this.iframe_events[n]);
+       else
+         iframedoc['onmousemove'] = this.iframe_events[n];
+
+        rcube_event.add_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
+      }
+    }                                                            
+  }
+
+  return false;
+},
+
+
+/**
+ * onmouseup-handler of message list row
+ */
+click_row: function(e, id)
+{
+  var now = new Date().getTime();
+  var mod_key = rcube_event.get_modifier(e);
+  var evtarget = rcube_event.get_target(e);
+
+  if ((evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG')))
+    return true;
+
+  // don't do anything (another action processed before)
+  if (this.dont_select)
+    {
+    this.dont_select = false;
+    return false;
+    }
+    
+  var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
+
+  // unselects currently selected row
+  if (!this.drag_active && this.in_selection_before == id && !dblclicked)
+    this.select_row(id, mod_key, false);
+
+  this.drag_start = false;
+  this.in_selection_before = false;
+
+  // row was double clicked
+  if (this.rows && dblclicked && this.in_selection(id))
+    this.trigger_event('dblclick');
+  else
+    this.trigger_event('click');
+
+  if (!this.drag_active)
+    rcube_event.cancel(e);
+
+  this.rows[id].clicked = now;
+  return false;
+},
+
+
+/**
+ * get next/previous/last rows that are not hidden
+ */
+get_next_row: function()
+{
+  if (!this.rows)
+    return false;
+
+  var last_selected_row = this.rows[this.last_selected];
+  var new_row = last_selected_row ? last_selected_row.obj.nextSibling : null;
+  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
+    new_row = new_row.nextSibling;
+
+  return new_row;
+},
+
+get_prev_row: function()
+{
+  if (!this.rows)
+    return false;
+
+  var last_selected_row = this.rows[this.last_selected];
+  var new_row = last_selected_row ? last_selected_row.obj.previousSibling : null;
+  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
+    new_row = new_row.previousSibling;
+
+  return new_row;
+},
+
+get_last_row: function()
+{
+  if (this.rowcount)
+    {
+    var rows = this.list.tBodies[0].rows;
+
+    for(var i=rows.length-1; i>=0; i--)
+      if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
+       return RegExp.$1;
+    }
+
+  return null;
+},
+
+
+/**
+ * selects or unselects the proper row depending on the modifier key pressed
+ */
+select_row: function(id, mod_key, with_mouse)
+{
+  var select_before = this.selection.join(',');
+  if (!this.multiselect)
+    mod_key = 0;
+    
+  if (!this.shift_start)
+    this.shift_start = id
+
+  if (!mod_key)
+  {
+    this.shift_start = id;
+    this.highlight_row(id, false);
+    this.multi_selecting = false;
+  }
+  else
+  {
+    switch (mod_key)
+    {
+      case SHIFT_KEY:
+        this.shift_select(id, false);
+        break;
+
+      case CONTROL_KEY:
+        if (!with_mouse)
+          this.highlight_row(id, true);
+        break; 
+
+      case CONTROL_SHIFT_KEY:
+        this.shift_select(id, true);
+        break;
+
+      default:
+        this.highlight_row(id, false);
+        break;
+    }
+    this.multi_selecting = true;
+  }
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.trigger_event('select');
+
+  if (this.last_selected != 0 && this.rows[this.last_selected])
+    this.set_classname(this.rows[this.last_selected].obj, 'focused', false);
+
+  // unselect if toggleselect is active and the same row was clicked again
+  if (this.toggleselect && this.last_selected == id)
+  {
+    this.clear_selection();
+    id = null;
+  }
+  else
+    this.set_classname(this.rows[id].obj, 'focused', true);
+
+  if (!this.selection.length)
+    this.shift_start = null;
+
+  this.last_selected = id;
+},
+
+
+/**
+ * Alias method for select_row
+ */
+select: function(id)
+{
+  this.select_row(id, false);
+  this.scrollto(id);
+},
+
+
+/**
+ * Select row next to the last selected one.
+ * Either below or above.
+ */
+select_next: function()
+{
+  var next_row = this.get_next_row();
+  var prev_row = this.get_prev_row();
+  var new_row = (next_row) ? next_row : prev_row;
+  if (new_row)
+    this.select_row(new_row.uid, false, false);  
+},
+
+
+/**
+ * Perform selection when shift key is pressed
+ */
+shift_select: function(id, control)
+{
+  if (!this.rows[this.shift_start] || !this.selection.length)
+    this.shift_start = id;
+
+  var from_rowIndex = this.rows[this.shift_start].obj.rowIndex;
+  var to_rowIndex = this.rows[id].obj.rowIndex;
+
+  var i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex);
+  var j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex);
+
+  // iterate through the entire message list
+  for (var n in this.rows)
+  {
+    if ((this.rows[n].obj.rowIndex >= i) && (this.rows[n].obj.rowIndex <= j))
+    {
+      if (!this.in_selection(n))
+        this.highlight_row(n, true);
+    }
+    else
+    {
+      if  (this.in_selection(n) && !control)
+        this.highlight_row(n, true);
+    }
+  }
+},
+
+
+/**
+ * Check if given id is part of the current selection
+ */
+in_selection: function(id)
+{
+  for(var n in this.selection)
+    if (this.selection[n]==id)
+      return true;
+
+  return false;    
+},
+
+
+/**
+ * Select each row in list
+ */
+select_all: function(filter)
+{
+  if (!this.rows || !this.rows.length)
+    return false;
+
+  // reset but remember selection first
+  var select_before = this.selection.join(',');
+  this.selection = new Array();
+  
+  for (var n in this.rows)
+  {
+    if (!filter || (this.rows[n] && this.rows[n][filter] == true))
+    {
+      this.last_selected = n;
+      this.highlight_row(n, true);
+    }
+    else if (this.rows[n])
+    {
+      this.set_classname(this.rows[n].obj, 'selected', false);
+      this.set_classname(this.rows[n].obj, 'unfocused', false);
+    }
+  }
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.trigger_event('select');
+
+  this.focus();
+
+  return true;
+},
+
+
+/**
+ * Unselect selected row(s)
+ */
+clear_selection: function(id)
+{
+  var num_select = this.selection.length;
+
+  // one row
+  if (id)
+    {
+    for (var n=0; n<this.selection.length; n++)
+      if (this.selection[n] == id)
+        {
+       this.selection.splice(n,1);
+       break;
+       }
+    }
+  // all rows
+  else
+    {
+    for (var n=0; n<this.selection.length; n++)
+      if (this.rows[this.selection[n]])
+        {
+        this.set_classname(this.rows[this.selection[n]].obj, 'selected', false);
+        this.set_classname(this.rows[this.selection[n]].obj, 'unfocused', false);
+        }
+    
+    this.selection = new Array();
+    }
+
+  if (num_select && !this.selection.length)
+    this.trigger_event('select');
+},
+
+
+/**
+ * Getter for the selection array
+ */
+get_selection: function()
+{
+  return this.selection;
+},
+
+
+/**
+ * Return the ID if only one row is selected
+ */
+get_single_selection: function()
+{
+  if (this.selection.length == 1)
+    return this.selection[0];
+  else
+    return null;
+},
+
+
+/**
+ * Highlight/unhighlight a row
+ */
+highlight_row: function(id, multiple)
+{
+  if (this.rows[id] && !multiple)
+  {
+    if (this.selection.length > 1 || !this.in_selection(id))
+    {
+      this.clear_selection();
+      this.selection[0] = id;
+      this.set_classname(this.rows[id].obj, 'selected', true);
+    }
+  }
+  else if (this.rows[id])
+  {
+    if (!this.in_selection(id))  // select row
+    {
+      this.selection[this.selection.length] = id;
+      this.set_classname(this.rows[id].obj, 'selected', true);
+    }
+    else  // unselect row
+    {
+      var p = find_in_array(id, this.selection);
+      var a_pre = this.selection.slice(0, p);
+      var a_post = this.selection.slice(p+1, this.selection.length);
+      this.selection = a_pre.concat(a_post);
+      this.set_classname(this.rows[id].obj, 'selected', false);
+      this.set_classname(this.rows[id].obj, 'unfocused', false);
+    }
+  }
+},
+
+
+/**
+ * Handler for keyboard events
+ */
+key_press: function(e)
+{
+  if (this.focused != true)
+    return true;
+
+  var keyCode = rcube_event.get_keycode(e);
+  var mod_key = rcube_event.get_modifier(e);
+  switch (keyCode)
+  {
+    case 40:
+    case 38: 
+    case 63233: // "down", in safari keypress
+    case 63232: // "up", in safari keypress
+      // Stop propagation so that the browser doesn't scroll
+      rcube_event.cancel(e);
+      return this.use_arrow_key(keyCode, mod_key);
+    default:
+      this.shiftkey = e.shiftKey;
+      this.key_pressed = keyCode;
+      this.trigger_event('keypress');
+      
+      if (this.key_pressed == this.BACKSPACE_KEY)
+        return rcube_event.cancel(e);
+  }
+  
+  return true;
+},
+
+/**
+ * Handler for keydown events
+ */
+key_down: function(e)
+{
+  switch (rcube_event.get_keycode(e))
+  {
+    case 40:
+    case 38: 
+    case 63233:
+    case 63232:
+      if (!rcube_event.get_modifier(e) && this.focused)
+        return rcube_event.cancel(e);
+        
+    default:
+  }
+  
+  return true;
+},
+
+
+/**
+ * Special handling method for arrow keys
+ */
+use_arrow_key: function(keyCode, mod_key)
+{
+  var new_row;
+  // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
+  // using the keypress event (but not the keydown or keyup event).
+  if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
+    new_row = this.get_next_row();
+  else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
+    new_row = this.get_prev_row();
+
+  if (new_row)
+  {
+    this.select_row(new_row.uid, mod_key, true);
+    this.scrollto(new_row.uid);
+  }
+
+  return false;
+},
+
+
+/**
+ * Try to scroll the list to make the specified row visible
+ */
+scrollto: function(id)
+{
+  var row = this.rows[id].obj;
+  if (row && this.frame)
+  {
+    var scroll_to = Number(row.offsetTop);
+
+    if (scroll_to < Number(this.frame.scrollTop))
+      this.frame.scrollTop = scroll_to;
+    else if (scroll_to + Number(row.offsetHeight) > Number(this.frame.scrollTop) + Number(this.frame.offsetHeight))
+      this.frame.scrollTop = (scroll_to + Number(row.offsetHeight)) - Number(this.frame.offsetHeight);
+  }
+},
+
+
+/**
+ * Handler for mouse move events
+ */
+drag_mouse_move: function(e)
+{
+  if (this.drag_start)
+  {
+    // check mouse movement, of less than 3 pixels, don't start dragging
+    var m = rcube_event.get_mouse_pos(e);
+
+    if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3))
+      return false;
+  
+    if (!this.draglayer)
+      this.draglayer = new rcube_layer('rcmdraglayer', {x:0, y:0, vis:0, zindex:2000});
+  
+    // get subjects of selectedd messages
+    var names = '';
+    var c, i, node, subject, obj;
+    for(var n=0; n<this.selection.length; n++)
+    {
+      if (n>12)  // only show 12 lines
+      {
+        names += '...';
+        break;
+      }
+
+      if (this.rows[this.selection[n]].obj)
+      {
+        obj = this.rows[this.selection[n]].obj;
+        subject = '';
+
+        for(c=0, i=0; i<obj.childNodes.length; i++)
+        {
+          if (obj.childNodes[i].nodeName == 'TD')
+          {
+            if (((node = obj.childNodes[i].firstChild) && (node.nodeType==3 || node.nodeName=='A')) &&
+              (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)))
+            {
+              subject = node.nodeType==3 ? node.data : node.innerHTML;
+             // remove leading spaces
+             subject = subject.replace(/^\s+/i, '');
+              // truncate line to 50 characters
+             names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />';
+              break;
+            }
+            c++;
+          }
+        }
+      }
+    }
+
+    this.draglayer.write(names);
+    this.draglayer.show(1);
+
+    this.drag_active = true;
+    this.trigger_event('dragstart');
+  }
+
+  if (this.drag_active && this.draglayer)
+  {
+    var pos = rcube_event.get_mouse_pos(e);
+    this.draglayer.move(pos.x+20, bw.ie ? pos.y-5+document.documentElement.scrollTop : pos.y-5);
+    this.trigger_event('dragmove', e);
+  }
+
+  this.drag_start = false;
+
+  return false;
+},
+
+
+/**
+ * Handler for mouse up events
+ */
+drag_mouse_up: function(e)
+{
+  document.onmousemove = null;
+
+  if (this.draglayer && this.draglayer.visible)
+    this.draglayer.show(0);
+
+  this.drag_active = false;
+  this.trigger_event('dragend');
+
+  rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
+  rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
+
+  var iframes = document.getElementsByTagName('IFRAME');
+  for (var n in iframes) {
+    var iframedoc;
+    
+    if (iframes[n].contentDocument)
+      iframedoc = iframes[n].contentDocument;
+    else if (iframes[n].contentWindow)
+      iframedoc = iframes[n].contentWindow.document;
+    else if (iframes[n].document)
+      iframedoc = iframes[n].document;
+
+    if (iframedoc) {
+      if (this.iframe_events[n]) {
+       if (iframedoc.removeEventListener)
+         iframedoc.removeEventListener('mousemove', this.iframe_events[n], false);
+       else if (iframedoc.detachEvent)
+         iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
+       else
+         iframedoc['onmousemove'] = null;
+       }
+      rcube_event.remove_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
+      }
+    }
+
+  return rcube_event.cancel(e);
+},
+
+
+
+/**
+ * set/unset a specific class name
+ */
+set_classname: function(obj, classname, set)
+{
+  var reg = new RegExp('\s*'+classname, 'i');
+  if (!set && obj.className.match(reg))
+    obj.className = obj.className.replace(reg, '');
+  else if (set && !obj.className.match(reg))
+    obj.className += ' '+classname;
+},
+
+
+/**
+ * Setter for object event handlers
+ *
+ * @param {String}   Event name
+ * @param {Function} Handler function
+ * @return Listener ID (used to remove this handler later on)
+ */
+addEventListener: function(evt, handler)
+{
+  if (this.events[evt]) {
+    var handle = this.events[evt].length;
+    this.events[evt][handle] = handler;
+    return handle;
+  }
+  else
+    return false;
+},
+
+
+/**
+ * Removes a specific event listener
+ *
+ * @param {String} Event name
+ * @param {Int}    Listener ID to remove
+ */
+removeEventListener: function(evt, handle)
+{
+  if (this.events[evt] && this.events[evt][handle])
+    this.events[evt][handle] = null;
+},
+
+
+/**
+ * This will execute all registered event handlers
+ * @private
+ */
+trigger_event: function(evt, p)
+{
+  if (this.events[evt] && this.events[evt].length) {
+    for (var i=0; i<this.events[evt].length; i++)
+      if (typeof(this.events[evt][i]) == 'function')
+        this.events[evt][i](this, p);
+  }
+}
+
+
+};
+
index e78ea10a943936008cdc22263b2a7bd512856c76..dbf0943d54f8e0c6d77d49dea859e350113218f6 100644 (file)
@@ -522,9 +522,9 @@ class html2text
             $this->_link_count++;
             $this->_link_list .= "[" . $this->_link_count . "] $link\n";
             $additional = ' [' . $this->_link_count . ']';
-               } elseif ( substr($link, 0, 11) == 'javascript:' ) {
-                       // Don't count the link; ignore it
-                       $additional = '';
+       } elseif ( substr($link, 0, 11) == 'javascript:' ) {
+               // Don't count the link; ignore it
+               $additional = '';
                // what about href="#anchor" ?
         } else {
             $this->_link_count++;
index 67a2b7b3cbc7577732531f384a491ab345680e39..995d82fb61240d8359cee1ef5255425b3de6f9bb 100644 (file)
@@ -335,6 +335,7 @@ function iil_StartsWithI($string, $match, $bye=false) {
        }
        if ($bye && strncmp($string, '* BYE ', 6) == 0) {
                return true;
+
        }
        return false;
 }
@@ -383,6 +384,12 @@ function iil_C_GetCapability(&$conn, $name)
        return false;
 }
 
+function iil_C_ClearCapability(&$conn)
+{
+       $conn->capability = array();
+       $conn->capability_readed = false;
+}
+
 function iil_C_Authenticate(&$conn, $user, $pass, $encChallenge) {
     
     $ipad = '';
@@ -564,7 +571,7 @@ function iil_Connect($host, $user, $password, $options=null) {
                
        $result = false;
        
-       //initialize connection
+       // initialize connection
        $conn              = new iilConnection;
        $conn->error       = '';
        $conn->errorNum    = 0;
@@ -598,16 +605,15 @@ function iil_Connect($host, $user, $password, $options=null) {
                $iil_errornum = -1;
                return false;
        }
+
        if (!$ICL_PORT) {
                $ICL_PORT = 143;
        }
-    
        //check for SSL
-       if ($ICL_SSL) {
+       if ($ICL_SSL && $ICL_SSL != 'tls') {
                $host = $ICL_SSL . '://' . $host;
        }
-       
-       //open socket connection
+
        $conn->fp = fsockopen($host, $ICL_PORT, $errno, $errstr, 10);
        if (!$conn->fp) {
                $iil_error = "Could not connect to $host at port $ICL_PORT: $errstr";
@@ -625,6 +631,29 @@ function iil_Connect($host, $user, $password, $options=null) {
 
        $conn->message .= $line;
 
+       // TLS connection
+       if ($ICL_SSL == 'tls' && iil_C_GetCapability($conn, 'STARTTLS')) {
+               if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
+                               iil_PutLine($conn->fp, 'stls000 STARTTLS');
+
+                       $line = iil_ReadLine($conn->fp, 4096);
+                       if (!iil_StartsWith($line, 'stls000 OK')) {
+                               $iil_error = "Server responded to STARTTLS with: $line";
+                               $iil_errornum = -2;
+                               return false;
+                       }
+
+                       if (!stream_socket_enable_crypto($conn->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+                               $iil_error = "Unable to negotiate TLS";
+                               $iil_errornum = -2;
+                               return false;
+                       }
+                       
+                       // Now we're authenticated, capabilities need to be reread
+                       iil_C_ClearCapability($conn);
+               }
+       }
+
        if (strcasecmp($auth_method, "check") == 0) {
                //check for supported auth methods
                if (iil_C_GetCapability($conn, 'AUTH=CRAM-MD5') || iil_C_GetCapability($conn, 'AUTH=CRAM_MD5')) {
@@ -2433,7 +2462,7 @@ function iil_C_FetchMIMEHeaders(&$conn, $mailbox, $id, $parts) {
 
        // format request
        foreach($parts as $part)
-               $peeks[] = "BODY[$part.MIME]";
+               $peeks[] = "BODY.PEEK[$part.MIME]";
        
        $request = "$key FETCH $id (" . implode(' ', $peeks) . ')';
 
index f9b7c368432c2478b445ddc5a1884f451b3f6f25..8e3682a9bbdc30d6bddeab2979a4b761f2709acd 100644 (file)
@@ -102,7 +102,7 @@ function tnef_geti32(&$buf)
 
 function tnef_decode_attribute($attribute, &$buf)
 {
-   global $debug, $download;
+   global $debug;
 
    $length = tnef_geti32($buf);
    $value = tnef_getx($length, $buf); //data
@@ -116,9 +116,9 @@ function tnef_decode_attribute($attribute, &$buf)
    switch($attribute)
    {
       case TNEF_BODYTEXT:
-         if (!$download)
+         if ($debug)
          {
-            printf("<b>Embedded message:</b><pre>%s</pre>",$value);
+            printf("<b>Embedded message:</b><pre>%s</pre>", $value);
          }
          break;
 
@@ -195,7 +195,7 @@ function extract_mapi_attrs($buf, &$attachment_data)
 
          case TNEF_MAPI_ATTACH_DATA:
             tnef_getx(16, $value); // skip the next 16 bytes (unknown data)
-            array_shift($attachment_data); // eliminate the current (bogus) attachment
+           array_shift($attachment_data); // eliminate the current (bogus) attachment
             do_tnef_decode($value, $attachment_data); // recursively process the attached message
             break;
 
@@ -349,4 +349,4 @@ function tnef_decode($buf)
 
 }
 
-?>
\ No newline at end of file
+?>
index 3a9a162614a1814953f9fbfce48904357b266d5e..c6db21f82935f41b0c4fba974ab5587e66c2fe26 100644 (file)
@@ -1,9 +1,8 @@
 <?php
 
 /*
-
 +-----------------------------------------------------------------------+
-| language/da/labels.inc                                                |
+| language/da_DK/labels.inc                                             |
 |                                                                       |
 | Language file of the RoundCube Webmail client                         |
 | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
@@ -15,7 +14,7 @@
 |         Søren Aggeboe <soren@aggeboe.dk>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -122,6 +121,9 @@ $labels['select'] = 'Vælg';
 $labels['all'] = 'Alle';
 $labels['none'] = 'Ingen';
 $labels['unread'] = 'Ulæste';
+$labels['flagged'] = 'Markeret';
+$labels['unanswered'] = 'Ubesvaret';
+$labels['filter'] = 'Filter';
 $labels['compact'] = 'Ryd op';
 $labels['empty'] = 'Tøm';
 $labels['purge'] = 'Udrens';
@@ -217,14 +219,20 @@ $labels['logoutclear'] = 'Tøm Skrald når jeg logger af';
 $labels['logoutcompact'] = 'Komprimér Indbakke når jeg logger af';
 $labels['uisettings'] = 'Brugerinterface';
 $labels['serversettings'] = 'Serverindstillinger';
+$labels['mdnrequests'] = 'Kvitteringer';
 $labels['askuser'] = 'spørg brugeren';
 $labels['autosend'] = 'send automatisk';
 $labels['ignore'] = 'ignorér';
 $labels['readwhendeleted'] = 'Markér beskeden som læst ved sletning';
+$labels['flagfordeletion'] = 'Markér beskeden til sletning istedet for at slette';
 $labels['skipdeleted'] = 'Skjul slettede beskeder';
+$labels['showremoteimages'] = 'Vis eksterne indlejrede billeder';
+$labels['fromknownsenders'] = 'fra kendte afsendere';
+$labels['always'] = 'altid';
 $labels['showinlineimages'] = 'Vis vedhæftede billeder under beskeden';
 $labels['autosavedraft'] = 'Gem kladde automatisk';
 $labels['everynminutes'] = 'hver $n. minut';
+$labels['keepaliveevery'] = 'hver $n. minut';
 $labels['never'] = 'aldrig';
 $labels['messagesdisplaying'] = 'Viser beskeder';
 $labels['messagescomposition'] = 'Skriver nye beskeder';
@@ -233,6 +241,8 @@ $labels['2231folding'] = 'Fuld RFC 2231 understøttelse (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 understøttelse (MS Outlook)';
 $labels['2047folding'] = 'Fuld RFC 2047 understøttelse (andre)';
 $labels['advancedoptions'] = 'Advancerede muligheder';
+$labels['focusonnewmessage'] = 'Fokusér browservindue når der kommer nye beskeder';
+$labels['checkallfolders'] = 'Tjek alle mapper for nye beskeder';
 $labels['folder'] = 'Mappe';
 $labels['folders'] = 'Mapper';
 $labels['foldername'] = 'Mappenavn';
@@ -254,3 +264,4 @@ $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 
 ?>
+
index 910c204222f7c42b60a47ce0d9f0d911ace8d29d..59c4ae6f9877dfa18490db7d581b5bfb3323b056 100644 (file)
@@ -1,21 +1,20 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| language/da_DK/messages.inc                                           |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author : Martin Moeller <martin@liga.dk>                              |
+|         Jesper R. Meyer <jesper@upthere.dk>                           |
+|         Søren Aggeboe <soren@aggeboe.dk>                              |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/da/messages.inc                                              |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author : Martin Moeller <martin@liga.dk>                              |
- |         Jesper R. Meyer <jesper@upthere.dk>                           |
- |         Søren Aggeboe <soren@aggeboe.dk>                              |
- +-----------------------------------------------------------------------+
-
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -42,6 +41,8 @@ $messages['encryptedmessage'] = 'Beskeden er krypteret og kan ikke vises. Beklag
 $messages['nocontactsfound'] = 'Ingen kontakter blev fundet';
 $messages['contactnotfound'] = 'Den søgte kontakt blev ikke fundet';
 $messages['sendingfailed'] = 'Beskeden kunne ikke sendes';
+$messages['senttooquickly'] = 'Vent venligst $sec sekunder før du sender denne besked';
+$messages['errorsavingsent'] = 'Der opstod en fejl da den sendte besked blev gemt';
 $messages['errorsaving'] = 'Der opstod en fejl ved lagring af data';
 $messages['errormoving'] = 'Beskeden kunne ikke flyttes';
 $messages['errordeleting'] = 'Beskeden kunne ikke slettes';
@@ -49,10 +50,15 @@ $messages['deletecontactconfirm'] = 'Vil du virkelig slette den/de valgte kontak
 $messages['deletemessagesconfirm'] = 'Vil du virkelig slette den/de valgte besked(er)?';
 $messages['deletefolderconfirm'] = 'Vil du virkelig slette den valgte mappe';
 $messages['purgefolderconfirm'] = 'Vil du virkelig slette alle beskeder i denne mappe?';
+$messages['foldercreating'] = 'Opretter mappen...';
+$messages['folderdeleting'] = 'Sletter mappen...';
+$messages['folderrenaming'] = 'Omdøber mappen...';
+$messages['foldermoving'] = 'Flytter mappen...';
 $messages['formincomplete'] = 'Formularen var ikke fuldstændig fyldt ud';
 $messages['noemailwarning'] = 'Indtast venligst en gyldig e-mail adresse';
 $messages['nonamewarning'] = 'Angiv venligst et navn';
 $messages['nopagesizewarning'] = 'Angiv sidestørrelsen';
+$messages['nosenderwarning'] = 'Indtast venligst afsenders email-adresse';
 $messages['norecipientwarning'] = 'Indtast mindst én modtager';
 $messages['nosubjectwarning'] = '\'Emne\'-feltet er tomt. Kunne du tænke dig at skrive et nu?';
 $messages['nobodywarning'] = 'Send denne besked uden tekst?';
@@ -79,6 +85,16 @@ $messages['movingmessage'] = 'Flytter besked...';
 $messages['receiptsent'] = 'Kvittering for læsning er sendt';
 $messages['errorsendingreceipt'] = 'Kvitteringen kunne ikke sendes';
 $messages['nodeletelastidentity'] = 'Du kan ikke slette denne identitet, da det er den eneste der er tilbage.';
-$messages['addsubfolderhint'] = 'Denne mappe vil blive oprettet som en undermappe af den der er valgt i øjeblikket.';
+$messages['addsubfolderhint'] = 'Denne mappe vil blive oprettet som en undermappe til den mappe der er valgt i øjeblikket.';
+$messages['forbiddencharacter'] = 'Mappe-navnet indeholder ugyldige tegn';
+$messages['selectimportfile'] = 'Vælg venligst den fil der skal uploades';
+$messages['addresswriterror'] = 'Der kan ikke skrives i den valgte adressebog';
+$messages['importwait'] = 'Importerer, vent venligst...';
+$messages['importerror'] = 'Fejl i importen! Den uploadede fil er ikke en gyldig vCard fil.';
+$messages['importconfirm'] = '<b>Importerede $inserted kontakter, sprang over $skipped allerede eksisterende kontakter</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Handlingen er ikke tilladt!';
+$messages['nofromaddress'] = 'Der mangler en email-adresse i den valgte identitet';
+$messages['editorwarning'] = 'Al formatering af teksten forsvinder, hvis der skiftes til ren tekst. Vil du fortsætte?';
 
 ?>
+
index 029454a8d87277bbb403356346867b66cd738242..6056fa170ea72997a3560fb8908bb08951f50b5e 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Weiran Zhang (weiran@weiran.co.uk)                            |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -131,6 +131,8 @@ $labels['unknown'] = 'unknown';
 $labels['unlimited'] = 'unlimited';
 $labels['quicksearch'] = 'Quick search';
 $labels['resetsearch'] = 'Reset search';
+$labels['searchmod']  = 'Search modifiers';
+$labels['msgtext']  = 'Entire message';
 $labels['openinextwin'] = 'Open in new window';
 $labels['compose'] = 'Compose a message';
 $labels['savemessage'] = 'Save this draft';
index 2558e013bec57ace7878efc5220e2497ae023b19..d8d05a18e02bdffd9f1bbf5c3a87d9a2a1f011a6 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+ @version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -161,6 +161,8 @@ $labels['unlimited']  = 'unlimited';
 
 $labels['quicksearch']  = 'Quick search';
 $labels['resetsearch']  = 'Reset search';
+$labels['searchmod']  = 'Search modifiers';
+$labels['msgtext']  = 'Entire message';
 
 $labels['openinextwin'] = 'Open in new window';
 
index a029447951baf712d1caded62d1c8c6eff8ea8a3..e9ac149873f2e684afd09d20a041063fd148b9a2 100644 (file)
@@ -131,6 +131,8 @@ $labels['unknown'] = 'teadmata';
 $labels['unlimited'] = 'piiramatu';
 $labels['quicksearch'] = 'Kiirotsing';
 $labels['resetsearch'] = 'Lähtesta otsing';
+$labels['searchmod'] = 'Otsingu laiendid';
+$labels['msgtext'] = 'Kogu kirjast';
 $labels['openinextwin'] = 'Ava uues aknas';
 $labels['compose'] = 'Koosta kiri';
 $labels['savemessage'] = 'Salvesta see mustand';
index 1057468313ca2963201d4b2a7fd9ef012cb286f0..faefcabde5a6898312870eb43e327352a85bf050 100644 (file)
@@ -5,7 +5,7 @@
 | language/gl_ES/labels.inc                                             |
 |                                                                       |
 | Language file of the RoundCube Webmail client                         |
-| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
@@ -158,7 +158,7 @@ $labels['maxuploadsize'] = 'O tamaño máximo permitido de ficheiro é de $size'
 $labels['addcc'] = 'Engadir Copia (CC)';
 $labels['addbcc'] = 'Engadir Copia Oculta (BCC)';
 $labels['addreplyto'] = 'Engadir Respostar a (Reply-To)';
-$labels['mdnrequest'] = 'O remitente desta mensaxe pediu ser notificado cando vostede lea esta mensaxe. Quere notificar ao remitente?';
+$labels['mdnrequest'] = 'O remitente desta mensaxe pediu ser notificado cando vostede a lea. Quere notificar ao remitente?';
 $labels['receiptread'] = 'Notificación da disposición da mensaxe (lectura)';
 $labels['yourmessage'] = 'Esta é unha notificación de disposición para a súa mensaxe';
 $labels['receiptnote'] = 'Nota: Esta notificación só confirma que a mensaxe se abriu no computador do destinatario. Non asegura que o destinatario o lera ou entendera o seu contido.';
index 9c9aad8a8a5f73786c87af29133c805fb2685dfc..daafd0845504fc76a0dd7273ae79ec56918bbf2d 100644 (file)
@@ -5,7 +5,7 @@
 | language/gl_ES/messages.inc                                           |
 |                                                                       |
 | Language file of the RoundCube Webmail client                         |
-| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Copyright (C) 2005-2008, RoundCube Dev. - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
@@ -40,8 +40,8 @@ $messages['sendingfailed'] = 'Fallou o envío da mensaxe';
 $messages['senttooquickly'] = 'Por favor, espere $sec segundos antes de enviar esta mensaxe';
 $messages['errorsavingsent'] = 'Ocurriu un erro mentres se gardaba a mensaxe enviada';
 $messages['errorsaving'] = 'Ocurriu un erro mentres se gardaba';
-$messages['errormoving'] = 'Non puiden mover a mensaxe';
-$messages['errordeleting'] = 'Non puiden eliminar a mensaxe';
+$messages['errormoving'] = 'Non se puido mover a mensaxe';
+$messages['errordeleting'] = 'Non se puido eliminar a mensaxe';
 $messages['deletecontactconfirm'] = 'Quere eliminar o(s) contacto(s) seleccionado(s)?';
 $messages['deletemessagesconfirm'] = 'Quere eliminar a(s) mensaxe(s) seleccionadas?';
 $messages['deletefolderconfirm'] = 'Quere eliminar este cartafol?';
@@ -70,13 +70,13 @@ $messages['nospellerrors'] = 'Non hai erros ortográficos';
 $messages['folderdeleted'] = 'Eliminouse correctamente o cartafol';
 $messages['deletedsuccessfully'] = 'Eliminouse correctamente';
 $messages['converting'] = 'Eliminando o formato da mensaxe...';
-$messages['messageopenerror'] = 'Non puiden cargar a mensaxe desde o servidor';
+$messages['messageopenerror'] = 'Non se puido cargar a mensaxe desde o servidor';
 $messages['fileuploaderror'] = 'Fallou a carga do ficheiro';
 $messages['filesizeerror'] = 'O ficheiro cargado é máis grande que o tamaño máximo de $size';
 $messages['copysuccess'] = 'Copiáronse correctamente $nr enderezos';
-$messages['copyerror'] = 'Non puiden copiar ningún enderezo';
+$messages['copyerror'] = 'Non se puido copiar ningún enderezo';
 $messages['sourceisreadonly'] = 'A orixe é de só lectura';
-$messages['errorsavingcontact'] = 'Non puiden gardar o contacto';
+$messages['errorsavingcontact'] = 'Non se puido gardar o contacto';
 $messages['movingmessage'] = 'Movendo mensaxe...';
 $messages['receiptsent'] = 'A notificación de disposición enviouse correctamente';
 $messages['errorsendingreceipt'] = 'Non se puido enviar a notificación de disposición';
index cdae9e8ed6cdeb774160c35636f0cf1b7b2b00f5..6e4012bdf3321aab8cdfaf05e7131a198ed4b6ed 100644 (file)
@@ -1,19 +1,18 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| language/hy_AM/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Vahan Yerkanian <vahan@arminco.com>                           |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/am/labels.inc                                                |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Vahan Yerkanian <vahan@arminco.com>                           |
- +-----------------------------------------------------------------------+
-
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -68,6 +67,30 @@ $labels['wednesday'] = 'Չորեքշաբթի';
 $labels['thursday'] = 'Հինգշաբթի';
 $labels['friday'] = 'Ուրբաթ';
 $labels['saturday'] = 'Շաբաթ';
+$labels['jan'] = 'Հնվ';
+$labels['feb'] = 'Փետ';
+$labels['mar'] = 'Մար';
+$labels['apr'] = 'Ապր';
+$labels['may'] = 'Մայ';
+$labels['jun'] = 'Հուս';
+$labels['jul'] = 'Հուլ';
+$labels['aug'] = 'Օգս';
+$labels['sep'] = 'Սեպ';
+$labels['oct'] = 'Հոկ';
+$labels['nov'] = 'Նոյ';
+$labels['dec'] = 'Դեկ';
+$labels['longjan'] = 'Հունվար';
+$labels['longfeb'] = 'Փետրվար';
+$labels['longmar'] = 'Մարտ';
+$labels['longapr'] = 'Ապրիլ';
+$labels['longmay'] = 'Մայիս';
+$labels['longjun'] = 'Հունիս';
+$labels['longjul'] = 'Հուլիս';
+$labels['longaug'] = 'Օգոստոս';
+$labels['longsep'] = 'Սեպտեմբեր';
+$labels['longoct'] = 'Հոկտեմբեր';
+$labels['longnov'] = 'Նոյեմբեր';
+$labels['longdec'] = 'Դեկտեմբեր';
 $labels['today'] = 'Այսօր';
 $labels['checkmail'] = 'Ստուգել նոր նամակները';
 $labels['writenewmessage'] = 'Նոր նամակ';
@@ -90,10 +113,15 @@ $labels['viewsource'] = 'Ցուցադրել նամակի կոդը';
 $labels['markmessages'] = 'Նշել նամակները';
 $labels['markread'] = 'որպես կարդացած';
 $labels['markunread'] = 'որպես չկարդացած';
+$labels['markflagged'] = 'որպես նշված';
+$labels['markunflagged'] = 'որպես չնշված';
 $labels['select'] = 'Նշել';
 $labels['all'] = 'Բոլորը';
 $labels['none'] = 'Չնշել';
 $labels['unread'] = 'Չկարդացածը';
+$labels['flagged'] = 'Նշված';
+$labels['unanswered'] = 'Անպատասխան';
+$labels['filter'] = 'Զտիչ';
 $labels['compact'] = 'Սեղմել';
 $labels['empty'] = 'Դատարկել';
 $labels['purge'] = 'Մաքրել';
@@ -102,6 +130,7 @@ $labels['unknown'] = 'անհայտ';
 $labels['unlimited'] = 'անսահմանափակ';
 $labels['quicksearch'] = 'Արագ որոնում';
 $labels['resetsearch'] = 'Վերսկսել որոնումը';
+$labels['openinextwin'] = 'Բացել նոր պատուհանում';
 $labels['compose'] = 'Գրել նամակ';
 $labels['savemessage'] = 'Հիշել որպես սևագիր';
 $labels['sendmessage'] = 'Ուղարկել';
@@ -122,8 +151,12 @@ $labels['high'] = 'Կարևոր';
 $labels['highest'] = 'Կարևորագույն';
 $labels['nosubject'] = '(առանց վերնագրի)';
 $labels['showimages'] = 'Ցուցադրել նկարները';
+$labels['alwaysshow'] = 'Միշտ ցուցադրել պատկերները $sender–ից';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Պարզ տեքստ';
+$labels['savesentmessagein'] = 'Գրանցել ուղարկված նամակը';
+$labels['dontsave'] = 'Չ՛գրանցել';
+$labels['maxuploadsize'] = 'Առավելագույն թույլատրելի ֆայլի չափը $size է';
 $labels['addcc'] = 'Ավելացնել Cc';
 $labels['addbcc'] = 'Ավելացնել Bcc';
 $labels['addreplyto'] = 'Ավելացնել Reply-To';
@@ -147,12 +180,19 @@ $labels['composeto'] = 'Գրել նամակ';
 $labels['contactsfromto'] = 'Հասցեներ $from–ից $to–ը եղած $count–ից';
 $labels['print'] = 'Տպել';
 $labels['export'] = 'Արտահանել';
+$labels['exportvcards'] = 'Արտահանել հասցեները vCard չափաձևով';
 $labels['previouspage'] = 'Ցուցադրել նախորդ էջը';
 $labels['firstpage'] = 'Ցուցադրել առաջին էջը';
 $labels['nextpage'] = 'Ցուցադրել հաջորդ էջը';
 $labels['lastpage'] = 'Ցուցադրել վերջին էջը';
 $labels['groups'] = 'Խմբեր';
 $labels['personaladrbook'] = 'Անձնական հասցեներ';
+$labels['import'] = 'Ներկրել';
+$labels['importcontacts'] = 'Ներկրել հասցեներ';
+$labels['importfromfile'] = 'Ներկրել ֆայլից';
+$labels['importreplace'] = 'Փոխել ողջ հասցեագիրքը';
+$labels['importtext'] = 'Դուք կարող եք ներկրել նոր հասցեներ առկա հասցեագրքից։ Համակարգը ընդունում է հասցեների ներկրումը <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> չափաձևով։';
+$labels['done'] = 'Ավարտված է';
 $labels['settingsfor'] = 'Նախասիրություններ';
 $labels['preferences'] = 'Ընդհանուր';
 $labels['userpreferences'] = 'Օգտվողի նախասիրություններ';
@@ -163,6 +203,7 @@ $labels['newidentity'] = 'Նոր անձ';
 $labels['newitem'] = 'Նոր իր';
 $labels['edititem'] = 'Խմբագրել իրը';
 $labels['setdefault'] = 'Հիմնական';
+$labels['autodetect'] = 'Ավտո';
 $labels['language'] = 'Լեզու';
 $labels['timezone'] = 'Ժամային գոտի';
 $labels['pagesize'] = 'Տողեր առ էջ';
@@ -171,9 +212,37 @@ $labels['dstactive'] = 'Ամառային ժամանակ';
 $labels['htmleditor'] = 'Ստեղծել HTML նամակներ';
 $labels['htmlsignature'] = 'HTML ստորագրություն';
 $labels['previewpane'] = 'Ցուցադրել պատուհանը';
+$labels['skin'] = 'Տեսքի տարբերակ';
+$labels['logoutclear'] = 'Դուրս գալուց դատարկել աղբարկղը';
+$labels['logoutcompact'] = 'Դուրս գալուց կարգի բերել փոստարկղը';
+$labels['uisettings'] = 'Տեսք';
+$labels['serversettings'] = 'Սերվերի կարգավորումներ';
+$labels['mailboxview'] = 'Փոստարկղի տեսք';
+$labels['mdnrequests'] = 'Տեղեկացումներ';
+$labels['askuser'] = 'Հարցնել օգտվողին';
+$labels['autosend'] = 'ուղարկել ավտոմատ';
+$labels['ignore'] = 'անտեսել';
+$labels['readwhendeleted'] = 'Ջնջելուց նշել նամակը որպես կարդացած';
+$labels['flagfordeletion'] = 'Ջնջելու փոխարեն նշել որպես ենթակա ջնջման ';
+$labels['skipdeleted'] = 'Ցույց չ՛տալ ջնջված նամակները';
+$labels['showremoteimages'] = 'Ցույց տալ հեռակա պատկերները';
+$labels['fromknownsenders'] = 'հայտնի հասցեատերերից';
+$labels['always'] = 'միշտ';
+$labels['showinlineimages'] = 'Ցուցադրել կցված պատկերները հաղորդագրության տակ';
 $labels['autosavedraft'] = 'Սևագրի ավտոմատ գրանցում';
 $labels['everynminutes'] = 'ամեն $n րոպեն';
+$labels['keepaliveevery'] = 'ամեն $n րոպեն';
+$labels['keepalive'] = 'Ստուգել նոր նամակները';
 $labels['never'] = 'երբեք';
+$labels['messagesdisplaying'] = 'նամակները ցուցադրելիս';
+$labels['messagescomposition'] = 'նամակ գրելիս';
+$labels['mimeparamfolding'] = 'Կցորդների անուններ';
+$labels['2231folding'] = 'Կատարյալ RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Կատարյալ RFC 2047 (այլ)';
+$labels['advancedoptions'] = 'Հավելյալ կարգավորումներ';
+$labels['focusonnewmessage'] = 'Առաջ բերել պատուհանը նոր նամակ ստանալիս';
+$labels['checkallfolders'] = 'Ստուգել բոլոր դարակները նոր նամակների համար';
 $labels['folder'] = 'Դարակ';
 $labels['folders'] = 'Դարակներ';
 $labels['foldername'] = 'Դարակի անուն';
@@ -185,8 +254,13 @@ $labels['rename'] = 'Վերանվանել';
 $labels['renamefolder'] = 'Վերանվանել դարակը';
 $labels['deletefolder'] = 'Ջնջել դարակը';
 $labels['managefolders'] = 'Կարգավորել դարակները';
+$labels['specialfolders'] = 'Հատուկ դարակներ';
 $labels['sortby'] = 'Դասավորել';
 $labels['sortasc'] = 'ըստ աճման';
 $labels['sortdesc'] = 'ըստ նվազման';
+$labels['B'] = 'Բ';
+$labels['KB'] = 'ԿԲ';
+$labels['MB'] = 'ՄԲ';
+$labels['GB'] = 'ԳԲ';
 
-?>
\ No newline at end of file
+?>
index 860c8cdfc4ce70cd9d72766a1ab15c029e9fc8ce..beb5e4ff62ebb408a0e7da82c9daf4664d995d29 100644 (file)
@@ -1,19 +1,18 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| language/hy_AM/messages.inc                                           |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Vahan Yerkanian <vahan@arminco.com>                           |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/am/messages.inc                                              |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Vahan Yerkanian <vahan@arminco.com>                           |
- +-----------------------------------------------------------------------+
-
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -40,6 +39,8 @@ $messages['encryptedmessage'] = 'Ներողություն, այս նամակը 
 $messages['nocontactsfound'] = 'Հասցեներ չկան';
 $messages['contactnotfound'] = 'Որոնվող հասցեն չգտնվեց';
 $messages['sendingfailed'] = 'Նամակի ուղարկումը ձախողվեց';
+$messages['senttooquickly'] = 'Խնդրում ենք սպասել $sec վարկյան մինչ այս նամակն ուղարկելը';
+$messages['errorsavingsent'] = 'Ուղարկված նամակի արխիվացումը խափանվեց';
 $messages['errorsaving'] = 'Գրանցման սխալ';
 $messages['errormoving'] = 'Նամակի տեղափոխման ձախողում';
 $messages['errordeleting'] = 'Նամակի ջնջման ձախողում';
@@ -47,10 +48,15 @@ $messages['deletecontactconfirm'] = 'Ուզու՞մ էք ջնջել նշված 
 $messages['deletemessagesconfirm'] = 'Ուզու՞մ էք ջնջել նշված նամակները';
 $messages['deletefolderconfirm'] = 'Ուզու՞մ էք ջնջել այս դարակը';
 $messages['purgefolderconfirm'] = 'Ուզու՞մ էք ջնջել այս դարակի բոլոր նամակները';
+$messages['foldercreating'] = 'Դարակը ստեղծվում է…';
+$messages['folderdeleting'] = 'Դարակը ջնջվում է…';
+$messages['folderrenaming'] = 'Դարակը վերանվանվում է…';
+$messages['foldermoving'] = 'Դարակը տեղափոխվում է…';
 $messages['formincomplete'] = 'Ձևը թերի է լրացված';
 $messages['noemailwarning'] = 'Մուտքագրեք ճիշտ էլ. հասցե';
 $messages['nonamewarning'] = 'Մուտքագրեք անուն';
 $messages['nopagesizewarning'] = 'Մուտքագրեք էջի չափս';
+$messages['nosenderwarning'] = 'Մուտքագրեք հասցեատիրոջ հասցեն';
 $messages['norecipientwarning'] = 'Մուտքագրեք նվազագույնը մեկ հասցեատեր';
 $messages['nosubjectwarning'] = 'Վերնագիր բացակայում է, ցանկանո՞ւմ եք լրացնել';
 $messages['nobodywarning'] = 'Ուղարկե՞լ այս նամակը դատարկ';
@@ -78,5 +84,14 @@ $messages['receiptsent'] = 'Նամակի ընթերցման ծանուցագիր
 $messages['errorsendingreceipt'] = 'Ծանուցագրի ուղարկումը ձախողվեց';
 $messages['nodeletelastidentity'] = 'Անհնար է ջնջել վերջին տարբերակը';
 $messages['addsubfolderhint'] = 'Այս դարակը կստեղծվի որպես նշվածի ենթադարակ';
+$messages['forbiddencharacter'] = 'Դարակի անունը պարունակում է անթույլատրելի նշան';
+$messages['selectimportfile'] = 'Ընտրեք ուղարկվող ֆայլը';
+$messages['addresswriterror'] = 'Ընտրված հասցեագիրքը ենթակա չէ փոփոխման';
+$messages['importwait'] = 'Ներկրումն ընթացքի մեջ է...';
+$messages['importerror'] = 'Ներկրումը խափանվեց։ Ներկրված ֆայլը vCard չափաձևի չէ։';
+$messages['importconfirm'] = '$inserted նոր ներկրված հասցեներ, $skipped արդեն առկա հասցեներ՝ <p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Գործողությունը անթույլատրելի է։';
+$messages['nofromaddress'] = 'Նշված անձը հասցե չունի։';
+$messages['editorwarning'] = 'Դեպի պարզ տեքստի խմբագրիչ անցման դեպքում կկորի տեքստի ձևավորումը։ Շարունակե՞լ։';
 
-?>
\ No newline at end of file
+?>
index 7f52479a79510829b4eeddd2982033572eeebf82..60d330b757c562e6e22e0c37a0c4364c56a7722e 100644 (file)
@@ -193,6 +193,7 @@ $labels['importcontacts'] = 'Import kontak';
 $labels['importfromfile'] = 'Import dari berkas:';
 $labels['importreplace'] = 'Ganti seluruh buku alamat';
 $labels['importtext'] = 'Anda bisa mengunggah kontak dari buku alamat yang sudah ada.<br/>Kami kebetulan mendukung pengimportan alamat dari format data <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>.';
+$labels['done'] = 'Selesai';
 $labels['settingsfor'] = 'Pengaturan untuk';
 $labels['preferences'] = 'Pilihan';
 $labels['userpreferences'] = 'Pilihan pengguna';
index edc7ef4067b3f3b56db6b1635ac140a03e334550..bb9adc63b55e103543acb0d87946ecd6efe57424 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: index.inc 2284 2009-02-09 12:47:50Z yllar $
+ $Id: index.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -68,6 +68,7 @@ $rcube_languages = array(
   'lt_LT' => 'Lithuanian',
   'mk_MK' => 'Macedonian',
   'ms_MY' => 'Malay',
+  'mr_IN' => 'Marathi',
   'nl_NL' => 'Nederlands',
   'ne_NP' => 'Nepali',
   'nb_NO' => 'Norsk (Bokmål)',
@@ -117,6 +118,7 @@ $rcube_language_aliases = array(
   'ne' => 'ne_NP',
   'no' => 'nn_NO',
   'ms' => 'ms_MY',
+  'mr' => 'mr_IN',
   'pl' => 'pl_PL',
   'tw' => 'zh_TW',
   'si' => 'si_LK',
index 38d03302be6356cfd16a53f0b7f9c7e2c06ecd45..bb936e95bbeefa8267fa6d4ddad8504127944787 100644 (file)
@@ -14,7 +14,7 @@
 |         Yusef Maali <contact@yusefmaali.net>                          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -121,6 +121,9 @@ $labels['select'] = 'Seleziona';
 $labels['all'] = 'Tutti';
 $labels['none'] = 'Nessuno';
 $labels['unread'] = 'Non letti';
+$labels['flagged'] = 'Contrassegnati';
+$labels['unanswered'] = 'Senza risposta';
+$labels['filter'] = 'Filtra';
 $labels['compact'] = 'Compatta';
 $labels['empty'] = 'Svuota';
 $labels['purge'] = 'Pulisci';
@@ -153,7 +156,7 @@ $labels['showimages'] = 'Visualizza immagini';
 $labels['alwaysshow'] = 'Mostra sempre immagini da $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Testo semplice';
-$labels['savesentmessagein'] = 'Salva messaggi inviati in';
+$labels['savesentmessagein'] = 'Salva messaggi inviati in';
 $labels['dontsave'] = 'non salvare';
 $labels['maxuploadsize'] = 'La dimensione massima consentita è $size';
 $labels['addcc'] = 'Aggiungi Cc';
@@ -190,7 +193,7 @@ $labels['import'] = 'Importa';
 $labels['importcontacts'] = 'Importa contatti';
 $labels['importfromfile'] = 'Importa da file:';
 $labels['importreplace'] = 'Sostituisci l\'intera rubrica';
-$labels['importtext'] = 'Puoi caricare i contatti da una rubrica esistente.Al momento è supportata l\'importazione dei contatti dal formato vCard.';
+$labels['importtext'] = 'Puoi caricare i contatti da una rubrica esistente. Al momento è supportata l\'importazione dei contatti dal formato vCard.';
 $labels['done'] = 'Fatto';
 $labels['settingsfor'] = 'Impostazioni per ';
 $labels['preferences'] = 'Preferenze';
@@ -217,18 +220,21 @@ $labels['logoutcompact'] = 'Compatta la Posta In Arrivo all\'uscita';
 $labels['uisettings'] = 'Interfaccia Utente';
 $labels['serversettings'] = 'Impostazioni Server';
 $labels['mailboxview'] = 'Vista Messaggi';
-$labels['mdnrequests'] = 'Notifiche Lettura';
+$labels['mdnrequests'] = 'Notifiche di lettura';
 $labels['askuser'] = 'chiedi all\'utente';
 $labels['autosend'] = 'invia automaticamente';
 $labels['ignore'] = 'ignora';
-$labels['readwhendeleted'] = 'Segna il messaggio come letto all\'eliminazione';
-$labels['flagfordeletion'] = 'Segna il messaggio per l\'eliminazione invece che eliminare';
-$labels['skipdeleted'] = 'Non mostrare messaggi eliminati';
+$labels['readwhendeleted'] = 'Marca il messaggio come letto prima di eliminarlo';
+$labels['flagfordeletion'] = 'Marca il messaggio come eliminato invece di eliminarlo';
+$labels['skipdeleted'] = 'Non mostrare i messaggi marcati come eliminati';
+$labels['showremoteimages'] = 'Mostra immagini remote contenute nel messaggio';
+$labels['fromknownsenders'] = 'da mittenti conosciuti';
+$labels['always'] = 'sempre';
 $labels['showinlineimages'] = 'Mostra immagini allegate sotto il messaggio';
 $labels['autosavedraft'] = 'Salva le bozze automaticamente';
 $labels['everynminutes'] = 'ogni $n minuti';
 $labels['keepaliveevery'] = 'ogni $n minuto(i)';
-$labels['keepalive'] = 'Verificare la presenza di nuovi messaggi su';
+$labels['keepalive'] = 'Controlla la presenza di nuovi messaggi';
 $labels['never'] = 'mai';
 $labels['messagesdisplaying'] = 'Visualizzazione Messaggi';
 $labels['messagescomposition'] = 'Composizione Messaggi';
@@ -237,7 +243,8 @@ $labels['2231folding'] = 'RFC 2231 completo (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
 $labels['2047folding'] = 'RFC 2047 completo (altri)';
 $labels['advancedoptions'] = 'Opzioni avanzate';
-$labels['focusonnewmessage'] = 'Finestra del browser sul nuovo messaggio';
+$labels['focusonnewmessage'] = 'Attiva la finestra del browser all\'arrivo di un nuovo messaggio';
+$labels['checkallfolders'] = 'Controlla tutte le cartelle per la presenza di nuovi messaggi';
 $labels['folder'] = 'Cartella';
 $labels['folders'] = 'Cartelle';
 $labels['foldername'] = 'Nome cartella';
index 49b415a7db3df10364c60a23810a77de187c43e5..1ff4b55df8d7471f574f45a1f974f2e62cc23ed0 100755 (executable)
@@ -1,19 +1,18 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| localization/ka_GE/labels.inc                                         |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Zaza Zviadadze <zviadadze@gmail.com>                          |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/ge/labels.inc                                                |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Zaza Zviadadze <zviadadze@gmail.com>                          |
- +-----------------------------------------------------------------------+
-
- @version $Id: labels.inc 842 2007-10-20 13:55:02Z  zaza$
+@version $Id: labels.inc 842 2009-03-16 01:00:02Z  zaza$
 
 */
 
@@ -68,6 +67,30 @@ $labels['wednesday'] = 'ოთხშაბათი';
 $labels['thursday'] = 'ხუთშაბათი';
 $labels['friday'] = 'პარასკევი';
 $labels['saturday'] = 'შაბათი';
+$labels['jan'] = 'იან';
+$labels['feb'] = 'თებ';
+$labels['mar'] = 'მარ';
+$labels['apr'] = 'აპრ';
+$labels['may'] = 'მაი';
+$labels['jun'] = 'ივნ';
+$labels['jul'] = 'ივლ';
+$labels['aug'] = 'აგვ';
+$labels['sep'] = 'სექ';
+$labels['oct'] = 'ოქტ';
+$labels['nov'] = 'ნოე';
+$labels['dec'] = 'დეკ';
+$labels['longjan'] = 'იანვარი';
+$labels['longfeb'] = 'თებერვალი';
+$labels['longmar'] = 'მარტი';
+$labels['longapr'] = 'აპრილი';
+$labels['longmay'] = 'მაისი';
+$labels['longjun'] = 'ივნისი';
+$labels['longjul'] = 'ივლისი';
+$labels['longaug'] = 'აგვისტო';
+$labels['longsep'] = 'სექტემბერი';
+$labels['longoct'] = 'ოქტომბერი';
+$labels['longnov'] = 'ნოემბერი';
+$labels['longdec'] = 'დეკემბერი';
 $labels['today'] = 'დღეს';
 $labels['checkmail'] = 'შემოწმება ახალ შეტყობინებაზე';
 $labels['writenewmessage'] = 'ახალი შეტყობინება';
@@ -90,10 +113,15 @@ $labels['viewsource'] = 'შიგთავსი';
 $labels['markmessages'] = 'მონიშნეთ შეტყობინებები';
 $labels['markread'] = 'როგორც წაკითხული';
 $labels['markunread'] = 'როგორც წაუკითხავი';
+$labels['markflagged'] = 'როგორც მონიშნული';
+$labels['markunflagged'] = 'როგორც მოუნიშნავი';
 $labels['select'] = 'მონიშვნა';
 $labels['all'] = 'ყველა';
 $labels['none'] = 'არცერთი';
 $labels['unread'] = 'წაუკითხავი';
+$labels['flagged'] = 'მონიშნული';
+$labels['unanswered'] = 'უპასუხო';
+$labels['filter'] = 'ფილტრი';
 $labels['compact'] = 'შეკუმშვა';
 $labels['empty'] = 'გაცარიელება';
 $labels['purge'] = 'გასუფთავება';
@@ -102,6 +130,7 @@ $labels['unknown'] = 'უცნობი';
 $labels['unlimited'] = 'შეუზღუდავი';
 $labels['quicksearch'] = 'სწრაფი ძიება';
 $labels['resetsearch'] = 'ძიების გასუფთავება';
+$labels['openinextwin'] = 'გახსნა ახალ ფანჯარაში';
 $labels['compose'] = 'შეტყობინების დაწერა';
 $labels['savemessage'] = 'დროებით შენახვა';
 $labels['sendmessage'] = 'შეტყობინების გაგზავნა';
@@ -122,8 +151,12 @@ $labels['high'] = 'მაღალი';
 $labels['highest'] = 'უმაღლესი';
 $labels['nosubject'] = '(უსათაურო)';
 $labels['showimages'] = 'გამოსახულების ჩვენება';
+$labels['alwaysshow'] = 'ყოველთვის გამოაჩინე სურათები $sender –გან';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'ტექსტური';
+$labels['savesentmessagein'] = 'შეინახე შეტყობინება';
+$labels['dontsave'] = 'არ შეინახო';
+$labels['maxuploadsize'] = 'მაქსიმალური დაშვებული ფაილის ზომა $size';
 $labels['addcc'] = 'დაამატე კოპიო';
 $labels['addbcc'] = 'დაამატე ფარული კოპიო';
 $labels['addreplyto'] = 'დაამატე გამომგზავნი';
@@ -147,12 +180,19 @@ $labels['composeto'] = 'ფოსტის გაგზავნა შერჩ
 $labels['contactsfromto'] = 'კონტაქტები $from დან $to ში $count';
 $labels['print'] = 'დაბეჭვდა';
 $labels['export'] = 'ექსპორტი';
+$labels['exportvcards'] = 'კონტაქტების ექსპორტი vCard ფორმატში';
 $labels['previouspage'] = 'წინას ჩვენება';
 $labels['firstpage'] = 'პირველის ჩვენება';
 $labels['nextpage'] = 'შემდეგის ჩვენება';
 $labels['lastpage'] = 'ბოლოს ჩვენება';
 $labels['groups'] = 'ჯგუფები';
 $labels['personaladrbook'] = 'პერსონალური მისამართები';
+$labels['import'] = 'შემოტანა';
+$labels['importcontacts'] = 'კონტაქტების შემოტანა';
+$labels['importfromfile'] = 'შემოტანა ფაილიდან:';
+$labels['importreplace'] = 'ჩაანაცვლეთ არსებული მისამართები';
+$labels['importtext'] = 'თქვენ შეგიძლიათ ატვირთოთ კონტაქტები აღნიშნული მისამართიდან. <br/> ჩვენ შეგვიძლია მივიღოთ მისამართები <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> მონაცემთა ფორმატში.';
+$labels['done'] = 'დასრულებულია';
 $labels['settingsfor'] = 'პარამეტრები';
 $labels['preferences'] = 'პარამეტრები';
 $labels['userpreferences'] = 'მომხმარებლის პარამეტრები';
@@ -163,6 +203,7 @@ $labels['newidentity'] = 'ახალი პროფილი';
 $labels['newitem'] = 'ახალი';
 $labels['edititem'] = 'რედაქტირება';
 $labels['setdefault'] = 'როგორც ზოგაგად';
+$labels['autodetect'] = 'ავტომატური';
 $labels['language'] = 'ენა';
 $labels['timezone'] = 'დროითი ზონა';
 $labels['pagesize'] = 'სტრიქონი გვერდზე';
@@ -171,13 +212,41 @@ $labels['dstactive'] = 'დროის გადაყვანა';
 $labels['htmleditor'] = 'შეტყობინების შექმნა HTML –ში';
 $labels['htmlsignature'] = 'HTML ხელმოწერა';
 $labels['previewpane'] = 'ჩვენება';
+$labels['skin'] = 'ინტერფეისი';
+$labels['logoutclear'] = 'წაშლილების გასუფთავება გამოსვლისას';
+$labels['logoutcompact'] = 'მიღებულების შეკუმშვა გამოსვლისას';
+$labels['uisettings'] = 'მომხმარებლის ინტერფეისი';
+$labels['serversettings'] = 'სერვერის პარამეტრები';
+$labels['mailboxview'] = 'საფოსტო ყუთის ჩვენება';
+$labels['mdnrequests'] = 'მგზავნელის შეტყობინებები';
+$labels['askuser'] = 'ჰკითხე მომხმარებელს';
+$labels['autosend'] = 'გაგზავნე ავტომატურად';
+$labels['ignore'] = 'იგნორირება';
+$labels['readwhendeleted'] = 'მონიშნე გზავნილი წაკითხულად წაშლის დროს';
+$labels['flagfordeletion'] = 'აღნიშნეთ გზავნილები როგორც წასაშლელი წაშლის ნაცვლად';
+$labels['skipdeleted'] = 'არ გამოაჩინო წაშლილი გზავნილები';
+$labels['showremoteimages'] = 'გამოაჩინე მოშორებული სურათები';
+$labels['fromknownsenders'] = 'ნაცნობი მგზავნელებისგან';
+$labels['always'] = 'ყოველთვის';
+$labels['showinlineimages'] = 'ატვირთული სურათები გამოაჩინე გზავნილის ქვემოთ';
 $labels['autosavedraft'] = 'ავტომატური შენახვა';
 $labels['everynminutes'] = 'ყოველ $n წუთში';
+$labels['keepaliveevery'] = 'ყოველ $n წუთში';
+$labels['keepalive'] = 'შეამოწმე ახალ შეტყობინებაზე';
 $labels['never'] = 'არასდროს';
+$labels['messagesdisplaying'] = 'გამოაჩინე შეტყობინებები';
+$labels['messagescomposition'] = 'შეტყობინებების შექმნა';
+$labels['mimeparamfolding'] = 'ბმულის სახელები';
+$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (other)';
+$labels['advancedoptions'] = 'დამატებითი პარამეტრები';
+$labels['focusonnewmessage'] = 'ფოკუსირება ახალ შეტყობინებებზე';
+$labels['checkallfolders'] = 'შეამოწმე ყველა საქაღალდე ახალ შეტყობინებაზე';
 $labels['folder'] = 'საქაღალდე';
 $labels['folders'] = 'საქაღალდეები';
 $labels['foldername'] = 'საქაღალდის დასახელება';
-$labels['subscribed'] = 'á\83\92á\83\90á\83\9bá\83\9dá\83ªერილია';
+$labels['subscribed'] = 'á\83\92á\83\90á\83\9bá\83\9dá\83¬ერილია';
 $labels['messagecount'] = 'შეტყობინებები';
 $labels['create'] = 'შექმნა';
 $labels['createfolder'] = 'საქაღალდის შექმნა';
@@ -185,8 +254,13 @@ $labels['rename'] = 'სახელის გადარქმევა';
 $labels['renamefolder'] = 'სახელის გადარქმევა საქაღალდისთვის';
 $labels['deletefolder'] = 'საქაღალდის წაშლა';
 $labels['managefolders'] = 'საქაღალდეების მართვა';
+$labels['specialfolders'] = 'სპეციალური საქაღალდე';
 $labels['sortby'] = 'დალაგება';
 $labels['sortasc'] = 'დალაგება ზრდადობით';
 $labels['sortdesc'] = 'დალაგება კლებადობით';
+$labels['B'] = 'ბ';
+$labels['KB'] = 'კბ';
+$labels['MB'] = 'მბ';
+$labels['GB'] = 'გბ';
 
 ?>
index 43456d634e474cfbf5dcafa47676ddc30c4ca639..81b4bce6205312ca742eeb20b7bb33c11fc4a913 100755 (executable)
@@ -1,19 +1,18 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| localization/ka_GE/messages.inc                                       |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Zaza Zviadadze <zviadadze@gmail.com>                          |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/ge/messages.inc                                              |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Zaza Zviadadze <zviadadze@gmail.com>                          |
- +-----------------------------------------------------------------------+
-
- @version $Id: labels.inc 842 2007-10-20 13:55:02Z  zaza $
+@version $Id: labels.inc 842 2009-03-16 01:00:02Z  zaza$
 
 */
 
@@ -40,6 +39,8 @@ $messages['encryptedmessage'] = 'შეტყობინება დაში
 $messages['nocontactsfound'] = 'კონტაქტი ვერ მოიძებნა';
 $messages['contactnotfound'] = 'მოთხოვნილი კონტაქტი ვერ მოიძებნა';
 $messages['sendingfailed'] = 'შეტყობინება ვერ გაიგზავნა';
+$messages['senttooquickly'] = 'გთხოვთ მოიცადოთ $sec წამი. სანამ იგზავნება შეტყობინება';
+$messages['errorsavingsent'] = 'შეცდომა სანამ ინახება გაგზავნილი შეტყობინება';
 $messages['errorsaving'] = 'შენახვის დროს მოხდა შეცდომა';
 $messages['errormoving'] = 'შეტყობინების გადატანა შეუძლებელია';
 $messages['errordeleting'] = 'შეტყობინების წაშლა შეუძლებელია';
@@ -47,10 +48,15 @@ $messages['deletecontactconfirm'] = 'ნამდვილად გსურთ
 $messages['deletemessagesconfirm'] = 'ნამდვილად გსურთ მონიშნული შეტყობინებების წაშლა?';
 $messages['deletefolderconfirm'] = 'ნამდვილად გსურთ ამ საქაღალდის წაშლა?';
 $messages['purgefolderconfirm'] = 'ნამდვილად გსურთ ყველა შეტყობინების წაშლა აღნიშნულ საქაღალდეში?';
+$messages['foldercreating'] = 'საქაღალდის შექმნა';
+$messages['folderdeleting'] = 'საქაღალდის წაშლა';
+$messages['folderrenaming'] = 'საქაღალდის სახელის შეცვლა';
+$messages['foldermoving'] = 'საქაღალდის გადატანა';
 $messages['formincomplete'] = 'ყველა ველი არ არის შევსებული';
 $messages['noemailwarning'] = 'მიუთითეთ სწორი ელ–ფოსტის მისამართი';
 $messages['nonamewarning'] = 'მიუთითეთ სახელი';
 $messages['nopagesizewarning'] = 'მიუთითეთ ფურცლის ზომა';
+$messages['nosenderwarning'] = 'გთხოვთ შეიტანოთ მგზავნელის ელ–ფოსტის მისამართი';
 $messages['norecipientwarning'] = 'მიუთითეთ მიმღები';
 $messages['nosubjectwarning'] = 'გსურთ თუ არა შეტყობინების გაგზავნა უსათაუროდ?';
 $messages['nobodywarning'] = 'გსურთ თუ არა შეტყობინების გაგზავნა უტექსტოდ?';
@@ -78,5 +84,14 @@ $messages['receiptsent'] = 'წარმატებით გაიგზავ
 $messages['errorsendingreceipt'] = 'არ გაიგზავნა';
 $messages['nodeletelastidentity'] = 'წაშლა შეუძლებელია, ის თქვენთვის ერთადერთია';
 $messages['addsubfolderhint'] = 'საქაღალდე შეიქმნება როგორც ქვესაქაღალდე მონიშნულ საქაღალდეში';
+$messages['forbiddencharacter'] = 'საქაღალდის სახელი შეიცავს აკრძალულ სიმბოლოებს';
+$messages['selectimportfile'] = 'გთხოვთ მონიშნოთ ფაილი ასატვირთად';
+$messages['addresswriterror'] = 'მონიშნულ მისამართებში ჩაწერა შეუძლებელია';
+$messages['importwait'] = 'გთხოვთ მოიცადოთ, მიმდინარეობს შემოტანა';
+$messages['importerror'] = 'შემოტანა გაუქმდა! ატვირთული ფაილის ფორმატი არ ემთხვევა დასაშვებ vCard ფორმატს';
+$messages['importconfirm'] = '<b>წარმატებით დასრულდა $inserted კონტაქტების შემოტანა, $skipped არსებულის გამოტოვება</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'ოპერაცია შეზღუდულია';
+$messages['nofromaddress'] = 'ელ–ფოსტის მისამართი გამოტოვებულია';
+$messages['editorwarning'] = 'რედაქტორის გადართვა ტექსტურ რეჟიმში გამოიწვევს არსებული ტექსტის ფორმატის დაკარგვას. გსურთ გაგრძელება?';
 
 ?>
index 5f8c19eee2a9c5a6d38f67e0c600d32d652805d0..b34df37c23d88e6207dec70ee5bfa9bbe6c8b498 100644 (file)
@@ -2,19 +2,20 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/lv/labels.inc                                                |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Rudolfs Osins <dev.random@gmail.com>                          |
- |         Mikelis Zalais <mik@prog.lv>                                  |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/lv/labels.inc                                                |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Rudolfs Osins <dev.random@gmail.com>                          |
+|         Mikelis Zalais <mik@prog.lv>                                  |
+|         Lauris Bukšis-Haberkorns <lauris@nix.lv>                      |
++-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -69,6 +70,30 @@ $labels['wednesday'] = 'Trešdiena';
 $labels['thursday'] = 'Ceturtdiena';
 $labels['friday'] = 'Piektdiena';
 $labels['saturday'] = 'Sestdiena';
+$labels['jan'] = 'Jan';
+$labels['feb'] = 'Feb';
+$labels['mar'] = 'Mar';
+$labels['apr'] = 'Apr';
+$labels['may'] = 'Mai';
+$labels['jun'] = 'Jūn';
+$labels['jul'] = 'Jūl';
+$labels['aug'] = 'Aug';
+$labels['sep'] = 'Sep';
+$labels['oct'] = 'Okt';
+$labels['nov'] = 'Nov';
+$labels['dec'] = 'Dec';
+$labels['longjan'] = 'Janvāris';
+$labels['longfeb'] = 'Februāris';
+$labels['longmar'] = 'Marts';
+$labels['longapr'] = 'Aprīlis';
+$labels['longmay'] = 'Maijs';
+$labels['longjun'] = 'Jūnijs';
+$labels['longjul'] = 'Jūlijs';
+$labels['longaug'] = 'Augusts';
+$labels['longsep'] = 'Septembris';
+$labels['longoct'] = 'Oktobris';
+$labels['longnov'] = 'Novembris';
+$labels['longdec'] = 'Decembris';
 $labels['today'] = 'Šodien';
 $labels['checkmail'] = 'Pārbaudīt pastu';
 $labels['writenewmessage'] = 'Rakstīt jaunu vēstuli';
@@ -91,10 +116,15 @@ $labels['viewsource'] = 'Rādīt pirmtekstu';
 $labels['markmessages'] = 'Atzīmēt vēstules';
 $labels['markread'] = 'Kā lasītas';
 $labels['markunread'] = 'Kā nelasītas';
+$labels['markflagged'] = 'Kā iezīmētas';
+$labels['markunflagged'] = 'Kā neiezīmētas';
 $labels['select'] = 'Iezīmēt';
 $labels['all'] = 'Visas';
 $labels['none'] = 'Nevienu';
 $labels['unread'] = 'Nelasītās';
+$labels['flagged'] = 'Iezīmētas';
+$labels['unanswered'] = 'Neatbildētas';
+$labels['filter'] = 'Filtrēt';
 $labels['compact'] = 'Saspiest';
 $labels['empty'] = 'Iztukšot';
 $labels['purge'] = 'Iztīrīt';
@@ -103,6 +133,7 @@ $labels['unknown'] = 'nezināms';
 $labels['unlimited'] = 'neierobežots';
 $labels['quicksearch'] = 'Ārtā meklēšana';
 $labels['resetsearch'] = 'Atstatīt meklēšanu';
+$labels['openinextwin'] = 'Atvērt jaunā logā';
 $labels['compose'] = 'Rakstīt vēstuli';
 $labels['savemessage'] = 'Saglabāt uzmetumu';
 $labels['sendmessage'] = 'Sūtīt vēstuli';
@@ -123,8 +154,12 @@ $labels['high'] = 'Augsta';
 $labels['highest'] = 'Augstākā';
 $labels['nosubject'] = '(no subject)';
 $labels['showimages'] = 'Rādīt attēlus';
+$labels['alwaysshow'] = 'Vienmēr rādīt attēlos no $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Vienkāršs teksts';
+$labels['savesentmessagein'] = 'Saglabāt nosūtīto vēstuli mapē';
+$labels['dontsave'] = 'nesaglabāt';
+$labels['maxuploadsize'] = 'Maksimālais atļautais faila izmērs ir $size';
 $labels['addcc'] = 'Pievienot Cc';
 $labels['addbcc'] = 'Pievienot Bcc';
 $labels['addreplyto'] = 'Pievienot Reply-To';
@@ -148,12 +183,19 @@ $labels['composeto'] = 'Rakstīt vēstuli';
 $labels['contactsfromto'] = 'Ieraksti $from līdz $to no $count';
 $labels['print'] = 'Drukāt';
 $labels['export'] = 'Eksportēt';
+$labels['exportvcards'] = 'Eksportēt kontaktus vCard formātā';
 $labels['previouspage'] = 'Parādīt iepriekšējo kopu';
 $labels['firstpage'] = 'Parādīt pirmo kopu';
 $labels['nextpage'] = 'Parādīt nākamo kopu';
 $labels['lastpage'] = 'Parādīt pēdējo kopu';
 $labels['groups'] = 'Grupas';
 $labels['personaladrbook'] = 'Personīgās adreses';
+$labels['import'] = 'Importēt';
+$labels['importcontacts'] = 'Importēt kontaktus';
+$labels['importfromfile'] = 'Importēt no faila:';
+$labels['importreplace'] = 'Aizvietot visu adrešu grāmatu';
+$labels['importtext'] = 'Jūst varat augšupielādēt kontaktus no citas adrešu grāmatas.<br/>Pašlaik ir atbalstīts adrešu imports no <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> datu formāta.';
+$labels['done'] = 'Pabeigts';
 $labels['settingsfor'] = 'Iestatījumi';
 $labels['preferences'] = 'Preferences';
 $labels['userpreferences'] = 'Lietotāja preferences';
@@ -164,6 +206,7 @@ $labels['newidentity'] = 'Jauna identitāte';
 $labels['newitem'] = 'Jauns';
 $labels['edititem'] = 'Rediģēt';
 $labels['setdefault'] = 'Uzlikt kā noklusēto';
+$labels['autodetect'] = 'Automātiski';
 $labels['language'] = 'Valoda';
 $labels['timezone'] = 'Laika zona';
 $labels['pagesize'] = 'Rindas lapā';
@@ -172,9 +215,35 @@ $labels['dstactive'] = 'Vasaras/ziemas laiks';
 $labels['htmleditor'] = 'Rakstīt HTML vēstules';
 $labels['htmlsignature'] = 'HTML paraksts';
 $labels['previewpane'] = 'Rādīt priekšskatījuma paneli';
+$labels['skin'] = 'Interfeisa izskats';
+$labels['logoutclear'] = 'Iztīrīt miskasti izejot';
+$labels['logoutcompact'] = 'Saspiest iesūtni izejot';
+$labels['uisettings'] = 'Lietotāja interfeiss';
+$labels['serversettings'] = 'Servera iestatījumi';
+$labels['askuser'] = 'jautāt lietotājam';
+$labels['autosend'] = 'sūtīt automātiski';
+$labels['ignore'] = 'ignorēt';
+$labels['readwhendeleted'] = 'Dzēšot atzīmēt vēstules kā izlasītas';
+$labels['flagfordeletion'] = 'Atzīmēt vēstules izdzēšanai, bet nedzēst';
+$labels['skipdeleted'] = 'Neattēlot dzēstās vēstules';
+$labels['showremoteimages'] = 'Attēlot attēlus, kas atrodas uz cita servera';
+$labels['fromknownsenders'] = 'no zināmiem sūtītājiem';
+$labels['always'] = 'vienmēr';
+$labels['showinlineimages'] = 'Attēlot pielikuma attēlus zem vēstules';
 $labels['autosavedraft'] = 'Automātiski saglabāt uzmetumu';
 $labels['everynminutes'] = 'katras $n minūtes';
+$labels['keepaliveevery'] = 'katru $n minūti(-es)';
+$labels['keepalive'] = 'Pārbaudīt jaunas vēstules mapēs';
 $labels['never'] = 'nekad';
+$labels['messagesdisplaying'] = 'Vēstuļu attēlošana';
+$labels['messagescomposition'] = 'Vēstuļu rakstīšana';
+$labels['mimeparamfolding'] = 'Pielikumu nosaukumi';
+$labels['2231folding'] = 'Pilns RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Pilns RFC 2047 (citi)';
+$labels['advancedoptions'] = 'Paplašināti iestatījumi';
+$labels['focusonnewmessage'] = 'Uztādīt pārluka fokusu uz jaunu vēstuli';
+$labels['checkallfolders'] = 'Pārbaudīt jaunās vēstulēs visās mapēs';
 $labels['folder'] = 'Mape';
 $labels['folders'] = 'Mapes';
 $labels['foldername'] = 'Mapes nosaukums';
@@ -186,8 +255,13 @@ $labels['rename'] = 'Pārsaukt';
 $labels['renamefolder'] = 'Pārsaukt mapi';
 $labels['deletefolder'] = 'Dzēst mapi';
 $labels['managefolders'] = 'Rediģēt mapes';
+$labels['specialfolders'] = 'Speciālās mapes';
 $labels['sortby'] = 'Kārtot pēc';
 $labels['sortasc'] = 'Kārtot augošā secībā';
 $labels['sortdesc'] = 'Kārtot dilstošā secībā';
+$labels['B'] = 'B';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
 
-?>
\ No newline at end of file
+?>
index 549f90587aa54fb34752f58ad1d3b54b162ba12e..3331df477a8c7e67cf704c929eecd2f4c9e177f9 100644 (file)
@@ -2,19 +2,20 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/lv/messages.inc                                              |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Rudolfs Osins <dev.random@gmail.com>                          |
- |         Mikelis Zalais <mik@prog.lv>                                  |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/lv/messages.inc                                              |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Rudolfs Osins <dev.random@gmail.com>                          |
+|         Mikelis Zalais <mik@prog.lv>                                  |
+|         Lauris Bukšis-Haberkorns <lauris@nix.lv>                      |
++-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -41,6 +42,8 @@ $messages['encryptedmessage'] = 'Šī ir šifrēta vēstule un diemžēl nevar t
 $messages['nocontactsfound'] = 'Ieraksti netika atrasti';
 $messages['contactnotfound'] = 'Prasītais kontakts nav atrasts';
 $messages['sendingfailed'] = 'Vēstule netika nosūtīta';
+$messages['senttooquickly'] = 'Lūdzu uzgaidiet $sec sekundi(-es) pirms sūtiet šo vēstuli';
+$messages['errorsavingsent'] = 'Notika kļūda saglabājot nosūtīto vēstuli';
 $messages['errorsaving'] = 'Saglabājot vēstuli notikusi kļūme, vēstule netika saglabāta';
 $messages['errormoving'] = 'Vēstule netika pārvietota';
 $messages['errordeleting'] = 'Vēstule netika dzēsta';
@@ -48,10 +51,15 @@ $messages['deletecontactconfirm'] = 'Vai tiešām vēlaties dzēst iezīmēto(ā
 $messages['deletemessagesconfirm'] = 'Vai tiešām vēlaties dzēst iezīmēto(ās) vēstules?';
 $messages['deletefolderconfirm'] = 'Vai tiešām vēlaties dzēst šo mapi?';
 $messages['purgefolderconfirm'] = 'Vai tiešām vēlaties dzēst visas vēstules, kas atrodas šajā mapē?';
+$messages['foldercreating'] = 'Izveidoju mapi...';
+$messages['folderdeleting'] = 'Dzēšu mapi...';
+$messages['folderrenaming'] = 'Pārsaucu mapi...';
+$messages['foldermoving'] = 'Pārvietoju mapi...';
 $messages['formincomplete'] = 'Formulārs nav pilnībā aizpildīts';
 $messages['noemailwarning'] = 'Lūdzu ievadiet pareizu e-pasta adresi';
 $messages['nonamewarning'] = 'Lūdzu ievadiet vārdu';
 $messages['nopagesizewarning'] = 'Lūdzu ievadiet lapas izmēru';
+$messages['nosenderwarning'] = 'Lūdzu ievadiet saņēmēja e-pasta adresi';
 $messages['norecipientwarning'] = 'Lūdzu ievadiet vismaz vienu saņēmēju';
 $messages['nosubjectwarning'] = 'Lauks "temats" ir tukšs. Vai vēlaties to aizpildīt tagad?';
 $messages['nobodywarning'] = 'Sūtīt vēstuli bez satura teksta?';
@@ -79,5 +87,14 @@ $messages['receiptsent'] = 'Saņemšanas apstiprinājums nosūtīts';
 $messages['errorsendingreceipt'] = 'Neizdevās nosūtīt apstiprinājumu';
 $messages['nodeletelastidentity'] = 'Šo identitāti nevar izdzēst, tā ir pati pēdējā.';
 $messages['addsubfolderhint'] = 'Šis folderis tiks izveidots kā apakšfolderis tam, kurš patreiz ir izvēlēts';
+$messages['forbiddencharacter'] = 'Mapes nosaukums satur aizliegtus simbolus';
+$messages['selectimportfile'] = 'Lūdzu izvēlieties failu, ko vēlaties augšupielādēt';
+$messages['addresswriterror'] = 'Izvēlētās adrešu grāmatas datus nevar labot';
+$messages['importwait'] = 'Importēju, lūdzu uzgaidiet...';
+$messages['importerror'] = 'Imports neizdevās! Augšupielādētais fails nav korekts vCard fails';
+$messages['importconfirm'] = '<b>Veiksmīgi ieimportēti $inserted kontakti, netika importēti $skipped esoši ieraksti</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Darbība nav atļauta!';
+$messages['nofromaddress'] = 'Izvēlētajai identitātei nav norādīta e-pasta adrese';
+$messages['editorwarning'] = 'Pārslēdzoties uz vienkāršotu teksta redaktoru, tiks pazaudēts esošais teksta formatējums. Vai vēlaties turpināt?';
 
-?>
\ No newline at end of file
+?>
index 218c90967550fa5a07dbb5b060035de2be635cf5..bd469ab72c60aff4bca62a0e50d5aad7a8a46adc 100644 (file)
@@ -2,19 +2,20 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/nb_NO/labels.inc                                             |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Kjetil Waage - Nextline AS <kjetil@nextline.no>               |
- | Author: Tor Erik Linnerud - JKLM <tel@jklm.no>                        |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/nb_NO/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Kjetil Waage - Nextline AS <kjetil@nextline.no>               |
+| Author: Tor Erik Linnerud - JKLM <tel@jklm.no>                        |
+| Author: Odd Henriksen <odd@digicon.no>                                |
++-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -52,7 +53,7 @@ $labels['download'] = 'last ned';
 $labels['filename'] = 'Filnavn';
 $labels['filesize'] = 'Filstørrelse';
 $labels['preferhtml'] = 'Foretrekk HTML';
-$labels['htmlmessage'] = 'HTML-beskjed';
+$labels['htmlmessage'] = 'HTML-melding';
 $labels['prettydate'] = 'Pen datovisning';
 $labels['addtoaddressbook'] = 'Tilføy til adresseboken';
 $labels['sun'] = 'Søn';
@@ -83,7 +84,7 @@ $labels['nov'] = 'Nov';
 $labels['dec'] = 'Des';
 $labels['longjan'] = 'Januar';
 $labels['longfeb'] = 'Februar';
-$labels['longmar'] = 'Marsj';
+$labels['longmar'] = 'Mars';
 $labels['longapr'] = 'April';
 $labels['longmay'] = 'Mai';
 $labels['longjun'] = 'Juni';
@@ -94,7 +95,7 @@ $labels['longoct'] = 'Oktober';
 $labels['longnov'] = 'November';
 $labels['longdec'] = 'Desember';
 $labels['today'] = 'I dag';
-$labels['checkmail'] = 'Sjekk for nye beskjeder';
+$labels['checkmail'] = 'Sjekk for nye meldinger';
 $labels['writenewmessage'] = 'Opprett en ny e-post';
 $labels['replytomessage'] = 'Svar på denne e-posten';
 $labels['replytoallmessage'] = 'Svar til alle mottakere';
@@ -112,13 +113,18 @@ $labels['lastmessage'] = 'Vis siste melding';
 $labels['lastmessages'] = 'Vis siste side med meldinger';
 $labels['backtolist'] = 'Tilbake til e-postlisten';
 $labels['viewsource'] = 'Vis kilde';
-$labels['markmessages'] = 'Merk e-postene';
+$labels['markmessages'] = 'Merk meldinger';
 $labels['markread'] = 'som lest';
 $labels['markunread'] = 'som ulest';
+$labels['markflagged'] = 'som flagget';
+$labels['markunflagged'] = 'som uflagget';
 $labels['select'] = 'Velg';
 $labels['all'] = 'Alle';
 $labels['none'] = 'Ingen';
 $labels['unread'] = 'Uleste';
+$labels['flagged'] = 'Flagget';
+$labels['unanswered'] = 'Ubesvarte';
+$labels['filter'] = 'Filter';
 $labels['compact'] = 'Rydd opp';
 $labels['empty'] = 'Tøm';
 $labels['purge'] = 'Tøm';
@@ -127,6 +133,7 @@ $labels['unknown'] = 'ukjent';
 $labels['unlimited'] = 'ubegrenset';
 $labels['quicksearch'] = 'Hurtigsøk';
 $labels['resetsearch'] = 'Nullstill søk';
+$labels['openinextwin'] = 'Åpne i nytt vindu';
 $labels['compose'] = 'Skriv ny e-post';
 $labels['savemessage'] = 'Lagre kladd';
 $labels['sendmessage'] = 'Send e-posten';
@@ -147,8 +154,12 @@ $labels['high'] = 'Høy';
 $labels['highest'] = 'Høyest';
 $labels['nosubject'] = '(intet emne)';
 $labels['showimages'] = 'Vis bilder';
+$labels['alwaysshow'] = 'Vis alltid bilder fra $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Ren tekst';
+$labels['savesentmessagein'] = 'Lagre sendt melding i';
+$labels['dontsave'] = 'ikke lagre';
+$labels['maxuploadsize'] = 'Maksimalt tillatt filstørrelse er $size';
 $labels['addcc'] = 'Legg til Cc';
 $labels['addbcc'] = 'Legg til Bcc';
 $labels['addreplyto'] = 'Legg til Reply-To';
@@ -171,13 +182,20 @@ $labels['deletecontact'] = 'Slett valgte kontakter';
 $labels['composeto'] = 'Skriv e-post til';
 $labels['contactsfromto'] = 'Kontakter $from til $to av $count';
 $labels['print'] = 'Skriv ut';
-$labels['export'] = 'Eksportere';
+$labels['export'] = 'Eksporter';
+$labels['exportvcards'] = 'Eksporter kontakter i vCard-format';
 $labels['previouspage'] = 'Vis forrige sett';
 $labels['firstpage'] = 'Vis første sett';
 $labels['nextpage'] = 'Vis neste sett';
 $labels['lastpage'] = 'Vis siste sett';
 $labels['groups'] = 'Grupper';
 $labels['personaladrbook'] = 'Egne adresser';
+$labels['import'] = 'Importer';
+$labels['importcontacts'] = 'Importer kontakter';
+$labels['importfromfile'] = 'Importer fra fil:';
+$labels['importreplace'] = 'Erstatt hele adresseboken';
+$labels['importtext'] = 'Du kan laste opp kontakter fra en eksisterende adressebok.<br/>For øyeblikket støttes importering av kontakter i <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>-formatet.';
+$labels['done'] = 'Fullført';
 $labels['settingsfor'] = 'Innstillinger for';
 $labels['preferences'] = 'Oppsett';
 $labels['userpreferences'] = 'Brukeroppsett';
@@ -188,6 +206,7 @@ $labels['newidentity'] = 'Ny identitet';
 $labels['newitem'] = 'Nytt punkt';
 $labels['edititem'] = 'Rediger punkt';
 $labels['setdefault'] = 'Sett som standard';
+$labels['autodetect'] = 'Auto';
 $labels['language'] = 'Språk';
 $labels['timezone'] = 'Tidssone';
 $labels['pagesize'] = 'Linjer per side';
@@ -196,13 +215,37 @@ $labels['dstactive'] = 'Sommertid';
 $labels['htmleditor'] = 'Bruk HTML-editor';
 $labels['htmlsignature'] = 'HTML-signatur';
 $labels['previewpane'] = 'Forhåndsvisning';
-$labels['logoutclear'] = 'Tøm søpel ved utlogging';
+$labels['skin'] = 'Utseende';
+$labels['logoutclear'] = 'Tøm søppel ved utlogging';
 $labels['logoutcompact'] = 'Kompakt innboksen ved utlogging';
 $labels['uisettings'] = 'Brukergrensesnitt';
 $labels['serversettings'] = 'Serverinnstillinger';
+$labels['mailboxview'] = 'E-postvisning';
+$labels['mdnrequests'] = 'Tilbakemelding til avsender';
+$labels['askuser'] = 'spør hver gang';
+$labels['autosend'] = 'send automatisk';
+$labels['ignore'] = 'ignorer';
+$labels['readwhendeleted'] = 'Merk melding som lest ved sletting';
+$labels['flagfordeletion'] = 'Flagg meldingen for sletting i stedet for å slette';
+$labels['skipdeleted'] = 'Ikke vis slettede meldinger';
+$labels['showremoteimages'] = 'Vis eksterne bilder i meldinger';
+$labels['fromknownsenders'] = 'fra kjente avsendere';
+$labels['always'] = 'alltid';
+$labels['showinlineimages'] = 'Vis vedlagte bilder under meldingen';
 $labels['autosavedraft'] = 'Autolagring av utkast';
 $labels['everynminutes'] = 'Hvert $n. minutt';
+$labels['keepaliveevery'] = 'hvert $n minutt';
+$labels['keepalive'] = 'Se etter ny e-post';
 $labels['never'] = 'Aldri';
+$labels['messagesdisplaying'] = 'Visning av meldinger';
+$labels['messagescomposition'] = 'Skriving av meldinger';
+$labels['mimeparamfolding'] = 'Vedleggsnavn';
+$labels['2231folding'] = 'Fullstendig RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Fullstendig RFC 2047 (andre)';
+$labels['advancedoptions'] = 'Avanserte alternativer';
+$labels['focusonnewmessage'] = 'Gi nettleservindu fokus ved nye meldinger';
+$labels['checkallfolders'] = 'Kontroller alle mapper for nye meldinger';
 $labels['folder'] = 'Mappe';
 $labels['folders'] = 'Mapper';
 $labels['foldername'] = 'Mappenavn';
@@ -214,8 +257,13 @@ $labels['rename'] = 'Endre navn';
 $labels['renamefolder'] = 'Endre navn på mappe';
 $labels['deletefolder'] = 'Slett mappe';
 $labels['managefolders'] = 'Rediger mapper';
+$labels['specialfolders'] = 'Spesielle mapper';
 $labels['sortby'] = 'Sorter etter';
 $labels['sortasc'] = 'Eldste først';
 $labels['sortdesc'] = 'Nyeste først';
+$labels['B'] = 'B';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
 
-?>
\ No newline at end of file
+?>
index 61e49bdd5bcc4824be44b70af91c54dbb31f4a9e..f74a32ccca28106cb9ac1581d82540c418bb3cdb 100644 (file)
@@ -2,19 +2,20 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/nb_NO/messages.inc                                           |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Kjetil Waage - Nextline AS <kjetil@nextline.no>               |
- | Author: Tor Erik Linnerud - JKLM <tel@jklm.no>                        |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/nb_NO/messages.inc                                           |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Kjetil Waage - Nextline AS <kjetil@nextline.no>               |
+| Author: Tor Erik Linnerud - JKLM <tel@jklm.no>                        |
+| Author: Odd Henriksen <odd@digicon.no>                                |
++-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -23,35 +24,42 @@ $messages['loginfailed'] = 'Pålogging mislyktes';
 $messages['cookiesdisabled'] = 'Din nettleser aksepterer ikke cookies';
 $messages['sessionerror'] = 'Din session er ugyldig eller utløpt';
 $messages['imaperror'] = 'Forbindelsen til IMAP serveren sviktet';
-$messages['nomessagesfound'] = 'Det ble ikke funnet noen beskjeder i denne innboksen';
+$messages['nomessagesfound'] = 'Det ble ikke funnet noen meldinger i denne innboksen';
 $messages['loggedout'] = 'Du er logget av webmail. Ha det bra!';
 $messages['mailboxempty'] = 'Postkassen er tom!';
 $messages['loading'] = 'Laster...';
 $messages['loadingdata'] = 'Laster data...';
-$messages['checkingmail'] = 'Sjekker for nye beskjeder...';
-$messages['sendingmessage'] = 'Sender beskjed...';
-$messages['messagesent'] = 'Beskjeden ble sendt uten feil';
-$messages['savingmessage'] = 'Lagrer beskjed...';
-$messages['messagesaved'] = 'Beskjed er lagret i "kladder" mappen';
+$messages['checkingmail'] = 'Sjekker for nye meldinger...';
+$messages['sendingmessage'] = 'Sender melding...';
+$messages['messagesent'] = 'Meldingen ble sendt uten feil';
+$messages['savingmessage'] = 'Lagrer melding...';
+$messages['messagesaved'] = 'Melding er lagret som utkast';
 $messages['successfullysaved'] = 'Lagret';
 $messages['addedsuccessfully'] = 'Kontakten ble tilføyd i adresseboken';
 $messages['contactexists'] = 'Der er allerede en kontakt med denne e-postadressen';
-$messages['blockedimages'] = 'Bilder fra eksterne servere er blokkert i denne e-posten.';
-$messages['encryptedmessage'] = 'Dette er en krypteret beskjed og kan ikke vises. Beklager!';
+$messages['blockedimages'] = 'Eksterne bilder er blitt blokkert i denne e-postmeldingen.';
+$messages['encryptedmessage'] = 'Dette er en kryptert melding og kan ikke vises. Beklager!';
 $messages['nocontactsfound'] = 'Ingen kontakter ble funnet';
 $messages['contactnotfound'] = 'Den forespurte kontakten ble ikke funnet';
 $messages['sendingfailed'] = 'Kunne ikke sende e-posten';
+$messages['senttooquickly'] = 'Vennligst vent $sec sekund(er) før du sender denne meldingen';
+$messages['errorsavingsent'] = 'En feil oppsto under lagring av sendt melding';
 $messages['errorsaving'] = 'Det oppstod en feil ved lagring av data';
-$messages['errormoving'] = 'Kunne ikke flytte beskjeden';
-$messages['errordeleting'] = 'Kunne ikke slette beskjeden';
+$messages['errormoving'] = 'Kunne ikke flytte meldingen';
+$messages['errordeleting'] = 'Kunne ikke slette meldingen';
 $messages['deletecontactconfirm'] = 'Vil du virkelig slette valgte kontakt(er)?';
-$messages['deletemessagesconfirm'] = 'Vil du virkelig slette de valgte meldingen(e)?';
+$messages['deletemessagesconfirm'] = 'Vil du virkelig slette de(n) valgte meldingen(e)?';
 $messages['deletefolderconfirm'] = 'Vil du virkelig slette denne mappen?';
 $messages['purgefolderconfirm'] = 'Vil du virkelig slette alle meldingene i denne mappen?';
+$messages['foldercreating'] = 'Oppretter mappe...';
+$messages['folderdeleting'] = 'Sletter mappe...';
+$messages['folderrenaming'] = 'Gir nytt navn til mappe...';
+$messages['foldermoving'] = 'Flytter mappe...';
 $messages['formincomplete'] = 'Skjemaet var ikke fullstendig fylt ut';
 $messages['noemailwarning'] = 'Skriv inn en gyldig e-post adresse';
 $messages['nonamewarning'] = 'Angi et navn';
 $messages['nopagesizewarning'] = 'Angi sidestørrelsen';
+$messages['nosenderwarning'] = 'Vennligst angi avsenderadresse';
 $messages['norecipientwarning'] = 'Skriv inn minst en mottaker';
 $messages['nosubjectwarning'] = '"Emne" feltet er tomt. Vil du skrive det inn nå?';
 $messages['nobodywarning'] = 'Send denne e-post uten tekst?';
@@ -79,5 +87,14 @@ $messages['receiptsent'] = 'Kvittering har blitt sent';
 $messages['errorsendingreceipt'] = 'Kunne ikke sende kvittering';
 $messages['nodeletelastidentity'] = 'Du kan ikke slette denne identiteten, det er din siste.';
 $messages['addsubfolderhint'] = 'Mappen vil bli opprettet som en undermappe av den nåværende valgte mappe';
+$messages['forbiddencharacter'] = 'Mappenavnet inneholder et tegn som ikke er tillatt';
+$messages['selectimportfile'] = 'Vennligst velg en fil for opplasting';
+$messages['addresswriterror'] = 'Den valgte adresseboken er ikke skrivbar';
+$messages['importwait'] = 'Importerer, vennligst vent...';
+$messages['importerror'] = 'Importering feilet! Den opplastede filen er ikke en gyldig vCard-fil.';
+$messages['importconfirm'] = '<b>Importerte $inserted kontakter vellykket, hoppet over $skipped eksisterende oppføringer</b>: <p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Handling ikke tillatt!';
+$messages['nofromaddress'] = 'E-postadresse mangler i valgt identitet';
+$messages['editorwarning'] = 'Å bytte format til ren tekst vil føre til at all tekstformatering går tapt. Ønsker du å fortsette?';
 
-?>
\ No newline at end of file
+?>
index c7d391256b97c85eeb3aa146017ec68936e9ec40..2041e47753f381974ba1f13b783272ab6afea471 100644 (file)
@@ -14,7 +14,7 @@
 |         Laurens Vets <laurens@daemon.be>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -121,7 +121,7 @@ $labels['select'] = 'Selecteren';
 $labels['all'] = 'Alles';
 $labels['none'] = 'Geen';
 $labels['unread'] = 'Ongelezen';
-$labels['flagged'] = 'Gemarkeerd';
+$labels['flagged'] = 'Geselecteerd';
 $labels['unanswered'] = 'Onbeantwoord';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Comprimeren';
index 2fcd4a29c3a237ebec215526d73be22813d4adb5..25ec8d92c22ca70c223b644ef5b26d395f12cc56 100644 (file)
@@ -15,7 +15,7 @@
 |         Laurens Vets <laurens@daemon.be>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -122,7 +122,7 @@ $labels['select'] = 'Selecteer';
 $labels['all'] = 'Allemaal';
 $labels['none'] = 'Geen';
 $labels['unread'] = 'Ongelezen';
-$labels['flagged'] = 'Gemarkeerd';
+$labels['flagged'] = 'Geselecteerd';
 $labels['unanswered'] = 'Onbeantwoord';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Opschonen';
@@ -133,6 +133,8 @@ $labels['unknown'] = 'onbekend';
 $labels['unlimited'] = 'onbeperkt';
 $labels['quicksearch'] = 'Snel zoeken';
 $labels['resetsearch'] = 'Reset zoekopdracht';
+$labels['searchmod'] = 'Zoekopties';
+$labels['msgtext'] = 'Gehele bericht';
 $labels['openinextwin'] = 'Openen in een nieuw venster';
 $labels['compose'] = 'Nieuw bericht aanmaken';
 $labels['savemessage'] = 'Bewaar als concept';
index dba23a8e0be0eb8604e62c8d3db72777062c49d7..7b8a39d64a16263dd0b61327cbf1bec76d5aeaef 100644 (file)
@@ -142,6 +142,8 @@ $labels['unknown'] = 'nieznane';
 $labels['unlimited'] = 'bez limitu';
 $labels['quicksearch'] = 'Szybkie wyszukiwanie';
 $labels['resetsearch'] = 'Wyczyść filtr';
+$labels['searchmod']  = 'Parametry wyszukiwania';
+$labels['msgtext']  = 'Cała wiadomość';
 $labels['openinextwin'] = 'Otwórz w nowym oknie';
 $labels['compose'] = 'Utwórz wiadomość';
 $labels['savemessage'] = 'Zapisz kopię roboczą';
index 9b36396071d751d88de9eea3983889d0ba3c94df..d53811d23a00ecd5631fc20315cac6044373785b 100644 (file)
@@ -17,7 +17,7 @@
 |         Victor Benincasa <vbenincasa@gmail.com>                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -41,7 +41,7 @@ $labels['from'] = 'Remetente';
 $labels['to'] = 'Para';
 $labels['cc'] = 'Cópia';
 $labels['bcc'] = 'Cópia Oculta (Bcc)';
-$labels['replyto'] = 'Responder para';
+$labels['replyto'] = 'Resp. para';
 $labels['date'] = 'Data';
 $labels['size'] = 'Tamanho';
 $labels['priority'] = 'Prioridade';
@@ -135,6 +135,8 @@ $labels['unknown'] = 'desconhecido';
 $labels['unlimited'] = 'ilimitado';
 $labels['quicksearch'] = 'Pesquisa rápida';
 $labels['resetsearch'] = 'Limpar';
+$labels['searchmod'] = 'Opções da pesquisa';
+$labels['msgtext'] = 'Mensagem inteira';
 $labels['openinextwin'] = 'Abrir em nova janela';
 $labels['compose'] = 'Escrever mensagem';
 $labels['savemessage'] = 'Salvar Rascunho';
@@ -164,7 +166,7 @@ $labels['dontsave'] = 'não salvar';
 $labels['maxuploadsize'] = 'Tamanho máximo permitido do arquivo é $size';
 $labels['addcc'] = 'Cópia';
 $labels['addbcc'] = 'Cópia Oculta';
-$labels['addreplyto'] = 'Responder para';
+$labels['addreplyto'] = 'Resp. para';
 $labels['mdnrequest'] = 'O remetente desta mensagem deseja ser notificado quando você ler esta mensagem. Você permite o envio desta notificação?';
 $labels['receiptread'] = 'Confirmação de Leitura (Exibida)';
 $labels['yourmessage'] = 'Esta é uma confirmação de leitura da sua mensagem';
index 14073ac9eb4ba39efd9675904e3a2bd43d362eae..2054e2cdff69f0e0b2378da40ab6ed6a89910ae3 100644 (file)
@@ -16,7 +16,7 @@
 |          Nuno Costa <nuno@criacaoweb.net>                             |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2254 2009-01-22 19:52:46Z yllar $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -40,7 +40,7 @@ $labels['from'] = 'Remetente';
 $labels['to'] = 'Para';
 $labels['cc'] = 'Cópia';
 $labels['bcc'] = 'Bcc';
-$labels['replyto'] = 'Responder para';
+$labels['replyto'] = 'Resp. para';
 $labels['date'] = 'Data';
 $labels['size'] = 'Tamanho';
 $labels['priority'] = 'Prioridade';
@@ -163,7 +163,7 @@ $labels['dontsave'] = 'não salvar';
 $labels['maxuploadsize'] = 'Tamanho máximo permitido do ficheiro é $size';
 $labels['addcc'] = 'Adicionar Cc';
 $labels['addbcc'] = 'Adicionar Bcc';
-$labels['addreplyto'] = 'Adicionar "Responder para"';
+$labels['addreplyto'] = 'Adicionar Resp. para';
 $labels['mdnrequest'] = 'O remetente desta mensagem pediu para ser notificado quando esta fosse lida. Deseja enviar uma notificação?';
 $labels['receiptread'] = 'Recibo de leitura';
 $labels['yourmessage'] = 'Isto é um recibo de leitura da sua mensagem';
index 33d0c342fa189240b60389dd1aae0282371c3ff0..057ddf1adcb6d79e47f8b3311b4a1f8e3641519e 100644 (file)
@@ -1,20 +1,19 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| language/ro_RO/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Daniel Anechitoaie - danieLs <daniels@safereaction.ro>        |
+|         Zeno Popovici <zeno.popovici at ulbsibiu.ro>                  |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/ro/labels.inc                                                |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Daniel Anechitoaie - danieLs <daniels@safereaction.ro>        |
- |         Ispas Dorin <dorinxp2004@yahoo.com>                           |
- +-----------------------------------------------------------------------+
-
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -32,7 +31,7 @@ $labels['inbox'] = 'Primite';
 $labels['drafts'] = 'Ciorne';
 $labels['sent'] = 'Trimise';
 $labels['trash'] = 'Gunoi';
-$labels['junk'] = 'Junk';
+$labels['junk'] = 'Spam';
 $labels['subject'] = 'Subiect';
 $labels['from'] = 'Expeditor';
 $labels['to'] = 'Destinatar';
@@ -69,6 +68,30 @@ $labels['wednesday'] = 'Miercuri';
 $labels['thursday'] = 'Joi';
 $labels['friday'] = 'Vineri';
 $labels['saturday'] = 'Sambata';
+$labels['jan'] = 'Ian';
+$labels['feb'] = 'Feb';
+$labels['mar'] = 'Mar';
+$labels['apr'] = 'Apr';
+$labels['may'] = 'Mai';
+$labels['jun'] = 'Iun';
+$labels['jul'] = 'Iul';
+$labels['aug'] = 'Aug';
+$labels['sep'] = 'Sep';
+$labels['oct'] = 'Oct';
+$labels['nov'] = 'Noi';
+$labels['dec'] = 'Dec';
+$labels['longjan'] = 'Ianuarie';
+$labels['longfeb'] = 'Februarie';
+$labels['longmar'] = 'Martie';
+$labels['longapr'] = 'Aprilie';
+$labels['longmay'] = 'Mai';
+$labels['longjun'] = 'Iunie';
+$labels['longjul'] = 'Iulie';
+$labels['longaug'] = 'August';
+$labels['longsep'] = 'Septembrie';
+$labels['longoct'] = 'Octombrie';
+$labels['longnov'] = 'Noiembrie';
+$labels['longdec'] = 'Decembrie';
 $labels['today'] = 'Astazi';
 $labels['checkmail'] = 'Verifica pentru mesaje noi';
 $labels['writenewmessage'] = 'Creaza mesaj nou';
@@ -91,10 +114,15 @@ $labels['viewsource'] = 'Afiseaza sursa';
 $labels['markmessages'] = 'Marcheaza mesajele';
 $labels['markread'] = 'Ca citit';
 $labels['markunread'] = 'Ca necitit';
+$labels['markflagged'] = 'Ca marcat';
+$labels['markunflagged'] = 'Ca nemarcat';
 $labels['select'] = 'Selecteaza';
 $labels['all'] = 'Toate';
 $labels['none'] = 'Nici unul';
 $labels['unread'] = 'Necitite';
+$labels['flagged'] = 'Marcat';
+$labels['unanswered'] = 'Neraspuns';
+$labels['filter'] = 'Filtru';
 $labels['compact'] = 'Compreseaza';
 $labels['empty'] = 'Goleste';
 $labels['purge'] = 'Curata';
@@ -103,6 +131,7 @@ $labels['unknown'] = 'necunoscut';
 $labels['unlimited'] = 'nelimitat';
 $labels['quicksearch'] = 'Cautare rapida';
 $labels['resetsearch'] = 'Resetare cautare';
+$labels['openinextwin'] = 'Deschide in fereastra noua';
 $labels['compose'] = 'Compune mesaj';
 $labels['savemessage'] = 'Salveaza aceasta ciorna';
 $labels['sendmessage'] = 'Trimite mesaj';
@@ -123,8 +152,12 @@ $labels['high'] = 'Mare';
 $labels['highest'] = 'Cea mai mare';
 $labels['nosubject'] = '(fara subiect)';
 $labels['showimages'] = 'Afiseaza imagini';
+$labels['alwaysshow'] = 'Afiseaza intotdeauna imaginile de la $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Text simplu';
+$labels['savesentmessagein'] = 'Salveaza mesajele in';
+$labels['dontsave'] = 'Nu salva';
+$labels['maxuploadsize'] = 'Marimea maxima admisa a fisierului este $size';
 $labels['addcc'] = 'Adauga Cc';
 $labels['addbcc'] = 'Adauga Bcc';
 $labels['addreplyto'] = 'Adauga Raspunde-La';
@@ -148,12 +181,19 @@ $labels['composeto'] = 'Compune e-mail pentru';
 $labels['contactsfromto'] = 'Contacte de la $from pana la $to din $count';
 $labels['print'] = 'Listeaza';
 $labels['export'] = 'Exporta';
+$labels['exportvcards'] = 'Exporta contactele in format vCard';
 $labels['previouspage'] = 'Pagina anterioara';
 $labels['firstpage'] = 'Arata primul set';
 $labels['nextpage'] = 'Pagina urmatoare';
 $labels['lastpage'] = 'Arata ultimul set';
 $labels['groups'] = 'Grupuri';
 $labels['personaladrbook'] = 'Adrese personale';
+$labels['import'] = 'Importa';
+$labels['importcontacts'] = 'Importa contacte';
+$labels['importfromfile'] = 'Importa din fisier:';
+$labels['importreplace'] = 'Inlocuieste intreaga agenda';
+$labels['importtext'] = 'Puteti incarca contacte dintr-o agenda existenta.<br/>Se pot importa adresele in format <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>.';
+$labels['done'] = 'Finalizat';
 $labels['settingsfor'] = 'Setari pentru';
 $labels['preferences'] = 'Preferinte';
 $labels['userpreferences'] = 'Preferinte utilizator';
@@ -164,6 +204,7 @@ $labels['newidentity'] = 'Identitate noua';
 $labels['newitem'] = 'Item nou';
 $labels['edititem'] = 'Editeaza item';
 $labels['setdefault'] = 'Seteaza implicit';
+$labels['autodetect'] = 'Automat';
 $labels['language'] = 'Limba';
 $labels['timezone'] = 'Fus orar';
 $labels['pagesize'] = 'Randuri pe pagina';
@@ -172,9 +213,37 @@ $labels['dstactive'] = 'Daylight savings';
 $labels['htmleditor'] = 'Scrie mesaje HTML';
 $labels['htmlsignature'] = 'Semnatura HTML';
 $labels['previewpane'] = 'Arata preview';
+$labels['skin'] = 'Tema interfata';
+$labels['logoutclear'] = 'Goleste dosarul Gunoi la logout';
+$labels['logoutcompact'] = 'Compacteaza dosarul Primite la logout';
+$labels['uisettings'] = 'Interfata utilizator';
+$labels['serversettings'] = 'Configuratii server';
+$labels['mailboxview'] = 'Afisare Mailbox';
+$labels['mdnrequests'] = 'Notificari expeditor';
+$labels['askuser'] = 'intreaba utilizatorul';
+$labels['autosend'] = 'trimite automat';
+$labels['ignore'] = 'ignora';
+$labels['readwhendeleted'] = 'Marcheaza mesajul ca si citit la stergere';
+$labels['flagfordeletion'] = 'Marcheaza mesajele pentru stergere in loc de a-l sterge direct';
+$labels['skipdeleted'] = 'Nu arata mesajele sterse';
+$labels['showremoteimages'] = 'Arata imagini remote';
+$labels['fromknownsenders'] = 'de la expeditori cunoscuti';
+$labels['always'] = 'intotdeauna';
+$labels['showinlineimages'] = 'Arata imaginile atasate sub mesaj';
 $labels['autosavedraft'] = 'Salveaza ciorna automat';
 $labels['everynminutes'] = 'fiecare $n minute';
+$labels['keepaliveevery'] = 'fiecare $n minut(e)';
+$labels['keepalive'] = 'Verifica mesaje noi la';
 $labels['never'] = 'niciodata';
+$labels['messagesdisplaying'] = 'Afisarea Mesajelor';
+$labels['messagescomposition'] = 'Compunerea Mesajelor';
+$labels['mimeparamfolding'] = 'Nume Atasamente';
+$labels['2231folding'] = 'RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'RFC 2047 (Altele)';
+$labels['advancedoptions'] = 'Optiuni Avansate';
+$labels['focusonnewmessage'] = 'Focus pe fereastra browser-ului la mesaje noi';
+$labels['checkallfolders'] = 'Verifica toate dosarele pentru mesaje noi';
 $labels['folder'] = 'Dosar';
 $labels['folders'] = 'Dosare';
 $labels['foldername'] = 'Nume dosar';
@@ -186,8 +255,14 @@ $labels['rename'] = 'Redenumeste';
 $labels['renamefolder'] = 'Redenumeste dosar';
 $labels['deletefolder'] = 'Sterge dosar';
 $labels['managefolders'] = 'Administreaza dosare';
+$labels['specialfolders'] = 'Dosare speciale';
 $labels['sortby'] = 'Sorteaza dupa';
 $labels['sortasc'] = 'Sorteaza ascendent';
 $labels['sortdesc'] = 'Sorteaza descendent';
+$labels['B'] = 'O';
+$labels['KB'] = 'KO';
+$labels['MB'] = 'MO';
+$labels['GB'] = 'GO';
+
+?>
 
-?>
\ No newline at end of file
index f20f38a3c891ab101994a6568d045480b755c6ee..e4ca2c1141ff08b9633fa3e5c650b0a7931e6629 100644 (file)
@@ -1,20 +1,19 @@
 <?php
 
 /*
++-----------------------------------------------------------------------+
+| language/ro_RO/messages.inc                                           |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Daniel Anechitoaie - danieLs <daniels@safereaction.ro>        |
+|         Zeno Popovici <zeno.popovici at ulbsibiu.ro>                  |
++-----------------------------------------------------------------------+
 
- +-----------------------------------------------------------------------+
- | language/ro/messages.inc                                              |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Daniel Anechitoaie - danieLs <daniels@safereaction.ro>        |
- |         Ispas Dorin <dorinxp2004@yahoo.com>                           |
- +-----------------------------------------------------------------------+
-
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -41,6 +40,8 @@ $messages['encryptedmessage'] = 'Acesta este un mesaj criptat si nu poate fi afi
 $messages['nocontactsfound'] = 'Nu s-a gasit nici un contact';
 $messages['contactnotfound'] = 'Contactul solicitat nu a fost gasit.';
 $messages['sendingfailed'] = 'Nu s-a reusit trimiterea mesajului';
+$messages['senttooquickly'] = 'Va rugam asteptati $sec sec. inainte de a trimite acest mesaj';
+$messages['errorsavingsent'] = 'A intervenit o eroare in timp ce se efectua salvarea mesajului trimis';
 $messages['errorsaving'] = 'A intervenit o eroare in timp ce se efectua salvarea';
 $messages['errormoving'] = 'Nu s-a putut muta mesajul';
 $messages['errordeleting'] = 'Nu s-a putut sterge mesajul';
@@ -48,10 +49,15 @@ $messages['deletecontactconfirm'] = 'Sunteti sigur ca doriti sa stergeti contact
 $messages['deletemessagesconfirm'] = 'Chiar doriti sa stergeti mesajele selectate ?';
 $messages['deletefolderconfirm'] = 'Sunteti sigur ca doriti sa stergeti acest dosar?';
 $messages['purgefolderconfirm'] = 'Sunteti sigur ca doriti sa stergeti toate mesajele din acest dosar?';
+$messages['foldercreating'] = 'Se creaza dosarul...';
+$messages['folderdeleting'] = 'Se sterge dosarul...';
+$messages['folderrenaming'] = 'Se redenumeste dosarul...';
+$messages['foldermoving'] = 'Se muta dosarul...';
 $messages['formincomplete'] = 'Formularul nu a fost completat corect';
 $messages['noemailwarning'] = 'Va rugam introduceti o adresa de e-mail valida';
 $messages['nonamewarning'] = 'Va rugam introduceti un nume';
 $messages['nopagesizewarning'] = 'Va rugam introduceti marimea paginii';
+$messages['nosenderwarning'] = 'Va rugam introduceti adresa expeditorului';
 $messages['norecipientwarning'] = 'Va rugam introduceti cel putin un destinatar';
 $messages['nosubjectwarning'] = 'Mesajul nu are subiect. Vreti sa introduceti unul acum?';
 $messages['nobodywarning'] = 'Trimiteti acest mesaj fara text?';
@@ -79,5 +85,15 @@ $messages['receiptsent'] = 'Confirmarea a fost trimisa cu succes';
 $messages['errorsendingreceipt'] = 'Confirmarea nu a putut fi trimisa';
 $messages['nodeletelastidentity'] = 'Nu putesti sterge aceasta identitate, este ultima.';
 $messages['addsubfolderhint'] = 'Acest dosar va fi creat ca subdosar al celui selectat.';
+$messages['forbiddencharacter'] = 'Numele dosarului contine un caracter nepermis.';
+$messages['selectimportfile'] = 'Va rugam selectati fisierul pentru incarcare';
+$messages['addresswriterror'] = 'Agenda selectata nu poate fi actualizata';
+$messages['importwait'] = 'Se importeaza, va rugam asteptati...';
+$messages['importerror'] = 'Importarea a esuat! Fisierul incarcat nu este un fisier vCard valid.';
+$messages['importconfirm'] = '<b>Contactele $inserted au fost importate cu succes, $skipped intrari au fost ignorate deoarece ele exista deja</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Operatia nu este permisa!';
+$messages['nofromaddress'] = 'Nu exista o adresa de e-mail in identitatea selectata';
+$messages['editorwarning'] = 'Trecerea in mod text a editorului va cauza pierderea formatarii textului. Doriti sa continuati?';
+
+?>
 
-?>
\ No newline at end of file
index b8c5a44cc75c7194e9b0513c59d97f48de338149..5479d2c9e71fc4315e4e3f4392eb05235bf40983 100644 (file)
 +-----------------------------------------------------------------------+
 | Author: Maxim Zenin <maxx@webmechanics.ru>                            |
 |         Vladimir Kulev <me@lightoze.net>                              |
-|         Artur Smolkin <admin@roundcube.ru>                            |
+|         Artur Smolkin <artsmolkin@ya.ru>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -133,6 +133,8 @@ $labels['unknown'] = 'неизвестно';
 $labels['unlimited'] = 'без ограничений';
 $labels['quicksearch'] = 'Быстрый поиск';
 $labels['resetsearch'] = 'Сброс';
+$labels['searchmod'] = 'Варианты поиска';
+$labels['msgtext'] = 'Всё сообщение';
 $labels['openinextwin'] = 'Открыть в новом окне';
 $labels['compose'] = 'Написать сообщение';
 $labels['savemessage'] = 'Сохранить черновик';
index 371f2e2fca16b423aef4c9487cab4c7fafc80d81..7f40c43dacf4c7e7e8984d8385baa32971d4e917 100644 (file)
@@ -2,46 +2,38 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/sv_SE/labels.inc                                             |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Fredrik Nygren <f.nygren@gmail.com>                           |
- |         Andreas Henriksson <andreas@fatal.se>                         |
- |         Jonas Nasholm <info@bitfuse.net>                              |
- +-----------------------------------------------------------------------+
-
- @version $Id: labels.inc 2215 2009-01-05 11:23:03Z alec $
++-----------------------------------------------------------------------+
+| language/sv_SE/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Jonas Nasholm <info@bitfuse.net>                              |
+|         Fredrik Nygren <f.nygren@gmail.com>                           |
+|         Andreas Henriksson <andreas@fatal.se>                         |
++-----------------------------------------------------------------------+
+
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
 $labels = array();
-
-// login page
 $labels['welcome'] = 'Välkommen till $product';
 $labels['username'] = 'Användarnamn';
 $labels['password'] = 'Lösenord';
 $labels['server'] = 'Server';
 $labels['login'] = 'Logga in';
-
-// taskbar
 $labels['logout'] = 'Logga ut';
 $labels['mail'] = 'Meddelanden';
 $labels['settings'] = 'Personliga inställningar';
 $labels['addressbook'] = 'Adressbok';
-
-// mailbox names
 $labels['inbox'] = 'Inkorg';
 $labels['drafts'] = 'Utkast';
 $labels['sent'] = 'Skickat';
 $labels['trash'] = 'Papperskorg';
 $labels['junk'] = 'Skräp';
-
-// message listing
 $labels['subject'] = 'Ämne';
 $labels['from'] = 'Avsändare';
 $labels['to'] = 'Mottagare';
@@ -52,27 +44,18 @@ $labels['date'] = 'Datum';
 $labels['size'] = 'Storlek';
 $labels['priority'] = 'Prioritet';
 $labels['organization'] = 'Organisation';
-
-// aliases
 $labels['reply-to'] = 'Svara till';
-
 $labels['mailboxlist'] = 'Kataloger';
 $labels['messagesfromto'] = 'Meddelande $from till $to av $count';
 $labels['messagenrof'] = 'Meddelande $nr av $count';
-
 $labels['moveto'] = 'Flytta till:';
 $labels['download'] = 'Ladda ner';
-
 $labels['filename'] = 'Filnamn';
 $labels['filesize'] = 'Filstorlek';
-
 $labels['preferhtml'] = 'Visa meddelanden i HTML-format';
 $labels['htmlmessage'] = 'HTML-meddelande';
 $labels['prettydate'] = 'Fina datum';
-
 $labels['addtoaddressbook'] = 'Lägg till i adressbok';
-
-// weekdays short
 $labels['sun'] = 'Sön';
 $labels['mon'] = 'Mån';
 $labels['tue'] = 'Tis';
@@ -80,8 +63,6 @@ $labels['wed'] = 'Ons';
 $labels['thu'] = 'Tor';
 $labels['fri'] = 'Fre';
 $labels['sat'] = 'Lör';
-
-// weekdays long
 $labels['sunday'] = 'Söndag';
 $labels['monday'] = 'Måndag';
 $labels['tuesday'] = 'Tisdag';
@@ -89,37 +70,31 @@ $labels['wednesday'] = 'Onsdag';
 $labels['thursday'] = 'Torsdag';
 $labels['friday'] = 'Fredag';
 $labels['saturday'] = 'Lördag';
-
-// months short
-$labels['jan'] = 'Jan';
-$labels['feb'] = 'Feb';
-$labels['mar'] = 'Mar';
-$labels['apr'] = 'Apr';
-$labels['may'] = 'Maj';
-$labels['jun'] = 'Jun';
-$labels['jul']         = 'Jul';
-$labels['aug'] = 'Aug';
-$labels['sep'] = 'Sep';
-$labels['oct'] = 'Okt';
-$labels['nov'] = 'Nov';
-$labels['dec'] = 'Dec';
-
-// months long
-$labels['longjan']     = 'Januari';
-$labels['longfeb']     = 'Februari';
-$labels['longmar']     = 'Mars';
-$labels['longapr']     = 'April';
-$labels['longmay']     = 'Maj';
-$labels['longjun']     = 'Juni';
-$labels['longjul']     = 'Juli';
-$labels['longaug']     = 'Augusti';
-$labels['longsep']     = 'September';
-$labels['longoct']     = 'Oktober';
-$labels['longnov']     = 'November';
-$labels['longdec']     = 'December';
+$labels['jan'] = 'Jan';
+$labels['feb'] = 'Feb';
+$labels['mar'] = 'Mar';
+$labels['apr'] = 'Apr';
+$labels['may'] = 'Maj';
+$labels['jun'] = 'Jun';
+$labels['jul'] = 'Jul';
+$labels['aug'] = 'Aug';
+$labels['sep'] = 'Sep';
+$labels['oct'] = 'Okt';
+$labels['nov'] = 'Nov';
+$labels['dec'] = 'Dec';
+$labels['longjan'] = 'Januari';
+$labels['longfeb'] = 'Februari';
+$labels['longmar'] = 'Mars';
+$labels['longapr'] = 'April';
+$labels['longmay'] = 'Maj';
+$labels['longjun'] = 'Juni';
+$labels['longjul'] = 'Juli';
+$labels['longaug'] = 'Augusti';
+$labels['longsep'] = 'September';
+$labels['longoct'] = 'Oktober';
+$labels['longnov'] = 'November';
+$labels['longdec'] = 'December';
 $labels['today'] = 'Idag';
-
-// toolbar buttons
 $labels['checkmail'] = 'Hämta nya meddelanden';
 $labels['writenewmessage'] = 'Skapa nytt meddelande';
 $labels['replytomessage'] = 'Svara avsändaren';
@@ -143,7 +118,6 @@ $labels['markread'] = 'Läst';
 $labels['markunread'] = 'Oläst';
 $labels['markflagged'] = 'Flaggat';
 $labels['markunflagged'] = 'Oflaggat';
-
 $labels['select'] = 'Välj';
 $labels['all'] = 'Alla';
 $labels['none'] = 'Ingen';
@@ -151,21 +125,17 @@ $labels['unread'] = 'Olästa';
 $labels['flagged'] = 'Flaggade';
 $labels['unanswered'] = 'Obesvarade';
 $labels['filter'] = 'Filter';
-
 $labels['compact'] = 'Packa';
 $labels['empty'] = 'Töm';
 $labels['purge'] = 'Rensa';
-
 $labels['quota'] = 'Diskutrymme';
 $labels['unknown'] = 'okänt';
 $labels['unlimited'] = 'obegränsat';
-
 $labels['quicksearch'] = 'Snabbsök';
 $labels['resetsearch'] = 'Återställ sökning';
-
+$labels['searchmod'] = 'Sökalternativ';
+$labels['msgtext'] = 'Hela meddelandet';
 $labels['openinextwin'] = 'Öppna i nytt fönster';
-
-// message compose
 $labels['compose'] = 'Skapa nytt meddelande';
 $labels['savemessage'] = 'Spara utkast';
 $labels['sendmessage'] = 'Skicka meddelande';
@@ -173,94 +143,72 @@ $labels['addattachment'] = 'Bifoga fil';
 $labels['charset'] = 'Teckenkodning';
 $labels['editortype'] = 'Typ av redigerare';
 $labels['returnreceipt'] = 'Mottagarkvitto';
-
 $labels['checkspelling'] = 'Kontrollera stavning';
 $labels['resumeediting'] = 'Återuppta redigering';
 $labels['revertto'] = 'Återgå till';
-
 $labels['attachments'] = 'Bilagor';
 $labels['upload'] = 'Bifoga';
 $labels['close'] = 'Stäng';
-
 $labels['low'] = 'Låg';
 $labels['lowest'] = 'Lägst';
 $labels['normal'] = 'Normal';
 $labels['high'] = 'Hög';
 $labels['highest'] = 'Högst';
-
 $labels['nosubject'] = '(inget ämne)';
 $labels['showimages'] = 'Visa bilder';
 $labels['alwaysshow'] = 'Visa alltid bilder från $sender';
-
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Text';
 $labels['savesentmessagein'] = 'Spara kopia i';
 $labels['dontsave'] = 'Spara inte';
 $labels['maxuploadsize'] = 'Tillåten filstorlek är $size';
-
 $labels['addcc'] = 'Kopia';
 $labels['addbcc'] = 'Hemlig kopia';
 $labels['addreplyto'] = 'Svara till';
-
-// mdn
 $labels['mdnrequest'] = 'Avsändaren har begärt mottagarkvitto för det här meddelandet. Vill du skicka ett mottagarkvitto?';
 $labels['receiptread'] = 'Mottagarkvitto (läst)';
 $labels['yourmessage'] = 'Det här är ett mottagarkvitto för ditt meddelande';
 $labels['receiptnote'] = 'Notera: Mottagarkvittot innebär bara att meddelandet visats på mottagarens dator. Därmed finns ingen garanti att mottagaren har läst och förstått meddelandet.';
-
-// address boook
 $labels['name'] = 'Namn';
 $labels['firstname'] = 'Förnamn';
 $labels['surname'] = 'Efternamn';
 $labels['email'] = 'E-post';
-
 $labels['addcontact'] = 'Lägg till ny kontakt';
 $labels['editcontact'] = 'Redigera kontakt';
-
 $labels['edit'] = 'Redigera';
 $labels['cancel'] = 'Avbryt';
 $labels['save'] = 'Spara';
 $labels['delete'] = 'Radera';
-
 $labels['newcontact'] = 'Ny kontakt';
 $labels['deletecontact'] = 'Radera vald kontakt';
 $labels['composeto'] = 'Skriv meddelande till vald kontakt';
 $labels['contactsfromto'] = 'Kontakt $from till $to av $count';
 $labels['print'] = 'Skriv ut';
 $labels['export'] = 'Exportera';
-$labels['exportvcards']   = 'Exportera kontakter';
-
+$labels['exportvcards'] = 'Exportera kontakter';
 $labels['previouspage'] = 'Visa föregående grupp';
 $labels['firstpage'] = 'Visa första gruppen';
 $labels['nextpage'] = 'Visa nästa grupp';
 $labels['lastpage'] = 'Visa sista gruppen';
-
 $labels['groups'] = 'Grupper';
 $labels['personaladrbook'] = 'Personliga adresser';
-
 $labels['import'] = 'Importera';
 $labels['importcontacts'] = 'Importera kontakter';
 $labels['importfromfile'] = 'Importera från fil:';
 $labels['importreplace'] = 'Ersätt samtliga kontakter i adressboken';
 $labels['importtext'] = 'Kontakter kan importeras från en befintlig adressbok.<br/>För närvarande stöds import av adresser i <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>-format.';
 $labels['done'] = 'Klart';
-
-// settings
 $labels['settingsfor'] = 'Inställningar för';
-
 $labels['preferences'] = 'Inställningar';
 $labels['userpreferences'] = 'Användarinställningar';
 $labels['editpreferences'] = 'Ändra användarinställningar';
-
 $labels['identities'] = 'Profiler';
 $labels['manageidentities'] = 'Hantera profiler för detta konto';
 $labels['newidentity'] = 'Ny profil';
-
 $labels['newitem'] = 'Ny post';
 $labels['edititem'] = 'Ändra post';
-
 $labels['setdefault'] = 'Sätt som standard';
-$labels['autodetect']  = 'Automatiskt';
+$labels['autodetect'] = 'Automatiskt';
 $labels['language'] = 'Språk';
 $labels['timezone'] = 'Tidszon';
 $labels['pagesize'] = 'Rader per sida';
@@ -288,8 +236,8 @@ $labels['always'] = 'Alltid';
 $labels['showinlineimages'] = 'Visa bifogade bilder efter meddelande';
 $labels['autosavedraft'] = 'Spara utkast med automatiskt intervall';
 $labels['everynminutes'] = '$n min';
-$labels['keepaliveevery']  = '$n min';
-$labels['keepalive']  = 'Hämta nya meddelanden med automatiskt intervall';
+$labels['keepaliveevery'] = '$n min';
+$labels['keepalive'] = 'Hämta nya meddelanden med automatiskt intervall';
 $labels['never'] = 'Aldrig';
 $labels['messagesdisplaying'] = 'Visning av meddelanden';
 $labels['messagescomposition'] = 'Redigering av meddelanden';
@@ -300,7 +248,6 @@ $labels['2047folding'] = 'Full RFC 2047 (övriga)';
 $labels['advancedoptions'] = 'Avancerade inställningar';
 $labels['focusonnewmessage'] = 'Fokusera webbläsarens fönster vid nytt meddelande';
 $labels['checkallfolders'] = 'Genomsök samtliga kataloger efter nya meddelanden';
-
 $labels['folder'] = 'Katalog';
 $labels['folders'] = 'Kataloger';
 $labels['foldername'] = 'Katalognamn';
@@ -313,12 +260,9 @@ $labels['renamefolder'] = 'Byt katalognamn';
 $labels['deletefolder'] = 'Radera katalog';
 $labels['managefolders'] = 'Hantera kataloger';
 $labels['specialfolders'] = 'Speciella kataloger';
-
 $labels['sortby'] = 'Sortera på';
 $labels['sortasc'] = 'Sortera stigande';
 $labels['sortdesc'] = 'Sortera fallande';
-
-// units
 $labels['B'] = 'B';
 $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
index bbfcd9de360c03818b08585370043d888f08c9d6..355c635d403b442ef11f1980e5df3e3ada67bb20 100644 (file)
 |         Ting-Hung Chiu <earrl@mmlab.cse.yzu.edu.tw>                   |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
 $labels = array();
-
-// login page
 $labels['welcome'] = '歡迎使用 $product';
 $labels['username'] = '使用者名稱';
 $labels['password'] = '使用者密碼';
 $labels['server'] = '伺服器';
 $labels['login'] = '登入';
-
-// taskbar
 $labels['logout'] = '登出';
 $labels['mail'] = '電子郵件';
 $labels['settings'] = '個人設定';
 $labels['addressbook'] = '通訊錄';
-
-// mailbox names
 $labels['inbox'] = '收件匣';
 $labels['drafts'] = '草稿匣';
 $labels['sent'] = '寄件備份';
 $labels['trash'] = '垃圾桶';
 $labels['junk'] = '垃圾郵件';
-
-// message listing
 $labels['subject'] = '主旨';
 $labels['from'] = '寄件者';
 $labels['to'] = '收件者';
@@ -52,36 +44,25 @@ $labels['date'] = '日期';
 $labels['size'] = '大小';
 $labels['priority'] = '優先順序';
 $labels['organization'] = '組織';
-
-// aliases
-$labels['reply-to'] = $labels['replyto'];
-
+$labels['reply-to'] = '回覆至';
 $labels['mailboxlist'] = '資料夾';
 $labels['messagesfromto'] = '郵件 $from 至 $to,共有 $count 封郵件';
 $labels['messagenrof'] = '第 $nr 封郵件,共有 $count 封';
-
 $labels['moveto'] = '移至...';
 $labels['download'] = '下載';
-
 $labels['filename'] = '檔案名稱';
 $labels['filesize'] = '檔案大小';
-
 $labels['preferhtml'] = '使用 HTML 顯示';
 $labels['htmlmessage'] = 'HTML 郵件';
 $labels['prettydate'] = '簡短日期顯示';
-
 $labels['addtoaddressbook'] = '新增至通訊錄';
-
-// weekdays short
-$labels['sun'] = '日';
-$labels['mon'] = '一';
-$labels['tue'] = '二';
-$labels['wed'] = '三';
-$labels['thu'] = '四';
-$labels['fri'] = '五';
-$labels['sat'] = '六';
-
-// weekdays long
+$labels['sun'] = '週日';
+$labels['mon'] = '週一';
+$labels['tue'] = '週二';
+$labels['wed'] = '週三';
+$labels['thu'] = '週四';
+$labels['fri'] = '週五';
+$labels['sat'] = '週六';
 $labels['sunday'] = '星期日';
 $labels['monday'] = '星期一';
 $labels['tuesday'] = '星期二';
@@ -89,8 +70,6 @@ $labels['wednesday'] = '星期三';
 $labels['thursday'] = '星期四';
 $labels['friday'] = '星期五';
 $labels['saturday'] = '星期六';
-
-// months short
 $labels['jan'] = '一';
 $labels['feb'] = '二';
 $labels['mar'] = '三';
@@ -103,8 +82,6 @@ $labels['sep'] = '九';
 $labels['oct'] = '十';
 $labels['nov'] = '十一';
 $labels['dec'] = '十二';
-
-// months long
 $labels['longjan'] = '一月';
 $labels['longfeb'] = '二月';
 $labels['longmar'] = '三月';
@@ -117,17 +94,14 @@ $labels['longsep'] = '九月';
 $labels['longoct'] = '十月';
 $labels['longnov'] = '十一月';
 $labels['longdec'] = '十二月';
-
 $labels['today'] = '今日';
-
-// toolbar buttons
 $labels['checkmail'] = '檢查新郵件';
 $labels['writenewmessage'] = '撰寫新郵件';
 $labels['replytomessage'] = '回覆';
 $labels['replytoallmessage'] = '全部回覆';
 $labels['forwardmessage'] = '轉寄';
 $labels['deletemessage'] = '刪除郵件';
-$labels['movemessagetotrash'] = '移動郵件至' . $labels['trash'];
+$labels['movemessagetotrash'] = '移動郵件至垃圾桶';
 $labels['printmessage'] = '列印此郵件';
 $labels['previousmessage'] = '顯示上一封郵件';
 $labels['previousmessages'] = '顯示上一頁';
@@ -144,26 +118,24 @@ $labels['markread'] = '標示為已讀取';
 $labels['markunread'] = '標示為未讀取';
 $labels['markflagged'] = '標上旗標';
 $labels['markunflagged'] = '移除旗標';
-
 $labels['select'] = '選取';
-$labels['all'] = '全部';
+$labels['all'] = '全部郵件';
 $labels['none'] = '無';
-$labels['unread'] = '未讀取';
-
+$labels['unread'] = '未讀取的郵件';
+$labels['flagged'] = '已加標記的郵件';
+$labels['unanswered'] = '未回覆的郵件';
+$labels['filter'] = '篩選範圍';
 $labels['compact'] = '壓縮';
 $labels['empty'] = '清空';
 $labels['purge'] = '清除';
-
 $labels['quota'] = '磁碟使用量';
 $labels['unknown'] = '未知';
 $labels['unlimited'] = '無限制';
-
 $labels['quicksearch'] = '快速搜尋';
 $labels['resetsearch'] = '重設搜尋';
-
+$labels['searchmod'] = '修改搜尋';
+$labels['msgtext'] = '整封郵件';
 $labels['openinextwin'] = '在新視窗開啟';
-
-// message compose
 $labels['compose'] = '撰寫新郵件';
 $labels['savemessage'] = '儲存成草稿';
 $labels['sendmessage'] = '立即寄出';
@@ -171,55 +143,42 @@ $labels['addattachment'] = '增加附件檔案';
 $labels['charset'] = '郵件編碼';
 $labels['editortype'] = '編輯器類型';
 $labels['returnreceipt'] = '要求讀取回條';
-
 $labels['checkspelling'] = '拼字檢查';
 $labels['resumeediting'] = '繼續編輯';
 $labels['revertto'] = '恢復至';
-
 $labels['attachments'] = '附加檔案';
 $labels['upload'] = '上傳';
 $labels['close'] = '關閉';
-
 $labels['low'] = '低';
 $labels['lowest'] = '最低';
 $labels['normal'] = '普通';
 $labels['high'] = '高';
 $labels['highest'] = '最高';
-
 $labels['nosubject'] = '(沒有主旨)';
 $labels['showimages'] = '顯示圖片';
 $labels['alwaysshow'] = '永遠顯示來自 $sender 的圖片';
-
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = '純文字';
 $labels['savesentmessagein'] = '儲存寄件備份至';
 $labels['dontsave'] = '不要儲存';
 $labels['maxuploadsize'] = '上傳檔案大小限制為 $size';
-
 $labels['addcc'] = '新增副本';
 $labels['addbcc'] = '新增密件副本';
 $labels['addreplyto'] = '新增回覆地址';
-
-// mdn
 $labels['mdnrequest'] = '此郵件的寄件者希望在你閱讀此郵件時受到通知。你想要通知寄件者嗎?';
 $labels['receiptread'] = '郵件回條(已閱讀)';
 $labels['yourmessage'] = '這是你郵件的郵件回條';
 $labels['receiptnote'] = '注意:此回條只能確認收件者的電腦顯示了郵件,並不能保證收件者已閱讀或了解郵件的內容。';
-
-// address book
 $labels['name'] = '顯示名稱';
 $labels['firstname'] = '名稱';
 $labels['surname'] = '姓氏';
 $labels['email'] = '電子郵件';
-
 $labels['addcontact'] = '新增聯絡人';
 $labels['editcontact'] = '編輯聯絡人';
-
 $labels['edit'] = '編輯';
 $labels['cancel'] = '取消';
 $labels['save'] = '儲存';
 $labels['delete'] = '刪除';
-
 $labels['newcontact'] = '建立新聯絡人資料';
 $labels['deletecontact'] = '刪除所選擇的聯絡人';
 $labels['composeto'] = '寄信至所選擇的聯絡人';
@@ -227,36 +186,27 @@ $labels['contactsfromto'] = '聯絡人 $from 至 $to,共有 $count 人';
 $labels['print'] = '列印';
 $labels['export'] = '匯出通訊錄';
 $labels['exportvcards'] = '匯出通訊錄為 vCard 格式';
-
 $labels['previouspage'] = '顯示上一頁';
 $labels['firstpage'] = '顯示第一頁';
 $labels['nextpage'] = '顯示下一頁';
 $labels['lastpage'] = '顯示最後一頁';
-
 $labels['groups'] = '群組';
 $labels['personaladrbook'] = '個人住址';
-
 $labels['import'] = '匯入通訊錄';
 $labels['importcontacts'] = '由檔案匯入通訊錄';
 $labels['importfromfile'] = '選擇你要匯入的檔案:';
 $labels['importreplace'] = '以匯入的資料取代已存在的重複資料';
 $labels['importtext'] = '你可以由已存在的通訊錄上傳資料,<br/>目前系統僅支援匯入 <a href="http://zh.wikipedia.org/wiki/VCard" target="_blank">vCard</a> 格式的資料。';
 $labels['done'] = '完成';
-
-// settings
 $labels['settingsfor'] = '設定';
-
 $labels['preferences'] = '設定';
 $labels['userpreferences'] = '個人設定';
 $labels['editpreferences'] = '編輯個人設定';
-
 $labels['identities'] = '身份資訊';
 $labels['manageidentities'] = '管理此帳號的身份資訊';
 $labels['newidentity'] = '新增身份資訊';
-
 $labels['newitem'] = '新增項目';
 $labels['edititem'] = '編輯項目';
-
 $labels['setdefault'] = '設成預設i值';
 $labels['autodetect'] = '自動選擇';
 $labels['language'] = '語言';
@@ -268,8 +218,8 @@ $labels['htmleditor'] = '使用 HTML 撰寫郵件';
 $labels['htmlsignature'] = 'HTML 簽名檔';
 $labels['previewpane'] = '顯示預覽窗格';
 $labels['skin'] = '版面風格';
-$labels['logoutclear'] = '登出時清空' . $labels['trash'];
-$labels['logoutcompact'] = '登出時壓縮' . $labels['inbox'];
+$labels['logoutclear'] = '登出時清空垃圾桶';
+$labels['logoutcompact'] = '登出時壓縮收件匣';
 $labels['uisettings'] = '使用介面設定';
 $labels['serversettings'] = '伺服器設定';
 $labels['mailboxview'] = '信箱顯示設定';
@@ -277,15 +227,27 @@ $labels['mdnrequests'] = '讀取回條回應';
 $labels['askuser'] = '詢問使用者';
 $labels['autosend'] = '自動送出';
 $labels['ignore'] = '完全忽略';
-$labels['readwhendeleted'] = '將刪除的信件標示為已讀取';
-$labels['flagfordeletion'] = '刪除信件時將原始信件標示為已刪除';
+$labels['readwhendeleted'] = '將刪除的郵件標示為已讀取';
+$labels['flagfordeletion'] = '刪除郵件時將原始郵件標示為已刪除';
+$labels['skipdeleted'] = '不要顯示已刪除的郵件';
+$labels['showremoteimages'] = '顯示遠端郵件內文中的圖片';
+$labels['fromknownsenders'] = '從已知的寄件者';
+$labels['always'] = '總是接受';
 $labels['showinlineimages'] = '將附加檔案的圖片顯示於郵件最後';
 $labels['autosavedraft'] = '自動儲存草稿';
 $labels['everynminutes'] = '每 $n 分鐘';
-$labels['never'] = '絕不';
+$labels['keepaliveevery'] = '每 $n 分鐘';
+$labels['keepalive'] = '檢查新郵件的間隔時間';
+$labels['never'] = '絕對不要';
 $labels['messagesdisplaying'] = '郵件顯示設定';
 $labels['messagescomposition'] = '撰寫郵件設定';
-
+$labels['mimeparamfolding'] = '附加檔案名稱的編碼方式';
+$labels['2231folding'] = '完全 RFC 2231 模式 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 混合模式 (MS Outlook)';
+$labels['2047folding'] = '完全 RFC 2047 模式 (其他)';
+$labels['advancedoptions'] = '顯示進階設定選項';
+$labels['focusonnewmessage'] = '收到新郵件時使瀏覽器獲得焦點';
+$labels['checkallfolders'] = '檢查所有資料夾中的新郵件';
 $labels['folder'] = '資料夾';
 $labels['folders'] = '資料夾';
 $labels['foldername'] = '資料夾名稱';
@@ -298,9 +260,12 @@ $labels['renamefolder'] = '重新命名資料夾';
 $labels['deletefolder'] = '刪除資料夾';
 $labels['managefolders'] = '管理資料夾';
 $labels['specialfolders'] = '預設資料夾設定';
-
 $labels['sortby'] = '排序';
 $labels['sortasc'] = '遞增排序';
 $labels['sortdesc'] = '遞減排序';
+$labels['B'] = 'B';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
 
-?>
\ No newline at end of file
+?>
index 6238e74dc22c334f51c4ca754566c68ed322157a..47f0234b4ab0a215696add8fc96a409ea2e641a0 100644 (file)
@@ -15,7 +15,7 @@
 |         Ting-Hung Chiu <earrl@mmlab.cse.yzu.edu.tw>                   |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -33,7 +33,7 @@ $messages['checkingmail'] = '檢查新郵件...';
 $messages['sendingmessage'] = '寄出郵件中...';
 $messages['messagesent'] = '郵件寄出成功';
 $messages['savingmessage'] = '儲存郵件中...';
-$messages['messagesaved'] = '訊息已經存至' . $labels['drafts'];
+$messages['messagesaved'] = '訊息已經存至';
 $messages['successfullysaved'] = '儲存成功';
 $messages['addedsuccessfully'] = '聯絡人已經成功地新增至通訊錄';
 $messages['contactexists'] = '此聯絡人的電子郵件位址已存在';
@@ -42,7 +42,7 @@ $messages['encryptedmessage'] = '此郵件經過加密,因此無法顯示。
 $messages['nocontactsfound'] = '沒有找到任何聯絡人';
 $messages['contactnotfound'] = '找不到要求的聯絡人';
 $messages['sendingfailed'] = '郵件寄出失敗';
-$messages['senttooquickly'] = '你寄出的件太過於頻繁,請稍候 $sec 秒後再試一次。';
+$messages['senttooquickly'] = '你寄出的件太過於頻繁,請稍候 $sec 秒後再試一次。';
 $messages['errorsavingsent'] = '儲存寄件備份時發生錯誤';
 $messages['errorsaving'] = '儲存時發生錯誤';
 $messages['errormoving'] = '無法移動此郵件';
@@ -54,10 +54,12 @@ $messages['purgefolderconfirm'] = '你確定要刪除這個資料夾裡面所有
 $messages['foldercreating'] = '建立資料夾中...';
 $messages['folderdeleting'] = '刪除資料夾中...';
 $messages['folderrenaming'] = '重新命名資料夾中...';
+$messages['foldermoving'] = '移動資料夾中...';
 $messages['formincomplete'] = '這個表單有部分未填,請完整填寫';
 $messages['noemailwarning'] = '請輸入一個有效的電子郵件位址';
 $messages['nonamewarning'] = '請輸入名字';
 $messages['nopagesizewarning'] = '請輸入一頁顯示多少郵件';
+$messages['nosenderwarning'] = '請輸入寄件者的電子郵件位址';
 $messages['norecipientwarning'] = '請輸入至少一位收信者';
 $messages['nosubjectwarning'] = '「主旨」欄是空的。你要輸入一個主旨嗎?';
 $messages['nobodywarning'] = '要傳送沒有內文的郵件嗎?';
@@ -92,5 +94,7 @@ $messages['importwait'] = '匯入中,請稍候...';
 $messages['importerror'] = '匯入失敗!上傳的檔案並非支援的 vCard 格式。';
 $messages['importconfirm'] = '<b>成功匯入 $inserted 筆資料,略過 $skipped 筆已存在的資料</b>:<p><em>$names</em></p>';
 $messages['opnotpermitted'] = '不允許的操作';
+$messages['nofromaddress'] = '在選擇的身分中遺失了電子郵件位址';
+$messages['editorwarning'] = '切換到純文字編輯模式將會遺失所有設定的樣式。您確定要繼續嗎?';
 
-?>
\ No newline at end of file
+?>
index b0a2a7e81066aebabae66aadc24fccf5b0e87be0..f6e29f9d76e1a1abc1271e78e005703c2fadb400 100644 (file)
@@ -63,6 +63,11 @@ if ($RCMAIL->action=='display-attachment')
 // use common temp dir for file uploads
 $temp_dir = unslashify($CONFIG['temp_dir']);
 
+// #1484529: we need absolute path on Windows for move_uploaded_file()
+if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+  $temp_dir = realpath($temp_dir);
+}
+
 if (!is_array($_SESSION['compose']['attachments'])) {
   $_SESSION['compose']['attachments'] = array();
 }
@@ -73,7 +78,7 @@ $OUTPUT->reset();
 if (is_array($_FILES['_attachments']['tmp_name'])) {
   foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
     $tmpfname = tempnam($temp_dir, 'rcmAttmnt');
-    if (move_uploaded_file($filepath, $tmpfname)) {
+    if (move_uploaded_file($filepath, $tmpfname) && file_exists($tmpfname)) {
       $id = count($_SESSION['compose']['attachments']);
       $_SESSION['compose']['attachments'][] = array(
         'name' => $_FILES['_attachments']['name'][$i],
index 26acc88c2dcf44972c06ef11b6ec2c1fe6aaab33..b1aba7d62e8db91b2e6e7da6f8913a2cbcc9b968 100644 (file)
@@ -19,7 +19,7 @@
 
 */
 
-$MAXNUM = 15;  // same limit as in app.js
+$MAXNUM = 15;
 $contacts = array();
 $book_types = (array) $RCMAIL->config->get('autocomplete_addressbooks', 'sql');
 
@@ -33,12 +33,11 @@ if ($book_types && $search = get_input_value('_search', RCUBE_INPUT_POST)) {
       while ($sql_arr = $result->iterate()) {
         if (stripos((string)$sql_arr['email'], $search) !== false || stripos((string)$sql_arr['name'], $search) !== false) {
           $contacts[] = format_email_recipient($sql_arr['email'], $sql_arr['name']);
+         if (count($contacts) >= $MAXNUM)
+            break 2;
         }
       }
     }
-    
-    if (count($contacts) >= $MAXNUM)
-      break;
   }
   
   sort($contacts);
index 97ba5d4cdabc5c615fe5cf2a89b526a84ec4cd69..525298b757a13215fcda9e9596ec28dd7d76b2cc 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: compose.inc 2301 2009-02-18 19:15:36Z alec $
+ $Id: compose.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -70,8 +70,10 @@ if ($msg_uid = $_SESSION['compose']['param']['_reply_uid'])
   $compose_mode = RCUBE_COMPOSE_REPLY;
 else if ($msg_uid = $_SESSION['compose']['param']['_forward_uid'])
   $compose_mode = RCUBE_COMPOSE_FORWARD;
-else if ($msg_uid = $_SESSION['compose']['param']['_draft_uid'])
+else if ($msg_uid = $_SESSION['compose']['param']['_draft_uid']) {
+  $RCMAIL->imap->set_mailbox($CONFIG['drafts_mbox']);
   $compose_mode = RCUBE_COMPOSE_DRAFT;
+}
 
 if (!empty($msg_uid))
 {
@@ -488,7 +490,7 @@ function rcmail_create_reply_body($body, $bodyIsHtml)
       }
 
     // add title line(s)
-    $prefix = wordwrap(sprintf("On %s, %s wrote:\n",
+    $prefix = rc_wordwrap(sprintf("On %s, %s wrote:\n",
       $MESSAGE->headers->date,
       $MESSAGE->get_header('from')), 76);
 
index d38306ebb3e0cc89e2386cca64f9db9b2d6781a5..e694b8aaaf0aab237b5d5d010c27b5073bdc6ca5 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 2324 2009-03-02 17:34:18Z thomasb $
+ $Id: func.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -660,7 +660,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
     '/<title>.*<\/title>/i',           // PHP bug #32547 workaround: remove title tag
     '/<html[^>]*>/im',                 // malformed html: remove html tags (#1485139)
     '/<\/html>/i',                     // malformed html: remove html tags (#1485139)
-    '/^[\xFE\xFF\xBB\xBF\x00]+((?:<\!doctype|\<html))/im',     // remove byte-order mark (only outlook?)
+    '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/',   // byte-order mark (only outlook?)
   );
   $html_replace = array(
     '\\1'.' &nbsp; '.'\\3',
@@ -669,7 +669,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
     '',
     '',
     '',
-    '\\1',
+    '',
   );
   $html = preg_replace($html_search, $html_replace, $html);
 
@@ -1179,7 +1179,7 @@ function rcmail_wrap_quoted($text, $max = 76)
         $prefix = substr($line, 0, $length);
 
         // Remove '> ' from the line, then wordwrap() the line
-        $line = wordwrap(substr($line, $length), $max - $length);
+        $line = rc_wordwrap(substr($line, $length), $max - $length);
 
         // Rebuild the line with '> ' at the beginning of each 'subline'
         $newline = '';
@@ -1191,7 +1191,7 @@ function rcmail_wrap_quoted($text, $max = 76)
         $line = rtrim($newline);
       }
       else {
-        $line = wordwrap($line, $max);
+        $line = rc_wordwrap($line, $max);
       }
     }
 
@@ -1308,7 +1308,14 @@ function rcmail_deliver_message(&$message, $from, $mailto)
     // reset stored headers and overwrite
     $message->_headers = array();
     $header_str = $message->txtHeaders($headers_php);
-  
+    
+    // #1485779
+    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+      if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) {
+        $headers_enc['To'] = implode(', ', $m[1]);
+        }
+      }
+       
     if (ini_get('safe_mode'))
       $sent = mail($headers_enc['To'], $headers_enc['Subject'], $msg_body, $header_str);
     else
@@ -1390,7 +1397,7 @@ function rcmail_send_mdn($uid)
                "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
     
     $compose->headers($headers);
-    $compose->setTXTBody(wordwrap($body, 75, "\r\n"));
+    $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
     $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
 
     $sent = rcmail_deliver_message($compose, $identity['email'], $mailto);
index cf6db639cde0c7cdb7771d77e6ee4035b6378c43..1ae84c3eae1ebf7b66d5ca1a8945e0b104642bc1 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: list.inc 2109 2008-12-03 08:16:44Z alec $
+ $Id: list.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
+if (!$OUTPUT->ajax_call) {
+  return;
+}
+
 // is there a sort type for this request?
 if ($sort = get_input_value('_sort', RCUBE_INPUT_GET))
 {
index 445ba206bf95705e811c87e1dbc9fce184911fd4..418e1728327213e2bc08180479a43b419a78147d 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: sendmail.inc 2320 2009-03-01 07:55:39Z alec $
+ $Id: sendmail.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -302,10 +302,10 @@ if ($isHtml)
   $MAIL_MIME->setHTMLBody($message_body . ($footer ? "\r\n<pre>".$footer.'</pre>' : ''));
 
   // add a plain text version of the e-mail as an alternative part.
-  $h2t = new html2text($message_body);
-  $plainTextPart = $h2t->get_text() . ($footer ? "\r\n".$footer : '');
+  $h2t = new html2text($message_body, false, true, 0);
+  $plainTextPart = rc_wordwrap($h2t->get_text(), 75, "\r\n"). ($footer ? "\r\n".$footer : '');
   $plainTextPart = wordwrap($plainTextPart, 998, "\r\n", true);
-  if (!strlen($plainTextPart)) 
+  if (!strlen($plainTextPart))
     { 
     // empty message body breaks attachment handling in drafts 
     $plainTextPart = "\r\n"; 
@@ -317,7 +317,7 @@ if ($isHtml)
   }
 else
   {
-  $message_body = wordwrap($message_body, 75, "\r\n");
+  $message_body = rc_wordwrap($message_body, 75, "\r\n");
   if ($footer)
     $message_body .= "\r\n" . $footer;
   $message_body = wordwrap($message_body, 998, "\r\n", true);
@@ -342,7 +342,7 @@ if (is_array($_SESSION['compose']['attachments']))
     if ($isHtml && ($match > 0))
     {
       $message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'" ', $message_body);
-      $MAIL_MIME->setHTMLBody($message_body. ($footer ? "\r\n<pre>".$footer.'</pre>' : ''));
+      $MAIL_MIME->setHTMLBody($message_body);
       $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name']);
     }
     else
index 3e96b2477996f759593a23c67e09fbe9e5a2f127..02802c742a9a7bed3c009a93d5eaeaa3ec00f753 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: edit_identity.inc 2040 2008-11-05 10:19:44Z alec $
+ $Id: edit_identity.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -43,7 +43,7 @@ else {
     return;
   }
   else if (IDENTITIES_LEVEL == 1)
-    $IDENTITY_RECORD['email'] = rcmail_get_email();
+    $IDENTITY_RECORD['email'] = $RCMAIL->user->get_username();
 }
 
 
index 59be85f262d81045aa6bc48d618497a49c4887af..cef7cee47c11048d21030f1a1c16776866483d80 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 2206 2008-12-31 17:52:55Z yllar $
+ $Id: func.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -469,24 +469,6 @@ function rcmail_get_skins()
   }
 
 
-function rcmail_get_email()
-  {
-  global $RCMAIL;
-  
-  if (strpos($RCMAIL->user->data['username'], '@'))
-    return $RCMAIL->user->data['username'];
-  else {
-    if ($RCMAIL->config->get('virtuser_file'))
-      $user_email = rcube_user::user2email($RCMAIL->user->data['username']);
-
-    if ($user_email == '')
-      $user_email = sprintf('%s@%s', $RCMAIL->user->data['username'], 
-           $RCMAIL->config->mail_domain($_SESSION['imap_host']));
-
-    return $user_email;
-    }                
-  }
-
 // register UI objects
 $OUTPUT->add_handlers(array(
   'userprefs' => 'rcmail_user_prefs_form',
@@ -494,5 +476,4 @@ $OUTPUT->add_handlers(array(
   'itentitieslist' => 'rcmail_identities_list'  // keep this for backward compatibility
 ));
 
-
 ?>
index 823d593d8630a75c8bdadf508e675244a8df5236..30beae4e25597a713cb2212975fc8a2bb716d5b7 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: save_identity.inc 2006 2008-10-24 07:57:21Z alec $
+ $Id: save_identity.inc 2483 2009-05-15 10:22:29Z thomasb $
 
 */
 
@@ -86,7 +86,7 @@ if ($_POST['_iid'])
 else if (IDENTITIES_LEVEL < 2)
 {
   if (IDENTITIES_LEVEL == 1)
-    $save_data['email'] = rcmail_get_email();
+    $save_data['email'] = $RCMAIL->user->get_username();
 
   if ($save_data['email'] && ($insert_id = $USER->insert_identity($save_data)))
   {
index ec2cd526f4fb5853e67b7e6cf5e2fccb6f41a106..34ea1d2b8310be33be23ef17aa2484f7e351dad5 100644 (file)
@@ -364,19 +364,13 @@ table.records-table tr.unfocused td
   top: 2px;
   left: 20px;
   width: 140px;
+  height: 15px;
   font-size: 11px;
   padding: 0px;
   border: none;
 }
 
 
-/*\*/
-html>body*#quicksearchbar[id$="quicksearchbar"]:not([class="none"]) { background-image: none; }
-html>body*#quicksearchbar[id$="quicksearchbar"]:not([class="none"]) a { top: 5px; }
-html>body*#quicksearchbar[id$="quicksearchbar"]:not([class="none"]) #quicksearchbox { width: 180px; top:0px; right: 1px; left: auto; }
-/**/
-
-
 /***** roundcube webmail pre-defined classes *****/
 
 #rcversion
index bb614dbd7517dc263e1a29ab9a7a2643d9e96ad3..5a4e57bfee5d1f2a29ab509b6081228b1c60567d 100644 (file)
@@ -820,6 +820,7 @@ div.message-htmlpart a
 }
 
 div.message-part pre,
+div.message-htmlpart pre,
 div.message-part div.pre
 {
   margin: 0px;
@@ -918,12 +919,12 @@ div.message-htmlpart div.rcmBody
 {
   position: absolute;
   top: 90px;
-  left: 200px;
+  left: 190px;
   right: 25px;
   bottom: 30px;
   margin: 0px;
   /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-220)+'px');
+  width: expression((parseInt(document.documentElement.clientWidth)-210)+'px');
   height: expression((parseInt(document.documentElement.clientHeight)-120)+'px');
 }
 
index fa9c38c7efc0f0c8d850bbee340ce6698839f28e..441a5de91574eafa7f50d48df960cbaa7812b812 100644 (file)
@@ -103,6 +103,8 @@ div.message-part a
   color: #0000CC;
 }
 
+div.message-part pre,
+div.message-htmlpart pre,
 div.message-part div.pre
 {
   margin: 0;
index 5c4bd56dc24fe3ff4dd683343dbfe054def7fe01..6c984ab672fe2df3ccbc016eaa40b5e5c347947a 100644 (file)
@@ -132,6 +132,14 @@ span.tablink-selected a
   background-color: #F9F9F9;
 }
 
+#subscription-table
+{
+  width: 100%;
+  /* css hack for IE */
+  width: expression('auto');
+}
+
+#subscription-table tbody td,
 #identities-table tbody td
 {
   cursor: default;
@@ -149,6 +157,45 @@ span.tablink-selected a
   width: 45%;
 }
 
+#subscription-table tr.virtual td
+{
+  color: #666;
+}
+
+#subscription-table tr.selected td,
+#subscription-table tr.selected td a
+{
+  color: #FFFFFF;
+  background-color: #CC3333;
+}
+
+#subscription-table tr.droptarget td,
+#subscription-table tr.droptarget td a
+{
+  background-color: #FFFFA6;
+}
+
+#subscription-table thead td.name
+{
+  width: 360px;
+}
+
+#subscription-table thead td.msgcount
+{
+  width: 90px;
+}
+
+#subscription-table thead td.subscribed
+{
+  width: 90px;
+}
+
+#subscription-table thead td.rename,
+#subscription-table thead td.delete
+{
+  width: 30px;
+}
+
 #identity-frame
 {
   position: relative;
@@ -194,8 +241,7 @@ input.disabled
 
 #userprefs-title,
 #identity-title,
-div.boxtitle,
-#subscription-table thead td
+div.boxtitle
 {
   height: 12px !important;
   padding: 4px 20px 3px 6px;
@@ -220,57 +266,6 @@ div.settingspart
   padding: 10px;
 }
 
-#subscription-table
-{
-  width: 100%;
-  /* css hack for IE */ 
-  width: expression('auto');
-}
-
-#subscription-table tbody td
-{
-  height: 20px;
-  padding-left: 6px;
-  padding-right: 10px;
-  white-space: nowrap;
-  border-bottom: 1px solid #EBEBEB;
-  background-color: #F9F9F9;
-  cursor: default;
-}
-
-#subscription-table tr.virtual td
-{
-  color: #666;
-}
-
-#subscription-table tr.selected td,
-#subscription-table tr.selected td a
-{
-  color: #FFFFFF;
-  background-color: #CC3333;
-}
-
-#subscription-table tr.droptarget td,
-#subscription-table tr.droptarget td a
-{
-  background-color: #FFFFA6;
-}
-
-#subscription-table thead td.name
-{
-  width: 250px;
-}
-
-#subscription-table thead td.msgcount
-{
-  width: 90px;
-}
-
-#subscription-table thead td.subscribed
-{
-  width: 90px;
-}
-
 fieldset 
 {
   margin-bottom: 0.5em;
index 326ded2966b74b2689f5dd7eceee03c9c79716b6..ce295567bdd23b71e5bb1a1c4e846a2948b6516b 100644 (file)
@@ -41,7 +41,7 @@
 </div>
 
 <div id="quicksearchbar">
-<roundcube:object name="searchform" type="search" results="5" id="quicksearchbox" /><roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
+<roundcube:object name="searchform" id="quicksearchbox" /><roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
 </div>
 
 <roundcube:if condition="config:ldap_public" />
index fb887ba5ec7a97f9a6db78c9e14ecd4840829a18..96be0f65ee68ed227cd9fa236af7e8d60ae84a29 100644 (file)
 </div>
 
 <div id="quicksearchbar">
-<roundcube:object name="searchform" type="search" results="5" id="quicksearchbox" /><roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
+<roundcube:object name="searchform" id="quicksearchbox" /><roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
 </div>
 
 </body>
index 8808f513078d95a94cb42cf8fa84c403005bce83..5da5c22f1801477bd719666a95a099bd9a25bb5a 100644 (file)
@@ -16,7 +16,7 @@
 
 <div id="folder-manager">
 <roundcube:object name="foldersubscription" form="subscriptionform" id="subscription-table"
-  cellpadding="1" cellspacing="0" summary="Folder subscription table"
+  cellpadding="1" cellspacing="0" summary="Folder subscription table" class="records-table"
   deleteIcon="/images/icons/folder-trash.png"
   renameIcon="/images/icons/rename.png" />
 </div>