]> git.donarmstrong.com Git - roundcube.git/commitdiff
Imported Upstream version 0.3.1
authorJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 15:03:22 +0000 (17:03 +0200)
committerJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 15:03:22 +0000 (17:03 +0200)
191 files changed:
.htaccess
CHANGELOG
INSTALL
README
SQL/mysql.initial.sql
SQL/mysql.update.sql
SQL/postgres.initial.sql
SQL/postgres.update.sql
SQL/sqlite.initial.sql
SQL/sqlite.update.sql
bin/quotaimg.php [deleted file]
config/db.inc.php.dist
config/main.inc.php.dist
index.php
installer/check.php
installer/config.php
plugins/archive/archive.js
plugins/archive/archive.php
plugins/archive/archive_act.png [deleted file]
plugins/archive/archive_pas.png [deleted file]
plugins/archive/foldericon.png [deleted file]
plugins/archive/localization/cs_CZ.inc [new file with mode: 0644]
plugins/archive/localization/et_EE.inc [new file with mode: 0644]
plugins/archive/localization/fr_FR.inc
plugins/archive/localization/ru_RU.inc [new file with mode: 0644]
plugins/archive/skins/default/archive_act.png [new file with mode: 0644]
plugins/archive/skins/default/archive_pas.png [new file with mode: 0644]
plugins/archive/skins/default/foldericon.png [new file with mode: 0644]
plugins/filesystem_attachments/filesystem_attachments.php
plugins/help/content/about.html
plugins/help/localization/cs_CZ.inc [new file with mode: 0644]
plugins/help/localization/hu_HU.inc [new file with mode: 0644]
plugins/help/skins/default/help.css
plugins/help/skins/default/help.gif
plugins/managesieve/Changelog
plugins/managesieve/config.inc.php.dist
plugins/managesieve/lib/rcube_sieve.php
plugins/managesieve/localization/cs_CZ.inc [new file with mode: 0644]
plugins/managesieve/localization/de_DE.inc
plugins/managesieve/localization/el_GR.inc [new file with mode: 0644]
plugins/managesieve/localization/en_GB.inc [new file with mode: 0644]
plugins/managesieve/localization/gb_GB.inc [deleted file]
plugins/managesieve/localization/ru_RU.inc
plugins/managesieve/managesieve.php
plugins/markasjunk/junk_act.png [deleted file]
plugins/markasjunk/junk_pas.png [deleted file]
plugins/markasjunk/localization/cs_CZ.inc [new file with mode: 0644]
plugins/markasjunk/localization/ru_RU.inc [new file with mode: 0644]
plugins/markasjunk/markasjunk.php
plugins/markasjunk/skins/default/junk_act.png [new file with mode: 0644]
plugins/markasjunk/skins/default/junk_pas.png [new file with mode: 0644]
plugins/new_user_dialog/localization/ru_RU.inc [new file with mode: 0644]
plugins/new_user_dialog/new_user_dialog.php
plugins/new_user_identity/new_user_identity.php
plugins/password/README
plugins/password/config.inc.php.dist
plugins/password/drivers/cpanel.php [new file with mode: 0644]
plugins/password/drivers/sql.php
plugins/password/drivers/vpopmaild.php [new file with mode: 0644]
plugins/password/drivers/ximss.php [new file with mode: 0644]
plugins/password/localization/bg_BG.inc [new file with mode: 0644]
plugins/password/localization/cs_CZ.inc [new file with mode: 0644]
plugins/password/localization/da_DK.inc [new file with mode: 0644]
plugins/password/localization/en_US.inc
plugins/password/localization/pl_PL.inc
plugins/password/localization/pt_PT.inc
plugins/password/password.js
plugins/password/password.php
plugins/subscriptions_option/localization/cs_CZ.inc [new file with mode: 0644]
plugins/subscriptions_option/localization/de_CH.inc [new file with mode: 0644]
plugins/subscriptions_option/localization/de_DE.inc [new file with mode: 0644]
plugins/subscriptions_option/localization/ru_RU.inc [new file with mode: 0644]
plugins/subscriptions_option/subscriptions_option.php
plugins/userinfo/localization/cs_CZ.inc [new file with mode: 0644]
plugins/userinfo/localization/pt_PT.inc
plugins/vcard_attachments/localization/de_CH.inc [new file with mode: 0644]
plugins/vcard_attachments/localization/de_DE.inc [new file with mode: 0644]
plugins/vcard_attachments/localization/en_US.inc [new file with mode: 0644]
plugins/vcard_attachments/localization/ru_RU.inc [new file with mode: 0644]
plugins/vcard_attachments/vcard_attachments.php
program/include/iniset.php
program/include/main.inc
program/include/rcmail.php
program/include/rcube_browser.php
program/include/rcube_imap.php
program/include/rcube_ldap.php
program/include/rcube_mdb2.php
program/include/rcube_message.php
program/include/rcube_plugin.php
program/include/rcube_shared.inc
program/include/rcube_string_replacer.php
program/include/rcube_template.php
program/include/rcube_user.php
program/include/rcube_vcard.php
program/include/session.inc
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/editor_images.js
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/imap.inc
program/localization/ast/labels.inc
program/localization/ast/messages.inc
program/localization/bg_BG/labels.inc
program/localization/bg_BG/messages.inc
program/localization/cs_CZ/labels.inc
program/localization/cs_CZ/messages.inc
program/localization/cy_GB/labels.inc
program/localization/cy_GB/messages.inc
program/localization/de_CH/labels.inc
program/localization/de_CH/messages.inc
program/localization/de_DE/labels.inc
program/localization/de_DE/messages.inc
program/localization/el_GR/labels.inc
program/localization/el_GR/messages.inc
program/localization/en_US/labels.inc
program/localization/en_US/messages.inc
program/localization/es_AR/labels.inc
program/localization/es_AR/messages.inc
program/localization/et_EE/labels.inc
program/localization/et_EE/messages.inc
program/localization/he_IL/labels.inc
program/localization/he_IL/messages.inc
program/localization/index.inc
program/localization/it_IT/labels.inc
program/localization/ja_JP/labels.inc
program/localization/ja_JP/messages.inc
program/localization/ka_GE/labels.inc
program/localization/ka_GE/messages.inc
program/localization/nl_NL/labels.inc
program/localization/pl_PL/labels.inc
program/localization/pl_PL/messages.inc
program/localization/pt_BR/labels.inc
program/localization/pt_BR/messages.inc
program/localization/pt_PT/labels.inc
program/localization/pt_PT/messages.inc
program/localization/ro_RO/labels.inc
program/localization/ro_RO/messages.inc
program/localization/ru_RU/labels.inc
program/localization/ru_RU/messages.inc
program/localization/sv_SE/labels.inc
program/localization/sv_SE/messages.inc
program/steps/addressbook/copy.inc
program/steps/addressbook/mailto.inc
program/steps/mail/attachments.inc
program/steps/mail/check_recent.inc
program/steps/mail/compose.inc
program/steps/mail/folders.inc
program/steps/mail/func.inc
program/steps/mail/get.inc
program/steps/mail/getunread.inc
program/steps/mail/headers.inc
program/steps/mail/list.inc
program/steps/mail/mark.inc
program/steps/mail/move_del.inc
program/steps/mail/rss.inc
program/steps/mail/search.inc
program/steps/mail/sendmail.inc
program/steps/mail/show.inc
program/steps/mail/spell_pspell.inc
program/steps/settings/edit_prefs.inc
program/steps/settings/func.inc
program/steps/settings/save_prefs.inc
skins/default/addresses.css
skins/default/common.css
skins/default/functions.js
skins/default/ie6hacks.css
skins/default/iehacks.css
skins/default/images/display/loading_blue.gif [new file with mode: 0644]
skins/default/images/mail_footer.png [new file with mode: 0644]
skins/default/images/mail_toolbar.gif
skins/default/images/mail_toolbar.png
skins/default/mail.css
skins/default/print.css
skins/default/settings.css
skins/default/splitter.js
skins/default/templates/addcontact.html
skins/default/templates/addressbook.html
skins/default/templates/compose.html
skins/default/templates/editcontact.html
skins/default/templates/editidentity.html
skins/default/templates/importcontacts.html
skins/default/templates/mail.html
skins/default/templates/managefolders.html
skins/default/templates/message.html
skins/default/templates/settingsedit.html
skins/default/templates/showcontact.html

index 19064fdcaad870a2ebb499ef0fc19c5d552e65c0..00e1bf2db837dbcbb54bc18c098036ec0dd03027 100644 (file)
--- a/.htaccess
+++ b/.htaccess
@@ -10,10 +10,11 @@ php_value   upload_max_filesize     5M
 php_value      post_max_size           6M
 php_value      memory_limit            64M
 
-php_value      zlib.output_compression         Off
-php_value      magic_quotes_gpc                0
-php_value      zend.ze1_compatibility_mode     0
-php_value      suhosin.session.encrypt         Off 
+php_flag       zlib.output_compression         Off
+php_flag       magic_quotes_gpc                Off
+php_flag       magic_quotes_runtime            Off
+php_flag       zend.ze1_compatibility_mode     Off
+php_flag       suhosin.session.encrypt         Off
 
 php_value      session.auto_start      0
 php_value      session.gc_maxlifetime  21600
@@ -35,7 +36,7 @@ SetOutputFilter DEFLATE
 
 <IfModule mod_headers.c>
 # replace 'append' with 'merge' for Apache version 2.2.9 and later
-Header append Cache-Control public env=!NO_CACHE
+#Header append Cache-Control public env=!NO_CACHE
 </IfModule>
 
 <IfModule mod_expires.c>
index b5d57b4e2b6a1251f04156aa722c06b6ede1fd93..6f927981ee151b18a70c02268a6ab014690144b7 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,36 +1,49 @@
-CHANGELOG Roundcube Webmail (release 0.3-stable)
+CHANGELOG RoundCube Webmail
 ===========================
 
-- Fix gn and givenName should be synonymous in LDAP addressbook (#1485892)
-- Add mail_domain to LDAP email entries without @ sign (#1485201)
-- Fix saving empty values in LDAP contact data (#1485781)
-- Fix LDAP contact update when RDN field is changed (#1485788)
-- Fix LDAP attributes case senitivity problems (#1485830)
-- Fix LDAP addressbook browsing when only one directory is used (#1486022)
-- Fix endless loop on error response for APPEND command (#1486060)
-- Don't require date.timezone setting in installer (#1485989)
-- Fix date sorting problem with Courier IMAP server (#1486065)
-- Unselect pressed buttons on mouse up (#1485987)
-- Don't set php_value error_log in .htaccess but mention in INSTALL (#1485924)
-- Fix too small status/flag/attachment columns in Safari 4 (#1486063)
-- Fix selection disabling while dragging splitter in webkit browsers (#1486056)
-- Added 'new_messages' plugin hook (#1486005)
-- Added 'logout_after' plugin hook (#1486042)
-- Added 'message_compose' hook
-- Added 'imap_connect' hook (#1485956)
-- Fix vcard_attachments plugin (#1486035)
-- Updated PEAR::Auth_SASL to 1.0.3 version
-- Use sequence names only with PostgreSQL (#1486018)
-- Re-designed User Preferences interface 
-- Fix MS SQL DDL (#1486020)
-- Fix rcube_mdb2.php: call to setCharset not implemented in mssql driver (#1486019)
-- Added 'display_next' option
-- Fix rcube_mdb2::unixtimestamp for MS SQL (#1486015)
-- Fix HTML washing to respect character encoding
-- Fix endless loop in iil_C_Login() with Courier IMAP (#1486010)
-- Fix #messagemenu display on IE (#1486006)
-- Speedup UI by using sprites for (toolbar) buttons
-- Fix charset names with X- prefix handling
-- Fix displaying of HTML messages with unknown/malformed tags (#1486003)
-
+- Specify toolbar container in compose template (#1486247)
+- Fix $_SERVER['HTTPS'] check for SSL forcing on IIS (#1486243)
+- Avoid unnecessary page loads for selected tab (#1486032)
+- Fix quota indicator issues by content generation on client-size (#1486197, #1486220)
+- Don't display disabled sections in Settings (#1486099)
+- Added server-side e-mail address validation with 'email_dns_check' option (#1485857)
+- Fix login page loading into an iframe when session expires (#1485952)
+- Allow setting port number in 'force_https' option (#1486091)
+- Option 'force_https' replaced by 'force_https' plugin
+- Fix IE issue with non-UTF-8 characters in AJAX response (#1486159)
+- Partially fixed "empty body" issue by showing raw body of malformed message (#1486166)
+- Fix importing/sending to email address with whitespace (#1486214)
+- Added XIMSS (CommuniGate) driver for Password plugin
+- Fix newly attached files are not saved in drafts w/o editing any text (#1486202)
+- Added attachment upload indicator with parallel upload (#1486058)
+- Use default_charset for bodies of messages without charset definition (#1486187)
+- Password: added cPanel driver
+- Fix return to first page from e-mail screen (#1486105)
+- Fix handling HTML comments in HTML messages (#1486189)
+- Fix folder/messagelist controls alignment - icons used (#1486072)
+- Fix LDAP addressbook shows 'Contact not found' error sometimes (#1486178)
+- Fix cache status checking + improve cache operations performance (#1486104)
+- Prevent from setting INBOX as any of special folders (#1486114)
+- Fix regular expression for e-mail address (#1486152)
+- Fix Received header format
+- Implemented sorting by message index - added 'index_sort' option (#1485936)
+- Fix dl() use in installer (#1486150)
+- Added 'ldap_debug' option
+- Fix "Empty startup greeting" bug (#1486085)
+- Fix setting user name in 'new_user_identity' plugin (#1486137)
+- Fix incorrect count of new messages in folder list when using multiple IMAP clients (#1485995)
+- Fix all folders checking for new messages with disabled caching (#1486128)
+- Support skins in 'archive' and 'markasjunk' plugins
+- Added 'html_editor' hook (#1486068)
+- Fix DB constraint violation when populating messages cache (#1486052)
+- Password: added password strength options (#1486062)
+- Fix LDAP partial result warning (#1485536)
+- Fix delete in message view deletes permanently with flag_for_deletion=true (#1486101)
+- Use faster/secure mt_rand() (#1486094)
+- Fix roundcube hangs on empty inbox with bincimapd (#1486093)
+- Fix wrong headers for IE on servers without $_SERVER['HTTPS'] (#1485926)
+- Force IE style headers for attachments in non-HTTPS session, 'use_https' option (#1485655)
+- Check 'post_max_size' for upload max filesize (#1486089) 
+- Password Plugin: Fix %d inserts username instead of domain (#1486088)
+- Fix rcube_mdb2::affected_rows() (#1486082)
 
diff --git a/INSTALL b/INSTALL
index ff905bd89ec548271f25b958e4cf49faad58b175..d2b9145a07c51898f287f65c11e7802bbeb3256c 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -25,9 +25,9 @@ REQUIREMENTS
    - session.auto_start disabled
    - zend.ze1_compatibility_mode disabled
 * The PEAR framework with the following packages installed
-   - MDB2 (2.4.1)
+   - MDB2 (2.5.0b2)
    - Mail_Mime (1.5.2)
-   - Net_SMTP (1.2.11)
+   - Net_SMTP (1.3.3)
 * PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker
 * A MySQL or PostgreSQL database engine or the SQLite extension for PHP
 * One of the above databases with permission to create tables
diff --git a/README b/README
index ff975de23e98cbba1fc27a6e0b835a5f72429f2a..d7a13f74d2b544cc31e87c2f228dbca94940d135 100644 (file)
--- a/README
+++ b/README
@@ -1,9 +1,9 @@
-Roundcube Webmail (http://roundcube.net)
+RoundCube Webmail (http://roundcube.net)
 
 
 Introduction:
 -------------
-Roundcube Webmail is a browser-based multilingual IMAP client with an
+RoundCube Webmail is a browser-based multilingual IMAP client with an
 application-like user interface. It provides full functionality you expect
 from an e-mail client, including MIME support, address book, folder management,
 message searching and spell checking. RoundCube Webmail is written in PHP and
@@ -35,7 +35,7 @@ LICENSE for more information about our license.
 
 Contribution:
 -------------
-Want to help make Roundcube the best webmail solution ever?
+Want to help make RoundCube the best webmail solution ever?
 RoundCube is open source software. Our developers and contributors all
 are volunteers and we're always looking for new additions and resources.
 For more information visit http://roundcube.net/contribute
index 9464dd702e68d3d553335febd5e9cdf2c1f73c84..f8145471f4c3053eee40cf1b75e25ee0fb6510b0 100644 (file)
@@ -10,7 +10,7 @@ CREATE TABLE `session` (
  `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
  `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
  `ip` varchar(40) NOT NULL,
- `vars` text NOT NULL,
+ `vars` mediumtext NOT NULL,
  PRIMARY KEY(`sess_id`),
  INDEX `changed_index` (`changed`)
 ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
@@ -53,6 +53,7 @@ CREATE TABLE `messages` (
  `structure` text,
  PRIMARY KEY(`message_id`),
  INDEX `created_index` (`created`),
+ INDEX `index_index` (`user_id`, `cache_key`, `idx`),
  UNIQUE `uniqueness` (`user_id`, `cache_key`, `uid`),
  CONSTRAINT `user_id_fk_messages` FOREIGN KEY (`user_id`)
    REFERENCES `users`(`user_id`)
@@ -94,6 +95,7 @@ CREATE TABLE `contacts` (
  `vcard` text NULL,
  `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
  PRIMARY KEY(`contact_id`),
+ INDEX `user_contacts_index` (`user_id`,`email`),
  CONSTRAINT `user_id_fk_contacts` FOREIGN KEY (`user_id`)
    REFERENCES `users`(`user_id`)
    /*!40008
index 5590099d02682af9fec9784659ce5be7eea26594..77bf317e941e3df37143f3fee7a6cd6d98217028 100644 (file)
@@ -1,5 +1,5 @@
 -- RoundCube Webmail update script for MySQL databases
--- Updates from version 0.1-stable to 0.1.1
+-- Updates from version 0.1-stable to 0.3.1
 
 TRUNCATE TABLE `messages`;
 
@@ -44,3 +44,16 @@ ALTER TABLE `cache`
 
 ALTER TABLE `users`
     CHANGE `language` `language` varchar(5);
+
+-- Updates from version 0.3-stable
+
+ALTER TABLE `messages`
+    ADD INDEX `index_index` (`user_id`, `cache_key`, `idx`);
+
+TRUNCATE `messages`;
+
+ALTER TABLE `session` 
+    CHANGE `vars` `vars` MEDIUMTEXT NOT NULL;
+
+ALTER TABLE `contacts`
+    ADD INDEX `user_contacts_index` (`user_id`,`email`);
index 1a21ee28b130021b6fa81478a82c638126e758cd..a52a01f91201c0c407864d9d47376186faa58761 100644 (file)
@@ -110,7 +110,7 @@ CREATE TABLE contacts (
     vcard text
 );
 
-CREATE INDEX contacts_user_id_idx ON contacts (user_id);
+CREATE INDEX contacts_user_id_idx ON contacts (user_id, email);
 
 --
 -- Sequence "cache_ids"
@@ -174,4 +174,5 @@ CREATE TABLE messages (
 );
 
 ALTER TABLE messages ADD UNIQUE (user_id, cache_key, uid);
+CREATE INDEX messages_index_idx ON messages (user_id, cache_key, idx);
 CREATE INDEX messages_created_idx ON messages (created);
index a29558e66bc7bee213cd9c14738c6100016e1f5c..e343dd440d34bf47c7bc76b2bea13ca2942d8845 100644 (file)
@@ -36,3 +36,10 @@ ALTER TABLE identities ALTER del TYPE smallint;
 ALTER TABLE identities ALTER standard TYPE smallint;
 ALTER TABLE contacts ALTER del TYPE smallint;
 ALTER TABLE messages ALTER del TYPE smallint;
+
+-- Updates from version 0.3-stable
+
+CREATE INDEX messages_index_idx ON messages (user_id, cache_key, idx);
+TRUNCATE messages;
+DROP INDEX contacts_user_id_idx;
+CREATE INDEX contacts_user_id_idx ON contacts (user_id, email);
index ef7cb43178f4c124003e59fe297c9f52cb433d46..cccad7a20589b241400d0ab51d79712ccacaba86 100644 (file)
@@ -34,7 +34,7 @@ CREATE TABLE contacts (
   vcard text NOT NULL default ''
 );
 
-CREATE INDEX ix_contacts_user_id ON contacts(user_id);
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
 
 -- --------------------------------------------------------
 
@@ -119,5 +119,6 @@ CREATE TABLE messages (
   structure text
 );
 
-CREATE INDEX ix_messages_user_cache_uid ON messages(user_id,cache_key,uid);
+CREATE UNIQUE INDEX ix_messages_user_cache_uid ON messages (user_id,cache_key,uid);
+CREATE INDEX ix_messages_index ON messages (user_id,cache_key,idx);
 CREATE INDEX ix_messages_created ON messages (created);
index 627074e428bf611f7a9bd1a7ab335e6b10b9cf11..09af76fae5cda782ab39ee88b87cd8164a062513 100644 (file)
@@ -34,3 +34,12 @@ CREATE INDEX ix_messages_created ON messages (created);
 
 CREATE INDEX ix_session_changed ON session (changed);
 CREATE INDEX ix_cache_created ON cache (created);
+
+-- Updates from version 0.3-stable
+
+DROP INDEX ix_messages_user_cache_uid;
+CREATE UNIQUE INDEX ix_messages_user_cache_uid ON messages (user_id,cache_key,uid);
+CREATE INDEX ix_messages_index ON messages (user_id,cache_key,idx);
+TRUNCATE messages;
+DROP INDEX ix_contacts_user_id;
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
diff --git a/bin/quotaimg.php b/bin/quotaimg.php
deleted file mode 100644 (file)
index 7111b89..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-<?php
-/*
- +-----------------------------------------------------------------------+
- | bin/quotaimg.php                                                      |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- | PURPOSE:                                                              |
- |   Create a GIF image showing the mailbox quot as bar                  |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Brett Patterson <brett2@umbc.edu>                             |
- +-----------------------------------------------------------------------+
-
- $Id: quotaimg.php 2453 2009-05-04 08:31:55Z alec $
-
-*/
-
-define('INSTALL_PATH', realpath(dirname(__FILE__).'/..') . '/');
-require INSTALL_PATH . 'program/include/iniset.php';
-
-$RCMAIL = rcmail::get_instance();
-
-$used   = isset($_GET['u']) ? intval($_GET['u']) : '??';
-$quota  = isset($_GET['q']) ? intval($_GET['q']) : '??';
-$width  = empty($_GET['w']) ? 100 : min(300, intval($_GET['w']));
-$height = empty($_GET['h']) ? 14  : min(50,  intval($_GET['h']));
-
-/**
- * Quota display
- * 
- *     Modify the following few elements to change the display of the image.
- *     Modifiable attributes are:
- *     bool    border  ::      Defines whether you want to show a border around it?
- *     bool    unknown ::      Leave default; Defines whether quota is "unknown"
- *
- *     int             height  ::      Defines height of the image
- *     int             width   ::      Defines width of the image
- *     int             font    ::      Changes the font size & font used in the GD library.
- *                                             Available values are from 1 to 5.
- *     int             padding ::      Changes the offset (in pixels) from the top of the image
- *                      to where the top of the text will be aligned. User
- *                      greater than 0 to ensure text is off the border.
- *     array   limit   ::      Holds the integer values of in an associative array as
- *                      to what defines the upper and lower levels for quota
- *                      display.
- *                                             High - Quota is nearing capacity.
- *                                             Mid  - Quota is around the middle
- *                                             Low  - Currently not used.
- *     array   color   ::      An associative array of strings of comma separated
- *                      values (R,G,B) for use in color creation.  Define the
- *                      RGB values you'd like to use. A list of colors (and
- *                      their RGB values) can be found here:
- *                                             http://www.december.com/html/spec/colorcodes.html
- * 
- * @return void
- * 
- * @param mixed $used   The amount used, or ?? if unknown.
- * @param mixed $total  The total available, or ?? if unknown.
- * @param int   $width  Width of the image.
- * @param int   $height Height of the image.
- * 
- * @see rcube_imap::get_quota()
- * @see iil_C_GetQuota()
- * 
- * @todo Make colors a config option.
- */
-function genQuota($used, $total, $width, $height)
-{
-       $unknown = false;
-       $border  = 0;
-
-       $font    = 2;
-       $padding = 0;
-
-       $limit['high'] = 80;
-       $limit['mid']  = 55;
-       $limit['low']  = 0;
-
-       // Fill Colors
-       $color['fill']['high'] = '243, 49, 49';   // Near quota fill color
-       $color['fill']['mid']  = '245, 173, 60'; // Mid-area of quota fill color
-       $color['fill']['low']  = '145, 225, 100'; // Far from quota fill color
-
-       // Background colors
-       $color['bg']['OL']      = '215, 13, 13';   // Over limit bbackground
-       $color['bg']['Unknown'] = '238, 99, 99';   // Unknown background
-       $color['bg']['quota']   = '255, 255, 255'; // Normal quota background
-
-       // Misc. Colors
-       $color['border'] = '0, 0, 0';
-       $color['text']['high'] = '255, 255, 255';  // white text for red background
-       $color['text']['mid'] = '102, 102, 102';
-       $color['text']['low'] = '102, 102, 102';
-       $color['text']['normal'] = '102, 102, 102';
-
-
-       /************************************
-        *****  DO NOT EDIT BELOW HERE  *****
-        ***********************************/
-
-       // @todo: Set to "??" instead?
-       if (preg_match('/^[^0-9?]*$/', $used) || preg_match('/^[^0-9?]*$/', $total)) {
-               return false; 
-       }
-
-       if (strpos($used, '?') !== false || strpos($total, '?') !== false && $used != 0) {
-               $unknown = true; 
-       }
-
-       $im = imagecreate($width, $height);
-
-       if ($border) {
-               list($r, $g, $b) = explode(',', $color['border']);
-        
-               $borderc = imagecolorallocate($im, $r, $g, $b);
-        
-               imageline($im, 0, 0, $width, 0, $borderc);
-               imageline($im, 0, $height-$border, 0, 0, $borderc);
-               imageline($im, $width-1, 0, $width-$border, $height, $borderc);
-               imageline($im, $width, $height-$border, 0, $height-$border, $borderc);
-       }
-               
-       if ($unknown) {
-               list($r, $g, $b) = explode(',', $color['text']['normal']);
-               $text = imagecolorallocate($im, $r, $g, $b);
-               list($r, $g, $b) = explode(',', $color['bg']['Unknown']);
-               $background = imagecolorallocate($im, $r, $g, $b);
-
-               imagefilledrectangle($im, 0, 0, $width, $height, $background);
-
-               $string = 'Unknown';
-               $mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
-               imagestring($im, $font, $mid, $padding, $string, $text);
-       } else if ($used > $total) {
-               list($r, $g, $b) = explode(',', $color['text']['normal']);
-               $text = imagecolorallocate($im, $r, $g, $b);
-               list($r, $g, $b) = explode(',', $color['bg']['OL']);
-               $background = imagecolorallocate($im, $r, $g, $b);
-        
-               imagefilledrectangle($im, 0, 0, $width, $height, $background);
-
-               $string = 'Over Limit';
-               $mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
-               imagestring($im, $font, $mid, $padding, $string, $text);
-       } else {
-               list($r, $g, $b) = explode(',', $color['bg']['quota']);
-               $background = imagecolorallocate($im, $r, $b, $g);
-        
-               imagefilledrectangle($im, 0, 0, $width, $height, $background);
-               
-               $quota = ($used==0)?0:(round($used/$total, 2)*100);
-
-               if ($quota >= $limit['high']) {
-                       list($r, $g, $b) = explode(',', $color['text']['high']);
-                       $text = imagecolorallocate($im, $r, $g, $b);
-                       list($r, $g, $b) = explode(',', $color['fill']['high']);
-                       $fill = imagecolorallocate($im, $r, $g, $b);
-               } elseif($quota >= $limit['mid']) {
-                       list($r, $g, $b) = explode(',', $color['text']['mid']);
-                       $text = imagecolorallocate($im, $r, $g, $b);
-                       list($r, $g, $b) = explode(',', $color['fill']['mid']);
-                       $fill = imagecolorallocate($im, $r, $g, $b);
-               } else {
-                       // if($quota >= $limit['low'])
-                       list($r, $g, $b) = explode(',', $color['text']['low']);
-                       $text = imagecolorallocate($im, $r, $g, $b);
-                       list($r, $g, $b) = explode(',', $color['fill']['low']);
-                       $fill = imagecolorallocate($im, $r, $g, $b);
-               }
-
-               $quota_width = $quota / 100 * $width;
-               if ($quota_width)
-                       imagefilledrectangle($im, $border, 0, $quota_width, $height-2*$border, $fill);
-
-               $string = $quota . '%';
-               $mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
-               // Print percent in black
-               imagestring($im, $font, $mid, $padding, $string, $text); 
-       }
-
-       header('Content-Type: image/gif');
-
-       // cache for 1 hour
-       $maxage = 3600;
-       header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$maxage). ' GMT');
-       header('Cache-Control: max-age=' . $maxage);
-       
-       imagegif($im);
-       imagedestroy($im);
-}
-
-if (!empty($RCMAIL->user->ID) && $width > 1 && $height > 1) {
-       genQuota($used, $quota, $width, $height);
-}
-else {
-       header("HTTP/1.0 403 Forbidden");
-       echo "Requires a valid user session and positive values";
-}
-
-exit;
-?>
index 4020b266ad0614b25fc00feb1b686352fbfdb922..a9ffe52acefd0eef19a48cf3e2d603230cb12970 100644 (file)
@@ -16,11 +16,13 @@ $rcmail_config = array();
 
 // PEAR database DSN for read/write operations
 // format is db_provider://user:password@host/database 
+// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
 // currently supported db_providers: mysql, mysqli, pgsql, sqlite, mssql
 
 $rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
 // postgres example: 'pgsql://roundcube:pass@localhost/roundcubemail';
-// sqlite example: 'sqlite://./sqlite.db?mode=0646';
+// Warning: for SQLite use absolute path in DSN:
+// sqlite example: 'sqlite:////full/path/to/sqlite.db?mode=0646';
 
 // PEAR database DSN for read only operations (if empty write database will be used)
 // useful for database replication
index 42881dfcd49f901e4c2a5688ccf13c16af44bc1f..efa45957cb9c27ea8c163a4fe7e0d4a4b0bc83c1 100644 (file)
@@ -43,14 +43,15 @@ $rcmail_config['plugins'] = array();
 
 // enable caching of messages and mailbox data in the local database.
 // this is recommended if the IMAP server does not run on the same machine
-$rcmail_config['enable_caching'] = TRUE;
+$rcmail_config['enable_caching'] = FALSE;
 
 // lifetime of message cache
 // possible units: s, m, h, d, w
 $rcmail_config['message_cache_lifetime'] = '10d';
 
 // enforce connections over https
-// with this option enabled, all non-secure connections will be redirected
+// with this option enabled, all non-secure connections will be redirected.
+// set the port for the ssl connection as value of this option if it differs from the default 443
 $rcmail_config['force_https'] = FALSE;
 
 // automatically create a new RoundCube user when log-in the first time.
@@ -130,6 +131,9 @@ $rcmail_config['sql_debug'] = false;
 // Log IMAP conversation to <log_dir>/imap or to syslog
 $rcmail_config['imap_debug'] = false;
 
+// Log LDAP conversation to <log_dir>/ldap or to syslog
+$rcmail_config['ldap_debug'] = false;
+
 // Log SMTP conversation to <log_dir>/smtp or to syslog
 $rcmail_config['smtp_debug'] = false;
 
@@ -365,6 +369,9 @@ $rcmail_config['delete_always'] = false;
 // Must be less than 'session_lifetime'
 $rcmail_config['min_keep_alive'] = 60;
 
+// Enable DNS checking for e-mail address validation
+$rcmail_config['email_dns_check'] = false;
+
 /***** these settings can be overwritten by user's preferences *****/
 
 // skin name: folder from skins/
@@ -440,5 +447,8 @@ $rcmail_config['check_all_folders'] = FALSE;
 // If true, after message delete/move, the next message will be displayed
 $rcmail_config['display_next'] = FALSE;
 
+// If true, messages list will be sorted by message index instead of message date
+$rcmail_config['index_sort'] = TRUE;
+
 // end of config file
 ?>
index 624d8980ebf70a7cc9837f0ee69918895722c356..2360d7f517811923ca6a6e864e9e091f69775434 100644 (file)
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
 /*
  +-------------------------------------------------------------------------+
  | RoundCube Webmail IMAP Client                                           |
- | Version 0.3-stable                                                      |
+ | Version 0.3.1-20091031                                                  |
  |                                                                         |
  | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                   |
  |                                                                         |
@@ -23,7 +23,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                          |
  +-------------------------------------------------------------------------+
 
- $Id: index.php 2916 2009-09-04 10:58:29Z thomasb $
+ $Id: index.php 3081 2009-10-31 13:20:02Z thomasb $
 
 */
 
@@ -64,9 +64,12 @@ if ($RCMAIL->action=='error' && !empty($_GET['_code'])) {
 }
 
 // check if https is required (for login) and redirect if necessary
-if ($RCMAIL->config->get('force_https', false) && empty($_SESSION['user_id']) && !(isset($_SERVER['HTTPS']) || $_SERVER['SERVER_PORT'] == 443)) {
-  header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
-  exit;
+if (empty($_SESSION['user_id']) && ($force_https = $RCMAIL->config->get('force_https', false))) {
+  $https_port = is_bool($force_https) ? 443 : $force_https;
+  if (!rcube_https_check($https_port)) {
+    header('Location: https://' . $_SERVER['HTTP_HOST'] . ($https_port != 443 ? ':' . $https_port : '') . $_SERVER['REQUEST_URI']);
+    exit;
+  }
 }
 
 // trigger startup plugin hook
@@ -74,7 +77,6 @@ $startup = $RCMAIL->plugins->exec_hook('startup', array('task' => $RCMAIL->task,
 $RCMAIL->set_task($startup['task']);
 $RCMAIL->action = $startup['action'];
 
-
 // try to log in
 if ($RCMAIL->action=='login' && $RCMAIL->task=='mail') {
   // purge the session in case of new login when a session already exists 
@@ -149,7 +151,7 @@ $request_check_whitelist = array('login'=>1, 'spell'=>1);
 
 // check client X-header to verify request origin
 if ($OUTPUT->ajax_call) {
-  if (!$RCMAIL->config->get('devel_mode') && rc_request_header('X-RoundCube-Request') != $RCMAIL->get_request_token()) {
+  if (!$RCMAIL->config->get('devel_mode') && rc_request_header('X-RoundCube-Request') != $RCMAIL->get_request_token() && !empty($RCMAIL->user->ID)) {
     header('HTTP/1.1 404 Not Found');
     die("Invalid Request");
   }
@@ -160,13 +162,14 @@ else if (!empty($_POST) && !$request_check_whitelist[$RCMAIL->action] && !$RCMAI
   $OUTPUT->send($RCMAIL->task);
 }
 
-
 // not logged in -> show login page
 if (empty($RCMAIL->user->ID)) {
-  
   if ($OUTPUT->ajax_call)
     $OUTPUT->redirect(array(), 2000);
   
+  if (!empty($_REQUEST['_framed']))
+    $OUTPUT->command('redirect', '?');
+
   // check if installer is still active
   if ($RCMAIL->config->get('enable_installer') && is_readable('./installer/index.php')) {
     $OUTPUT->add_footer(html::div(array('style' => "background:#ef9398; border:2px solid #dc5757; padding:0.5em; margin:2em auto; width:50em"),
index 9bdb41ba5e9ae3efb1e83bd407daecaeb518ab1e..459305138cb84354432b885f8a95dc08cb5afc35 100644 (file)
@@ -55,14 +55,17 @@ if (version_compare(PHP_VERSION, MIN_PHP_VERSION, '>=')) {
 <h3>Checking PHP extensions</h3>
 <p class="hint">The following modules/extensions are <em>required</em> to run RoundCube:</p>
 <?php
-    
+
+// get extensions location
+$ext_dir = ini_get('extension_dir');
+
 $prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
 foreach ($required_php_exts AS $name => $ext) {
     if (extension_loaded($ext)) {
         $RCI->pass($name);
     } else {
-        $_ext = $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
-        $msg = @dl($_ext) ? 'Could be loaded. Please add in php.ini' : '';
+        $_ext = $ext_dir . '/' . $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
+        $msg = @is_readable($_ext) ? 'Could be loaded. Please add in php.ini' : '';
         $RCI->fail($name, $msg, $source_urls[$name]);
     }
     echo '<br />';
@@ -78,8 +81,8 @@ foreach ($optional_php_exts AS $name => $ext) {
         $RCI->pass($name);
     }
     else {
-        $_ext = $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
-        $msg = @dl($_ext) ? 'Could be loaded. Please add in php.ini' : '';
+        $_ext = $ext_dir . '/' . $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
+        $msg = @is_readable($_ext) ? 'Could be loaded. Please add in php.ini' : '';
         $RCI->na($name, $msg, $source_urls[$name]);
     }
     echo '<br />';
@@ -99,8 +102,8 @@ foreach ($supported_dbs AS $database => $ext) {
         $RCI->pass($database);
     }
     else {
-        $_ext = $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
-        $msg = @dl($_ext) ? 'Could be loaded. Please add in php.ini' : 'Not installed';
+        $_ext = $ext_dir . '/' . $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
+        $msg = @is_readable($_ext) ? 'Could be loaded. Please add in php.ini' : 'Not installed';
         $RCI->na($database, $msg, $source_urls[$database]);
     }
     echo '<br />';
index e51b4bf0af6624168cfaef62697933416205e07f..02deb9b6db1f51e49af596988664513518a322a8 100644 (file)
@@ -124,7 +124,7 @@ echo $check_spell->show(intval($RCI->getprop('enable_spellcheck')), array('value
 $select_spell = new html_select(array('name' => '_spellcheck_engine', 'id' => "cfgspellcheckengine"));
 if (extension_loaded('pspell'))
   $select_spell->add('pspell', 'pspell');
-$select_spell->add('Googlie', 'googlie');
+$select_spell->add('Googie', 'googie');
 
 echo $select_spell->show($RCI->is_post ? $_POST['_spellcheck_engine'] : 'pspell');
 
@@ -269,7 +269,7 @@ echo '<label for="cfgdbtype">Database type</label><br />';
 echo $input_dbhost->show($RCI->is_post ? $_POST['_dbhost'] : $dsnw['hostspec']);
 echo '<label for="cfgdbhost">Database server (omit for sqlite)</label><br />';
 echo $input_dbname->show($RCI->is_post ? $_POST['_dbname'] : $dsnw['database']);
-echo '<label for="cfgdbname">Database name (use a path and filename for sqlite)</label><br />';
+echo '<label for="cfgdbname">Database name (use absolute path and filename for sqlite)</label><br />';
 echo $input_dbuser->show($RCI->is_post ? $_POST['_dbuser'] : $dsnw['username']);
 echo '<label for="cfgdbuser">Database user name (needs write permissions)(omit for sqlite)</label><br />';
 echo $input_dbpass->show($RCI->is_post ? $_POST['_dbpass'] : $dsnw['password']);
index d771fb66b226c093b6ad55e188df0de04e36ef67..954fd1549e919821922d3a979090e009c9fbf385 100644 (file)
@@ -29,8 +29,8 @@ if (window.rcmail) {
     
     // set css style for archive folder
     var li;
-    if (rcmail.env.archive_folder && (li = rcmail.get_folder_li(rcmail.env.archive_folder)))
-      $(li).css('background-image', 'url(plugins/archive/foldericon.png)');
+    if (rcmail.env.archive_folder && rcmail.env.archive_folder_icon && (li = rcmail.get_folder_li(rcmail.env.archive_folder)))
+      $(li).css('background-image', 'url(' + rcmail.env.archive_folder_icon + ')');
   })
 }
 
index 9df7f8b99e9cb66f3ddd7701b0e999c1a4565ca6..27887cef3310310992b61e5172ef66ec4b3c60f4 100644 (file)
@@ -17,18 +17,22 @@ class archive extends rcube_plugin
   {
     $this->register_action('plugin.archive', array($this, 'request_action'));
 
-    # There is no "Archived flags"
-    # $GLOBALS['IMAP_FLAGS']['ARCHIVED'] = 'Archive';
+    // There is no "Archived flags"
+    // $GLOBALS['IMAP_FLAGS']['ARCHIVED'] = 'Archive';
     
     $rcmail = rcmail::get_instance();
-    if ($rcmail->task == 'mail' && ($rcmail->action == '' || $rcmail->action == 'show') && ($archive_folder = $rcmail->config->get('archive_mbox'))) {
+    if ($rcmail->task == 'mail' && ($rcmail->action == '' || $rcmail->action == 'show')
+      && ($archive_folder = $rcmail->config->get('archive_mbox'))) {
+
+      $skin_path = $this->local_skin_path();
+      
       $this->include_script('archive.js');
       $this->add_texts('localization', true);
       $this->add_button(
         array(
             'command' => 'plugin.archive',
-            'imagepas' => 'archive_pas.png',
-            'imageact' => 'archive_act.png',
+            'imagepas' => $skin_path.'/archive_pas.png',
+            'imageact' => $skin_path.'/archive_act.png',
             'title' => 'buttontitle',
             'domain' => $this->ID,
         ),
@@ -39,13 +43,13 @@ class archive extends rcube_plugin
 
       // set env variable for client
       $rcmail->output->set_env('archive_folder', $archive_folder);
+      $rcmail->output->set_env('archive_folder_icon', $this->url($skin_path.'/foldericon.png'));
 
       // add archive folder to the list of default mailboxes
       if (($default_folders = $rcmail->config->get('default_imap_folders')) && !in_array($archive_folder, $default_folders)) {
         $default_folders[] = $archive_folder;
         $rcmail->config->set('default_imap_folders', $default_folders);
-      }
-      
+      }  
     }
     else if ($rcmail->task == 'settings') {
       $dont_override = $rcmail->config->get('dont_override', array());
@@ -111,7 +115,8 @@ class archive extends rcube_plugin
       $this->add_texts('localization');
       
       $rcmail = rcmail::get_instance();
-      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true, 'maxlength' => 30));
+      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true,
+        'maxlength' => 30, 'exceptions' => array('INBOX')));
 
       $args['blocks']['main']['options']['archive_mbox'] = array(
           'title' => $this->gettext('archivefolder'),
diff --git a/plugins/archive/archive_act.png b/plugins/archive/archive_act.png
deleted file mode 100644 (file)
index 2a17358..0000000
Binary files a/plugins/archive/archive_act.png and /dev/null differ
diff --git a/plugins/archive/archive_pas.png b/plugins/archive/archive_pas.png
deleted file mode 100644 (file)
index 8de2085..0000000
Binary files a/plugins/archive/archive_pas.png and /dev/null differ
diff --git a/plugins/archive/foldericon.png b/plugins/archive/foldericon.png
deleted file mode 100644 (file)
index ec0853c..0000000
Binary files a/plugins/archive/foldericon.png and /dev/null differ
diff --git a/plugins/archive/localization/cs_CZ.inc b/plugins/archive/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..04c8fcf
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+/*
+
++-----------------------------------------------------------------------+
+| language/cs_CZ/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube archive plugin                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Milan Kozak <hodza@hodza.net>                                 |
++-----------------------------------------------------------------------+
+
+@version $Id: labels.inc 2993 2009-09-26 18:32:07Z alec $
+
+*/
+
+$labels = array();
+$labels['buttontitle'] = 'Archivovat zprávu';
+$labels['archived'] = 'Úspěšně vloženo do archivu';
+$labels['archivefolder'] = 'Archiv';
+
+?>
diff --git a/plugins/archive/localization/et_EE.inc b/plugins/archive/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..e3968d7
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Arhiveeri see kiri';
+$labels['archived'] = 'Edukalt arhiveeritud';
+$labels['archivefolder'] = 'Arhiveeri';
+
+?>
index 422d45d8747058dfa5c07b17f143587eba03f26b..f44f30f44e17696fa63996304d0a8a5d3452c67a 100644 (file)
@@ -6,4 +6,3 @@ $labels['archived'] = 'Message archiv
 $labels['archivefolder'] = 'Archive';
 
 ?>
-
diff --git a/plugins/archive/localization/ru_RU.inc b/plugins/archive/localization/ru_RU.inc
new file mode 100644 (file)
index 0000000..e377ad0
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Переместить выбранное в архив';
+$labels['archived'] = 'Перенесено в Архив';
+$labels['archivefolder'] = 'Архив';
+
+?>
diff --git a/plugins/archive/skins/default/archive_act.png b/plugins/archive/skins/default/archive_act.png
new file mode 100644 (file)
index 0000000..2a17358
Binary files /dev/null and b/plugins/archive/skins/default/archive_act.png differ
diff --git a/plugins/archive/skins/default/archive_pas.png b/plugins/archive/skins/default/archive_pas.png
new file mode 100644 (file)
index 0000000..8de2085
Binary files /dev/null and b/plugins/archive/skins/default/archive_pas.png differ
diff --git a/plugins/archive/skins/default/foldericon.png b/plugins/archive/skins/default/foldericon.png
new file mode 100644 (file)
index 0000000..ec0853c
Binary files /dev/null and b/plugins/archive/skins/default/foldericon.png differ
index fcdcea7a5d73fc47a8153548555e64db025be2b0..dce2de29391df87a5fa6b5ac7dd0ec47ef7d66e0 100644 (file)
@@ -57,7 +57,7 @@ class filesystem_attachments extends rcube_plugin
         $tmpfname = tempnam($temp_dir, 'rcmAttmnt');
 
         if (move_uploaded_file($args['path'], $tmpfname) && file_exists($tmpfname)) {
-            $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+            $args['id'] = $this->file_id();
             $args['path'] = $tmpfname;
             $args['status'] = true;
 
@@ -88,7 +88,7 @@ class filesystem_attachments extends rcube_plugin
                 return $args;
         }
         
-        $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+        $args['id'] = $this->file_id();
         $args['status'] = true;
             
         // Note the file for later cleanup
@@ -146,4 +146,11 @@ class filesystem_attachments extends rcube_plugin
         }
         return $args;
     }
+
+    function file_id()
+    {
+        $userid = rcmail::get_instance()->user->ID;
+       list($usec, $sec) = explode(' ', microtime()); 
+        return preg_replace('/[^0-9]/', '', $userid . $sec . $usec);
+    }
 }
index afaded6f4911d45832177802f34e9921de3687af..69ac080b69df5f6c677d9cd838778544efc5ba5c 100644 (file)
@@ -1,5 +1,5 @@
 <div id="helpabout">
-<h3 align="center">Copyright &copy; 2005-2009, RoundCube Dev. - Switzerland</h3>
+<h3 align="center">Copyright &copy; 2005-2009, The Roundcube Dev Team</h3>
 
 <p>This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License version 2
@@ -33,5 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 <b>Tomasz Pajor (tomekp)</b><br />
 <b>Fourat Zouari (fourat.zouari)</b><br />
 <b>Aleksander Machniak (alec)</b>
+
+<p><br/>Website: <a href="http://roundcube.net">roundcube.net</a></p>
 </div>
 </div>
diff --git a/plugins/help/localization/cs_CZ.inc b/plugins/help/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..638b355
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+/*
+
++-----------------------------------------------------------------------+
+| language/cs_CZ/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube help plugin                            |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Milan Kozak <hodza@hodza.net>                                 |
++-----------------------------------------------------------------------+
+
+@version $Id: labels.inc 2993 2009-09-26 18:32:07Z alec $
+
+*/
+
+$labels = array();
+$labels['help'] = 'Nápověda';
+$labels['about'] = 'O aplikaci';
+$labels['license'] = 'Licence';
+
+?>
diff --git a/plugins/help/localization/hu_HU.inc b/plugins/help/localization/hu_HU.inc
new file mode 100644 (file)
index 0000000..6ff4f24
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['help'] = 'Segítség';
+$labels['about'] = 'Névjegy';
+$labels['license'] = 'Licenc';
+
+?>
index 7ccc671a2512913a90c3588cfed4ea237f55c3a1..e0b01bbf0d17003268b38d2c5889b17b9b764ef1 100644 (file)
 
 #helplicense, #helpabout
 {
-  padding: 20px;
+  width: 46em;
+  padding: 1em 2em;
 }
+
+#helplicense a, #helpabout a
+{
+  color: #900;
+}
+
+#helpabout
+{
+  margin: 0 auto;
+}
+
index 1ae90320c9b00d1cde9140965c479a5da1b2c4ab..fe41e43c0476b00f7973c54e5c7e18c16fc89692 100644 (file)
Binary files a/plugins/help/skins/default/help.gif and b/plugins/help/skins/default/help.gif differ
index 358836f01cc122d9a042ffdf4ecebd880d98647c..d5abbb2c14e6d4763e2b79587e2a07990d660ca6 100644 (file)
@@ -1,3 +1,19 @@
+* version 1.7 [2009-09-20]
+-----------------------------------------------------------
+- Support multiple managesieve hosts using %h variable
+  in managesieve_host option
+- Fix first rule deleting (#1486140) 
+
+* version 1.6 [2009-09-08]
+-----------------------------------------------------------
+- Fix warning when importing squirrelmail rules
+- Fix handling of "true" as "anyof (true)" test
+
+* version 1.5 [2009-09-04]
+-----------------------------------------------------------
+- Added es_ES, ua_UA localizations
+- Added 'managesieve_mbox_encoding' option
+
 * version 1.4 [2009-07-29]
 -----------------------------------------------------------
 - Updated PEAR::Net_Sieve to 1.1.7
index d8e949a1fcbda7dee380bc481456b1b064a8c375..c9ea44e764032c1f9a6f82cd32862e04dde17e29 100644 (file)
@@ -3,7 +3,8 @@
 // managesieve server port
 $rcmail_config['managesieve_port'] = 2000;
 
-// managesieve server address
+// managesieve server address, default is localhost.
+// Use %h variable as replacement for user's IMAP hostname
 $rcmail_config['managesieve_host'] = 'localhost';
 
 // use or not TLS for managesieve server connection
@@ -14,6 +15,11 @@ $rcmail_config['managesieve_usetls'] = false;
 // default contents of filters script (eg. default spam filter)
 $rcmail_config['managesieve_default'] = '/etc/dovecot/sieve/global';
 
+// Sieve RFC says that we should use UTF-8 endcoding for mailbox names,
+// but some implementations does not covert UTF-8 to modified UTF-7.
+// Defaults to UTF7-IMAP for backward compatybility
+$rcmail_config['managesieve_mbox_encoding'] = 'UTF7-IMAP';
+
 // I need this because my dovecot (with listescape plugin) uses
 // ':' delimiter, but creates folders with dot delimiter
 $rcmail_config['managesieve_replace_delimiter'] = '';
index 3bb150e444eb6d6442444261be66efa8b4925d3d..2490aca6edbc9bb969deb4a0df164c525f06e1c8 100644 (file)
@@ -117,7 +117,7 @@ class rcube_sieve
 
           $script = $this->_convert_from_squirrel_rules($script);
 
-          $this->script = new rcube_sieve_script($script);
+          $this->script = new rcube_sieve_script($script, $this->disabled);
        
           $this->save();
 
@@ -184,7 +184,7 @@ class rcube_sieve_script
     * @param  string  Script's text content
     * @param  array   Disabled extensions
     */
-  public function __construct($script, $disabled)
+  public function __construct($script, $disabled=NULL)
     {
       if (!empty($disabled))
         foreach ($disabled as $ext)
@@ -264,9 +264,10 @@ class rcube_sieve_script
     {
       $script = '';
       $exts = array();
+      $idx = 0;
       
       // rules
-      foreach ($this->content as $idx => $rule)
+      foreach ($this->content as $rule)
         {
          $extension = '';
          $tests = array();
@@ -367,7 +368,8 @@ class rcube_sieve_script
            }
          
          $script .= "}\n";
-       
+         $idx++;
+
          if ($extension && !isset($exts[$extension]))
            $exts[$extension] = $extension;
        }
@@ -442,7 +444,7 @@ class rcube_sieve_script
     {
       $result = NULL;
     
-      if (preg_match('/^(if|elsif|else)\s+((allof|anyof|exists|header|not|size)\s+(.*))\s+\{(.*)\}$/sm', trim($content), $matches))
+      if (preg_match('/^(if|elsif|else)\s+((true|not\s+true|allof|anyof|exists|header|not|size)(.*))\s+\{(.*)\}$/sm', trim($content), $matches))
         {
          list($tests, $join) = $this->_parse_tests(trim($matches[2]));
          $actions = $this->_parse_actions(trim($matches[5]));
@@ -454,7 +456,7 @@ class rcube_sieve_script
                    'join' => $join,
            );
        }
-    
+
       return $result;
     }    
 
diff --git a/plugins/managesieve/localization/cs_CZ.inc b/plugins/managesieve/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..62f0fdf
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Czech translation for Roundcube managesieve plugin
+ *
+ * @version 1.0 (2009-09-29)
+ * @author Daniel Kolar <kolar@g2n.cz>
+ *
+ */
+
+$labels['filters'] = 'Filtry';
+$labels['managefilters'] = 'Nastavení filtrů';
+$labels['filtername'] = 'Název filtru';
+$labels['newfilter'] = 'Nový filtr';
+$labels['filteradd'] = 'Přidej filtr';
+$labels['filterdel'] = 'Smaž filtr';
+$labels['moveup'] = 'Posunout nahoru';
+$labels['movedown'] = 'Posunout dolů';
+$labels['filterallof'] = 'Odpovídají všechny pravidla';
+$labels['filteranyof'] = 'Odpovídá kterékoliv pravidlo';
+$labels['filterany'] = 'Všechny zprávy';
+$labels['filtercontains'] = 'obsahuje';
+$labels['filternotcontains'] = 'neobsahuje';
+$labels['filteris'] = 'odpovídá';
+$labels['filterisnot'] = 'neodpovídá';
+$labels['filterexists'] = 'existuje';
+$labels['filternotexists'] = 'neexistuje';
+$labels['filterunder'] = 'pod';
+$labels['filterover'] = 'nad';
+$labels['addrule'] = 'Přidej pravidlo';
+$labels['delrule'] = 'Smaž pravidlo';
+$labels['messagemoveto'] = 'Přesuň zprávu do';
+$labels['messageredirect'] = 'Přeposlat zprávu na';
+$labels['messagereply'] = 'Odpovědět se zprávou';
+$labels['messagedelete'] = 'Smazat zprávu';
+$labels['messagediscard'] = 'Smazat se zprávou';
+$labels['messagesrules'] = 'Pravidla pro příchozí zprávu:';
+$labels['messagesactions'] = '...vykonej následující akce:';
+$labels['add'] = 'Přidej';
+$labels['del'] = 'Smaž';
+$labels['sender'] = 'Odesílatel';
+$labels['recipient'] = 'Příjemce';
+$labels['vacationaddresses'] = 'Seznam příjemců, kterým nebude zpráva odeslána (oddělené čárkou):';
+$labels['vacationdays'] = 'Počet dnů mezi automatickými odpověďmi:';
+$labels['vacationreason'] = 'Zpráva (Důvod nepřítomnosti):';
+$labels['rulestop'] = 'Zastavit pravidla';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Neznámá chyba serveru';
+$messages['filterconnerror'] = 'Nebylo možné se připojit k sieve serveru';
+$messages['filterdeleteerror'] = 'Nebylo možné smazat filtr. Server nahlásil chybu';
+$messages['filterdeleted'] = 'Filtr byl smazán';
+$messages['filterconfirmdelete'] = 'Opravdu chcete smazat vybraný filtr?';
+$messages['filtersaved'] = 'Filtr byl uložen';
+$messages['filtersaveerror'] = 'Nebylo možné uložit filtr. Server nahlásil chybu.';
+$messages['ruledeleteconfirm'] = 'Jste si jisti, že chcete smazat vybrané pravidlo?';
+$messages['actiondeleteconfirm'] = 'Jste si jisti, že chcete smazat vybranou akci?';
+$messages['forbiddenchars'] = 'Zakázané znaky v poli';
+$messages['cannotbeempty'] = 'Pole nemůže být prázdné';
+
+?>
index c3a2feb98be196e0689ef1d449c7c5b0629af178..e2caf77ead3926b1576489fb21b07cb6cad7a276 100644 (file)
@@ -25,7 +25,7 @@ $labels['messagemoveto'] = 'Verschiebe Nachricht nach';
 $labels['messageredirect'] = 'Leite Nachricht um nach';
 $labels['messagereply'] = 'Antworte mit Nachricht';
 $labels['messagedelete'] = 'Nachricht löschen';
-$labels['messagediscard'] = 'Discard with message';
+$labels['messagediscard'] = 'Weise ab mit Nachricht';
 $labels['messagesrules'] = 'Für eingehende Nachrichten:';
 $labels['messagesactions'] = '...führe folgende Aktionen aus:';
 $labels['add'] = 'Hinzufügen';
@@ -40,13 +40,13 @@ $labels['rulestop'] = 'Regelauswertung anhalten';
 $messages = array();
 $messages['filterunknownerror'] = 'Unbekannter Serverfehler';
 $messages['filterconnerror'] = 'Kann nicht zum Sieve-Server verbinden';
-$messages['filterdeleteerror'] = 'Fehler beim des löschen  Filters. Serverfehler';
+$messages['filterdeleteerror'] = 'Fehler beim Löschen des Filters. Serverfehler';
 $messages['filterdeleted'] = 'Filter erfolgreich gelöscht';
-$messages['filterconfirmdelete'] = 'Möchten Sie den Filter löschen ?';
+$messages['filterconfirmdelete'] = 'Möchten Sie den Filter löschen?';
 $messages['filtersaved'] = 'Filter gespeichert';
 $messages['filtersaveerror'] = 'Serverfehler, konnte den Filter nicht speichern.';
 $messages['ruledeleteconfirm'] = 'Sicher, dass Sie die Regel löschen wollen?';
-$messages['actiondeleteconfirm'] = 'Sicher, dass Sie die ausgewaehlte Aktion löschen wollen?';
+$messages['actiondeleteconfirm'] = 'Sicher, dass Sie die ausgewählte Aktion löschen wollen?';
 $messages['forbiddenchars'] = 'Unerlaubte Zeichen im Feld';
 $messages['cannotbeempty'] = 'Feld darf nicht leer sein';
 
diff --git a/plugins/managesieve/localization/el_GR.inc b/plugins/managesieve/localization/el_GR.inc
new file mode 100644 (file)
index 0000000..a1a5eec
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+// Antonis Kanouras (2009-10-22)
+
+$labels = array();
+$labels['filters'] = 'Φίλτρα';
+$labels['managefilters'] = 'Διαχείριση φίλτρων εισερχόμενων';
+$labels['filtername'] = 'Ονομασία φίλτρου';
+$labels['newfilter'] = 'Δημιουργία φίλτρου';
+$labels['filteradd'] = 'Προσθήκη φίλτρου';
+$labels['filterdel'] = 'Διαγραφή φίλτρου';
+$labels['moveup'] = 'Μετακίνηση πάνω';
+$labels['movedown'] = 'Μετακίνηση κάτω';
+$labels['filterallof'] = 'ταιριάζουν με όλους τους παρακάτω κανόνες';
+$labels['filteranyof'] = 'ταιριάζουν με οποιονδήποτε από τους παρακάτω κανόνες';
+$labels['filterany'] = 'όλα τα μηνύματα';
+$labels['filtercontains'] = 'περιέχει';
+$labels['filternotcontains'] = 'δεν περιέχει';
+$labels['filteris'] = 'είναι ίσο με';
+$labels['filterisnot'] = 'δεν είναι ίσο με';
+$labels['filterexists'] = 'υπάρχει';
+$labels['filternotexists'] = 'δεν υπάρχει';
+$labels['filterunder'] = 'κάτω';
+$labels['filterover'] = 'πάνω';
+$labels['addrule'] = 'Προσθήκη κανόνα';
+$labels['delrule'] = 'Διαγραφή κανόνα';
+$labels['messagemoveto'] = 'Μετακίνηση μηνύματος στο';
+$labels['messageredirect'] = 'Προώθηση μηνύματος στο';
+$labels['messagereply'] = 'Απάντηση με μήνυμα';
+$labels['messagedelete'] = 'Διαγραφή μηνύματος';
+$labels['messagediscard'] = 'Απόρριψη με μήνυμα';
+$labels['messagesrules'] = 'Για εισερχόμενα μηνύματα που:';
+$labels['messagesactions'] = '...εκτέλεση των παρακάτω ενεργειών:';
+$labels['add'] = 'Προσθήκη';
+$labels['del'] = 'Διαγραφή';
+$labels['sender'] = 'Αποστολέας';
+$labels['recipient'] = 'Παραλήπτης';
+$labels['vacationaddresses'] = 'Πρόσθετη λίστα email παραληπτών (διαχωρισμένη με κόμματα):';
+$labels['vacationdays'] = 'Συχνότητα αποστολής μηνυμάτων (σε ημέρες):';
+$labels['vacationreason'] = 'Σώμα μηνύματος (λόγος απουσίας):';
+$labels['rulestop'] = 'Παύση επαλήθευσης κανόνων';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Άγνωστο σφάλμα διακομιστή';
+$messages['filterconnerror'] = 'Αδυναμία σύνδεσης στον διακομιστή managesieve';
+$messages['filterdeleteerror'] = 'Αδυναμία διαγραφής φίλτρου. Προέκυψε σφάλμα στον διακομιστή';
+$messages['filterdeleted'] = 'Το φίλτρο διαγράφηκε επιτυχώς';
+$messages['filterconfirmdelete'] = 'Θέλετε όντως να διαγράψετε το επιλεγμένο φίλτρο;';
+$messages['filtersaved'] = 'Το φίλτρο αποθηκεύτηκε επιτυχώς';
+$messages['filtersaveerror'] = 'Αδυναμία αποθήκευσης φίλτρου. Προέκυψε σφάλμα στον διακομιστή';
+$messages['ruledeleteconfirm'] = 'Θέλετε όντως να διαγράψετε τον επιλεγμένο κανόνα;';
+$messages['actiondeleteconfirm'] = 'Θέλετε όντως να διαγράψετε την επιλεγμένη ενέργεια;';
+$messages['forbiddenchars'] = 'Μη επιτρεπτοί χαρακτήρες στο πεδίο';
+$messages['cannotbeempty'] = 'Το πεδίο δεν μπορεί να είναι κενό';
+
+?>
diff --git a/plugins/managesieve/localization/en_GB.inc b/plugins/managesieve/localization/en_GB.inc
new file mode 100644 (file)
index 0000000..c671b83
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filters';
+$labels['managefilters'] = 'Manage incoming mail filters';
+$labels['filtername'] = 'Filter name';
+$labels['newfilter'] = 'New filter';
+$labels['filteradd'] = 'Add filter';
+$labels['filterdel'] = 'Delete filter';
+$labels['moveup'] = 'Move up';
+$labels['movedown'] = 'Move down';
+$labels['filterallof'] = 'matching all of the following rules';
+$labels['filteranyof'] = 'matching any of the following rules';
+$labels['filterany'] = 'all messages';
+$labels['filtercontains'] = 'contains';
+$labels['filternotcontains'] = 'not contains';
+$labels['filteris'] = 'is equal to';
+$labels['filterisnot'] = 'is not equal to';
+$labels['filterexists'] = 'exists';
+$labels['filternotexists'] = 'not exists';
+$labels['filterunder'] = 'under';
+$labels['filterover'] = 'over';
+$labels['addrule'] = 'Add rule';
+$labels['delrule'] = 'Delete rule';
+$labels['messagemoveto'] = 'Move message to';
+$labels['messageredirect'] = 'Redirect message to';
+$labels['messagereply'] = 'Reply with message';
+$labels['messagedelete'] = 'Delete message';
+$labels['messagediscard'] = 'Discard with message';
+$labels['messagesrules'] = 'For incoming mail:';
+$labels['messagesactions'] = '...execute the following actions:';
+$labels['add'] = 'Add';
+$labels['del'] = 'Delete';
+$labels['sender'] = 'Sender';
+$labels['recipient'] = 'Recipient';
+$labels['vacationaddresses'] = 'Additional list of recipient e-mails (comma separated):';
+$labels['vacationdays'] = 'How often send messages (in days):';
+$labels['vacationreason'] = 'Message body (vacation reason):';
+$labels['rulestop'] = 'Stop evaluating rules';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Unknown server error';
+$messages['filterconnerror'] = 'Unable to connect to managesieve server';
+$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured';
+$messages['filterdeleted'] = 'Filter deleted successfully';
+$messages['filterconfirmdelete'] = 'Do you really want to delete selected filter?';
+$messages['filtersaved'] = 'Filter saved successfully';
+$messages['filtersaveerror'] = 'Unable to save filter. Server error occured.';
+$messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?';
+$messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?';
+$messages['forbiddenchars'] = 'Forbidden characters in field';
+$messages['cannotbeempty'] = 'Field cannot be empty';
+
+?>
diff --git a/plugins/managesieve/localization/gb_GB.inc b/plugins/managesieve/localization/gb_GB.inc
deleted file mode 100644 (file)
index c671b83..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-$labels['filters'] = 'Filters';
-$labels['managefilters'] = 'Manage incoming mail filters';
-$labels['filtername'] = 'Filter name';
-$labels['newfilter'] = 'New filter';
-$labels['filteradd'] = 'Add filter';
-$labels['filterdel'] = 'Delete filter';
-$labels['moveup'] = 'Move up';
-$labels['movedown'] = 'Move down';
-$labels['filterallof'] = 'matching all of the following rules';
-$labels['filteranyof'] = 'matching any of the following rules';
-$labels['filterany'] = 'all messages';
-$labels['filtercontains'] = 'contains';
-$labels['filternotcontains'] = 'not contains';
-$labels['filteris'] = 'is equal to';
-$labels['filterisnot'] = 'is not equal to';
-$labels['filterexists'] = 'exists';
-$labels['filternotexists'] = 'not exists';
-$labels['filterunder'] = 'under';
-$labels['filterover'] = 'over';
-$labels['addrule'] = 'Add rule';
-$labels['delrule'] = 'Delete rule';
-$labels['messagemoveto'] = 'Move message to';
-$labels['messageredirect'] = 'Redirect message to';
-$labels['messagereply'] = 'Reply with message';
-$labels['messagedelete'] = 'Delete message';
-$labels['messagediscard'] = 'Discard with message';
-$labels['messagesrules'] = 'For incoming mail:';
-$labels['messagesactions'] = '...execute the following actions:';
-$labels['add'] = 'Add';
-$labels['del'] = 'Delete';
-$labels['sender'] = 'Sender';
-$labels['recipient'] = 'Recipient';
-$labels['vacationaddresses'] = 'Additional list of recipient e-mails (comma separated):';
-$labels['vacationdays'] = 'How often send messages (in days):';
-$labels['vacationreason'] = 'Message body (vacation reason):';
-$labels['rulestop'] = 'Stop evaluating rules';
-
-$messages = array();
-$messages['filterunknownerror'] = 'Unknown server error';
-$messages['filterconnerror'] = 'Unable to connect to managesieve server';
-$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured';
-$messages['filterdeleted'] = 'Filter deleted successfully';
-$messages['filterconfirmdelete'] = 'Do you really want to delete selected filter?';
-$messages['filtersaved'] = 'Filter saved successfully';
-$messages['filtersaveerror'] = 'Unable to save filter. Server error occured.';
-$messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?';
-$messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?';
-$messages['forbiddenchars'] = 'Forbidden characters in field';
-$messages['cannotbeempty'] = 'Field cannot be empty';
-
-?>
index ad459a0f2a66158d542bb0b83f94cef281e59c48..b4029438d8207899488ba4cfe9e86d34d2985017 100644 (file)
@@ -32,6 +32,10 @@ $labels['add'] = 'Добавить';
 $labels['del'] = 'Удалить';
 $labels['sender'] = 'Отправитель';
 $labels['recipient'] = 'Получатель';
+$labels['vacationaddresses'] = 'Список дополнительных адресов почты (разделённый запятыми):';
+$labels['vacationdays'] = 'Как часто отправлять сообщение (раз в сколько дней):';
+$labels['vacationreason'] = 'Текст сообщения (причины отсутствия):';
+$labels['rulestop'] = 'Не обрабатывать последующие правила';
 
 $messages = array();
 $messages['filterunknownerror'] = 'Неизвестная ошибка сервера';
index 21d974da6fe696085376b01b768f13a9c4f9a0f8..0c8c492e4bb4059016d19c4bc7baf3e90f1eceb5 100644 (file)
@@ -7,7 +7,7 @@
  * It's clickable interface which operates on text scripts and communicates
  * with server using managesieve protocol. Adds Filters tab in Settings.
  *
- * @version 1.3
+ * @version 1.7
  * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
  *
  * Configuration (see config.inc.php.dist):
@@ -62,7 +62,7 @@ class managesieve extends rcube_plugin
     // try to connect to managesieve server and to fetch the script
     $this->sieve = new rcube_sieve($_SESSION['username'],
        $this->rc->decrypt($_SESSION['password']), 
-       $this->rc->config->get('managesieve_host', 'localhost'),
+       str_replace('%h', $_SESSION['imap_host'], $this->rc->config->get('managesieve_host', 'localhost')),
        $this->rc->config->get('managesieve_port', 2000),
        $this->rc->config->get('managesieve_usetls', false),
        $this->rc->config->get('managesieve_disabled_extensions'));
@@ -744,6 +744,9 @@ class managesieve extends rcube_plugin
     $a_folders = $this->rc->imap->list_mailboxes();
     $delimiter = $this->rc->imap->get_hierarchy_delimiter();
 
+    // set mbox encoding
+    $mbox_encoding = $this->rc->config->get('managesieve_mbox_encoding', 'UTF7-IMAP'); 
+
     if ($action['type'] == 'fileinto')
       $mailbox = $action['target'];
     else
@@ -758,6 +761,9 @@ class managesieve extends rcube_plugin
       if ($replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter'))
         $utf7folder = str_replace($delimiter, $replace_delimiter, $utf7folder);
     
+      // convert to Sieve implementation encoding
+      $utf7folder = $this->mbox_encode($utf7folder, $mbox_encoding);
+    
       if ($folder_class = rcmail_folder_classname($name))
         $foldername = $this->gettext($folder_class);
       else
@@ -812,6 +818,9 @@ class managesieve extends rcube_plugin
 
   private function check_email($email)
   {
+    if (function_exists('check_email'));
+      return check_email($email);
+
     // Check for invalid characters
     if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $email))
       return false;
@@ -849,6 +858,10 @@ class managesieve extends rcube_plugin
     return false;
   }
  
+  private function mbox_encode($text, $encoding)
+  {
+    return rcube_charset_convert($text, 'UTF7-IMAP', $encoding);
+  }
 }
 
 ?>
diff --git a/plugins/markasjunk/junk_act.png b/plugins/markasjunk/junk_act.png
deleted file mode 100644 (file)
index b5a84f6..0000000
Binary files a/plugins/markasjunk/junk_act.png and /dev/null differ
diff --git a/plugins/markasjunk/junk_pas.png b/plugins/markasjunk/junk_pas.png
deleted file mode 100644 (file)
index b88a561..0000000
Binary files a/plugins/markasjunk/junk_pas.png and /dev/null differ
diff --git a/plugins/markasjunk/localization/cs_CZ.inc b/plugins/markasjunk/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..06ab2e9
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+/*
+
++-----------------------------------------------------------------------+
+| language/cs_CZ/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube markasjunk plugin                      |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Milan Kozak <hodza@hodza.net>                                 |
++-----------------------------------------------------------------------+
+
+@version $Id: labels.inc 2993 2009-09-26 18:32:07Z alec $
+
+*/
+
+$labels = array();
+$labels['buttontitle'] = 'Označit jako Spam';
+$labels['reportedasjunk'] = 'Úspěšně nahlášeno jako Spam';
+
+?>
\ No newline at end of file
diff --git a/plugins/markasjunk/localization/ru_RU.inc b/plugins/markasjunk/localization/ru_RU.inc
new file mode 100644 (file)
index 0000000..32d00c2
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Переместить в "СПАМ"';
+$labels['reportedasjunk'] = 'Перемещено в "СПАМ"';
+
+?>
index 959111d84e9641a9f8a05e4db7f0b352a741a3ab..cf81883fc106ac16cb6bf12fee29e7c2a0ed49f4 100644 (file)
@@ -16,24 +16,32 @@ class markasjunk extends rcube_plugin
   function init()
   {
     $this->register_action('plugin.markasjunk', array($this, 'request_action'));
-    $GLOBALS['IMAP_FLAGS']['JUNK'] = 'Junk';
     
     $rcmail = rcmail::get_instance();
     if ($rcmail->action == '' || $rcmail->action == 'show') {
+      $skin_path = $this->local_skin_path();
       $this->include_script('markasjunk.js');
       $this->add_texts('localization', true);
-      $this->add_button(array('command' => 'plugin.markasjunk', 'imagepas' => 'junk_pas.png', 'imageact' => 'junk_act.png'), 'toolbar');
+      $this->add_button(array(
+        'command' => 'plugin.markasjunk',
+        'imagepas' => $skin_path.'/junk_pas.png',
+        'imageact' => $skin_path.'/junk_act.png',
+       'title' => 'markasjunk.buttontitle'), 'toolbar');
     }
   }
 
   function request_action()
   {
     $this->add_texts('localization');
+
+    $GLOBALS['IMAP_FLAGS']['JUNK'] = 'Junk';
+    $GLOBALS['IMAP_FLAGS']['NONJUNK'] = 'NonJunk';
     
     $uids = get_input_value('_uid', RCUBE_INPUT_POST);
     $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
     
     $rcmail = rcmail::get_instance();
+    $rcmail->imap->unset_flag($uids, 'NONJUNK');
     $rcmail->imap->set_flag($uids, 'JUNK');
     
     if (($junk_mbox = $rcmail->config->get('junk_mbox')) && $mbox != $junk_mbox) {
@@ -44,4 +52,4 @@ class markasjunk extends rcube_plugin
     $rcmail->output->send();
   }
 
-}
\ No newline at end of file
+}
diff --git a/plugins/markasjunk/skins/default/junk_act.png b/plugins/markasjunk/skins/default/junk_act.png
new file mode 100644 (file)
index 0000000..b5a84f6
Binary files /dev/null and b/plugins/markasjunk/skins/default/junk_act.png differ
diff --git a/plugins/markasjunk/skins/default/junk_pas.png b/plugins/markasjunk/skins/default/junk_pas.png
new file mode 100644 (file)
index 0000000..b88a561
Binary files /dev/null and b/plugins/markasjunk/skins/default/junk_pas.png differ
diff --git a/plugins/new_user_dialog/localization/ru_RU.inc b/plugins/new_user_dialog/localization/ru_RU.inc
new file mode 100644 (file)
index 0000000..d1eb28e
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Пожалуйста, укажите Ваше имя.';
+$labels['identitydialoghint'] = 'Данное сообщение отображается только при первом входе.';
+
+?>
index 4f6250f08ba7392104bc093325eac676998fed7a..965a405b782c0da4d9bf3b5d2df90645acaef580 100644 (file)
@@ -96,7 +96,7 @@ class new_user_dialog extends rcube_plugin
       $save_data['email'] = $identity['email'];
     
     // save data if not empty
-    if (!empty($save_data['name']) && !empty($save_data['name'])) {
+    if (!empty($save_data['name']) && !empty($save_data['email'])) {
       $rcmail->user->update_identity($identity['identity_id'], $save_data);
       rcube_sess_unset('plugin.newuserdialog');
     }
index 75595693c8f7ba4ad7f4d9a52fe808ebe255d8b8..78c99522d9700f4b4d184e2e64b780864af9a063 100644 (file)
  *  // When automatically setting a new users's full name in their
  *  // new identity, match the user's login name against this field.
  *  $rcmail_config['new_user_identity_match'] = 'uid';
- *  
- *  // Use the value in this field to automatically set a new users's
- *  // full name in their new identity.
- *  $rcmail_config['new_user_identity_field'] = 'name';
  */
 class new_user_identity extends rcube_plugin
 {
@@ -40,7 +36,7 @@ class new_user_identity extends rcube_plugin
             $ldap->prop['search_fields'] = array($match);
             $results = $ldap->search($match, $args['user'], TRUE);
             if (count($results->records) == 1) {
-                $args['user_name'] = $results->records[0][$rcmail->config->get('new_user_identity_field')];
+                $args['user_name'] = $results->records[0]['name'];
             }
         }
         return $args;
index 033af5f694ecc0ffaf55695b5361bd504072c8f0..c7e8203ad516afde707d9984fbfc64f5add57434 100644 (file)
@@ -31,6 +31,8 @@
  2.3.  Poppassd/Courierpassd (poppassd)
  2.4.  LDAP (ldap)
  2.5.  DirectAdmin Control Panel
+ 2.6.   cPanel
+ 2.7.   XIMSS (Communigate)
  3.    Driver API
 
 
  2.3. Poppassd/Courierpassd (poppassd)
  -------------------------------------
 
- You can specify which host to connect to via `password_pop_host` and
- what port via `password_pop_port`. See config.inc.php file for more info.
+ You can specify which host to connect to via 'password_pop_host' and
+ what port via 'password_pop_port'. See config.inc.php file for more info.
 
 
  2.4. LDAP (ldap)
  2.5. DirectAdmin Control Panel
  -------------------------------------
 
- You can specify which host to connect to via `password_directadmin_host` 
- and what port via `password_direactadmin_port`. See config.inc.php file 
+ You can specify which host to connect to via 'password_directadmin_host' 
+ and what port via 'password_direactadmin_port'. See config.inc.php file 
  for more info.
 
 
+ 2.6. cPanel
+ -----------
+
+ You can specify parameters for HTTP connection to cPanel's admin
+ interface. See config.inc.php file for more info.
+
+
+ 2.7. XIMSS (Communigate)
+ -------------------------------------
+
+ You can specify which host and port to connect to via 'password_ximss_host' 
+ and 'password_ximss_port'. See config.inc.php file for more info.
+
+
  3. Driver API
  -------------
 
index 076cfd6a1811f2b4683cc32c85417deda42d5b0b..b9e3b9102f4ac67955d2d2c71a802a8082a9b410 100644 (file)
@@ -3,12 +3,21 @@
 // Password Plugin options
 // -----------------------
 // A driver to use for password change. Default: "sql".
+// Current possibilities: 'directadmin', 'ldap', 'poppassd', 'sasl', 'sql', 'vpopmaild', 'cpanel'
 $rcmail_config['password_driver'] = 'sql';
 
 // Determine whether current password is required to change password.
 // Default: false.
 $rcmail_config['password_confirm_current'] = true;
 
+// Require the new password to be a certain length.
+// set to blank to allow passwords of any length
+$rcmail_config['password_minimum_length'] = 0;
+// Require the new password to contain a letter and punctuation character
+// Change to false to remove this check.
+$rcmail_config['password_require_nonalpha'] = false;
+
 
 // SQL Driver options
 // ------------------
@@ -134,9 +143,49 @@ $rcmail_config['password_ldap_force_replace'] = true;
 // DirectAdmin Driver options
 // --------------------------
 // The host which changes the password
-$rcmail_config['password_directadmin_host'] = 'localhost';
+// Use 'ssl://serverip' instead of 'tcp://serverip' when running DirectAdmin over SSL.
+$rcmail_config['password_directadmin_host'] = 'tcp://localhost';
 
 // TCP port used for DirectAdmin connections
 $rcmail_config['password_directadmin_port'] = 2222;
 
+
+// vpopmaild Driver options
+// -----------------------
+// The host which changes the password
+$rcmail_config['password_vpopmaild_host'] = 'localhost';
+
+// TCP port used for vpopmaild connections
+$rcmail_config['password_vpopmaild_port'] = 89;
+
+
+// cPanel Driver options
+// --------------------------
+// The cPanel Host name
+$rcmail_config['password_cpanel_host'] = 'host.domain.com';
+
+// The cPanel admin username
+$rcmail_config['password_cpanel_username'] = 'username';
+
+// The cPanel admin password
+$rcmail_config['password_cpanel_password'] = 'password';
+
+// The cPanel port to use
+$rcmail_config['password_cpanel_port'] = 2082;
+
+// Using ssl for cPanel connections?
+$rcmail_config['password_cpanel_ssl'] = true;
+
+// The cPanel theme in use
+$rcmail_config['password_cpanel_theme'] = 'x';
+
+
+// XIMSS (Communigate server) Driver options
+// -----------------------------------------
+// Host name of the Communigate server
+$rcmail_config['password_ximss_host'] = 'mail.example.com';
+
+// XIMSS port on Communigate server
+$rcmail_config['password_ximss_port'] = 11024;
+
 ?>
diff --git a/plugins/password/drivers/cpanel.php b/plugins/password/drivers/cpanel.php
new file mode 100644 (file)
index 0000000..82bfe74
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * cPanel Password Driver
+ *
+ * Driver that adds functionality to change the users cPanel password.
+ * The cPanel PHP API code has been taken from: http://www.phpclasses.org/browse/package/3534.html
+ *
+ * This driver has been tested with Hostmonster hosting and seems to work fine.
+
+ *
+ * @version 1.0
+ * @author Fulvio Venturelli <fulvio@venturelli.org>
+ */
+
+class HTTP
+{
+       function HTTP($host, $username, $password, $port, $ssl, $theme)
+       {
+               $this->ssl = $ssl ? 'ssl://' : '';
+               $this->username = $username;
+               $this->password = $password;
+               $this->theme = $theme;
+               $this->auth = base64_encode($username . ':' . $password);
+               $this->port = $port;
+               $this->host = $host;
+               $this->path = '/frontend/' . $theme . '/';
+       }
+
+       function getData($url, $data = '')
+       {
+               $url = $this->path . $url;
+               if(is_array($data))
+               {
+                       $url = $url . '?';
+                       foreach($data as $key=>$value)
+                       {
+                               $url .= urlencode($key) . '=' . urlencode($value) . '&';
+                       }
+                       $url = substr($url, 0, -1);
+               }
+               $response = '';
+               $fp = fsockopen($this->ssl . $this->host, $this->port);
+               if(!$fp)
+               {
+                       return false;
+               }
+               $out = 'GET ' . $url . ' HTTP/1.0' . "\r\n";
+               $out .= 'Authorization: Basic ' . $this->auth . "\r\n";
+               $out .= 'Connection: Close' . "\r\n\r\n";
+               fwrite($fp, $out);
+               while (!feof($fp))
+               {
+                       $response .= @fgets($fp);
+               }
+               fclose($fp);
+               return $response;
+       }
+}
+
+
+class emailAccount
+{          
+       function emailAccount($host, $username, $password, $port, $ssl, $theme, $address)
+       {
+               $this->HTTP = new HTTP($host, $username, $password, $port, $ssl, $theme);
+               if(strpos($address, '@'))
+               {
+                       list($this->email, $this->domain) = explode('@', $address);
+               }
+               else
+               {
+                       list($this->email, $this->domain) = array($address, '');
+               }
+       }
+
+ /*
+  * Change email account password
+  *
+  * Returns true on success or false on failure.
+  * @param string $password email account password
+  * @return bool
+  */
+       function setPassword($password)
+       {
+               $data['email'] = $this->email;
+               $data['domain'] = $this->domain;
+               $data['password'] = $password;
+               $response = $this->HTTP->getData('mail/dopasswdpop.html', $data);
+               if(strpos($response, 'success') && !strpos($response, 'failure'))
+               {
+                       return true;
+               }
+               return false;
+       }
+}
+
+
+function password_save($curpas, $newpass)
+{
+    $rcmail = rcmail::get_instance();
+
+    // Create a cPanel email object
+    $cPanel = new emailAccount($rcmail->config->get('password_cpanel_host'),
+       $rcmail->config->get('password_cpanel_username'),
+       $rcmail->config->get('password_cpanel_password'),
+       $rcmail->config->get('password_cpanel_port'),
+       $rcmail->config->get('password_cpanel_ssl'),
+       $rcmail->config->get('password_cpanel_theme'),
+       $_SESSION['username'] );
+
+    if ($cPanel->setPassword($newpass)){
+        return PASSWORD_SUCCESS;
+    }
+    else
+    {
+       return PASSWORD_ERROR;
+    }
+}
+
+?>
index 9afaa65d87d295233ab17996bd99c2d6193b4087..1e737f2333accaf1750e28bfaeac474e70868856 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Driver for passwords stored in SQL database
  *
- * @version 1.2
+ * @version 1.3
  * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
  *
  */
@@ -81,7 +81,7 @@ function password_save($curpass, $passwd)
     $user_info = explode('@', $_SESSION['username']);
     if (count($user_info) >= 2) {
        $sql = str_replace('%l', $db->quote($user_info[0], 'text'), $sql);
-       $sql = str_replace('%d', $db->quote($user_info[0], 'text'), $sql);
+       $sql = str_replace('%d', $db->quote($user_info[1], 'text'), $sql);
     }
     
     $sql = str_replace('%u', $db->quote($_SESSION['username'],'text'), $sql);
diff --git a/plugins/password/drivers/vpopmaild.php b/plugins/password/drivers/vpopmaild.php
new file mode 100644 (file)
index 0000000..db57eaf
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * vpopmail Password Driver
+ *
+ * Driver to change passwords via vpopmaild
+ *
+ * @version 1.0
+ * @author Johannes Hessellund
+ *
+ */
+
+function password_save($curpass, $passwd)
+{
+    $rcmail = rcmail::get_instance();
+//    include('Net/Socket.php');
+    $vpopmaild = new Net_Socket();
+
+    if (PEAR::isError($vpopmaild->connect($rcmail->config->get('password_vpopmaild_host'), $rcmail->config->get('password_vpopmaild_port'), null))) {
+        return PASSWORD_CONNECT_ERROR;
+    }
+    else {
+        $result = $vpopmaild->readLine();
+        if(!preg_match('/^\+OK/', $result)) {
+            $vpopmaild->disconnect();
+            return PASSWORD_CONNECT_ERROR;
+        }
+        else {
+            $vpopmaild->writeLine("slogin ". $_SESSION['username'] . " " . $curpass);
+            $result = $vpopmaild->readLine();
+            if(!preg_match('/^\+OK/', $result) ) {
+                $vpopmaild->writeLine("quit");
+                $vpopmaild->disconnect();
+                return PASSWORD_ERROR;
+            }
+            else {
+                $vpopmaild->writeLine("mod_user ". $_SESSION['username']);
+                $result = $vpopmaild->readLine();
+                if(!preg_match('/^\+OK/', $result) ) {
+                    $vpopmaild->writeLine("quit");
+                    $vpopmaild->disconnect();
+                    return PASSWORD_ERROR;
+                }
+                else {
+                    $vpopmaild->writeLine("clear_text_password ". $passwd);
+                    $vpopmaild->writeLine(".");
+                    $result = $vpopmaild->readLine();
+                    $vpopmaild->writeLine("quit");
+                    $vpopmaild->disconnect();
+                    if (!preg_match('/^\+OK/', $result))
+                        return PASSWORD_ERROR;
+                    else
+                        return PASSWORD_SUCCESS;
+                }
+            }
+        }
+    }
+}
+
+?>
diff --git a/plugins/password/drivers/ximss.php b/plugins/password/drivers/ximss.php
new file mode 100644 (file)
index 0000000..94aba18
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Communigate driver for the Password Plugin for Roundcube 
+ *
+ * Tested with Communigate Pro 5.1.2
+ *
+ * Configuration options:
+ *   password_ximss_host - Host name of Communigate server
+ *   password_ximss_port - XIMSS port on Communigate server
+ *
+ *
+ * References:
+ *   http://www.communigate.com/WebGuide/XMLAPI.html
+ *
+ * @version 1
+ * @author Erik Meitner <erik wanderings.us>
+ */
+function password_save($pass, $newpass)
+{
+
+  $rcmail = rcmail::get_instance();
+  
+  $sock = stream_socket_client("tcp://".$rcmail->config->get('password_ximss_host').":".$rcmail->config->get('password_ximss_port'), $errno, $errstr, 30) ;
+  if( $sock === FALSE )
+  {
+    return PASSWORD_CONNECT_ERROR;
+  }
+  
+  // send all requests at once(pipelined)
+  fwrite( $sock, '<login id="A001" authData="'.$_SESSION['username'].'" password="'.$pass.'" />'."\0");
+  fwrite( $sock, '<passwordModify id="A002" oldPassword="'.$pass.'" newPassword="'.$newpass.'"  />'."\0");
+  fwrite( $sock, '<bye id="A003" />'."\0");
+
+  //example responses
+  //  <session id="A001" urlID="4815-vN2Txjkggy7gjHRD10jw" userName="user@example.com"/>\0
+  //  <response id="A001"/>\0
+  //  <response id="A002"/>\0
+  //  <response id="A003"/>\0
+  // or an error:
+  //  <response id="A001" errorText="incorrect password or account name" errorNum="515"/>\0
+
+  $responseblob = '';
+  while (!feof($sock)) {
+    $responseblob .= fgets($sock, 1024);
+  }
+
+  fclose($sock);
+  
+  foreach( explode( "\0",$responseblob) as $response )
+  {
+    $resp = simplexml_load_string("<xml>".$response."</xml>");
+
+    if( $resp->response[0]['id'] == 'A001' )
+    {
+      if( isset( $resp->response[0]['errorNum'] ) )
+      {
+        return PASSWORD_CONNECT_ERROR;
+      }  
+    }
+    else if( $resp->response[0]['id'] == 'A002' )
+    {
+      if( isset( $resp->response[0]['errorNum'] ))
+      {
+        return PASSWORD_ERROR;
+      }  
+    }
+    else if( $resp->response[0]['id'] == 'A003' )
+    {
+      if( isset($resp->response[0]['errorNum'] ))
+      {
+        //There was a problem during logout(This is probably harmless)
+      }  
+    }
+  } //foreach
+
+  return PASSWORD_SUCCESS;
+  
+}
+  
+?>
\ No newline at end of file
diff --git a/plugins/password/localization/bg_BG.inc b/plugins/password/localization/bg_BG.inc
new file mode 100644 (file)
index 0000000..b4576a0
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Смяна на парола';
+$labels['curpasswd']  = 'Текуща парола:';
+$labels['newpasswd']  = 'Нова парола:';
+$labels['confpasswd']  = 'Повторете:';
+
+$messages = array();
+$messages['nopassword'] = 'Моля въведете нова парола.';
+$messages['nocurpassword'] = 'Моля въведете текущата .';
+$messages['passwordincorrect'] = 'Невалидна текуща парола.';
+$messages['passwordinconsistency'] = 'Паролите не съвпадат, опитайте пак.';
+$messages['crypterror'] = 'Паролата не може да бъде сменена. Грешка в криптирането.';
+$messages['connecterror'] = 'Паролата не може да бъде сменена. Грешка в свързването.';
+$messages['internalerror'] = 'Паролата не може да бъде сменена.';
+
+?>
diff --git a/plugins/password/localization/cs_CZ.inc b/plugins/password/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..18270db
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * Czech translation for Roundcube password plugin
+ *
+ * @version 1.0 (2009-08-29)
+ * @author Milan Kozak <hodza@hodza.net>
+ *
+ */
+
+$labels = array();
+$labels['changepasswd']  = 'Změna hesla';
+$labels['curpasswd']  = 'Aktuální heslo:';
+$labels['newpasswd']  = 'Nové heslo:';
+$labels['confpasswd']  = 'Nové heslo (pro kontrolu):';
+
+$messages = array();
+$messages['nopassword'] = 'Prosím zadejte nové heslo.';
+$messages['nocurpassword'] = 'Prosím zadejte aktuální heslo.';
+$messages['passwordincorrect'] = 'Zadané aktuální heslo není správné.';
+$messages['passwordinconsistency'] = 'Zadaná hesla se neshodují. Prosím zkuste to znovu.';
+$messages['crypterror'] = 'Heslo se nepodařilo uložit. Chybí šifrovací funkce.';
+$messages['connecterror'] = 'Heslo se nepodařilo uložit. Problém s připojením.';
+$messages['internalerror'] = 'Heslo se nepodařilo uložit.';
+
+?>
diff --git a/plugins/password/localization/da_DK.inc b/plugins/password/localization/da_DK.inc
new file mode 100644 (file)
index 0000000..5d1d0c9
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Skift adgangskode';
+$labels['curpasswd']  = 'Nuværende adgangskode:';
+$labels['newpasswd']  = 'Ny adgangskode:';
+$labels['confpasswd']  = 'Bekræft ny adgangskode:';
+
+$messages = array();
+$messages['nopassword'] = 'Indtast venligst en ny adgangskode.';
+$messages['nocurpassword'] = 'Indtast venligst nyværende adgangskode.';
+$messages['passwordincorrect'] = 'Nyværende adgangskode er forkert.';
+$messages['passwordinconsistency'] = 'Adgangskoderne er ikke ens, prøv igen.';
+$messages['crypterror'] = 'Kunne ikke gemme den nye adgangskode. Krypteringsfunktion mangler.';
+$messages['connecterror'] = 'Kunne ikke gemme den nye adgangskode. Fejl ved forbindelsen.';
+$messages['internalerror'] = 'Kunne ikke gemme den nye adgangskode.';
+
+?>
index 6c64cc04d5597ad24895ed54591c0fe1f21d032a..75fe8618f565a13d2483ef763c5c8cfff215b10b 100644 (file)
@@ -14,5 +14,7 @@ $messages['passwordinconsistency'] = 'Passwords do not match, please try again.'
 $messages['crypterror'] = 'Could not save new password. Encrypt function missing.';
 $messages['connecterror'] = 'Could not save new password. Connection error.';
 $messages['internalerror'] = 'Could not save new password.';
+$messages['passwordshort'] = 'Your password must be at least $length characters long.';
+$messages['passwordweak'] = 'Your new password must include at least one number and one punctuation character.';
 
 ?>
index 4520d7966121580d93855d27f07bdfbc21609d55..774437a282052cd6f2136444dfeaaa665d580b3a 100644 (file)
@@ -14,5 +14,7 @@ $messages['passwordinconsistency'] = 'Hasła nie pasują, spróbuj ponownie.';
 $messages['crypterror'] = 'Nie udało się zapisać nowego hasła. Brak funkcji kodującej.';
 $messages['connecterror'] = 'Nie udało się zapisać nowego hasła. Błąd połączenia.';
 $messages['internalerror'] = 'Nie udało się zapisać nowego hasła.';
+$messages['passwordshort'] = 'Hasło musi posiadać co najmniej $length znaków.';
+$messages['passwordweak'] = 'Hasło musi zawierać co najmniej jedną cyfrę i znak interpunkcyjny.';
 
 ?>
index 80ddf5885e0bbd9a43bd67fdb5ec61c3486018fe..5307ad69fceec87d0bdf755f6235afa0a0e91700 100644 (file)
@@ -1,4 +1,4 @@
-<?php
+<?php
 
 $labels = array();
 $labels['changepasswd']  = 'Alterar password';
@@ -10,7 +10,7 @@ $messages = array();
 $messages['nopassword'] = 'Introduza a nova password.';
 $messages['nocurpassword'] = 'Introduza a password actual.';
 $messages['passwordincorrect'] = 'Password actual errada.';
-$messages['passwordinconsistency'] = 'Password's não combinam, tente novamente..';
+$messages['passwordinconsistency'] = 'Password\'s não combinam, tente novamente..';
 $messages['crypterror'] = 'Não foi possível gravar a nova password. Função de criptografica inexistente.';
 $messages['connecterror'] = 'Não foi possível gravar a nova password. Erro de ligação.';
 $messages['internalerror'] = 'Não foi possível gravar a nova password.';
index c3252f03133a12a59f13a28aa625e76c1c256891..8a079de2d98ffa61a6b86f44410297966c9bc3ee 100644 (file)
@@ -25,7 +25,7 @@ if (window.rcmail) {
       } else if (input_confpasswd && input_confpasswd.value=='') {
           alert(rcmail.gettext('nopassword', 'password'));
           input_confpasswd.focus();
-      } else if ((input_newpasswd && input_confpasswd) && (input_newpasswd.value != input_confpasswd.value)) {
+      } else if (input_newpasswd && input_confpasswd && input_newpasswd.value != input_confpasswd.value) {
           alert(rcmail.gettext('passwordinconsistency', 'password'));
           input_newpasswd.focus();
       } else {
index 0e5e1efff6814e2d9c876b1fd0bad756640c3735..a03d3540abde89da7b07a54c9811b7354e04c5dc 100644 (file)
@@ -79,20 +79,36 @@ class password extends rcube_plugin
     $rcmail->output->set_pagetitle($this->gettext('changepasswd'));
 
     $confirm = $rcmail->config->get('password_confirm_current');
+    $required_length = intval($rcmail->config->get('password_minimum_length'));
+    $check_strength = $rcmail->config->get('password_require_nonalpha');
 
     if (($confirm && !isset($_POST['_curpasswd'])) || !isset($_POST['_newpasswd'])) {
       $rcmail->output->command('display_message', $this->gettext('nopassword'), 'error');
     }
     else {
+
       $curpwd = get_input_value('_curpasswd', RCUBE_INPUT_POST);
       $newpwd = get_input_value('_newpasswd', RCUBE_INPUT_POST);
+      $conpwd = get_input_value('_confpasswd', RCUBE_INPUT_POST);
 
-      if ($confirm && $rcmail->decrypt($_SESSION['password']) != $curpwd)
+      if ($conpwd != $newpwd) {
+        $rcmail->output->command('display_message', $this->gettext('passwordinconsistency'), 'error');
+      }
+      else if ($confirm && $rcmail->decrypt($_SESSION['password']) != $curpwd) {
         $rcmail->output->command('display_message', $this->gettext('passwordincorrect'), 'error');
+      }
+      else if ($required_length && strlen($newpwd) < $required_length) {
+        $rcmail->output->command('display_message', $this->gettext(
+         array('name' => 'passwordshort', 'vars' => array('length' => $required_length))), 'error');
+      }
+      else if ($check_strength && (!preg_match("/[0-9]/", $newpwd) || !preg_match("/[^A-Za-z0-9]/", $newpwd))) {
+        $rcmail->output->command('display_message', $this->gettext('passwordweak'), 'error');
+      }
       else if (!($res = $this->_save($curpwd,$newpwd))) {
         $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
         $_SESSION['password'] = $rcmail->encrypt($newpwd);
-      } else
+      }
+      else
         $rcmail->output->command('display_message', $res, 'error');
     }
 
@@ -142,9 +158,9 @@ class password extends rcube_plugin
     $table->add('title', html::label($field_id, Q($this->gettext('confpasswd'))));
     $table->add(null, $input_confpasswd->show());
 
-    $out = html::div(array('class' => "settingsbox", 'style' => "margin:0"),
-      html::div(array('id' => "prefs-title"), $this->gettext('changepasswd')) .
-      html::div(array('style' => "padding:15px"), $table->show() .
+    $out = html::div(array('class' => 'settingsbox', 'style' => 'margin:0'),
+      html::div(array('id' => 'prefs-title', 'class' => 'boxtitle'), $this->gettext('changepasswd')) .
+      html::div(array('class' => 'boxcontent'), $table->show() .
         html::p(null,
           $rcmail->output->button(array(
             'command' => 'plugin.password-save',
diff --git a/plugins/subscriptions_option/localization/cs_CZ.inc b/plugins/subscriptions_option/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..ca637fc
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/*
+
++-----------------------------------------------------------------------+
+| language/cs_CZ/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube subscriptions option plugin            |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Milan Kozak <hodza@hodza.net>                                 |
++-----------------------------------------------------------------------+
+
+@version $Id: labels.inc 2993 2009-09-26 18:32:07Z alec $
+
+*/
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Používat odebírání IMAP složek';
+
+?>
diff --git a/plugins/subscriptions_option/localization/de_CH.inc b/plugins/subscriptions_option/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..b4affe0
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Nur abonnierte Ordner anzeigen';
+
+?>
diff --git a/plugins/subscriptions_option/localization/de_DE.inc b/plugins/subscriptions_option/localization/de_DE.inc
new file mode 100644 (file)
index 0000000..b4affe0
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Nur abonnierte Ordner anzeigen';
+
+?>
diff --git a/plugins/subscriptions_option/localization/ru_RU.inc b/plugins/subscriptions_option/localization/ru_RU.inc
new file mode 100644 (file)
index 0000000..5deb84e
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Использовать IMAP подписку';
+
+?>
index 09ee6e3df09ccf84522f695241c678d15dd223c9..ecbc4e238aed09ce27211d89c5c5e1309afb625c 100644 (file)
@@ -46,9 +46,9 @@ class subscriptions_option extends rcube_plugin
             $checkbox = new html_checkbox(array('name' => '_use_subscriptions', 'id' => $field_id, 'value' => 1));
 
             $args['blocks']['main']['options']['use_subscriptions'] = array(
-               'title' => html::label($field_id, Q($this->gettext('useimapsubscriptions'))),
+                'title' => html::label($field_id, Q($this->gettext('useimapsubscriptions'))),
                 'content' => $checkbox->show($use_subscriptions?1:0),
-           );
+            );
         }
 
         return $args;
@@ -57,18 +57,18 @@ class subscriptions_option extends rcube_plugin
     function save_prefs($args)
     {
         if ($args['section'] == 'server') {
-           $rcmail = rcmail::get_instance();
+            $rcmail = rcmail::get_instance();
             $use_subscriptions = $rcmail->config->get('use_subscriptions');
 
-           $args['prefs']['use_subscriptions'] = isset($_POST['_use_subscriptions']) ? true : false;
+            $args['prefs']['use_subscriptions'] = isset($_POST['_use_subscriptions']) ? true : false;
 
-           // if the use_subscriptions preference changes, flush the folder cache
-           if (($use_subscriptions && !isset($_POST['_use_subscriptions'])) ||
-               (!$use_subscriptions && isset($_POST['_use_subscriptions']))) {
-                   $rcmail->imap_init(true);
-                   $rcmail->imap->clear_cache('mailboxes');
-           }
-       }
+            // if the use_subscriptions preference changes, flush the folder cache
+            if (($use_subscriptions && !isset($_POST['_use_subscriptions'])) ||
+                (!$use_subscriptions && isset($_POST['_use_subscriptions']))) {
+                    $rcmail->imap_init(true);
+                    $rcmail->imap->clear_cache('mailboxes');
+            }
+        }
         return $args;
     }
 
diff --git a/plugins/userinfo/localization/cs_CZ.inc b/plugins/userinfo/localization/cs_CZ.inc
new file mode 100644 (file)
index 0000000..812ca7b
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+/*
+
++-----------------------------------------------------------------------+
+| language/cs_CZ/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube userinfo plugin                        |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Milan Kozak <hodza@hodza.net>                                 |
++-----------------------------------------------------------------------+
+
+@version $Id: labels.inc 2993 2009-09-26 18:32:07Z alec $
+
+*/
+
+$labels = array();
+$labels['infosfor'] = 'Informace pro';
+$labels['userinfo'] = 'Uživatel';
+$labels['created'] = 'Vytvořen';
+$labels['lastlogin'] = 'Naspoledy přihlášen';
+$labels['defaultidentity'] = 'Výchozí identita';
+
+?>
\ No newline at end of file
index e36d67858c4695aace7f1a8a848c6b9e97fcad8f..45009f9f4a42191c46949b75e11b9e17a81d553c 100644 (file)
@@ -1,4 +1,4 @@
-<?php
+<?php
 
 $labels = array();
 $labels['userinfo'] = 'Informação do utilizador';
diff --git a/plugins/vcard_attachments/localization/de_CH.inc b/plugins/vcard_attachments/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..dcc8ce7
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['addvardmsg'] = 'Kontakt im Adressbuch speichern';
+$labels['vcardsavefailed'] = 'Der Kontakt konnte nicht gespeichert werden';
+
+?>
\ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/de_DE.inc b/plugins/vcard_attachments/localization/de_DE.inc
new file mode 100644 (file)
index 0000000..dcc8ce7
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['addvardmsg'] = 'Kontakt im Adressbuch speichern';
+$labels['vcardsavefailed'] = 'Der Kontakt konnte nicht gespeichert werden';
+
+?>
\ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/en_US.inc b/plugins/vcard_attachments/localization/en_US.inc
new file mode 100644 (file)
index 0000000..59a36e9
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['addvardmsg'] = 'Add vCard to addressbook';
+$labels['vcardsavefailed'] = 'Unable to save vCard';
+
+?>
\ No newline at end of file
diff --git a/plugins/vcard_attachments/localization/ru_RU.inc b/plugins/vcard_attachments/localization/ru_RU.inc
new file mode 100644 (file)
index 0000000..e127b58
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['addvardmsg'] = 'Добавить в контакты';
+$labels['vcardsavefailed'] = 'Не удалось сохранить vCard';
+
+?>
\ No newline at end of file
index 532311e55b8a772da029fbb2840b7dfc446ed839..d23cf37b1ef61460c7e2ca2d8f87fa7846a70a10 100644 (file)
@@ -35,6 +35,9 @@ class vcard_attachments extends rcube_plugin
       if (in_array($attachment->mimetype, array('text/vcard', 'text/x-vcard')))
         $this->vcard_part = $attachment->mime_id;
     }
+
+    if ($this->vcard_part)
+      $this->add_texts('localization');
   }
   
   /**
@@ -57,7 +60,7 @@ class vcard_attachments extends rcube_plugin
           html::a(array(
               'href' => "#",
               'onclick' => "return plugin_vcard_save_contact('".JQ($this->vcard_part)."')",
-              'title' => "Save contact in local address book"),  // TODO: localize this title
+              'title' => $this->gettext('addvardmsg')),
             html::img(array('src' => $this->url('vcard_add_contact.png'), 'align' => "middle")))
             . ' ' . html::span(null, Q($display)));
         
@@ -73,6 +76,8 @@ class vcard_attachments extends rcube_plugin
    */
   function save_vcard()
   {
+         $this->add_texts('localization', true);
+
     $uid = get_input_value('_uid', RCUBE_INPUT_POST);
     $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
     $mime_id = get_input_value('_part', RCUBE_INPUT_POST);
@@ -80,7 +85,7 @@ class vcard_attachments extends rcube_plugin
     $rcmail = rcmail::get_instance();
     $part = $uid && $mime_id ? $rcmail->imap->get_message_part($uid, $mime_id) : null;
     
-    $error_msg = 'Failed to saved vcard'; // TODO: localize this text
+    $error_msg = $this->gettext('vcardsavefailed');
     
     if ($part && ($vcard = new rcube_vcard($part)) && $vcard->displayname && $vcard->email) {
       $contacts = $rcmail->get_address_book(null, true);
@@ -111,5 +116,4 @@ class vcard_attachments extends rcube_plugin
     
     $rcmail->output->send();
   }
-  
-}
\ No newline at end of file
+}
index 5d836860bb0add2587bde62248c5e7932b5cb582..df2f3f310445c0e3984a41bf6497293abd48ac92 100755 (executable)
  |         Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: iniset.php 2916 2009-09-04 10:58:29Z thomasb $
+ $Id: iniset.php 3081 2009-10-31 13:20:02Z thomasb $
 
 */
 
 
 // application constants
-define('RCMAIL_VERSION', '0.3-stable');
+define('RCMAIL_VERSION', '0.3.1');
 define('RCMAIL_CHARSET', 'UTF-8');
 define('JS_OBJECT_NAME', 'rcmail');
 
@@ -59,15 +59,10 @@ if  (isset($_SERVER['HTTPS'])) {
 ini_set('session.name', 'roundcube_sessid');
 ini_set('session.use_cookies', 1);
 ini_set('session.use_only_cookies', 1);
-if (function_exists('set_magic_quotes_runtime')) {
-  set_magic_quotes_runtime(0);
-}
 
 // increase maximum execution time for php scripts
 // (does not work in safe mode)
-if (!ini_get('safe_mode')) {
-  set_time_limit(120);
-}
+@set_time_limit(120);
 
 // set internal encoding for mbstring extension
 if(extension_loaded('mbstring'))
index f25f4cbd755f45b6f285c7255e9287db6baaeb82..423b46e1b7670d51e8177a466dd1c9a2c33a28f5 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: main.inc 2852 2009-08-10 21:32:44Z thomasb $
+ $Id: main.inc 3063 2009-10-27 09:43:39Z alec $
 
 */
 
@@ -942,7 +942,7 @@ function format_date($date, $format=NULL)
 
 
 /**
- * Compose a valid representaion of name and e-mail address
+ * Compose a valid representation of name and e-mail address
  *
  * @param string E-mail address
  * @param string Person name
@@ -953,10 +953,10 @@ function format_email_recipient($email, $name='')
   if ($name && $name != $email)
     {
     // Special chars as defined by RFC 822 need to in quoted string (or escaped).
-    return sprintf('%s <%s>', preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name) ? '"'.addcslashes($name, '"').'"' : $name, $email);
+    return sprintf('%s <%s>', preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name) ? '"'.addcslashes($name, '"').'"' : $name, trim($email));
     }
   else
-    return $email;
+    return trim($email);
   }
 
 
@@ -1022,7 +1022,7 @@ function write_log($name, $line)
     $line = $log['line'];
     $date = $log['date'];
     if ($log['abort'])
-      return;
+      return true;
   }
  
   $log_entry = sprintf("[%s]: %s\n", $date, $line);
@@ -1038,12 +1038,15 @@ function write_log($name, $line)
       $CONFIG['log_dir'] = INSTALL_PATH.'logs';
 
     // try to open specific log file for writing
-    if ($fp = @fopen($CONFIG['log_dir'].'/'.$name, 'a')) {
+    $logfile = $CONFIG['log_dir'].'/'.$name;
+    if ($fp = @fopen($logfile, 'a')) {
       fwrite($fp, $log_entry);
       fflush($fp);
       fclose($fp);
       return true;
     }
+    else
+      trigger_error("Error writing to log file $logfile; Please check permissions", E_USER_WARNING);
   }
   return false;
 }
@@ -1148,11 +1151,12 @@ function rcmail_mailbox_select($p = array())
 {
   global $RCMAIL;
   
-  $p += array('maxlength' => 100, 'relanames' => false);
+  $p += array('maxlength' => 100, 'realnames' => false);
   $a_mailboxes = array();
   
   foreach ($RCMAIL->imap->list_mailboxes() as $folder)
-    rcmail_build_folder_tree($a_mailboxes, $folder, $RCMAIL->imap->get_hierarchy_delimiter());
+    if (empty($p['exceptions']) || !in_array($folder, $p['exceptions']))
+      rcmail_build_folder_tree($a_mailboxes, $folder, $RCMAIL->imap->get_hierarchy_delimiter());
 
   $select = new html_select($p);
   
@@ -1374,18 +1378,96 @@ function rcmail_localize_foldername($name)
  */
 function rcube_html_editor($mode='')
 {
-  global $OUTPUT, $CONFIG;
+  global $RCMAIL, $CONFIG;
+
+  $hook = $RCMAIL->plugins->exec_hook('hmtl_editor', array('mode' => $mode));
+
+  if ($hook['abort'])
+    return;  
 
-  $lang = $tinylang = strtolower(substr($_SESSION['language'], 0, 2));
-  if (!file_exists(INSTALL_PATH . 'program/js/tiny_mce/langs/'.$tinylang.'.js'))
-    $tinylang = 'en';
+  $lang = strtolower(substr($_SESSION['language'], 0, 2));
+  if (!file_exists(INSTALL_PATH . 'program/js/tiny_mce/langs/'.$lang.'.js'))
+    $lang = 'en';
 
-  $OUTPUT->include_script('tiny_mce/tiny_mce.js');
-  $OUTPUT->include_script('editor.js');
-  $OUTPUT->add_script('rcmail_editor_init("$__skin_path", "'.JQ($tinylang).'", '.intval($CONFIG['enable_spellcheck']).', "'.$mode.'");');
+  $RCMAIL->output->include_script('tiny_mce/tiny_mce.js');
+  $RCMAIL->output->include_script('editor.js');
+  $RCMAIL->output->add_script('rcmail_editor_init("$__skin_path",
+    "'.JQ($lang).'", '.intval($CONFIG['enable_spellcheck']).', "'.$mode.'");');
+}
+
+
+/**
+ * Check if working in SSL mode
+ *
+ * @param integer HTTPS port number
+ * @param boolean Enables 'use_https' option checking
+ */
+function rcube_https_check($port=null, $use_https=true)
+{
+  global $RCMAIL;
+  
+  if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')
+    return true;
+  if ($port && $_SERVER['SERVER_PORT'] == $port)
+    return true;
+  if ($use_https && $RCMAIL->config->get('use_https'))
+    return true;
+
+  return false;
 }
 
 
+/**
+ * E-mail address validation
+ */
+function check_email($email)
+{
+  // Check for invalid characters
+  if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $email))
+    return false;
+
+  // Check that there's one @ symbol, and that the lengths are right
+  if (!preg_match('/^([^@]{1,64})@([^@]{1,255})$/', $email, $email_array))
+    return false;
+
+  // Check local part
+  $local_array = explode('.', $email_array[1]);
+  foreach ($local_array as $local_part)
+    if (!preg_match('/^(([A-Za-z0-9!#$%&\'*+\/=?^_`{|}~-]+)|("[^"]+"))$/', $local_part))
+      return false;
+
+  // Check domain part
+  if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/', $email_array[2]) 
+      || preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/', $email_array[2]))
+    return true; // If an IP address
+  else {
+    // If not an IP address
+    $domain_array = explode('.', $email_array[2]);
+    if (sizeof($domain_array) < 2)
+      return false; // Not enough parts to be a valid domain
+
+    foreach ($domain_array as $domain_part)
+      if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $domain_part))
+        return false;
+
+    if (!rcmail::get_instance()->config->get('email_dns_check'))
+      return true;
+
+    if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && version_compare(PHP_VERSION, '5.3.0', '<'))
+      return true;
+
+    // find MX record(s)
+    if (getmxrr($email_array[2], $mx_records))
+      return true;
+
+    // find any DNS record
+    if (checkdnsrr($email_array[2], 'ANY'))
+      return true;
+  }
+
+  return false;
+}
+
 
 /**
  * Helper class to turn relative urls into absolute ones
index 4624ee1943ee758dc9af5d19f1d6ff91b6eedb09..763c7088953fb6aba1d9c25193b2f76a1ce20e46 100644 (file)
@@ -266,7 +266,7 @@ class rcmail
       $contacts = $plugin['instance'];
     }
     else if ($id && $ldap_config[$id]) {
-      $contacts = new rcube_ldap($ldap_config[$id]);
+      $contacts = new rcube_ldap($ldap_config[$id], $this->config->get('ldap_debug'), $this->config->mail_domain($_SESSION['imap_host']));
     }
     else if ($id === '0') {
       $contacts = new rcube_contacts($this->db, $this->user->ID);
@@ -275,7 +275,7 @@ class rcmail
       // Use the first writable LDAP address book.
       foreach ($ldap_config as $id => $prop) {
         if (!$writeable || $prop['writable']) {
-          $contacts = new rcube_ldap($prop);
+          $contacts = new rcube_ldap($prop, $this->config->get('ldap_debug'), $this->config->mail_domain($_SESSION['imap_host']));
           break;
         }
       }
@@ -366,6 +366,7 @@ class rcmail
     $this->imap = new rcube_imap($this->db);
     $this->imap->debug_level = $this->config->get('debug_level');
     $this->imap->skip_deleted = $this->config->get('skip_deleted');
+    $this->imap->index_sort = $this->config->get('index_sort', true);
 
     // enable caching of imap data
     if ($this->config->get('enable_caching')) {
@@ -378,7 +379,7 @@ class rcmail
     // Setting root and delimiter before iil_Connect can save time detecting them
     // using NAMESPACE and LIST 
     $options = array(
-      'imap' => $this->config->get('imap_auth_type', 'check'),
+      'auth_method' => $this->config->get('imap_auth_type', 'check'),
       'delimiter' => isset($_SESSION['imap_delimiter']) ? $_SESSION['imap_delimiter'] : $this->config->get('imap_delimiter'),
       'rootdir' => isset($_SESSION['imap_root']) ? $_SESSION['imap_root'] : $this->config->get('imap_root'),
       'debug_mode' => (bool) $this->config->get('imap_debug', 0),
@@ -761,7 +762,7 @@ class rcmail
             continue;
 
           if ($label = $rcube_languages[$name])
-            $sa_languages[$name] = $label ? $label : $name;
+            $sa_languages[$name] = $label;
         }
         closedir($dh);
       }
@@ -879,7 +880,7 @@ class rcmail
     $key = $this->task;
     
     if (!$_SESSION['request_tokens'][$key])
-      $_SESSION['request_tokens'][$key] = md5(uniqid($key . rand(), true));
+      $_SESSION['request_tokens'][$key] = md5(uniqid($key . mt_rand(), true));
     
     return $_SESSION['request_tokens'][$key];
   }
index 4010dbc48f082c4cc9e130f2f8b77c51ee3178e7..9f37aaa0b9c051bb89a475dfcd2ee488c434037c 100644 (file)
@@ -43,24 +43,21 @@ class rcube_browser
         $this->ns  = ($this->ns4 || stristr($HTTP_USER_AGENT, 'netscape'));
         $this->ie  = stristr($HTTP_USER_AGENT, 'compatible; msie') && !$this->opera;
         $this->mz  = stristr($HTTP_USER_AGENT, 'mozilla/5');
+        $this->chrome = stristr($HTTP_USER_AGENT, 'chrome');
         $this->khtml = stristr($HTTP_USER_AGENT, 'khtml');
         $this->safari = ($this->khtml || stristr($HTTP_USER_AGENT, 'safari'));
 
-        if ($this->ns) {
-            $test = preg_match('/mozilla\/([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
-            $this->ver = $test ? (float)$regs[1] : 0;
+        if ($this->ns || $this->chrome) {
+            $test = preg_match('/(mozilla|chrome)\/([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
+            $this->ver = $test ? (float)$regs[2] : 0;
         }
-        if ($this->mz) {
+        else if ($this->mz) {
             $test = preg_match('/rv:([0-9.]+)/', $HTTP_USER_AGENT, $regs);
             $this->ver = $test ? (float)$regs[1] : 0;
         }
-        if($this->ie) {
-            $test = preg_match('/msie ([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
-            $this->ver = $test ? (float)$regs[1] : 0;
-        }
-        if ($this->opera) {
-            $test = preg_match('/opera ([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
-            $this->ver = $test ? (float)$regs[1] : 0;
+        else if ($this->ie || $this->opera) {
+            $test = preg_match('/(msie|opera) ([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
+            $this->ver = $test ? (float)$regs[2] : 0;
         }
 
         if (preg_match('/ ([a-z]{2})-([a-z]{2})/i', $HTTP_USER_AGENT, $regs))
index bc6d40a0614e06d8b67e62cae6062896c69b8d2f..2a64c5d295d28f86d3290a4e7891895a72090d7d 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_imap.php 2884 2009-08-28 08:31:41Z alec $
+ $Id: rcube_imap.php 3048 2009-10-19 07:47:10Z alec $
 
 */
 
@@ -50,6 +50,7 @@ class rcube_imap
   var $page_size = 10;
   var $sort_field = 'date';
   var $sort_order = 'DESC';
+  var $index_sort = true;
   var $delimiter = NULL;
   var $caching_enabled = FALSE;
   var $default_charset = 'ISO-8859-1';
@@ -69,7 +70,7 @@ class rcube_imap
   var $search_sort_field = '';  
   var $debug_level = 1;
   var $error_code = 0;
-  var $options = array('imap' => 'check');
+  var $options = array('auth_method' => 'check');
   
   private $host, $user, $pass, $port, $ssl;
 
@@ -111,7 +112,7 @@ class rcube_imap
 
     $ICL_PORT = $port;
     $IMAP_USE_INTERNAL_DATE = false;
-    
+
     $attempt = 0;
     do {
       $data = rcmail::get_instance()->plugins->exec_hook('imap_connect', array('host' => $host, 'user' => $user, 'attempt' => ++$attempt));
@@ -143,13 +144,13 @@ class rcube_imap
     // get server properties
     if ($this->conn)
       {
-      if (!empty($this->conn->delimiter))
-        $this->delimiter = $this->conn->delimiter;
       if (!empty($this->conn->rootdir))
         {
         $this->set_rootdir($this->conn->rootdir);
         $this->root_ns = preg_replace('/[.\/]$/', '', $this->conn->rootdir);
         }
+      if (empty($this->delimiter))
+       $this->get_hierarchy_delimiter();
       }
 
     return $this->conn ? TRUE : FALSE;
@@ -484,7 +485,6 @@ class rcube_imap
    */
   private function _messagecount($mailbox='', $mode='ALL', $force=FALSE)
     {
-    $a_mailbox_cache = FALSE;
     $mode = strtoupper($mode);
 
     if (empty($mailbox))
@@ -598,7 +598,31 @@ class rcube_imap
     // retrieve headers from IMAP
     $a_msg_headers = array();
 
-    if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
+    // use message index sort for sorting by Date (for better performance)
+    if ($this->index_sort && $this->sort_field == 'date')
+      {
+        if ($this->skip_deleted) {
+          // @TODO: this could be cached
+         if ($msg_index = $this->_search_index($mailbox, 'ALL UNDELETED')) {
+            $max = max($msg_index);
+            list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
+            $msg_index = array_slice($msg_index, $begin, $end-$begin);
+           }
+       } else if ($max = iil_C_CountMessages($this->conn, $mailbox)) {
+          list($begin, $end) = $this->_get_message_range($max, $page);
+         $msg_index = range($begin+1, $end);
+       } else
+         $msg_index = array();
+
+        if ($slice)
+          $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice);
+
+        // fetch reqested headers from server
+       if ($msg_index)
+          $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key);
+      }
+    // use SORT command
+    else if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
       {
       list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
       $max = max($msg_index);
@@ -610,13 +634,9 @@ class rcube_imap
       // fetch reqested headers from server
       $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key);
       }
-    else
+    // fetch specified header for all messages and sort
+    else if ($a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted))
       {
-      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted);
-    
-      if (empty($a_index))
-        return array();
-
       asort($a_index); // ASC
       $msg_index = array_keys($a_index);
       $max = max($msg_index);
@@ -677,14 +697,34 @@ class rcube_imap
 
     $this->_set_sort_order($sort_field, $sort_order);
 
+    // quickest method
+    if ($this->index_sort && $this->search_sort_field == 'date' && $this->sort_field == 'date')
+      {
+      if ($sort_order == 'DESC')
+        $msgs = array_reverse($msgs);
+
+      // get messages uids for one page
+      $msgs = array_slice(array_values($msgs), $start_msg, min(count($msgs)-$start_msg, $this->page_size));
+
+      if ($slice)
+        $msgs = array_slice($msgs, -$slice, $slice);
+
+      // fetch headers
+      $this->_fetch_headers($mailbox, join(',',$msgs), $a_msg_headers, NULL);
+
+      // I didn't found in RFC that FETCH always returns messages sorted by index
+      $sorter = new rcube_header_sorter();
+      $sorter->set_sequence_numbers($msgs);
+      $sorter->sort_headers($a_msg_headers);
+
+      return array_values($a_msg_headers);
+      }
     // sorted messages, so we can first slice array and then fetch only wanted headers
-    if ($this->get_capability('sort')) // SORT searching result
+    if ($this->get_capability('sort') && (!$this->index_sort || $this->sort_field != 'date')) // SORT searching result
       {
       // reset search set if sorting field has been changed
       if ($this->sort_field && $this->search_sort_field != $this->sort_field)
-        {
         $msgs = $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
-        }
 
       // return empty array if no messages found
       if (empty($msgs))
@@ -710,7 +750,8 @@ class rcube_imap
       }
     else { // SEARCH searching result, need sorting
       $cnt = count($msgs);
-      if ($cnt > 300 && $cnt > $this->page_size) { // experimantal value for best result
+      // 300: experimantal value for best result
+      if (($cnt > 300 && $cnt > $this->page_size) || ($this->index_sort && $this->sort_field == 'date')) {
         // use memory less expensive (and quick) method for big result set
        $a_index = $this->message_index('', $this->sort_field, $this->sort_order);
         // get messages uids for one page...
@@ -808,23 +849,18 @@ class rcube_imap
       {
       // cache is incomplete
       $cache_index = $this->get_message_cache_index($cache_key);
-    
-      foreach ($a_header_index as $i => $headers)
-        { 
-/*
-        if ($headers->deleted && $this->skip_deleted)
-          {
-          // delete from cache
-          if ($cache_index[$headers->id] && $cache_index[$headers->id] == $headers->uid)
-            $this->remove_message_cache($cache_key, $headers->uid);
 
-          continue;
-          }
-*/
-        // add message to cache
-        if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid)
-          $this->add_message_cache($cache_key, $headers->id, $headers, NULL,
-               !in_array((string)$headers->uid, $cache_index, true));
+      foreach ($a_header_index as $i => $headers) {
+        if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid) {
+         // prevent index duplicates
+         if ($cache_index[$headers->id]) {
+           $this->remove_message_cache($cache_key, $headers->id, true);
+           unset($cache_index[$headers->id]);
+           }
+          // add message to cache
+         $this->add_message_cache($cache_key, $headers->id, $headers, NULL,
+           !in_array($headers->uid, $cache_index));
+         }
 
         $a_msg_headers[$headers->uid] = $headers;
         }
@@ -849,12 +885,26 @@ class rcube_imap
     $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
     $key = "{$mailbox}:{$this->sort_field}:{$this->sort_order}:{$this->search_string}.msgi";
 
-    // we have a saved search result. get index from there
+    // we have a saved search result, get index from there
     if (!isset($this->cache[$key]) && $this->search_string && $mailbox == $this->mailbox)
     {
       $this->cache[$key] = array();
       
-      if ($this->get_capability('sort'))
+      // use message index sort for sorting by Date
+      if ($this->index_sort && $this->sort_field == 'date')
+        {
+       $msgs = $this->search_set;
+       
+       if ($this->search_sort_field != 'date')
+         sort($msgs);
+       
+        if ($this->sort_order == 'DESC')
+          $this->cache[$key] = array_reverse($msgs);
+        else
+          $this->cache[$key] = $msgs;
+        }
+      // sort with SORT command
+      else if ($this->get_capability('sort'))
         {
         if ($this->sort_field && $this->search_sort_field != $this->sort_field)
           $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
@@ -892,8 +942,22 @@ class rcube_imap
       return array_keys($a_index);
       }
 
+    // use message index sort for sorting by Date
+    if ($this->index_sort && $this->sort_field == 'date')
+      {
+      if ($this->skip_deleted) {
+        $a_index = $this->_search_index($mailbox, 'ALL');
+      } else if ($max = $this->_messagecount($mailbox)) {
+        $a_index = range(1, $max);
+      }
+
+      if ($this->sort_order == 'DESC')
+        $a_index = array_reverse($a_index);
+
+      $this->cache[$key] = $a_index;
+      }
     // fetch complete message index
-    if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
+    else if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
       {
       if ($this->sort_order == 'DESC')
         $a_index = array_reverse($a_index);
@@ -967,7 +1031,7 @@ class rcube_imap
       if ($headers = iil_C_FetchHeader($this->conn, $mailbox, join(',', $for_update), false, $this->fetch_add_headers))
         foreach ($headers as $header)
           $this->add_message_cache($cache_key, $header->id, $header, NULL,
-               in_array((string)$header->uid, (array)$for_remove, true));
+               in_array($header->uid, (array)$for_remove));
       }
     }
 
@@ -1037,14 +1101,23 @@ class rcube_imap
     if ($this->skip_deleted && !preg_match('/UNDELETED/', $criteria))
       $criteria = 'UNDELETED '.$criteria;
 
-    if ($sort_field && $this->get_capability('sort'))
-      {
+    if ($sort_field && $this->get_capability('sort') && (!$this->index_sort || $sort_field != 'date')) {
       $charset = $charset ? $charset : $this->default_charset;
       $a_messages = iil_C_Sort($this->conn, $mailbox, $sort_field, $criteria, FALSE, $charset);
       }
-    else
-      $a_messages = iil_C_Search($this->conn, $mailbox, ($charset ? "CHARSET $charset " : '') . $criteria);
+    else {
+      if ($orig_criteria == 'ALL') {
+        $max = $this->_messagecount($mailbox);
+        $a_messages = $max ? range(1, $max) : array();
+        }
+      else {
+        $a_messages = iil_C_Search($this->conn, $mailbox, ($charset ? "CHARSET $charset " : '') . $criteria);
     
+        // I didn't found that SEARCH always returns sorted IDs
+        if ($this->index_sort && $this->sort_field == 'date')
+          sort($a_messages);
+        }
+      }
     // update messagecount cache ?
 //    $a_mailbox_cache = get_cache('messagecount');
 //    $a_mailbox_cache[$mailbox][$criteria] = sizeof($a_messages);
@@ -1150,6 +1223,16 @@ class rcube_imap
       else
         $this->struct_charset = $this->_structure_charset($structure);
 
+      // Here we can recognize malformed BODYSTRUCTURE and 
+      // 1. [@TODO] parse the message in other way to create our own message structure
+      // 2. or just show the raw message body.
+      // Example of structure for malformed MIME message:
+      // ("text" "plain" ("charset" "us-ascii") NIL NIL "7bit" 2154 70 NIL NIL NIL)
+      if ($headers->ctype && $headers->ctype != 'text/plain'
+         && $structure[0] == 'text' && $structure[1] == 'plain') {
+       return false;  
+       }
+
       $struct = &$this->_structure_part($structure);
       $struct->headers = get_object_vars($headers);
 
@@ -1467,7 +1550,7 @@ class rcube_imap
     // convert charset (if text or message part)
     if ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message') {
       // assume default if no charset specified
-      if (empty($o_part->charset))
+      if (empty($o_part->charset) || strtolower($o_part->charset) == 'us-ascii')
         $o_part->charset = $this->default_charset;
 
       $body = rcube_charset_convert($body, $o_part->charset);
@@ -1533,9 +1616,10 @@ class rcube_imap
    * @param mixed  Message UIDs as array or as comma-separated string
    * @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
    * @param string Folder name
+   * @param boolean True to skip message cache clean up
    * @return boolean True on success, False on failure
    */
-  function set_flag($uids, $flag, $mbox_name=NULL)
+  function set_flag($uids, $flag, $mbox_name=NULL, $skip_cache=false)
     {
     $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
 
@@ -1549,14 +1633,9 @@ class rcube_imap
       $result = iil_C_Flag($this->conn, $mailbox, join(',', $uids), $flag);
 
     // reload message headers if cached
-    if ($this->caching_enabled)
-      {
+    if ($this->caching_enabled && !$skip_cache) {
       $cache_key = $mailbox.'.msg';
       $this->remove_message_cache($cache_key, $uids);
-
-      // close and re-open connection
-      // this prevents connection problems with Courier 
-      $this->reconnect();
       }
 
     // set nr of messages that were flaged
@@ -1624,6 +1703,8 @@ class rcube_imap
    */
   function move_message($uids, $to_mbox, $from_mbox='')
     {
+    $fbox = $from_mbox;
+    $tbox = $to_mbox;
     $to_mbox = $this->mod_mailbox($to_mbox);
     $from_mbox = $from_mbox ? $this->mod_mailbox($from_mbox) : $this->mailbox;
 
@@ -1638,11 +1719,19 @@ class rcube_imap
 
     // convert the list of uids to array
     $a_uids = is_string($uids) ? explode(',', $uids) : (is_array($uids) ? $uids : NULL);
-    
+
     // exit if no message uids are specified
     if (!is_array($a_uids) || empty($a_uids))
       return false;
 
+    // flag messages as read before moving them
+    $config = rcmail::get_instance()->config;
+    if ($config->get('read_when_deleted') && $tbox == $config->get('trash_mbox')) {
+      // don't flush cache (4th argument)
+      $this->set_flag($uids, 'SEEN', $fbox, true);
+      }
+
+    // move messages
     $iil_move = iil_C_Move($this->conn, join(',', $a_uids), $from_mbox, $to_mbox);
     $moved = !($iil_move === false || $iil_move < 0);
     
@@ -1657,13 +1746,14 @@ class rcube_imap
     else if (rcmail::get_instance()->config->get('delete_always', false)) {
       return iil_C_Delete($this->conn, $from_mbox, join(',', $a_uids));
     }
-      
+
     // remove message ids from search set
     if ($moved && $this->search_set && $from_mbox == $this->mailbox) {
       foreach ($a_uids as $uid)
         $a_mids[] = $this->_uid2id($uid, $from_mbox);
       $this->search_set = array_diff($this->search_set, $a_mids);
     }
+
     // update cached message headers
     $cache_key = $from_mbox.'.msg';
     if ($moved && $start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) {
@@ -1694,7 +1784,7 @@ class rcube_imap
       return false;
 
     $deleted = iil_C_Delete($this->conn, $mailbox, join(',', $a_uids));
-    
+
     // send expunge command in order to have the deleted message
     // really deleted from the mailbox
     if ($deleted)
@@ -1710,7 +1800,7 @@ class rcube_imap
         $a_mids[] = $this->_uid2id($uid, $mailbox);
       $this->search_set = array_diff($this->search_set, $a_mids);
     }
-    
+
     // remove deleted messages from cache
     $cache_key = $mailbox.'.msg';
     if ($deleted && $start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) {
@@ -2057,8 +2147,8 @@ class rcube_imap
    */
   function get_cache($key)
     {
-    // read cache
-    if (!isset($this->cache[$key]) && $this->caching_enabled)
+    // read cache (if it was not read before)
+    if (!count($this->cache) && $this->caching_enabled)
       {
       return $this->_read_cache_record($key);
       }
@@ -2135,7 +2225,8 @@ class rcube_imap
         {
        $sql_key = preg_replace('/^IMAP\./', '', $sql_arr['cache_key']);
         $this->cache_keys[$sql_key] = $sql_arr['cache_id'];
-       $this->cache[$sql_key] = $sql_arr['data'] ? unserialize($sql_arr['data']) : FALSE;
+       if (!isset($this->cache[$sql_key]))
+         $this->cache[$sql_key] = $sql_arr['data'] ? unserialize($sql_arr['data']) : FALSE;
         }
       }
 
@@ -2150,23 +2241,6 @@ class rcube_imap
     if (!$this->db)
       return FALSE;
 
-    // check if we already have a cache entry for this key
-    if (!isset($this->cache_keys[$key]))
-      {
-      $sql_result = $this->db->query(
-        "SELECT cache_id
-         FROM ".get_table_name('cache')."
-         WHERE  user_id=?
-         AND    cache_key=?",
-        $_SESSION['user_id'],
-        'IMAP.'.$key);
-                                     
-      if ($sql_arr = $this->db->fetch_assoc($sql_result))
-        $this->cache_keys[$key] = $sql_arr['cache_id'];
-      else
-        $this->cache_keys[$key] = FALSE;
-      }
-
     // update existing cache record
     if ($this->cache_keys[$key])
       {
@@ -2189,6 +2263,18 @@ class rcube_imap
         $_SESSION['user_id'],
         'IMAP.'.$key,
         $data);
+
+      // get cache entry ID for this key
+      $sql_result = $this->db->query(
+        "SELECT cache_id
+         FROM ".get_table_name('cache')."
+         WHERE  user_id=?
+         AND    cache_key=?",
+        $_SESSION['user_id'],
+        'IMAP.'.$key);
+                                     
+        if ($sql_arr = $this->db->fetch_assoc($sql_result))
+          $this->cache_keys[$key] = $sql_arr['cache_id'];
       }
     }
 
@@ -2203,6 +2289,8 @@ class rcube_imap
        AND    cache_key=?",
       $_SESSION['user_id'],
       'IMAP.'.$key);
+      
+    unset($this->cache_keys[$key]);
     }
 
 
@@ -2217,18 +2305,26 @@ class rcube_imap
    *
    * @param string Mailbox name
    * @param string Internal cache key
-   * @return int -3 = off, -2 = incomplete, -1 = dirty
+   * @return int   Cache status: -3 = off, -2 = incomplete, -1 = dirty
    */
   private function check_cache_status($mailbox, $cache_key)
   {
     if (!$this->caching_enabled)
       return -3;
 
-    $cache_index = $this->get_message_cache_index($cache_key, TRUE);
+    $cache_index = $this->get_message_cache_index($cache_key);
     $msg_count = $this->_messagecount($mailbox);
     $cache_count = count($cache_index);
 
-    // console("Cache check: $msg_count !== ".count($cache_index));
+    // empty mailbox
+    if (!$msg_count)
+      return $cache_count ? -2 : 1;
+
+    // @TODO: We've got one big performance problem in cache status checking method
+    // E.g. mailbox contains 1000 messages, in cache table we've got first 100
+    // of them. Now if we want to display only that 100 (which we've got)
+    // check_cache_status returns 'incomplete' and messages are fetched
+    // from IMAP instead of DB.
 
     if ($cache_count==$msg_count) {
       if ($this->skip_deleted) {
@@ -2244,12 +2340,12 @@ class rcube_imap
        }
        return -2;
       } else {
-        // get highest index
-        $header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count");
+        // get UID of message with highest index
+        $uid = iil_C_ID2UID($this->conn, $mailbox, $msg_count);
         $cache_uid = array_pop($cache_index);
       
         // uids of highest message matches -> cache seems OK
-        if ($cache_uid == $header->uid)
+        if ($cache_uid == $uid)
           return 1;
       }
       // cache is dirty
@@ -2270,8 +2366,13 @@ class rcube_imap
     $cache_key = "$key:$from:$to:$sort_field:$sort_order";
     $db_header_fields = array('idx', 'uid', 'subject', 'from', 'to', 'cc', 'date', 'size');
     
-    if (!in_array($sort_field, $db_header_fields))
+    $config = rcmail::get_instance()->config;
+
+    // use idx sort for sorting by Date with index_sort=true or for unknown field
+    if (($sort_field == 'date' && $this->index_sort)
+      || !in_array($sort_field, $db_header_fields)) {
       $sort_field = 'idx';
+      }
     
     if ($this->caching_enabled && !isset($this->cache[$cache_key]))
       {
@@ -2345,6 +2446,10 @@ class rcube_imap
     
     if (!empty($sa_message_index[$key]) && !$force)
       return $sa_message_index[$key];
+
+    // use idx sort for sorting by Date with index_sort=true
+    if ($sort_field == 'date' && $this->index_sort)
+      $sort_field = 'idx';
     
     $sa_message_index[$key] = array();
     $sql_result = $this->db->query(
@@ -2385,8 +2490,7 @@ class rcube_imap
          FROM ".get_table_name('messages')."
          WHERE  user_id=?
          AND    cache_key=?
-         AND    uid=?
-         AND    del<>1",
+         AND    uid=?",
         $_SESSION['user_id'],
         $key,
         $headers->uid);
@@ -2431,16 +2535,16 @@ class rcube_imap
   /**
    * @access private
    */
-  private function remove_message_cache($key, $uids)
+  private function remove_message_cache($key, $ids, $idx=false)
     {
     if (!$this->caching_enabled)
       return;
     
     $this->db->query(
       "DELETE FROM ".get_table_name('messages')."
-      WHERE  user_id=?
-      AND    cache_key=?
-      AND    uid IN (".$this->db->array2list($uids, 'integer').")",
+      WHERE user_id=?
+      AND cache_key=?
+      AND ".($idx ? "idx" : "uid")." IN (".$this->db->array2list($ids, 'integer').")",
       $_SESSION['user_id'],
       $key);
     }
@@ -2455,12 +2559,10 @@ class rcube_imap
     
     $this->db->query(
       "DELETE FROM ".get_table_name('messages')."
-       WHERE  user_id=?
-       AND    cache_key=?
-       AND    idx>=?",
-      $_SESSION['user_id'],
-      $key,
-      $start_index);
+       WHERE user_id=?
+       AND cache_key=?
+       AND idx>=?",
+      $_SESSION['user_id'], $key, $start_index);
     }
 
   /**
index e071ed03384844e71ab8cc4f08e897097669319f..a8e35a33ee3479dd59f42d22a27f24515cc96b47 100644 (file)
@@ -14,7 +14,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_ldap.php 2894 2009-08-29 20:56:00Z alec $
+ $Id: rcube_ldap.php 2976 2009-09-21 11:50:53Z alec $
 
 */
 
@@ -34,6 +34,8 @@ class rcube_ldap extends rcube_addressbook
   var $result = null;
   var $ldap_result = null;
   var $sort_col = '';
+  var $mail_domain = '';
+  var $debug = false;
   
   /** public properties */
   var $primary_key = 'ID';
@@ -46,10 +48,12 @@ class rcube_ldap extends rcube_addressbook
   /**
    * Object constructor
    *
-   * @param array LDAP connection properties
+   * @param array      LDAP connection properties
+   * @param boolean    Enables debug mode
+   * @param string     Current user mail domain name
    * @param integer User-ID
    */
-  function __construct($p)
+  function __construct($p, $debug=false, $mail_domain=NULL)
   {
     $this->prop = $p;
 
@@ -57,10 +61,16 @@ class rcube_ldap extends rcube_addressbook
       if (preg_match('/^(.+)_field$/', $prop, $matches))
         $this->fieldmap[$matches[1]] = $this->_attr_name(strtolower($value));
 
+    // make sure 'required_fields' is an array
+    if (!is_array($this->prop['required_fields']))
+      $this->prop['required_fields'] = (array) $this->prop['required_fields'];
+
     foreach ($this->prop['required_fields'] as $key => $val)
       $this->prop['required_fields'][$key] = $this->_attr_name(strtolower($val));
 
     $this->sort_col = $p['sort'];
+    $this->debug = $debug;
+    $this->mail_domain = $mail_domain;
 
     $this->connect();
   }
@@ -87,17 +97,22 @@ class rcube_ldap extends rcube_addressbook
 
     foreach ($this->prop['hosts'] as $host)
     {
+      $this->_debug("C: Connect [$host".($this->prop['port'] ? ':'.$this->prop['port'] : '')."]");
+
       if ($lc = @ldap_connect($host, $this->prop['port']))
       {
         if ($this->prop['use_tls']===true)
           if (!ldap_start_tls($lc))
             continue;
 
+        $this->_debug("S: OK");
+
         ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->prop['ldap_version']);
         $this->prop['host'] = $host;
         $this->conn = $lc;
         break;
       }
+      $this->_debug("S: NOT OK");
     }
     
     if (is_resource($this->conn))
@@ -148,10 +163,15 @@ class rcube_ldap extends rcube_addressbook
       return false;
     }
     
+    $this->_debug("C: Bind [dn: $dn] [pass: $pass]");
+    
     if (@ldap_bind($this->conn, $dn, $pass)) {
+      $this->_debug("S: OK");
       return true;
     }
 
+    $this->_debug("S: ".ldap_error($this->conn));
+
     raise_error(array(
         'code' => ldap_errno($this->conn),
         'type' => 'ldap',
@@ -169,6 +189,7 @@ class rcube_ldap extends rcube_addressbook
   {
     if ($this->conn)
     {
+      $this->_debug("C: Close");
       ldap_unbind($this->conn);
       $this->conn = null;
     }
@@ -384,11 +405,17 @@ class rcube_ldap extends rcube_addressbook
     $res = null;
     if ($this->conn && $dn)
     {
-      $this->ldap_result = ldap_read($this->conn, base64_decode($dn), '(objectclass=*)', array_values($this->fieldmap));
-      $entry = @ldap_first_entry($this->conn, $this->ldap_result);
+      $this->_debug("C: Read [dn: ".base64_decode($dn)."] [(objectclass=*)]");
+    
+      if ($this->ldap_result = @ldap_read($this->conn, base64_decode($dn), '(objectclass=*)', array_values($this->fieldmap)))
+        $entry = ldap_first_entry($this->conn, $this->ldap_result);
+      else
+        $this->_debug("S: ".ldap_error($this->conn));
 
       if ($entry && ($rec = ldap_get_attributes($this->conn, $entry)))
       {
+        $this->_debug("S: OK");
+
         $rec = array_change_key_case($rec, CASE_LOWER);
 
         // Add in the dn for the entry.
@@ -433,11 +460,17 @@ class rcube_ldap extends rcube_addressbook
 
     // Build the new entries DN.
     $dn = $this->prop['LDAP_rdn'].'='.$newentry[$this->prop['LDAP_rdn']].','.$this->prop['base_dn'];
+
+    $this->_debug("C: Add [dn: $dn]: ".print_r($newentry, true));
+
     $res = ldap_add($this->conn, $dn, $newentry);
     if ($res === FALSE) {
+      $this->_debug("S: ".ldap_error($this->conn));
       return false;
     } // end if
 
+    $this->_debug("S: OK");
+
     return base64_encode($dn);
   }
   
@@ -488,8 +521,12 @@ class rcube_ldap extends rcube_addressbook
     // Update the entry as required.
     if (!empty($deletedata)) {
       // Delete the fields.
-      if (!ldap_mod_del($this->conn, $dn, $deletedata))
+      $this->_debug("C: Delete [dn: $dn]: ".print_r($deletedata, true));
+      if (!ldap_mod_del($this->conn, $dn, $deletedata)) {
+        $this->_debug("S: ".ldap_error($this->conn));
         return false;
+      }
+      $this->_debug("S: OK");
     } // end if
 
     if (!empty($replacedata)) {
@@ -503,21 +540,33 @@ class rcube_ldap extends rcube_addressbook
       }
       // Replace the fields.
       if (!empty($replacedata)) {
-        if (!ldap_mod_replace($this->conn, $dn, $replacedata))
+        $this->_debug("C: Replace [dn: $dn]: ".print_r($replacedata, true));
+        if (!ldap_mod_replace($this->conn, $dn, $replacedata)) {
+          $this->_debug("S: ".ldap_error($this->conn));
           return false;
+       }
+        $this->_debug("S: OK");
       } // end if
     } // end if
 
     if (!empty($newdata)) {
       // Add the fields.
-      if (!ldap_mod_add($this->conn, $dn, $newdata))
+      $this->_debug("C: Add [dn: $dn]: ".print_r($newdata, true));
+      if (!ldap_mod_add($this->conn, $dn, $newdata)) {
+        $this->_debug("S: ".ldap_error($this->conn));
         return false;
+      }
+      $this->_debug("S: OK");
     } // end if
 
     // Handle RDN change
     if (!empty($newrdn)) {
-      if (@ldap_rename($this->conn, $dn, $newrdn, NULL, TRUE))
+      $this->_debug("C: Rename [dn: $dn] [dn: $newrdn]");
+      if (@ldap_rename($this->conn, $dn, $newrdn, NULL, TRUE)) {
+        $this->_debug("S: ".ldap_error($this->conn));
         return base64_encode($newdn);
+      }
+      $this->_debug("S: OK");
     }
 
     return true;
@@ -539,14 +588,17 @@ class rcube_ldap extends rcube_addressbook
 
     foreach ($dns as $id) {
       $dn = base64_decode($id);
+      $this->_debug("C: Delete [dn: $dn]");
       // Delete the record.
       $res = ldap_delete($this->conn, $dn);
       if ($res === FALSE) {
+        $this->_debug("S: ".ldap_error($this->conn));
         return false;
       } // end if
+      $this->_debug("S: OK");
     } // end foreach
 
-    return true;
+    return count($dns);
   }
 
 
@@ -561,11 +613,17 @@ class rcube_ldap extends rcube_addressbook
     {
       $filter = $this->filter ? $this->filter : '(objectclass=*)';
       $function = $this->prop['scope'] == 'sub' ? 'ldap_search' : ($this->prop['scope'] == 'base' ? 'ldap_read' : 'ldap_list');
-      $this->ldap_result = $function($this->conn, $this->prop['base_dn'], $filter, array_values($this->fieldmap), 0, 0);
-      return true;
+
+      $this->_debug("C: Search [".$filter."]");
+
+      if ($this->ldap_result = @$function($this->conn, $this->prop['base_dn'], $filter, array_values($this->fieldmap), 0, 0)) {
+        $this->_debug("S: ".ldap_count_entries($this->conn, $this->ldap_result)." record(s)");
+        return true;
+      } else
+        $this->_debug("S: ".ldap_error($this->conn));
     }
-    else
-      return false;
+    
+    return false;
   }
   
   
@@ -584,8 +642,8 @@ class rcube_ldap extends rcube_addressbook
     foreach ($this->fieldmap as $rf => $lf)
     {
       if ($rec[$lf]['count']) {
-        if ($rf == 'email' && !strpos($rec[$lf][0], '@'))
-          $out[$rf] = sprintf('%s@%s', $rec[$lf][0] , $RCMAIL->config->mail_domain($_SESSION['imap_host']));
+        if ($rf == 'email' && $mail_domain && !strpos($rec[$lf][0], '@'))
+          $out[$rf] = sprintf('%s@%s', $rec[$lf][0], $this->mail_domain);
         else
           $out[$rf] = $rec[$lf][0];
       }
@@ -621,6 +679,16 @@ class rcube_ldap extends rcube_addressbook
   }
 
 
+  /**
+   * @access private
+   */
+  private function _debug($str)
+  {
+    if ($this->debug)
+      write_log('ldap', $str);
+  }
+  
+
   /**
    * @static
    */
index 51f8be3ce72d0a1e891b9278d056bceb468a9db4..f8ed4bb0bd3c15c62b3095015e75c428d2529dd4 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Lukas Kahwe Smith <smith@pooteeweet.org>                      |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_mdb2.php 2834 2009-08-04 08:22:41Z alec $
+ $Id: rcube_mdb2.php 2920 2009-09-04 13:07:48Z alec $
 
 */
 
@@ -256,11 +256,11 @@ class rcube_mdb2
       $result = $this->db_handle->setLimit($numrows,$offset);
 
     if (empty($params))
-        $result = $this->db_handle->query($query);
+      $result = $mode=='r' ? $this->db_handle->query($query) : $this->db_handle->exec($query);
     else
       {
       $params = (array)$params;
-      $q = $this->db_handle->prepare($query);
+      $q = $this->db_handle->prepare($query, null, $mode=='w' ? MDB2_PREPARE_MANIP : null);
       if ($this->db_handle->isError($q))
         {
         $this->db_error = TRUE;
index 7c2457e5579b6f6932b833bd7ae753b75e77e1c1..1a22427d03ac89e0167eb3dba79abc8e4f1cf294 100644 (file)
@@ -402,7 +402,7 @@ class rcube_message
             $this->inline_parts[] = $mail_part;
           }
           // is a regular attachment
-          else if (preg_match('!^[a-z]+/[a-z0-9-.]+$!i', $mail_part->mimetype)) {
+          else if (preg_match('!^[a-z]+/[a-z0-9-.+]+$!i', $mail_part->mimetype)) {
             if (!$mail_part->filename)
               $mail_part->filename = 'Part '.$mail_part->mime_id;
             $this->attachments[] = $mail_part;
index 5e37764c4c3a3f6f6df2987babc85884754906f0..ed30e8f175db9ecb36facf1c88b30c63edcbc230 100644 (file)
@@ -231,6 +231,20 @@ abstract class rcube_plugin
     else
       return $fn;
   }
+  
+  /**
+   * Provide path to the currently selected skin folder within the plugin directory
+   * with a fallback to the default skin folder.
+   *
+   * @return string Skin path relative to plugins directory
+   */
+  protected function local_skin_path()
+  {
+      $skin_path = 'skins/'.$this->api->output->config['skin'];
+      if (!is_dir(realpath(slashify($this->home) . $skin_path)))
+        $skin_path = 'skins/default';
+    return $skin_path;
+  }
 
   /**
    * Callback function for array_map
index e99d324e5550847b384f2c393b7b2dda89b1b2ff..04885df4cd87b67278697925ca60d368804877af 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_shared.inc 2789 2009-07-23 12:14:17Z alec $
+ $Id: rcube_shared.inc 3063 2009-10-27 09:43:39Z alec $
 
 */
 
@@ -41,7 +41,7 @@ function send_nocacheing_headers()
   header("Pragma: no-cache");
   
   // We need to set the following headers to make downloads work using IE in HTTPS mode.
-  if (isset($_SERVER['HTTPS'])) {
+  if (rcube_https_check()) {
     header('Pragma: ');
     header('Cache-Control: ');
   }
@@ -554,7 +554,6 @@ function rc_mime_content_type($path, $name, $failover = 'application/octet-strea
     return $mime_type;
 }
 
-
 /**
  * A method to guess encoding of a string.
  *
@@ -585,6 +584,75 @@ function rc_detect_encoding($string, $failover='')
     return $result ? $result : $failover;
 }
 
+/**
+ * Removes non-unicode characters from input
+ *
+ * @param mixed $input String or array.
+ * @return string
+ */
+function rc_utf8_clean($input)
+{
+  // handle input of type array
+  if (is_array($input)) {
+    foreach ($input as $idx => $val)
+      $input[$idx] = rc_utf8_clean($val);
+    return $input;
+  }
+  
+  if (!is_string($input) || $input == '')
+    return $input;
+  
+  // iconv/mbstring are much faster (especially with long strings)
+  if (function_exists('mb_convert_encoding') && ($res = mb_convert_encoding($input, 'UTF8', 'UTF8')))
+    return $res;
+
+  if (function_exists('iconv') && ($res = iconv('UTF8', 'UTF8//IGNORE', $input)))
+    return $res;
+
+  $regexp = '/^('.
+//    '[\x00-\x7F]'.                                  // UTF8-1
+    '|[\xC2-\xDF][\x80-\xBF]'.                      // UTF8-2
+    '|\xE0[\xA0-\xBF][\x80-\xBF]'.                  // UTF8-3
+    '|[\xE1-\xEC][\x80-\xBF][\x80-\xBF]'.           // UTF8-3
+    '|\xED[\x80-\x9F][\x80-\xBF]'.                  // UTF8-3
+    '|[\xEE-\xEF][\x80-\xBF][\x80-\xBF]'.           // UTF8-3
+    '|\xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF]'.       // UTF8-4
+    '|[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.// UTF8-4
+    '|\xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF]'.       // UTF8-4
+    ')$/';
+  
+  $seq = '';
+  $out = '';
+
+  for ($i = 0, $len = strlen($input)-1; $i < $len; $i++) {
+    $chr = $input[$i];
+    $ord = ord($chr);
+    // 1-byte character
+    if ($ord <= 0x7F) {
+      if ($seq)
+        $out .= preg_match($regexp, $seq) ? $seq : '';
+      $seq = '';
+      $out .= $chr;
+    // first (or second) byte of multibyte sequence
+    } else if ($ord >= 0xC0) {
+      if (strlen($seq)>1) {
+       $out .= preg_match($regexp, $seq) ? $seq : '';
+        $seq = '';
+      } else if ($seq && ord($seq) < 0xC0) {
+        $seq = '';
+      }
+      $seq .= $chr;
+    // next byte of multibyte sequence
+    } else if ($seq) {
+      $seq .= $chr;
+    }
+  }
+
+  if ($seq)
+    $out .= preg_match($regexp, $seq) ? $seq : '';
+
+  return $out;
+}
 
 /**
  * Explode quoted string
index 2625fdfb9a8b34b7bff594c3975c99e6f85bb000..b1c1fbbbeb6644202857d3bbda230b92fde8d78e 100644 (file)
@@ -39,7 +39,7 @@ class rcube_string_replacer
     $url_chars_within = '\?\.~,!';
 
     $this->link_pattern = "/([\w]+:\/\/|\Wwww\.)([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i";
-    $this->mailto_pattern = "/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/i";
+    $this->mailto_pattern = "/([a-z0-9][a-z0-9\-\.\+\_]*@([a-z0-9]([-a-z0-9]*[a-z0-9])?\\.)+[a-z]{2,5})/i";
   }
 
   /**
index 3d894b5b6d0a2aa65843af3ac8c2e0086f53657f..5226f8db891ecce1e990495d5402bb1e81f17f41 100755 (executable)
@@ -1005,8 +1005,8 @@ class rcube_template extends rcube_html_page
         if (empty($url) && !preg_match('/_(task|action)=logout/', $_SERVER['QUERY_STRING']))
             $url = $_SERVER['QUERY_STRING'];
 
-        $input_user   = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30) + $attrib);
-        $input_pass   = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30) + $attrib);
+        $input_user   = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser') + $attrib);
+        $input_pass   = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd') + $attrib);
         $input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'login'));
         $input_tzone  = new html_hiddenfield(array('name' => '_timezone', 'id' => 'rcmlogintz', 'value' => '_default_'));
         $input_url    = new html_hiddenfield(array('name' => '_url', 'id' => 'rcmloginurl', 'value' => $url));
@@ -1026,7 +1026,7 @@ class rcube_template extends rcube_html_page
             }
         }
         else if (empty($default_host)) {
-            $input_host = new html_inputfield(array('name' => '_host', 'id' => 'rcmloginhost', 'size' => 30));
+            $input_host = new html_inputfield(array('name' => '_host', 'id' => 'rcmloginhost') + $attrib);
         }
 
         $form_name  = !empty($attrib['form']) ? $attrib['form'] : 'form';
index 54a76c5abe67b615d4e8923c4beedcbf10f7c6ac..c2cad1121289d318ac73b749757c12f8c3dff96e 100644 (file)
@@ -360,9 +360,8 @@ class rcube_user
     $rcmail = rcmail::get_instance();
 
     // try to resolve user in virtuser table and file
-    if (!strpos($user, '@')) {
-      if ($email_list = self::user2email($user, false, true))
-        $user_email = is_array($email_list[0]) ? $email_list[0][0] : $email_list[0];
+    if ($email_list = self::user2email($user, false, true)) {
+      $user_email = is_array($email_list[0]) ? $email_list[0][0] : $email_list[0];
     }
 
     $data = $rcmail->plugins->exec_hook('create_user',
index 7dbbb3f71da22fdbe13b4f9fc8706d3aea4e8824..f574eed14a0d155ebb475aeecc9766ea4073a7a6 100644 (file)
@@ -269,6 +269,7 @@ class rcube_vcard
 
         foreach($regs2[1] as $attrid => $attr) {
           if ((list($key, $value) = explode('=', $attr)) && $value) {
+           $value = trim($value);
             if ($key == 'ENCODING') {
               // add next line(s) to value string if QP line end detected
               while ($value == 'QUOTED-PRINTABLE' && preg_match('/=$/', $lines[$i]))
index 35bd1b869cc257d73ddca96202bd0ba72660cb87..77d1b1fe76dd442342a80a257a7ed208a14c9c4e 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: session.inc 2573 2009-05-29 19:10:24Z alec $
+ $Id: session.inc 2932 2009-09-07 12:51:21Z alec $
 
 */
 
@@ -245,7 +245,7 @@ function rcube_sess_regenerate_id()
   $randval = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
   for ($random = "", $i=1; $i <= 32; $i++) {
-    $random .= substr($randval, rand(0,(strlen($randval) - 1)), 1);
+    $random .= substr($randval, mt_rand(0,(strlen($randval) - 1)), 1);
   }
 
   // use md5 value for id or remove capitals from string $randval
index 5d1903fcce7758e1e0aba5a2e0fdbdd8508c9551..57d1471b6394336453e501781f4790bc346d2cf0 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: jquery.js, common.js, list.js                               |
- +-----------------------------------------------------------------------+
-
-  $Id: app.js 2889 2009-08-29 18:41:17Z alec $
-*/
-
-
-function rcube_webmail()
-{
-  this.env = new Object();
-  this.labels = new Object();
-  this.buttons = new Object();
-  this.buttons_sel = new Object();
-  this.gui_objects = new Object();
-  this.gui_containers = new Object();
-  this.commands = new Object();
-  this.command_handlers = new Object();
-  this.onloads = new Array();
-
-  // create protected reference to myself
-  this.ref = 'rcmail';
-  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 jQuery ajax options
-  jQuery.ajaxSetup({ cache:false,
-    error:function(request, status, err){ ref.http_error(request, status, err); },
-    beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-RoundCube-Request', ref.env.request_token); }
-  });
-
-  // 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;
-    };
-  
-  // register a container object
-  this.gui_container = function(name, id)
-  {
-    this.gui_containers[name] = id;
-  };
-  
-  // add a GUI element (html node) to a specified container
-  this.add_element = function(elm, container)
-  {
-    if (this.gui_containers[container] && this.gui_containers[container].jquery)
-      this.gui_containers[container].append(elm);
-  };
-
-  // register an external handler for a certain command
-  this.register_command = function(command, callback, enable)
-  {
-    this.command_handlers[command] = callback;
-    
-    if (enable)
-      this.enable_command(command, true);
-  };
-  
-  // execute the given script on load
-  this.add_onload = function(f)
-  {
-    this.onloads[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 containers
-    for (var n in this.gui_containers)
-      this.gui_containers[n] = $('#'+this.gui_containers[n]);
-
-    // find all registered gui objects
-    for (var n in this.gui_objects)
-      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
-      
-    // init registered buttons
-    this.init_buttons();
-
-    // 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(e){ p.drag_move(e); });
-          this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); });
-          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-
-          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); };
-          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',
-            'open', 'mark', 'edit', 'viewsource', 'download', '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.blockedobjects)
-            {
-            if (this.gui_objects.remoteobjectsmsg)
-              this.gui_objects.remoteobjectsmsg.style.display = 'block';
-            this.enable_command('load-images', 'always-load', 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=='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 ($("input[name='_is_html']").val() == '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); };
-
-          // init message compose form
-          this.init_messageform();
-          }
-
-        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();
-
-        // 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.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); };
-          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
-          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
-          this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
-          this.contact_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
-          this.contact_list.addEventListener('dragend', function(e){ p.drag_end(e); });
-          this.contact_list.init();
-
-          if (this.env.cid)
-            this.contact_list.highlight_row(this.env.cid);
-
-          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.gui_objects.folderlist = this.gui_objects.contactslist;
-          }
-
-        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.enable_command('add', this.env.identities_level < 2);
-        }
-        else if (this.env.action=='edit-identity' || this.env.action=='add-identity') {
-          this.enable_command('add', this.env.identities_level < 2);
-          this.enable_command('save', 'delete', 'edit', true);
-        }
-        else 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);
-          }
-        else if (this.gui_objects.sectionslist)
-          {
-          this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:false});
-          this.sections_list.addEventListener('select', function(o){ p.section_select(o); });
-          this.sections_list.init();
-          this.sections_list.focus();
-          this.sections_list.select('general');  // open first section by default
-        }
-        else if (this.gui_objects.subscriptionlist)
-          this.init_subscription_list();
-
-        break;
-
-      case 'login':
-        var input_user = $('#rcmloginuser');
-        input_user.bind('keyup', function(e){ return rcmail.login_user_keyup(e); });
-        
-        if (input_user.val() == '')
-          input_user.focus();
-        else
-          $('#rcmloginpwd').focus();
-
-        // detect client timezone
-        $('#rcmlogintz').val(new Date().getTimezoneOffset() / -60);
-
-        this.enable_command('login', true);
-        break;
-      
-      default:
-        break;
-      }
-
-    // flag object as complete
-    this.loaded = true;
-
-    // show message
-    if (this.pending_message)
-      this.display_message(this.pending_message[0], this.pending_message[1]);
-      
-    // map implicit containers
-    if (this.gui_objects.folderlist)
-      this.gui_containers.foldertray = $(this.gui_objects.folderlist);
-
-    // trigger init event hook
-    this.triggerEvent('init', { task:this.task, action:this.env.action });
-    
-    // execute all foreign onload scripts
-    // @deprecated
-    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 keep-alive interval
-    this.start_keepalive();
-  };
-
-  // 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.getElementsByTagName('td')[0].getElementsByTagName('img')[0])
-      {
-      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.getElementsByTagName('td')[this.env.flagged_col].getElementsByTagName('img')[0]))
-      {
-      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.triggerEvent('insertrow', { uid:uid, row:row });
-  };
-
-  // 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 = $("[name='_from']");
-    var input_to = $("[name='_to']");
-    var input_subject = $("input[name='_subject']");
-    var input_message = $("[name='_message']").get(0);
-
-    // init live search events
-    this.init_address_input_events(input_to);
-    this.init_address_input_events($("[name='_cc']"));
-    this.init_address_input_events($("[name='_bcc']"));
-
-    // add signature according to selected identity
-    if (input_from.attr('type') == 'select-one' && $("input[name='_draft_saveid']").val() == ''
-        && $("input[name='_is_html']").val() != '1') {  // if we have HTML editor, signature is added in callback
-      this.change_identity(input_from[0]);
-    }
-
-    if (input_to.val() == '')
-      input_to.focus();
-    else if (input_subject.val() == '')
-      input_subject.focus();
-    else if (input_message)
-      input_message.focus();
-
-    // 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); };
-    obj.bind((bw.safari || bw.ie ? 'keydown' : 'keypress'), handler);
-    obj.attr('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 external commands
-    if (typeof this.command_handlers[command] == 'function')
-    {
-      var ret = this.command_handlers[command](props, obj);
-      return ret !== null ? ret : (obj ? false : true);
-    }
-    else if (typeof this.command_handlers[command] == 'string')
-    {
-      var ret = window[this.command_handlers[command]](props, obj);
-      return ret !== null ? ret : (obj ? false : true);
-    }
-    
-    // trigger plugin hook
-    var event_ret = this.triggerEvent('before'+command, props);
-    if (typeof event_ret != 'undefined') {
-      // abort if one the handlers returned false
-      if (event_ret === false)
-        return false;
-      else
-        props = event_ret;
-    }
-
-    // process internal command
-    switch (command)
-      {
-      case 'login':
-        if (this.gui_objects.loginform)
-          this.gui_objects.loginform.submit();
-        break;
-
-      // commands to switch task
-      case 'mail':
-      case 'addressbook':
-      case 'settings':
-      case 'logout':
-        this.switch_task(command);
-        break;
-
-      case 'permaurl':
-        if (obj && obj.href && obj.target)
-          return true;
-        else if (this.env.permaurl)
-          parent.location.href = this.env.permaurl;
-        break;
-
-      case 'open':
-        var uid;
-        if (uid = this.get_single_uid())
-        {
-          obj.href = '?_task='+this.env.task+'&_action=show&_mbox='+urlencode(this.env.mailbox)+'&_uid='+uid;
-          return true;
-        }
-        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':
-        var sort_order, sort_col = props;
-
-        if (this.env.sort_col==sort_col)
-          sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
-        else
-         sort_order = 'ASC';
-       
-        // set table header class
-        $('#rcm'+this.env.sort_col).removeClass('sorted'+(this.env.sort_order.toUpperCase()));
-        $('#rcm'+sort_col).addClass('sorted'+sort_order);
-
-        // 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');
-        else if (this.task=='mail' && (cid = this.get_single_uid())) {
-          var url = (this.env.mailbox == this.env.drafts_mailbox) ? '_draft_uid=' : '_uid=';
-          this.goto_url('compose', url+cid+'&_mbox='+urlencode(this.env.mailbox), true);
-        }
-        break;
-
-      case 'save-identity':
-      case 'save':
-        if (this.gui_objects.editform)
-          {
-          var input_pagesize = $("input[name='_pagesize']");
-          var input_name  = $("input[name='_name']");
-          var input_email = $("input[name='_email']");
-
-          // user prefs
-          if (input_pagesize.length && isNaN(parseInt(input_pagesize.val())))
-            {
-            alert(this.get_label('nopagesizewarning'));
-            input_pagesize.focus();
-            break;
-            }
-          // contacts/identities
-          else
-            {
-            if (input_name.length && input_name.val() == '')
-              {
-              alert(this.get_label('nonamewarning'));
-              input_name.focus();
-              break;
-              }
-            else if (input_email.length && !rcube_check_email(input_email.val()))
-              {
-              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':
-        if (props == 'invert')
-          this.message_list.invert_selection();
-        else
-          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(this.env.composebody)) {
-          tinyMCE.execCommand('mceSpellCheck', true);
-        }
-        else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) {
-          this.env.spellcheck.spellCheck();
-          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='+uid+'&_mbox='+urlencode(this.env.mailbox));
-          if (this.sourcewin)
-            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
-          }
-        break;
-
-      case 'download':
-        var uid;
-        if (uid = this.get_single_uid())
-          this.goto_url('viewsource', '&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+'&_save=1');
-        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;
-
-      }
-      
-    this.triggerEvent('after'+command, props);
-
-    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, domain)
-    {
-    if (domain && this.labels[domain+'.'+name])
-      return this.labels[domain+'.'+name];
-    else if (this.labels[name])
-      return this.labels[name];
-    else
-      return name;
-    };
-  
-  // alias for convenience reasons
-  this.gettext = this.get_label;
-
-  // switch to another application task
-  this.switch_task = function(task)
-    {
-    if (this.task===task && task!='mail')
-      return;
-
-    var url = this.get_task_url(task);
-    if (task=='mail')
-      url += '&_mbox=INBOX';
-
-    this.redirect(url);
-    };
-
-  this.get_task_url = function(task, url)
-    {
-    if (!url)
-      url = this.env.comm_path;
-
-    return url.replace(/_task=[a-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');
-    };
-  
-  this.reload = function(delay)
-  {
-    if (this.env.framed && parent.rcmail)
-      parent.rcmail.reload(delay);
-    else if (delay)
-      window.setTimeout(function(){ rcmail.reload(); }, delay);
-    else if (window.location)
-      location.href = this.env.comm_path;
-  };
-
-
-  /*********************************************************/
-  /*********        event handling methods         *********/
-  /*********************************************************/
-
-  this.doc_mouse_up = function(e)
-  {
-    var model, list, li;
-
-    if (this.message_list) {
-      if (!rcube_mouse_is_over(e, this.message_list.list))
-        this.message_list.blur();
-      list = this.message_list;
-      model = this.env.mailboxes;
-    }
-    else if (this.contact_list) {
-      if (!rcube_mouse_is_over(e, this.contact_list.list))
-        this.contact_list.blur();
-      list = this.contact_list;
-      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.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
-      this.command('moveto', model[this.env.last_folder_target].id);
-      this.env.last_folder_target = null;
-      list.draglayer.hide();
-    }
-    
-    // reset 'pressed' buttons
-    if (this.buttons_sel) {
-      for (var id in this.buttons_sel)
-        if (typeof id != 'function')
-          this.button_out(this.buttons_sel[id], id);
-      this.buttons_sel = {};
-    }
-  };
-
-  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)
-      {
-      this.initialBodyScrollTop = bw.ie ? 0 : window.pageYOffset;
-      this.initialListScrollTop = this.gui_objects.folderlist.parentNode.scrollTop;
-
-      var li, pos, list, height;
-      list = $(this.gui_objects.folderlist);
-      pos = list.offset();
-      this.env.folderlist_coords = { x1:pos.left, y1:pos.top, x2:pos.left + list.width(), y2:pos.top + list.height() };
-
-      this.env.folder_coords = new Array();
-      for (var k in model) {
-        if (li = this.get_folder_li(k)) {
-          // only visible folders
-          if (height = li.firstChild.offsetHeight) {
-            pos = $(li.firstChild).offset();
-            this.env.folder_coords[k] = { x1:pos.left, y1:pos.top,
-              x2:pos.left + li.firstChild.offsetWidth, y2:pos.top + height, on:0 };
-          }
-        }
-      }
-    }
-  };
-
-  this.drag_end = function(e)
-  {
-    this.drag_active = false;
-    this.env.last_folder_target = null;
-    
-    if (this.folder_auto_timer) {
-      window.clearTimeout(this.folder_auto_timer);
-      this.folder_auto_timer = null;
-      this.folder_auto_expand = null;
-    }
-
-    // over the folders
-    if (this.gui_objects.folderlist && this.env.folder_coords) {
-      for (var k in this.env.folder_coords) {
-        if (this.env.folder_coords[k].on)
-          $(this.get_folder_li(k)).removeClass('droptarget');
-      }
-    }
-  };
-  
-  this.drag_move = function(e)
-  {
-    if (this.gui_objects.folderlist && this.env.folder_coords) {
-      // offsets to compensate for scrolling while dragging a message
-      var boffset = bw.ie ? -document.documentElement.scrollTop : this.initialBodyScrollTop;
-      var moffset = this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop;
-      var toffset = -moffset-boffset;
-
-      var li, div, 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.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
-          this.env.folder_coords[this.env.last_folder_target].on = 0;
-          this.env.last_folder_target = null;
-        }
-        return;
-      }
-    
-      // over the folders
-      for (var k in this.env.folder_coords) {
-        pos = this.env.folder_coords[k];
-        if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.y >= pos.y1 && mouse.y < pos.y2
-            && this.check_droptarget(k)) {
-
-          li = this.get_folder_li(k);
-          div = $(li.getElementsByTagName("div")[0]);
-
-          // if the folder is collapsed, expand it after 1sec and restart the drag & drop process.
-          if (div.hasClass('collapsed')) {
-            if (this.folder_auto_timer)
-              window.clearTimeout(this.folder_auto_timer);
-            
-            this.folder_auto_expand = k;
-            this.folder_auto_timer = window.setTimeout(function() {
-                rcmail.command("collapse-folder", rcmail.folder_auto_expand);
-                rcmail.drag_start(null);
-              }, 1000);
-          } else if (this.folder_auto_timer) {
-            window.clearTimeout(this.folder_auto_timer);
-            this.folder_auto_timer = null;
-            this.folder_auto_expand = null;
-          }
-          
-          $(li).addClass('droptarget');
-          this.env.last_folder_target = k;
-          this.env.folder_coords[k].on = 1;
-        }
-        else if (pos.on) {
-          $(this.get_folder_li(k)).removeClass('droptarget');
-          this.env.folder_coords[k].on = 0;
-        }
-      }
-    }
-  };
-
-  this.collapse_folder = function(id)
-    {
-    var div;
-    if ((li = this.get_folder_li(id)) &&
-        (div = $(li.getElementsByTagName("div")[0])) &&
-        (div.hasClass('collapsed') || div.hasClass('expanded')))
-      {
-      var ul = $(li.getElementsByTagName("ul")[0]);
-      if (div.hasClass('collapsed'))
-        {
-        ul.show();
-        div.removeClass('collapsed').addClass('expanded');
-        var reg = new RegExp('&'+urlencode(id)+'&');
-        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
-        }
-      else
-        {
-        ul.hide();
-        div.removeClass('expanded').addClass('collapsed');
-        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();
-
-    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', 'open', 'edit', 'download', 'viewsource', selected);
-      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
-      }
-    else
-      {
-      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', 'edit', 'open', 'download', 'viewsource', 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 = $('#'+this.env.contentframe)) && frm.length)
-      {
-      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[show ? 'show' : 'hide']();
-      }
-
-    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)
-    {
-    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)
-      {
-      page = 1;
-      this.env.current_page = page;
-      this.show_contentframe(false);
-      }
-    
-    if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
-      add_url += '&_refresh=1';
-
-    // unselect selected messages
-    this.last_selected = 0;
-    if (this.message_list)
-      this.message_list.clear_selection();
-    
-    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);
-    
-    var rowobj = $(rows[uid].obj);
-    if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0)
-      {
-      rows[uid].classname += ' unread';
-      rowobj.addClass('unread');
-      }
-    else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*unread/, '');
-      rowobj.removeClass('unread');
-      }
-    
-    if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0)
-      {
-      rows[uid].classname += ' deleted';
-      rowobj.addClass('deleted');
-      }
-    else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
-      rowobj.removeClass('deleted');
-      }
-
-    if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0)
-      {
-      rows[uid].classname += ' flagged';
-      rowobj.addClass('flagged');
-      }
-    else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, '');
-      rowobj.removeClass('flagged');
-      }
-
-    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
-      this.show_contentframe(false);
-
-    // Hide message command buttons until a message is selected
-    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', false);
-
-    this._with_selected_messages('moveto', lock, add_url);
-    };
-
-  // 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 config is set to flag for deletion
-    if (this.env.flag_for_deletion)
-      this.mark_message('delete');
-    // if there isn't a defined trash mailbox or 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 is a trash mailbox defined and we're not currently in it
-    else {
-      // 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);
-      }
-  };
-
-  // 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 : ''));
-    };
-
-  // 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;
-        this.message_list.remove_row(id, (this.env.display_next && n == selection.length-1));
-      }
-      // make sure there are no selected rows
-      if (!this.env.display_next)
-        this.message_list.clear_selection();
-    }
-
-    // also send search request to get the right messages 
-    if (this.env.search_request) 
-      add_url += '&_search='+this.env.search_request;
-
-    if (this.env.display_next && this.env.next_uid)
-      add_url += '&_next_uid='+this.env.next_uid;
-
-    // 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])
-        {
-        if (rows[uid].unread)
-          r_uids[r_uids.length] = uid;
-
-       if (this.env.skip_deleted)
-          this.message_list.remove_row(uid, (this.env.display_next && i == this.message_list.selection.length-1));
-       else
-         this.set_message(uid, 'deleted', true);
-        }
-      }
-
-    // make sure there are no selected rows
-    if (this.env.skip_deleted && !this.env.display_next && this.message_list)
-      this.message_list.clear_selection();
-
-    add_url = '&_from='+(this.env.action ? this.env.action : '');
-    
-    if (r_uids.length)
-      add_url += '&_ruid='+r_uids.join(',');
-
-    if (this.env.skip_deleted) {
-      // also send search request to get the right messages 
-      if (this.env.search_request) 
-        add_url += '&_search='+this.env.search_request;
-      if (this.env.display_next && this.env.next_uid)
-        add_url += '&_next_uid='+this.env.next_uid;
-    }
-    
-    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 passwd = $('#rcmloginpwd');
-
-    // enter
-    if (key == 13 && passwd.length && !passwd.val()) {
-      passwd.focus();
-      return rcube_event.cancel(e);
-    }
-    
-    return true;
-  };
-
-
-  /*********************************************************/
-  /*********        message compose methods        *********/
-  /*********************************************************/
-  
-  // checks the input fields before sending a message
-  this.check_compose_input = function()
-    {
-    // check input fields
-    var input_to = $("[name='_to']");
-    var input_cc = $("[name='_cc']");
-    var input_bcc = $("[name='_bcc']");
-    var input_from = $("[name='_from']");
-    var input_subject = $("[name='_subject']");
-    var input_message = $("[name='_message']");
-
-    // check sender (if have no identities)
-    if (input_from.attr('type') == 'text' && !rcube_check_email(input_from.val(), true))
-      {
-      alert(this.get_label('nosenderwarning'));
-      input_from.focus();
-      return false;
-      }
-
-    // check for empty recipient
-    var recipients = input_to.val() ? input_to.val() : (input_cc.val() ? input_cc.val() : input_bcc.val());
-    if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true))
-      {
-      alert(this.get_label('norecipientwarning'));
-      input_to.focus();
-      return false;
-      }
-
-    // display localized warning for missing subject
-    if (input_subject.val() == '')
-      {
-      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.val((subject ? subject : this.get_label('nosubject')));
-        }
-      }
-
-    // check for empty body
-    if ((!window.tinyMCE || !tinyMCE.get(this.env.composebody))
-       && input_message.val() == '' && !confirm(this.get_label('nobodywarning')))
-      {
-      input_message.focus();
-      return false;
-      }
-    else if (window.tinyMCE && tinyMCE.get(this.env.composebody)
-       && !tinyMCE.get(this.env.composebody).getContent()
-       && !confirm(this.get_label('nobodywarning')))
-      {
-      tinyMCE.get(this.env.composebody).focus();
-      return false;
-      }
-
-    // Apply spellcheck changes if spell checker is active
-    this.stop_spellchecking();
-
-    // move body from html editor to textarea (just to be sure, #1485860)
-    if (window.tinyMCE && tinyMCE.get(this.env.composebody))
-      tinyMCE.triggerSave();
-
-    return true;
-    };
-
-  this.stop_spellchecking = function()
-    {
-    if (this.env.spellcheck && !this.spellcheck_ready) {
-      $(this.env.spellcheck.spell_span).trigger('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.spell_container).css('visibility', vis ? 'visible' : 'hidden');
-      }
-    };
-
-  this.set_spellcheck_state = function(s)
-    {
-    this.spellcheck_ready = (s == 'ready' || s == 'no_error_found');
-    this.enable_command('spellcheck', this.spellcheck_ready);
-    };
-
-  this.set_draft_id = function(id)
-    {
-    $("input[name='_draft_saveid']").val(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 value_to = $("[name='_to']").val();
-    var value_cc = $("[name='_cc']").val();
-    var value_bcc = $("[name='_bcc']").val();
-    var value_subject = $("[name='_subject']").val();
-    var str = '';
-    
-    if (value_to)
-      str += value_to+':';
-    if (value_cc)
-      str += value_cc+':';
-    if (value_bcc)
-      str += value_bcc+':';
-    if (value_subject)
-      str += value_subject+':';
-    
-    var editor = tinyMCE.get(this.env.composebody);
-    if (editor)
-      str += editor.getContent();
-    else
-      str += $("[name='_message']").val();
-    
-    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 = $("[name='_message']");
-    var message = input_message.val();
-    var is_html = ($("input[name='_is_html']").val() == '1');
-    var sig, p, len;
-
-    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]+$/, '');
-      len = message.length;
-
-      // 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;
-       if (len) len += 1;
-        }
-      }
-    else
-      {
-      var editor = tinyMCE.get(this.env.composebody);
-
-      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>';
-        }
-      }
-
-    input_message.val(message);
-
-    // move cursor before the signature
-    if (!is_html)
-      this.set_caret_pos(input_message.get(0), len);
-
-    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 = $(list).offset();
-        elm.style.top = (pos.top + list.offsetHeight + 10) + 'px';
-        elm.style.left = pos.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;
-      
-    $('<li>').attr('id', name).html(content).appendTo(this.gui_objects.attachmentlist);
-    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)
-    {
-    if (value != '')
-      {
-      var addurl = '';
-      if (this.message_list) {
-        this.message_list.clear();
-       if (this.env.search_mods) {
-          var head_arr = new Array();
-          for (var n in this.env.search_mods)
-           head_arr.push(n);
-         addurl += '&_headers='+head_arr.join(',');
-          }
-        } 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 = $('#rcmksearchSelected');
-    if (current[0] && node) {
-      current.removeAttr('id').removeClass('selected');
-    }
-
-    if (node) {
-      $(node).attr('id', 'rcmksearchSelected').addClass('selected');
-      this.ksearch_selected = node._rcm_id;
-    }
-  };
-
-  this.insert_recipient = function(id)
-  {
-    if (!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.is(":visible"))
-      this.ksearch_pane.hide();
-
-    // 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 the last results are still active
-    if (q == this.ksearch_value)
-      return;
-    
-    var old_value = this.ksearch_value;
-    this.ksearch_value = q;
-    
-    // ...string is empty
-    if (!q.length)
-      return;
-
-    // ...new search value contains old one and previous search result was empty
-    if (old_value && old_value.length && this.env.contacts && !this.env.contacts.length && q.indexOf(old_value) == 0)
-      return;
-    
-    this.display_message(this.get_label('searching'), 'loading', true);
-    this.http_post('autocomplete', '_search='+urlencode(q));
-  };
-
-  this.ksearch_query_results = function(results, search)
-  {
-    // ignore this outdated search response
-    if (this.ksearch_value && 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 = $('<ul>');
-        this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane').css({ position:'absolute', 'z-index':30000 }).append(ul).appendTo(document.body);
-        this.ksearch_pane.__ul = ul[0];
-      }
-
-      // remove all search results
-      ul = this.ksearch_pane.__ul;
-      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).attr('id', 'rcmksearchSelected').addClass('selected');
-      this.ksearch_selected = 0;
-
-      // move the results pane right under the input box and make it visible
-      var pos = $(this.ksearch_input).offset();
-      this.ksearch_pane.css({ left:pos.left+'px', top:(pos.top + this.ksearch_input.offsetHeight)+'px' }).show();
-    }
-    // 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.hide();
-    };
-
-
-  /*********************************************************/
-  /*********         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, newcid)
-  {
-    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]).html(cols_arr[c]);
-
-      // cid change
-      if (newcid) {
-       row.id = 'rcmrow' + newcid;
-        this.contact_list.remove_row(cid);
-        this.contact_list.init_row(row);
-       this.contact_list.selection[0] = newcid;
-       row.style.display = '';
-      }
-
-      return true;
-    }
-
-    return false;
-  };
-
-  // 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));
-    };
-
-
-  /*********************************************************/
-  /*********        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();
-    }
-
-  // preferences section select and load options frame
-  this.section_select = function(list)
-    {
-    var id = list.get_single_selection();
-    
-    if (id) {
-      var add_url = '';
-      var target = window;
-      this.set_busy(true);
-
-      if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) {
-        add_url = '&_framed=1';
-        target = window.frames[this.env.contentframe];
-        }
-
-      target.location.href = this.env.comm_path+'&_action=edit-prefs&_section='+id+add_url;
-      }
-
-    return true;
-    };
-
-  this.identity_select = function(list)
-    {
-    var id;
-    if (id = list.get_single_selection())
-      this.load_identity(id, 'edit-identity');
-    };
-
-  // load identity record
-  this.load_identity = function(id, action)
-    {
-    if (action=='edit-identity' && (!id || id==this.env.iid))
-      return false;
-
-    var 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];
-
-    // append token to request
-    this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, 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);
-          $(row).addClass('droptarget');
-          }
-        }
-      else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter))))
-        {
-        this.set_env('dstfolder', this.env.delimiter);
-        $(this.subscription_list.frame).addClass('droptarget');
-        }
-    }
-
-  this.unfocus_subscription = function(id)
-    {
-      var row = $('#'+id);
-      this.set_env('dstfolder', null);
-      if (this.env.subscriptionrows[id] && row[0])
-        row.removeClass('droptarget');
-      else
-        $(this.subscription_list.frame).removeClass('droptarget');
-    }
-
-  this.subscription_select = function(list)
-    {
-    var id, folder;
-    if ((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).html(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.type = 'text';
-      this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, '');
-
-      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).html(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);
-
-      $(this.gui_objects.createfolderhint).html('');
-      }
-    };
-
-  // 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.toLowerCase()=='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 event handlers on registered buttons
-  this.init_buttons = function()
-  {
-    for (var cmd in this.buttons) {
-      if (typeof cmd != 'string')
-        continue;
-      
-      for (var i=0; i< this.buttons[cmd].length; i++) {
-        var prop = this.buttons[cmd][i];
-        var elm = document.getElementById(prop.id);
-        if (!elm)
-          continue;
-
-        var preload = false;
-        if (prop.type == 'image') {
-          elm = elm.parentNode;
-          preload = true;
-        }
-        
-        elm._command = cmd;
-        elm._id = prop.id;
-        if (prop.sel) {
-          elm.onmousedown = function(e){ return rcmail.button_sel(this._command, this._id); };
-          elm.onmouseup = function(e){ return rcmail.button_out(this._command, this._id); };
-          if (preload)
-            new Image().src = prop.sel;
-        }
-        if (prop.over) {
-          elm.onmouseover = function(e){ return rcmail.button_over(this._command, this._id); };
-          elm.onmouseout = function(e){ return rcmail.button_out(this._command, this._id); };
-          if (preload)
-            new Image().src = prop.over;
-        }
-      }
-    }
-  };
-
-  // set 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.toLowerCase() == 'a')
-            link.setAttribute('title', this.get_label(label));
-        }
-        else if (obj)
-          obj.setAttribute('title', this.get_label(label));
-      }
-    };
-
-  // mouse over button
-  this.button_over = function(command, id)
-  {
-    var a_buttons = this.buttons[command];
-    var button, elm;
-
-    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')
-      {
-        elm = document.getElementById(button.id);
-        if (elm && button.over) {
-          if (button.type == 'image')
-            elm.src = button.over;
-          else
-            elm.className = button.over;
-        }
-      }
-    }
-  };
-
-  // mouse down on button
-  this.button_sel = function(command, id)
-  {
-    var a_buttons = this.buttons[command];
-    var button, elm;
-
-    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')
-      {
-        elm = document.getElementById(button.id);
-        if (elm && button.sel) {
-          if (button.type == 'image')
-            elm.src = button.sel;
-          else
-            elm.className = button.sel;
-        }
-        this.buttons_sel[id] = command;
-      }
-    }
-  };
-
-  // mouse out of button
-  this.button_out = function(command, id)
-  {
-    var a_buttons = this.buttons[command];
-    var button, elm;
-
-    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')
-      {
-        elm = document.getElementById(button.id);
-        if (elm && button.act) {
-          if (button.type == 'image')
-            elm.src = button.act;
-          else
-            elm.className = button.act;
-        }
-      }
-    }
-  };
-
-  // write to the document/window title
-  this.set_pagetitle = function(title)
-  {
-    if (title && document.title)
-      document.title = title;
-  }
-
-  // display a system message
-  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 obj = $(this.gui_objects.message).html(cont).show();
-    
-    if (type!='loading')
-      obj.bind('mousedown', function(){ ref.hide_message(); return true; });
-    
-    if (!hold)
-      this.message_timer = window.setTimeout(function(){ ref.hide_message(true); }, this.message_time);
-    };
-
-  // make a message row disapear
-  this.hide_message = function(fade)
-    {
-    if (this.gui_objects.message)
-      $(this.gui_objects.message).unbind()[(fade?'fadeOut':'hide')]();
-    };
-
-  // 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))) {
-        $(current_li).removeClass('selected').removeClass('unfocused');
-      }
-      if ((target_li = this.get_folder_li(name))) {
-        $(target_li).removeClass('unfocused').addClass('selected');
-      }
-      
-      // trigger event hook
-      this.triggerEvent('selectfolder', { folder:name, old:old });
-    }
-  };
-
-  // 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.toLowerCase()=='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;
-
-    if (this.message_list.background)
-      var tbody = this.message_list.background;
-    else
-      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 css_class = 'message'
-        + (even ? ' even' : ' odd')
-        + (flags.unread ? ' unread' : '')
-        + (flags.deleted ? ' deleted' : '')
-        + (flags.flagged ? ' flagged' : '')
-        + (this.message_list.in_selection(uid) ? ' selected' : '');
-
-    // for performance use DOM instead of jQuery here
-    var row = document.createElement('tr');
-    row.id = 'rcmrow'+uid;
-    row.className = css_class;
-    
-    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;
-    
-    // add icon col
-    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);
-      }
-    };
-
-  // messages list handling in background (for performance)
-  this.offline_message_list = function(flag)
-    {
-      if (this.message_list)
-       this.message_list.set_background_mode(flag);
-    };
-
-  // replace content of row count display
-  this.set_rowcount = function(text)
-    {
-    $(this.gui_objects.countdisplay).html(text);
-
-    // update page navigation buttons
-    this.set_page_buttons();
-    };
-
-  // replace content of mailboxname display
-  this.set_mailboxname = function(content)
-    {
-    if (this.gui_objects.mailboxname && content)
-      this.gui_objects.mailboxname.innerHTML = content;
-    };
-
-  // replace content of quota display
-  this.set_quota = function(content)
-    {
-    if (content && this.gui_objects.quotadisplay)
-      $(this.gui_objects.quotadisplay).html(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
-      if ((mycount+childcount)>0)
-        $(item).addClass('unread');
-      else
-        $(item).removeClass('unread');
-      }
-
-    // set unread count to window title
-    reg = /^\([0-9]+\)\s+/i;
-    if (set_title && document.title)
-      {
-      var 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();
-    }
-
-  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) {
-      $(this.gui_objects.all_headers_box).html(content).show();
-
-      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;
-    
-    $(elem).removeClass('show-headers').addClass('hide-headers');
-    $(this.gui_objects.all_headers_row).show();
-    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;
-
-    $(elem).removeClass('hide-headers').addClass('show-headers');
-    $(this.gui_objects.all_headers_row).hide();
-    elem.onclick = function() { rcmail.load_headers(elem); }
-    }
-
-
-  /********************************************************/
-  /*********  html to text conversion functions   *********/
-  /********************************************************/
-
-  this.html2plain = function(htmlText, id)
-    {
-    var url = this.env.bin_path+'html2text.php';
-    var rcmail = this;
-
-    this.set_busy(true, 'converting');
-    console.log('HTTP POST: '+url);
-
-    $.ajax({ type: 'POST', url: url, data: htmlText, contentType: 'application/octet-stream',
-      error: function(o) { rcmail.http_error(o); },
-      success: function(data) { rcmail.set_busy(false); $(document.getElementById(id)).val(data); console.log(data); }
-      });
-    }
-
-  this.plain2html = function(plainText, id)
-    {
-    this.set_busy(true, 'converting');
-    $(document.getElementById(id)).val('<pre>'+plainText+'</pre>');
-    this.set_busy(false);
-    }
-
-
-  /********************************************************/
-  /*********        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);
-    };
-
-  // send a http request to the server
-  this.http_request = function(action, querystring, lock)
-  {
-    querystring += (querystring ? '&' : '') + '_remote=1';
-    var url = this.env.comm_path + '&_action=' + action + '&' + querystring
-    
-    // send request
-    console.log('HTTP POST: ' + url);
-    jQuery.get(url, { _unlock:(lock?1:0) }, function(data){ ref.http_response(data); }, 'json');
-  };
-
-  // send a http POST request to the server
-  this.http_post = function(action, postdata, lock)
-  {
-    var url = this.env.comm_path+'&_action=' + action;
-    
-    if (postdata && typeof(postdata) == 'object') {
-      postdata._remote = 1;
-      postdata._unlock = (lock ? 1 : 0);
-    }
-    else
-      postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock=1' : '');
-
-    // send request
-    console.log('HTTP POST: ' + url);
-    jQuery.post(url, postdata, function(data){ ref.http_response(data); }, 'json');
-  };
-
-  // handle HTTP response
-  this.http_response = function(response)
-  {
-    var console_msg = '';
-    
-    if (response.unlock)
-      this.set_busy(false);
-
-    // set env vars
-    if (response.env)
-      this.set_env(response.env);
-
-    // we have labels to add
-    if (typeof response.texts == 'object') {
-      for (var name in response.texts)
-        if (typeof response.texts[name] == 'string')
-          this.add_label(name, response.texts[name]);
-    }
-
-    // if we get javascript code from server -> execute it
-    if (response.exec) {
-      console.log(response.exec);
-      eval(response.exec);
-    }
-    
-    // execute callback functions of plugins
-    if (response.callbacks && response.callbacks.length) {
-      for (var i=0; i < response.callbacks.length; i++)
-        this.triggerEvent(response.callbacks[i][0], response.callbacks[i][1]);
-    }
-    // process the response data according to the sent action
-    switch (response.action) {
-      case 'delete':
-        if (this.task == 'addressbook') {
-          var 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') {
-         // re-enable commands on move/delete error
-         this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', true);
-        } 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', 'open', 'edit', 'download', '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 && response.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());
-          
-          if (response.action == 'list')
-            this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
-        }
-        else if (this.task == 'addressbook') {
-          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
-          
-          if (response.action == 'list')
-            this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
-        }
-        break;
-    }
-  };
-
-  // handle HTTP request errors
-  this.http_error = function(request, status, err)
-    {
-    var errmsg = request.statusText;
-
-    this.set_busy(false);
-    request.abort();
-    
-    if (errmsg)
-      this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', '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_caret_pos = function(obj, pos)
-    {
-    if (obj.setSelectionRange)
-      obj.setSelectionRange(pos, pos);
-    else if (obj.createTextRange)
-      {
-      var range = obj.createTextRange();
-      range.collapse(true);
-      range.moveEnd('character', pos);
-      range.moveStart('character', pos);
-      range.select();
-      }
-    }
-
-  // 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
-
-
-// copy event engine prototype
-rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
-rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
-rcube_webmail.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
+function rcube_webmail(){
+this.env=new Object();
+this.labels=new Object();
+this.buttons=new Object();
+this.buttons_sel=new Object();
+this.gui_objects=new Object();
+this.gui_containers=new Object();
+this.commands=new Object();
+this.command_handlers=new Object();
+this.onloads=new Array();
+this.ref="rcmail";
+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";
+jQuery.ajaxSetup({cache:false,error:function(_2,_3,_4){
+_1.http_error(_2,_3,_4);
+},beforeSend:function(_5){
+_5.setRequestHeader("X-RoundCube-Request",_1.env.request_token);
+}});
+this.set_env=function(p,_7){
+if(p!=null&&typeof (p)=="object"&&!_7){
+for(var n in p){
+this.env[n]=p[n];
+}
+}else{
+this.env[p]=_7;
+}
+};
+this.add_label=function(_9,_a){
+this.labels[_9]=_a;
+};
+this.register_button=function(_b,id,_d,_e,_f,_10){
+if(!this.buttons[_b]){
+this.buttons[_b]=new Array();
+}
+var _11={id:id,type:_d};
+if(_e){
+_11.act=_e;
+}
+if(_f){
+_11.sel=_f;
+}
+if(_10){
+_11.over=_10;
+}
+this.buttons[_b][this.buttons[_b].length]=_11;
+};
+this.gui_object=function(_12,id){
+this.gui_objects[_12]=id;
+};
+this.gui_container=function(_14,id){
+this.gui_containers[_14]=id;
+};
+this.add_element=function(elm,_17){
+if(this.gui_containers[_17]&&this.gui_containers[_17].jquery){
+this.gui_containers[_17].append(elm);
+}
+};
+this.register_command=function(_18,_19,_1a){
+this.command_handlers[_18]=_19;
+if(_1a){
+this.enable_command(_18,true);
+}
+};
+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_containers){
+this.gui_containers[n]=$("#"+this.gui_containers[n]);
+}
+for(var n in this.gui_objects){
+this.gui_objects[n]=rcube_find_object(this.gui_objects[n]);
+}
+this.init_buttons();
+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(e){
+p.drag_move(e);
+});
+this.message_list.addEventListener("dragend",function(e){
+p.drag_end(e);
+});
+document.onmouseup=function(e){
+return p.doc_mouse_up(e);
+};
+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);
+};
+}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","open","mark","edit","viewsource","download","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.blockedobjects){
+if(this.gui_objects.remoteobjectsmsg){
+this.gui_objects.remoteobjectsmsg.style.display="block";
+}
+this.enable_command("load-images","always-load",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=="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($("input[name='_is_html']").val()=="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);
+};
+this.init_messageform();
+}
+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=="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 _29="_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox);
+if(confirm(this.get_label("mdnrequest"))){
+this.http_post("sendmdn",_29);
+}else{
+this.http_post("mark",_29+"&_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.row_init=function(row){
+p.triggerEvent("insertrow",{cid:row.uid,row:row});
+};
+this.contact_list.addEventListener("keypress",function(o){
+p.contactlist_keypress(o);
+});
+this.contact_list.addEventListener("select",function(o){
+p.contactlist_select(o);
+});
+this.contact_list.addEventListener("dragstart",function(o){
+p.drag_start(o);
+});
+this.contact_list.addEventListener("dragmove",function(e){
+p.drag_move(e);
+});
+this.contact_list.addEventListener("dragend",function(e){
+p.drag_end(e);
+});
+this.contact_list.init();
+if(this.env.cid){
+this.contact_list.highlight_row(this.env.cid);
+}
+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.gui_objects.folderlist=this.gui_objects.contactslist;
+}
+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.enable_command("add",this.env.identities_level<2);
+}else{
+if(this.env.action=="edit-identity"||this.env.action=="add-identity"){
+this.enable_command("add",this.env.identities_level<2);
+this.enable_command("save","delete","edit",true);
+}else{
+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);
+}
+}else{
+if(this.gui_objects.sectionslist){
+this.sections_list=new rcube_list_widget(this.gui_objects.sectionslist,{multiselect:false,draggable:false,keyboard:false});
+this.sections_list.addEventListener("select",function(o){
+p.section_select(o);
+});
+this.sections_list.init();
+this.sections_list.focus();
+this.sections_list.select_first();
+}else{
+if(this.gui_objects.subscriptionlist){
+this.init_subscription_list();
+}
+}
+}
+break;
+case "login":
+var _34=$("#rcmloginuser");
+_34.bind("keyup",function(e){
+return rcmail.login_user_keyup(e);
+});
+if(_34.val()==""){
+_34.focus();
+}else{
+$("#rcmloginpwd").focus();
+}
+$("#rcmlogintz").val(new Date().getTimezoneOffset()/-60);
+this.enable_command("login",true);
+break;
+default:
+break;
+}
+this.loaded=true;
+if(this.pending_message){
+this.display_message(this.pending_message[0],this.pending_message[1]);
+}
+if(this.gui_objects.folderlist){
+this.gui_containers.foldertray=$(this.gui_objects.folderlist);
+}
+this.triggerEvent("init",{task:this.task,action:this.env.action});
+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();
+};
+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.getElementsByTagName("td")[0].getElementsByTagName("img")[0]){
+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 _3b;
+if((_3b=find_in_array("flag",this.env.coltypes))>=0){
+this.set_env("flagged_col",_3b+1);
+}
+}
+if(this.env.flagged_col&&(row.flagged_icon=row.obj.getElementsByTagName("td")[this.env.flagged_col].getElementsByTagName("img")[0])){
+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.triggerEvent("insertrow",{uid:uid,row:row});
+};
+this.init_messageform=function(){
+if(!this.gui_objects.messageform){
+return false;
+}
+var _3d=$("[name='_from']");
+var _3e=$("[name='_to']");
+var _3f=$("input[name='_subject']");
+var _40=$("[name='_message']").get(0);
+var _41=$("input[name='_is_html']").val()=="1";
+this.init_address_input_events(_3e);
+this.init_address_input_events($("[name='_cc']"));
+this.init_address_input_events($("[name='_bcc']"));
+if(_3d.attr("type")=="select-one"&&$("input[name='_draft_saveid']").val()==""&&!_41){
+this.change_identity(_3d[0]);
+}
+if(_3e.val()==""){
+_3e.focus();
+}else{
+if(_3f.val()==""){
+_3f.focus();
+}else{
+if(_40&&!_41){
+_40.focus();
+}
+}
+}
+this.compose_field_hash(true);
+this.auto_save_start();
+};
+this.init_address_input_events=function(obj){
+var _43=function(e){
+return _1.ksearch_keypress(e,this);
+};
+obj.bind((bw.safari||bw.ie?"keydown":"keypress"),_43);
+obj.attr("autocomplete","off");
+};
+this.command=function(_45,_46,obj){
+if(obj&&obj.blur){
+obj.blur();
+}
+if(this.busy){
+return false;
+}
+if(!this.commands[_45]){
+if(this.env.framed&&parent.rcmail&&parent.rcmail.command){
+parent.rcmail.command(_45,_46);
+}
+return false;
+}
+if(this.task=="mail"&&this.env.action=="compose"&&(_45=="list"||_45=="mail"||_45=="addressbook"||_45=="settings")){
+if(this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning"))){
+return false;
+}
+}
+if(typeof this.command_handlers[_45]=="function"){
+var ret=this.command_handlers[_45](_46,obj);
+return ret!==null?ret:(obj?false:true);
+}else{
+if(typeof this.command_handlers[_45]=="string"){
+var ret=window[this.command_handlers[_45]](_46,obj);
+return ret!==null?ret:(obj?false:true);
+}
+}
+var _49=this.triggerEvent("before"+_45,_46);
+if(typeof _49!="undefined"){
+if(_49===false){
+return false;
+}else{
+_46=_49;
+}
+}
+switch(_45){
+case "login":
+if(this.gui_objects.loginform){
+this.gui_objects.loginform.submit();
+}
+break;
+case "mail":
+case "addressbook":
+case "settings":
+case "logout":
+this.switch_task(_45);
+break;
+case "permaurl":
+if(obj&&obj.href&&obj.target){
+return true;
+}else{
+if(this.env.permaurl){
+parent.location.href=this.env.permaurl;
+}
+}
+break;
+case "open":
+var uid;
+if(uid=this.get_single_uid()){
+obj.href="?_task="+this.env.task+"&_action=show&_mbox="+urlencode(this.env.mailbox)+"&_uid="+uid;
+return true;
+}
+break;
+case "list":
+if(this.task=="mail"){
+if(this.env.search_request<0||(_46!=""&&(this.env.search_request&&_46!=this.env.mailbox))){
+this.reset_qsearch();
+}
+this.list_mailbox(_46);
+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&&_46!=this.env.source)){
+this.reset_qsearch();
+}
+this.list_contacts(_46);
+this.enable_command("add",(this.env.address_sources&&!this.env.address_sources[_46].readonly));
+}
+}
+break;
+case "load-headers":
+this.load_headers(obj);
+break;
+case "sort":
+var _4b,_4c=_46;
+if(this.env.sort_col==_4c){
+_4b=this.env.sort_order=="ASC"?"DESC":"ASC";
+}else{
+_4b="ASC";
+}
+$("#rcm"+this.env.sort_col).removeClass("sorted"+(this.env.sort_order.toUpperCase()));
+$("#rcm"+_4c).addClass("sorted"+_4b);
+this.env.sort_col=_4c;
+this.env.sort_order=_4b;
+this.list_mailbox("","",_4c+"_"+_4b);
+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=_46?_46: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"&&_46){
+this.load_identity(_46,"edit-identity");
+}else{
+if(this.task=="mail"&&(cid=this.get_single_uid())){
+var url=(this.env.mailbox==this.env.drafts_mailbox)?"_draft_uid=":"_uid=";
+this.goto_url("compose",url+cid+"&_mbox="+urlencode(this.env.mailbox),true);
+}
+}
+}
+break;
+case "save-identity":
+case "save":
+if(this.gui_objects.editform){
+var _4f=$("input[name='_pagesize']");
+var _50=$("input[name='_name']");
+var _51=$("input[name='_email']");
+if(_4f.length&&isNaN(parseInt(_4f.val()))){
+alert(this.get_label("nopagesizewarning"));
+_4f.focus();
+break;
+}else{
+if(_50.length&&_50.val()==""){
+alert(this.get_label("nonamewarning"));
+_50.focus();
+break;
+}else{
+if(_51.length&&!rcube_check_email(_51.val())){
+alert(this.get_label("noemailwarning"));
+_51.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(_46);
+}else{
+if(this.task=="addressbook"&&this.drag_active){
+this.copy_contact(null,_46);
+}
+}
+break;
+case "mark":
+if(_46){
+this.mark_message(_46);
+}
+break;
+case "toggle_status":
+if(_46&&!_46._row){
+break;
+}
+var uid;
+var _52="read";
+if(_46._row.uid){
+uid=_46._row.uid;
+if(this.message_list.rows[uid].deleted){
+_52="undelete";
+}else{
+if(!this.message_list.rows[uid].unread){
+_52="unread";
+}
+}
+}
+this.mark_message(_52,uid);
+break;
+case "toggle_flag":
+if(_46&&!_46._row){
+break;
+}
+var uid;
+var _52="flagged";
+if(_46._row.uid){
+uid=_46._row.uid;
+if(this.message_list.rows[uid].flagged){
+_52="unflagged";
+}
+}
+this.mark_message(_52,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 _53="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+_46.part;
+if(this.env.uid&&_46.mimetype&&find_in_array(_46.mimetype,this.mimetypes)>=0){
+if(_46.mimetype=="text/html"){
+_53+="&_safe=1";
+}
+this.attachment_win=window.open(this.env.comm_path+"&_action=get&"+_53+"&_frame=1","rcubemailattachment");
+if(this.attachment_win){
+window.setTimeout(function(){
+_1.attachment_win.focus();
+},10);
+break;
+}
+}
+this.goto_url("get",_53+"&_download=1",false);
+break;
+case "select-all":
+if(_46=="invert"){
+this.message_list.invert_selection();
+}else{
+this.message_list.select_all(_46);
+}
+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(_46){
+url+="&_to="+urlencode(_46);
+}
+}
+}else{
+if(this.task=="addressbook"){
+if(_46&&_46.indexOf("@")>0){
+url=this.get_task_url("mail",url);
+this.redirect(url+"&_to="+urlencode(_46));
+break;
+}
+var _54=new Array();
+if(_46){
+_54[_54.length]=_46;
+}else{
+if(this.contact_list){
+var _55=this.contact_list.get_selection();
+for(var n=0;n<_55.length;n++){
+_54[_54.length]=_55[n];
+}
+}
+}
+if(_54.length){
+this.http_request("mailto","_cid="+urlencode(_54.join(","))+"&_source="+urlencode(this.env.source),true);
+}
+break;
+}
+}
+url=url.replace(/&_framed=1/,"");
+this.redirect(url);
+break;
+case "spellcheck":
+if(window.tinyMCE&&tinyMCE.get(this.env.composebody)){
+tinyMCE.execCommand("mceSpellCheck",true);
+}else{
+if(this.env.spellcheck&&this.env.spellcheck.spellCheck&&this.spellcheck_ready){
+this.env.spellcheck.spellCheck();
+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 _57=this.gui_objects.messageform;
+_57.target="savetarget";
+_57._draft.value="1";
+_57.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 _57=this.gui_objects.messageform;
+_57.target="savetarget";
+_57._draft.value="";
+_57.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(_46);
+break;
+case "remove-attachment":
+this.remove_attachment(_46);
+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)+(_45=="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="+uid+"&_mbox="+urlencode(this.env.mailbox));
+if(this.sourcewin){
+window.setTimeout(function(){
+_1.sourcewin.focus();
+},20);
+}
+}
+break;
+case "download":
+var uid;
+if(uid=this.get_single_uid()){
+this.goto_url("viewsource","&_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+"&_save=1");
+}
+break;
+case "add-contact":
+this.add_contact(_46);
+break;
+case "search":
+if(!_46&&this.gui_objects.qsearchbox){
+_46=this.gui_objects.qsearchbox.value;
+}
+if(_46){
+this.qsearch(_46);
+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 _59=document.getElementById("rcmimportfile");
+if(_59&&!_59.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 _5a=(this.env.source?"_source="+urlencode(this.env.source)+"&":"");
+if(this.env.search_request){
+_5a+="_search="+this.env.search_request;
+}
+this.goto_url("export",_5a);
+}
+break;
+case "collapse-folder":
+if(_46){
+this.collapse_folder(_46);
+}
+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(_46);
+break;
+case "unsubscribe":
+this.unsubscribe_folder(_46);
+break;
+case "create-folder":
+this.create_folder(_46);
+break;
+case "rename-folder":
+this.rename_folder(_46);
+break;
+case "delete-folder":
+this.delete_folder(_46);
+break;
+}
+this.triggerEvent("after"+_45,_46);
+return obj?false:true;
+};
+this.enable_command=function(){
+var _5b=arguments;
+if(!_5b.length){
+return -1;
+}
+var _5c;
+var _5d=_5b[_5b.length-1];
+for(var n=0;n<_5b.length-1;n++){
+_5c=_5b[n];
+this.commands[_5c]=_5d;
+this.set_button(_5c,(_5d?"act":"pas"));
+}
+return true;
+};
+this.set_busy=function(a,_60){
+if(a&&_60){
+var msg=this.get_label(_60);
+if(msg==_60){
+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(_62,_63){
+if(_63&&this.labels[_63+"."+_62]){
+return this.labels[_63+"."+_62];
+}else{
+if(this.labels[_62]){
+return this.labels[_62];
+}else{
+return _62;
+}
+}
+};
+this.gettext=this.get_label;
+this.switch_task=function(_64){
+if(this.task===_64&&_64!="mail"){
+return;
+}
+var url=this.get_task_url(_64);
+if(_64=="mail"){
+url+="&_mbox=INBOX";
+}
+this.redirect(url);
+};
+this.get_task_url=function(_66,url){
+if(!url){
+url=this.env.comm_path;
+}
+return url.replace(/_task=[a-z]+/,"_task="+_66);
+};
+this.request_timed_out=function(){
+this.set_busy(false);
+this.display_message("Request timed out!","error");
+};
+this.reload=function(_68){
+if(this.env.framed&&parent.rcmail){
+parent.rcmail.reload(_68);
+}else{
+if(_68){
+window.setTimeout(function(){
+rcmail.reload();
+},_68);
+}else{
+if(window.location){
+location.href=this.env.comm_path;
+}
+}
+}
+};
+this.doc_mouse_up=function(e){
+var _6a,_6b,li;
+if(this.message_list){
+if(!rcube_mouse_is_over(e,this.message_list.list)){
+this.message_list.blur();
+}
+_6b=this.message_list;
+_6a=this.env.mailboxes;
+}else{
+if(this.contact_list){
+if(!rcube_mouse_is_over(e,this.contact_list.list)){
+this.contact_list.blur();
+}
+_6b=this.contact_list;
+_6a=this.env.address_sources;
+}else{
+if(this.ksearch_value){
+this.ksearch_blur();
+}
+}
+}
+if(this.drag_active&&_6a&&this.env.last_folder_target){
+$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget");
+this.command("moveto",_6a[this.env.last_folder_target].id);
+this.env.last_folder_target=null;
+_6b.draglayer.hide();
+}
+if(this.buttons_sel){
+for(var id in this.buttons_sel){
+if(typeof id!="function"){
+this.button_out(this.buttons_sel[id],id);
+}
+}
+this.buttons_sel={};
+}
+};
+this.drag_start=function(_6e){
+var _6f=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&&_6f){
+this.initialBodyScrollTop=bw.ie?0:window.pageYOffset;
+this.initialListScrollTop=this.gui_objects.folderlist.parentNode.scrollTop;
+var li,pos,_6e,_72;
+_6e=$(this.gui_objects.folderlist);
+pos=_6e.offset();
+this.env.folderlist_coords={x1:pos.left,y1:pos.top,x2:pos.left+_6e.width(),y2:pos.top+_6e.height()};
+this.env.folder_coords=new Array();
+for(var k in _6f){
+if(li=this.get_folder_li(k)){
+if(_72=li.firstChild.offsetHeight){
+pos=$(li.firstChild).offset();
+this.env.folder_coords[k]={x1:pos.left,y1:pos.top,x2:pos.left+li.firstChild.offsetWidth,y2:pos.top+_72,on:0};
+}
+}
+}
+}
+};
+this.drag_end=function(e){
+this.drag_active=false;
+this.env.last_folder_target=null;
+if(this.folder_auto_timer){
+window.clearTimeout(this.folder_auto_timer);
+this.folder_auto_timer=null;
+this.folder_auto_expand=null;
+}
+if(this.gui_objects.folderlist&&this.env.folder_coords){
+for(var k in this.env.folder_coords){
+if(this.env.folder_coords[k].on){
+$(this.get_folder_li(k)).removeClass("droptarget");
+}
+}
+}
+};
+this.drag_move=function(e){
+if(this.gui_objects.folderlist&&this.env.folder_coords){
+var _77=bw.ie?-document.documentElement.scrollTop:this.initialBodyScrollTop;
+var _78=this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop;
+var _79=-_78-_77;
+var li,div,pos,_7d;
+_7d=rcube_event.get_mouse_pos(e);
+pos=this.env.folderlist_coords;
+_7d.y+=_79;
+if(_7d.x<pos.x1||_7d.x>=pos.x2||_7d.y<pos.y1||_7d.y>=pos.y2){
+if(this.env.last_folder_target){
+$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget");
+this.env.folder_coords[this.env.last_folder_target].on=0;
+this.env.last_folder_target=null;
+}
+return;
+}
+for(var k in this.env.folder_coords){
+pos=this.env.folder_coords[k];
+if(_7d.x>=pos.x1&&_7d.x<pos.x2&&_7d.y>=pos.y1&&_7d.y<pos.y2&&this.check_droptarget(k)){
+li=this.get_folder_li(k);
+div=$(li.getElementsByTagName("div")[0]);
+if(div.hasClass("collapsed")){
+if(this.folder_auto_timer){
+window.clearTimeout(this.folder_auto_timer);
+}
+this.folder_auto_expand=k;
+this.folder_auto_timer=window.setTimeout(function(){
+rcmail.command("collapse-folder",rcmail.folder_auto_expand);
+rcmail.drag_start(null);
+},1000);
+}else{
+if(this.folder_auto_timer){
+window.clearTimeout(this.folder_auto_timer);
+this.folder_auto_timer=null;
+this.folder_auto_expand=null;
+}
+}
+$(li).addClass("droptarget");
+this.env.last_folder_target=k;
+this.env.folder_coords[k].on=1;
+}else{
+if(pos.on){
+$(this.get_folder_li(k)).removeClass("droptarget");
+this.env.folder_coords[k].on=0;
+}
+}
+}
+}
+};
+this.collapse_folder=function(id){
+var div;
+if((li=this.get_folder_li(id))&&(div=$(li.getElementsByTagName("div")[0]))&&(div.hasClass("collapsed")||div.hasClass("expanded"))){
+var ul=$(li.getElementsByTagName("ul")[0]);
+if(div.hasClass("collapsed")){
+ul.show();
+div.removeClass("collapsed").addClass("expanded");
+var reg=new RegExp("&"+urlencode(id)+"&");
+this.set_env("collapsed_folders",this.env.collapsed_folders.replace(reg,""));
+}else{
+ul.hide();
+div.removeClass("expanded").addClass("collapsed");
+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();
+}
+}
+return rcube_event.get_button(e)==2?true:rcube_event.cancel(e);
+};
+this.msglist_select=function(_84){
+if(this.preview_timer){
+clearTimeout(this.preview_timer);
+}
+var _85=_84.selection.length==1;
+if(this.env.mailbox==this.env.drafts_mailbox){
+this.enable_command("reply","reply-all","forward",false);
+this.enable_command("show","print","open","edit","download","viewsource",_85);
+this.enable_command("delete","moveto","mark",(_84.selection.length>0?true:false));
+}else{
+this.enable_command("show","reply","reply-all","forward","print","edit","open","download","viewsource",_85);
+this.enable_command("delete","moveto","mark",(_84.selection.length>0?true:false));
+}
+if(_85&&this.env.contentframe&&!_84.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(_86){
+if(this.preview_timer){
+clearTimeout(this.preview_timer);
+}
+var uid=_86.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(_88){
+if(_88.key_pressed==_88.ENTER_KEY){
+this.command("show");
+}else{
+if(_88.key_pressed==_88.DELETE_KEY){
+this.command("delete");
+}else{
+if(_88.key_pressed==_88.BACKSPACE_KEY){
+this.command("delete");
+}else{
+_88.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,_8c,_8d){
+if(!id){
+return;
+}
+var _8e="";
+var _8f=_8d?"preview":"show";
+var _90=window;
+if(_8d&&this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_90=window.frames[this.env.contentframe];
+_8e="&_framed=1";
+}
+if(_8c){
+_8e="&_safe=1";
+}
+if(this.env.search_request){
+_8e+="&_search="+this.env.search_request;
+}
+var url="&_action="+_8f+"&_uid="+id+"&_mbox="+urlencode(this.env.mailbox)+_8e;
+if(_8f=="preview"&&String(_90.location.href).indexOf(url)>=0){
+this.show_contentframe(true);
+}else{
+this.set_busy(true,"loading");
+_90.location.href=this.env.comm_path+url;
+if(_8f=="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(_92){
+var frm;
+if(this.env.contentframe&&(frm=$("#"+this.env.contentframe))&&frm.length){
+if(!_92&&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[_92?"show":"hide"]();
+}
+}
+}
+if(!_92&&this.busy){
+this.set_busy(false);
+}
+};
+this.list_page=function(_94){
+if(_94=="next"){
+_94=this.env.current_page+1;
+}
+if(_94=="last"){
+_94=this.env.pagecount;
+}
+if(_94=="prev"&&this.env.current_page>1){
+_94=this.env.current_page-1;
+}
+if(_94=="first"&&this.env.current_page>1){
+_94=1;
+}
+if(_94>0&&_94<=this.env.pagecount){
+this.env.current_page=_94;
+if(this.task=="mail"){
+this.list_mailbox(this.env.mailbox,_94);
+}else{
+if(this.task=="addressbook"){
+this.list_contacts(this.env.source,_94);
+}
+}
+}
+};
+this.filter_mailbox=function(_95){
+var _96;
+if(this.gui_objects.qsearchbox){
+_96=this.gui_objects.qsearchbox.value;
+}
+this.message_list.clear();
+this.env.current_page=1;
+this.set_busy(true,"searching");
+this.http_request("search","_filter="+_95+(_96?"&_q="+urlencode(_96):"")+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):""),true);
+};
+this.list_mailbox=function(_97,_98,_99){
+var _9a="";
+var _9b=window;
+if(!_97){
+_97=this.env.mailbox;
+}
+if(_99){
+_9a+="&_sort="+_99;
+}
+if(this.env.search_request){
+_9a+="&_search="+this.env.search_request;
+}
+if(!_98&&this.env.mailbox!=_97){
+_98=1;
+this.env.current_page=_98;
+this.show_contentframe(false);
+}
+if(_97!=this.env.mailbox||(_97==this.env.mailbox&&!_98&&!_99)){
+_9a+="&_refresh=1";
+}
+this.last_selected=0;
+if(this.message_list){
+this.message_list.clear_selection();
+}
+this.select_folder(_97,this.env.mailbox);
+this.env.mailbox=_97;
+if(this.gui_objects.messagelist){
+this.list_mailbox_remote(_97,_98,_9a);
+return;
+}
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_9b=window.frames[this.env.contentframe];
+_9a+="&_framed=1";
+}
+if(_97){
+this.set_busy(true,"loading");
+_9b.location.href=this.env.comm_path+"&_mbox="+urlencode(_97)+(_98?"&_page="+_98:"")+_9a;
+}
+};
+this.list_mailbox_remote=function(_9c,_9d,_9e){
+this.message_list.clear();
+var url="_mbox="+urlencode(_9c)+(_9d?"&_page="+_9d:"");
+this.set_busy(true,"loading");
+this.http_request("list",url+_9e,true);
+};
+this.expunge_mailbox=function(_a0){
+var _a1=false;
+var _a2="";
+if(_a0==this.env.mailbox){
+_a1=true;
+this.set_busy(true,"loading");
+_a2="&_reload=1";
+}
+var url="_mbox="+urlencode(_a0);
+this.http_post("expunge",url+_a2,_a1);
+};
+this.purge_mailbox=function(_a4){
+var _a5=false;
+var _a6="";
+if(!confirm(this.get_label("purgefolderconfirm"))){
+return false;
+}
+if(_a4==this.env.mailbox){
+_a5=true;
+this.set_busy(true,"loading");
+_a6="&_reload=1";
+}
+var url="_mbox="+urlencode(_a4);
+this.http_post("purge",url+_a6,_a5);
+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 _a9;
+var _aa=this.message_list.rows;
+if(!_aa[uid]){
+return false;
+}
+if(_aa[uid].deleted&&this.env.deletedicon){
+_a9=this.env.deletedicon;
+}else{
+if(_aa[uid].replied&&this.env.repliedicon){
+if(_aa[uid].forwarded&&this.env.forwardedrepliedicon){
+_a9=this.env.forwardedrepliedicon;
+}else{
+_a9=this.env.repliedicon;
+}
+}else{
+if(_aa[uid].forwarded&&this.env.forwardedicon){
+_a9=this.env.forwardedicon;
+}else{
+if(_aa[uid].unread&&this.env.unreadicon){
+_a9=this.env.unreadicon;
+}else{
+if(this.env.messageicon){
+_a9=this.env.messageicon;
+}
+}
+}
+}
+}
+if(_a9&&_aa[uid].icon){
+_aa[uid].icon.src=_a9;
+}
+_a9="";
+if(_aa[uid].flagged&&this.env.flaggedicon){
+_a9=this.env.flaggedicon;
+}else{
+if(!_aa[uid].flagged&&this.env.unflaggedicon){
+_a9=this.env.unflaggedicon;
+}
+}
+if(_aa[uid].flagged_icon&&_a9){
+_aa[uid].flagged_icon.src=_a9;
+}
+};
+this.set_message_status=function(uid,_ac,_ad){
+var _ae=this.message_list.rows;
+if(!_ae[uid]){
+return false;
+}
+if(_ac=="unread"){
+_ae[uid].unread=_ad;
+}else{
+if(_ac=="deleted"){
+_ae[uid].deleted=_ad;
+}else{
+if(_ac=="replied"){
+_ae[uid].replied=_ad;
+}else{
+if(_ac=="forwarded"){
+_ae[uid].forwarded=_ad;
+}else{
+if(_ac=="flagged"){
+_ae[uid].flagged=_ad;
+}
+}
+}
+}
+}
+this.env.messages[uid]=_ae[uid];
+};
+this.set_message=function(uid,_b0,_b1){
+var _b2=this.message_list.rows;
+if(!_b2[uid]){
+return false;
+}
+if(_b0){
+this.set_message_status(uid,_b0,_b1);
+}
+var _b3=$(_b2[uid].obj);
+if(_b2[uid].unread&&_b2[uid].classname.indexOf("unread")<0){
+_b2[uid].classname+=" unread";
+_b3.addClass("unread");
+}else{
+if(!_b2[uid].unread&&_b2[uid].classname.indexOf("unread")>=0){
+_b2[uid].classname=_b2[uid].classname.replace(/\s*unread/,"");
+_b3.removeClass("unread");
+}
+}
+if(_b2[uid].deleted&&_b2[uid].classname.indexOf("deleted")<0){
+_b2[uid].classname+=" deleted";
+_b3.addClass("deleted");
+}else{
+if(!_b2[uid].deleted&&_b2[uid].classname.indexOf("deleted")>=0){
+_b2[uid].classname=_b2[uid].classname.replace(/\s*deleted/,"");
+_b3.removeClass("deleted");
+}
+}
+if(_b2[uid].flagged&&_b2[uid].classname.indexOf("flagged")<0){
+_b2[uid].classname+=" flagged";
+_b3.addClass("flagged");
+}else{
+if(!_b2[uid].flagged&&_b2[uid].classname.indexOf("flagged")>=0){
+_b2[uid].classname=_b2[uid].classname.replace(/\s*flagged/,"");
+_b3.removeClass("flagged");
+}
+}
+this.set_message_icon(uid);
+};
+this.move_messages=function(_b4){
+if(!_b4||_b4==this.env.mailbox||(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){
+return;
+}
+var _b5=false;
+var _b6="&_target_mbox="+urlencode(_b4)+"&_from="+(this.env.action?this.env.action:"");
+if(this.env.action=="show"){
+_b5=true;
+this.set_busy(true,"movingmessage");
+}else{
+this.show_contentframe(false);
+}
+this.enable_command("reply","reply-all","forward","delete","mark","print","open","edit","viewsource","download",false);
+this._with_selected_messages("moveto",_b5,_b6);
+};
+this.delete_messages=function(){
+var _b7=this.message_list?this.message_list.get_selection():new Array();
+if(!this.env.uid&&!_b7.length){
+return;
+}
+if(this.env.flag_for_deletion){
+this.mark_message("delete");
+}else{
+if(!this.env.trash_mailbox||String(this.env.mailbox).toLowerCase()==String(this.env.trash_mailbox).toLowerCase()){
+this.permanently_remove_messages();
+}else{
+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);
+}
+}
+}
+};
+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:""));
+};
+this._with_selected_messages=function(_b8,_b9,_ba,_bb){
+var _bc=new Array();
+if(this.env.uid){
+_bc[0]=this.env.uid;
+}else{
+var _bd=this.message_list.get_selection();
+var _be=this.message_list.rows;
+var id;
+for(var n=0;n<_bd.length;n++){
+id=_bd[n];
+_bc[_bc.length]=id;
+this.message_list.remove_row(id,(this.env.display_next&&n==_bd.length-1));
+}
+if(!this.env.display_next){
+this.message_list.clear_selection();
+}
+}
+if(this.env.search_request){
+_ba+="&_search="+this.env.search_request;
+}
+if(this.env.display_next&&this.env.next_uid){
+_ba+="&_next_uid="+this.env.next_uid;
+}
+this.http_post(_b8,"_uid="+_bc.join(",")+"&_mbox="+urlencode(this.env.mailbox)+_ba,_b9);
+};
+this.mark_message=function(_c1,uid){
+var _c3=new Array();
+var _c4=new Array();
+var _c5=this.message_list?this.message_list.get_selection():new Array();
+if(uid){
+_c3[0]=uid;
+}else{
+if(this.env.uid){
+_c3[0]=this.env.uid;
+}else{
+if(this.message_list){
+for(var n=0;n<_c5.length;n++){
+_c3[_c3.length]=_c5[n];
+}
+}
+}
+}
+if(!this.message_list){
+_c4=_c3;
+}else{
+for(var id,n=0;n<_c3.length;n++){
+id=_c3[n];
+if((_c1=="read"&&this.message_list.rows[id].unread)||(_c1=="unread"&&!this.message_list.rows[id].unread)||(_c1=="delete"&&!this.message_list.rows[id].deleted)||(_c1=="undelete"&&this.message_list.rows[id].deleted)||(_c1=="flagged"&&!this.message_list.rows[id].flagged)||(_c1=="unflagged"&&this.message_list.rows[id].flagged)){
+_c4[_c4.length]=id;
+}
+}
+}
+if(!_c4.length){
+return;
+}
+switch(_c1){
+case "read":
+case "unread":
+this.toggle_read_status(_c1,_c4);
+break;
+case "delete":
+case "undelete":
+this.toggle_delete_status(_c4);
+break;
+case "flagged":
+case "unflagged":
+this.toggle_flagged_status(_c1,_c3);
+break;
+}
+};
+this.toggle_read_status=function(_c8,_c9){
+for(var i=0;i<_c9.length;i++){
+this.set_message(_c9[i],"unread",(_c8=="unread"?true:false));
+}
+this.http_post("mark","_uid="+_c9.join(",")+"&_flag="+_c8);
+};
+this.toggle_flagged_status=function(_cb,_cc){
+for(var i=0;i<_cc.length;i++){
+this.set_message(_cc[i],"flagged",(_cb=="flagged"?true:false));
+}
+this.http_post("mark","_uid="+_cc.join(",")+"&_flag="+_cb);
+};
+this.toggle_delete_status=function(_ce){
+var _cf=this.message_list?this.message_list.rows:new Array();
+if(_ce.length==1){
+if(!_cf.length||(_cf[_ce[0]]&&!_cf[_ce[0]].deleted)){
+this.flag_as_deleted(_ce);
+}else{
+this.flag_as_undeleted(_ce);
+}
+return true;
+}
+var _d0=true;
+for(var i=0;i<_ce.length;i++){
+uid=_ce[i];
+if(_cf[uid]){
+if(!_cf[uid].deleted){
+_d0=false;
+break;
+}
+}
+}
+if(_d0){
+this.flag_as_undeleted(_ce);
+}else{
+this.flag_as_deleted(_ce);
+}
+return true;
+};
+this.flag_as_undeleted=function(_d2){
+for(var i=0;i<_d2.length;i++){
+this.set_message(_d2[i],"deleted",false);
+}
+this.http_post("mark","_uid="+_d2.join(",")+"&_flag=undelete");
+return true;
+};
+this.flag_as_deleted=function(_d4){
+var _d5="";
+var _d6=new Array();
+var _d7=this.message_list?this.message_list.rows:new Array();
+for(var i=0;i<_d4.length;i++){
+uid=_d4[i];
+if(_d7[uid]){
+if(_d7[uid].unread){
+_d6[_d6.length]=uid;
+}
+if(this.env.skip_deleted){
+this.message_list.remove_row(uid,(this.env.display_next&&i==this.message_list.selection.length-1));
+}else{
+this.set_message(uid,"deleted",true);
+}
+}
+}
+if(this.env.skip_deleted&&!this.env.display_next&&this.message_list){
+this.message_list.clear_selection();
+}
+_d5="&_from="+(this.env.action?this.env.action:"");
+if(_d6.length){
+_d5+="&_ruid="+_d6.join(",");
+}
+if(this.env.skip_deleted){
+if(this.env.search_request){
+_d5+="&_search="+this.env.search_request;
+}
+if(this.env.display_next&&this.env.next_uid){
+_d5+="&_next_uid="+this.env.next_uid;
+}
+}
+this.http_post("mark","_uid="+_d4.join(",")+"&_flag=delete"+_d5);
+return true;
+};
+this.flag_deleted_as_read=function(_d9){
+var _da;
+var _db=this.message_list?this.message_list.rows:new Array();
+var str=String(_d9);
+var _dd=new Array();
+_dd=str.split(",");
+for(var uid,i=0;i<_dd.length;i++){
+uid=_dd[i];
+if(_db[uid]){
+this.set_message(uid,"unread",false);
+}
+}
+};
+this.login_user_keyup=function(e){
+var key=rcube_event.get_keycode(e);
+var _e2=$("#rcmloginpwd");
+if(key==13&&_e2.length&&!_e2.val()){
+_e2.focus();
+return rcube_event.cancel(e);
+}
+return true;
+};
+this.check_compose_input=function(){
+var _e3=$("[name='_to']");
+var _e4=$("[name='_cc']");
+var _e5=$("[name='_bcc']");
+var _e6=$("[name='_from']");
+var _e7=$("[name='_subject']");
+var _e8=$("[name='_message']");
+if(_e6.attr("type")=="text"&&!rcube_check_email(_e6.val(),true)){
+alert(this.get_label("nosenderwarning"));
+_e6.focus();
+return false;
+}
+var _e9=_e3.val()?_e3.val():(_e4.val()?_e4.val():_e5.val());
+if(!rcube_check_email(_e9.replace(/^\s+/,"").replace(/[\s,;]+$/,""),true)){
+alert(this.get_label("norecipientwarning"));
+_e3.focus();
+return false;
+}
+for(var key in this.env.attachments){
+if(typeof this.env.attachments[key]=="object"&&!this.env.attachments[key].complete){
+alert(this.get_label("notuploadedwarning"));
+return false;
+}
+}
+if(_e7.val()==""){
+var _eb=prompt(this.get_label("nosubjectwarning"),this.get_label("nosubject"));
+if(!_eb&&_eb!==""){
+_e7.focus();
+return false;
+}else{
+_e7.val((_eb?_eb:this.get_label("nosubject")));
+}
+}
+if((!window.tinyMCE||!tinyMCE.get(this.env.composebody))&&_e8.val()==""&&!confirm(this.get_label("nobodywarning"))){
+_e8.focus();
+return false;
+}else{
+if(window.tinyMCE&&tinyMCE.get(this.env.composebody)&&!tinyMCE.get(this.env.composebody).getContent()&&!confirm(this.get_label("nobodywarning"))){
+tinyMCE.get(this.env.composebody).focus();
+return false;
+}
+}
+this.stop_spellchecking();
+if(window.tinyMCE&&tinyMCE.get(this.env.composebody)){
+tinyMCE.triggerSave();
+}
+return true;
+};
+this.stop_spellchecking=function(){
+if(this.env.spellcheck&&!this.spellcheck_ready){
+$(this.env.spellcheck.spell_span).trigger("click");
+this.set_spellcheck_state("ready");
+}
+};
+this.display_spellcheck_controls=function(vis){
+if(this.env.spellcheck){
+if(!vis){
+this.stop_spellchecking();
+}
+$(this.env.spellcheck.spell_container).css("visibility",vis?"visible":"hidden");
+}
+};
+this.set_spellcheck_state=function(s){
+this.spellcheck_ready=(s=="ready"||s=="no_error_found");
+this.enable_command("spellcheck",this.spellcheck_ready);
+};
+this.set_draft_id=function(id){
+$("input[name='_draft_saveid']").val(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(_ef){
+var _f0=$("[name='_to']").val();
+var _f1=$("[name='_cc']").val();
+var _f2=$("[name='_bcc']").val();
+var _f3=$("[name='_subject']").val();
+var str="";
+if(_f0){
+str+=_f0+":";
+}
+if(_f1){
+str+=_f1+":";
+}
+if(_f2){
+str+=_f2+":";
+}
+if(_f3){
+str+=_f3+":";
+}
+var _f5=tinyMCE.get(this.env.composebody);
+if(_f5){
+str+=_f5.getContent();
+}else{
+str+=$("[name='_message']").val();
+}
+if(this.env.attachments){
+for(var _f6 in this.env.attachments){
+str+=_f6;
+}
+}
+if(_ef){
+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 _f9=$("[name='_message']");
+var _fa=_f9.val();
+var _fb=($("input[name='_is_html']").val()=="1");
+var sig,p,len;
+if(!this.env.identity){
+this.env.identity=id;
+}
+if(!_fb){
+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=_fa.lastIndexOf(sig);
+if(p>=0){
+_fa=_fa.substring(0,p-1)+_fa.substring(p+sig.length,_fa.length);
+}
+}
+_fa=_fa.replace(/[\r\n]+$/,"");
+len=_fa.length;
+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;
+}
+_fa+="\n\n"+sig;
+if(len){
+len+=1;
+}
+}
+}else{
+var _ff=tinyMCE.get(this.env.composebody);
+if(this.env.signatures){
+var _100=_ff.dom.get("_rc_sig");
+var _101="";
+var _102=true;
+if(!_100){
+if(bw.ie){
+_ff.getBody().appendChild(_ff.getDoc().createElement("br"));
+}
+_100=_ff.getDoc().createElement("div");
+_100.setAttribute("id","_rc_sig");
+_ff.getBody().appendChild(_100);
+}
+if(this.env.signatures[id]){
+_101=this.env.signatures[id]["text"];
+_102=this.env.signatures[id]["is_html"];
+if(_101){
+if(_102&&this.env.signatures[id]["plain_text"].indexOf("-- ")!=0){
+_101="<p>-- </p>"+_101;
+}else{
+if(!_102&&_101.indexOf("-- ")!=0){
+_101="-- \n"+_101;
+}
+}
+}
+}
+if(_102){
+_100.innerHTML=_101;
+}else{
+_100.innerHTML="<pre>"+_101+"</pre>";
+}
+}
+}
+_f9.val(_fa);
+if(!_fb){
+this.set_caret_pos(_f9.get(0),len);
+}
+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=$(list).offset();
+elm.style.top=(pos.top+list.offsetHeight+10)+"px";
+elm.style.left=pos.left+"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(form){
+if(!form){
+return false;
+}
+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;
+}
+}
+if(send){
+var ts=new Date().getTime();
+var _10b="rcmupload"+ts;
+if(document.all){
+var html="<iframe name=\""+_10b+"\" src=\"program/blank.gif\" style=\"width:0;height:0;visibility:hidden;\"></iframe>";
+document.body.insertAdjacentHTML("BeforeEnd",html);
+}else{
+var _10d=document.createElement("iframe");
+_10d.name=_10b;
+_10d.style.border="none";
+_10d.style.width=0;
+_10d.style.height=0;
+_10d.style.visibility="hidden";
+document.body.appendChild(_10d);
+}
+var fr=document.getElementsByName(_10b)[0];
+$(fr).bind("load",{ts:ts},function(e){
+var _110="";
+try{
+if(this.contentDocument){
+var d=this.contentDocument;
+}else{
+if(this.contentWindow){
+var d=this.contentWindow.document;
+}
+}
+_110=d.childNodes[0].innerHTML;
+}
+catch(e){
+}
+if(!String(_110).match(/add2attachment/)&&(!bw.opera||(rcmail.env.uploadframe&&rcmail.env.uploadframe==e.data.ts))){
+rcmail.display_message(rcmail.get_label("fileuploaderror"),"error");
+rcmail.remove_from_attachment_list(e.data.ts);
+}
+if(bw.opera){
+rcmail.env.uploadframe=e.data.ts;
+}
+});
+form.target=_10b;
+form.action=this.env.comm_path+"&_action=upload&_uploadid="+ts;
+form.setAttribute("enctype","multipart/form-data");
+form.submit();
+this.show_attachment_form(false);
+var _112=this.get_label("uploading");
+if(this.env.loadingicon){
+_112="<img src=\""+this.env.loadingicon+"\" alt=\"\" />"+_112;
+}
+if(this.env.cancelicon){
+_112="<a title=\""+this.get_label("cancel")+"\" onclick=\"return rcmail.cancel_attachment_upload('"+ts+"', '"+_10b+"');\" href=\"#cancelupload\"><img src=\""+this.env.cancelicon+"\" alt=\"\" /></a>"+_112;
+}
+this.add2attachment_list(ts,{name:"",html:_112,complete:false});
+}
+this.gui_objects.attachmentform=form;
+return true;
+};
+this.add2attachment_list=function(name,att,_115){
+if(!this.gui_objects.attachmentlist){
+return false;
+}
+var li=$("<li>").attr("id",name).html(att.html);
+var _117;
+if(_115&&(_117=document.getElementById(_115))){
+li.replaceAll(_117);
+}else{
+li.appendTo(this.gui_objects.attachmentlist);
+}
+if(_115&&this.env.attachments[_115]){
+delete this.env.attachments[_115];
+}
+this.env.attachments[name]=att;
+return true;
+};
+this.remove_from_attachment_list=function(name){
+if(this.env.attachments[name]){
+delete this.env.attachments[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.env.attachments[name]){
+this.http_post("remove-attachment","_file="+urlencode(name));
+}
+return true;
+};
+this.cancel_attachment_upload=function(name,_11c){
+if(!name||!_11c){
+return false;
+}
+this.remove_from_attachment_list(name);
+$("iframe[name='"+_11c+"']").remove();
+return false;
+};
+this.add_contact=function(_11d){
+if(_11d){
+this.http_post("addcontact","_address="+_11d);
+}
+return true;
+};
+this.qsearch=function(_11e){
+if(_11e!=""){
+var _11f="";
+if(this.message_list){
+this.message_list.clear();
+if(this.env.search_mods){
+var _120=new Array();
+for(var n in this.env.search_mods){
+_120.push(n);
+}
+_11f+="&_headers="+_120.join(",");
+}
+}else{
+if(this.contact_list){
+this.contact_list.clear(true);
+this.show_contentframe(false);
+}
+}
+if(this.gui_objects.search_filter){
+_11f+="&_filter="+this.gui_objects.search_filter.value;
+}
+this.env.current_page=1;
+this.set_busy(true,"searching");
+this.http_request("search","_q="+urlencode(_11e)+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):"")+(this.env.source?"&_source="+urlencode(this.env.source):"")+(_11f?_11f:""),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 _126;
+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;
+_126=document.getElementById("rcmksearchSelected");
+if(!_126){
+_126=this.ksearch_pane.__ul.firstChild;
+}
+if(_126){
+this.ksearch_select(dir?_126.previousSibling:_126.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 _12b=$("#rcmksearchSelected");
+if(_12b[0]&&node){
+_12b.removeAttr("id").removeClass("selected");
+}
+if(node){
+$(node).attr("id","rcmksearchSelected").addClass("selected");
+this.ksearch_selected=node._rcm_id;
+}
+};
+this.insert_recipient=function(id){
+if(!this.env.contacts[id]||!this.ksearch_input){
+return;
+}
+var _12d=this.ksearch_input.value;
+var cpos=this.get_caret_pos(this.ksearch_input);
+var p=_12d.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 _132=this.env.contacts[id]+", ";
+this.ksearch_input.value=pre+_132+end;
+cpos=p+_132.length;
+if(this.ksearch_input.setSelectionRange){
+this.ksearch_input.setSelectionRange(cpos,cpos);
+}
+};
+this.ksearch_get_results=function(){
+var _133=this.ksearch_input?this.ksearch_input.value:null;
+if(_133===null){
+return;
+}
+if(this.ksearch_pane&&this.ksearch_pane.is(":visible")){
+this.ksearch_pane.hide();
+}
+var cpos=this.get_caret_pos(this.ksearch_input);
+var p=_133.lastIndexOf(",",cpos-1);
+var q=_133.substring(p+1,cpos);
+q=q.replace(/(^\s+|\s+$)/g,"");
+if(q==this.ksearch_value){
+return;
+}
+var _137=this.ksearch_value;
+this.ksearch_value=q;
+if(!q.length){
+return;
+}
+if(_137&&_137.length&&this.env.contacts&&!this.env.contacts.length&&q.indexOf(_137)==0){
+return;
+}
+this.display_message(this.get_label("searching"),"loading",true);
+this.http_post("autocomplete","_search="+urlencode(q));
+};
+this.ksearch_query_results=function(_138,_139){
+if(this.ksearch_value&&_139!=this.ksearch_value){
+return;
+}
+this.hide_message();
+this.env.contacts=_138?_138:[];
+this.ksearch_display_results(this.env.contacts);
+};
+this.ksearch_display_results=function(_13a){
+if(_13a.length&&this.ksearch_input){
+var p,ul,li;
+if(!this.ksearch_pane){
+ul=$("<ul>");
+this.ksearch_pane=$("<div>").attr("id","rcmKSearchpane").css({position:"absolute","z-index":30000}).append(ul).appendTo(document.body);
+this.ksearch_pane.__ul=ul[0];
+}
+ul=this.ksearch_pane.__ul;
+ul.innerHTML="";
+for(i=0;i<_13a.length;i++){
+li=document.createElement("LI");
+li.innerHTML=_13a[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).attr("id","rcmksearchSelected").addClass("selected");
+this.ksearch_selected=0;
+var pos=$(this.ksearch_input).offset();
+this.ksearch_pane.css({left:pos.left+"px",top:(pos.top+this.ksearch_input.offsetHeight)+"px"}).show();
+}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.hide();
+}
+};
+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,_143,_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 _146="";
+var _147=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]){
+_147=window.frames[this.env.contentframe];
+_146="&_framed=1";
+}
+if(this.env.search_request){
+_146+="&_search="+this.env.search_request;
+}
+this.set_busy(true,"loading");
+_147.location.href=this.env.comm_path+(src?"&_source="+urlencode(src):"")+(page?"&_page="+page:"")+_146;
+};
+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,_14c,_14d){
+var _14e="";
+var _14f=window;
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_14e="&_framed=1";
+_14f=window.frames[this.env.contentframe];
+this.show_contentframe(true);
+}else{
+if(_14d){
+return false;
+}
+}
+if(_14c&&(cid||_14c=="add")&&!this.drag_active){
+this.set_busy(true);
+_14f.location.href=this.env.comm_path+"&_action="+_14c+"&_source="+urlencode(this.env.source)+"&_cid="+urlencode(cid)+_14e;
+}
+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 _152=this.contact_list.get_selection();
+if(!(_152.length||this.env.cid)||!confirm(this.get_label("deletecontactconfirm"))){
+return;
+}
+var _153=new Array();
+var qs="";
+if(this.env.cid){
+_153[_153.length]=this.env.cid;
+}else{
+var id;
+for(var n=0;n<_152.length;n++){
+id=_152[n];
+_153[_153.length]=id;
+this.contact_list.remove_row(id,(n==_152.length-1));
+}
+if(_152.length==1){
+this.show_contentframe(false);
+}
+}
+if(this.env.search_request){
+qs+="&_search="+this.env.search_request;
+}
+this.http_post("delete","_cid="+urlencode(_153.join(","))+"&_source="+urlencode(this.env.source)+"&_from="+(this.env.action?this.env.action:"")+qs);
+return true;
+};
+this.update_contact_row=function(cid,_158,_159){
+var row;
+if(this.contact_list.rows[cid]&&(row=this.contact_list.rows[cid].obj)){
+for(var c=0;c<_158.length;c++){
+if(row.cells[c]){
+$(row.cells[c]).html(_158[c]);
+}
+}
+if(_159){
+row.id="rcmrow"+_159;
+this.contact_list.remove_row(cid);
+this.contact_list.init_row(row);
+this.contact_list.selection[0]=_159;
+row.style.display="";
+}
+return true;
+}
+return false;
+};
+this.add_contact_row=function(cid,cols,_15e){
+if(!this.gui_objects.contactslist||!this.gui_objects.contactslist.tBodies[0]){
+return false;
+}
+var _15f=this.gui_objects.contactslist.tBodies[0];
+var _160=_15f.rows.length;
+var even=_160%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.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 _169=row.obj.getElementsByTagName("a");
+if(_169[0]){
+_169[0].onclick=function(){
+p.rename_folder(row.id);
+return false;
+};
+}
+if(_169[1]){
+_169[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.section_select=function(list){
+var id=list.get_single_selection();
+if(id){
+var _16c="";
+var _16d=window;
+this.set_busy(true);
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_16c="&_framed=1";
+_16d=window.frames[this.env.contentframe];
+}
+_16d.location.href=this.env.comm_path+"&_action=edit-prefs&_section="+id+_16c;
+}
+return true;
+};
+this.identity_select=function(list){
+var id;
+if(id=list.get_single_selection()){
+this.load_identity(id,"edit-identity");
+}
+};
+this.load_identity=function(id,_171){
+if(_171=="edit-identity"&&(!id||id==this.env.iid)){
+return false;
+}
+var _172="";
+var _173=window;
+if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
+_172="&_framed=1";
+_173=window.frames[this.env.contentframe];
+document.getElementById(this.env.contentframe).style.visibility="inherit";
+}
+if(_171&&(id||_171=="add-identity")){
+this.set_busy(true);
+_173.location.href=this.env.comm_path+"&_action="+_171+"&_iid="+id+_172;
+}
+return true;
+};
+this.delete_identity=function(id){
+var _175=this.identity_list.get_selection();
+if(!(_175.length||this.env.iid)){
+return;
+}
+if(!id){
+id=this.env.iid?this.env.iid:_175[0];
+}
+this.goto_url("delete-identity","_iid="+id+"&_token="+this.env.request_token,true);
+return true;
+};
+this.focus_subscription=function(id){
+var row,_178;
+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]&&(_178=this.env.subscriptionrows[id][0])){
+if(this.check_droptarget(_178)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2]&&(_178!=this.env.folder.replace(reg,""))&&(!_178.match(new RegExp("^"+RegExp.escape(this.env.folder+this.env.delimiter))))){
+this.set_env("dstfolder",_178);
+$(row).addClass("droptarget");
+}
+}else{
+if(this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter)))){
+this.set_env("dstfolder",this.env.delimiter);
+$(this.subscription_list.frame).addClass("droptarget");
+}
+}
+}
+};
+this.unfocus_subscription=function(id){
+var row=$("#"+id);
+this.set_env("dstfolder",null);
+if(this.env.subscriptionrows[id]&&row[0]){
+row.removeClass("droptarget");
+}else{
+$(this.subscription_list.frame).removeClass("droptarget");
+}
+};
+this.subscription_select=function(list){
+var id,_17e;
+if((id=list.get_single_selection())&&this.env.subscriptionrows["rcmrow"+id]&&(_17e=this.env.subscriptionrows["rcmrow"+id][0])){
+this.set_env("folder",_17e);
+}else{
+this.set_env("folder",null);
+}
+if(this.gui_objects.createfolderhint){
+$(this.gui_objects.createfolderhint).html(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 _181=this.env.folder.replace(reg,"");
+var _182=this.env.dstfolder==this.env.delimiter?_181:this.env.dstfolder+this.env.delimiter+_181;
+this.set_busy(true,"foldermoving");
+this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.folder)+"&_folder_newname="+urlencode(_182),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.type="text";
+this.name_input.value=this.env.subscriptionrows[id][0].replace(reg,"");
+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).html(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 _18e=this.name_input?this.name_input.value:null;
+if(this.edit_folder&&_18e){
+if(_18e.indexOf(this.env.delimiter)>=0){
+alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")");
+return false;
+}
+if(this.name_input.__parent){
+_18e=this.name_input.__parent+this.env.delimiter+_18e;
+}
+this.set_busy(true,"folderrenaming");
+this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.subscriptionrows[this.edit_folder][0])+"&_folder_newname="+urlencode(_18e),true);
+}
+}else{
+if(key==27){
+this.reset_folder_rename();
+}
+}
+};
+this.delete_folder=function(id){
+var _190=this.env.subscriptionrows[id][0];
+if(this.edit_folder){
+this.reset_folder_rename();
+}
+if(_190&&confirm(this.get_label("deletefolderconfirm"))){
+this.set_busy(true,"folderdeleting");
+this.http_post("delete-folder","_mboxes="+urlencode(_190),true);
+this.set_env("folder",null);
+$(this.gui_objects.createfolderhint).html("");
+}
+};
+this.add_folder_row=function(name,_192,_193,_194){
+if(!this.gui_objects.subscriptionlist){
+return false;
+}
+for(var _195 in this.env.subscriptionrows){
+if(this.env.subscriptionrows[_195]!=null&&!this.env.subscriptionrows[_195][2]){
+break;
+}
+}
+var _196,form;
+var _198=this.gui_objects.subscriptionlist.tBodies[0];
+var id="rcmrow"+(_198.childNodes.length+1);
+var _19a=this.subscription_list.get_single_selection();
+if(_193&&_193.id){
+id=_193.id;
+_195=_193.id;
+}
+if(!id||!(_196=document.getElementById(_195))){
+this.goto_url("folders");
+}else{
+var row=this.clone_table_row(_196);
+row.id=id;
+if(_194&&(_194=this.get_folder_row_id(_194))){
+_198.insertBefore(row,document.getElementById(_194));
+}else{
+_198.appendChild(row);
+}
+if(_193){
+_198.removeChild(_193);
+}
+}
+this.env.subscriptionrows[row.id]=[name,_192,0];
+row.cells[0].innerHTML=_192;
+if(!_193){
+row.cells[1].innerHTML="*";
+}
+if(!_193&&row.cells[2]&&row.cells[2].firstChild.tagName.toLowerCase()=="input"){
+row.cells[2].firstChild.value=name;
+row.cells[2].firstChild.checked=true;
+}
+if(!_193&&(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(_19a&&document.getElementById("rcmrow"+_19a)){
+this.subscription_list.select_row(_19a);
+}
+if(document.getElementById(id).scrollIntoView){
+document.getElementById(id).scrollIntoView();
+}
+};
+this.replace_folder_row=function(_19c,_19d,_19e,_19f){
+var id=this.get_folder_row_id(_19c);
+var row=document.getElementById(id);
+this.add_folder_row(_19d,_19e,row,_19f);
+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==_19c){
+elm.options[i].text=_19e;
+elm.options[i].value=_19d;
+break;
+}
+}
+form.elements["_folder_newname"].value="";
+}
+};
+this.remove_folder_row=function(_1a5){
+var row;
+var id=this.get_folder_row_id(_1a5);
+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==_1a5){
+form.elements["_folder_oldname"].options[i]=null;
+break;
+}
+}
+}
+if(form&&form.elements["_folder_newname"]){
+form.elements["_folder_newname"].value="";
+}
+};
+this.subscribe_folder=function(_1aa){
+if(_1aa){
+this.http_post("subscribe","_mbox="+urlencode(_1aa));
+}
+};
+this.unsubscribe_folder=function(_1ab){
+if(_1ab){
+this.http_post("unsubscribe","_mbox="+urlencode(_1ab));
+}
+};
+this.get_folder_row_id=function(_1ac){
+for(var id in this.env.subscriptionrows){
+if(this.env.subscriptionrows[id]&&this.env.subscriptionrows[id][0]==_1ac){
+break;
+}
+}
+return id;
+};
+this.clone_table_row=function(row){
+var cell,td;
+var _1b1=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;
+_1b1.appendChild(td);
+}
+return _1b1;
+};
+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.init_buttons=function(){
+for(var cmd in this.buttons){
+if(typeof cmd!="string"){
+continue;
+}
+for(var i=0;i<this.buttons[cmd].length;i++){
+var prop=this.buttons[cmd][i];
+var elm=document.getElementById(prop.id);
+if(!elm){
+continue;
+}
+var _1b7=false;
+if(prop.type=="image"){
+elm=elm.parentNode;
+_1b7=true;
+}
+elm._command=cmd;
+elm._id=prop.id;
+if(prop.sel){
+elm.onmousedown=function(e){
+return rcmail.button_sel(this._command,this._id);
+};
+elm.onmouseup=function(e){
+return rcmail.button_out(this._command,this._id);
+};
+if(_1b7){
+new Image().src=prop.sel;
+}
+}
+if(prop.over){
+elm.onmouseover=function(e){
+return rcmail.button_over(this._command,this._id);
+};
+elm.onmouseout=function(e){
+return rcmail.button_out(this._command,this._id);
+};
+if(_1b7){
+new Image().src=prop.over;
+}
+}
+}
+}
+};
+this.set_button=function(_1bc,_1bd){
+var _1be=this.buttons[_1bc];
+var _1bf,obj;
+if(!_1be||!_1be.length){
+return false;
+}
+for(var n=0;n<_1be.length;n++){
+_1bf=_1be[n];
+obj=document.getElementById(_1bf.id);
+if(obj&&_1bf.type=="image"&&!_1bf.status){
+_1bf.pas=obj._original_src?obj._original_src:obj.src;
+if(obj.runtimeStyle&&obj.runtimeStyle.filter&&obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/)){
+_1bf.pas=RegExp.$1;
+}
+}else{
+if(obj&&!_1bf.status){
+_1bf.pas=String(obj.className);
+}
+}
+if(obj&&_1bf.type=="image"&&_1bf[_1bd]){
+_1bf.status=_1bd;
+obj.src=_1bf[_1bd];
+}else{
+if(obj&&typeof (_1bf[_1bd])!="undefined"){
+_1bf.status=_1bd;
+obj.className=_1bf[_1bd];
+}
+}
+if(obj&&_1bf.type=="input"){
+_1bf.status=_1bd;
+obj.disabled=!_1bd;
+}
+}
+};
+this.set_alttext=function(_1c2,_1c3){
+if(!this.buttons[_1c2]||!this.buttons[_1c2].length){
+return;
+}
+var _1c4,obj,link;
+for(var n=0;n<this.buttons[_1c2].length;n++){
+_1c4=this.buttons[_1c2][n];
+obj=document.getElementById(_1c4.id);
+if(_1c4.type=="image"&&obj){
+obj.setAttribute("alt",this.get_label(_1c3));
+if((link=obj.parentNode)&&link.tagName.toLowerCase()=="a"){
+link.setAttribute("title",this.get_label(_1c3));
+}
+}else{
+if(obj){
+obj.setAttribute("title",this.get_label(_1c3));
+}
+}
+}
+};
+this.button_over=function(_1c8,id){
+var _1ca=this.buttons[_1c8];
+var _1cb,elm;
+if(!_1ca||!_1ca.length){
+return false;
+}
+for(var n=0;n<_1ca.length;n++){
+_1cb=_1ca[n];
+if(_1cb.id==id&&_1cb.status=="act"){
+elm=document.getElementById(_1cb.id);
+if(elm&&_1cb.over){
+if(_1cb.type=="image"){
+elm.src=_1cb.over;
+}else{
+elm.className=_1cb.over;
+}
+}
+}
+}
+};
+this.button_sel=function(_1ce,id){
+var _1d0=this.buttons[_1ce];
+var _1d1,elm;
+if(!_1d0||!_1d0.length){
+return;
+}
+for(var n=0;n<_1d0.length;n++){
+_1d1=_1d0[n];
+if(_1d1.id==id&&_1d1.status=="act"){
+elm=document.getElementById(_1d1.id);
+if(elm&&_1d1.sel){
+if(_1d1.type=="image"){
+elm.src=_1d1.sel;
+}else{
+elm.className=_1d1.sel;
+}
+}
+this.buttons_sel[id]=_1ce;
+}
+}
+};
+this.button_out=function(_1d4,id){
+var _1d6=this.buttons[_1d4];
+var _1d7,elm;
+if(!_1d6||!_1d6.length){
+return;
+}
+for(var n=0;n<_1d6.length;n++){
+_1d7=_1d6[n];
+if(_1d7.id==id&&_1d7.status=="act"){
+elm=document.getElementById(_1d7.id);
+if(elm&&_1d7.act){
+if(_1d7.type=="image"){
+elm.src=_1d7.act;
+}else{
+elm.className=_1d7.act;
+}
+}
+}
+}
+};
+this.set_pagetitle=function(_1da){
+if(_1da&&document.title){
+document.title=_1da;
+}
+};
+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 obj=$(this.gui_objects.message).html(cont).show();
+if(type!="loading"){
+obj.bind("mousedown",function(){
+_1.hide_message();
+return true;
+});
+}
+if(!hold){
+this.message_timer=window.setTimeout(function(){
+_1.hide_message(true);
+},this.message_time);
+}
+};
+this.hide_message=function(fade){
+if(this.gui_objects.message){
+$(this.gui_objects.message).unbind()[(fade?"fadeOut":"hide")]();
+}
+};
+this.select_folder=function(name,old){
+if(this.gui_objects.folderlist){
+var _1e3,_1e4;
+if((_1e3=this.get_folder_li(old))){
+$(_1e3).removeClass("selected").removeClass("unfocused");
+}
+if((_1e4=this.get_folder_li(name))){
+$(_1e4).removeClass("unfocused").addClass("selected");
+}
+this.triggerEvent("selectfolder",{folder:name,old:old});
+}
+};
+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(_1e6){
+this.coltypes=_1e6;
+var cell,col;
+var _1e9=this.gui_objects.messagelist?this.gui_objects.messagelist.tHead:null;
+for(var n=0;_1e9&&n<this.coltypes.length;n++){
+col=this.coltypes[n];
+if((cell=_1e9.rows[0].cells[n+1])&&(col=="from"||col=="to")){
+if(cell.firstChild&&cell.firstChild.tagName.toLowerCase()=="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,_1ed,_1ee,_1ef){
+if(!this.gui_objects.messagelist||!this.message_list){
+return false;
+}
+if(this.message_list.background){
+var _1f0=this.message_list.background;
+}else{
+var _1f0=this.gui_objects.messagelist.tBodies[0];
+}
+var _1f1=_1f0.rows.length;
+var even=_1f1%2;
+this.env.messages[uid]={deleted:_1ed.deleted?1:0,replied:_1ed.replied?1:0,unread:_1ed.unread?1:0,forwarded:_1ed.forwarded?1:0,flagged:_1ed.flagged?1:0};
+var _1f3="message"+(even?" even":" odd")+(_1ed.unread?" unread":"")+(_1ed.deleted?" deleted":"")+(_1ed.flagged?" flagged":"")+(this.message_list.in_selection(uid)?" selected":"");
+var row=document.createElement("tr");
+row.id="rcmrow"+uid;
+row.className=_1f3;
+var icon=this.env.messageicon;
+if(_1ed.deleted&&this.env.deletedicon){
+icon=this.env.deletedicon;
+}else{
+if(_1ed.replied&&this.env.repliedicon){
+if(_1ed.forwarded&&this.env.forwardedrepliedicon){
+icon=this.env.forwardedrepliedicon;
+}else{
+icon=this.env.repliedicon;
+}
+}else{
+if(_1ed.forwarded&&this.env.forwardedicon){
+icon=this.env.forwardedicon;
+}else{
+if(_1ed.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(_1ed.flagged&&this.env.flaggedicon){
+col.innerHTML="<img src=\""+this.env.flaggedicon+"\" alt=\"\" />";
+}else{
+if(!_1ed.flagged&&this.env.unflaggedicon){
+col.innerHTML="<img src=\""+this.env.unflaggedicon+"\" alt=\"\" />";
+}
+}
+}else{
+if(c=="attachment"){
+col.innerHTML=(_1ee&&this.env.attachmenticon?"<img src=\""+this.env.attachmenticon+"\" alt=\"\" />":"&nbsp;");
+}else{
+col.innerHTML=cols[c];
+}
+}
+row.appendChild(col);
+}
+this.message_list.insert_row(row,_1ef);
+if(_1ef&&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.offline_message_list=function(flag){
+if(this.message_list){
+this.message_list.set_background_mode(flag);
+}
+};
+this.set_rowcount=function(text){
+$(this.gui_objects.countdisplay).html(text);
+this.set_page_buttons();
+};
+this.set_mailboxname=function(_1fb){
+if(this.gui_objects.mailboxname&&_1fb){
+this.gui_objects.mailboxname.innerHTML=_1fb;
+}
+};
+this.set_quota=function(_1fc){
+if(_1fc&&this.gui_objects.quotadisplay){
+if(typeof (_1fc)=="object"){
+this.percent_indicator(this.gui_objects.quotadisplay,_1fc);
+}else{
+$(this.gui_objects.quotadisplay).html(_1fc);
+}
+}
+};
+this.set_unread_count=function(mbox,_1fe,_1ff){
+if(!this.gui_objects.mailboxlist){
+return false;
+}
+this.env.unread_counts[mbox]=_1fe;
+this.set_unread_count_display(mbox,_1ff);
+};
+this.set_unread_count_display=function(mbox,_201){
+var reg,_203,item,_205,_206,div;
+if(item=this.get_folder_li(mbox)){
+_205=this.env.unread_counts[mbox]?this.env.unread_counts[mbox]:0;
+_203=item.getElementsByTagName("a")[0];
+reg=/\s+\([0-9]+\)$/i;
+_206=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){
+_206+=this.env.unread_counts[k];
+}
+}
+}
+if(_205&&_203.innerHTML.match(reg)){
+_203.innerHTML=_203.innerHTML.replace(reg," ("+_205+")");
+}else{
+if(_205){
+_203.innerHTML+=" ("+_205+")";
+}else{
+_203.innerHTML=_203.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);
+}
+if((_205+_206)>0){
+$(item).addClass("unread");
+}else{
+$(item).removeClass("unread");
+}
+}
+reg=/^\([0-9]+\)\s+/i;
+if(_201&&document.title){
+var _209=String(document.title);
+var _20a="";
+if(_205&&_209.match(reg)){
+_20a=_209.replace(reg,"("+_205+") ");
+}else{
+if(_205){
+_20a="("+_205+") "+_209;
+}else{
+_20a=_209.replace(reg,"");
+}
+}
+this.set_pagetitle(_20a);
+}
+};
+this.new_message_focus=function(){
+if(this.env.framed&&window.parent){
+window.parent.focus();
+}else{
+window.focus();
+}
+};
+this.toggle_prefer_html=function(_20b){
+var _20c;
+if(_20c=document.getElementById("rcmfd_addrbook_show_images")){
+_20c.disabled=!_20b.checked;
+}
+};
+this.set_headers=function(_20d){
+if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&_20d){
+$(this.gui_objects.all_headers_box).html(_20d).show();
+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;
+}
+$(elem).removeClass("show-headers").addClass("hide-headers");
+$(this.gui_objects.all_headers_row).show();
+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;
+}
+$(elem).removeClass("hide-headers").addClass("show-headers");
+$(this.gui_objects.all_headers_row).hide();
+elem.onclick=function(){
+rcmail.load_headers(elem);
+};
+};
+this.percent_indicator=function(obj,data){
+if(!data||!obj){
+return false;
+}
+var _212=80;
+var _213=55;
+var _214=data.width?data.width:this.env.indicator_width?this.env.indicator_width:100;
+var _215=data.height?data.height:this.env.indicator_height?this.env.indicator_height:14;
+var _216=data.percent?Math.abs(parseInt(data.percent)):0;
+var _217=parseInt(_216/100*_214);
+var pos=$(obj).position();
+this.env.indicator_width=_214;
+this.env.indicator_height=_215;
+if(_217>_214){
+_217=_214;
+_216=100;
+}
+var main=$("<div>");
+main.css({position:"absolute",top:pos.top,left:pos.left,width:_214+"px",height:_215+"px",zIndex:100,lineHeight:_215+"px"}).attr("title",data.title).addClass("quota_text").html(_216+"%");
+var bar1=$("<div>");
+bar1.css({position:"absolute",top:pos.top+1,left:pos.left+1,width:_217+"px",height:_215+"px",zIndex:99});
+var bar2=$("<div>");
+bar2.css({position:"absolute",top:pos.top+1,left:pos.left+1,width:_214+"px",height:_215+"px",zIndex:98}).addClass("quota_bg");
+if(_216>=_212){
+main.addClass(" quota_text_high");
+bar1.addClass("quota_high");
+}else{
+if(_216>=_213){
+main.addClass(" quota_text_mid");
+bar1.addClass("quota_mid");
+}else{
+main.addClass(" quota_text_normal");
+bar1.addClass("quota_low");
+}
+}
+obj.innerHTML="";
+$(obj).append(bar1).append(bar2).append(main);
+};
+this.html2plain=function(_21c,id){
+var url=this.env.bin_path+"html2text.php";
+var _21f=this;
+this.set_busy(true,"converting");
+console.log("HTTP POST: "+url);
+$.ajax({type:"POST",url:url,data:_21c,contentType:"application/octet-stream",error:function(o){
+_21f.http_error(o);
+},success:function(data){
+_21f.set_busy(false);
+$(document.getElementById(id)).val(data);
+console.log(data);
+}});
+};
+this.plain2html=function(_222,id){
+this.set_busy(true,"converting");
+$(document.getElementById(id)).val("<pre>"+_222+"</pre>");
+this.set_busy(false);
+};
+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(_226,_227,lock){
+var _229=_227?"&"+_227:"";
+this.redirect(this.env.comm_path+"&_action="+_226+_229,lock);
+};
+this.http_request=function(_22a,_22b,lock){
+_22b+=(_22b?"&":"")+"_remote=1";
+var url=this.env.comm_path+"&_action="+_22a+"&"+_22b;
+console.log("HTTP POST: "+url);
+jQuery.get(url,{_unlock:(lock?1:0)},function(data){
+_1.http_response(data);
+},"json");
+};
+this.http_post=function(_22f,_230,lock){
+var url=this.env.comm_path+"&_action="+_22f;
+if(_230&&typeof (_230)=="object"){
+_230._remote=1;
+_230._unlock=(lock?1:0);
+}else{
+_230+=(_230?"&":"")+"_remote=1"+(lock?"&_unlock=1":"");
+}
+console.log("HTTP POST: "+url);
+jQuery.post(url,_230,function(data){
+_1.http_response(data);
+},"json");
+};
+this.http_response=function(_234){
+var _235="";
+if(_234.unlock){
+this.set_busy(false);
+}
+if(_234.env){
+this.set_env(_234.env);
+}
+if(typeof _234.texts=="object"){
+for(var name in _234.texts){
+if(typeof _234.texts[name]=="string"){
+this.add_label(name,_234.texts[name]);
+}
+}
+}
+if(_234.exec){
+console.log(_234.exec);
+eval(_234.exec);
+}
+if(_234.callbacks&&_234.callbacks.length){
+for(var i=0;i<_234.callbacks.length;i++){
+this.triggerEvent(_234.callbacks[i][0],_234.callbacks[i][1]);
+}
+}
+switch(_234.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.enable_command("reply","reply-all","forward","delete","mark","print","open","edit","viewsource","download",true);
+}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","open","edit","download","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&&_234.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());
+if(_234.action=="list"){
+this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount});
+}
+}else{
+if(this.task=="addressbook"){
+this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0));
+if(_234.action=="list"){
+this.triggerEvent("listupdate",{folder:this.env.source,rowcount:this.contact_list.rowcount});
+}
+}
+}
+break;
+}
+};
+this.http_error=function(_239,_23a,err){
+var _23c=_239.statusText;
+this.set_busy(false);
+_239.abort();
+if(_23c){
+this.display_message(this.get_label("servererror")+" ("+_23c+")","error");
+}
+};
+this.send_keep_alive=function(){
+var d=new Date();
+this.http_request("keep-alive","_t="+d.getTime());
+};
+this.check_for_recent=function(_23e){
+if(this.busy){
+return;
+}
+if(_23e){
+this.set_busy(true,"checkingmail");
+}
+var _23f="_t="+(new Date().getTime());
+if(this.gui_objects.messagelist){
+_23f+="&_list=1";
+}
+if(this.gui_objects.quotadisplay){
+_23f+="&_quota=1";
+}
+if(this.env.search_request){
+_23f+="&_search="+this.env.search_request;
+}
+this.http_request("check-recent",_23f,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 _241=document.selection.createRange();
+if(_241.parentElement()!=obj){
+return 0;
+}
+var gm=_241.duplicate();
+if(obj.tagName=="TEXTAREA"){
+gm.moveToElementText(obj);
+}else{
+gm.expand("textedit");
+}
+gm.setEndPoint("EndToStart",_241);
+var p=gm.text.length;
+return p<=obj.value.length?p:-1;
+}else{
+return obj.value.length;
+}
+}
+};
+this.set_caret_pos=function(obj,pos){
+if(obj.setSelectionRange){
+obj.setSelectionRange(pos,pos);
+}else{
+if(obj.createTextRange){
+var _246=obj.createTextRange();
+_246.collapse(true);
+_246.moveEnd("character",pos);
+_246.moveStart("character",pos);
+_246.select();
+}
+}
+};
+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;
+}
+};
+};
+rcube_webmail.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;
+rcube_webmail.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;
+rcube_webmail.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;
 
diff --git a/program/js/app.js.src b/program/js/app.js.src
new file mode 100644 (file)
index 0000000..da9238b
--- /dev/null
@@ -0,0 +1,4387 @@
+/*
+ +-----------------------------------------------------------------------+
+ | 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: jquery.js, common.js, list.js                               |
+ +-----------------------------------------------------------------------+
+
+  $Id: app.js 3059 2009-10-24 19:18:35Z alec $
+*/
+
+
+function rcube_webmail()
+{
+  this.env = new Object();
+  this.labels = new Object();
+  this.buttons = new Object();
+  this.buttons_sel = new Object();
+  this.gui_objects = new Object();
+  this.gui_containers = new Object();
+  this.commands = new Object();
+  this.command_handlers = new Object();
+  this.onloads = new Array();
+
+  // create protected reference to myself
+  this.ref = 'rcmail';
+  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 jQuery ajax options
+  jQuery.ajaxSetup({ cache:false,
+    error:function(request, status, err){ ref.http_error(request, status, err); },
+    beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-RoundCube-Request', ref.env.request_token); }
+  });
+
+  // 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;
+    };
+  
+  // register a container object
+  this.gui_container = function(name, id)
+  {
+    this.gui_containers[name] = id;
+  };
+  
+  // add a GUI element (html node) to a specified container
+  this.add_element = function(elm, container)
+  {
+    if (this.gui_containers[container] && this.gui_containers[container].jquery)
+      this.gui_containers[container].append(elm);
+  };
+
+  // register an external handler for a certain command
+  this.register_command = function(command, callback, enable)
+  {
+    this.command_handlers[command] = callback;
+    
+    if (enable)
+      this.enable_command(command, true);
+  };
+  
+  // execute the given script on load
+  this.add_onload = function(f)
+  {
+    this.onloads[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 containers
+    for (var n in this.gui_containers)
+      this.gui_containers[n] = $('#'+this.gui_containers[n]);
+
+    // find all registered gui objects
+    for (var n in this.gui_objects)
+      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
+      
+    // init registered buttons
+    this.init_buttons();
+
+    // 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(e){ p.drag_move(e); });
+          this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); });
+          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+
+          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); };
+          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',
+            'open', 'mark', 'edit', 'viewsource', 'download', '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.blockedobjects)
+            {
+            if (this.gui_objects.remoteobjectsmsg)
+              this.gui_objects.remoteobjectsmsg.style.display = 'block';
+            this.enable_command('load-images', 'always-load', 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=='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 ($("input[name='_is_html']").val() == '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); };
+
+          // init message compose form
+          this.init_messageform();
+          }
+
+        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();
+
+        // 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.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); };
+          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
+          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
+          this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
+          this.contact_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
+          this.contact_list.addEventListener('dragend', function(e){ p.drag_end(e); });
+          this.contact_list.init();
+
+          if (this.env.cid)
+            this.contact_list.highlight_row(this.env.cid);
+
+          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.gui_objects.folderlist = this.gui_objects.contactslist;
+          }
+
+        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.enable_command('add', this.env.identities_level < 2);
+        }
+        else if (this.env.action=='edit-identity' || this.env.action=='add-identity') {
+          this.enable_command('add', this.env.identities_level < 2);
+          this.enable_command('save', 'delete', 'edit', true);
+        }
+        else 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);
+          }
+        else if (this.gui_objects.sectionslist)
+          {
+          this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:false});
+          this.sections_list.addEventListener('select', function(o){ p.section_select(o); });
+          this.sections_list.init();
+          this.sections_list.focus();
+          this.sections_list.select_first();  // open first section by default
+        }
+        else if (this.gui_objects.subscriptionlist)
+          this.init_subscription_list();
+
+        break;
+
+      case 'login':
+        var input_user = $('#rcmloginuser');
+        input_user.bind('keyup', function(e){ return rcmail.login_user_keyup(e); });
+        
+        if (input_user.val() == '')
+          input_user.focus();
+        else
+          $('#rcmloginpwd').focus();
+
+        // detect client timezone
+        $('#rcmlogintz').val(new Date().getTimezoneOffset() / -60);
+
+        this.enable_command('login', true);
+        break;
+      
+      default:
+        break;
+      }
+
+    // flag object as complete
+    this.loaded = true;
+
+    // show message
+    if (this.pending_message)
+      this.display_message(this.pending_message[0], this.pending_message[1]);
+      
+    // map implicit containers
+    if (this.gui_objects.folderlist)
+      this.gui_containers.foldertray = $(this.gui_objects.folderlist);
+
+    // trigger init event hook
+    this.triggerEvent('init', { task:this.task, action:this.env.action });
+    
+    // execute all foreign onload scripts
+    // @deprecated
+    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 keep-alive interval
+    this.start_keepalive();
+  };
+
+  // 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.getElementsByTagName('td')[0].getElementsByTagName('img')[0])
+      {
+      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.getElementsByTagName('td')[this.env.flagged_col].getElementsByTagName('img')[0]))
+      {
+      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.triggerEvent('insertrow', { uid:uid, row:row });
+  };
+
+  // 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 = $("[name='_from']");
+    var input_to = $("[name='_to']");
+    var input_subject = $("input[name='_subject']");
+    var input_message = $("[name='_message']").get(0);
+    var html_mode = $("input[name='_is_html']").val() == '1';
+
+    // init live search events
+    this.init_address_input_events(input_to);
+    this.init_address_input_events($("[name='_cc']"));
+    this.init_address_input_events($("[name='_bcc']"));
+
+    // add signature according to selected identity
+    if (input_from.attr('type') == 'select-one' && $("input[name='_draft_saveid']").val() == ''
+        && !html_mode) {  // if we have HTML editor, signature is added in callback
+      this.change_identity(input_from[0]);
+    }
+
+    if (input_to.val() == '')
+      input_to.focus();
+    else if (input_subject.val() == '')
+      input_subject.focus();
+    else if (input_message && !html_mode)
+      input_message.focus();
+
+    // 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); };
+    obj.bind((bw.safari || bw.ie ? 'keydown' : 'keypress'), handler);
+    obj.attr('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 external commands
+    if (typeof this.command_handlers[command] == 'function')
+    {
+      var ret = this.command_handlers[command](props, obj);
+      return ret !== null ? ret : (obj ? false : true);
+    }
+    else if (typeof this.command_handlers[command] == 'string')
+    {
+      var ret = window[this.command_handlers[command]](props, obj);
+      return ret !== null ? ret : (obj ? false : true);
+    }
+    
+    // trigger plugin hook
+    var event_ret = this.triggerEvent('before'+command, props);
+    if (typeof event_ret != 'undefined') {
+      // abort if one the handlers returned false
+      if (event_ret === false)
+        return false;
+      else
+        props = event_ret;
+    }
+
+    // process internal command
+    switch (command)
+      {
+      case 'login':
+        if (this.gui_objects.loginform)
+          this.gui_objects.loginform.submit();
+        break;
+
+      // commands to switch task
+      case 'mail':
+      case 'addressbook':
+      case 'settings':
+      case 'logout':
+        this.switch_task(command);
+        break;
+
+      case 'permaurl':
+        if (obj && obj.href && obj.target)
+          return true;
+        else if (this.env.permaurl)
+          parent.location.href = this.env.permaurl;
+        break;
+
+      case 'open':
+        var uid;
+        if (uid = this.get_single_uid())
+        {
+          obj.href = '?_task='+this.env.task+'&_action=show&_mbox='+urlencode(this.env.mailbox)+'&_uid='+uid;
+          return true;
+        }
+        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':
+        var sort_order, sort_col = props;
+
+        if (this.env.sort_col==sort_col)
+          sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
+        else
+         sort_order = 'ASC';
+       
+        // set table header class
+        $('#rcm'+this.env.sort_col).removeClass('sorted'+(this.env.sort_order.toUpperCase()));
+        $('#rcm'+sort_col).addClass('sorted'+sort_order);
+
+        // 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');
+        else if (this.task=='mail' && (cid = this.get_single_uid())) {
+          var url = (this.env.mailbox == this.env.drafts_mailbox) ? '_draft_uid=' : '_uid=';
+          this.goto_url('compose', url+cid+'&_mbox='+urlencode(this.env.mailbox), true);
+        }
+        break;
+
+      case 'save-identity':
+      case 'save':
+        if (this.gui_objects.editform)
+          {
+          var input_pagesize = $("input[name='_pagesize']");
+          var input_name  = $("input[name='_name']");
+          var input_email = $("input[name='_email']");
+
+          // user prefs
+          if (input_pagesize.length && isNaN(parseInt(input_pagesize.val())))
+            {
+            alert(this.get_label('nopagesizewarning'));
+            input_pagesize.focus();
+            break;
+            }
+          // contacts/identities
+          else
+            {
+            if (input_name.length && input_name.val() == '')
+              {
+              alert(this.get_label('nonamewarning'));
+              input_name.focus();
+              break;
+              }
+            else if (input_email.length && !rcube_check_email(input_email.val()))
+              {
+              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':
+        if (props == 'invert')
+          this.message_list.invert_selection();
+        else
+          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(this.env.composebody)) {
+          tinyMCE.execCommand('mceSpellCheck', true);
+        }
+        else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) {
+          this.env.spellcheck.spellCheck();
+          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='+uid+'&_mbox='+urlencode(this.env.mailbox));
+          if (this.sourcewin)
+            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
+          }
+        break;
+
+      case 'download':
+        var uid;
+        if (uid = this.get_single_uid())
+          this.goto_url('viewsource', '&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+'&_save=1');
+        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;
+
+      }
+      
+    this.triggerEvent('after'+command, props);
+
+    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, domain)
+    {
+    if (domain && this.labels[domain+'.'+name])
+      return this.labels[domain+'.'+name];
+    else if (this.labels[name])
+      return this.labels[name];
+    else
+      return name;
+    };
+  
+  // alias for convenience reasons
+  this.gettext = this.get_label;
+
+  // switch to another application task
+  this.switch_task = function(task)
+    {
+    if (this.task===task && task!='mail')
+      return;
+
+    var url = this.get_task_url(task);
+    if (task=='mail')
+      url += '&_mbox=INBOX';
+
+    this.redirect(url);
+    };
+
+  this.get_task_url = function(task, url)
+    {
+    if (!url)
+      url = this.env.comm_path;
+
+    return url.replace(/_task=[a-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');
+    };
+  
+  this.reload = function(delay)
+  {
+    if (this.env.framed && parent.rcmail)
+      parent.rcmail.reload(delay);
+    else if (delay)
+      window.setTimeout(function(){ rcmail.reload(); }, delay);
+    else if (window.location)
+      location.href = this.env.comm_path;
+  };
+
+
+  /*********************************************************/
+  /*********        event handling methods         *********/
+  /*********************************************************/
+
+  this.doc_mouse_up = function(e)
+  {
+    var model, list, li;
+
+    if (this.message_list) {
+      if (!rcube_mouse_is_over(e, this.message_list.list))
+        this.message_list.blur();
+      list = this.message_list;
+      model = this.env.mailboxes;
+    }
+    else if (this.contact_list) {
+      if (!rcube_mouse_is_over(e, this.contact_list.list))
+        this.contact_list.blur();
+      list = this.contact_list;
+      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.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
+      this.command('moveto', model[this.env.last_folder_target].id);
+      this.env.last_folder_target = null;
+      list.draglayer.hide();
+    }
+    
+    // reset 'pressed' buttons
+    if (this.buttons_sel) {
+      for (var id in this.buttons_sel)
+        if (typeof id != 'function')
+          this.button_out(this.buttons_sel[id], id);
+      this.buttons_sel = {};
+    }
+  };
+
+  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)
+      {
+      this.initialBodyScrollTop = bw.ie ? 0 : window.pageYOffset;
+      this.initialListScrollTop = this.gui_objects.folderlist.parentNode.scrollTop;
+
+      var li, pos, list, height;
+      list = $(this.gui_objects.folderlist);
+      pos = list.offset();
+      this.env.folderlist_coords = { x1:pos.left, y1:pos.top, x2:pos.left + list.width(), y2:pos.top + list.height() };
+
+      this.env.folder_coords = new Array();
+      for (var k in model) {
+        if (li = this.get_folder_li(k)) {
+          // only visible folders
+          if (height = li.firstChild.offsetHeight) {
+            pos = $(li.firstChild).offset();
+            this.env.folder_coords[k] = { x1:pos.left, y1:pos.top,
+              x2:pos.left + li.firstChild.offsetWidth, y2:pos.top + height, on:0 };
+          }
+        }
+      }
+    }
+  };
+
+  this.drag_end = function(e)
+  {
+    this.drag_active = false;
+    this.env.last_folder_target = null;
+    
+    if (this.folder_auto_timer) {
+      window.clearTimeout(this.folder_auto_timer);
+      this.folder_auto_timer = null;
+      this.folder_auto_expand = null;
+    }
+
+    // over the folders
+    if (this.gui_objects.folderlist && this.env.folder_coords) {
+      for (var k in this.env.folder_coords) {
+        if (this.env.folder_coords[k].on)
+          $(this.get_folder_li(k)).removeClass('droptarget');
+      }
+    }
+  };
+  
+  this.drag_move = function(e)
+  {
+    if (this.gui_objects.folderlist && this.env.folder_coords) {
+      // offsets to compensate for scrolling while dragging a message
+      var boffset = bw.ie ? -document.documentElement.scrollTop : this.initialBodyScrollTop;
+      var moffset = this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop;
+      var toffset = -moffset-boffset;
+
+      var li, div, 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.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
+          this.env.folder_coords[this.env.last_folder_target].on = 0;
+          this.env.last_folder_target = null;
+        }
+        return;
+      }
+    
+      // over the folders
+      for (var k in this.env.folder_coords) {
+        pos = this.env.folder_coords[k];
+        if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.y >= pos.y1 && mouse.y < pos.y2
+            && this.check_droptarget(k)) {
+
+          li = this.get_folder_li(k);
+          div = $(li.getElementsByTagName("div")[0]);
+
+          // if the folder is collapsed, expand it after 1sec and restart the drag & drop process.
+          if (div.hasClass('collapsed')) {
+            if (this.folder_auto_timer)
+              window.clearTimeout(this.folder_auto_timer);
+            
+            this.folder_auto_expand = k;
+            this.folder_auto_timer = window.setTimeout(function() {
+                rcmail.command("collapse-folder", rcmail.folder_auto_expand);
+                rcmail.drag_start(null);
+              }, 1000);
+          } else if (this.folder_auto_timer) {
+            window.clearTimeout(this.folder_auto_timer);
+            this.folder_auto_timer = null;
+            this.folder_auto_expand = null;
+          }
+          
+          $(li).addClass('droptarget');
+          this.env.last_folder_target = k;
+          this.env.folder_coords[k].on = 1;
+        }
+        else if (pos.on) {
+          $(this.get_folder_li(k)).removeClass('droptarget');
+          this.env.folder_coords[k].on = 0;
+        }
+      }
+    }
+  };
+
+  this.collapse_folder = function(id)
+    {
+    var div;
+    if ((li = this.get_folder_li(id)) &&
+        (div = $(li.getElementsByTagName("div")[0])) &&
+        (div.hasClass('collapsed') || div.hasClass('expanded')))
+      {
+      var ul = $(li.getElementsByTagName("ul")[0]);
+      if (div.hasClass('collapsed'))
+        {
+        ul.show();
+        div.removeClass('collapsed').addClass('expanded');
+        var reg = new RegExp('&'+urlencode(id)+'&');
+        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
+        }
+      else
+        {
+        ul.hide();
+        div.removeClass('expanded').addClass('collapsed');
+        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();
+
+    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', 'open', 'edit', 'download', 'viewsource', selected);
+      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
+      }
+    else
+      {
+      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', 'edit', 'open', 'download', 'viewsource', 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 = $('#'+this.env.contentframe)) && frm.length)
+      {
+      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[show ? 'show' : 'hide']();
+      }
+
+    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)
+    {
+    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 && this.env.mailbox != mbox)
+      {
+      page = 1;
+      this.env.current_page = page;
+      this.show_contentframe(false);
+      }
+
+    if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
+      add_url += '&_refresh=1';
+
+    // unselect selected messages
+    this.last_selected = 0;
+    if (this.message_list)
+      this.message_list.clear_selection();
+    
+    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);
+    
+    var rowobj = $(rows[uid].obj);
+    if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0)
+      {
+      rows[uid].classname += ' unread';
+      rowobj.addClass('unread');
+      }
+    else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*unread/, '');
+      rowobj.removeClass('unread');
+      }
+    
+    if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0)
+      {
+      rows[uid].classname += ' deleted';
+      rowobj.addClass('deleted');
+      }
+    else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
+      rowobj.removeClass('deleted');
+      }
+
+    if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0)
+      {
+      rows[uid].classname += ' flagged';
+      rowobj.addClass('flagged');
+      }
+    else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, '');
+      rowobj.removeClass('flagged');
+      }
+
+    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
+      this.show_contentframe(false);
+
+    // Hide message command buttons until a message is selected
+    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', false);
+
+    this._with_selected_messages('moveto', lock, add_url);
+    };
+
+  // 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 config is set to flag for deletion
+    if (this.env.flag_for_deletion)
+      this.mark_message('delete');
+    // if there isn't a defined trash mailbox or 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 is a trash mailbox defined and we're not currently in it
+    else {
+      // 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);
+      }
+  };
+
+  // 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 : ''));
+    };
+
+  // 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;
+        this.message_list.remove_row(id, (this.env.display_next && n == selection.length-1));
+      }
+      // make sure there are no selected rows
+      if (!this.env.display_next)
+        this.message_list.clear_selection();
+    }
+
+    // also send search request to get the right messages 
+    if (this.env.search_request) 
+      add_url += '&_search='+this.env.search_request;
+
+    if (this.env.display_next && this.env.next_uid)
+      add_url += '&_next_uid='+this.env.next_uid;
+
+    // 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])
+        {
+        if (rows[uid].unread)
+          r_uids[r_uids.length] = uid;
+
+       if (this.env.skip_deleted)
+          this.message_list.remove_row(uid, (this.env.display_next && i == this.message_list.selection.length-1));
+       else
+         this.set_message(uid, 'deleted', true);
+        }
+      }
+
+    // make sure there are no selected rows
+    if (this.env.skip_deleted && !this.env.display_next && this.message_list)
+      this.message_list.clear_selection();
+
+    add_url = '&_from='+(this.env.action ? this.env.action : '');
+    
+    if (r_uids.length)
+      add_url += '&_ruid='+r_uids.join(',');
+
+    if (this.env.skip_deleted) {
+      // also send search request to get the right messages 
+      if (this.env.search_request) 
+        add_url += '&_search='+this.env.search_request;
+      if (this.env.display_next && this.env.next_uid)
+        add_url += '&_next_uid='+this.env.next_uid;
+    }
+    
+    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 passwd = $('#rcmloginpwd');
+
+    // enter
+    if (key == 13 && passwd.length && !passwd.val()) {
+      passwd.focus();
+      return rcube_event.cancel(e);
+    }
+    
+    return true;
+  };
+
+
+  /*********************************************************/
+  /*********        message compose methods        *********/
+  /*********************************************************/
+  
+  // checks the input fields before sending a message
+  this.check_compose_input = function()
+    {
+    // check input fields
+    var input_to = $("[name='_to']");
+    var input_cc = $("[name='_cc']");
+    var input_bcc = $("[name='_bcc']");
+    var input_from = $("[name='_from']");
+    var input_subject = $("[name='_subject']");
+    var input_message = $("[name='_message']");
+
+    // check sender (if have no identities)
+    if (input_from.attr('type') == 'text' && !rcube_check_email(input_from.val(), true))
+      {
+      alert(this.get_label('nosenderwarning'));
+      input_from.focus();
+      return false;
+      }
+
+    // check for empty recipient
+    var recipients = input_to.val() ? input_to.val() : (input_cc.val() ? input_cc.val() : input_bcc.val());
+    if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true))
+      {
+      alert(this.get_label('norecipientwarning'));
+      input_to.focus();
+      return false;
+      }
+
+    // check if all files has been uploaded
+    for (var key in this.env.attachments) {
+      if (typeof this.env.attachments[key] == 'object' && !this.env.attachments[key].complete) {
+        alert(this.get_label('notuploadedwarning'));
+        return false;
+      }
+    }
+    
+    // display localized warning for missing subject
+    if (input_subject.val() == '')
+      {
+      var 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.val((subject ? subject : this.get_label('nosubject')));
+        }
+      }
+
+    // check for empty body
+    if ((!window.tinyMCE || !tinyMCE.get(this.env.composebody))
+       && input_message.val() == '' && !confirm(this.get_label('nobodywarning')))
+      {
+      input_message.focus();
+      return false;
+      }
+    else if (window.tinyMCE && tinyMCE.get(this.env.composebody)
+       && !tinyMCE.get(this.env.composebody).getContent()
+       && !confirm(this.get_label('nobodywarning')))
+      {
+      tinyMCE.get(this.env.composebody).focus();
+      return false;
+      }
+
+    // Apply spellcheck changes if spell checker is active
+    this.stop_spellchecking();
+
+    // move body from html editor to textarea (just to be sure, #1485860)
+    if (window.tinyMCE && tinyMCE.get(this.env.composebody))
+      tinyMCE.triggerSave();
+
+    return true;
+    };
+
+  this.stop_spellchecking = function()
+    {
+    if (this.env.spellcheck && !this.spellcheck_ready) {
+      $(this.env.spellcheck.spell_span).trigger('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.spell_container).css('visibility', vis ? 'visible' : 'hidden');
+      }
+    };
+
+  this.set_spellcheck_state = function(s)
+    {
+    this.spellcheck_ready = (s == 'ready' || s == 'no_error_found');
+    this.enable_command('spellcheck', this.spellcheck_ready);
+    };
+
+  this.set_draft_id = function(id)
+    {
+    $("input[name='_draft_saveid']").val(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 value_to = $("[name='_to']").val();
+    var value_cc = $("[name='_cc']").val();
+    var value_bcc = $("[name='_bcc']").val();
+    var value_subject = $("[name='_subject']").val();
+    var str = '';
+    
+    if (value_to)
+      str += value_to+':';
+    if (value_cc)
+      str += value_cc+':';
+    if (value_bcc)
+      str += value_bcc+':';
+    if (value_subject)
+      str += value_subject+':';
+    
+    var editor = tinyMCE.get(this.env.composebody);
+    if (editor)
+      str += editor.getContent();
+    else
+      str += $("[name='_message']").val();
+
+    if (this.env.attachments)
+      for (var upload_id in this.env.attachments)
+        str += upload_id;
+
+    if (save)
+      this.cmp_hash = str;
+
+    return str;
+    };
+    
+  this.change_identity = function(obj)
+    {
+    if (!obj || !obj.options)
+      return false;
+
+    var id = obj.options[obj.selectedIndex].value;
+    var input_message = $("[name='_message']");
+    var message = input_message.val();
+    var is_html = ($("input[name='_is_html']").val() == '1');
+    var sig, p, len;
+
+    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]+$/, '');
+      len = message.length;
+
+      // 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;
+       if (len) len += 1;
+        }
+      }
+    else
+      {
+      var editor = tinyMCE.get(this.env.composebody);
+
+      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>';
+        }
+      }
+
+    input_message.val(message);
+
+    // move cursor before the signature
+    if (!is_html)
+      this.set_caret_pos(input_message.get(0), len);
+
+    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 = $(list).offset();
+        elm.style.top = (pos.top + list.offsetHeight + 10) + 'px';
+        elm.style.left = pos.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);
+        }
+
+      // handle upload errors, parsing iframe content in onload
+      var fr = document.getElementsByName(frame_name)[0];
+      $(fr).bind('load', {ts:ts}, function(e) {
+        var content = '';
+        try {
+          if (this.contentDocument) {
+            var d = this.contentDocument;
+          } else if (this.contentWindow) {
+            var d = this.contentWindow.document;
+          }
+          content = d.childNodes[0].innerHTML;
+        } catch (e) {}
+
+        if (!String(content).match(/add2attachment/) && (!bw.opera || (rcmail.env.uploadframe && rcmail.env.uploadframe == e.data.ts))) {
+          rcmail.display_message(rcmail.get_label('fileuploaderror'), 'error');
+          rcmail.remove_from_attachment_list(e.data.ts);
+        }
+        // Opera hack: handle double onload
+        if (bw.opera)
+          rcmail.env.uploadframe = e.data.ts;
+      });
+
+      form.target = frame_name;
+      form.action = this.env.comm_path+'&_action=upload&_uploadid='+ts;
+      form.setAttribute('enctype', 'multipart/form-data');
+      form.submit();
+      
+      // hide upload form
+      this.show_attachment_form(false);
+      // display upload indicator and cancel button
+      var content = this.get_label('uploading');
+      if (this.env.loadingicon)
+        content = '<img src="'+this.env.loadingicon+'" alt="" />'+content;
+      if (this.env.cancelicon)
+        content = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+ts+'\', \''+frame_name+'\');" href="#cancelupload"><img src="'+this.env.cancelicon+'" alt="" /></a>'+content;
+      this.add2attachment_list(ts, { name:'', html:content, complete:false });
+      }
+    
+    // set reference to the form object
+    this.gui_objects.attachmentform = form;
+    return true;
+    };
+
+  // add file name to attachment list
+  // called from upload page
+  this.add2attachment_list = function(name, att, upload_id)
+  {
+    if (!this.gui_objects.attachmentlist)
+      return false;
+    
+    var li = $('<li>').attr('id', name).html(att.html);
+    var indicator;
+    
+    // replace indicator's li
+    if (upload_id && (indicator = document.getElementById(upload_id))) {
+      li.replaceAll(indicator);
+    }
+    else { // add new li
+      li.appendTo(this.gui_objects.attachmentlist);
+    }
+    
+    if (upload_id && this.env.attachments[upload_id])
+      delete this.env.attachments[upload_id];
+    
+    this.env.attachments[name] = att;
+    
+    return true;
+  };
+
+  this.remove_from_attachment_list = function(name)
+  {
+    if (this.env.attachments[name])
+      delete this.env.attachments[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.env.attachments[name])
+      this.http_post('remove-attachment', '_file='+urlencode(name));
+
+    return true;
+    };
+
+  this.cancel_attachment_upload = function(name, frame_name)
+    {
+    if (!name || !frame_name)
+      return false;
+
+    this.remove_from_attachment_list(name);
+    $("iframe[name='"+frame_name+"']").remove();
+    return false;
+    };
+
+  // send remote request to add a new contact
+  this.add_contact = function(value)
+    {
+    if (value)
+      this.http_post('addcontact', '_address='+value);
+    
+    return true;
+    };
+
+  // send remote request to search mail or contacts
+  this.qsearch = function(value)
+    {
+    if (value != '')
+      {
+      var addurl = '';
+      if (this.message_list) {
+        this.message_list.clear();
+        if (this.env.search_mods) {
+          var head_arr = new Array();
+          for (var n in this.env.search_mods)
+            head_arr.push(n);
+          addurl += '&_headers='+head_arr.join(',');
+          }
+        } 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 = $('#rcmksearchSelected');
+    if (current[0] && node) {
+      current.removeAttr('id').removeClass('selected');
+    }
+
+    if (node) {
+      $(node).attr('id', 'rcmksearchSelected').addClass('selected');
+      this.ksearch_selected = node._rcm_id;
+    }
+  };
+
+  this.insert_recipient = function(id)
+  {
+    if (!this.env.contacts[id] || !this.ksearch_input)
+      return;
+    
+    // get cursor pos
+    var inp_value = this.ksearch_input.value;
+    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.is(":visible"))
+      this.ksearch_pane.hide();
+
+    // 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, '');
+
+    // Don't (re-)search if the last results are still active
+    if (q == this.ksearch_value)
+      return;
+    
+    var old_value = this.ksearch_value;
+    this.ksearch_value = q;
+    
+    // ...string is empty
+    if (!q.length)
+      return;
+
+    // ...new search value contains old one and previous search result was empty
+    if (old_value && old_value.length && this.env.contacts && !this.env.contacts.length && q.indexOf(old_value) == 0)
+      return;
+    
+    this.display_message(this.get_label('searching'), 'loading', true);
+    this.http_post('autocomplete', '_search='+urlencode(q));
+  };
+
+  this.ksearch_query_results = function(results, search)
+  {
+    // ignore this outdated search response
+    if (this.ksearch_value && 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 = $('<ul>');
+        this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane').css({ position:'absolute', 'z-index':30000 }).append(ul).appendTo(document.body);
+        this.ksearch_pane.__ul = ul[0];
+      }
+
+      // remove all search results
+      ul = this.ksearch_pane.__ul;
+      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).attr('id', 'rcmksearchSelected').addClass('selected');
+      this.ksearch_selected = 0;
+
+      // move the results pane right under the input box and make it visible
+      var pos = $(this.ksearch_input).offset();
+      this.ksearch_pane.css({ left:pos.left+'px', top:(pos.top + this.ksearch_input.offsetHeight)+'px' }).show();
+    }
+    // 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.hide();
+    };
+
+
+  /*********************************************************/
+  /*********         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, newcid)
+  {
+    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]).html(cols_arr[c]);
+
+      // cid change
+      if (newcid) {
+       row.id = 'rcmrow' + newcid;
+        this.contact_list.remove_row(cid);
+        this.contact_list.init_row(row);
+       this.contact_list.selection[0] = newcid;
+       row.style.display = '';
+      }
+
+      return true;
+    }
+
+    return false;
+  };
+
+  // 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));
+    };
+
+
+  /*********************************************************/
+  /*********        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();
+    }
+
+  // preferences section select and load options frame
+  this.section_select = function(list)
+    {
+    var id = list.get_single_selection();
+    
+    if (id) {
+      var add_url = '';
+      var target = window;
+      this.set_busy(true);
+
+      if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) {
+        add_url = '&_framed=1';
+        target = window.frames[this.env.contentframe];
+        }
+      target.location.href = this.env.comm_path+'&_action=edit-prefs&_section='+id+add_url;
+      }
+
+    return true;
+    };
+
+  this.identity_select = function(list)
+    {
+    var id;
+    if (id = list.get_single_selection())
+      this.load_identity(id, 'edit-identity');
+    };
+
+  // load identity record
+  this.load_identity = function(id, action)
+    {
+    if (action=='edit-identity' && (!id || id==this.env.iid))
+      return false;
+
+    var 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];
+
+    // append token to request
+    this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, 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);
+          $(row).addClass('droptarget');
+          }
+        }
+      else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter))))
+        {
+        this.set_env('dstfolder', this.env.delimiter);
+        $(this.subscription_list.frame).addClass('droptarget');
+        }
+    }
+
+  this.unfocus_subscription = function(id)
+    {
+      var row = $('#'+id);
+      this.set_env('dstfolder', null);
+      if (this.env.subscriptionrows[id] && row[0])
+        row.removeClass('droptarget');
+      else
+        $(this.subscription_list.frame).removeClass('droptarget');
+    }
+
+  this.subscription_select = function(list)
+    {
+    var id, folder;
+    if ((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).html(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.type = 'text';
+      this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, '');
+
+      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).html(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);
+
+      $(this.gui_objects.createfolderhint).html('');
+      }
+    };
+
+  // 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.toLowerCase()=='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 event handlers on registered buttons
+  this.init_buttons = function()
+  {
+    for (var cmd in this.buttons) {
+      if (typeof cmd != 'string')
+        continue;
+      
+      for (var i=0; i< this.buttons[cmd].length; i++) {
+        var prop = this.buttons[cmd][i];
+        var elm = document.getElementById(prop.id);
+        if (!elm)
+          continue;
+
+        var preload = false;
+        if (prop.type == 'image') {
+          elm = elm.parentNode;
+          preload = true;
+        }
+        
+        elm._command = cmd;
+        elm._id = prop.id;
+        if (prop.sel) {
+          elm.onmousedown = function(e){ return rcmail.button_sel(this._command, this._id); };
+          elm.onmouseup = function(e){ return rcmail.button_out(this._command, this._id); };
+          if (preload)
+            new Image().src = prop.sel;
+        }
+        if (prop.over) {
+          elm.onmouseover = function(e){ return rcmail.button_over(this._command, this._id); };
+          elm.onmouseout = function(e){ return rcmail.button_out(this._command, this._id); };
+          if (preload)
+            new Image().src = prop.over;
+        }
+      }
+    }
+  };
+
+  // set 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.toLowerCase() == 'a')
+            link.setAttribute('title', this.get_label(label));
+        }
+        else if (obj)
+          obj.setAttribute('title', this.get_label(label));
+      }
+    };
+
+  // mouse over button
+  this.button_over = function(command, id)
+  {
+    var a_buttons = this.buttons[command];
+    var button, elm;
+
+    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')
+      {
+        elm = document.getElementById(button.id);
+        if (elm && button.over) {
+          if (button.type == 'image')
+            elm.src = button.over;
+          else
+            elm.className = button.over;
+        }
+      }
+    }
+  };
+
+  // mouse down on button
+  this.button_sel = function(command, id)
+  {
+    var a_buttons = this.buttons[command];
+    var button, elm;
+
+    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')
+      {
+        elm = document.getElementById(button.id);
+        if (elm && button.sel) {
+          if (button.type == 'image')
+            elm.src = button.sel;
+          else
+            elm.className = button.sel;
+        }
+        this.buttons_sel[id] = command;
+      }
+    }
+  };
+
+  // mouse out of button
+  this.button_out = function(command, id)
+  {
+    var a_buttons = this.buttons[command];
+    var button, elm;
+
+    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')
+      {
+        elm = document.getElementById(button.id);
+        if (elm && button.act) {
+          if (button.type == 'image')
+            elm.src = button.act;
+          else
+            elm.className = button.act;
+        }
+      }
+    }
+  };
+
+  // write to the document/window title
+  this.set_pagetitle = function(title)
+  {
+    if (title && document.title)
+      document.title = title;
+  }
+
+  // display a system message
+  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 obj = $(this.gui_objects.message).html(cont).show();
+    
+    if (type!='loading')
+      obj.bind('mousedown', function(){ ref.hide_message(); return true; });
+    
+    if (!hold)
+      this.message_timer = window.setTimeout(function(){ ref.hide_message(true); }, this.message_time);
+    };
+
+  // make a message row disapear
+  this.hide_message = function(fade)
+    {
+    if (this.gui_objects.message)
+      $(this.gui_objects.message).unbind()[(fade?'fadeOut':'hide')]();
+    };
+
+  // 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))) {
+        $(current_li).removeClass('selected').removeClass('unfocused');
+      }
+      if ((target_li = this.get_folder_li(name))) {
+        $(target_li).removeClass('unfocused').addClass('selected');
+      }
+      
+      // trigger event hook
+      this.triggerEvent('selectfolder', { folder:name, old:old });
+    }
+  };
+
+  // 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.toLowerCase()=='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;
+
+    if (this.message_list.background)
+      var tbody = this.message_list.background;
+    else
+      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 css_class = 'message'
+        + (even ? ' even' : ' odd')
+        + (flags.unread ? ' unread' : '')
+        + (flags.deleted ? ' deleted' : '')
+        + (flags.flagged ? ' flagged' : '')
+        + (this.message_list.in_selection(uid) ? ' selected' : '');
+
+    // for performance use DOM instead of jQuery here
+    var row = document.createElement('tr');
+    row.id = 'rcmrow'+uid;
+    row.className = css_class;
+    
+    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;
+    
+    // add icon col
+    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);
+      }
+    };
+
+  // messages list handling in background (for performance)
+  this.offline_message_list = function(flag)
+    {
+      if (this.message_list)
+       this.message_list.set_background_mode(flag);
+    };
+
+  // replace content of row count display
+  this.set_rowcount = function(text)
+    {
+    $(this.gui_objects.countdisplay).html(text);
+
+    // update page navigation buttons
+    this.set_page_buttons();
+    };
+
+  // replace content of mailboxname display
+  this.set_mailboxname = function(content)
+    {
+    if (this.gui_objects.mailboxname && content)
+      this.gui_objects.mailboxname.innerHTML = content;
+    };
+
+  // replace content of quota display
+  this.set_quota = function(content)
+    {
+    if (content && this.gui_objects.quotadisplay) {
+      if (typeof(content) == 'object')
+        this.percent_indicator(this.gui_objects.quotadisplay, content);
+      else
+        $(this.gui_objects.quotadisplay).html(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
+      if ((mycount+childcount)>0)
+        $(item).addClass('unread');
+      else
+        $(item).removeClass('unread');
+      }
+
+    // set unread count to window title
+    reg = /^\([0-9]+\)\s+/i;
+    if (set_title && document.title)
+      {
+      var 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();
+    }
+
+  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) {
+      $(this.gui_objects.all_headers_box).html(content).show();
+
+      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;
+    
+    $(elem).removeClass('show-headers').addClass('hide-headers');
+    $(this.gui_objects.all_headers_row).show();
+    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;
+
+    $(elem).removeClass('hide-headers').addClass('show-headers');
+    $(this.gui_objects.all_headers_row).hide();
+    elem.onclick = function() { rcmail.load_headers(elem); }
+    }
+
+  // percent (quota) indicator
+  this.percent_indicator = function(obj, data)
+    {
+    if (!data || !obj)
+      return false;
+
+    var limit_high = 80;
+    var limit_mid  = 55;
+    var width = data.width ? data.width : this.env.indicator_width ? this.env.indicator_width : 100;
+    var height = data.height ? data.height : this.env.indicator_height ? this.env.indicator_height : 14;
+    var quota = data.percent ? Math.abs(parseInt(data.percent)) : 0;
+    var quota_width = parseInt(quota / 100 * width);
+    var pos = $(obj).position();
+
+    this.env.indicator_width = width;
+    this.env.indicator_height = height;
+    
+    // overlimit
+    if (quota_width > width) {
+      quota_width = width;
+      quota = 100; 
+      }
+  
+    // main div
+    var main = $('<div>');
+    main.css({position: 'absolute', top: pos.top, left: pos.left,
+       width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'})
+       .attr('title', data.title).addClass('quota_text').html(quota + '%');
+    // used bar
+    var bar1 = $('<div>');
+    bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
+       width: quota_width + 'px', height: height + 'px', zIndex: 99});
+    // background
+    var bar2 = $('<div>');
+    bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
+       width: width + 'px', height: height + 'px', zIndex: 98})
+       .addClass('quota_bg');
+
+    if (quota >= limit_high) {
+      main.addClass(' quota_text_high');
+      bar1.addClass('quota_high');
+      }
+    else if(quota >= limit_mid) {
+      main.addClass(' quota_text_mid');
+      bar1.addClass('quota_mid');
+      }
+    else {
+      main.addClass(' quota_text_normal');
+      bar1.addClass('quota_low');
+      }
+
+    // replace quota image
+    obj.innerHTML = '';
+    $(obj).append(bar1).append(bar2).append(main);
+    }
+
+  /********************************************************/
+  /*********  html to text conversion functions   *********/
+  /********************************************************/
+
+  this.html2plain = function(htmlText, id)
+    {
+    var url = this.env.bin_path+'html2text.php';
+    var rcmail = this;
+
+    this.set_busy(true, 'converting');
+    console.log('HTTP POST: '+url);
+
+    $.ajax({ type: 'POST', url: url, data: htmlText, contentType: 'application/octet-stream',
+      error: function(o) { rcmail.http_error(o); },
+      success: function(data) { rcmail.set_busy(false); $(document.getElementById(id)).val(data); console.log(data); }
+      });
+    }
+
+  this.plain2html = function(plainText, id)
+    {
+    this.set_busy(true, 'converting');
+    $(document.getElementById(id)).val('<pre>'+plainText+'</pre>');
+    this.set_busy(false);
+    }
+
+
+  /********************************************************/
+  /*********        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);
+    };
+
+  // send a http request to the server
+  this.http_request = function(action, querystring, lock)
+  {
+    querystring += (querystring ? '&' : '') + '_remote=1';
+    var url = this.env.comm_path + '&_action=' + action + '&' + querystring
+    
+    // send request
+    console.log('HTTP POST: ' + url);
+    jQuery.get(url, { _unlock:(lock?1:0) }, function(data){ ref.http_response(data); }, 'json');
+  };
+
+  // send a http POST request to the server
+  this.http_post = function(action, postdata, lock)
+  {
+    var url = this.env.comm_path+'&_action=' + action;
+    
+    if (postdata && typeof(postdata) == 'object') {
+      postdata._remote = 1;
+      postdata._unlock = (lock ? 1 : 0);
+    }
+    else
+      postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock=1' : '');
+
+    // send request
+    console.log('HTTP POST: ' + url);
+    jQuery.post(url, postdata, function(data){ ref.http_response(data); }, 'json');
+  };
+
+  // handle HTTP response
+  this.http_response = function(response)
+  {
+    var console_msg = '';
+    
+    if (response.unlock)
+      this.set_busy(false);
+
+    // set env vars
+    if (response.env)
+      this.set_env(response.env);
+
+    // we have labels to add
+    if (typeof response.texts == 'object') {
+      for (var name in response.texts)
+        if (typeof response.texts[name] == 'string')
+          this.add_label(name, response.texts[name]);
+    }
+
+    // if we get javascript code from server -> execute it
+    if (response.exec) {
+      console.log(response.exec);
+      eval(response.exec);
+    }
+    
+    // execute callback functions of plugins
+    if (response.callbacks && response.callbacks.length) {
+      for (var i=0; i < response.callbacks.length; i++)
+        this.triggerEvent(response.callbacks[i][0], response.callbacks[i][1]);
+    }
+    // process the response data according to the sent action
+    switch (response.action) {
+      case 'delete':
+        if (this.task == 'addressbook') {
+          var 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') {
+         // re-enable commands on move/delete error
+         this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', true);
+        } 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', 'open', 'edit', 'download', '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 && response.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());
+          
+          if (response.action == 'list')
+            this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
+        }
+        else if (this.task == 'addressbook') {
+          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
+          
+          if (response.action == 'list')
+            this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
+        }
+        break;
+    }
+  };
+
+  // handle HTTP request errors
+  this.http_error = function(request, status, err)
+    {
+    var errmsg = request.statusText;
+
+    this.set_busy(false);
+    request.abort();
+    
+    if (errmsg)
+      this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', '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_caret_pos = function(obj, pos)
+    {
+    if (obj.setSelectionRange)
+      obj.setSelectionRange(pos, pos);
+    else if (obj.createTextRange)
+      {
+      var range = obj.createTextRange();
+      range.collapse(true);
+      range.moveEnd('character', pos);
+      range.moveStart('character', pos);
+      range.select();
+      }
+    }
+
+  // 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
+
+
+// copy event engine prototype
+rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
+rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
+rcube_webmail.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
index cf3a8659a871d26ff7593f9607a9a748deb1217a..f9573a4c09a1f8642d5195e1446ffd37f5a0f1a9 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 2721 2009-07-07 17:23:55Z 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 DOM event handling
-var rcube_event = {
-
-/**
- * returns the event target element
- */
-get_target: function(e)
-{
-  e = e || window.event;
-  return e && e.target ? e.target : e.srcElement;
-},
-
-/**
- * returns the event key code
- */
-get_keycode: function(e)
-{
-  e = e || window.event;
-  return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns the event key code
- */
-get_button: function(e)
-{
-  e = e || window.event;
-  return e && (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.left;
-    mY += e._offset.top;
-  }
-
-  return { x:mX, y:mY };
-},
-
-/**
- * Add an object method as event listener to a certain element
- */
-add_listener: function(p)
-{
-  if (!p.object || !p.method)  // not enough arguments
-    return;
-  if (!p.element)
-    p.element = document;
-
-  if (!p.object._rc_events)
-    p.object._rc_events = [];
-  
-  var key = p.event + '*' + p.method;
-  if (!p.object._rc_events[key])
-    p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
-
-  if (p.element.addEventListener)
-    p.element.addEventListener(p.event, p.object._rc_events[key], false);
-  else if (p.element.attachEvent)
-    {
-    // IE allows multiple events with the same function to be applied to the same object
-    // forcibly detach the event, then attach
-    p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
-    p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
-    }
-  else
-    p.element['on'+p.event] = p.object._rc_events[key];
-},
-
-/**
- * Remove event listener
- */
-remove_listener: function(p)
-{
-  if (!p.element)
-    p.element = document;
-
-  var key = p.event + '*' + p.method;
-  if (p.object && p.object._rc_events && p.object._rc_events[key]) {
-    if (p.element.removeEventListener)
-      p.element.removeEventListener(p.event, p.object._rc_events[key], false);
-    else if (p.element.detachEvent)
-      p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
-    else
-      p.element['on'+p.event] = null;
-  }
-},
-
-/**
- * Prevent event propagation and 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.ie8=(this.dom&&this.appver.indexOf("MSIE 8")>0);
+this.ie7=(this.dom&&this.appver.indexOf("MSIE 7")>0);
+this.ie6=(this.dom&&!this.ie8&&!this.ie7&&this.appver.indexOf("MSIE 6")>0);
+this.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;
 };
-
-
-/**
- * rcmail objects event interface
- */
-function rcube_event_engine()
-{
-  this._events = {};
+};
+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;
 }
-
-rcube_event_engine.prototype = {
-
-/**
- * Setter for object event handlers
- *
- * @param {String}   Event name
- * @param {Function} Handler function
- * @return Listener ID (used to remove this handler later on)
- */
-addEventListener: function(evt, func, obj)
-{
-  if (!this._events)
-    this._events = {};
-  if (!this._events[evt])
-    this._events[evt] = [];
-    
-  var e = {func:func, obj:obj ? obj : window};
-  this._events[evt][this._events[evt].length] = e;
-},
-
-/**
- * Removes a specific event listener
- *
- * @param {String} Event name
- * @param {Int}    Listener ID to remove
- */
-removeEventListener: function(evt, func, obj)
-{
-  if (typeof obj == 'undefined')
-    obj = window;
-    
-  for (var h,i=0; this._events && this._events[evt] && i < this._events[evt].length; i++)
-    if ((h = this._events[evt][i]) && h.func == func && h.obj == obj)
-      this._events[evt][i] = null;
-},
-
-/**
- * This will execute all registered event handlers
- *
- * @param {String} Event to trigger
- * @param {Object} Event object/arguments
- */
-triggerEvent: function(evt, e)
-{
-  var ret, h;
-  if (typeof e == 'undefined')
-    e = this;
-  else if (typeof e == 'object')
-    e.event = evt;
-  
-  if (this._events && this._events[evt] && !this._event_exec) {
-    this._event_exec = true;
-    for (var i=0; i < this._events[evt].length; i++) {
-      if ((h = this._events[evt][i])) {
-        if (typeof h.func == 'function')
-          ret = h.func.call ? h.func.call(h.obj, e) : h.func(e);
-        else if (typeof h.obj[h.func] == 'function')
-          ret = h.obj[h.func](e);
-              
-        // cancel event execution
-        if (typeof ret != 'undefined' && !ret)
-          break;
-      }
-    }
-  }
-
-  this._event_exec = false;
-  return ret;
+if(e){
+_6+=(e.ctrlKey&&CONTROL_KEY)+(e.shiftKey&&SHIFT_KEY);
+return _6;
 }
-
-}  // end rcube_event_engine.prototype
-
-
-
-/**
- * RoundCube generic layer (floating box) class
- *
- * @constructor
- */
-function rcube_layer(id, attributes)
-{
-  this.name = id;
-  
-  // create a new layer in the current document
-  this.create = function(arg)
-    {
-    var l = (arg.x) ? arg.x : 0;
-    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;
-
-
-  // ********* layer object methods *********
-
-
-  // move the layer to a specific position
-  this.move = function(x, y)
-    {
-    this.x = x;
-    this.y = y;
-    this.css.left = Math.round(this.x)+'px';
-    this.css.top = Math.round(this.y)+'px';
-    }
-
-  // change the layers width and height
-  this.resize = function(w,h)
-    {
-    this.css.width  = w+'px';
-    this.css.height = h+'px';
-    this.width = w;
-    this.height = h;
-    }
-
-
-  // show or hide the layer
-  this.show = function(a)
-    {
-    if(a==1)
-      {
-      this.css.visibility = 'visible';
-      this.visible = true;
-      }
-    else if(a==2)
-      {
-      this.css.visibility = 'inherit';
-      this.visible = true;
-      }
-    else
-      {
-      this.css.visibility = 'hidden';
-      this.visible = false;
-      }
-    }
-
-
-  // write new content into a Layer
-  this.write = function(cont)
-    {
-    this.elm.innerHTML = cont;
-    }
-
+},get_mouse_pos:function(e){
+if(!e){
+e=window.event;
 }
-
-
-// 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 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;
 }
-
-
-// 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;
+if(e._offset){
+mX+=e._offset.left;
+mY+=e._offset.top;
 }
-
-// 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 = $(obj).offset();
-
-  return ((mouse.x >= pos.left) && (mouse.x < (pos.left + obj.offsetWidth)) &&
-    (mouse.y >= pos.top) && (mouse.y < (pos.top + obj.offsetHeight)));
+return {x:mX,y:mY};
+},add_listener:function(p){
+if(!p.object||!p.method){
+return;
 }
-
-
-// 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('dbgconsole');
-
-    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('dbgconsole');
-    if (box)
-      box.innerText = box.value = '';
-  };
+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;
+}};
+function rcube_event_engine(){
+this._events={};
+};
+rcube_event_engine.prototype={addEventListener:function(evt,_12,obj){
+if(!this._events){
+this._events={};
+}
+if(!this._events[evt]){
+this._events[evt]=[];
+}
+var e={func:_12,obj:obj?obj:window};
+this._events[evt][this._events[evt].length]=e;
+},removeEventListener:function(evt,_16,obj){
+if(typeof obj=="undefined"){
+obj=window;
+}
+for(var h,i=0;this._events&&this._events[evt]&&i<this._events[evt].length;i++){
+if((h=this._events[evt][i])&&h.func==_16&&h.obj==obj){
+this._events[evt][i]=null;
+}
+}
+},triggerEvent:function(evt,e){
+var ret,h;
+if(typeof e=="undefined"){
+e=this;
+}else{
+if(typeof e=="object"){
+e.event=evt;
+}
+}
+if(this._events&&this._events[evt]&&!this._event_exec){
+this._event_exec=true;
+for(var i=0;i<this._events[evt].length;i++){
+if((h=this._events[evt][i])){
+if(typeof h.func=="function"){
+ret=h.func.call?h.func.call(h.obj,e):h.func(e);
+}else{
+if(typeof h.obj[h.func]=="function"){
+ret=h.obj[h.func](e);
+}
+}
+if(typeof ret!="undefined"&&!ret){
+break;
+}
+}
+}
+}
+this._event_exec=false;
+return ret;
+}};
+function rcube_layer(id,_20){
+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 _28=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(_28){
+_28.appendChild(obj);
+}else{
+document.body.appendChild(obj);
+}
+this.elm=obj;
+};
+if(_20!=null){
+this.create(_20);
+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.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.resize=function(w,h){
+this.css.width=w+"px";
+this.css.height=h+"px";
+this.width=w;
+this.height=h;
+};
+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(_2f){
+this.elm.innerHTML=_2f;
+};
+};
+function rcube_check_email(_30,_31){
+if(_30&&window.RegExp){
+var _32="[^\\x0d\\x22\\x5c\\x80-\\xff]";
+var _33="[^\\x0d\\x5b-\\x5d\\x80-\\xff]";
+var _34="[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+";
+var _35="\\x5c[\\x00-\\x7f]";
+var _36="\\x5b("+_33+"|"+_35+")*\\x5d";
+var _37="\\x22("+_32+"|"+_35+")*\\x22";
+var _38="("+_34+"|"+_36+")";
+var _39="("+_34+"|"+_37+")";
+var _3a=_38+"(\\x2e"+_38+")*";
+var _3b=_39+"(\\x2e"+_39+")*";
+var _3c=_3b+"\\x40"+_3a;
+var _3d="[,;s\n]";
+var _3e=_31?new RegExp("(^|<|"+_3d+")"+_3c+"($|>|"+_3d+")","i"):new RegExp("^"+_3c+"$","i");
+return _3e.test(_30)?true:false;
+}
+return false;
+};
+function find_in_array(){
+var _3f=find_in_array.arguments;
+if(!_3f.length){
+return -1;
+}
+var _40=typeof (_3f[0])=="object"?_3f[0]:_3f.length>1&&typeof (_3f[1])=="object"?_3f[1]:new Array();
+var _41=typeof (_3f[0])!="object"?_3f[0]:_3f.length>1&&typeof (_3f[1])!="object"?_3f[1]:"";
+var _42=_3f.length==3?_3f[2]:false;
+if(!_40.length){
+return -1;
+}
+for(var i=0;i<_40.length;i++){
+if(_42&&_40[i].toLowerCase()==_41.toLowerCase()){
+return i;
+}else{
+if(_40[i]==_41){
+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_mouse_is_over(ev,obj){
+var _4d=rcube_event.get_mouse_pos(ev);
+var pos=$(obj).offset();
+return ((_4d.x>=pos.left)&&(_4d.x<(pos.left+obj.offsetWidth))&&(_4d.y>=pos.top)&&(_4d.y<(pos.top+obj.offsetHeight)));
+};
+function setCookie(_4f,_50,_51,_52,_53,_54){
+var _55=_4f+"="+escape(_50)+(_51?"; expires="+_51.toGMTString():"")+(_52?"; path="+_52:"")+(_53?"; domain="+_53:"")+(_54?"; secure":"");
+document.cookie=_55;
+};
+roundcube_browser.prototype.set_cookie=setCookie;
+function getCookie(_56){
+var dc=document.cookie;
+var _58=_56+"=";
+var _59=dc.indexOf("; "+_58);
+if(_59==-1){
+_59=dc.indexOf(_58);
+if(_59!=0){
+return null;
+}
+}else{
+_59+=2;
+}
+var end=document.cookie.indexOf(";",_59);
+if(end==-1){
+end=dc.length;
+}
+return unescape(dc.substring(_59+_58.length,end));
+};
+roundcube_browser.prototype.get_cookie=getCookie;
+function rcube_console(){
+this.log=function(msg){
+var box=rcube_find_object("dbgconsole");
+if(box){
+if(msg.charAt(msg.length-1)=="\n"){
+msg+="--------------------------------------\n";
+}else{
+msg+="\n--------------------------------------\n";
+}
+if(bw.konq){
+box.innerText+=msg;
+box.value=box.innerText;
+}else{
+box.value+=msg;
+}
+}
+};
+this.reset=function(){
+var box=rcube_find_object("dbgconsole");
+if(box){
+box.innerText=box.value="";
+}
+};
+};
+var bw=new roundcube_browser();
+if(!window.console){
+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;
+};
 }
 
-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;
-    }
-  }
diff --git a/program/js/common.js.src b/program/js/common.js.src
new file mode 100644 (file)
index 0000000..ba87246
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+ +-----------------------------------------------------------------------+
+ | 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 2971 2009-09-20 06:53:11Z 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.ie8 = (this.dom && this.appver.indexOf('MSIE 8')>0);
+  this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0);
+  this.ie6 = (this.dom && !this.ie8 && !this.ie7 && this.appver.indexOf('MSIE 6')>0);
+
+  this.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 DOM event handling
+var rcube_event = {
+
+/**
+ * returns the event target element
+ */
+get_target: function(e)
+{
+  e = e || window.event;
+  return e && e.target ? e.target : e.srcElement;
+},
+
+/**
+ * returns the event key code
+ */
+get_keycode: function(e)
+{
+  e = e || window.event;
+  return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
+},
+
+/**
+ * returns the event key code
+ */
+get_button: function(e)
+{
+  e = e || window.event;
+  return e && (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.left;
+    mY += e._offset.top;
+  }
+
+  return { x:mX, y:mY };
+},
+
+/**
+ * Add an object method as event listener to a certain element
+ */
+add_listener: function(p)
+{
+  if (!p.object || !p.method)  // not enough arguments
+    return;
+  if (!p.element)
+    p.element = document;
+
+  if (!p.object._rc_events)
+    p.object._rc_events = [];
+  
+  var key = p.event + '*' + p.method;
+  if (!p.object._rc_events[key])
+    p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
+
+  if (p.element.addEventListener)
+    p.element.addEventListener(p.event, p.object._rc_events[key], false);
+  else if (p.element.attachEvent)
+    {
+    // IE allows multiple events with the same function to be applied to the same object
+    // forcibly detach the event, then attach
+    p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
+    p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
+    }
+  else
+    p.element['on'+p.event] = p.object._rc_events[key];
+},
+
+/**
+ * Remove event listener
+ */
+remove_listener: function(p)
+{
+  if (!p.element)
+    p.element = document;
+
+  var key = p.event + '*' + p.method;
+  if (p.object && p.object._rc_events && p.object._rc_events[key]) {
+    if (p.element.removeEventListener)
+      p.element.removeEventListener(p.event, p.object._rc_events[key], false);
+    else if (p.element.detachEvent)
+      p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
+    else
+      p.element['on'+p.event] = null;
+  }
+},
+
+/**
+ * Prevent event propagation and 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;
+}
+
+};
+
+
+/**
+ * rcmail objects event interface
+ */
+function rcube_event_engine()
+{
+  this._events = {};
+}
+
+rcube_event_engine.prototype = {
+
+/**
+ * Setter for object event handlers
+ *
+ * @param {String}   Event name
+ * @param {Function} Handler function
+ * @return Listener ID (used to remove this handler later on)
+ */
+addEventListener: function(evt, func, obj)
+{
+  if (!this._events)
+    this._events = {};
+  if (!this._events[evt])
+    this._events[evt] = [];
+    
+  var e = {func:func, obj:obj ? obj : window};
+  this._events[evt][this._events[evt].length] = e;
+},
+
+/**
+ * Removes a specific event listener
+ *
+ * @param {String} Event name
+ * @param {Int}    Listener ID to remove
+ */
+removeEventListener: function(evt, func, obj)
+{
+  if (typeof obj == 'undefined')
+    obj = window;
+    
+  for (var h,i=0; this._events && this._events[evt] && i < this._events[evt].length; i++)
+    if ((h = this._events[evt][i]) && h.func == func && h.obj == obj)
+      this._events[evt][i] = null;
+},
+
+/**
+ * This will execute all registered event handlers
+ *
+ * @param {String} Event to trigger
+ * @param {Object} Event object/arguments
+ */
+triggerEvent: function(evt, e)
+{
+  var ret, h;
+  if (typeof e == 'undefined')
+    e = this;
+  else if (typeof e == 'object')
+    e.event = evt;
+  
+  if (this._events && this._events[evt] && !this._event_exec) {
+    this._event_exec = true;
+    for (var i=0; i < this._events[evt].length; i++) {
+      if ((h = this._events[evt][i])) {
+        if (typeof h.func == 'function')
+          ret = h.func.call ? h.func.call(h.obj, e) : h.func(e);
+        else if (typeof h.obj[h.func] == 'function')
+          ret = h.obj[h.func](e);
+              
+        // cancel event execution
+        if (typeof ret != 'undefined' && !ret)
+          break;
+      }
+    }
+  }
+
+  this._event_exec = false;
+  return ret;
+}
+
+}  // end rcube_event_engine.prototype
+
+
+
+/**
+ * RoundCube generic layer (floating box) class
+ *
+ * @constructor
+ */
+function rcube_layer(id, attributes)
+{
+  this.name = id;
+  
+  // create a new layer in the current document
+  this.create = function(arg)
+    {
+    var l = (arg.x) ? arg.x : 0;
+    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;
+
+
+  // ********* layer object methods *********
+
+
+  // move the layer to a specific position
+  this.move = function(x, y)
+    {
+    this.x = x;
+    this.y = y;
+    this.css.left = Math.round(this.x)+'px';
+    this.css.top = Math.round(this.y)+'px';
+    }
+
+  // change the layers width and height
+  this.resize = function(w,h)
+    {
+    this.css.width  = w+'px';
+    this.css.height = h+'px';
+    this.width = w;
+    this.height = h;
+    }
+
+
+  // show or hide the layer
+  this.show = function(a)
+    {
+    if(a==1)
+      {
+      this.css.visibility = 'visible';
+      this.visible = true;
+      }
+    else if(a==2)
+      {
+      this.css.visibility = 'inherit';
+      this.visible = true;
+      }
+    else
+      {
+      this.css.visibility = 'hidden';
+      this.visible = false;
+      }
+    }
+
+
+  // write new content into a Layer
+  this.write = function(cont)
+    {
+    this.elm.innerHTML = cont;
+    }
+
+}
+
+
+// check if input is a valid email address
+// By Cal Henderson <cal@iamcal.com>
+// http://code.iamcal.com/php/rfc822/
+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;
+}
+
+// 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 = $(obj).offset();
+
+  return ((mouse.x >= pos.left) && (mouse.x < (pos.left + obj.offsetWidth)) &&
+    (mouse.y >= pos.top) && (mouse.y < (pos.top + obj.offsetHeight)));
+}
+
+
+// cookie functions by GoogieSpell
+function setCookie(name, value, expires, path, domain, secure)
+  {
+  var curCookie = name + "=" + escape(value) +
+      (expires ? "; expires=" + expires.toGMTString() : "") +
+      (path ? "; path=" + path : "") +
+      (domain ? "; domain=" + domain : "") +
+      (secure ? "; secure" : "");
+  document.cookie = curCookie;
+  }
+
+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('dbgconsole');
+
+    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('dbgconsole');
+    if (box)
+      box.innerText = box.value = '';
+  };
+}
+
+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;
+    }
+  }
index 36fc1ab59688920f8bac41f0fd7899606559056c..2faafd339eb51fe2a4d3c1aac0c47e0587174938 100644 (file)
@@ -1,22 +1,12 @@
 
 var rc_client = tinyMCEPopup.getParam("rc_client");
-if (rc_client.gui_objects.attachmentlist)
+if (rc_client.env.attachments)
 {
    var tinyMCEImageList = new Array();
-   var attachElems = rc_client.gui_objects.attachmentlist.getElementsByTagName("li");
-   for (i = 0; i < attachElems.length; i++)
+   for (var id in rc_client.env.attachments)
    {
-      var liElem = attachElems[i];
-      var fname = attachElems[i].id;
-      for (j = 0; j < liElem.childNodes.length; j++)
-      {
-         if (liElem.childNodes[j].nodeName == "#text")
-         {
-            fname = liElem.childNodes[j].nodeValue;
-         }
-      }
-      
-      if (fname.match(/\.(bmp|gif|png|jpg|jpeg)$/))
-        tinyMCEImageList.push([fname, rc_client.env.comm_path+'&_action=display-attachment&_file='+attachElems[i].id]);
+      var att = rc_client.env.attachments[id];
+      if (att.complete && att.mimetype.indexOf('image/') == 0)
+        tinyMCEImageList.push([att.name, rc_client.env.comm_path+'&_action=display-attachment&_file='+id]);
    }
 };
index abd3462ecd267cb9f0b143529369631f14150460..48e8407fcb7e670e9c630d625c8a5e3d12037dc3 100644 (file)
-/*
- SpellCheck
-    jQuery'fied spell checker based on GoogieSpell 4.0
- Copyright Amir Salihefendic 2006
- Copyright Aleksander Machniak 2009
-     LICENSE
-         GPL
-     AUTHORS
-         4mir Salihefendic (http://amix.dk) - amix@amix.dk
-        Aleksander Machniak - alec [at] alec.pl
-*/
-
-var SPELL_CUR_LANG = null;
-var GOOGIE_DEFAULT_LANG = 'en';
-
-function GoogieSpell(img_dir, server_url) {
-    var ref = this;
-
-    this.array_keys = function(arr) {
-       var res = [];
-       for (var key in arr) { res.push([key]); }
-       return res;
-    }
-    
-    var cookie_value = getCookie('language');
-    GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG;
-
-    this.img_dir = img_dir;
-    this.server_url = server_url;
-
-    this.org_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.lang_to_word = this.org_lang_to_word;
-    this.langlist_codes = this.array_keys(this.lang_to_word);
-    this.show_change_lang_pic = true;
-    this.change_lang_pic_placement = 'right';
-    this.report_state_change = true;
-
-    this.ta_scroll_top = 0;
-    this.el_scroll_top = 0;
-
-    this.lang_chck_spell = "Check spelling";
-    this.lang_revert = "Revert to";
-    this.lang_close = "Close";
-    this.lang_rsm_edt = "Resume editing";
-    this.lang_no_error_found = "No spelling errors found";
-    this.lang_no_suggestions = "No suggestions";
-    
-    this.show_spell_img = false; // roundcube mod.
-    this.decoration = true;
-    this.use_close_btn = true;
-    this.edit_layer_dbl_click = true;
-    this.report_ta_not_found = true;
-
-    //Extensions
-    this.custom_ajax_error = null;
-    this.custom_no_spelling_error = null;
-    this.custom_menu_builder = []; //Should take an eval function and a build menu function
-    this.custom_item_evaulator = null; //Should take an eval function and a build menu function
-    this.extra_menu_items = [];
-    this.custom_spellcheck_starter = null;
-    this.main_controller = true;
-
-    //Observers
-    this.lang_state_observer = null;
-    this.spelling_state_observer = null;
-    this.show_menu_observer = null;
-    this.all_errors_fixed_observer = null;
-
-    //Focus links - used to give the text box focus
-    this.use_focus = false;
-    this.focus_link_t = null;
-    this.focus_link_b = null;
-
-    //Counters
-    this.cnt_errors = 0;
-    this.cnt_errors_fixed = 0;
-    
-    //Set document on click to hide the language and error menu
-    $(document).bind('click', function(e) {
-        if($(e.target).attr('googie_action_btn') != '1' && ref.isLangWindowShown())
-           ref.hideLangWindow();
-       if($(e.target).attr('googie_action_btn') != '1' && ref.isErrorWindowShown())
-            ref.hideErrorWindow();
-    });
-
-
-this.decorateTextarea = function(id) {
-    this.text_area = typeof(id) == 'string' ? document.getElementById(id) : id;
-
-    if (this.text_area) {
-        if (!this.spell_container && this.decoration) {
-            var table = document.createElement('table');
-            var tbody = document.createElement('tbody');
-            var tr = document.createElement('tr');
-            var spell_container = document.createElement('td');
-
-            var r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth;
-            var r_height = this.isDefined(this.force_height) ? this.force_height : 16;
-
-            tr.appendChild(spell_container);
-            tbody.appendChild(tr);
-            $(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height);
-            $(spell_container).height(r_height).width(r_width).css('text-align', 'right');
-
-            this.spell_container = spell_container;
-        }
-
-        this.checkSpellingState();
-    }
-    else 
-        if (this.report_ta_not_found)
-            alert('Text area not found');
-}
-
-//////
-// API Functions (the ones that you can call)
-/////
-this.setSpellContainer = function(id) {
-    this.spell_container = typeof(id) == 'string' ? document.getElementById(id) : id;
-
-}
-
-this.setLanguages = function(lang_dict) {
-    this.lang_to_word = lang_dict;
-    this.langlist_codes = this.array_keys(lang_dict);
-}
-
-this.setCurrentLanguage = function(lan_code) {
-    GOOGIE_CUR_LANG = lan_code;
-
-    //Set cookie
-    var now = new Date();
-    now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
-    setCookie('language', lan_code, now);
-}
-
-this.setForceWidthHeight = function(width, height) {
-    // Set to null if you want to use one of them
-    this.force_width = width;
-    this.force_height = height;
-}
-
-this.setDecoration = function(bool) {
-    this.decoration = bool;
-}
-
-this.dontUseCloseButtons = function() {
-    this.use_close_btn = false;
-}
-
-this.appendNewMenuItem = function(name, call_back_fn, checker) {
-    this.extra_menu_items.push([name, call_back_fn, checker]);
-}
-
-this.appendCustomMenuBuilder = function(eval, builder) {
-    this.custom_menu_builder.push([eval, builder]);
-}
-
-this.setFocus = function() {
-    try {
-        this.focus_link_b.focus();
-        this.focus_link_t.focus();
-        return true;
-    }
-    catch(e) {
-        return false;
-    }
-}
-
-
-//////
-// Set functions (internal)
-/////
-this.setStateChanged = function(current_state) {
-    this.state = current_state;
-    if (this.spelling_state_observer != null && this.report_state_change)
-        this.spelling_state_observer(current_state, this);
-}
-
-this.setReportStateChange = function(bool) {
-    this.report_state_change = bool;
-}
-
-
-//////
-// Request functions
-/////
-this.getUrl = function() {
-    return this.server_url + GOOGIE_CUR_LANG;
-}
-
-this.escapeSpecial = function(val) {
-    return val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
-}
-
-this.createXMLReq = function (text) {
-    return '<?xml version="1.0" encoding="utf-8" ?>'
-       + '<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
-       + '<text>' + text + '</text></spellrequest>';
-}
-
-this.spellCheck = function(ignore) {
-    this.cnt_errors_fixed = 0;
-    this.cnt_errors = 0;
-    this.setStateChanged('checking_spell');
-
-    if (this.main_controller)
-        this.appendIndicator(this.spell_span);
-
-    this.error_links = [];
-    this.ta_scroll_top = this.text_area.scrollTop;
-    this.ignore = ignore;
-    this.hideLangWindow();
-
-    if ($(this.text_area).val() == '' || ignore) {
-        if (!this.custom_no_spelling_error)
-            this.flashNoSpellingErrorState();
-        else
-            this.custom_no_spelling_error(this);
-        this.removeIndicator();
-        return;
-    }
-    
-    this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
-    this.createErrorWindow();
-    $('body').append(this.error_window);
-
-    try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 
-    catch (e) { }
-
-    if (this.main_controller)
-        $(this.spell_span).unbind('click');
-
-    this.orginal_text = $(this.text_area).val();
-    var req_text = this.escapeSpecial(this.orginal_text);
-    var ref = this;
-
-    $.ajax({ type: 'POST', url: this.getUrl(),
-       data: this.createXMLReq(req_text), dataType: 'text',
-       error: function(o) {
-           if (ref.custom_ajax_error)
-               ref.custom_ajax_error(ref);
-           else
-               alert('An error was encountered on the server. Please try again later.');
-           if (ref.main_controller) {
-               $(ref.spell_span).remove();
-               ref.removeIndicator();
-           }
-           ref.checkSpellingState();
-       },
-        success: function(data) {
-           var r_text = data;
-           ref.results = ref.parseResult(r_text);
-           if (r_text.match(/<c.*>/) != null) {
-               //Before parsing be sure that errors were found
-               ref.showErrorsInIframe();
-               ref.resumeEditingState();
-           } else {
-               if (!ref.custom_no_spelling_error)
-                   ref.flashNoSpellingErrorState();
-               else
-                   ref.custom_no_spelling_error(ref);
-           }
-           ref.removeIndicator();
-       }
-    });
+var SPELL_CUR_LANG=null;
+var GOOGIE_DEFAULT_LANG="en";
+function GoogieSpell(_1,_2){
+var _3=this;
+this.array_keys=function(_4){
+var _5=[];
+for(var _6 in _4){
+_5.push([_6]);
+}
+return _5;
+};
+var _7=getCookie("language");
+GOOGIE_CUR_LANG=_7!=null?_7:GOOGIE_DEFAULT_LANG;
+this.img_dir=_1;
+this.server_url=_2;
+this.org_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.lang_to_word=this.org_lang_to_word;
+this.langlist_codes=this.array_keys(this.lang_to_word);
+this.show_change_lang_pic=true;
+this.change_lang_pic_placement="right";
+this.report_state_change=true;
+this.ta_scroll_top=0;
+this.el_scroll_top=0;
+this.lang_chck_spell="Check spelling";
+this.lang_revert="Revert to";
+this.lang_close="Close";
+this.lang_rsm_edt="Resume editing";
+this.lang_no_error_found="No spelling errors found";
+this.lang_no_suggestions="No suggestions";
+this.show_spell_img=false;
+this.decoration=true;
+this.use_close_btn=true;
+this.edit_layer_dbl_click=true;
+this.report_ta_not_found=true;
+this.custom_ajax_error=null;
+this.custom_no_spelling_error=null;
+this.custom_menu_builder=[];
+this.custom_item_evaulator=null;
+this.extra_menu_items=[];
+this.custom_spellcheck_starter=null;
+this.main_controller=true;
+this.lang_state_observer=null;
+this.spelling_state_observer=null;
+this.show_menu_observer=null;
+this.all_errors_fixed_observer=null;
+this.use_focus=false;
+this.focus_link_t=null;
+this.focus_link_b=null;
+this.cnt_errors=0;
+this.cnt_errors_fixed=0;
+$(document).bind("click",function(e){
+if($(e.target).attr("googie_action_btn")!="1"&&_3.isLangWindowShown()){
+_3.hideLangWindow();
+}
+if($(e.target).attr("googie_action_btn")!="1"&&_3.isErrorWindowShown()){
+_3.hideErrorWindow();
+}
+});
+this.decorateTextarea=function(id){
+this.text_area=typeof (id)=="string"?document.getElementById(id):id;
+if(this.text_area){
+if(!this.spell_container&&this.decoration){
+var _a=document.createElement("table");
+var _b=document.createElement("tbody");
+var tr=document.createElement("tr");
+var _d=document.createElement("td");
+var _e=this.isDefined(this.force_width)?this.force_width:this.text_area.offsetWidth;
+var _f=this.isDefined(this.force_height)?this.force_height:16;
+tr.appendChild(_d);
+_b.appendChild(tr);
+$(_a).append(_b).insertBefore(this.text_area).width("100%").height(_f);
+$(_d).height(_f).width(_e).css("text-align","right");
+this.spell_container=_d;
+}
+this.checkSpellingState();
+}else{
+if(this.report_ta_not_found){
+alert("Text area not found");
 }
-
-
-//////
-// Spell checking functions
-/////
-this.parseResult = function(r_text) {
-    // Returns an array: result[item] -> ['attrs'], ['suggestions']
-    var re_split_attr_c = /\w+="(\d+|true)"/g;
-    var re_split_text = /\t/g;
-
-    var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g);
-    var results = new Array();
-
-    if (matched_c == null)
-        return results;
-    
-    for (var i=0; i < matched_c.length; i++) {
-        var item = new Array();
-        this.errorFound();
-
-        //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(/=/);
-            var val = c_attr[1].replace(/"/g, '');
-            item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val;
-        }
-
-        //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 menu functions
-/////
-this.createErrorWindow = function() {
-    this.error_window = document.createElement('div');
-    $(this.error_window).addClass('googie_window').attr('googie_action_btn', '1');
+};
+this.setSpellContainer=function(id){
+this.spell_container=typeof (id)=="string"?document.getElementById(id):id;
+};
+this.setLanguages=function(_11){
+this.lang_to_word=_11;
+this.langlist_codes=this.array_keys(_11);
+};
+this.setCurrentLanguage=function(_12){
+GOOGIE_CUR_LANG=_12;
+var now=new Date();
+now.setTime(now.getTime()+365*24*60*60*1000);
+setCookie("language",_12,now);
+};
+this.setForceWidthHeight=function(_14,_15){
+this.force_width=_14;
+this.force_height=_15;
+};
+this.setDecoration=function(_16){
+this.decoration=_16;
+};
+this.dontUseCloseButtons=function(){
+this.use_close_btn=false;
+};
+this.appendNewMenuItem=function(_17,_18,_19){
+this.extra_menu_items.push([_17,_18,_19]);
+};
+this.appendCustomMenuBuilder=function(_1a,_1b){
+this.custom_menu_builder.push([_1a,_1b]);
+};
+this.setFocus=function(){
+try{
+this.focus_link_b.focus();
+this.focus_link_t.focus();
+return true;
 }
-
-this.isErrorWindowShown = function() {
-    return $(this.error_window).is(':visible');
+catch(e){
+return false;
 }
-
-this.hideErrorWindow = function() {
-    $(this.error_window).css('visibility', 'hidden');
-    $(this.error_window_iframe).css('visibility', 'hidden');
+};
+this.setStateChanged=function(_1c){
+this.state=_1c;
+if(this.spelling_state_observer!=null&&this.report_state_change){
+this.spelling_state_observer(_1c,this);
 }
-
-this.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;
-    $(this.text_area).val(this.orginal_text);
-    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;
-    }
+};
+this.setReportStateChange=function(_1d){
+this.report_state_change=_1d;
+};
+this.getUrl=function(){
+return this.server_url+GOOGIE_CUR_LANG;
+};
+this.escapeSpecial=function(val){
+return val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
+};
+this.createXMLReq=function(_1f){
+return "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"+"<spellrequest textalreadyclipped=\"0\" ignoredups=\"0\" ignoredigits=\"1\" ignoreallcaps=\"1\">"+"<text>"+_1f+"</text></spellrequest>";
+};
+this.spellCheck=function(_20){
+this.cnt_errors_fixed=0;
+this.cnt_errors=0;
+this.setStateChanged("checking_spell");
+if(this.main_controller){
+this.appendIndicator(this.spell_span);
+}
+this.error_links=[];
+this.ta_scroll_top=this.text_area.scrollTop;
+this.ignore=_20;
+this.hideLangWindow();
+if($(this.text_area).val()==""||_20){
+if(!this.custom_no_spelling_error){
+this.flashNoSpellingErrorState();
+}else{
+this.custom_no_spelling_error(this);
+}
+this.removeIndicator();
+return;
+}
+this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight);
+this.createErrorWindow();
+$("body").append(this.error_window);
+try{
+netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+}
+catch(e){
+}
+if(this.main_controller){
+$(this.spell_span).unbind("click");
+}
+this.orginal_text=$(this.text_area).val();
+var _21=this.escapeSpecial(this.orginal_text);
+var ref=this;
+$.ajax({type:"POST",url:this.getUrl(),data:this.createXMLReq(_21),dataType:"text",error:function(o){
+if(ref.custom_ajax_error){
+ref.custom_ajax_error(ref);
+}else{
+alert("An error was encountered on the server. Please try again later.");
+}
+if(ref.main_controller){
+$(ref.spell_span).remove();
+ref.removeIndicator();
+}
+ref.checkSpellingState();
+},success:function(_24){
+var _25=_24;
+ref.results=ref.parseResult(_25);
+if(_25.match(/<c.*>/)!=null){
+ref.showErrorsInIframe();
+ref.resumeEditingState();
+}else{
+if(!ref.custom_no_spelling_error){
+ref.flashNoSpellingErrorState();
+}else{
+ref.custom_no_spelling_error(ref);
+}
+}
+ref.removeIndicator();
+}});
+};
+this.parseResult=function(_26){
+var _27=/\w+="(\d+|true)"/g;
+var _28=/\t/g;
+var _29=_26.match(/<c[^>]*>[^<]*<\/c>/g);
+var _2a=new Array();
+if(_29==null){
+return _2a;
+}
+for(var i=0;i<_29.length;i++){
+var _2c=new Array();
+this.errorFound();
+_2c["attrs"]=new Array();
+var _2d=_29[i].match(_27);
+for(var j=0;j<_2d.length;j++){
+var _2f=_2d[j].split(/=/);
+var val=_2f[1].replace(/"/g,"");
+_2c["attrs"][_2f[0]]=val!="true"?parseInt(val):val;
+}
+_2c["suggestions"]=new Array();
+var _31=_29[i].replace(/<[^>]*>/g,"");
+var _32=_31.split(_28);
+for(var k=0;k<_32.length;k++){
+if(_32[k]!=""){
+_2c["suggestions"].push(_32[k]);
+}
+}
+_2a.push(_2c);
+}
+return _2a;
+};
+this.createErrorWindow=function(){
+this.error_window=document.createElement("div");
+$(this.error_window).addClass("googie_window").attr("googie_action_btn","1");
+};
+this.isErrorWindowShown=function(){
+return $(this.error_window).is(":visible");
+};
+this.hideErrorWindow=function(){
+$(this.error_window).css("visibility","hidden");
+$(this.error_window_iframe).css("visibility","hidden");
+};
+this.updateOrginalText=function(_34,_35,_36,id){
+var _38=this.orginal_text.substring(0,_34);
+var _39=this.orginal_text.substring(_34+_35.length);
+this.orginal_text=_38+_36+_39;
+$(this.text_area).val(this.orginal_text);
+var _3a=_36.length-_35.length;
+for(var j=0;j<this.results.length;j++){
+if(j!=id&&j>id){
+this.results[j]["attrs"]["o"]+=_3a;
 }
-
-this.saveOldValue = function(elm, old_value) {
-    elm.is_changed = true;
-    elm.old_value = old_value;
 }
-
-this.createListSeparator = function() {
-    var td = document.createElement('td');
-    var tr = document.createElement('tr');
-
-    $(td).html(' ').attr('googie_action_btn', '1')
-       .css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'});
-    tr.appendChild(td);
-
-    return tr;
+};
+this.saveOldValue=function(elm,_3d){
+elm.is_changed=true;
+elm.old_value=_3d;
+};
+this.createListSeparator=function(){
+var td=document.createElement("td");
+var tr=document.createElement("tr");
+$(td).html(" ").attr("googie_action_btn","1").css({"cursor":"default","font-size":"3px","border-top":"1px solid #ccc","padding-top":"3px"});
+tr.appendChild(td);
+return tr;
+};
+this.correctError=function(id,elm,_42,_43){
+var _44=elm.innerHTML;
+var _45=_42.nodeType==3?_42.nodeValue:_42.innerHTML;
+var _46=this.results[id]["attrs"]["o"];
+if(_43){
+var _47=elm.previousSibling.innerHTML;
+elm.previousSibling.innerHTML=_47.slice(0,_47.length-1);
+_44=" "+_44;
+_46--;
+}
+this.hideErrorWindow();
+this.updateOrginalText(_46,_44,_45,id);
+$(elm).html(_45).css("color","green").attr("is_corrected",true);
+this.results[id]["attrs"]["l"]=_45.length;
+if(!this.isDefined(elm.old_value)){
+this.saveOldValue(elm,_44);
+}
+this.errorFixed();
+};
+this.showErrorWindow=function(elm,id){
+if(this.show_menu_observer){
+this.show_menu_observer(this);
+}
+var ref=this;
+var pos=$(elm).offset();
+pos.top-=this.edit_layer.scrollTop;
+$(this.error_window).css({"visibility":"visible","top":(pos.top+20)+"px","left":(pos.left)+"px"}).html("");
+var _4c=document.createElement("table");
+var _4d=document.createElement("tbody");
+$(_4c).addClass("googie_list").attr("googie_action_btn","1");
+var _4e=false;
+if(this.custom_menu_builder!=[]){
+for(var k=0;k<this.custom_menu_builder.length;k++){
+var eb=this.custom_menu_builder[k];
+if(eb[0]((this.results[id]))){
+_4e=eb[1](this,_4d,elm);
+break;
+}
+}
+}
+if(!_4e){
+var _51=this.results[id]["suggestions"];
+var _52=this.results[id]["attrs"]["o"];
+var len=this.results[id]["attrs"]["l"];
+if(_51.length==0){
+var row=document.createElement("tr");
+var _55=document.createElement("td");
+var _56=document.createElement("span");
+$(_56).text(this.lang_no_suggestions);
+$(_55).attr("googie_action_btn","1").css("cursor","default");
+_55.appendChild(_56);
+row.appendChild(_55);
+_4d.appendChild(row);
+}
+for(i=0;i<_51.length;i++){
+var row=document.createElement("tr");
+var _55=document.createElement("td");
+var _56=document.createElement("span");
+$(_56).html(_51[i]);
+$(_55).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout).bind("click",function(e){
+ref.correctError(id,elm,e.target.firstChild);
+});
+_55.appendChild(_56);
+row.appendChild(_55);
+_4d.appendChild(row);
+}
+if(elm.is_changed&&elm.innerHTML!=elm.old_value){
+var _58=elm.old_value;
+var _59=document.createElement("tr");
+var _5a=document.createElement("td");
+var _5b=document.createElement("span");
+$(_5b).addClass("googie_list_revert").html(this.lang_revert+" "+_58);
+$(_5a).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout).bind("click",function(e){
+ref.updateOrginalText(_52,elm.innerHTML,_58,id);
+$(elm).attr("is_corrected",true).css("color","#b91414").html(_58);
+ref.hideErrorWindow();
+});
+_5a.appendChild(_5b);
+_59.appendChild(_5a);
+_4d.appendChild(_59);
+}
+var _5d=document.createElement("tr");
+var _5e=document.createElement("td");
+var _5f=document.createElement("input");
+var _60=document.createElement("img");
+var _61=document.createElement("form");
+var _62=function(){
+if(_5f.value!=""){
+if(!ref.isDefined(elm.old_value)){
+ref.saveOldValue(elm,elm.innerHTML);
+}
+ref.updateOrginalText(_52,elm.innerHTML,_5f.value,id);
+$(elm).attr("is_corrected",true).css("color","green").html(_5f.value);
+ref.hideErrorWindow();
+}
+return false;
+};
+$(_5f).width(120).css({"margin":0,"padding":0});
+$(_5f).val(elm.innerHTML).attr("googie_action_btn","1");
+$(_5e).css("cursor","default").attr("googie_action_btn","1");
+$(_60).attr("src",this.img_dir+"ok.gif").width(32).height(16).css({"cursor":"pointer","margin-left":"2px","margin-right":"2px"}).bind("click",_62);
+$(_61).attr("googie_action_btn","1").css({"margin":0,"padding":0,"cursor":"default","white-space":"nowrap"}).bind("submit",_62);
+_61.appendChild(_5f);
+_61.appendChild(_60);
+_5e.appendChild(_61);
+_5d.appendChild(_5e);
+_4d.appendChild(_5d);
+if(this.extra_menu_items.length>0){
+_4d.appendChild(this.createListSeparator());
+}
+var _63=function(i){
+if(i<ref.extra_menu_items.length){
+var _65=ref.extra_menu_items[i];
+if(!_65[2]||_65[2](elm,ref)){
+var _66=document.createElement("tr");
+var _67=document.createElement("td");
+$(_67).html(_65[0]).bind("mouseover",ref.item_onmouseover).bind("mouseout",ref.item_onmouseout).bind("click",function(){
+return _65[1](elm,ref);
+});
+_66.appendChild(_67);
+_4d.appendChild(_66);
+}
+_63(i+1);
 }
-
-this.correctError = function(id, elm, l_elm, rm_pre_space) {
-    var old_value = elm.innerHTML;
-    var new_value = l_elm.nodeType == 3 ? l_elm.nodeValue : l_elm.innerHTML;
-    var offset = this.results[id]['attrs']['o'];
-
-    if (rm_pre_space) {
-        var pre_length = elm.previousSibling.innerHTML;
-        elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1);
-        old_value = " " + old_value;
-        offset--;
-    }
-
-    this.hideErrorWindow();
-    this.updateOrginalText(offset, old_value, new_value, id);
-
-    $(elm).html(new_value).css('color', 'green').attr('is_corrected', true);
-
-    this.results[id]['attrs']['l'] = new_value.length;
-
-    if (!this.isDefined(elm.old_value))
-        this.saveOldValue(elm, old_value);
-    
-    this.errorFixed();
+};
+_63(0);
+_63=null;
+if(this.use_close_btn){
+_4d.appendChild(this.createCloseButton(this.hideErrorWindow));
 }
-
-this.showErrorWindow = function(elm, id) {
-    if (this.show_menu_observer)
-        this.show_menu_observer(this);
-
-    var ref = this;
-    var pos = $(elm).offset();
-    pos.top -= this.edit_layer.scrollTop;
-
-    $(this.error_window).css({'visibility': 'visible',
-       'top': (pos.top+20)+'px', 'left': (pos.left)+'px'}).html('');
-
-    var table = document.createElement('table');
-    var list = document.createElement('tbody');
-
-    $(table).addClass('googie_list').attr('googie_action_btn', '1');
-
-    //Check if we should use custom menu builder, if not we use the default
-    var changed = false;
-    if (this.custom_menu_builder != []) {
-        for (var k=0; k<this.custom_menu_builder.length; k++) {
-            var eb = this.custom_menu_builder[k];
-            if(eb[0]((this.results[id]))){
-                changed = eb[1](this, list, elm);
-                break;
-            }
-        }
-    }
-    if (!changed) {
-        //Build up the result list
-        var suggestions = this.results[id]['suggestions'];
-        var offset = this.results[id]['attrs']['o'];
-        var len = this.results[id]['attrs']['l'];
-
-        if (suggestions.length == 0) {
-            var row = document.createElement('tr');
-            var item = document.createElement('td');
-            var dummy = document.createElement('span');
-
-            $(dummy).text(this.lang_no_suggestions);
-            $(item).attr('googie_action_btn', '1').css('cursor', 'default');
-
-            item.appendChild(dummy);
-            row.appendChild(item);
-            list.appendChild(row);
-        }
-
-        for (i=0; i < suggestions.length; i++) {
-            var row = document.createElement('tr');
-            var item = document.createElement('td');
-            var dummy = document.createElement('span');
-
-            $(dummy).html(suggestions[i]);
-            
-            $(item).bind('mouseover', this.item_onmouseover)
-               .bind('mouseout', this.item_onmouseout)
-               .bind('click', function(e) { ref.correctError(id, elm, e.target.firstChild) });
-
-            item.appendChild(dummy);
-            row.appendChild(item);
-            list.appendChild(row);
-        }
-
-        //The element is changed, append the revert
-        if (elm.is_changed && elm.innerHTML != elm.old_value) {
-            var old_value = elm.old_value;
-            var revert_row = document.createElement('tr');
-            var revert = document.createElement('td');
-            var rev_span = document.createElement('span');
-           
-           $(rev_span).addClass('googie_list_revert').html(this.lang_revert + ' ' + old_value);
-
-            $(revert).bind('mouseover', this.item_onmouseover)
-               .bind('mouseout', this.item_onmouseout)
-               .bind('click', function(e) {
-                   ref.updateOrginalText(offset, elm.innerHTML, old_value, id);
-                   $(elm).attr('is_corrected', true).css('color', '#b91414').html(old_value);
-                   ref.hideErrorWindow();
-               });
-
-            revert.appendChild(rev_span);
-            revert_row.appendChild(revert);
-            list.appendChild(revert_row);
-        }
-        
-        //Append the edit box
-        var edit_row = document.createElement('tr');
-        var edit = document.createElement('td');
-        var edit_input = document.createElement('input');
-        var ok_pic = document.createElement('img');
-       var edit_form = document.createElement('form');
-
-        var onsub = function () {
-            if (edit_input.value != '') {
-                if (!ref.isDefined(elm.old_value))
-                    ref.saveOldValue(elm, elm.innerHTML);
-
-                ref.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
-               $(elm).attr('is_corrected', true).css('color', 'green').html(edit_input.value);
-                ref.hideErrorWindow();
-            }
-            return false;
-        };
-
-       $(edit_input).width(120).css({'margin': 0, 'padding': 0});
-       $(edit_input).val(elm.innerHTML).attr('googie_action_btn', '1');
-       $(edit).css('cursor', 'default').attr('googie_action_btn', '1');
-
-       $(ok_pic).attr('src', this.img_dir + 'ok.gif')
-           .width(32).height(16)
-           .css({'cursor': 'pointer', 'margin-left': '2px', 'margin-right': '2px'})
-           .bind('click', onsub);
-
-        $(edit_form).attr('googie_action_btn', '1')
-           .css({'margin': 0, 'padding': 0, 'cursor': 'default', 'white-space': 'nowrap'})
-           .bind('submit', onsub);
-        
-       edit_form.appendChild(edit_input);
-       edit_form.appendChild(ok_pic);
-        edit.appendChild(edit_form);
-        edit_row.appendChild(edit);
-        list.appendChild(edit_row);
-
-        //Append extra menu items
-        if (this.extra_menu_items.length > 0)
-           list.appendChild(this.createListSeparator());
-       
-        var loop = function(i) {
-                if (i < ref.extra_menu_items.length) {
-                    var e_elm = ref.extra_menu_items[i];
-
-                    if (!e_elm[2] || e_elm[2](elm, ref)) {
-                        var e_row = document.createElement('tr');
-                        var e_col = document.createElement('td');
-
-                       $(e_col).html(e_elm[0])
-                           .bind('mouseover', ref.item_onmouseover)
-                           .bind('mouseout', ref.item_onmouseout)
-                           .bind('click', function() { return e_elm[1](elm, ref) });
-                       
-                       e_row.appendChild(e_col);
-                        list.appendChild(e_row);
-                    }
-                    loop(i+1);
-                }
-        }
-       
-        loop(0);
-        loop = null;
-
-        //Close button
-        if (this.use_close_btn) {
-           list.appendChild(this.createCloseButton(this.hideErrorWindow));
-        }
-    }
-
-    table.appendChild(list);
-    this.error_window.appendChild(table);
-
-    //Dummy for IE - dropdown bug fix
-    if ($.browser.msie) {
-       if (!this.error_window_iframe) {
-            var iframe = $('<iframe>').css('position', 'absolute').css('z-index', 0);
-           $('body').append(iframe);
-           this.error_window_iframe = iframe;
-        }
-       
-       $(this.error_window_iframe).css({'visibility': 'visible',
-           'top': this.error_window.offsetTop, 'left': this.error_window.offsetLeft,
-           'width': this.error_window.offsetWidth, 'height': this.error_window.offsetHeight});
-    }
 }
-
-
-//////
-// Edit layer (the layer where the suggestions are stored)
-//////
-this.createEditLayer = function(width, height) {
-    this.edit_layer = document.createElement('div');
-    $(this.edit_layer).addClass('googie_edit_layer').width(width-10).height(height);
-
-    if (this.text_area.nodeName.toLowerCase() != 'input' || $(this.text_area).val() == '') {
-        $(this.edit_layer).css('overflow', 'auto').height(height-4);
-    } else {
-        $(this.edit_layer).css('overflow', 'hidden');
-    }
-
-    var ref = this;
-    if (this.edit_layer_dbl_click) {
-        $(this.edit_layer).bind('click', function(e) {
-            if (e.target.className != 'googie_link' && !ref.isErrorWindowShown()) {
-                ref.resumeEditing();
-                var fn1 = function() {
-                    $(ref.text_area).focus();
-                    fn1 = null;
-                };
-                window.setTimeout(fn1, 10);
-            }
-            return false;
-        });
-    }
+_4c.appendChild(_4d);
+this.error_window.appendChild(_4c);
+if($.browser.msie){
+if(!this.error_window_iframe){
+var _68=$("<iframe>").css("position","absolute").css("z-index",0);
+$("body").append(_68);
+this.error_window_iframe=_68;
 }
-
-this.resumeEditing = function() {
-    this.setStateChanged('ready');
-
-    if (this.edit_layer)
-        this.el_scroll_top = this.edit_layer.scrollTop;
-
-    this.hideErrorWindow();
-
-    if (this.main_controller)
-        $(this.spell_span).removeClass().addClass('googie_no_style');
-
-    if (!this.ignore) {
-        if (this.use_focus) {
-            $(this.focus_link_t).remove();
-            $(this.focus_link_b).remove();
-        }
-
-        $(this.edit_layer).remove();
-        $(this.text_area).show();
-
-        if (this.el_scroll_top != undefined)
-            this.text_area.scrollTop = this.el_scroll_top;
-    }
-    this.checkSpellingState(false);
+$(this.error_window_iframe).css({"visibility":"visible","top":this.error_window.offsetTop,"left":this.error_window.offsetLeft,"width":this.error_window.offsetWidth,"height":this.error_window.offsetHeight});
 }
-
-this.createErrorLink = function(text, id) {
-    var elm = document.createElement('span');
-    var ref = this;
-    var d = function (e) {
-           ref.showErrorWindow(elm, id);
-           d = null;
-           return false;
-    };
-    
-    $(elm).html(text).addClass('googie_link').bind('click', d)
-       .attr({'googie_action_btn' : '1', 'g_id' : id, 'is_corrected' : false});
-
-    return elm;
+};
+this.createEditLayer=function(_69,_6a){
+this.edit_layer=document.createElement("div");
+$(this.edit_layer).addClass("googie_edit_layer").width(_69-10).height(_6a);
+if(this.text_area.nodeName.toLowerCase()!="input"||$(this.text_area).val()==""){
+$(this.edit_layer).css("overflow","auto").height(_6a-4);
+}else{
+$(this.edit_layer).css("overflow","hidden");
+}
+var ref=this;
+if(this.edit_layer_dbl_click){
+$(this.edit_layer).bind("click",function(e){
+if(e.target.className!="googie_link"&&!ref.isErrorWindowShown()){
+ref.resumeEditing();
+var fn1=function(){
+$(ref.text_area).focus();
+fn1=null;
+};
+window.setTimeout(fn1,10);
 }
-
-this.createPart = function(txt_part) {
-    if (txt_part == " ")
-        return document.createTextNode(" ");
-
-    txt_part = this.escapeSpecial(txt_part);
-    txt_part = txt_part.replace(/\n/g, "<br>");
-    txt_part = txt_part.replace(/    /g, " &nbsp;");
-    txt_part = txt_part.replace(/^ /g, "&nbsp;");
-    txt_part = txt_part.replace(/ $/g, "&nbsp;");
-    
-    var span = document.createElement('span');
-    $(span).html(txt_part);
-    return span;
+return false;
+});
 }
-
-this.showErrorsInIframe = function() {
-    var output = document.createElement('div')
-    var pointer = 0;
-    var results = this.results;
-
-    if (results.length > 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 = this.createPart(part_1_text);
-    
-            output.appendChild(part_1);
-            pointer += offset - pointer;
-            
-            //If the last child was an error, then insert some space
-            var err_link = this.createErrorLink(this.orginal_text.substr(offset, len), i);
-            this.error_links.push(err_link);
-            output.appendChild(err_link);
-            pointer += len;
-        }
-        //Insert the rest of the orginal text
-        var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length);
-        var part_2 = this.createPart(part_2_text);
-
-        output.appendChild(part_2);
-    }
-    else
-        output.innerHTML = this.orginal_text;
-
-    $(output).css('text-align', 'left');
-
-    var me = this;
-    if (this.custom_item_evaulator)
-        $.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)});
-    
-    $(this.edit_layer).append(output);
-
-    //Hide text area and show edit layer
-    $(this.text_area).hide();
-    $(this.edit_layer).insertBefore(this.text_area);
-
-    if (this.use_focus) {
-        this.focus_link_t = this.createFocusLink('focus_t');
-        this.focus_link_b = this.createFocusLink('focus_b');
-
-        $(this.focus_link_t).insertBefore(this.edit_layer);
-        $(this.focus_link_b).insertAfter(this.edit_layer);
-    }
-
-//    this.edit_layer.scrollTop = this.ta_scroll_top;
+};
+this.resumeEditing=function(){
+this.setStateChanged("ready");
+if(this.edit_layer){
+this.el_scroll_top=this.edit_layer.scrollTop;
 }
-
-
-//////
-// Choose language menu
-//////
-this.createLangWindow = function() {
-    this.language_window = document.createElement('div');
-    $(this.language_window).addClass('googie_window')
-       .width(100).attr('googie_action_btn', '1');
-
-    //Build up the result list
-    var table = document.createElement('table');
-    var list = document.createElement('tbody');
-    var ref = this;
-
-    $(table).addClass('googie_list').width('100%');
-    this.lang_elms = new Array();
-
-    for (i=0; i < this.langlist_codes.length; i++) {
-        var row = document.createElement('tr');
-        var item = document.createElement('td');
-        var span = document.createElement('span');
-       
-       $(span).text(this.lang_to_word[this.langlist_codes[i]]);
-        this.lang_elms.push(item);
-
-        $(item).attr('googieId', this.langlist_codes[i])
-           .bind('click', function(e) {
-               ref.deHighlightCurSel();
-               ref.setCurrentLanguage($(this).attr('googieId'));
-
-               if (ref.lang_state_observer != null) {
-                   ref.lang_state_observer();
-               }
-
-               ref.highlightCurSel();
-               ref.hideLangWindow();
-           })
-           .bind('mouseover', function(e) { 
-               if (this.className != "googie_list_selected")
-                   this.className = "googie_list_onhover";
-           })
-           .bind('mouseout', function(e) { 
-               if (this.className != "googie_list_selected")
-                   this.className = "googie_list_onout"; 
-           });
-
-       item.appendChild(span);
-        row.appendChild(item);
-        list.appendChild(row);
-    }
-
-    //Close button
-    if (this.use_close_btn) {
-        list.appendChild(this.createCloseButton(function () { ref.hideLangWindow.apply(ref) }));
-    }
-
-    this.highlightCurSel();
-
-    table.appendChild(list);
-    this.language_window.appendChild(table);
+this.hideErrorWindow();
+if(this.main_controller){
+$(this.spell_span).removeClass().addClass("googie_no_style");
 }
-
-this.isLangWindowShown = function() {
-    return $(this.language_window).is(':hidden');
+if(!this.ignore){
+if(this.use_focus){
+$(this.focus_link_t).remove();
+$(this.focus_link_b).remove();
 }
-
-this.hideLangWindow = function() {
-    $(this.language_window).css('visibility', 'hidden');
-    $(this.switch_lan_pic).removeClass().addClass('googie_lang_3d_on');
+$(this.edit_layer).remove();
+$(this.text_area).show();
+if(this.el_scroll_top!=undefined){
+this.text_area.scrollTop=this.el_scroll_top;
 }
-
-this.deHighlightCurSel = function() {
-    $(this.lang_cur_elm).removeClass().addClass('googie_list_onout');
 }
-
-this.highlightCurSel = function() {
-    if (GOOGIE_CUR_LANG == null)
-        GOOGIE_CUR_LANG = GOOGIE_DEFAULT_LANG;
-    for (var i=0; i < this.lang_elms.length; i++) {
-        if ($(this.lang_elms[i]).attr('googieId') == GOOGIE_CUR_LANG) {
-            this.lang_elms[i].className = "googie_list_selected";
-            this.lang_cur_elm = this.lang_elms[i];
-        }
-        else {
-            this.lang_elms[i].className = "googie_list_onout";
-        }
-    }
+this.checkSpellingState(false);
+};
+this.createErrorLink=function(_6e,id){
+var elm=document.createElement("span");
+var ref=this;
+var d=function(e){
+ref.showErrorWindow(elm,id);
+d=null;
+return false;
+};
+$(elm).html(_6e).addClass("googie_link").bind("click",d).attr({"googie_action_btn":"1","g_id":id,"is_corrected":false});
+return elm;
+};
+this.createPart=function(_74){
+if(_74==" "){
+return document.createTextNode(" ");
+}
+_74=this.escapeSpecial(_74);
+_74=_74.replace(/\n/g,"<br>");
+_74=_74.replace(/    /g," &nbsp;");
+_74=_74.replace(/^ /g,"&nbsp;");
+_74=_74.replace(/ $/g,"&nbsp;");
+var _75=document.createElement("span");
+$(_75).html(_74);
+return _75;
+};
+this.showErrorsInIframe=function(){
+var _76=document.createElement("div");
+var _77=0;
+var _78=this.results;
+if(_78.length>0){
+for(var i=0;i<_78.length;i++){
+var _7a=_78[i]["attrs"]["o"];
+var len=_78[i]["attrs"]["l"];
+var _7c=this.orginal_text.substring(_77,_7a);
+var _7d=this.createPart(_7c);
+_76.appendChild(_7d);
+_77+=_7a-_77;
+var _7e=this.createErrorLink(this.orginal_text.substr(_7a,len),i);
+this.error_links.push(_7e);
+_76.appendChild(_7e);
+_77+=len;
+}
+var _7f=this.orginal_text.substr(_77,this.orginal_text.length);
+var _80=this.createPart(_7f);
+_76.appendChild(_80);
+}else{
+_76.innerHTML=this.orginal_text;
+}
+$(_76).css("text-align","left");
+var me=this;
+if(this.custom_item_evaulator){
+$.map(this.error_links,function(elm){
+me.custom_item_evaulator(me,elm);
+});
+}
+$(this.edit_layer).append(_76);
+$(this.text_area).hide();
+$(this.edit_layer).insertBefore(this.text_area);
+if(this.use_focus){
+this.focus_link_t=this.createFocusLink("focus_t");
+this.focus_link_b=this.createFocusLink("focus_b");
+$(this.focus_link_t).insertBefore(this.edit_layer);
+$(this.focus_link_b).insertAfter(this.edit_layer);
 }
-
-this.showLangWindow = function(elm) {
-    if (this.show_menu_observer)
-        this.show_menu_observer(this);
-
-    this.createLangWindow();
-    $('body').append(this.language_window);
-
-    var pos = $(elm).offset();
-    var top = pos.top + $(elm).height();
-    var left = this.change_lang_pic_placement == 'right' ? 
-       pos.left - 100 + $(elm).width() : pos.left + $(elm).width();
-
-    $(this.language_window).css({'visibility': 'visible', 'top' : top+'px','left' : left+'px'});
-
-    this.highlightCurSel();
+};
+this.createLangWindow=function(){
+this.language_window=document.createElement("div");
+$(this.language_window).addClass("googie_window").width(100).attr("googie_action_btn","1");
+var _83=document.createElement("table");
+var _84=document.createElement("tbody");
+var ref=this;
+$(_83).addClass("googie_list").width("100%");
+this.lang_elms=new Array();
+for(i=0;i<this.langlist_codes.length;i++){
+var row=document.createElement("tr");
+var _87=document.createElement("td");
+var _88=document.createElement("span");
+$(_88).text(this.lang_to_word[this.langlist_codes[i]]);
+this.lang_elms.push(_87);
+$(_87).attr("googieId",this.langlist_codes[i]).bind("click",function(e){
+ref.deHighlightCurSel();
+ref.setCurrentLanguage($(this).attr("googieId"));
+if(ref.lang_state_observer!=null){
+ref.lang_state_observer();
+}
+ref.highlightCurSel();
+ref.hideLangWindow();
+}).bind("mouseover",function(e){
+if(this.className!="googie_list_selected"){
+this.className="googie_list_onhover";
+}
+}).bind("mouseout",function(e){
+if(this.className!="googie_list_selected"){
+this.className="googie_list_onout";
+}
+});
+_87.appendChild(_88);
+row.appendChild(_87);
+_84.appendChild(row);
+}
+if(this.use_close_btn){
+_84.appendChild(this.createCloseButton(function(){
+ref.hideLangWindow.apply(ref);
+}));
+}
+this.highlightCurSel();
+_83.appendChild(_84);
+this.language_window.appendChild(_83);
+};
+this.isLangWindowShown=function(){
+return $(this.language_window).is(":hidden");
+};
+this.hideLangWindow=function(){
+$(this.language_window).css("visibility","hidden");
+$(this.switch_lan_pic).removeClass().addClass("googie_lang_3d_on");
+};
+this.deHighlightCurSel=function(){
+$(this.lang_cur_elm).removeClass().addClass("googie_list_onout");
+};
+this.highlightCurSel=function(){
+if(GOOGIE_CUR_LANG==null){
+GOOGIE_CUR_LANG=GOOGIE_DEFAULT_LANG;
 }
-
-this.createChangeLangPic = function() {
-    var img = $('<img>')
-       .attr({src: this.img_dir + 'change_lang.gif', 'alt': 'Change language', 'googie_action_btn': '1'});
-
-    var switch_lan = document.createElement('span');
-    var ref = this;
-
-    $(switch_lan).addClass('googie_lang_3d_on')
-       .append(img)
-       .bind('click', function(e) {
-           var elm = this.tagName.toLowerCase() == 'img' ? this.parentNode : this;
-           if($(elm).hasClass('googie_lang_3d_click')) {
-               elm.className = 'googie_lang_3d_on';
-               ref.hideLangWindow();
-           }
-           else {
-               elm.className = 'googie_lang_3d_click';
-               ref.showLangWindow(elm);
-           }
-       });
-
-    return switch_lan;
+for(var i=0;i<this.lang_elms.length;i++){
+if($(this.lang_elms[i]).attr("googieId")==GOOGIE_CUR_LANG){
+this.lang_elms[i].className="googie_list_selected";
+this.lang_cur_elm=this.lang_elms[i];
+}else{
+this.lang_elms[i].className="googie_list_onout";
 }
-
-this.createSpellDiv = function() {
-    var span = document.createElement('span');
-
-    $(span).addClass('googie_check_spelling_link').text(this.lang_chck_spell);
-
-    if (this.show_spell_img) {
-       $(span).append(' ').append($('<img>').attr('src', this.img_dir + 'spellc.gif'));
-    }
-    return span;
 }
-
-
-//////
-// State functions
-/////
-this.flashNoSpellingErrorState = function(on_finish) {
-    this.setStateChanged('no_error_found');
-
-    var ref = this;
-    if (this.main_controller) {
-       var no_spell_errors;
-       if (on_finish) {
-           var fn = function() {
-               on_finish();
-               ref.checkSpellingState();
-           };
-           no_spell_errors = fn;
-       }
-       else
-           no_spell_errors = function () { ref.checkSpellingState() };
-
-        var rsm = $('<span>').text(this.lang_no_error_found);
-        
-        $(this.switch_lan_pic).hide();
-       $(this.spell_span).empty().append(rsm)
-           .removeClass().addClass('googie_check_spelling_ok');
-
-        window.setTimeout(no_spell_errors, 1000);
-    }
+};
+this.showLangWindow=function(elm){
+if(this.show_menu_observer){
+this.show_menu_observer(this);
+}
+this.createLangWindow();
+$("body").append(this.language_window);
+var pos=$(elm).offset();
+var top=pos.top+$(elm).height();
+var _90=this.change_lang_pic_placement=="right"?pos.left-100+$(elm).width():pos.left+$(elm).width();
+$(this.language_window).css({"visibility":"visible","top":top+"px","left":_90+"px"});
+this.highlightCurSel();
+};
+this.createChangeLangPic=function(){
+var img=$("<img>").attr({src:this.img_dir+"change_lang.gif","alt":"Change language","googie_action_btn":"1"});
+var _92=document.createElement("span");
+var ref=this;
+$(_92).addClass("googie_lang_3d_on").append(img).bind("click",function(e){
+var elm=this.tagName.toLowerCase()=="img"?this.parentNode:this;
+if($(elm).hasClass("googie_lang_3d_click")){
+elm.className="googie_lang_3d_on";
+ref.hideLangWindow();
+}else{
+elm.className="googie_lang_3d_click";
+ref.showLangWindow(elm);
+}
+});
+return _92;
+};
+this.createSpellDiv=function(){
+var _96=document.createElement("span");
+$(_96).addClass("googie_check_spelling_link").text(this.lang_chck_spell);
+if(this.show_spell_img){
+$(_96).append(" ").append($("<img>").attr("src",this.img_dir+"spellc.gif"));
 }
-
-this.resumeEditingState = function() {
-    this.setStateChanged('resume_editing');
-
-    //Change link text to resume
-    if (this.main_controller) {
-        var rsm = $('<span>').text(this.lang_rsm_edt);
-       var ref = this;
-
-        $(this.switch_lan_pic).hide();
-        $(this.spell_span).empty().unbind().append(rsm)
-           .bind('click', function() { ref.resumeEditing() })
-           .removeClass().addClass('googie_resume_editing');
-    }
-
-    try { this.edit_layer.scrollTop = this.ta_scroll_top; }
-    catch (e) {};
+return _96;
+};
+this.flashNoSpellingErrorState=function(_97){
+this.setStateChanged("no_error_found");
+var ref=this;
+if(this.main_controller){
+var _99;
+if(_97){
+var fn=function(){
+_97();
+ref.checkSpellingState();
+};
+_99=fn;
+}else{
+_99=function(){
+ref.checkSpellingState();
+};
 }
-
-this.checkSpellingState = function(fire) {
-    if (fire)
-        this.setStateChanged('ready');
-
-    if (this.show_change_lang_pic)
-        this.switch_lan_pic = this.createChangeLangPic();
-    else
-        this.switch_lan_pic = document.createElement('span');
-
-    var span_chck = this.createSpellDiv();
-    var ref = this;
-
-    if (this.custom_spellcheck_starter)
-        $(span_chck).bind('click', function(e) { ref.custom_spellcheck_starter() });
-    else {
-        $(span_chck).bind('click', function(e) { ref.spellCheck() });
-    }
-
-    if (this.main_controller) {
-        if (this.change_lang_pic_placement == 'left') {
-           $(this.spell_container).empty().append(this.switch_lan_pic).append(' ').append(span_chck);
-        } else {
-           $(this.spell_container).empty().append(span_chck).append(' ').append(this.switch_lan_pic);
-       }
-    }
-
-    this.spell_span = span_chck;
+var rsm=$("<span>").text(this.lang_no_error_found);
+$(this.switch_lan_pic).hide();
+$(this.spell_span).empty().append(rsm).removeClass().addClass("googie_check_spelling_ok");
+window.setTimeout(_99,1000);
 }
-
-
-//////
-// Misc. functions
-/////
-this.isDefined = function(o) {
-    return (o != 'undefined' && o != null)
+};
+this.resumeEditingState=function(){
+this.setStateChanged("resume_editing");
+if(this.main_controller){
+var rsm=$("<span>").text(this.lang_rsm_edt);
+var ref=this;
+$(this.switch_lan_pic).hide();
+$(this.spell_span).empty().unbind().append(rsm).bind("click",function(){
+ref.resumeEditing();
+}).removeClass().addClass("googie_resume_editing");
 }
-
-this.errorFixed = function() { 
-    this.cnt_errors_fixed++; 
-    if (this.all_errors_fixed_observer)
-        if (this.cnt_errors_fixed == this.cnt_errors) {
-            this.hideErrorWindow();
-            this.all_errors_fixed_observer();
-        }
+try{
+this.edit_layer.scrollTop=this.ta_scroll_top;
 }
-
-this.errorFound = function() {
-    this.cnt_errors++;
+catch(e){
 }
-
-this.createCloseButton = function(c_fn) {
-    return this.createButton(this.lang_close, 'googie_list_close', c_fn);
+};
+this.checkSpellingState=function(_9e){
+if(_9e){
+this.setStateChanged("ready");
+}
+if(this.show_change_lang_pic){
+this.switch_lan_pic=this.createChangeLangPic();
+}else{
+this.switch_lan_pic=document.createElement("span");
+}
+var _9f=this.createSpellDiv();
+var ref=this;
+if(this.custom_spellcheck_starter){
+$(_9f).bind("click",function(e){
+ref.custom_spellcheck_starter();
+});
+}else{
+$(_9f).bind("click",function(e){
+ref.spellCheck();
+});
+}
+if(this.main_controller){
+if(this.change_lang_pic_placement=="left"){
+$(this.spell_container).empty().append(this.switch_lan_pic).append(" ").append(_9f);
+}else{
+$(this.spell_container).empty().append(_9f).append(" ").append(this.switch_lan_pic);
+}
+}
+this.spell_span=_9f;
+};
+this.isDefined=function(o){
+return (o!="undefined"&&o!=null);
+};
+this.errorFixed=function(){
+this.cnt_errors_fixed++;
+if(this.all_errors_fixed_observer){
+if(this.cnt_errors_fixed==this.cnt_errors){
+this.hideErrorWindow();
+this.all_errors_fixed_observer();
 }
-
-this.createButton = function(name, css_class, c_fn) {
-    var btn_row = document.createElement('tr');
-    var btn = document.createElement('td');
-    var spn_btn;
-
-    if (css_class) {
-        spn_btn = document.createElement('span');
-       $(spn_btn).addClass(css_class).html(name);
-    } else {
-        spn_btn = document.createTextNode(name);
-    }
-
-    $(btn).bind('click', c_fn)
-       .bind('mouseover', this.item_onmouseover)
-       .bind('mouseout', this.item_onmouseout);
-
-    btn.appendChild(spn_btn);
-    btn_row.appendChild(btn);
-
-    return btn_row;
 }
-
-this.removeIndicator = function(elm) {
-    //$(this.indicator).remove();
-    // roundcube mod.
-    if (window.rcmail)
-       rcmail.set_busy(false);
+};
+this.errorFound=function(){
+this.cnt_errors++;
+};
+this.createCloseButton=function(_a4){
+return this.createButton(this.lang_close,"googie_list_close",_a4);
+};
+this.createButton=function(_a5,_a6,_a7){
+var _a8=document.createElement("tr");
+var btn=document.createElement("td");
+var _aa;
+if(_a6){
+_aa=document.createElement("span");
+$(_aa).addClass(_a6).html(_a5);
+}else{
+_aa=document.createTextNode(_a5);
+}
+$(btn).bind("click",_a7).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout);
+btn.appendChild(_aa);
+_a8.appendChild(btn);
+return _a8;
+};
+this.removeIndicator=function(elm){
+if(window.rcmail){
+rcmail.set_busy(false);
 }
-
-this.appendIndicator = function(elm) {
-    // modified by roundcube
-    if (window.rcmail)
-       rcmail.set_busy(true, 'checking');
-/*    
-    this.indicator = document.createElement('img');
-    $(this.indicator).attr('src', this.img_dir + 'indicator.gif')
-       .css({'margin-right': '5px', 'text-decoration': 'none'}).width(16).height(16);
-    
-    if (elm)
-       $(this.indicator).insertBefore(elm);
-    else
-       $('body').append(this.indicator);
-*/                                 
+};
+this.appendIndicator=function(elm){
+if(window.rcmail){
+rcmail.set_busy(true,"checking");
 }
-
-this.createFocusLink = function(name) {
-    var link = document.createElement('a');
-    $(link).attr({'href': 'javascript:;', 'name': name});
-    return link;
+};
+this.createFocusLink=function(_ad){
+var _ae=document.createElement("a");
+$(_ae).attr({"href":"javascript:;","name":_ad});
+return _ae;
+};
+this.item_onmouseover=function(e){
+if(this.className!="googie_list_revert"&&this.className!="googie_list_close"){
+this.className="googie_list_onhover";
+}else{
+this.parentNode.className="googie_list_onhover";
 }
-
-this.item_onmouseover = function(e) {
-    if (this.className != "googie_list_revert" && this.className != "googie_list_close")
-        this.className = "googie_list_onhover";
-    else
-        this.parentNode.className = "googie_list_onhover";
-}
-this.item_onmouseout = function(e) {
-    if (this.className != "googie_list_revert" && this.className != "googie_list_close")
-        this.className = "googie_list_onout";
-    else
-        this.parentNode.className = "googie_list_onout";
+};
+this.item_onmouseout=function(e){
+if(this.className!="googie_list_revert"&&this.className!="googie_list_close"){
+this.className="googie_list_onout";
+}else{
+this.parentNode.className="googie_list_onout";
 }
-
-
 };
+};
+
diff --git a/program/js/googiespell.js.src b/program/js/googiespell.js.src
new file mode 100644 (file)
index 0000000..abd3462
--- /dev/null
@@ -0,0 +1,1006 @@
+/*
+ SpellCheck
+    jQuery'fied spell checker based on GoogieSpell 4.0
+ Copyright Amir Salihefendic 2006
+ Copyright Aleksander Machniak 2009
+     LICENSE
+         GPL
+     AUTHORS
+         4mir Salihefendic (http://amix.dk) - amix@amix.dk
+        Aleksander Machniak - alec [at] alec.pl
+*/
+
+var SPELL_CUR_LANG = null;
+var GOOGIE_DEFAULT_LANG = 'en';
+
+function GoogieSpell(img_dir, server_url) {
+    var ref = this;
+
+    this.array_keys = function(arr) {
+       var res = [];
+       for (var key in arr) { res.push([key]); }
+       return res;
+    }
+    
+    var cookie_value = getCookie('language');
+    GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG;
+
+    this.img_dir = img_dir;
+    this.server_url = server_url;
+
+    this.org_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.lang_to_word = this.org_lang_to_word;
+    this.langlist_codes = this.array_keys(this.lang_to_word);
+    this.show_change_lang_pic = true;
+    this.change_lang_pic_placement = 'right';
+    this.report_state_change = true;
+
+    this.ta_scroll_top = 0;
+    this.el_scroll_top = 0;
+
+    this.lang_chck_spell = "Check spelling";
+    this.lang_revert = "Revert to";
+    this.lang_close = "Close";
+    this.lang_rsm_edt = "Resume editing";
+    this.lang_no_error_found = "No spelling errors found";
+    this.lang_no_suggestions = "No suggestions";
+    
+    this.show_spell_img = false; // roundcube mod.
+    this.decoration = true;
+    this.use_close_btn = true;
+    this.edit_layer_dbl_click = true;
+    this.report_ta_not_found = true;
+
+    //Extensions
+    this.custom_ajax_error = null;
+    this.custom_no_spelling_error = null;
+    this.custom_menu_builder = []; //Should take an eval function and a build menu function
+    this.custom_item_evaulator = null; //Should take an eval function and a build menu function
+    this.extra_menu_items = [];
+    this.custom_spellcheck_starter = null;
+    this.main_controller = true;
+
+    //Observers
+    this.lang_state_observer = null;
+    this.spelling_state_observer = null;
+    this.show_menu_observer = null;
+    this.all_errors_fixed_observer = null;
+
+    //Focus links - used to give the text box focus
+    this.use_focus = false;
+    this.focus_link_t = null;
+    this.focus_link_b = null;
+
+    //Counters
+    this.cnt_errors = 0;
+    this.cnt_errors_fixed = 0;
+    
+    //Set document on click to hide the language and error menu
+    $(document).bind('click', function(e) {
+        if($(e.target).attr('googie_action_btn') != '1' && ref.isLangWindowShown())
+           ref.hideLangWindow();
+       if($(e.target).attr('googie_action_btn') != '1' && ref.isErrorWindowShown())
+            ref.hideErrorWindow();
+    });
+
+
+this.decorateTextarea = function(id) {
+    this.text_area = typeof(id) == 'string' ? document.getElementById(id) : id;
+
+    if (this.text_area) {
+        if (!this.spell_container && this.decoration) {
+            var table = document.createElement('table');
+            var tbody = document.createElement('tbody');
+            var tr = document.createElement('tr');
+            var spell_container = document.createElement('td');
+
+            var r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth;
+            var r_height = this.isDefined(this.force_height) ? this.force_height : 16;
+
+            tr.appendChild(spell_container);
+            tbody.appendChild(tr);
+            $(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height);
+            $(spell_container).height(r_height).width(r_width).css('text-align', 'right');
+
+            this.spell_container = spell_container;
+        }
+
+        this.checkSpellingState();
+    }
+    else 
+        if (this.report_ta_not_found)
+            alert('Text area not found');
+}
+
+//////
+// API Functions (the ones that you can call)
+/////
+this.setSpellContainer = function(id) {
+    this.spell_container = typeof(id) == 'string' ? document.getElementById(id) : id;
+
+}
+
+this.setLanguages = function(lang_dict) {
+    this.lang_to_word = lang_dict;
+    this.langlist_codes = this.array_keys(lang_dict);
+}
+
+this.setCurrentLanguage = function(lan_code) {
+    GOOGIE_CUR_LANG = lan_code;
+
+    //Set cookie
+    var now = new Date();
+    now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
+    setCookie('language', lan_code, now);
+}
+
+this.setForceWidthHeight = function(width, height) {
+    // Set to null if you want to use one of them
+    this.force_width = width;
+    this.force_height = height;
+}
+
+this.setDecoration = function(bool) {
+    this.decoration = bool;
+}
+
+this.dontUseCloseButtons = function() {
+    this.use_close_btn = false;
+}
+
+this.appendNewMenuItem = function(name, call_back_fn, checker) {
+    this.extra_menu_items.push([name, call_back_fn, checker]);
+}
+
+this.appendCustomMenuBuilder = function(eval, builder) {
+    this.custom_menu_builder.push([eval, builder]);
+}
+
+this.setFocus = function() {
+    try {
+        this.focus_link_b.focus();
+        this.focus_link_t.focus();
+        return true;
+    }
+    catch(e) {
+        return false;
+    }
+}
+
+
+//////
+// Set functions (internal)
+/////
+this.setStateChanged = function(current_state) {
+    this.state = current_state;
+    if (this.spelling_state_observer != null && this.report_state_change)
+        this.spelling_state_observer(current_state, this);
+}
+
+this.setReportStateChange = function(bool) {
+    this.report_state_change = bool;
+}
+
+
+//////
+// Request functions
+/////
+this.getUrl = function() {
+    return this.server_url + GOOGIE_CUR_LANG;
+}
+
+this.escapeSpecial = function(val) {
+    return val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
+}
+
+this.createXMLReq = function (text) {
+    return '<?xml version="1.0" encoding="utf-8" ?>'
+       + '<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
+       + '<text>' + text + '</text></spellrequest>';
+}
+
+this.spellCheck = function(ignore) {
+    this.cnt_errors_fixed = 0;
+    this.cnt_errors = 0;
+    this.setStateChanged('checking_spell');
+
+    if (this.main_controller)
+        this.appendIndicator(this.spell_span);
+
+    this.error_links = [];
+    this.ta_scroll_top = this.text_area.scrollTop;
+    this.ignore = ignore;
+    this.hideLangWindow();
+
+    if ($(this.text_area).val() == '' || ignore) {
+        if (!this.custom_no_spelling_error)
+            this.flashNoSpellingErrorState();
+        else
+            this.custom_no_spelling_error(this);
+        this.removeIndicator();
+        return;
+    }
+    
+    this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
+    this.createErrorWindow();
+    $('body').append(this.error_window);
+
+    try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 
+    catch (e) { }
+
+    if (this.main_controller)
+        $(this.spell_span).unbind('click');
+
+    this.orginal_text = $(this.text_area).val();
+    var req_text = this.escapeSpecial(this.orginal_text);
+    var ref = this;
+
+    $.ajax({ type: 'POST', url: this.getUrl(),
+       data: this.createXMLReq(req_text), dataType: 'text',
+       error: function(o) {
+           if (ref.custom_ajax_error)
+               ref.custom_ajax_error(ref);
+           else
+               alert('An error was encountered on the server. Please try again later.');
+           if (ref.main_controller) {
+               $(ref.spell_span).remove();
+               ref.removeIndicator();
+           }
+           ref.checkSpellingState();
+       },
+        success: function(data) {
+           var r_text = data;
+           ref.results = ref.parseResult(r_text);
+           if (r_text.match(/<c.*>/) != null) {
+               //Before parsing be sure that errors were found
+               ref.showErrorsInIframe();
+               ref.resumeEditingState();
+           } else {
+               if (!ref.custom_no_spelling_error)
+                   ref.flashNoSpellingErrorState();
+               else
+                   ref.custom_no_spelling_error(ref);
+           }
+           ref.removeIndicator();
+       }
+    });
+}
+
+
+//////
+// Spell checking functions
+/////
+this.parseResult = function(r_text) {
+    // Returns an array: result[item] -> ['attrs'], ['suggestions']
+    var re_split_attr_c = /\w+="(\d+|true)"/g;
+    var re_split_text = /\t/g;
+
+    var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g);
+    var results = new Array();
+
+    if (matched_c == null)
+        return results;
+    
+    for (var i=0; i < matched_c.length; i++) {
+        var item = new Array();
+        this.errorFound();
+
+        //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(/=/);
+            var val = c_attr[1].replace(/"/g, '');
+            item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val;
+        }
+
+        //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 menu functions
+/////
+this.createErrorWindow = function() {
+    this.error_window = document.createElement('div');
+    $(this.error_window).addClass('googie_window').attr('googie_action_btn', '1');
+}
+
+this.isErrorWindowShown = function() {
+    return $(this.error_window).is(':visible');
+}
+
+this.hideErrorWindow = function() {
+    $(this.error_window).css('visibility', 'hidden');
+    $(this.error_window_iframe).css('visibility', 'hidden');
+}
+
+this.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;
+    $(this.text_area).val(this.orginal_text);
+    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;
+    }
+}
+
+this.saveOldValue = function(elm, old_value) {
+    elm.is_changed = true;
+    elm.old_value = old_value;
+}
+
+this.createListSeparator = function() {
+    var td = document.createElement('td');
+    var tr = document.createElement('tr');
+
+    $(td).html(' ').attr('googie_action_btn', '1')
+       .css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'});
+    tr.appendChild(td);
+
+    return tr;
+}
+
+this.correctError = function(id, elm, l_elm, rm_pre_space) {
+    var old_value = elm.innerHTML;
+    var new_value = l_elm.nodeType == 3 ? l_elm.nodeValue : l_elm.innerHTML;
+    var offset = this.results[id]['attrs']['o'];
+
+    if (rm_pre_space) {
+        var pre_length = elm.previousSibling.innerHTML;
+        elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1);
+        old_value = " " + old_value;
+        offset--;
+    }
+
+    this.hideErrorWindow();
+    this.updateOrginalText(offset, old_value, new_value, id);
+
+    $(elm).html(new_value).css('color', 'green').attr('is_corrected', true);
+
+    this.results[id]['attrs']['l'] = new_value.length;
+
+    if (!this.isDefined(elm.old_value))
+        this.saveOldValue(elm, old_value);
+    
+    this.errorFixed();
+}
+
+this.showErrorWindow = function(elm, id) {
+    if (this.show_menu_observer)
+        this.show_menu_observer(this);
+
+    var ref = this;
+    var pos = $(elm).offset();
+    pos.top -= this.edit_layer.scrollTop;
+
+    $(this.error_window).css({'visibility': 'visible',
+       'top': (pos.top+20)+'px', 'left': (pos.left)+'px'}).html('');
+
+    var table = document.createElement('table');
+    var list = document.createElement('tbody');
+
+    $(table).addClass('googie_list').attr('googie_action_btn', '1');
+
+    //Check if we should use custom menu builder, if not we use the default
+    var changed = false;
+    if (this.custom_menu_builder != []) {
+        for (var k=0; k<this.custom_menu_builder.length; k++) {
+            var eb = this.custom_menu_builder[k];
+            if(eb[0]((this.results[id]))){
+                changed = eb[1](this, list, elm);
+                break;
+            }
+        }
+    }
+    if (!changed) {
+        //Build up the result list
+        var suggestions = this.results[id]['suggestions'];
+        var offset = this.results[id]['attrs']['o'];
+        var len = this.results[id]['attrs']['l'];
+
+        if (suggestions.length == 0) {
+            var row = document.createElement('tr');
+            var item = document.createElement('td');
+            var dummy = document.createElement('span');
+
+            $(dummy).text(this.lang_no_suggestions);
+            $(item).attr('googie_action_btn', '1').css('cursor', 'default');
+
+            item.appendChild(dummy);
+            row.appendChild(item);
+            list.appendChild(row);
+        }
+
+        for (i=0; i < suggestions.length; i++) {
+            var row = document.createElement('tr');
+            var item = document.createElement('td');
+            var dummy = document.createElement('span');
+
+            $(dummy).html(suggestions[i]);
+            
+            $(item).bind('mouseover', this.item_onmouseover)
+               .bind('mouseout', this.item_onmouseout)
+               .bind('click', function(e) { ref.correctError(id, elm, e.target.firstChild) });
+
+            item.appendChild(dummy);
+            row.appendChild(item);
+            list.appendChild(row);
+        }
+
+        //The element is changed, append the revert
+        if (elm.is_changed && elm.innerHTML != elm.old_value) {
+            var old_value = elm.old_value;
+            var revert_row = document.createElement('tr');
+            var revert = document.createElement('td');
+            var rev_span = document.createElement('span');
+           
+           $(rev_span).addClass('googie_list_revert').html(this.lang_revert + ' ' + old_value);
+
+            $(revert).bind('mouseover', this.item_onmouseover)
+               .bind('mouseout', this.item_onmouseout)
+               .bind('click', function(e) {
+                   ref.updateOrginalText(offset, elm.innerHTML, old_value, id);
+                   $(elm).attr('is_corrected', true).css('color', '#b91414').html(old_value);
+                   ref.hideErrorWindow();
+               });
+
+            revert.appendChild(rev_span);
+            revert_row.appendChild(revert);
+            list.appendChild(revert_row);
+        }
+        
+        //Append the edit box
+        var edit_row = document.createElement('tr');
+        var edit = document.createElement('td');
+        var edit_input = document.createElement('input');
+        var ok_pic = document.createElement('img');
+       var edit_form = document.createElement('form');
+
+        var onsub = function () {
+            if (edit_input.value != '') {
+                if (!ref.isDefined(elm.old_value))
+                    ref.saveOldValue(elm, elm.innerHTML);
+
+                ref.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
+               $(elm).attr('is_corrected', true).css('color', 'green').html(edit_input.value);
+                ref.hideErrorWindow();
+            }
+            return false;
+        };
+
+       $(edit_input).width(120).css({'margin': 0, 'padding': 0});
+       $(edit_input).val(elm.innerHTML).attr('googie_action_btn', '1');
+       $(edit).css('cursor', 'default').attr('googie_action_btn', '1');
+
+       $(ok_pic).attr('src', this.img_dir + 'ok.gif')
+           .width(32).height(16)
+           .css({'cursor': 'pointer', 'margin-left': '2px', 'margin-right': '2px'})
+           .bind('click', onsub);
+
+        $(edit_form).attr('googie_action_btn', '1')
+           .css({'margin': 0, 'padding': 0, 'cursor': 'default', 'white-space': 'nowrap'})
+           .bind('submit', onsub);
+        
+       edit_form.appendChild(edit_input);
+       edit_form.appendChild(ok_pic);
+        edit.appendChild(edit_form);
+        edit_row.appendChild(edit);
+        list.appendChild(edit_row);
+
+        //Append extra menu items
+        if (this.extra_menu_items.length > 0)
+           list.appendChild(this.createListSeparator());
+       
+        var loop = function(i) {
+                if (i < ref.extra_menu_items.length) {
+                    var e_elm = ref.extra_menu_items[i];
+
+                    if (!e_elm[2] || e_elm[2](elm, ref)) {
+                        var e_row = document.createElement('tr');
+                        var e_col = document.createElement('td');
+
+                       $(e_col).html(e_elm[0])
+                           .bind('mouseover', ref.item_onmouseover)
+                           .bind('mouseout', ref.item_onmouseout)
+                           .bind('click', function() { return e_elm[1](elm, ref) });
+                       
+                       e_row.appendChild(e_col);
+                        list.appendChild(e_row);
+                    }
+                    loop(i+1);
+                }
+        }
+       
+        loop(0);
+        loop = null;
+
+        //Close button
+        if (this.use_close_btn) {
+           list.appendChild(this.createCloseButton(this.hideErrorWindow));
+        }
+    }
+
+    table.appendChild(list);
+    this.error_window.appendChild(table);
+
+    //Dummy for IE - dropdown bug fix
+    if ($.browser.msie) {
+       if (!this.error_window_iframe) {
+            var iframe = $('<iframe>').css('position', 'absolute').css('z-index', 0);
+           $('body').append(iframe);
+           this.error_window_iframe = iframe;
+        }
+       
+       $(this.error_window_iframe).css({'visibility': 'visible',
+           'top': this.error_window.offsetTop, 'left': this.error_window.offsetLeft,
+           'width': this.error_window.offsetWidth, 'height': this.error_window.offsetHeight});
+    }
+}
+
+
+//////
+// Edit layer (the layer where the suggestions are stored)
+//////
+this.createEditLayer = function(width, height) {
+    this.edit_layer = document.createElement('div');
+    $(this.edit_layer).addClass('googie_edit_layer').width(width-10).height(height);
+
+    if (this.text_area.nodeName.toLowerCase() != 'input' || $(this.text_area).val() == '') {
+        $(this.edit_layer).css('overflow', 'auto').height(height-4);
+    } else {
+        $(this.edit_layer).css('overflow', 'hidden');
+    }
+
+    var ref = this;
+    if (this.edit_layer_dbl_click) {
+        $(this.edit_layer).bind('click', function(e) {
+            if (e.target.className != 'googie_link' && !ref.isErrorWindowShown()) {
+                ref.resumeEditing();
+                var fn1 = function() {
+                    $(ref.text_area).focus();
+                    fn1 = null;
+                };
+                window.setTimeout(fn1, 10);
+            }
+            return false;
+        });
+    }
+}
+
+this.resumeEditing = function() {
+    this.setStateChanged('ready');
+
+    if (this.edit_layer)
+        this.el_scroll_top = this.edit_layer.scrollTop;
+
+    this.hideErrorWindow();
+
+    if (this.main_controller)
+        $(this.spell_span).removeClass().addClass('googie_no_style');
+
+    if (!this.ignore) {
+        if (this.use_focus) {
+            $(this.focus_link_t).remove();
+            $(this.focus_link_b).remove();
+        }
+
+        $(this.edit_layer).remove();
+        $(this.text_area).show();
+
+        if (this.el_scroll_top != undefined)
+            this.text_area.scrollTop = this.el_scroll_top;
+    }
+    this.checkSpellingState(false);
+}
+
+this.createErrorLink = function(text, id) {
+    var elm = document.createElement('span');
+    var ref = this;
+    var d = function (e) {
+           ref.showErrorWindow(elm, id);
+           d = null;
+           return false;
+    };
+    
+    $(elm).html(text).addClass('googie_link').bind('click', d)
+       .attr({'googie_action_btn' : '1', 'g_id' : id, 'is_corrected' : false});
+
+    return elm;
+}
+
+this.createPart = function(txt_part) {
+    if (txt_part == " ")
+        return document.createTextNode(" ");
+
+    txt_part = this.escapeSpecial(txt_part);
+    txt_part = txt_part.replace(/\n/g, "<br>");
+    txt_part = txt_part.replace(/    /g, " &nbsp;");
+    txt_part = txt_part.replace(/^ /g, "&nbsp;");
+    txt_part = txt_part.replace(/ $/g, "&nbsp;");
+    
+    var span = document.createElement('span');
+    $(span).html(txt_part);
+    return span;
+}
+
+this.showErrorsInIframe = function() {
+    var output = document.createElement('div')
+    var pointer = 0;
+    var results = this.results;
+
+    if (results.length > 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 = this.createPart(part_1_text);
+    
+            output.appendChild(part_1);
+            pointer += offset - pointer;
+            
+            //If the last child was an error, then insert some space
+            var err_link = this.createErrorLink(this.orginal_text.substr(offset, len), i);
+            this.error_links.push(err_link);
+            output.appendChild(err_link);
+            pointer += len;
+        }
+        //Insert the rest of the orginal text
+        var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length);
+        var part_2 = this.createPart(part_2_text);
+
+        output.appendChild(part_2);
+    }
+    else
+        output.innerHTML = this.orginal_text;
+
+    $(output).css('text-align', 'left');
+
+    var me = this;
+    if (this.custom_item_evaulator)
+        $.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)});
+    
+    $(this.edit_layer).append(output);
+
+    //Hide text area and show edit layer
+    $(this.text_area).hide();
+    $(this.edit_layer).insertBefore(this.text_area);
+
+    if (this.use_focus) {
+        this.focus_link_t = this.createFocusLink('focus_t');
+        this.focus_link_b = this.createFocusLink('focus_b');
+
+        $(this.focus_link_t).insertBefore(this.edit_layer);
+        $(this.focus_link_b).insertAfter(this.edit_layer);
+    }
+
+//    this.edit_layer.scrollTop = this.ta_scroll_top;
+}
+
+
+//////
+// Choose language menu
+//////
+this.createLangWindow = function() {
+    this.language_window = document.createElement('div');
+    $(this.language_window).addClass('googie_window')
+       .width(100).attr('googie_action_btn', '1');
+
+    //Build up the result list
+    var table = document.createElement('table');
+    var list = document.createElement('tbody');
+    var ref = this;
+
+    $(table).addClass('googie_list').width('100%');
+    this.lang_elms = new Array();
+
+    for (i=0; i < this.langlist_codes.length; i++) {
+        var row = document.createElement('tr');
+        var item = document.createElement('td');
+        var span = document.createElement('span');
+       
+       $(span).text(this.lang_to_word[this.langlist_codes[i]]);
+        this.lang_elms.push(item);
+
+        $(item).attr('googieId', this.langlist_codes[i])
+           .bind('click', function(e) {
+               ref.deHighlightCurSel();
+               ref.setCurrentLanguage($(this).attr('googieId'));
+
+               if (ref.lang_state_observer != null) {
+                   ref.lang_state_observer();
+               }
+
+               ref.highlightCurSel();
+               ref.hideLangWindow();
+           })
+           .bind('mouseover', function(e) { 
+               if (this.className != "googie_list_selected")
+                   this.className = "googie_list_onhover";
+           })
+           .bind('mouseout', function(e) { 
+               if (this.className != "googie_list_selected")
+                   this.className = "googie_list_onout"; 
+           });
+
+       item.appendChild(span);
+        row.appendChild(item);
+        list.appendChild(row);
+    }
+
+    //Close button
+    if (this.use_close_btn) {
+        list.appendChild(this.createCloseButton(function () { ref.hideLangWindow.apply(ref) }));
+    }
+
+    this.highlightCurSel();
+
+    table.appendChild(list);
+    this.language_window.appendChild(table);
+}
+
+this.isLangWindowShown = function() {
+    return $(this.language_window).is(':hidden');
+}
+
+this.hideLangWindow = function() {
+    $(this.language_window).css('visibility', 'hidden');
+    $(this.switch_lan_pic).removeClass().addClass('googie_lang_3d_on');
+}
+
+this.deHighlightCurSel = function() {
+    $(this.lang_cur_elm).removeClass().addClass('googie_list_onout');
+}
+
+this.highlightCurSel = function() {
+    if (GOOGIE_CUR_LANG == null)
+        GOOGIE_CUR_LANG = GOOGIE_DEFAULT_LANG;
+    for (var i=0; i < this.lang_elms.length; i++) {
+        if ($(this.lang_elms[i]).attr('googieId') == GOOGIE_CUR_LANG) {
+            this.lang_elms[i].className = "googie_list_selected";
+            this.lang_cur_elm = this.lang_elms[i];
+        }
+        else {
+            this.lang_elms[i].className = "googie_list_onout";
+        }
+    }
+}
+
+this.showLangWindow = function(elm) {
+    if (this.show_menu_observer)
+        this.show_menu_observer(this);
+
+    this.createLangWindow();
+    $('body').append(this.language_window);
+
+    var pos = $(elm).offset();
+    var top = pos.top + $(elm).height();
+    var left = this.change_lang_pic_placement == 'right' ? 
+       pos.left - 100 + $(elm).width() : pos.left + $(elm).width();
+
+    $(this.language_window).css({'visibility': 'visible', 'top' : top+'px','left' : left+'px'});
+
+    this.highlightCurSel();
+}
+
+this.createChangeLangPic = function() {
+    var img = $('<img>')
+       .attr({src: this.img_dir + 'change_lang.gif', 'alt': 'Change language', 'googie_action_btn': '1'});
+
+    var switch_lan = document.createElement('span');
+    var ref = this;
+
+    $(switch_lan).addClass('googie_lang_3d_on')
+       .append(img)
+       .bind('click', function(e) {
+           var elm = this.tagName.toLowerCase() == 'img' ? this.parentNode : this;
+           if($(elm).hasClass('googie_lang_3d_click')) {
+               elm.className = 'googie_lang_3d_on';
+               ref.hideLangWindow();
+           }
+           else {
+               elm.className = 'googie_lang_3d_click';
+               ref.showLangWindow(elm);
+           }
+       });
+
+    return switch_lan;
+}
+
+this.createSpellDiv = function() {
+    var span = document.createElement('span');
+
+    $(span).addClass('googie_check_spelling_link').text(this.lang_chck_spell);
+
+    if (this.show_spell_img) {
+       $(span).append(' ').append($('<img>').attr('src', this.img_dir + 'spellc.gif'));
+    }
+    return span;
+}
+
+
+//////
+// State functions
+/////
+this.flashNoSpellingErrorState = function(on_finish) {
+    this.setStateChanged('no_error_found');
+
+    var ref = this;
+    if (this.main_controller) {
+       var no_spell_errors;
+       if (on_finish) {
+           var fn = function() {
+               on_finish();
+               ref.checkSpellingState();
+           };
+           no_spell_errors = fn;
+       }
+       else
+           no_spell_errors = function () { ref.checkSpellingState() };
+
+        var rsm = $('<span>').text(this.lang_no_error_found);
+        
+        $(this.switch_lan_pic).hide();
+       $(this.spell_span).empty().append(rsm)
+           .removeClass().addClass('googie_check_spelling_ok');
+
+        window.setTimeout(no_spell_errors, 1000);
+    }
+}
+
+this.resumeEditingState = function() {
+    this.setStateChanged('resume_editing');
+
+    //Change link text to resume
+    if (this.main_controller) {
+        var rsm = $('<span>').text(this.lang_rsm_edt);
+       var ref = this;
+
+        $(this.switch_lan_pic).hide();
+        $(this.spell_span).empty().unbind().append(rsm)
+           .bind('click', function() { ref.resumeEditing() })
+           .removeClass().addClass('googie_resume_editing');
+    }
+
+    try { this.edit_layer.scrollTop = this.ta_scroll_top; }
+    catch (e) {};
+}
+
+this.checkSpellingState = function(fire) {
+    if (fire)
+        this.setStateChanged('ready');
+
+    if (this.show_change_lang_pic)
+        this.switch_lan_pic = this.createChangeLangPic();
+    else
+        this.switch_lan_pic = document.createElement('span');
+
+    var span_chck = this.createSpellDiv();
+    var ref = this;
+
+    if (this.custom_spellcheck_starter)
+        $(span_chck).bind('click', function(e) { ref.custom_spellcheck_starter() });
+    else {
+        $(span_chck).bind('click', function(e) { ref.spellCheck() });
+    }
+
+    if (this.main_controller) {
+        if (this.change_lang_pic_placement == 'left') {
+           $(this.spell_container).empty().append(this.switch_lan_pic).append(' ').append(span_chck);
+        } else {
+           $(this.spell_container).empty().append(span_chck).append(' ').append(this.switch_lan_pic);
+       }
+    }
+
+    this.spell_span = span_chck;
+}
+
+
+//////
+// Misc. functions
+/////
+this.isDefined = function(o) {
+    return (o != 'undefined' && o != null)
+}
+
+this.errorFixed = function() { 
+    this.cnt_errors_fixed++; 
+    if (this.all_errors_fixed_observer)
+        if (this.cnt_errors_fixed == this.cnt_errors) {
+            this.hideErrorWindow();
+            this.all_errors_fixed_observer();
+        }
+}
+
+this.errorFound = function() {
+    this.cnt_errors++;
+}
+
+this.createCloseButton = function(c_fn) {
+    return this.createButton(this.lang_close, 'googie_list_close', c_fn);
+}
+
+this.createButton = function(name, css_class, c_fn) {
+    var btn_row = document.createElement('tr');
+    var btn = document.createElement('td');
+    var spn_btn;
+
+    if (css_class) {
+        spn_btn = document.createElement('span');
+       $(spn_btn).addClass(css_class).html(name);
+    } else {
+        spn_btn = document.createTextNode(name);
+    }
+
+    $(btn).bind('click', c_fn)
+       .bind('mouseover', this.item_onmouseover)
+       .bind('mouseout', this.item_onmouseout);
+
+    btn.appendChild(spn_btn);
+    btn_row.appendChild(btn);
+
+    return btn_row;
+}
+
+this.removeIndicator = function(elm) {
+    //$(this.indicator).remove();
+    // roundcube mod.
+    if (window.rcmail)
+       rcmail.set_busy(false);
+}
+
+this.appendIndicator = function(elm) {
+    // modified by roundcube
+    if (window.rcmail)
+       rcmail.set_busy(true, 'checking');
+/*    
+    this.indicator = document.createElement('img');
+    $(this.indicator).attr('src', this.img_dir + 'indicator.gif')
+       .css({'margin-right': '5px', 'text-decoration': 'none'}).width(16).height(16);
+    
+    if (elm)
+       $(this.indicator).insertBefore(elm);
+    else
+       $('body').append(this.indicator);
+*/                                 
+}
+
+this.createFocusLink = function(name) {
+    var link = document.createElement('a');
+    $(link).attr({'href': 'javascript:;', 'name': name});
+    return link;
+}
+
+this.item_onmouseover = function(e) {
+    if (this.className != "googie_list_revert" && this.className != "googie_list_close")
+        this.className = "googie_list_onhover";
+    else
+        this.parentNode.className = "googie_list_onhover";
+}
+this.item_onmouseout = function(e) {
+    if (this.className != "googie_list_revert" && this.className != "googie_list_close")
+        this.className = "googie_list_onout";
+    else
+        this.parentNode.className = "googie_list_onout";
+}
+
+
+};
index 2588556eea2c131f2fc692c02de28f5fd845dc31..8bd9aac88e876d45195aa989262a5073a70f42c5 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 2761 2009-07-17 08:46:59Z 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(){};
-  
-  // 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:bw.opera?'keypress':'keydown', object:this, method:'key_press'});
-      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
-    }
-  }
-},
-
-
-/**
- * Init list row and set mouse events on it
- */
-init_row: function(row)
-{
-  // make references in internal array and set event handlers
-  if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i))
-  {
-    var 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]);
-  }
-},
-
-
-/**
- * Remove all list rows
- */
-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--;
-},
-
-
-/**
- * Add row to the list and initialize it
- */
-insert_row: function(row, attop)
-{
-  if (this.background)
-    var tbody = this.background;
-  else
-    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.rows[id].obj).addClass('selected').removeClass('unfocused');
-    }
-  }
-
-  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.rows[id].obj).removeClass('selected').addClass('unfocused');
-    }
-  }
-},
-
-
-/**
- * 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);
-  var tagname = evtarget.tagName.toLowerCase();
-  if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img')))
-    return true;
-    
-  // accept right-clicks
-  if (rcube_event.get_button(e) == 2)
-    return true;
-  
-  this.in_selection_before = 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 = $('#'+iframes[n].id).offset();
-        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);
-  var tagname = evtarget.tagName.toLowerCase();
-
-  if ((evtarget && (tagname == 'input' || tagname == 'img')))
-    return true;
-
-  // don't do anything (another action processed before)
-  if (this.dont_select)
-    {
-    this.dont_select = false;
-    return false;
-    }
-    
-  var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
-
-  // unselects currently selected row
-  if (!this.drag_active && this.in_selection_before == id && !dblclicked)
-    this.select_row(id, mod_key, false);
-
-  this.drag_start = false;
-  this.in_selection_before = false;
-
-  // row was double clicked
-  if (this.rows && dblclicked && this.in_selection(id))
-    this.triggerEvent('dblclick');
-  else
-    this.triggerEvent('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.triggerEvent('select');
-
-  if (this.last_selected != 0 && this.rows[this.last_selected])
-    $(this.rows[this.last_selected].obj).removeClass('focused');
-
-  // unselect if toggleselect is active and the same row was clicked again
-  if (this.toggleselect && this.last_selected == id)
-  {
-    this.clear_selection();
-    id = null;
-  }
-  else
-    $(this.rows[id].obj).addClass('focused');
-
-  if (!this.selection.length)
-    this.shift_start = null;
-
-  this.last_selected = id;
-},
-
-
-/**
- * Alias method for select_row
- */
-select: function(id)
-{
-  this.select_row(id, false);
-  this.scrollto(id);
-},
-
-
-/**
- * Select row next to the last selected one.
- * Either below or above.
- */
-select_next: function()
-{
-  var next_row = this.get_next_row();
-  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.rows[n].obj).removeClass('selected').removeClass('unfocused');
-    }
-  }
-
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.triggerEvent('select');
-
-  this.focus();
-
-  return true;
-},
-
-
-/**
- * Invert selection
- */
-invert_selection: function()
-{
-  if (!this.rows || !this.rows.length)
-    return false;
-
-  // remember old selection
-  var select_before = this.selection.join(',');
-  
-  for (var n in this.rows)
-    this.highlight_row(n, true);    
-
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.triggerEvent('select');
-
-  this.focus();
-
-  return true;
-},
-
-
-/**
- * Unselect selected row(s)
- */
-clear_selection: function(id)
-{
-  var 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.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused');
-        }
-    
-    this.selection = new Array();
-    }
-
-  if (num_select && !this.selection.length)
-    this.triggerEvent('select');
-},
-
-
-/**
- * Getter for the selection array
- */
-get_selection: function()
-{
-  return this.selection;
-},
-
-
-/**
- * Return the ID if only one row is selected
- */
-get_single_selection: function()
-{
-  if (this.selection.length == 1)
-    return this.selection[0];
-  else
-    return null;
-},
-
-
-/**
- * Highlight/unhighlight a row
- */
-highlight_row: function(id, multiple)
-{
-  if (this.rows[id] && !multiple)
-  {
-    if (this.selection.length > 1 || !this.in_selection(id))
-    {
-      this.clear_selection();
-      this.selection[0] = id;
-      $(this.rows[id].obj).addClass('selected');
-    }
-  }
-  else if (this.rows[id])
-  {
-    if (!this.in_selection(id))  // select row
-    {
-      this.selection[this.selection.length] = id;
-      $(this.rows[id].obj).addClass('selected');
-    }
-    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.rows[id].obj).removeClass('selected').removeClass('unfocused');
-    }
-  }
-},
-
-
-/**
- * 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.triggerEvent('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 27:
-      if (this.drag_active)
-       return this.drag_mouse_up(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 = $('<div>').attr('id', 'rcmdraglayer').css({ position:'absolute', display:'none', 'z-index':2000 }).appendTo(document.body);
-
-    // 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)))
-            {
-             if (n == 0) {
-               if (node.nodeType == 3)
-                 this.drag_start_pos = $(obj.childNodes[i]).offset();
-               else
-                  this.drag_start_pos = $(node).offset();
-             }
-              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.html(names);
-    this.draglayer.show();
-
-    this.drag_active = true;
-    this.triggerEvent('dragstart');
-  }
-
-  if (this.drag_active && this.draglayer)
-  {
-    var pos = rcube_event.get_mouse_pos(e);
-    this.draglayer.css({ left:(pos.x+20)+'px', top:(pos.y-5 + (bw.ie ? document.documentElement.scrollTop : 0))+'px' });
-    this.triggerEvent('dragmove', e?e:window.event);
-  }
-
-  this.drag_start = false;
-
-  return false;
-},
-
-
-/**
- * Handler for mouse up events
- */
-drag_mouse_up: function(e)
-{
-  document.onmousemove = null;
-
-  if (this.draglayer && this.draglayer.is(':visible')) {
-    if (this.drag_start_pos)
-      this.draglayer.animate(this.drag_start_pos, 300, 'swing').hide(20);
-    else
-      this.draglayer.hide();
-  }
-
-  this.drag_active = false;
-  this.triggerEvent('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);
-},
-
-
-/**
- * Creating the list in background
- */
-set_background_mode: function(flag)
-{
-  if (flag) {
-    this.background = document.createElement('tbody');
-  } else if (this.background) {
-    this.list.replaceChild(this.background, this.list.tBodies[0]);
-    this.background = null;
-  }
+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(){
+};
+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:bw.opera?"keypress":"keydown",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){
+if(this.background){
+var _11=this.background;
+}else{
+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.rows[id].obj).addClass("selected").removeClass("unfocused");
+}
+}
+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.rows[id].obj).removeClass("selected").addClass("unfocused");
+}
+}
+},drag_row:function(e,id){
+var _18=rcube_event.get_target(e);
+var _19=_18.tagName.toLowerCase();
+if(this.dont_select||(_18&&(_19=="input"||_19=="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 _1a=rcube_event.get_modifier(e);
+this.select_row(id,_1a,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 _1b=document.getElementsByTagName("iframe");
+this.iframe_events=Object();
+for(var n in _1b){
+var _1d=null;
+if(_1b[n].contentDocument){
+_1d=_1b[n].contentDocument;
+}else{
+if(_1b[n].contentWindow){
+_1d=_1b[n].contentWindow.document;
+}else{
+if(_1b[n].document){
+_1d=_1b[n].document;
+}
+}
+}
+if(_1d){
+var _1e=this;
+var pos=$("#"+_1b[n].id).offset();
+this.iframe_events[n]=function(e){
+e._offset=pos;
+return _1e.drag_mouse_move(e);
+};
+if(_1d.addEventListener){
+_1d.addEventListener("mousemove",this.iframe_events[n],false);
+}else{
+if(_1b[n].attachEvent){
+_1d.attachEvent("onmousemove",this.iframe_events[n]);
+}else{
+_1d["onmousemove"]=this.iframe_events[n];
+}
+}
+rcube_event.add_listener({element:_1d,event:"mouseup",object:this,method:"drag_mouse_up"});
+}
+}
+}
+return false;
+},click_row:function(e,id){
+var now=new Date().getTime();
+var _24=rcube_event.get_modifier(e);
+var _25=rcube_event.get_target(e);
+var _26=_25.tagName.toLowerCase();
+if((_25&&(_26=="input"||_26=="img"))){
+return true;
+}
+if(this.dont_select){
+this.dont_select=false;
+return false;
+}
+var _27=now-this.rows[id].clicked<this.dblclick_time;
+if(!this.drag_active&&this.in_selection_before==id&&!_27){
+this.select_row(id,_24,false);
+}
+this.drag_start=false;
+this.in_selection_before=false;
+if(this.rows&&_27&&this.in_selection(id)){
+this.triggerEvent("dblclick");
+}else{
+this.triggerEvent("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 _28=this.rows[this.last_selected];
+var _29=_28?_28.obj.nextSibling:null;
+while(_29&&(_29.nodeType!=1||_29.style.display=="none")){
+_29=_29.nextSibling;
+}
+return _29;
+},get_prev_row:function(){
+if(!this.rows){
+return false;
+}
+var _2a=this.rows[this.last_selected];
+var _2b=_2a?_2a.obj.previousSibling:null;
+while(_2b&&(_2b.nodeType!=1||_2b.style.display=="none")){
+_2b=_2b.previousSibling;
+}
+return _2b;
+},get_first_row:function(){
+if(this.rowcount){
+var _2c=this.list.tBodies[0].rows;
+for(var i=0;i<_2c.length-1;i++){
+if(_2c[i].id&&String(_2c[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null){
+return RegExp.$1;
+}
+}
+}
+return null;
+},get_last_row:function(){
+if(this.rowcount){
+var _2e=this.list.tBodies[0].rows;
+for(var i=_2e.length-1;i>=0;i--){
+if(_2e[i].id&&String(_2e[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null){
+return RegExp.$1;
+}
+}
+}
+return null;
+},select_row:function(id,_31,_32){
+var _33=this.selection.join(",");
+if(!this.multiselect){
+_31=0;
+}
+if(!this.shift_start){
+this.shift_start=id;
+}
+if(!_31){
+this.shift_start=id;
+this.highlight_row(id,false);
+this.multi_selecting=false;
+}else{
+switch(_31){
+case SHIFT_KEY:
+this.shift_select(id,false);
+break;
+case CONTROL_KEY:
+if(!_32){
+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(",")!=_33){
+this.triggerEvent("select");
+}
+if(this.last_selected!=0&&this.rows[this.last_selected]){
+$(this.rows[this.last_selected].obj).removeClass("focused");
+}
+if(this.toggleselect&&this.last_selected==id){
+this.clear_selection();
+id=null;
+}else{
+$(this.rows[id].obj).addClass("focused");
+}
+if(!this.selection.length){
+this.shift_start=null;
+}
+this.last_selected=id;
+},select:function(id){
+this.select_row(id,false);
+this.scrollto(id);
+},select_next:function(){
+var _35=this.get_next_row();
+var _36=this.get_prev_row();
+var _37=(_35)?_35:_36;
+if(_37){
+this.select_row(_37.uid,false,false);
+}
+},select_first:function(){
+var _38=this.get_first_row();
+if(_38){
+this.select_row(_38,false,false);
+}
+},shift_select:function(id,_3a){
+if(!this.rows[this.shift_start]||!this.selection.length){
+this.shift_start=id;
+}
+var _3b=this.rows[this.shift_start].obj.rowIndex;
+var _3c=this.rows[id].obj.rowIndex;
+var i=((_3b<_3c)?_3b:_3c);
+var j=((_3b>_3c)?_3b:_3c);
+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)&&!_3a){
+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(_42){
+if(!this.rows||!this.rows.length){
+return false;
+}
+var _43=this.selection.join(",");
+this.selection=new Array();
+for(var n in this.rows){
+if(!_42||(this.rows[n]&&this.rows[n][_42]==true)){
+this.last_selected=n;
+this.highlight_row(n,true);
+}else{
+if(this.rows[n]){
+$(this.rows[n].obj).removeClass("selected").removeClass("unfocused");
+}
+}
+}
+if(this.selection.join(",")!=_43){
+this.triggerEvent("select");
+}
+this.focus();
+return true;
+},invert_selection:function(){
+if(!this.rows||!this.rows.length){
+return false;
+}
+var _45=this.selection.join(",");
+for(var n in this.rows){
+this.highlight_row(n,true);
+}
+if(this.selection.join(",")!=_45){
+this.triggerEvent("select");
+}
+this.focus();
+return true;
+},clear_selection:function(id){
+var _48=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.rows[this.selection[n]].obj).removeClass("selected").removeClass("unfocused");
+}
+}
+this.selection=new Array();
+}
+if(_48&&!this.selection.length){
+this.triggerEvent("select");
+}
+},get_selection:function(){
+return this.selection;
+},get_single_selection:function(){
+if(this.selection.length==1){
+return this.selection[0];
+}else{
+return null;
+}
+},highlight_row:function(id,_4b){
+if(this.rows[id]&&!_4b){
+if(this.selection.length>1||!this.in_selection(id)){
+this.clear_selection();
+this.selection[0]=id;
+$(this.rows[id].obj).addClass("selected");
+}
+}else{
+if(this.rows[id]){
+if(!this.in_selection(id)){
+this.selection[this.selection.length]=id;
+$(this.rows[id].obj).addClass("selected");
+}else{
+var p=find_in_array(id,this.selection);
+var _4d=this.selection.slice(0,p);
+var _4e=this.selection.slice(p+1,this.selection.length);
+this.selection=_4d.concat(_4e);
+$(this.rows[id].obj).removeClass("selected").removeClass("unfocused");
+}
+}
+}
+},key_press:function(e){
+if(this.focused!=true){
+return true;
+}
+var _50=rcube_event.get_keycode(e);
+var _51=rcube_event.get_modifier(e);
+switch(_50){
+case 40:
+case 38:
+case 63233:
+case 63232:
+rcube_event.cancel(e);
+return this.use_arrow_key(_50,_51);
+default:
+this.shiftkey=e.shiftKey;
+this.key_pressed=_50;
+this.triggerEvent("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 27:
+if(this.drag_active){
+return this.drag_mouse_up(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(_53,_54){
+var _55;
+if(_53==40||_53==63233){
+_55=this.get_next_row();
+}else{
+if(_53==38||_53==63232){
+_55=this.get_prev_row();
+}
+}
+if(_55){
+this.select_row(_55.uid,_54,true);
+this.scrollto(_55.uid);
+}
+return false;
+},scrollto:function(id){
+var row=this.rows[id].obj;
+if(row&&this.frame){
+var _58=Number(row.offsetTop);
+if(_58<Number(this.frame.scrollTop)){
+this.frame.scrollTop=_58;
+}else{
+if(_58+Number(row.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight)){
+this.frame.scrollTop=(_58+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=$("<div>").attr("id","rcmdraglayer").css({position:"absolute",display:"none","z-index":2000}).appendTo(document.body);
+}
+var _5b="";
+var c,i,_5e,_5f,obj;
+for(var n=0;n<this.selection.length;n++){
+if(n>12){
+_5b+="...";
+break;
+}
+if(this.rows[this.selection[n]].obj){
+obj=this.rows[this.selection[n]].obj;
+_5f="";
+for(c=0,i=0;i<obj.childNodes.length;i++){
+if(obj.childNodes[i].nodeName=="TD"){
+if(((_5e=obj.childNodes[i].firstChild)&&(_5e.nodeType==3||_5e.nodeName=="A"))&&(this.subject_col<0||(this.subject_col>=0&&this.subject_col==c))){
+if(n==0){
+if(_5e.nodeType==3){
+this.drag_start_pos=$(obj.childNodes[i]).offset();
+}else{
+this.drag_start_pos=$(_5e).offset();
+}
+}
+_5f=_5e.nodeType==3?_5e.data:_5e.innerHTML;
+_5f=_5f.replace(/^\s+/i,"");
+_5b+=(_5f.length>50?_5f.substring(0,50)+"...":_5f)+"<br />";
+break;
+}
+c++;
+}
+}
+}
+}
+this.draglayer.html(_5b);
+this.draglayer.show();
+this.drag_active=true;
+this.triggerEvent("dragstart");
+}
+if(this.drag_active&&this.draglayer){
+var pos=rcube_event.get_mouse_pos(e);
+this.draglayer.css({left:(pos.x+20)+"px",top:(pos.y-5+(bw.ie?document.documentElement.scrollTop:0))+"px"});
+this.triggerEvent("dragmove",e?e:window.event);
+}
+this.drag_start=false;
+return false;
+},drag_mouse_up:function(e){
+document.onmousemove=null;
+if(this.draglayer&&this.draglayer.is(":visible")){
+if(this.drag_start_pos){
+this.draglayer.animate(this.drag_start_pos,300,"swing").hide(20);
+}else{
+this.draglayer.hide();
+}
+}
+this.drag_active=false;
+this.triggerEvent("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 _64=document.getElementsByTagName("iframe");
+for(var n in _64){
+var _66;
+if(_64[n].contentDocument){
+_66=_64[n].contentDocument;
+}else{
+if(_64[n].contentWindow){
+_66=_64[n].contentWindow.document;
+}else{
+if(_64[n].document){
+_66=_64[n].document;
+}
+}
+}
+if(_66){
+if(this.iframe_events[n]){
+if(_66.removeEventListener){
+_66.removeEventListener("mousemove",this.iframe_events[n],false);
+}else{
+if(_66.detachEvent){
+_66.detachEvent("onmousemove",this.iframe_events[n]);
+}else{
+_66["onmousemove"]=null;
+}
+}
+}
+rcube_event.remove_listener({element:_66,event:"mouseup",object:this,method:"drag_mouse_up"});
+}
+}
+return rcube_event.cancel(e);
+},set_background_mode:function(_67){
+if(_67){
+this.background=document.createElement("tbody");
+}else{
+if(this.background){
+this.list.replaceChild(this.background,this.list.tBodies[0]);
+this.background=null;
+}
+}
+}};
+rcube_list_widget.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;
+rcube_list_widget.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;
+rcube_list_widget.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;
 
-rcube_list_widget.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
-rcube_list_widget.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
-rcube_list_widget.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
diff --git a/program/js/list.js.src b/program/js/list.js.src
new file mode 100644 (file)
index 0000000..6f7fe66
--- /dev/null
@@ -0,0 +1,909 @@
+/*
+ +-----------------------------------------------------------------------+
+ | 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 3055 2009-10-23 18:11:41Z 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(){};
+  
+  // 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:bw.opera?'keypress':'keydown', object:this, method:'key_press'});
+      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
+    }
+  }
+},
+
+
+/**
+ * Init list row and set mouse events on it
+ */
+init_row: function(row)
+{
+  // make references in internal array and set event handlers
+  if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i))
+  {
+    var 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]);
+  }
+},
+
+
+/**
+ * Remove all list rows
+ */
+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--;
+},
+
+
+/**
+ * Add row to the list and initialize it
+ */
+insert_row: function(row, attop)
+{
+  if (this.background)
+    var tbody = this.background;
+  else
+    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.rows[id].obj).addClass('selected').removeClass('unfocused');
+    }
+  }
+
+  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.rows[id].obj).removeClass('selected').addClass('unfocused');
+    }
+  }
+},
+
+
+/**
+ * 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);
+  var tagname = evtarget.tagName.toLowerCase();
+  if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img')))
+    return true;
+    
+  // accept right-clicks
+  if (rcube_event.get_button(e) == 2)
+    return true;
+  
+  this.in_selection_before = 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 = $('#'+iframes[n].id).offset();
+        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);
+  var tagname = evtarget.tagName.toLowerCase();
+
+  if ((evtarget && (tagname == 'input' || tagname == 'img')))
+    return true;
+
+  // don't do anything (another action processed before)
+  if (this.dont_select)
+    {
+    this.dont_select = false;
+    return false;
+    }
+    
+  var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
+
+  // unselects currently selected row
+  if (!this.drag_active && this.in_selection_before == id && !dblclicked)
+    this.select_row(id, mod_key, false);
+
+  this.drag_start = false;
+  this.in_selection_before = false;
+
+  // row was double clicked
+  if (this.rows && dblclicked && this.in_selection(id))
+    this.triggerEvent('dblclick');
+  else
+    this.triggerEvent('click');
+
+  if (!this.drag_active)
+    rcube_event.cancel(e);
+
+  this.rows[id].clicked = now;
+  return false;
+},
+
+
+/**
+ * get first/next/previous/last rows that are not hidden
+ */
+get_next_row: function()
+{
+  if (!this.rows)
+    return false;
+
+  var last_selected_row = this.rows[this.last_selected];
+  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_first_row: function()
+{
+  if (this.rowcount)
+    {
+    var rows = this.list.tBodies[0].rows;
+
+    for(var i=0; i<rows.length-1; i++)
+      if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
+       return RegExp.$1;
+    }
+
+  return null;
+},
+
+get_last_row: function()
+{
+  if (this.rowcount)
+    {
+    var 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.triggerEvent('select');
+
+  if (this.last_selected != 0 && this.rows[this.last_selected])
+    $(this.rows[this.last_selected].obj).removeClass('focused');
+
+  // unselect if toggleselect is active and the same row was clicked again
+  if (this.toggleselect && this.last_selected == id)
+  {
+    this.clear_selection();
+    id = null;
+  }
+  else
+    $(this.rows[id].obj).addClass('focused');
+
+  if (!this.selection.length)
+    this.shift_start = null;
+
+  this.last_selected = id;
+},
+
+
+/**
+ * Alias method for select_row
+ */
+select: function(id)
+{
+  this.select_row(id, false);
+  this.scrollto(id);
+},
+
+
+/**
+ * Select row next to the last selected one.
+ * Either below or above.
+ */
+select_next: function()
+{
+  var next_row = this.get_next_row();
+  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);  
+},
+
+/**
+ * Select first row 
+ */
+select_first: function()
+{
+  var first_row = this.get_first_row();
+  if (first_row)
+    this.select_row(first_row, 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.rows[n].obj).removeClass('selected').removeClass('unfocused');
+    }
+  }
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.triggerEvent('select');
+
+  this.focus();
+
+  return true;
+},
+
+
+/**
+ * Invert selection
+ */
+invert_selection: function()
+{
+  if (!this.rows || !this.rows.length)
+    return false;
+
+  // remember old selection
+  var select_before = this.selection.join(',');
+  
+  for (var n in this.rows)
+    this.highlight_row(n, true);    
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.triggerEvent('select');
+
+  this.focus();
+
+  return true;
+},
+
+
+/**
+ * Unselect selected row(s)
+ */
+clear_selection: function(id)
+{
+  var 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.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused');
+        }
+    
+    this.selection = new Array();
+    }
+
+  if (num_select && !this.selection.length)
+    this.triggerEvent('select');
+},
+
+
+/**
+ * Getter for the selection array
+ */
+get_selection: function()
+{
+  return this.selection;
+},
+
+
+/**
+ * Return the ID if only one row is selected
+ */
+get_single_selection: function()
+{
+  if (this.selection.length == 1)
+    return this.selection[0];
+  else
+    return null;
+},
+
+
+/**
+ * Highlight/unhighlight a row
+ */
+highlight_row: function(id, multiple)
+{
+  if (this.rows[id] && !multiple)
+  {
+    if (this.selection.length > 1 || !this.in_selection(id))
+    {
+      this.clear_selection();
+      this.selection[0] = id;
+      $(this.rows[id].obj).addClass('selected');
+    }
+  }
+  else if (this.rows[id])
+  {
+    if (!this.in_selection(id))  // select row
+    {
+      this.selection[this.selection.length] = id;
+      $(this.rows[id].obj).addClass('selected');
+    }
+    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.rows[id].obj).removeClass('selected').removeClass('unfocused');
+    }
+  }
+},
+
+
+/**
+ * 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.triggerEvent('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 27:
+      if (this.drag_active)
+       return this.drag_mouse_up(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 = $('<div>').attr('id', 'rcmdraglayer').css({ position:'absolute', display:'none', 'z-index':2000 }).appendTo(document.body);
+
+    // 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)))
+            {
+             if (n == 0) {
+               if (node.nodeType == 3)
+                 this.drag_start_pos = $(obj.childNodes[i]).offset();
+               else
+                  this.drag_start_pos = $(node).offset();
+             }
+              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.html(names);
+    this.draglayer.show();
+
+    this.drag_active = true;
+    this.triggerEvent('dragstart');
+  }
+
+  if (this.drag_active && this.draglayer)
+  {
+    var pos = rcube_event.get_mouse_pos(e);
+    this.draglayer.css({ left:(pos.x+20)+'px', top:(pos.y-5 + (bw.ie ? document.documentElement.scrollTop : 0))+'px' });
+    this.triggerEvent('dragmove', e?e:window.event);
+  }
+
+  this.drag_start = false;
+
+  return false;
+},
+
+
+/**
+ * Handler for mouse up events
+ */
+drag_mouse_up: function(e)
+{
+  document.onmousemove = null;
+
+  if (this.draglayer && this.draglayer.is(':visible')) {
+    if (this.drag_start_pos)
+      this.draglayer.animate(this.drag_start_pos, 300, 'swing').hide(20);
+    else
+      this.draglayer.hide();
+  }
+
+  this.drag_active = false;
+  this.triggerEvent('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);
+},
+
+
+/**
+ * Creating the list in background
+ */
+set_background_mode: function(flag)
+{
+  if (flag) {
+    this.background = document.createElement('tbody');
+  } else if (this.background) {
+    this.list.replaceChild(this.background, this.list.tBodies[0]);
+    this.background = null;
+  }
+}
+
+};
+
+rcube_list_widget.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
+rcube_list_widget.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
+rcube_list_widget.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
index e6b3ce1710fdb50d101344886fbccd9fda78070c..9d896ffe0363cf7ec23d2f5534906cdc92bbe94c 100644 (file)
@@ -303,13 +303,14 @@ function iil_ReadReply($fp) {
 function iil_ParseResult($string) {
        $a = explode(' ', trim($string));
        if (count($a) >= 2) {
-               if (strcasecmp($a[1], 'OK') == 0) {
+               $res = strtoupper($a[1]);
+               if ($res == 'OK') {
                        return 0;
-               } else if (strcasecmp($a[1], 'NO') == 0) {
+               } else if ($res == 'NO') {
                        return -1;
-               } else if (strcasecmp($a[1], 'BAD') == 0) {
+               } else if ($res == 'BAD') {
                        return -2;
-               } else if (strcasecmp($a[1], 'BYE') == 0) {
+               } else if ($res == 'BYE') {
                        return -3;
                }
        }
@@ -341,7 +342,6 @@ function iil_StartsWithI($string, $match, $error=false) {
        }
        if ($error && preg_match('/^\* (BYE|BAD) /i', $string)) {
                return true;
-
        }
        return false;
 }
@@ -555,7 +555,7 @@ function iil_Connect($host, $user, $password, $options=null) {
        if (is_array($options)) {
                foreach($options as $optkey => $optval) {
                        if ($optkey == 'imap') {
-                               $auth_method = $optval;
+                               $auth_method = strtoupper($optval);
                        } else if ($optkey == 'rootdir') {
                                $my_prefs['rootdir'] = $optval;
                        } else if ($optkey == 'delimiter') {
@@ -567,7 +567,7 @@ function iil_Connect($host, $user, $password, $options=null) {
        }
 
        if (empty($auth_method))
-               $auth_method = 'check';
+               $auth_method = 'CHECK';
                
        $message = "INITIAL: $auth_method\n";
                
@@ -612,7 +612,7 @@ function iil_Connect($host, $user, $password, $options=null) {
                $host = $ICL_SSL . '://' . $host;
        }
 
-       $conn->fp = fsockopen($host, $ICL_PORT, $errno, $errstr, 10);
+       $conn->fp = @fsockopen($host, $ICL_PORT, $errno, $errstr, 10);
        if (!$conn->fp) {
                $iil_error = "Could not connect to $host at port $ICL_PORT: $errstr";
                $iil_errornum = -2;
@@ -620,7 +620,7 @@ function iil_Connect($host, $user, $password, $options=null) {
        }
 
        stream_set_timeout($conn->fp, 10);
-       $line = stream_get_line($conn->fp, 8192, "\r\n");
+       $line = trim(fgets($conn->fp, 8192));
 
        if ($my_prefs['debug_mode'] && $line)
                write_log('imap', 'S: '. $line);
@@ -640,7 +640,7 @@ function iil_Connect($host, $user, $password, $options=null) {
                $conn->capability = explode(' ', strtoupper($matches[1]));
        }
 
-       $conn->message .= $line;
+       $conn->message .= $line . "\n";
 
        // TLS connection
        if ($ICL_SSL == 'tls' && iil_C_GetCapability($conn, 'STARTTLS')) {
@@ -665,29 +665,23 @@ function iil_Connect($host, $user, $password, $options=null) {
                }
        }
 
-       if (strcasecmp($auth_method, "check") == 0) {
+       if ($auth_method == 'CHECK') {
                //check for supported auth methods
                if (iil_C_GetCapability($conn, 'AUTH=CRAM-MD5') || iil_C_GetCapability($conn, 'AUTH=CRAM_MD5')) {
-                       $auth_method = 'auth';
+                       $auth_method = 'AUTH';
                }
                else {
                        //default to plain text auth
-                       $auth_method = 'plain';
+                       $auth_method = 'PLAIN';
                }
        }
 
-       if (strcasecmp($auth_method, 'auth') == 0) {
-               $conn->message .= "Trying CRAM-MD5\n";
-
+       if ($auth_method == 'AUTH') {
                //do CRAM-MD5 authentication
                iil_PutLine($conn->fp, "a000 AUTHENTICATE CRAM-MD5");
                $line = trim(iil_ReadLine($conn->fp, 1024));
 
-               $conn->message .= "$line\n";
-
                if ($line[0] == '+') {
-                       $conn->message .= 'Got challenge: ' . htmlspecialchars($line) . "\n";
-
                        //got a challenge string, try CRAM-5
                        $result = iil_C_Authenticate($conn, $user, $password, substr($line,2));
                        
@@ -697,21 +691,19 @@ function iil_Connect($host, $user, $password, $options=null) {
                                $iil_errornum = $conn->errorNum;
                                return false;
                        }
-                       $conn->message .= "Tried CRAM-MD5: $result \n";
+                       $conn->message .= "AUTH CRAM-MD5: $result\n";
                } else {
-                       $conn->message .='No challenge ('.htmlspecialchars($line)."), try plain\n";
-                       $auth = 'plain';
+                       $conn->message .= "AUTH CRAM-MD5: failed\n";
+                       $auth_method = 'PLAIN';
                }
        }
                
-       if ((!$result)||(strcasecmp($auth, "plain") == 0)) {
+       if (!$result || $auth_method == 'PLAIN') {
                //do plain text auth
                $result = iil_C_Login($conn, $user, $password);
-               $conn->message .= "Tried PLAIN: $result \n";
+               $conn->message .= "AUTH PLAIN: $result\n";
        }
                
-       $conn->message .= $auth;
-                       
        if (!is_int($result)) {
                iil_C_Namespace($conn);
                return $conn;
@@ -779,7 +771,7 @@ function iil_C_Select(&$conn, $mailbox) {
        if (empty($mailbox)) {
                return false;
        }
-       if (strcmp($conn->selected, $mailbox) == 0) {
+       if ($conn->selected == $mailbox) {
                return true;
        }
     
@@ -788,10 +780,11 @@ function iil_C_Select(&$conn, $mailbox) {
                        $line = chop(iil_ReadLine($conn->fp, 300));
                        $a = explode(' ', $line);
                        if (count($a) == 3) {
-                               if (strcasecmp($a[2], 'EXISTS') == 0) {
+                               $token = strtoupper($a[2]);
+                               if ($token == 'EXISTS') {
                                        $conn->exists = (int) $a[1];
                                }
-                               else if (strcasecmp($a[2], 'RECENT') == 0) {
+                               else if ($token == 'RECENT') {
                                        $conn->recent = (int) $a[1];
                                }
                        }
@@ -800,8 +793,6 @@ function iil_C_Select(&$conn, $mailbox) {
                        }
                } while (!iil_StartsWith($line, 'sel1', true));
 
-               $a = explode(' ', $line);
-
                if (strcasecmp($a[1], 'OK') == 0) {
                        $conn->selected = $mailbox;
                        return true;
@@ -1477,13 +1468,13 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                $parts_count = count($a);
                                if ($parts_count>=6) {
                                        for ($i=0; $i<$parts_count; $i=$i+2) {
-                                               if (strcasecmp($a[$i],'UID') == 0)
+                                               if ($a[$i] == 'UID')
                                                        $result[$id]->uid = $a[$i+1];
-                                               else if (strcasecmp($a[$i],'RFC822.SIZE') == 0)
+                                               else if ($a[$i] == 'RFC822.SIZE')
                                                        $result[$id]->size = $a[$i+1];
-                                               else if (strcasecmp($a[$i],'INTERNALDATE') == 0)
+                                               else if ($a[$i] == 'INTERNALDATE')
                                                        $time_str = $a[$i+1];
-                                               else if (strcasecmp($a[$i],'FLAGS') == 0)
+                                               else if ($a[$i] == 'FLAGS')
                                                        $flags_str = $a[$i+1];
                                        }
 
@@ -1510,11 +1501,11 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                preg_match('/ BODY\[HEADER.FIELDS \(.*?\)\]\s*(.*)$/s', $line, $m);
                                $reslines = explode("\n", trim($m[1], '"'));
                                // re-parse (see below)
-                               foreach ($reslines as $line) {
-                                       if (ord($line[0])<=32) {
-                                               $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($line);
+                               foreach ($reslines as $resln) {
+                                       if (ord($resln[0])<=32) {
+                                               $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($resln);
                                        } else {
-                                               $lines[++$ln] = trim($line);
+                                               $lines[++$ln] = trim($resln);
                                        }
                                }
                        }
@@ -1553,7 +1544,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                        $lines[++$ln] = trim($line);
                                }
                        // patch from "Maksim Rubis" <siburny@hotmail.com>
-                       } while (trim($line[0]) != ')' && strncmp($line, $key, strlen($key)));
+                       } while ($line[0] != ')' && !iil_StartsWith($line, $key, true));
 
                        if (strncmp($line, $key, strlen($key))) { 
                                // process header, fill iilBasicHeader obj.
@@ -1601,13 +1592,10 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                                $result[$id]->encoding = $string;
                                                break;
                                        case 'content-type':
-                                               $ctype_parts = explode(";", $string);
+                                               $ctype_parts = preg_split('/[; ]/', $string);
                                                $result[$id]->ctype = array_shift($ctype_parts);
-                                               foreach ($ctype_parts as $ctype_add) {
-                                                       if (preg_match('/charset="?([a-z0-9\-\.\_]+)"?/i',
-                                                               $ctype_add, $regs)) {
-                                                               $result[$id]->charset = $regs[1];
-                                                       }
+                                               if (preg_match('/charset\s*=\s*"?([a-z0-9\-\.\_]+)"?/i', $string, $regs)) {
+                                                       $result[$id]->charset = $regs[1];
                                                }
                                                break;
                                        case 'in-reply-to':
@@ -1644,23 +1632,24 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                $flags_a   = explode(' ', $flags_str);
                                        
                                if (is_array($flags_a)) {
-                                       reset($flags_a);
-                                       while (list(,$val)=each($flags_a)) {
-                                               if (strcasecmp($val,'Seen') == 0) {
+                               //      reset($flags_a);
+                                       foreach($flags_a as $flag) {
+                                               $flag = strtoupper($flag);
+                                               if ($flag == 'SEEN') {
                                                    $result[$id]->seen = true;
-                                               } else if (strcasecmp($val, 'Deleted') == 0) {
-                                                   $result[$id]->deleted=true;
-                                               } else if (strcasecmp($val, 'Recent') == 0) {
+                                               } else if ($flag == 'DELETED') {
+                                                   $result[$id]->deleted = true;
+                                               } else if ($flag == 'RECENT') {
                                                    $result[$id]->recent = true;
-                                               } else if (strcasecmp($val, 'Answered') == 0) {
+                                               } else if ($flag == 'ANSWERED') {
                                                        $result[$id]->answered = true;
-                                               } else if (strcasecmp($val, '$Forwarded') == 0) {
+                                               } else if ($flag == '$FORWARDED') {
                                                        $result[$id]->forwarded = true;
-                                               } else if (strcasecmp($val, 'Draft') == 0) {
+                                               } else if ($flag == 'DRAFT') {
                                                        $result[$id]->is_draft = true;
-                                               } else if (strcasecmp($val, '$MDNSent') == 0) {
+                                               } else if ($flag == '$MDNSENT') {
                                                        $result[$id]->mdn_sent = true;
-                                               } else if (strcasecmp($val, 'Flagged') == 0) {
+                                               } else if ($flag == 'FLAGGED') {
                                                         $result[$id]->flagged = true;
                                                }
                                        }
@@ -1668,7 +1657,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                }
                        }
                }
-       } while (strcmp($a[0], $key) != 0);
+       } while (!iil_StartsWith($line, $key, true));
 
        return $result;
 }
@@ -2277,7 +2266,7 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $is_uid=false, $part='', $e
                                        }
                                        else
                                                $prev = '';
-
+                                               
                                        if ($file)
                                                fwrite($file, base64_decode($line));
                                        else if ($print)
@@ -2313,7 +2302,6 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $is_uid=false, $part='', $e
                                }
                        }
                }
-
                // read in anything up until last line
                if (!$end)
                        do {
@@ -2321,18 +2309,17 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $is_uid=false, $part='', $e
                        } while (!iil_StartsWith($line, $key, true));
 
                if ($result) {
-                       $result = rtrim($result, "\t\r\n\0\x0B");
                        if ($file) {
                                fwrite($file, $result);
                        } else if ($print) {
                                echo $result;
                        } else
-                               return $result; // substr($result, 0, strlen($result)-1);
+                               return $result;
 
                        return true;
                }
        }
-    
+
        return false;
 }
 
index 2a2df2b3cb68a09410998559680bf0db353f339d..1f1927e217bcec94ec3b4879d1e08964ef24ecbc 100644 (file)
 |         http://softastur.org                                          |
 +-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2124 2009-02-02 03:55:53Z mikelg $
+@version $Id: labels.inc 2124 2009-02-02 03:55:53Z mikelg $
 
 */
 
 $labels = array();
-
-// login page
 $labels['welcome'] = 'Bienllegáu a $product';
 $labels['username'] = 'Usuariu';
 $labels['password'] = 'Clave';
 $labels['server'] = 'Sirvidor';
 $labels['login'] = 'Entrar';
-
-// taskbar
 $labels['logout'] = 'Zarrar';
 $labels['mail'] = 'Corréu';
 $labels['settings'] = 'Preferencies personales';
 $labels['addressbook'] = 'Llibru de direiciones';
-
-// mailbox names
 $labels['inbox'] = 'Entrantes';
 $labels['drafts'] = 'Borradores';
 $labels['sent'] = 'Unviaos';
 $labels['trash'] = 'Papelera';
 $labels['junk'] = 'Puxarra';
-
-// message listing
 $labels['subject'] = 'Asuntu';
 $labels['from'] = 'De';
 $labels['to'] = 'Pa';
@@ -52,27 +44,18 @@ $labels['date'] = 'Fecha';
 $labels['size'] = 'Tamañu';
 $labels['priority'] = 'Prioridá';
 $labels['organization'] = 'Organización';
-
-// aliases
-$labels['reply-to'] = $labels['replyto'];
-
+$labels['reply-to'] = 'Contestar a';
 $labels['mailboxlist'] = 'Carpetes';
 $labels['messagesfromto'] = 'Mensaxes del $from a $to de $count';
 $labels['messagenrof'] = 'Mensaxe $nr de $count';
-
 $labels['moveto'] = 'mover pa...';
 $labels['download'] = 'baxar';
-
 $labels['filename'] = 'Nome del Ficheru';
 $labels['filesize'] = 'Tamañu del ficheru';
-
 $labels['preferhtml'] = 'Amosar HTML';
 $labels['htmlmessage'] = 'Mensaxe HTML';
 $labels['prettydate'] = 'Fecha prestosa';
-
 $labels['addtoaddressbook'] = 'Amestar al llibru de direiciones';
-
-// weekdays short
 $labels['sun'] = 'Dom';
 $labels['mon'] = 'Llu';
 $labels['tue'] = 'Mar';
@@ -80,8 +63,6 @@ $labels['wed'] = 'Mie';
 $labels['thu'] = 'Xue';
 $labels['fri'] = 'Vie';
 $labels['sat'] = 'Sab';
-
-// weekdays long
 $labels['sunday'] = 'Domingu';
 $labels['monday'] = 'Llunes';
 $labels['tuesday'] = 'Martes';
@@ -89,8 +70,6 @@ $labels['wednesday'] = 'Miércoles';
 $labels['thursday'] = 'Xueves';
 $labels['friday'] = 'Vienres';
 $labels['saturday'] = 'Sábadu';
-
-// months short
 $labels['jan'] = 'Xin';
 $labels['feb'] = 'Feb';
 $labels['mar'] = 'Mar';
@@ -103,8 +82,6 @@ $labels['sep'] = 'Set';
 $labels['oct'] = 'Och';
 $labels['nov'] = 'Pay';
 $labels['dec'] = 'Avi';
-
-// months long
 $labels['longjan'] = 'Xineru';
 $labels['longfeb'] = 'Febreru';
 $labels['longmar'] = 'Marzu';
@@ -117,10 +94,7 @@ $labels['longsep'] = 'Setiembre';
 $labels['longoct'] = 'Ochobre';
 $labels['longnov'] = 'Payares';
 $labels['longdec'] = 'Avientu';
-
 $labels['today'] = 'Güei';
-
-// toolbar buttons
 $labels['checkmail'] = 'Buscar mensaxes nuevos';
 $labels['writenewmessage'] = 'Facer un mensaxe nuevu';
 $labels['replytomessage'] = 'Contestar al mensaxe';
@@ -144,124 +118,102 @@ $labels['markread'] = 'Como lleíu';
 $labels['markunread'] = 'Como non lleíu';
 $labels['markflagged'] = 'Como marcáu';
 $labels['markunflagged'] = 'Como non marcáu';
-
+$labels['messageactions'] = 'Más aiciones...';
 $labels['select'] = 'Escueye';
 $labels['all'] = 'Toos';
 $labels['none'] = 'Nengún';
 $labels['unread'] = 'Ensin lleer';
 $labels['flagged'] = 'Marcáu';
 $labels['unanswered'] = 'Ensin contestar';
+$labels['deleted'] = 'Desaniciáu';
+$labels['invert'] = 'Invertir';
 $labels['filter'] = 'Filtru';
-
 $labels['compact'] = 'Compautar';
 $labels['empty'] = 'Vaciar';
 $labels['purge'] = 'Desaniciar';
-
 $labels['quota'] = 'Espaciu en discu';
 $labels['unknown'] = 'desconocíu';
 $labels['unlimited'] = 'ensin llímite';
-
 $labels['quicksearch'] = 'Búsqueda rápida';
 $labels['resetsearch'] = 'Anovar la búsqueda';
-
+$labels['searchmod'] = 'Guetar modificadores';
+$labels['msgtext'] = 'Mensax completu';
 $labels['openinextwin'] = 'Abrir en una ventana nueva';
-
-// message compose
+$labels['emlsave'] = 'Baxar (.eml)';
 $labels['compose'] = 'Escribir un mensaxe';
+$labels['editasnew'] = 'Editar como nuevu';
 $labels['savemessage'] = 'Guardar como borrador';
 $labels['sendmessage'] = 'Unviar el mensaxe yá';
 $labels['addattachment'] = 'Amestar un archivu';
 $labels['charset'] = 'Codificación';
 $labels['editortype'] = 'Tipo d\'editor';
 $labels['returnreceipt'] = 'Avisu de recibu';
-
 $labels['checkspelling'] = 'Revisar ortografía';
 $labels['resumeediting'] = 'Siguir cola edición';
 $labels['revertto'] = 'Desfacer a';
-
 $labels['attachments'] = 'Axuntos';
 $labels['upload'] = 'Xubir';
 $labels['close'] = 'Zarrar';
-
 $labels['low'] = 'Baxu';
 $labels['lowest'] = 'Mui baxu';
 $labels['normal'] = 'Normal';
 $labels['high'] = 'Altu';
 $labels['highest'] = 'Mui altu';
-
 $labels['nosubject'] = '(ensin asuntu)';
 $labels['showimages'] = 'Amosar imáxenes';
 $labels['alwaysshow'] = 'Amosar siempre les imáxenes de $sender';
-
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Testu';
 $labels['savesentmessagein'] = 'Guardar mensaxe unviau en';
 $labels['dontsave'] = 'Desanicialu';
 $labels['maxuploadsize'] = 'El tamañu másimu pa un ficheru ye $size';
-
 $labels['addcc'] = 'Amestar Cc';
 $labels['addbcc'] = 'Amestar Bcc';
 $labels['addreplyto'] = 'Amestar Rempuesta pa';
-
-// mdn
 $labels['mdnrequest'] = 'El qu\'unvia esti mensaxe quier que lo avises cuando lleas el corréu. ¿Quies avisalo?';
 $labels['receiptread'] = 'Avisu de llectura';
 $labels['yourmessage'] = 'Esto ye un avisu de llectura del to mensaxe';
 $labels['receiptnote'] = 'Nota: Esti avisu namás quier dicir que\'l to mensaxe amosośe nel equipu del receptor. Nun hai forma de garantizate que lo lleera o que pescanciara\'l to mensaxe.';
-
-// address boook
 $labels['name'] = 'Nome completu';
 $labels['firstname'] = 'Nome';
 $labels['surname'] = 'Apellíu';
 $labels['email'] = 'Corréu';
-
 $labels['addcontact'] = 'Amestar contautu nuevu';
 $labels['editcontact'] = 'Editar contautu';
-
 $labels['edit'] = 'Editar';
 $labels['cancel'] = 'Encaboxar';
 $labels['save'] = 'Guardar';
 $labels['delete'] = 'Desaniciar';
-
 $labels['newcontact'] = 'Facer un contautu nuevu';
 $labels['deletecontact'] = 'Desaniciar los contautos marcaos';
 $labels['composeto'] = 'Unviar mensaxe a';
 $labels['contactsfromto'] = 'Contautos $from a $to de $count';
 $labels['print'] = 'Imprentar';
 $labels['export'] = 'Esportar';
-$labels['exportvcards']   = 'Esportar contautos en formatu vCard';
-
+$labels['exportvcards'] = 'Esportar contautos en formatu vCard';
 $labels['previouspage'] = 'Amosar grupu anterior';
 $labels['firstpage'] = 'Amosar primer grupu';
 $labels['nextpage'] = 'Amosar siguiente grupu';
 $labels['lastpage'] = 'Amosar l\'últimu grupu';
-
 $labels['groups'] = 'Grupos';
 $labels['personaladrbook'] = 'Direiciones personales';
-
 $labels['import'] = 'Importar';
 $labels['importcontacts'] = 'Importar contautos';
 $labels['importfromfile'] = 'Importar dende un ficheru:';
 $labels['importreplace'] = 'Trocar el llibru de direiciones enteru';
 $labels['importtext'] = 'Puedes xubir direcione d\'un llibr que yá tengas.<br/>Anguaño puedes importar direiciones en formatu <a href="http://ast.wikipedia.org/wiki/VCard">vCard</a>.';
 $labels['done'] = 'Fecho';
-
-// settings
 $labels['settingsfor'] = 'Configuración pa';
-
 $labels['preferences'] = 'Preferencies';
 $labels['userpreferences'] = 'Preferencies d\'usuariu';
 $labels['editpreferences'] = 'Editar preferencies d\'usuariu';
-
 $labels['identities'] = 'Identidaes';
 $labels['manageidentities'] = 'Remanar identidaes pa esta cuenta';
 $labels['newidentity'] = 'Identidad nueva';
-
 $labels['newitem'] = 'Nuevu';
 $labels['edititem'] = 'Editar';
-
 $labels['setdefault'] = 'Escoyer opción preferída';
-$labels['autodetect']  = 'Escoyer automáticamente';
+$labels['autodetect'] = 'Escoyer automáticamente';
 $labels['language'] = 'Idioma';
 $labels['timezone'] = 'Franxa horaria';
 $labels['pagesize'] = 'Fileres per páxina';
@@ -288,8 +240,8 @@ $labels['fromknownsenders'] = 'de contautos conocíos';
 $labels['always'] = 'siempre';
 $labels['showinlineimages'] = 'Amosar imáxenes axuntes embaxu\'l mensaxe';
 $labels['autosavedraft'] = 'Guardar borrador de secute';
-$labels['everynminutes']  = 'cada $n minutu/os';
-$labels['keepalive']  = 'Guetar mensaxes nuevos cada';
+$labels['everynminutes'] = 'cada $n minutu/os';
+$labels['keepalive'] = 'Guetar mensaxes nuevos cada';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'Vista de mensaxes';
 $labels['messagescomposition'] = 'Edición de mensaxes';
@@ -300,7 +252,13 @@ $labels['2047folding'] = 'Too RFC 2047 (otros)';
 $labels['advancedoptions'] = 'Opciones avanzaes';
 $labels['focusonnewmessage'] = 'Poner el focu nos mensaxes nuevos';
 $labels['checkallfolders'] = 'Guetar mensaxes nuevos en toles bandexes';
-
+$labels['displaynext'] = 'Depués de mover/desaniciar amosar el mensaxe que sigue darréu';
+$labels['indexsort'] = 'Usar l\'indiz del mensaxe pa ordenalu por fecha';
+$labels['mainoptions'] = 'Opciones principales';
+$labels['section'] = 'Seición';
+$labels['maintenance'] = 'Mantenimientu';
+$labels['newmessage'] = 'Mensax nuevu';
+$labels['listoptions'] = 'Allistar opciones';
 $labels['folder'] = 'Bandexa';
 $labels['folders'] = 'Bandexes';
 $labels['foldername'] = 'Nome de bandexa';
@@ -313,12 +271,9 @@ $labels['renamefolder'] = 'Renomar bandexa';
 $labels['deletefolder'] = 'Desaniciar bandexa';
 $labels['managefolders'] = 'Alministrar bandexes';
 $labels['specialfolders'] = 'Bandexes especiales';
-
 $labels['sortby'] = 'Ordenar por';
 $labels['sortasc'] = 'Orden ascendente';
 $labels['sortdesc'] = 'Orden descendente';
-
-// units
 $labels['B'] = 'B';
 $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
index 63f50578726c4d00e398f51e65fd3c6801e463d7..ed8b31d1a1a1013455fbffb63e3bf08ef8c8664d 100644 (file)
@@ -15,7 +15,7 @@
 |         http://softastur.org                                          |
 +-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2036 2009-02-02 04:37:58Z mikelg $
+@version $Id: messages.inc 2036 2009-02-02 04:37:58Z mikelg $
 
 */
 
@@ -24,6 +24,8 @@ $messages['loginfailed'] = 'La clave nun val';
 $messages['cookiesdisabled'] = 'El to navegador nun acepta "cookies"';
 $messages['sessionerror'] = 'La to sesión nun val';
 $messages['imaperror'] = 'Fallu de conexón col sirvidor IMAP';
+$messages['servererror'] = '¡Fallu del sirvidor!';
+$messages['invalidrequest'] = 'Fallu de la solicitú. Nun se guardaron datos.';
 $messages['nomessagesfound'] = 'Nun doi con mensaxes';
 $messages['loggedout'] = 'Zarraste la sesión.';
 $messages['mailboxempty'] = 'La to cuenta nun tien mensaxes';
@@ -47,6 +49,7 @@ $messages['errorsavingsent'] = 'Di con un fallu al guardar el mensaxe';
 $messages['errorsaving'] = 'Falló al guardase';
 $messages['errormoving'] = 'Nun fui a mover el mensaxe';
 $messages['errordeleting'] = 'Nun fui a desaniciar el mensaxe';
+$messages['errormarking'] = 'Nun se puede marcar el mensaxe';
 $messages['deletecontactconfirm'] = '¿Tas seguru de desaniciar los contautos que marcaste?';
 $messages['deletemessagesconfirm'] = '¿Tas seguru de desaniciar los mensaxes que marcaste?';
 $messages['deletefolderconfirm'] = '¿Tas seguru de desaniciar esta bandexa?';
@@ -96,5 +99,12 @@ $messages['importconfirm'] = '<b>Importaronse correchamente $inserted contautos,
 $messages['opnotpermitted'] = 'Nun tienes permisu pa facelo.';
 $messages['nofromaddress'] = 'Perdiose la direición de corréu de la identidá qu\'escoyisti';
 $messages['editorwarning'] = 'Si pases a editor en modu testu vas perder tol estilu aplicáu al mensaxe. ¿Tas seguru de que quies facelo?';
+$messages['httpreceivedencrypterror'] = 'Hai un fallu garrafal de configuración. Contauta col alministrador de secute. <b>Nun se pude unviar el mesaxe</b>';
+$messages['smtpconnerror'] = 'Fallu SMTP ($code): Fallu de conexón col sirvidor';
+$messages['smtpautherror'] = 'Fallu SMTP ($code): Fallu d\'autorización';
+$messages['smtpfromerror'] = 'Fallu SMTP ($code): Fallu al aficar el remitente "$from"';
+$messages['smtptoerror'] = 'Fallu SMTP ($code): Fallu al amestar el destinatariu "$to"';
+$messages['smtprecipientserror'] = 'Fallu SMTP: Nun soi a amosar la llista de destinatarios';
+$messages['smtperror'] = 'Fallu SMTP: $msg';
 
 ?>
index 415b31c47900a7eda59a56ec36e554b298e4778b..7790f3617a00382d2002576f9d20cf25d528f354 100644 (file)
@@ -10,8 +10,8 @@
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Todor Dragnev <todor.dragnev@gmail.com>                      |
-|        Nickolay Bunev <just4nick@gmail.com>                          |
+| Author: Todor Dragnev <todor.dragnev@gmail.com>                                              |
+|        Nickolay Bunev <just4nick@gmail.com>                                                          |
 +-----------------------------------------------------------------------+
 
 @version $Id$
@@ -69,18 +69,18 @@ $labels['wednesday'] = 'Сряда';
 $labels['thursday'] = 'Четвъртък';
 $labels['friday'] = 'Петък';
 $labels['saturday'] = 'Събота';
-$labels['jan'] = 'Jan';
-$labels['feb'] = 'Feb';
-$labels['mar'] = 'Mar';
-$labels['apr'] = 'Apr';
-$labels['may'] = 'May';
-$labels['jun'] = 'Jun';
-$labels['jul'] = 'Jul';
-$labels['aug'] = 'Aug';
-$labels['sep'] = 'Sep';
-$labels['oct'] = 'Oct';
-$labels['nov'] = 'Nov';
-$labels['dec'] = 'Dec';
+$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'] = 'Март';
@@ -97,7 +97,7 @@ $labels['today'] = 'Днес';
 $labels['checkmail'] = 'Провери за нови писма';
 $labels['writenewmessage'] = 'Създай ново писмо';
 $labels['replytomessage'] = 'Отговори на писмото';
-$labels['replytoallmessage'] = 'Отговори до изпращача и всички получатели';
+$labels['replytoallmessage'] = 'Отговор до изпращача и всички получатели';
 $labels['forwardmessage'] = 'Препрати писмото';
 $labels['deletemessage'] = 'Изтрий писмото';
 $labels['movemessagetotrash'] = 'Премести писмото в кошчето';
@@ -111,7 +111,7 @@ $labels['nextmessages'] = 'Следваща страница';
 $labels['lastmessage'] = 'Последно писмо';
 $labels['lastmessages'] = 'Последна страница';
 $labels['backtolist'] = 'Обратно към списъка';
-$labels['viewsource'] = 'Ð\92иж ÐºÐ¾Ð´Ð°';
+$labels['viewsource'] = 'Ð\92иж ÐºÐ°Ñ\82о ÐºÐ¾Ð´';
 $labels['markmessages'] = 'Маркирай писмата';
 $labels['markread'] = 'Като прочетени';
 $labels['markunread'] = 'Като нови';
@@ -125,7 +125,7 @@ $labels['unread'] = 'Нови';
 $labels['flagged'] = 'Отбелязано';
 $labels['unanswered'] = 'Неотговорено';
 $labels['deleted'] = 'Изтрито';
-$labels['invert'] = 'Invert';
+$labels['invert'] = 'Инвертирай';
 $labels['filter'] = 'Филтър';
 $labels['compact'] = 'Свий';
 $labels['empty'] = 'Изпразни';
@@ -135,9 +135,10 @@ $labels['unknown'] = 'няма информация';
 $labels['unlimited'] = 'няма ограничение';
 $labels['quicksearch'] = 'Бързо търсене';
 $labels['resetsearch'] = 'Изчисти търсенето и покажи всички писма';
+$labels['searchmod'] = 'Търсене във';
 $labels['msgtext'] = 'Цялото съобщение';
 $labels['openinextwin'] = 'Отвори в нов прозорец';
-$labels['emlsave'] = 'Изтегли (.eml)';
+$labels['emlsave'] = 'Изтегли като .eml';
 $labels['compose'] = 'Ново писмо';
 $labels['editasnew'] = 'Редактирай като ново';
 $labels['savemessage'] = 'Запиши в Чернови';
@@ -164,7 +165,7 @@ $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'текстов';
 $labels['savesentmessagein'] = 'Запази съобщението в';
 $labels['dontsave'] = 'Не съхранявай';
-$labels['maxuploadsize'] = 'Максимално позволенa големина в $size';
+$labels['maxuploadsize'] = 'Максимално позволен размер $size';
 $labels['addcc'] = 'Копие до';
 $labels['addbcc'] = 'Скрито копие до';
 $labels['addreplyto'] = 'Отговор на';
@@ -233,22 +234,25 @@ $labels['ignore'] = 'Отхвърли';
 $labels['readwhendeleted'] = 'Отбележи като прочетено при изтриване';
 $labels['flagfordeletion'] = 'Отбележи съобщението за изтриване';
 $labels['skipdeleted'] = 'Не показвай изтритите съобщения';
+$labels['showremoteimages'] = 'Покажи блокираните изображения';
 $labels['fromknownsenders'] = 'Oт познати изпращачи';
 $labels['always'] = 'Винаги';
 $labels['showinlineimages'] = 'Покажи прикачените изображения след съобщението';
 $labels['autosavedraft'] = 'Автоматично записвай чернова';
 $labels['everynminutes'] = 'всеки $n минути';
-$labels['keepalive'] = 'Ð\9fÑ\80овеÑ\80Ñ\8fвай Ð·Ð° Ð½Ð¾Ð²Ð¸ Ñ\81Ñ\8aобÑ\89ениÑ\8f Ð¿Ñ\80и';
+$labels['keepalive'] = 'Ð\9fÑ\80овеÑ\80Ñ\8fвай Ð·Ð° Ð½Ð¾Ð²Ð¸ Ñ\81Ñ\8aобÑ\89ениÑ\8f Ð½Ð°';
 $labels['never'] = 'никога';
 $labels['messagesdisplaying'] = 'Показване на събщенията';
 $labels['messagescomposition'] = 'Писане на съобщения';
 $labels['mimeparamfolding'] = 'Добавяне име на прикрепените файлове';
-$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['2231folding'] = 'Според RFC 2231 (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
-$labels['2047folding'] = 'Full RFC 2047 (други)';
+$labels['2047folding'] = 'Според RFC 2047 (други)';
 $labels['advancedoptions'] = 'Настройки за напреднали';
+$labels['focusonnewmessage'] = 'Премигване на прозореца при ново писмо';
 $labels['checkallfolders'] = 'Провери всички папки за нови писма';
 $labels['displaynext'] = 'След изтриване / премини към следващото писмо';
+$labels['indexsort'] = 'Използвай индекса на писмата при сортиране по дата';
 $labels['mainoptions'] = 'Основни настройки';
 $labels['section'] = 'Раздел';
 $labels['maintenance'] = 'Поддръжка';
@@ -269,9 +273,9 @@ $labels['specialfolders'] = 'Служебни папки';
 $labels['sortby'] = 'Сортирай по';
 $labels['sortasc'] = 'Сортирай възходящо';
 $labels['sortdesc'] = 'Сортирай низходящо';
-$labels['B'] = 'B';
-$labels['KB'] = 'KB';
-$labels['MB'] = 'MB';
-$labels['GB'] = 'GB';
+$labels['B'] = 'Б';
+$labels['KB'] = 'КБ';
+$labels['MB'] = 'МБ';
+$labels['GB'] = 'ГБ';
 
-?>
+?>
\ No newline at end of file
index 6badf083bed146b9c2a245d3a2ee67c37a998a77..a2af5e08c320b3f3b70b97f5ca39a9cc084730f5 100644 (file)
@@ -11,7 +11,7 @@
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Todor Dragnev <todor.dragnev@gmail.com>                       |
-|        Nickolay Bunev <just4nick@gmail.com>                          |
+|        Nickolay Bunev <just4nick@gmail.com>                                                          |
 +-----------------------------------------------------------------------+
 
 @version $Id$
@@ -23,10 +23,13 @@ $messages['loginfailed'] = 'Вход неуспешен';
 $messages['cookiesdisabled'] = 'Вашият браузър не приема cookies';
 $messages['sessionerror'] = 'Невалидна или изтекла сесия';
 $messages['imaperror'] = 'Неуспешно свързване към IMAP сървъра';
+$messages['servererror'] = 'Грешка!';
+$messages['invalidrequest'] = 'Невалидна заявка! Данните не са съхранени.';
 $messages['nomessagesfound'] = 'Няма съобщения';
 $messages['loggedout'] = 'Довиждане!';
 $messages['mailboxempty'] = 'Кутията е празна';
 $messages['loading'] = 'Зареждане...';
+$messages['uploading'] = 'Качване на файла...';
 $messages['loadingdata'] = 'Зареждане на данни...';
 $messages['checkingmail'] = 'Проверка за нови писма...';
 $messages['sendingmessage'] = 'Изпращане на писмото...';
@@ -46,6 +49,7 @@ $messages['errorsavingsent'] = 'Възникна грешка при запис
 $messages['errorsaving'] = 'Възникна грешка при записването';
 $messages['errormoving'] = 'Писмото не може да бъде преместено';
 $messages['errordeleting'] = 'Писмото не може да бъде изтрито';
+$messages['errormarking'] = 'Съобщението не може да бъде маркирано';
 $messages['deletecontactconfirm'] = 'Искате ли да изтриете маркираните контакти?';
 $messages['deletemessagesconfirm'] = 'Искате ли да изтриете маркираните съобщения?';
 $messages['deletefolderconfirm'] = 'Искате ли да изтриете тази папка?';
@@ -66,6 +70,7 @@ $messages['notsentwarning'] = 'Писмото не е изпратено. Иск
 $messages['noldapserver'] = 'Изберете LDAP сървър за търсене';
 $messages['nocontactsreturned'] = 'Не са намерени контакти';
 $messages['nosearchname'] = 'Моля, въведете Име на контакта или e-mail адрес';
+$messages['notuploadedwarning'] = 'Все още не са качени всички прикачени файлове. Моля изчакайте или откажете качването.';
 $messages['searchsuccessful'] = '$nr намерени писма';
 $messages['searchnomatch'] = 'Търсенето не откри съвпадения';
 $messages['searching'] = 'Търсене...';
@@ -91,9 +96,17 @@ $messages['selectimportfile'] = 'Моля изберете файл за кач
 $messages['addresswriterror'] = 'Избраната адресна книга не може да бъде записвана';
 $messages['importwait'] = 'Внасяне, моля изчакайте...';
 $messages['importerror'] = 'Внасянето неуспешно! Каченият файл не е във валиден vCard формат.';
-$messages['importconfirm'] = '<b>Успешно са внесени следните контакти $inserted contacts, вече съществуващите $skipped контакти са пропуснати</b>:<p><em>$names</em></p>';
+$messages['importconfirm'] = '<b>Успешно са внесени $inserted контакта, вече съществуващите $skipped контакта са пропуснати</b>:<p><em>$names</em></p>';
 $messages['opnotpermitted'] = 'Операцията не е позволена!';
 $messages['nofromaddress'] = 'Липсва e-mail адрес за избраната самоличност';
 $messages['editorwarning'] = 'Превключването на редактора в текстов режим ще доведе до загуба на форматирането на текса. Сигурни ли сте, че искате да продължите?';
+$messages['httpreceivedencrypterror'] = 'Фатална конфигурационна грешка. Моля, свържете се веднага с администратора. <b>Съобщението Ви не може да бъде изпратено.</b>';
+$messages['smtpconnerror'] = 'SMTP грешка ($code): Няма връзка със сървъра';
+$messages['smtpautherror'] = 'SMTP грешка ($code): Грешни потребител/парола';
+$messages['smtpfromerror'] = 'SMTP грешка ($code): Не може да бъде изпратено писмо от "$from"';
+$messages['smtptoerror'] = 'SMTP грешка ($code): Не може да бъде изпратено писмо до "$to"';
+$messages['smtprecipientserror'] = 'SMTP грешка: Не може да бъде обработен списъка с получатели';
+$messages['smtperror'] = 'SMTP грешка: $msg';
+$messages['emailformaterror'] = 'Невалиден e-mail адрес: $email';
 
-?>
+?>
\ No newline at end of file
index 9f880dc2b7bf1525bb7cda1f499264c6e296c4c3..a814f3a7a1b1f994356ecb49f69f88da0bd965fb 100644 (file)
@@ -3,7 +3,7 @@
 /*
 
 +-----------------------------------------------------------------------+
-| language/cs_CZ/labels.inc                                                |
+| language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the RoundCube Webmail client                         |
 | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
 | Author: Martin Mrajca <martin@moonlake.cz>                            |
 |        joe <joe@humlak.cz>                                            |
 |        Jiri Kaderavek <jiri.kaderavek@webstep.net>                    |
+|        Milan Kozak <hodza@hodza.net>                                 |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2827 2009-08-02 13:32:47Z yllar $
+@version $Id: labels.inc 2994 2009-09-27 14:16:33Z yllar $
 
 */
 
@@ -253,6 +254,12 @@ $labels['advancedoptions'] = 'Pokročilá nastavení';
 $labels['focusonnewmessage'] = 'Aktivovat okno prohlížeče při príchozí zprávě';
 $labels['checkallfolders'] = 'Kontrolovat nové zprávy ve všech složkách';
 $labels['displaynext'] = 'Zobrazit další zprávu po smazání/přesunu zprávy';
+$labels['indexsort'] = 'Používat index k řazení zpráv podle data';
+$labels['mainoptions'] = 'Hlavní nastavení';
+$labels['section'] = 'Sekce';
+$labels['maintenance'] = 'Údržba';
+$labels['newmessage'] = 'Nová zpráva';
+$labels['listoptions'] = 'Nastavení stránkování';
 $labels['folder'] = 'Složka';
 $labels['folders'] = 'Složky';
 $labels['foldername'] = 'Jméno složky';
@@ -273,4 +280,4 @@ $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 
-?>
\ No newline at end of file
+?>
index 96dc00e47c51346e2a549e5669b00523a2636c23..86b09a1f577997651a4006d9e8d4f61b94c12076 100644 (file)
@@ -15,7 +15,7 @@
 |        Jiri Kaderavek <jiri.kaderavek@webstep.net>                    |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2827 2009-08-02 13:32:47Z yllar $
+@version $Id: messages.inc 3061 2009-10-26 21:42:58Z yllar $
 
 */
 
@@ -30,6 +30,7 @@ $messages['nomessagesfound'] = 'Ve schránce nebyla nalezena žádná zpráva';
 $messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Nashledanou!';
 $messages['mailboxempty'] = 'Schránka je prázdná';
 $messages['loading'] = 'Načítám...';
+$messages['uploading'] = 'Nahrávám soubor...';
 $messages['loadingdata'] = 'Načítám data...';
 $messages['checkingmail'] = 'Kontroluji nové zprávy...';
 $messages['sendingmessage'] = 'Odesílám zprávu...';
@@ -70,6 +71,7 @@ $messages['notsentwarning'] = 'Zpráva nebyla odeslána. Přejete si zprávu zah
 $messages['noldapserver'] = 'Zvolte, prosím, LDAP server k hledání';
 $messages['nocontactsreturned'] = 'Nebyly nalezeny žádné kontakty';
 $messages['nosearchname'] = 'Zadejte, prosím, jméno nebo e-mail kontaktu';
+$messages['notuploadedwarning'] = 'Ještě nebyly nahrány všechny přílohy. Počkejte prosím nebo nahrávání zrušte.';
 $messages['searchsuccessful'] = '$nr zpráv nalezeno';
 $messages['searchnomatch'] = 'Nenalezena žádná zpráva';
 $messages['searching'] = 'Vyhledávám...';
@@ -99,12 +101,13 @@ $messages['importconfirm'] = '<b>Úspěšně naimportováno $inserted kontaktů,
 $messages['opnotpermitted'] = 'Operace není povolena!';
 $messages['nofromaddress'] = 'Chybějící e-mailová adresa v označeném profilu';
 $messages['editorwarning'] = 'Přepnutím do režimu prostého textu ztratíte veškeré formátování. Chcete pokračovat?';
-$messages['httpreceivedencrypterror'] = 'Vyskytla se vážná chyba v konfiguraci. Kontaktujte neprodleně administátora. <b>Vaše zpráva nemohla být odeslána.</b>        ';
+$messages['httpreceivedencrypterror'] = 'Vyskytla se vážná chyba v konfiguraci. Kontaktujte neprodleně administátora. <b>Vaše zpráva nemohla být odeslána.</b>';
 $messages['smtpconnerror'] = 'Chyba SMTP ($code): Připojení k serveru selhalo';
 $messages['smtpautherror'] = 'Chyba SMTP ($code): Chyba přihlášení';
 $messages['smtpfromerror'] = 'Chyba SMTP ($code): Nelze nastavit odesílatele "$from"';
 $messages['smtptoerror'] = 'Chyba SMTP ($code): Nelze přidat příjemce "$to"';
 $messages['smtprecipientserror'] = 'Chyba SMTP: Nelze zpracovat seznam příjemců';
 $messages['smtperror'] = 'Chyba SMTP: $msg';
+$messages['emailformaterror'] = 'Neplatná e-mailová adresa: $email';
 
-?>
\ No newline at end of file
+?>
index 5125c7e813c3a18084f7a2ca151b2ca6b4188da4..cdbf86037d1a382771949302c0d50b3e75962903 100644 (file)
@@ -248,6 +248,7 @@ $labels['advancedoptions'] = 'Dewisiadau uwch';
 $labels['focusonnewmessage'] = 'Ffocysu\'r porwr ar y neges newydd';
 $labels['checkallfolders'] = 'Chwilio pob ffolder am negeseuon newydd';
 $labels['displaynext'] = 'Ar ôl dileu/symud neges dangos y neges nesaf';
+$labels['indexsort'] = 'Defnyddio mynegai negeseuon i drefnu yn ôl dyddiad';
 $labels['mainoptions'] = 'Prif Ddewisiadau';
 $labels['section'] = 'Adran';
 $labels['maintenance'] = 'Gwaith cynnal a chadw';
index 5ddc8a3d4ed48fc96c7ff354291eda1a8665b8f1..c7d5886e4e834e8962b47cea764f3c42c457683f 100644 (file)
@@ -25,6 +25,7 @@ $messages['nomessagesfound'] = 'Dim negeseuon wedi eu canfod yn y blwch hwn';
 $messages['loggedout'] = 'Rydych wedi gorffen y sesiwn yn llwyddianus. Hwyl fawr!';
 $messages['mailboxempty'] = 'Blwch yn wag';
 $messages['loading'] = 'Yn llwytho...';
+$messages['uploading'] = 'Yn llwytho ffeil i fyny...';
 $messages['loadingdata'] = 'Yn llwytho data...';
 $messages['checkingmail'] = 'Yn edrych am negeseuon newydd...';
 $messages['sendingmessage'] = 'Yn danfon neges...';
@@ -65,6 +66,7 @@ $messages['notsentwarning'] = 'Ni ddanfonwyd y neges. Hoffech chi gael gwared a\
 $messages['noldapserver'] = 'Dewiswch weinydd ldap i chwilio';
 $messages['nocontactsreturned'] = 'Ni gafwyd hyd i unrhyw gysylltiadau';
 $messages['nosearchname'] = 'Rhowch enw cyswllt neu gyfeiriad e-bost';
+$messages['notuploadedwarning'] = 'Nid yw pob atodiad wedi eu llwytho i fyny eto. Triwch eto neu canslo.';
 $messages['searchsuccessful'] = 'Cafwyd hyd i $nr neges';
 $messages['searchnomatch'] = 'Ni gafwyd hyd i unrhyw ganlyniadau chwilio';
 $messages['searching'] = 'Yn chwilio...';
@@ -101,5 +103,6 @@ $messages['smtpfromerror'] = 'Gwall SMTP ($code): Methwyd gosod y danfonwr "$fro
 $messages['smtptoerror'] = 'Gwall SMTP ($code): Methwyd ychwanegu derbynwr "$to"';
 $messages['smtprecipientserror'] = 'Gwall SMTP: Nid oedd yn bosib darllen y rhestr o dderbynnwyr';
 $messages['smtperror'] = 'Gwall SMTP: $msg';
+$messages['emailformaterror'] = 'Cyfeiriad e-bost anghywir: $email';
 
 ?>
index ebe538af92e9682b7b68bdd9e739408ceabd43a1..1f4edf9f53ce4d9492d657f7251db5a9a234becc 100644 (file)
@@ -14,7 +14,7 @@
 | Corrections: Alexander Stiebing <ja.stiebing[NOSPAM]@web.de>          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2854 2009-08-12 11:00:13Z thomasb $
+@version $Id: labels.inc 3065 2009-10-27 16:08:00Z thomasb $
 
 */
 
@@ -252,6 +252,7 @@ $labels['advancedoptions'] = 'Erweiterte Einstellungen';
 $labels['focusonnewmessage'] = 'Fokussiere Browserfenster bei neuen Nachrichten';
 $labels['checkallfolders'] = 'Alle Ordner auf neue Nachrichten prüfen';
 $labels['displaynext'] = 'Zeige nächste Nachricht nach verschieben/löschen';
+$labels['indexsort'] = 'Benutze Index für Sortierung nach Datum (schneller)';
 $labels['mainoptions'] = 'Allgemein';
 $labels['section'] = 'Bereich';
 $labels['maintenance'] = 'Wartung';
index 522b267b492499fd1eed4c97f6f483fe2e8f9ed2..10deef7a38252527e35ba9409375fc66bfaabfbd 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2755 2009-07-15 09:49:35Z thomasb $
+@version $Id: messages.inc 3065 2009-10-27 16:08:00Z thomasb $
 
 */
 
@@ -29,6 +29,7 @@ $messages['loggedout'] = 'Sie haben Ihre Session erfolgreich beendet. Auf Wieder
 $messages['mailboxempty'] = 'Ordner ist leer';
 $messages['loading'] = 'Daten werden geladen...';
 $messages['loadingdata'] = 'Daten werden geladen...';
+$messages['uploading'] = 'Datei wird hochgeladen...';
 $messages['checkingmail'] = 'Überprüfung auf neue Nachrichten...';
 $messages['sendingmessage'] = 'Nachricht wird gesendet...';
 $messages['messagesent'] = 'Nachricht erfolgreich gesendet';
@@ -68,6 +69,7 @@ $messages['notsentwarning'] = 'Ihre Nachricht wurde nicht gesendet. Wollen Sie d
 $messages['noldapserver'] = 'Bitte wählen Sie einen LDAP-Server aus';
 $messages['nocontactsreturned'] = 'Es wurden keine Kontakte gefunden';
 $messages['nosearchname'] = 'Bitte geben Sie einen Namen oder eine E-Mail-Adresse ein';
+$messages['notuploadedwarning'] = 'Es wurden noch nicht alle Dateien hochgeladen. Bitte warten oder Upload abbrechen.';
 $messages['searchsuccessful'] = '$nr Nachrichten gefunden';
 $messages['searchnomatch'] = 'Keine Treffer';
 $messages['searching'] = 'Suche...';
@@ -97,11 +99,13 @@ $messages['importconfirm'] = '<b>Es wurden $inserted Adressen erfolgreich import
 $messages['opnotpermitted'] = 'Operation nicht erlaubt!';
 $messages['nofromaddress'] = 'Fehlende E-Mail-Adresse in ausgewählter Identität';
 $messages['editorwarning'] = 'Beim Wechseln in den Texteditor gehen alle Textformatierungen verloren. Möchten Sie fortfahren?';
+$messages['httpreceivedencrypterror'] = 'Ein gravierender Konfigurationsfehler ist aufgetreten. Kontaktieren Sie den Server-Administrator. <b>Die Nachricht wurde nicht gesendet!</b>';
 $messages['smtpconnerror'] = 'SMTP Fehler ($code): Die Verbindung ist fehlgeschlagen';
 $messages['smtpautherror'] = 'SMTP Fehler ($code): Die Authentisierung ist fehlgeschlagen';
 $messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender ("$from") konnte nicht gesetzt werden';
 $messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger ("$to") konnte nicht gesetzt werden';
 $messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden';
 $messages['smtperror'] = 'SMTP Fehler: $msg';
+$messages['emailformaterror'] = 'Ungültige E-Mail-Adresse: $email';
 
 ?>
index af3f19f5e540624f6080b4da65f2ca58764ebd77..0a5b25a131167d9b052bbf2f6bec900511809d8e 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Marcel Schlesinger <info@marcel-schlesinger.de>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2854 2009-08-12 11:00:13Z thomasb $
+@version $Id: labels.inc 3065 2009-10-27 16:08:00Z thomasb $
 
 */
 
@@ -251,6 +251,7 @@ $labels['advancedoptions'] = 'Erweiterte Einstellungen';
 $labels['focusonnewmessage'] = 'Fokussiere Browserfenster bei neuen Nachrichten';
 $labels['checkallfolders'] = 'Alle Ordner auf neue Nachrichten prüfen';
 $labels['displaynext'] = 'Zeige nächste Nachricht nach verschieben/löschen';
+$labels['indexsort'] = 'Benutze Index für Sortierung nach Datum (schneller)';
 $labels['mainoptions'] = 'Allgemein';
 $labels['section'] = 'Bereich';
 $labels['maintenance'] = 'Wartung';
index 0437bb08a7b6bc7467bd9deb24ba7db65bb6e4a6..05d3905a3246d3879aa71f5d44bcff6ac5ebd1a0 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Marcel Schlesinger <info@marcel-schlesinger.de>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2755 2009-07-15 09:49:35Z thomasb $
+@version $Id: messages.inc 3065 2009-10-27 16:08:00Z thomasb $
 
 */
 
@@ -29,6 +29,7 @@ $messages['loggedout'] = 'Sie haben Ihre Session erfolgreich beendet. Auf Wieder
 $messages['mailboxempty'] = 'Ordner ist leer';
 $messages['loading'] = 'Lade...';
 $messages['loadingdata'] = 'Daten werden geladen...';
+$messages['uploading'] = 'Datei wird hochgeladen...';
 $messages['checkingmail'] = 'Überprüfung auf neue Nachrichten...';
 $messages['sendingmessage'] = 'Nachricht wird gesendet...';
 $messages['messagesent'] = 'Nachricht erfolgreich gesendet';
@@ -68,6 +69,7 @@ $messages['notsentwarning'] = 'Ihre Nachricht wurde nicht gesendet. Wollen Sie d
 $messages['noldapserver'] = 'Bitte wählen Sie einen LDAP-Server aus';
 $messages['nocontactsreturned'] = 'Es wurden keine Kontakte gefunden';
 $messages['nosearchname'] = 'Bitte geben Sie einen Namen oder eine E-Mail-Adresse ein';
+$messages['notuploadedwarning'] = 'Es wurden noch nicht alle Dateien hochgeladen. Bitte warten oder Upload abbrechen.';
 $messages['searchsuccessful'] = '$nr Nachrichten gefunden';
 $messages['searchnomatch'] = 'Die Suche lieferte keine Treffer';
 $messages['searching'] = 'Suche...';
@@ -104,5 +106,6 @@ $messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender ("$from") konnte
 $messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger ("$to") konnte nicht gesetzt werden';
 $messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden';
 $messages['smtperror'] = 'SMTP Fehler: $msg';
+$messages['emailformaterror'] = 'Ungültige E-Mail-Adresse: $email';
 
 ?>
index c3e7c1be0c54cad58b9ed5d3cd9dd8934a2c104b..f86318406dc89db9e1424db1330feca503b74644 100644 (file)
@@ -2,19 +2,19 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/el/labels.inc                                                |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Jim Deves <jim@cobaltblue.gr>                                 |
- |         John Economou <hsoc@irc.gr>                                   |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/el/labels.inc                                                |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Jim Deves <jim@cobaltblue.gr>                                 |
+|         John Economou <hsoc@irc.gr>                                   |
++-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
+@version $Id: labels.inc 3075 2009-10-28 18:37:59Z yllar $
 
 */
 
@@ -69,6 +69,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'] = 'Δημιουργία νέου μηνύματος';
@@ -80,7 +104,7 @@ $labels['movemessagetotrash'] = 'Μετακίνηση μηνύματος στο
 $labels['printmessage'] = 'Εκτύπωση';
 $labels['previousmessage'] = 'Εμφάνιση προηγούμενου μηνύματος';
 $labels['previousmessages'] = 'Εμφάνιση προηγούμενης ομάδας μηνυμάτων';
-$labels['firstmessage'] = 'Εμφάνιση πρώτου μυνήματος';
+$labels['firstmessage'] = 'Εμφάνιση πρώτου μηνύματος';
 $labels['firstmessages'] = 'Εμφάνιση πρώτης ομάδας μηνυμάτων';
 $labels['nextmessage'] = 'Εμφάνιση επόμενου μηνύματος';
 $labels['nextmessages'] = 'Εμφάνιση επόμενης ομάδας μηνυμάτων';
@@ -91,18 +115,27 @@ $labels['viewsource'] = 'Προβολή πηγαίου κώδικα';
 $labels['markmessages'] = 'Σήμανση μηνυμάτων';
 $labels['markread'] = 'ως αναγνωσμένα';
 $labels['markunread'] = 'ως μη-αναγνωσμένα';
+$labels['markflagged'] = 'Με σήμανση';
+$labels['markunflagged'] = 'Χωρίς σήμανση';
+$labels['messageactions'] = 'Περισσότερες ενέργειες...';
 $labels['select'] = 'Επιλογή';
 $labels['all'] = 'Όλα';
 $labels['none'] = 'Κανένα';
 $labels['unread'] = 'Μη αναγνωσμένα';
+$labels['unanswered'] = 'Αναπάντητο';
+$labels['deleted'] = 'Διεγραμμένο';
+$labels['invert'] = 'Αναστροφή';
+$labels['filter'] = 'Φίλτρο';
 $labels['compact'] = 'Συμπίεση';
-$labels['empty'] = 'δειασμα';
+$labels['empty'] = 'Άδειασμα';
 $labels['purge'] = 'Καθάρισμα';
 $labels['quota'] = 'Χρήση δίσκου';
 $labels['unknown'] = 'άγνωστο';
 $labels['unlimited'] = 'απεριόριστο';
 $labels['quicksearch'] = 'Γρήγορη Εύρεση';
 $labels['resetsearch'] = 'Επαναφορά Εύρεσης';
+$labels['msgtext'] = 'Σε όλο το μήνυμα';
+$labels['openinextwin'] = 'Άνοιγμα σε νέο παράθυρο';
 $labels['compose'] = 'Συγγραφή μηνύματος';
 $labels['savemessage'] = 'Αποθήκευση ως πρόχειρου';
 $labels['sendmessage'] = 'Αποστολή μηνύματος τώρα';
@@ -125,6 +158,8 @@ $labels['nosubject'] = '(κανένα θέμα)';
 $labels['showimages'] = 'Εμφάνιση εικόνων';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Απλό κείμενο';
+$labels['savesentmessagein'] = 'Αποθήκευση απεσταλμένου στο φάκελο';
+$labels['dontsave'] = 'Χωρίς αποθήκευση';
 $labels['addcc'] = 'Προσθήκη Cc';
 $labels['addbcc'] = 'Προσθήκη Bcc';
 $labels['addreplyto'] = 'Προσθήκη Απάντηση-Σε';
@@ -148,12 +183,17 @@ $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['done'] = 'Έτοιμο';
 $labels['settingsfor'] = 'Ρυθμίσεις για';
 $labels['preferences'] = 'Προτιμήσεις';
 $labels['userpreferences'] = 'Προτιμήσεις χρήστη';
@@ -172,8 +212,25 @@ $labels['dstactive'] = 'Daylight savings';
 $labels['htmleditor'] = 'Σύνθεση HTML μηνύματος';
 $labels['htmlsignature'] = 'Υπογραφή HTML';
 $labels['previewpane'] = 'Εμφάνιση προηγούμενου παραθύρου';
+$labels['skin'] = 'Θεματική παραλλαγή';
+$labels['logoutclear'] = 'Άδειασμα κάδου στην έξοδο';
+$labels['logoutcompact'] = 'Συμπίεση εισερχομένων στην έξοδο';
+$labels['serversettings'] = 'Ρυθμίσεις εξυπηρετητή';
+$labels['mdnrequests'] = 'Ειδοποιήσεις αποστολέα';
+$labels['autosend'] = 'Στείλε αυτόματα';
+$labels['skipdeleted'] = 'Να μην εμφανίζονται διεγραμένα  μυνήματα';
+$labels['fromknownsenders'] = 'από γνωστούς αποστολείς';
+$labels['always'] = 'πάντα';
+$labels['showinlineimages'] = 'Προβολή συνημένων φωτογραφιών, κάτω από το μήνυμα';
 $labels['autosavedraft'] = 'Αυτόματη προχείρου';
+$labels['everynminutes'] = 'κάθε $n λεπτό/α';
 $labels['never'] = 'ποτέ';
+$labels['messagesdisplaying'] = 'Προβολή Μηνυμάτων';
+$labels['messagescomposition'] = 'Συνθέτοντας Μηνύματα';
+$labels['mimeparamfolding'] = 'Ονόματα συνημένων';
+$labels['advancedoptions'] = 'Προχωρημένες επιλογές';
+$labels['mainoptions'] = 'Βασικές επιλογές';
+$labels['newmessage'] = 'Νέο Μήνυμα';
 $labels['folder'] = 'Φάκελος';
 $labels['folders'] = 'Φάκελοι';
 $labels['foldername'] = 'Όνομα φακέλου';
@@ -185,8 +242,9 @@ $labels['rename'] = 'Μετονομασία';
 $labels['renamefolder'] = 'Μετονομασία φακέλου';
 $labels['deletefolder'] = 'Διαγραφή φακέλου';
 $labels['managefolders'] = 'Διαχείριση φακέλων';
+$labels['specialfolders'] = 'Ειδικοί Φάκελοι';
 $labels['sortby'] = 'Ταξινόμηση κατά';
 $labels['sortasc'] = 'Αύξουσα ταξινόμηση';
 $labels['sortdesc'] = 'Φθίνουσα ταξινόμηση';
 
-?>
\ No newline at end of file
+?>
index ac01d1c223a3c1369405ce23aaf6ba9db2fa567a..dea38eeb7da3262570fdfcd6ca5a7623fde48100 100644 (file)
@@ -2,19 +2,19 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/el/messages.inc                                              |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Jim Deves <jim@cobaltblue.gr>                                 |
- |         John Economou <hsoc@irc.gr>                                   |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/el/messages.inc                                              |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Jim Deves <jim@cobaltblue.gr>                                 |
+|         John Economou <hsoc@irc.gr>                                   |
++-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 3061 2009-10-26 21:42:58Z yllar $
 
 */
 
@@ -48,6 +48,10 @@ $messages['deletecontactconfirm'] = 'Θέλετε να διαγράψετε τη
 $messages['deletemessagesconfirm'] = 'Θέλετε να διαγράψετε το συγκεκριμένο μήνυμα/τα;';
 $messages['deletefolderconfirm'] = 'Θέλετε να διαγράψετε το συγκεκριμένο φάκελο;';
 $messages['purgefolderconfirm'] = 'Θέλετε να διαγράψετε όλα τα μηνύματα στο συγκεκριμένο φάκελο;';
+$messages['foldercreating'] = 'Δημιουργία φακέλου';
+$messages['folderdeleting'] = 'Διαγραφή φακέλου';
+$messages['folderrenaming'] = 'Μετονομασία φακέλου';
+$messages['foldermoving'] = 'Μεταφορά φακέλου';
 $messages['formincomplete'] = 'Η φόρμα δεν έχει συμπληρωθεί πλήρως';
 $messages['noemailwarning'] = 'Παρακαλώ εισάγεται έγκυρη διεύθυνση email';
 $messages['nonamewarning'] = 'Παρακαλώ εισάγεται όνομα';
@@ -79,5 +83,6 @@ $messages['receiptsent'] = 'Επιτυχής αποστολή αναφοράς 
 $messages['errorsendingreceipt'] = 'Αποστολή αναφοράς απέτυχε';
 $messages['nodeletelastidentity'] = 'Δε μπορείτε να διαγράψετε αυτήν την ταυτότητα, είναι η τελευταία.';
 $messages['addsubfolderhint'] = 'Αυτός ο φάκελος θα δημιουργηθεί ως υποφάκελος του επιλεγμένου';
+$messages['importwait'] = 'Εισαγωγή, παρακαλώ περιμένετε...';
 
 ?>
\ No newline at end of file
index b6b8bb4230c70102a38c9972cc4f768412d07e52..659631db7bdbee9f94a763b984560b6b6a58161d 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2831 2009-08-03 18:42:57Z alec $
+ @version $Id: labels.inc 2983 2009-09-23 12:32:09Z alec $
 
 */
 
@@ -306,6 +306,7 @@ $labels['advancedoptions'] = 'Advanced options';
 $labels['focusonnewmessage'] = 'Focus browser window on new message';
 $labels['checkallfolders'] = 'Check all folders for new messages';
 $labels['displaynext'] = 'After message delete/move display the next message';
+$labels['indexsort'] = 'Use message index for sorting by date';
 $labels['mainoptions'] = 'Main Options';
 $labels['section'] = 'Section';
 $labels['maintenance'] = 'Maintenance';
index 79c9f162ec9151f08c7ab822196a0abb213882fe..15e5c565095e75cc85e21112fe9397eef828ea5f 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2755 2009-07-15 09:49:35Z thomasb $
+ @version $Id: messages.inc 3042 2009-10-14 10:52:27Z alec $
 
 */
 
@@ -28,6 +28,7 @@ $messages['nomessagesfound'] = 'No messages found in this mailbox';
 $messages['loggedout'] = 'You have successfully terminated the session. Good bye!';
 $messages['mailboxempty'] = 'Mailbox is empty';
 $messages['loading'] = 'Loading...';
+$messages['uploading'] = 'Uploading file...';
 $messages['loadingdata'] = 'Loading data...';
 $messages['checkingmail'] = 'Checking for new messages...';
 $messages['sendingmessage'] = 'Sending message...';
@@ -68,6 +69,7 @@ $messages['notsentwarning'] = 'Message has not been sent. Do you want to discard
 $messages['noldapserver'] = 'Please select an ldap server to search';
 $messages['nocontactsreturned'] = 'No contacts were found';
 $messages['nosearchname'] = 'Please enter a contact name or email address';
+$messages['notuploadedwarning'] = 'Not all attachments have been uploaded yet. Please wait or cancel the upload.';
 $messages['searchsuccessful'] = '$nr messages found';
 $messages['searchnomatch'] = 'Search returned no matches';
 $messages['searching'] = 'Searching...';
@@ -104,5 +106,6 @@ $messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from"';
 $messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to"';
 $messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list';
 $messages['smtperror'] = 'SMTP Error: $msg';
+$messages['emailformaterror'] = 'Incorrect e-mail address: $email';
 
 ?>
index 4191351fa682f54c78a15207eb767a7766ab98a2..a688df673c182dae38727f1413e839b30e1c4129 100644 (file)
@@ -127,6 +127,7 @@ $labels['none'] = 'Ninguno';
 $labels['unread'] = 'Sin leer';
 $labels['flagged'] = 'Marcado';
 $labels['unanswered'] = 'Sin respuesta';
+$labels['deleted'] = 'Eliminado';
 $labels['invert'] = 'Invertir';
 $labels['filter'] = 'Filtrar';
 $labels['compact'] = 'Compactar';
@@ -142,6 +143,7 @@ $labels['msgtext'] = 'Mensaje completo';
 $labels['openinextwin'] = 'Abrir en ventana nueva';
 $labels['emlsave'] = 'Guardar (.eml)';
 $labels['compose'] = 'Escribir un mensaje';
+$labels['editasnew'] = 'Editar como nuevo';
 $labels['savemessage'] = 'Guardar como borrador';
 $labels['sendmessage'] = 'Enviar ahora el mensaje';
 $labels['addattachment'] = 'Añadir un archivo';
@@ -252,6 +254,13 @@ $labels['2047folding'] = 'RFC 2047 (Otro)';
 $labels['advancedoptions'] = 'Opciones Avanzadas';
 $labels['focusonnewmessage'] = 'Traer al frente la ventana del navegador cuando haya nuevos mensajes';
 $labels['checkallfolders'] = 'Verificar todas las carpetas por nuevos mensajes';
+$labels['displaynext'] = 'Luedo de eliminar/mover, mostrar el próximo mensaje';
+$labels['indexsort'] = 'Usar el índice de mensaje para ordenar por fecha';
+$labels['mainoptions'] = 'Opciones Principales';
+$labels['section'] = 'Selección';
+$labels['maintenance'] = 'Mantenimiento';
+$labels['newmessage'] = 'Nuevo Mensaje';
+$labels['listoptions'] = 'Opciones de Listado';
 $labels['folder'] = 'Carpeta';
 $labels['folders'] = 'Carpetas';
 $labels['foldername'] = 'Nombre de carpeta';
index 027485bdfcf68aac0d5d1a2d72b112285f37fcc9..c8d6339c3e1c8c1fe74c5d33f26e404f229d9079 100644 (file)
@@ -26,6 +26,7 @@ $messages['cookiesdisabled'] = 'Su navegador no acepta cookies';
 $messages['sessionerror'] = 'Su sesión no existe o ha expirado';
 $messages['imaperror'] = 'Error de conexión con el servidor IMAP';
 $messages['servererror'] = '¡Error en el servidor!';
+$messages['invalidrequest'] = 'Peteción invalida! No se guardó nada.';
 $messages['nomessagesfound'] = 'No se han encontrado mensajes en esta casilla';
 $messages['loggedout'] = 'Ha cerrado la sesión. ¡Hasta pronto!';
 $messages['mailboxempty'] = 'La casilla está vacía';
@@ -49,6 +50,7 @@ $messages['errorsavingsent'] = 'Ocurrió un error al guardar el mensaje enviado'
 $messages['errorsaving'] = 'Ocurrió un error al guardar';
 $messages['errormoving'] = 'No se ha podido mover el mensaje';
 $messages['errordeleting'] = 'No se ha podido eliminar el mensaje';
+$messages['errormarking'] = 'No se puede marcar el mensaje.';
 $messages['deletecontactconfirm'] = '¿Realmente quiere eliminar los contactos seleccionados?';
 $messages['deletemessagesconfirm'] = '¿Realmente quiere eliminar los mensajes seleccionados?';
 $messages['deletefolderconfirm'] = '¿Realmente quiere eliminar esta carpeta?';
@@ -99,5 +101,11 @@ $messages['opnotpermitted'] = 'Operación no permitida!';
 $messages['nofromaddress'] = 'El contacto seleccionado no tiene dirección de e-mail';
 $messages['editorwarning'] = 'Si cambia a texto plano se perderán todas las opciones de formato. ¿Desea continuar?';
 $messages['httpreceivedencrypterror'] = 'Ha ocurrido un error fatal de configuración. Contacte inmediatamente a su administrador. <b>Su mensaje no ha sido enviado.</b>';
+$messages['smtpconnerror'] = 'Error SMTP ($code): Conexión al servidor falló';
+$messages['smtpautherror'] = 'Error SMTP ($code): Falló la autentificación';
+$messages['smtpfromerror'] = 'Error SMTP ($code): No se pudo establecer el remitente "$from"';
+$messages['smtptoerror'] = 'Error SMTP ($code): No se puedo agregar el destinatario "$to"';
+$messages['smtprecipientserror'] = 'Error SMTP: No se pudo leer la lista de destinatarios';
+$messages['smtperror'] = 'Error SMTP: $msg';
 
 ?>
index 8ee16b89601721f8edcb72c5be799461ef6fb6ab..0a0bf1ae0d6f144cc5f218338515c19a8e2c3271 100644 (file)
@@ -251,6 +251,7 @@ $labels['advancedoptions'] = 'Lisaseadistused';
 $labels['focusonnewmessage'] = 'Fokusseeri brauseri aken uue kirja korral';
 $labels['checkallfolders'] = 'Kontrolli uusi kirju kõigist kaustadest';
 $labels['displaynext'] = 'Peale kirja kustutamist/liigutamist näita järgmist kirja';
+$labels['indexsort'] = 'Kasuta kuupäeva järgi sorteerimiseks kirjade indeksit';
 $labels['mainoptions'] = 'Peamised valikud';
 $labels['section'] = 'Osa';
 $labels['maintenance'] = 'Hooldus';
index 30d85c7cddbb1bcbdec7d8204e36284ba5b343f6..3247ac416560669953bd7dceb2e4cfcdf28b15f0 100644 (file)
@@ -28,6 +28,7 @@ $messages['nomessagesfound'] = 'Postkast paistab tühi olevat';
 $messages['loggedout'] = 'Sinu sessioon on edukalt lõpetatud. Nägemiseni!';
 $messages['mailboxempty'] = 'Postkast on tühi';
 $messages['loading'] = 'Laadimine...';
+$messages['uploading'] = 'Faili üleslaadimine...';
 $messages['loadingdata'] = 'Andmete laadimine...';
 $messages['checkingmail'] = 'Uute kirjade kontrollimine...';
 $messages['sendingmessage'] = 'Kirja saatmine...';
@@ -68,6 +69,7 @@ $messages['notsentwarning'] = 'Kirja ei suudetud saata. Soovid selle ära visata
 $messages['noldapserver'] = 'Palun vali otsinguks LDAPi server';
 $messages['nocontactsreturned'] = 'Ühtegi kontakti ei leitud';
 $messages['nosearchname'] = 'Palun sisesta kontakti nimi või e-maili aadress';
+$messages['notuploadedwarning'] = 'Kõik manused pole veel üles laaditud. Palun oota või tühista üleslaadimine.';
 $messages['searchsuccessful'] = 'Leiti $nr kirja';
 $messages['searchnomatch'] = 'Otsingule vastavaid kirju ei leitud';
 $messages['searching'] = 'Otsimine...';
@@ -104,5 +106,6 @@ $messages['smtpfromerror'] = 'SMTP Tõrge ($code): "$from" saatjaks määramine
 $messages['smtptoerror'] = 'SMTP Tõrge ($code): "$to" saajaks määramine nurjus';
 $messages['smtprecipientserror'] = 'SMTP Tõrge: Saajate nimekirja parsimine nurjus';
 $messages['smtperror'] = 'SMTP Tõrge: $msg';
+$messages['emailformaterror'] = 'Lubamatu e-posti aadress: $email';
 
 ?>
index e82e7c78ab0114691a556d6fe85feb6be697b66e..a3a1eb1c83fd77b3160a83bfbe32936ce8a8e5bf 100644 (file)
@@ -11,7 +11,7 @@
 +-----------------------------------------------------------------------+
 | Author: Moshe Leibovitch  <moish@mln.co.il>                           |
 | Updates: Noor Dawod <noor@comrax.com>                                 |
-| Updates: Moshe Leibovitch  <moish@mln.co.il>  19082009                |
+| Updates: Moshe Leibovitch  <moish@mln.co.il>  27092009                |
 +-----------------------------------------------------------------------+
 */
 
@@ -249,6 +249,7 @@ $labels['advancedoptions'] = 'הגדרות נוספות';
 $labels['focusonnewmessage'] = 'מיקוד הסמן על החלון עם ההודעה החדשה';
 $labels['checkallfolders'] = 'בדיקת הודעות חדשות בכל התיקים';
 $labels['displaynext'] = 'מעבר להודעה הבאה לאחר מחיקה או תיוק';
+$labels['indexsort'] = 'שימוש בשרת המערכת לשם מיון התצוגה לפי תאריך';
 $labels['mainoptions'] = 'אפשרויות עיקריות';
 $labels['section'] = 'קטע';
 $labels['maintenance'] = 'תחזוקה';
index ccd3959d13ce521743e3225d87bb8b15031a6aa8..3cb80c6078e5a90c3bca7ca14d1222e6d3b18e26 100644 (file)
@@ -11,7 +11,7 @@
 +-----------------------------------------------------------------------+
 | Author: Moshe Leibovitch    <moish@mln.co.il>                         |
 | Updates: Noor Dawod <noor@comrax.com>                                 |
-| Updates: Moshe Leibovitch  <moish@mln.co.il>  30072009                |
+| Updates: Moshe Leibovitch  <moish@mln.co.il>  25102009                |
 +-----------------------------------------------------------------------+
 
 */
@@ -27,6 +27,7 @@ $messages['nomessagesfound'] = 'לא נמצאו הודעות בתיבה זו';
 $messages['loggedout'] = 'הקשר הסתיים. להתראות!';
 $messages['mailboxempty'] = 'רשימת ההודעות ריקה';
 $messages['loading'] = 'טעינה...';
+$messages['uploading'] = 'קובץ עולה...';
 $messages['loadingdata'] = 'טעינת מידע...';
 $messages['checkingmail'] = 'בדיקת קיום הודעות חדשות...';
 $messages['sendingmessage'] = 'ההודעה נמסרת...';
@@ -67,6 +68,7 @@ $messages['notsentwarning'] = 'ההודעה לא נשלחה. האם לבטל?';
 $messages['noldapserver'] = 'נא לבחור שרת כתובות לחיפוש';
 $messages['nocontactsreturned'] = 'לא נמצאו אנשי קשר';
 $messages['nosearchname'] = 'נא להוסיף איש קשר או כתובת דוא\"ל';
+$messages['notuploadedwarning'] = 'עדיין לא הועלו כל הקבצים. נא לחכות או לבטל הפעולה.';
 $messages['searchsuccessful'] = 'נמצאו $nr הודעות';
 $messages['searchnomatch'] = 'תוצאת החיפוש ריקה';
 $messages['searching'] = 'חיפוש...';
@@ -103,5 +105,6 @@ $messages['smtpfromerror'] = 'SMTP ($code): "$from" לא נרשמה כתובת 
 $messages['smtptoerror'] = 'SMTP ($code): "$to" לא נרשמה כתובת המקבל';
 $messages['smtprecipientserror'] = 'SMTP : לא ניתן לפענח רשימת נמענים';
 $messages['smtperror'] = 'SMTP: $msg';
+$messages['emailformaterror'] = '$email  כתובת דוא"ל שגויה';
 
 ?>
index 964d41d84862932d497694fb88b41e87e6a1e38b..06922425e3df41fa9fd5beb5896e559d1ab4d284 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: index.inc 2653 2009-06-18 20:42:48Z yllar $
+ $Id: index.inc 2991 2009-09-25 12:23:46Z alec $
 
 */
 
 // langage codes according to ISO 639-1
 // country codes according to ISO 3166-1 (Alpha-2)
+// original names from http://www.mediaglyphs.org/mg/p/langnames.html
 
 $rcube_languages = array(
-  'sq_AL' => 'Albanian',
-  'ar_SA' => 'Arabic',
-  'hy_AM' => 'Armenian',
-  'ast'        => 'Asturianu',
-  'az_AZ' => 'Azerbaijani',
-  'bs_BA' => 'Bosnian (Serbian Latin)',
-  'bg_BG' => 'Bulgarian',
-  'bn_BD' => 'Bengali',
-  'br'   => 'Brezhoneg',
-  'ca_ES' => 'Català',
-  'cy_GB' => 'Cymraeg',
-  'zh_CN' => 'Chinese (Simplified)',
-  'zh_TW' => 'Chinese (Traditional)',
+  'sq_AL' => 'Albanian (Shqip)',
+  'ar_SA' => 'Arabic (العربية)',
+  'hy_AM' => 'Armenian (Հայերեն)',
+  'ast'          => 'Asturiana (Asturianu)',
+  'az_AZ' => 'Azerbaijani (Azəri)',
+  'eu_ES' => 'Basque (Euskara)',
+  'bn_BD' => 'Bengali (বাংলা)',
+  'bs_BA' => 'Bosnian (Bošnjački)',
+  'br'   => 'Breton (Brezhoneg)',
+  'bg_BG' => 'Bulgarian (Български)',
+  'ca_ES' => 'Catalan (Català)',
+  'zh_CN' => 'Chinese (普通话)',
+  'zh_TW' => 'Chinese (國語)',
   'hr_HR' => 'Croatian (Hrvatski)',
-  'cs_CZ' => 'Czech',
-  'da_DK' => 'Dansk',
-  'fa_AF' => 'Dari',
+  'cs_CZ' => 'Czech (Česky)',
+  'da_DK' => 'Danish (Dansk)',
+  'fa_AF' => 'Dari (ﻯﺭﺩ)',
   'de_DE' => 'Deutsch (Deutsch)',
   'de_CH' => 'Deutsch (Schweiz)',
+  'nl_NL' => 'Dutch (Nederlands)',
   'en_GB' => 'English (GB)',
   'en_US' => 'English (US)',
-  'es_AR' => 'Spanish (Argentina)',
-  'es_ES' => 'Español',
   'eo'    => 'Esperanto',
-  'et_EE' => 'Estonian',
-  'eu_ES' => 'Euskara (Basque)',
+  'et_EE' => 'Estonian (Eesti)',
   'fi_FI' => 'Finnish (Suomi)',
-  'nl_BE' => 'Flemish',
-  'fr_FR' => 'Français',
-  'gl_ES' => 'Galego (Galician)',
-  'ka_GE' => 'Georgian (Kartuli)',
-  'el_GR' => 'Greek',
-  'he_IL' => 'Hebrew',
-  'hi_IN' => 'Hindi',
-  'hu_HU' => 'Hungarian',
-  'is_IS' => 'Icelandic',
-  'id_ID' => 'Indonesian',
-  'ga_IE' => 'Irish',
-  'it_IT' => 'Italiano',
+  'nl_BE' => 'Flemish (Vlaams)',
+  'fr_FR' => 'French (Français)',
+  'gl_ES' => 'Galician (Galego)',
+  'ka_GE' => 'Georgian (ქართული)',
+  'el_GR' => 'Greek (Ελληνικά)',
+  'he_IL' => 'Hebrew (עברית)',
+  'hi_IN' => 'Hindi (हिनदी)',
+  'hu_HU' => 'Hungarian (Magyar)',
+  'is_IS' => 'Icelandic (Íslenska)',
+  'id_ID' => 'Indonesian (Bahasa Indonesia)',
+  'ga_IE' => 'Irish (Gaedhilge)',
+  'it_IT' => 'Italian (Italiano)',
   'ja_JP' => 'Japanese (日本語)',
-  'ko_KR' => 'Korean',
+  'ko_KR' => 'Korean (한국어)',
   'ku'    => 'Kurdish (Kurmancî)',
-  'lv_LV' => 'Latvian',
-  'lt_LT' => 'Lithuanian',
-  'mk_MK' => 'Macedonian',
-  'ms_MY' => 'Malay',
-  'mr_IN' => 'Marathi',
-  'nl_NL' => 'Nederlands',
-  'ne_NP' => 'Nepali',
-  'nb_NO' => 'Norsk (Bokmål)',
-  'nn_NO' => 'Norsk (Nynorsk)',
+  'lv_LV' => 'Latvian (Latviešu)',
+  'lt_LT' => 'Lithuanian (Lietuviškai)',
+  'mk_MK' => 'Macedonian (Македонски)',
+  'ms_MY' => 'Malay (Bahasa Melayu)',
+  'mr_IN' => 'Marathi (मराठी)',
+  'ne_NP' => 'Nepali (नेपाली)',
+  'nb_NO' => 'Norwegian (Bokmål)',
+  'nn_NO' => 'Norwegian (Nynorsk)',
   'ps'           => 'Pashto',
-  'fa'    => 'Persian (Farsi)',
-  'pl_PL' => 'Polski',
-  'pt_BR' => 'Portuguese (Brazilian)',
-  'pt_PT' => 'Portuguese (Standard)',
-  'ro_RO' => 'Romanian',
-  'ru_RU' => 'Русский',
-  'sr_CS' => 'Serbian (Cyrillic)',
-  'si_LK' => 'Sinhala',
-  'sk_SK' => 'Slovak',
-  'sl_SI' => 'Slovenian',
+  'fa'    => 'Persian (دری)',
+  'pl_PL' => 'Polish (Polski)',
+  'pt_BR' => 'Portuguese (Brasil)',
+  'pt_PT' => 'Portuguese (Português)',
+  'ro_RO' => 'Romanian (Româneşte)',
+  'ru_RU' => 'Russian (Русский)',
+  'sr_CS' => 'Serbian (Српски)',
+  'si_LK' => 'Sinhalese (සිංහල)',
+  'sk_SK' => 'Slovak (Slovenčina)',
+  'sl_SI' => 'Slovenian (Slovenščina)',
+  'es_AR' => 'Spanish (Argentina)',
+  'es_ES' => 'Spanish (Español)',
   'sv_SE' => 'Swedish (Svenska)',
-  'th_TH' => 'Thai',
-  'tr_TR' => 'Türkçe',
-  'uk_UA' => 'Ukrainian',
-  'vi_VN' => 'Vietnamese',
+  'th_TH' => 'Thai (ไทย)',
+  'tr_TR' => 'Turkish (Türkçe)',
+  'uk_UA' => 'Ukrainian (Українська)',
+  'vi_VN' => 'Vietnamese (Tiếng Việt)',
+  'cy_GB' => 'Welsh (Cymraeg)',
 );
 
 $rcube_language_aliases = array(
index ab69f38a50b9f71b8f13b9021a2ced43ac6b459f..bff322d3b3cc450cb47a642b2c33ccdbed8c9f44 100644 (file)
@@ -14,7 +14,7 @@
 |         Yusef Maali <contact@yusefmaali.net>                          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2900 2009-09-01 11:47:46Z yllar $
+@version $Id: labels.inc 3025 2009-10-07 10:05:48Z alec $
 
 */
 
@@ -168,7 +168,7 @@ $labels['addbcc'] = 'Aggiungi Bcc';
 $labels['addreplyto'] = 'Aggiungi Rispondi a';
 $labels['mdnrequest'] = 'Il mittente ha richiesto di ricevere una notifica dell\'avvenuta lettura del messaggio. Si desidera inviare tale notifica?';
 $labels['receiptread'] = 'Ricevuta di ritorno (letto)';
-$labels['yourmessage'] = 'Questa è la ricevuta di ritorno del mesaggio inviato';
+$labels['yourmessage'] = 'Questa è la ricevuta di ritorno del messaggio inviato';
 $labels['receiptnote'] = 'Nota: questa Ricevuta di ritorno attesta solamente che il messaggio è stato visualizzato nel computer del destinatario. Non c\'è pertanto alcuna garanzia che il destinatario abbia letto o compreso il suo contenuto.';
 $labels['name'] = 'Nome visualizzato';
 $labels['firstname'] = 'Nome';
index d4ef97f77c649e8af1059f945b3bfb91f5b2e089..9c99124fd7cf1508aece9760151f684e2abe5f61 100644 (file)
@@ -14,7 +14,7 @@
 |         Takashi Takamatsu <taka717@gmail.com>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2653 2009-06-18 20:42:48Z yllar $
+@version $Id: labels.inc 2953 2009-09-13 16:42:56Z yllar $
 
 */
 
@@ -34,8 +34,8 @@ $labels['sent'] = '送信済みアイテム';
 $labels['trash'] = 'ごみ箱';
 $labels['junk'] = '迷惑メール';
 $labels['subject'] = '件名';
-$labels['from'] = '送信者';
-$labels['to'] = 'å\8f\97ä¿¡è\80\85';
+$labels['from'] = '差出人';
+$labels['to'] = 'å®\9bå\85\88';
 $labels['cc'] = 'コピー';
 $labels['bcc'] = 'Bcc';
 $labels['replyto'] = '返信先';
@@ -53,7 +53,7 @@ $labels['filename'] = 'ファイル名';
 $labels['filesize'] = 'ファイルサイズ';
 $labels['preferhtml'] = 'HTMLを表示';
 $labels['htmlmessage'] = 'HTMLメール';
-$labels['prettydate'] = 'ç°¡æ\98\93ã\81ª日付表示';
+$labels['prettydate'] = 'ç\9f­ã\81\84日付表示';
 $labels['addtoaddressbook'] = 'アドレス帳に追加';
 $labels['sun'] = '日';
 $labels['mon'] = '月';
@@ -97,7 +97,7 @@ $labels['today'] = '今日';
 $labels['checkmail'] = '新着の確認';
 $labels['writenewmessage'] = '新規メールの作成';
 $labels['replytomessage'] = '返信';
-$labels['replytoallmessage'] = '送信者とすべての受信者に返信';
+$labels['replytoallmessage'] = '差出人とすべての宛先に返信';
 $labels['forwardmessage'] = '転送';
 $labels['deletemessage'] = '削除';
 $labels['movemessagetotrash'] = 'ごみ箱に移動';
@@ -169,7 +169,7 @@ $labels['maxuploadsize'] = '添付可能ファイルサイズ : $size';
 $labels['addcc'] = 'Cc 追加';
 $labels['addbcc'] = 'Bcc 追加';
 $labels['addreplyto'] = 'Reply-To 追加';
-$labels['mdnrequest'] = 'メールの送信者は開封確認の送付を求めています。開封確認のメールを送付しますか?';
+$labels['mdnrequest'] = 'メールの差出人は開封確認の送付を求めています。開封確認のメールを送付しますか?';
 $labels['receiptread'] = '開封確認 (表示済)';
 $labels['yourmessage'] = 'これはあなたが送信したメールに対する開封確認です。';
 $labels['receiptnote'] = '注意: この開封確認はメールが受信者に表示されたことの通知です。受信者がメールを読んだこと、内容を理解したことを保証するものではありません。';
@@ -227,7 +227,7 @@ $labels['logoutcompact'] = 'ログアウト時にフォルダのコンパクト
 $labels['uisettings'] = 'ユーザーインターフェース';
 $labels['serversettings'] = 'サーバの設定';
 $labels['mailboxview'] = '受信箱';
-$labels['mdnrequests'] = '送信者への通知';
+$labels['mdnrequests'] = '差出人への通知';
 $labels['askuser'] = 'ユーザーに確認する';
 $labels['autosend'] = '自動的に送信する';
 $labels['ignore'] = '無視する';
@@ -251,6 +251,12 @@ $labels['2047folding'] = 'RFC 2047 準拠 (other)';
 $labels['advancedoptions'] = '高度な設定';
 $labels['focusonnewmessage'] = '新着メールが届いたらブラウザにフォーカスを移す';
 $labels['checkallfolders'] = 'すべてのフォルダで新着メールを確認する';
+$labels['displaynext'] = 'メールを削除・移動したら、次のメールを表示する';
+$labels['mainoptions'] = '基本設定';
+$labels['section'] = '設定項目';
+$labels['maintenance'] = 'メンテナンス設定';
+$labels['newmessage'] = '新着メール設定';
+$labels['listoptions'] = '一覧設定';
 $labels['folder'] = 'フォルダ';
 $labels['folders'] = 'フォルダ一覧';
 $labels['foldername'] = 'フォルダ名';
index 39344b53574cf9ccd66e154d061fcb95a320fbd2..4697ce5c02ac63fd0089ec06572272aa5b6e0a66 100644 (file)
@@ -14,7 +14,7 @@
 |         Takashi Takamatsu <taka717@gmail.com>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2653 2009-06-18 20:42:48Z yllar $
+@version $Id: messages.inc 2953 2009-09-13 16:42:56Z yllar $
 
 */
 
@@ -24,6 +24,7 @@ $messages['cookiesdisabled'] = 'ブラウザで Cookie が無効に設定され
 $messages['sessionerror'] = 'セッションが正しくないか期限切れです。';
 $messages['imaperror'] = 'IMAP サーバへの接続に失敗しました。';
 $messages['servererror'] = 'サーバエラーが発生しました。';
+$messages['invalidrequest'] = '不正なリクエストです! 保存されませんでした。';
 $messages['nomessagesfound'] = 'メールはありません。';
 $messages['loggedout'] = 'ログアウトしました。';
 $messages['mailboxempty'] = 'メールボックスは空です。';
@@ -60,8 +61,8 @@ $messages['formincomplete'] = 'フォームの項目が完全に入力されて
 $messages['noemailwarning'] = '有効なメールアドレスを入力して下さい。';
 $messages['nonamewarning'] = '名前を入力して下さい。';
 $messages['nopagesizewarning'] = 'ページのサイズを入力して下さい。';
-$messages['nosenderwarning'] = '送信者のメールアドレスを入力してください。';
-$messages['norecipientwarning'] = 'å\8f\97ä¿¡è\80\85を最低 1 人は入力して下さい。';
+$messages['nosenderwarning'] = '差出人のメールアドレスを入力してください。';
+$messages['norecipientwarning'] = 'å®\9bå\85\88を最低 1 人は入力して下さい。';
 $messages['nosubjectwarning'] = '件名が空です。今すぐ入力しますか?';
 $messages['nobodywarning'] = '本文が無いメールを送信しますか?';
 $messages['notsentwarning'] = 'メールは送信されませんでした。破棄しますか?';
@@ -98,5 +99,11 @@ $messages['opnotpermitted'] = 'その操作は許可されていません。';
 $messages['nofromaddress'] = '選択中の個人情報にメールアドレスが含まれていません。';
 $messages['editorwarning'] = 'テキストエディタに切り替えるとすべての書式が失われます。よろしいですか?';
 $messages['httpreceivedencrypterror'] = '致命的な設定エラーが発生しました。<b>メッセージは送信されませんでした。</b>システム管理者に至急連絡してください。';
+$messages['smtpconnerror'] = 'SMTP Error ($code): サーバーへの接続に失敗しました';
+$messages['smtpautherror'] = 'SMTP Error ($code): 認証に失敗しました';
+$messages['smtpfromerror'] = 'SMTP Error ($code): 差出人 "$from" を設定できませんでした';
+$messages['smtptoerror'] = 'SMTP Error ($code): 宛先 "$to" を追加できませんでした';
+$messages['smtprecipientserror'] = 'SMTP Error: 宛先のリストを解析できませんでした';
+$messages['smtperror'] = 'SMTP Error: $msg';
 
 ?>
index 5a000f674fbbbd601e15b85b416f446b2d6653df..12ce531ded943cc43731e82ec90028e27c530b0e 100755 (executable)
@@ -9,10 +9,10 @@
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Zaza Zviadadze <zviadadze@gmail.com>                          |
+| Author: Zaza Zviadadze                                                                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 842 2009-03-16 01:00:02Z  zaza$
+@version $Id: labels.inc 842 2009-10-03 19:00:00  zaza$
 
 */
 
@@ -115,12 +115,15 @@ $labels['markread'] = 'როგორც წაკითხული';
 $labels['markunread'] = 'როგორც წაუკითხავი';
 $labels['markflagged'] = 'როგორც მონიშნული';
 $labels['markunflagged'] = 'როგორც მოუნიშნავი';
+$labels['messageactions'] = 'მეტი ფუნქციები';
 $labels['select'] = 'მონიშვნა';
 $labels['all'] = 'ყველა';
 $labels['none'] = 'არცერთი';
 $labels['unread'] = 'წაუკითხავი';
 $labels['flagged'] = 'მონიშნული';
 $labels['unanswered'] = 'უპასუხო';
+$labels['deleted'] = 'წაშლილი';
+$labels['invert'] = 'შებრუნებული';
 $labels['filter'] = 'ფილტრი';
 $labels['compact'] = 'შეკუმშვა';
 $labels['empty'] = 'გაცარიელება';
@@ -130,8 +133,12 @@ $labels['unknown'] = 'უცნობი';
 $labels['unlimited'] = 'შეუზღუდავი';
 $labels['quicksearch'] = 'სწრაფი ძიება';
 $labels['resetsearch'] = 'ძიების გასუფთავება';
+$labels['searchmod'] = 'ძებნის ვარიანტები';
+$labels['msgtext'] = 'ყველა შეტყობინება';
 $labels['openinextwin'] = 'გახსნა ახალ ფანჯარაში';
+$labels['emlsave'] = 'გადმოწერა (.eml)';
 $labels['compose'] = 'შეტყობინების დაწერა';
+$labels['editasnew'] = 'რედაქტირება როგორც ახლის';
 $labels['savemessage'] = 'დროებით შენახვა';
 $labels['sendmessage'] = 'შეტყობინების გაგზავნა';
 $labels['addattachment'] = 'ფაილის ატვირთვა';
@@ -242,6 +249,13 @@ $labels['2047folding'] = 'Full RFC 2047 (other)';
 $labels['advancedoptions'] = 'დამატებითი პარამეტრები';
 $labels['focusonnewmessage'] = 'ფოკუსირება ახალ შეტყობინებებზე';
 $labels['checkallfolders'] = 'შეამოწმე ყველა საქაღალდე ახალ შეტყობინებაზე';
+$labels['displaynext'] = 'შეტყობინების წაშლის ან გადატანის შემდეგ გამოჩნდეს შემდეგი შეტყობინება';
+$labels['indexsort'] = 'თარიღით დალაგებისთვის გამოიყენე შეტყობინების ინდექსი';
+$labels['mainoptions'] = 'ძირითადი პარამეტრები';
+$labels['section'] = 'განყოფილება';
+$labels['maintenance'] = 'მომსახურება';
+$labels['newmessage'] = 'ახალი შეტყობინება';
+$labels['listoptions'] = 'პარამეტრების ჩამონათვალი';
 $labels['folder'] = 'საქაღალდე';
 $labels['folders'] = 'საქაღალდეები';
 $labels['foldername'] = 'საქაღალდის დასახელება';
index 81b4bce6205312ca742eeb20b7bb33c11fc4a913..d7a5b390b36eecb304c2732e786b44bf8db242bd 100755 (executable)
@@ -9,10 +9,10 @@
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Zaza Zviadadze <zviadadze@gmail.com>                          |
+| Author: Zaza Zviadadze                                                |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 842 2009-03-16 01:00:02Z  zaza$
+@version $Id: messages.inc 842 2009-10-03 19:30:00  zaza$
 
 */
 
@@ -21,10 +21,13 @@ $messages['loginfailed'] = 'შესვლა შეუძლებელია
 $messages['cookiesdisabled'] = 'თქვენი ბროუზერი კუკიებს არ პასუხობს';
 $messages['sessionerror'] = 'თქვენი სესია არის მცდარი ან ვადაგასული';
 $messages['imaperror'] = 'IMAP სერვერთან დაკავშირება შეუძლებელია';
+$messages['servererror'] = 'შეცდომა სერვერზე!';
+$messages['invalidrequest'] = 'არასწორი მოთხოვნა! მონაცემების შენახვა არ მოხერხდა.';
 $messages['nomessagesfound'] = 'არ არის ახალი შეტყობინება';
 $messages['loggedout'] = 'წარმატებით დაიხურა თქვენი სესია';
 $messages['mailboxempty'] = 'საფოსტო ყუთი ცარიელია';
 $messages['loading'] = 'იტვირთება...';
+$messages['uploading'] = 'ფაილი იტვირთება...';
 $messages['loadingdata'] = 'მონაცემების ჩატვირთვა...';
 $messages['checkingmail'] = 'ახალი შეტყობინების ნახვა';
 $messages['sendingmessage'] = 'შეტყობინების გაგზავნა';
@@ -44,14 +47,15 @@ $messages['errorsavingsent'] = 'შეცდომა სანამ ინა
 $messages['errorsaving'] = 'შენახვის დროს მოხდა შეცდომა';
 $messages['errormoving'] = 'შეტყობინების გადატანა შეუძლებელია';
 $messages['errordeleting'] = 'შეტყობინების წაშლა შეუძლებელია';
+$messages['errormarking'] = 'შეტყობინების მონიშვნა შეუძლებელია';
 $messages['deletecontactconfirm'] = 'ნამდვილად გსურთ მონიშნული კონტაქტების წაშლა?';
 $messages['deletemessagesconfirm'] = 'ნამდვილად გსურთ მონიშნული შეტყობინებების წაშლა?';
 $messages['deletefolderconfirm'] = 'ნამდვილად გსურთ ამ საქაღალდის წაშლა?';
 $messages['purgefolderconfirm'] = 'ნამდვილად გსურთ ყველა შეტყობინების წაშლა აღნიშნულ საქაღალდეში?';
-$messages['foldercreating'] = 'საქაღალდის შექმნა';
-$messages['folderdeleting'] = 'საქაღალდის წაშლა';
-$messages['folderrenaming'] = 'საქაღალდის სახელის შეცვლა';
-$messages['foldermoving'] = 'საქაღალდის გადატანა';
+$messages['foldercreating'] = 'საქაღალდის შექმნა...';
+$messages['folderdeleting'] = 'საქაღალდის წაშლა...';
+$messages['folderrenaming'] = 'საქაღალდის სახელის შეცვლა...';
+$messages['foldermoving'] = 'საქაღალდის გადატანა...';
 $messages['formincomplete'] = 'ყველა ველი არ არის შევსებული';
 $messages['noemailwarning'] = 'მიუთითეთ სწორი ელ–ფოსტის მისამართი';
 $messages['nonamewarning'] = 'მიუთითეთ სახელი';
@@ -64,6 +68,7 @@ $messages['notsentwarning'] = 'შეტყობინება ვერ ი
 $messages['noldapserver'] = 'მიუთითეთ LDAP სერვერი ძიებისთვის';
 $messages['nocontactsreturned'] = 'კონტაქტები ვერ მოძებნა';
 $messages['nosearchname'] = 'მიუთითეთ სახელი ან ელ–ფოსტის მისამართი';
+$messages['notuploadedwarning'] = 'ჯერ არ ატვირთულა ყველა მიმაგრებული ფაილი. დაელოდეთ ან გააუქმეთ ატვირთვა.';
 $messages['searchsuccessful'] = '$nr შეტყობინეა მოიძებნა';
 $messages['searchnomatch'] = 'შეტყობინება ვერ მოიძებნა';
 $messages['searching'] = 'ძიება...';
@@ -93,5 +98,12 @@ $messages['importconfirm'] = '<b>წარმატებით დასრუ
 $messages['opnotpermitted'] = 'ოპერაცია შეზღუდულია';
 $messages['nofromaddress'] = 'ელ–ფოსტის მისამართი გამოტოვებულია';
 $messages['editorwarning'] = 'რედაქტორის გადართვა ტექსტურ რეჟიმში გამოიწვევს არსებული ტექსტის ფორმატის დაკარგვას. გსურთ გაგრძელება?';
+$messages['httpreceivedencrypterror'] = 'სერვერზე მოხდა შეცდომა. დაუყონებლივ დაუკავშირდით ადმინისტრატორს. <b>თქვენი შეტყობინება შესაძლოა ვერ გაიგზავნა.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): სერვერთან დაკავშირება ვერ მოხერხდა';
+$messages['smtpautherror'] = 'SMTP Error ($code): ავტორიზაციის შეცდომა';
+$messages['smtpfromerror'] = 'SMTP Error ($code): ვერ მიეთითა გამგზავნი "$from"';
+$messages['smtptoerror'] = 'SMTP Error ($code): ვერ დაემატა მიმღები "$to"';
+$messages['smtprecipientserror'] = 'SMTP Error: მიმღებთა ჩამონათვალის დამუშავება ვერ მოხერხდა';
+$messages['smtperror'] = 'SMTP Error: $msg';
 
 ?>
index 48cce87eb90899fd6922feb29536dc1c28384db4..66b9659cdcc15626140eaf9bb0e9c5b3d3f4661c 100644 (file)
@@ -16,7 +16,7 @@
 |         Frits Letteboer <f.letteboer@radiotwenterand.nl>              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2914 2009-09-04 10:51:09Z robin $
+@version $Id: labels.inc 3029 2009-10-09 11:46:23Z alec $
 
 */
 
@@ -28,7 +28,7 @@ $labels['server'] = 'Server';
 $labels['login'] = 'Inloggen';
 $labels['logout'] = 'Uitloggen';
 $labels['mail'] = 'E-Mail';
-$labels['settings'] = 'Persoonlijke Instellingen';
+$labels['settings'] = 'Instellingen';
 $labels['addressbook'] = 'Adresboek';
 $labels['inbox'] = 'Postvak IN';
 $labels['drafts'] = 'Concepten';
index 9f98d206a8d079eab2f903b3760b8337c7d043b4..886cc730c9f75c36db4ec26677568a7109168a18 100644 (file)
@@ -241,6 +241,7 @@ $labels['readwhendeleted'] = 'Podczas usuwania oznacz wiadomość jako przeczyta
 $labels['flagfordeletion'] = 'Oznacz wiadomość do usunięcia zamiast ją usuwać';
 $labels['skipdeleted'] = 'Ukryj wiadomości oznaczone do usunięcia';
 $labels['autosavedraft'] = 'Automatyczny zapis tworzonej wiadomości';
+$labels['indexsort'] = 'Stosuj indeks wiadomości do sortowania wg daty';
 $labels['keepalive']  = 'Sprawdzaj czy nadeszły nowe wiadomości';
 $labels['everynminutes']  = 'co $n minut(y)';
 $labels['never'] = 'nigdy';
index 0c0168f6d9c9e4448d5c2fb9e027c9dfdc6a1848..1fc76598292b0187344158e98509ddeedfedbbe1 100644 (file)
@@ -32,6 +32,7 @@ $messages['nomessagesfound'] = 'Brak wiadomości w skrzynce.';
 $messages['loggedout'] = 'Użytkownik wylogował się poprawnie.';
 $messages['mailboxempty'] = 'Skrzynka jest pusta!';
 $messages['loading'] = 'Ładowanie...';
+$messages['uploading'] = 'Zapisywanie pliku...';
 $messages['loadingdata'] = 'Ładowanie danych...';
 $messages['checkingmail'] = 'Sprawdzanie nowych wiadomości...';
 $messages['sendingmessage'] = 'Wysyłanie wiadomości...';
@@ -109,5 +110,6 @@ $messages['smtptoerror'] = 'Błąd SMTP ($code): Nie można dodać odbiorcy "$to
 $messages['smtprecipientserror'] = 'Błąd SMTP: Parsowanie listy odbiorców nie powiodło się';
 $messages['smtperror'] = 'Błąd SMTP: $msg';
 $messages['invalidrequest'] = 'Błędne żądanie! Nie zapisano danych.';
+$messages['emailformaterror'] = 'Błędny adres e-mail: $email';
 
 ?>
index 9d6873d71bbf5bde79ad6f08de2023baa025769d..81501027f5f3bec8fc92e42b9a175e520e3b2134 100644 (file)
@@ -17,7 +17,7 @@
 |         Victor Benincasa <vbenincasa@gmail.com>                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
+@version $Id: labels.inc 3061 2009-10-26 21:42:58Z yllar $
 
 */
 
@@ -255,6 +255,7 @@ $labels['advancedoptions'] = 'Opções avançadas';
 $labels['focusonnewmessage'] = 'Focar janela do navegador na nova mensagem';
 $labels['checkallfolders'] = 'Verificar se há novas mensagens em todas as pastas';
 $labels['displaynext'] = 'Exibir a mensagem seguinte após apagar/mover uma mensagem';
+$labels['indexsort'] = 'Utilize o índice de mensagens para ordenar por data';
 $labels['mainoptions'] = 'Opções Principais';
 $labels['section'] = 'Seção';
 $labels['maintenance'] = 'Manutenção';
index b17e6ccff73a6fb1a2d49c17d02a4d28bf979c90..be835effe098faa3a613036d376332ac10608cff 100644 (file)
@@ -17,7 +17,7 @@
 |         Victor Benincasa <vbenincasa@gmail.com>                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2799 2009-07-26 11:42:46Z yllar $
+@version $Id: messages.inc 3061 2009-10-26 21:42:58Z yllar $
 
 */
 
@@ -32,6 +32,7 @@ $messages['nomessagesfound'] = 'Nenhuma mensagem foi encontrada';
 $messages['loggedout'] = 'Sua sessão foi finalizada com sucesso. Até breve!';
 $messages['mailboxempty'] = 'A caixa de mensagens está vazia';
 $messages['loading'] = 'Carregando...';
+$messages['uploading'] = 'Enviando anexo...';
 $messages['loadingdata'] = 'Carregando informações...';
 $messages['checkingmail'] = 'Verificando se há novas mensagens...';
 $messages['sendingmessage'] = 'Enviando mensagem...';
@@ -72,6 +73,7 @@ $messages['notsentwarning'] = 'A mensagem não foi enviada, deseja excluí-la?';
 $messages['noldapserver'] = 'Por favor, selecione um servidor LDAP para a pesquisa';
 $messages['nocontactsreturned'] = 'Nenhum contato foi encontrado';
 $messages['nosearchname'] = 'Por favor, informe o nome do contado ou seu endereço de e-mail';
+$messages['notuploadedwarning'] = 'Há anexos ainda não enviados. Aguarde ou cancele o envio.';
 $messages['searchsuccessful'] = '$nr mensagens encontradas';
 $messages['searchnomatch'] = 'A pesquisa não encontrou resultados';
 $messages['searching'] = 'Pesquisando...';
@@ -108,5 +110,6 @@ $messages['smtpfromerror'] = 'Erro SMTP ($code): Falha ao definir o remetente "$
 $messages['smtptoerror'] = 'Erro SMTP ($code): Falha ao adicionar o destinatário "$to"';
 $messages['smtprecipientserror'] = 'Erro SMTP: Não é possível analisar a lista destinatários';
 $messages['smtperror'] = 'Erro SMTP: $msg';
+$messages['emailformaterror'] = 'Endereço de Email incorreto: $email';
 
 ?>
index 66d2baa59eb51b9f48d48f4f330520c062a6683e..ddf5df35c1543431175a938304de95a8bf1fabf8 100644 (file)
 |          João Vale <jpvale@gmail.com>                                 |
 |          Fernando Silva <fernando.silva@openquest.pt>                 |
 |          Nuno Costa <nuno@criacaoweb.net>                             |
+|          Teotónio Ricardo <teotonio.ricardo@webtuga.pt>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
+@version $Id: labels.inc 3019 2009-10-05 19:10:11Z yllar $
 
 */
 
@@ -119,12 +120,15 @@ $labels['markread'] = 'Como lidas';
 $labels['markunread'] = 'Como não lidas';
 $labels['markflagged'] = 'Com sinalização';
 $labels['markunflagged'] = 'Sem sinalização';
+$labels['messageactions'] = 'Mais acções...';
 $labels['select'] = 'Seleccionar';
 $labels['all'] = 'Todas';
 $labels['none'] = 'Nenhuma';
 $labels['unread'] = 'Não lidas';
 $labels['flagged'] = 'Sinalizadas';
 $labels['unanswered'] = 'Não respondidas';
+$labels['deleted'] = 'Eliminado';
+$labels['invert'] = 'Inverter';
 $labels['filter'] = 'Filtro';
 $labels['compact'] = 'Compactar';
 $labels['empty'] = 'Vazio';
@@ -134,8 +138,12 @@ $labels['unknown'] = 'desconhecido';
 $labels['unlimited'] = 'ilimitado';
 $labels['quicksearch'] = 'Pesquisa rápida';
 $labels['resetsearch'] = 'Limpar pesquisa';
+$labels['searchmod'] = 'Modificadores de Pesquisa';
+$labels['msgtext'] = 'Mensagem completa';
 $labels['openinextwin'] = 'Abrir numa nova janela';
+$labels['emlsave'] = 'Descarregar (.eml)';
 $labels['compose'] = 'Escrever mensagem';
+$labels['editasnew'] = 'Editar como novo';
 $labels['savemessage'] = 'Salvar rascunho';
 $labels['sendmessage'] = 'Enviar';
 $labels['addattachment'] = 'Anexar';
@@ -246,6 +254,13 @@ $labels['2047folding'] = 'Total RFC 2047 (outro)';
 $labels['advancedoptions'] = 'Opções avançadas';
 $labels['focusonnewmessage'] = 'Focar janela de navegador na nova mensagem';
 $labels['checkallfolders'] = 'Verificar todas as pastas para novas mensagens';
+$labels['displaynext'] = 'Depois de mover/eliminar uma mensagem, mostrar a próxima mensagem';
+$labels['indexsort'] = 'Utilize o índice de mensagens para ordenar por data';
+$labels['mainoptions'] = 'Opções';
+$labels['section'] = 'Secção';
+$labels['maintenance'] = 'Manutenção';
+$labels['newmessage'] = 'Nova Mensagem';
+$labels['listoptions'] = 'Listar opções';
 $labels['folder'] = 'Pasta';
 $labels['folders'] = 'Pastas';
 $labels['foldername'] = 'Nome da pasta';
index 5faacc81187c057322a7196f6ebc8d96aa1aa558..8b335a294fbfe0031be84e43050a94477db288e1 100644 (file)
@@ -15,7 +15,7 @@
 |         Nuno Costa <nuno@criacaoweb.net>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2953 2009-09-13 16:42:56Z yllar $
 
 */
 
@@ -24,6 +24,8 @@ $messages['loginfailed'] = 'Erro ao entrar';
 $messages['cookiesdisabled'] = 'O seu navegador não suporta cookies';
 $messages['sessionerror'] = 'A sessão do seu navegador é inválida ou expirou';
 $messages['imaperror'] = 'A ligação ao servidor IMAP falhou';
+$messages['servererror'] = 'Erro do Servidor!';
+$messages['invalidrequest'] = 'Pedido inválido! Nenhuma informação foi salva.';
 $messages['nomessagesfound'] = 'Nenhuma mensagem encontrada na caixa de entrada';
 $messages['loggedout'] = 'A sua sessão foi finalizada com sucesso. Até breve!';
 $messages['mailboxempty'] = 'A caixa de entrada está vazia';
@@ -47,6 +49,7 @@ $messages['errorsavingsent'] = 'Ocorreu um erro ao salvar mensagem enviada';
 $messages['errorsaving'] = 'Ocorreu um erro a gravar';
 $messages['errormoving'] = 'Não foi possível mover a mensagem';
 $messages['errordeleting'] = 'Não foi possível apagar a mensagem';
+$messages['errormarking'] = 'Não foi possível marcar a mensagem.';
 $messages['deletecontactconfirm'] = 'Deseja realmente apagar o(s) contacto(s) selecionado(s)?';
 $messages['deletemessagesconfirm'] = 'Deseja realmente apagar a(s) mensagem(ns) selecionada(s)?';
 $messages['deletefolderconfirm'] = 'Deseja realmente apagar esta pasta?';
@@ -96,5 +99,12 @@ $messages['importconfirm'] = '<b>$inserted contactos importados com sucesso, $sk
 $messages['opnotpermitted'] = 'Operação não permitida';
 $messages['nofromaddress'] = 'Falta endereço de email na identidade selecionada';
 $messages['editorwarning'] = 'Ao mudar para o editor plain text vai perder toda a formação de texto. Deseja continuar?';
+$messages['httpreceivedencrypterror'] = 'Ocorreu um erro fatal de configuração. Contacte o seu administrador imediatamente. <b>A sua mensagem não pôde ser enviada.</b>';
+$messages['smtpconnerror'] = 'Erro SMTP ($code): Ligação ao servidor falhou';
+$messages['smtpautherror'] = 'Erro SMTP ($code): Autenticação falhou';
+$messages['smtpfromerror'] = 'Erro SMTP ($code): Falhou a definir remetente "$from"';
+$messages['smtptoerror'] = 'Erro SMTP ($code): Falhou ao adicionar destinatário: "$to"';
+$messages['smtprecipientserror'] = 'Erro SMTP: Impossível analisar lista de destinatários';
+$messages['smtperror'] = 'Erro SMTP: $msg';
 
 ?>
index 40d0fe2ff2b0e43458d5969944459eace44c4ef4..eeb4d429e4f03a7375085f633b47e656849e5cda 100644 (file)
 +-----------------------------------------------------------------------+
 | Author: Daniel Anechitoaie - danieLs <daniels@safereaction.ro>        |
 |         Zeno Popovici <zeno.popovici at ulbsibiu.ro>                  |
+|         Cristian Nastase <cristian.nastase@itcaffe.net>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
+@version $Id: labels.inc 2994 2009-09-27 14:16:33Z yllar $
 
 */
 
 $labels = array();
-$labels['welcome'] = 'Bine ati venit la $product';
+$labels['welcome'] = 'Bine aţi venit la $product';
 $labels['username'] = 'Utilizator';
-$labels['password'] = 'Parola';
+$labels['password'] = 'Parolă';
 $labels['server'] = 'Server';
 $labels['login'] = 'Autentificare';
 $labels['logout'] = 'Deconectare';
 $labels['mail'] = 'E-Mail';
-$labels['settings'] = 'Setari Personale';
-$labels['addressbook'] = 'Agenda';
+$labels['settings'] = 'Setări Personale';
+$labels['addressbook'] = 'Agendă';
 $labels['inbox'] = 'Primite';
 $labels['drafts'] = 'Ciorne';
 $labels['sent'] = 'Trimise';
@@ -35,39 +36,39 @@ $labels['junk'] = 'Spam';
 $labels['subject'] = 'Subiect';
 $labels['from'] = 'Expeditor';
 $labels['to'] = 'Destinatar';
-$labels['cc'] = 'Copie';
-$labels['bcc'] = 'Bcc';
-$labels['replyto'] = 'Raspunde-La';
+$labels['cc'] = 'Copie (CC)';
+$labels['bcc'] = 'Copie oarbă (BCC)';
+$labels['replyto'] = 'Răspunde-La';
 $labels['date'] = 'Data';
-$labels['size'] = 'Marime';
+$labels['size'] = 'Mărime';
 $labels['priority'] = 'Prioritate';
-$labels['organization'] = 'Organizatie';
-$labels['reply-to'] = 'Raspunde-La';
+$labels['organization'] = 'Organizaţie';
+$labels['reply-to'] = 'Răspunde-La';
 $labels['mailboxlist'] = 'Dosare';
-$labels['messagesfromto'] = 'Mesaje de la $from pana la $to din $count';
+$labels['messagesfromto'] = 'Mesaje de la $from până la $to din $count';
 $labels['messagenrof'] = '$nr mesaje din $count';
-$labels['moveto'] = 'muta in...';
-$labels['download'] = 'descarca';
-$labels['filename'] = 'Nume fisier';
-$labels['filesize'] = 'Marime fisier';
-$labels['preferhtml'] = 'Prefer HTML';
+$labels['moveto'] = 'Mută in...';
+$labels['download'] = 'Descarcă';
+$labels['filename'] = 'Nume fişier';
+$labels['filesize'] = 'Mărime fişier';
+$labels['preferhtml'] = 'Format HTML';
 $labels['htmlmessage'] = 'Mesaj HTML';
-$labels['prettydate'] = 'Data formatata';
-$labels['addtoaddressbook'] = 'Adauga in agenda';
+$labels['prettydate'] = 'Dată formatată';
+$labels['addtoaddressbook'] = 'Adaugă în agendă';
 $labels['sun'] = 'Dum';
 $labels['mon'] = 'Lun';
 $labels['tue'] = 'Mar';
 $labels['wed'] = 'Mie';
 $labels['thu'] = 'Joi';
 $labels['fri'] = 'Vin';
-$labels['sat'] = 'Sam';
-$labels['sunday'] = 'Duminica';
+$labels['sat'] = 'Sâm';
+$labels['sunday'] = 'Duminică';
 $labels['monday'] = 'Luni';
-$labels['tuesday'] = 'Marti';
+$labels['tuesday'] = 'Marţi';
 $labels['wednesday'] = 'Miercuri';
 $labels['thursday'] = 'Joi';
 $labels['friday'] = 'Vineri';
-$labels['saturday'] = 'Sambata';
+$labels['saturday'] = 'Sâmbătă';
 $labels['jan'] = 'Ian';
 $labels['feb'] = 'Feb';
 $labels['mar'] = 'Mar';
@@ -92,175 +93,188 @@ $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';
-$labels['replytomessage'] = 'Raspunde la mesaj';
-$labels['replytoallmessage'] = 'Raspunde la toti';
+$labels['today'] = 'Astăzi';
+$labels['checkmail'] = 'Verifică mesaje noi';
+$labels['writenewmessage'] = 'Scrie mesaj nou';
+$labels['replytomessage'] = 'Răspunde la mesaj';
+$labels['replytoallmessage'] = 'Răspunde la toţi';
 $labels['forwardmessage'] = 'Trimite mesajul mai departe';
 $labels['deletemessage'] = 'Trimite mesajul la gunoi';
-$labels['movemessagetotrash'] = 'Muta mesajul la gunoi';
-$labels['printmessage'] = 'Listeaza mesajul';
-$labels['previousmessage'] = 'Afiseaza mesajul anterior';
-$labels['previousmessages'] = 'Afiseaza setul anterior de mesaje';
-$labels['firstmessage'] = 'Afiseaza primul mesaj';
-$labels['firstmessages'] = 'Afiseaza primul set de mesaje';
-$labels['nextmessage'] = 'Afiseaza urmatorul mesaj';
-$labels['nextmessages'] = 'Afiseaza setul urmator de mesaje';
-$labels['lastmessage'] = 'Afiseaza ultimul mesaj';
-$labels['lastmessages'] = 'Afiseaza ultimul set de mesaje';
-$labels['backtolist'] = 'Inapoi la lista cu mesaje';
-$labels['viewsource'] = 'Afiseaza sursa';
-$labels['markmessages'] = 'Marcheaza mesajele';
+$labels['movemessagetotrash'] = 'Mută mesajul la gunoi';
+$labels['printmessage'] = 'Listează mesajul';
+$labels['previousmessage'] = 'Afişează mesajul anterior';
+$labels['previousmessages'] = 'Afişează setul anterior de mesaje';
+$labels['firstmessage'] = 'Afişează primul mesaj';
+$labels['firstmessages'] = 'Afişează primul set de mesaje';
+$labels['nextmessage'] = 'Afişează următorul mesaj';
+$labels['nextmessages'] = 'Afişează setul următor de mesaje';
+$labels['lastmessage'] = 'Afişează ultimul mesaj';
+$labels['lastmessages'] = 'Afişează ultimul set de mesaje';
+$labels['backtolist'] = 'Înapoi la lista cu mesaje';
+$labels['viewsource'] = 'Afişează sursa';
+$labels['markmessages'] = 'Marchează mesajele';
 $labels['markread'] = 'Ca citit';
 $labels['markunread'] = 'Ca necitit';
 $labels['markflagged'] = 'Ca marcat';
 $labels['markunflagged'] = 'Ca nemarcat';
-$labels['select'] = 'Selecteaza';
+$labels['messageactions'] = 'Mai multe acţiuni...';
+$labels['select'] = 'Selectează';
 $labels['all'] = 'Toate';
 $labels['none'] = 'Nici unul';
 $labels['unread'] = 'Necitite';
 $labels['flagged'] = 'Marcat';
-$labels['unanswered'] = 'Neraspuns';
+$labels['unanswered'] = 'Fără răspuns';
+$labels['deleted'] = 'Şterse';
+$labels['invert'] = 'Inversează';
 $labels['filter'] = 'Filtru';
-$labels['compact'] = 'Compreseaza';
-$labels['empty'] = 'Goleste';
-$labels['purge'] = 'Curata';
-$labels['quota'] = 'Spatiu folosit';
+$labels['compact'] = 'Compactează';
+$labels['empty'] = 'Goleşte';
+$labels['purge'] = 'Curăţă';
+$labels['quota'] = 'Spaţiu folosit';
 $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['quicksearch'] = 'Căutare rapidă';
+$labels['resetsearch'] = 'Resetare căutare';
+$labels['searchmod'] = 'Parametrii de căutare';
+$labels['msgtext'] = 'Tot mesajul';
+$labels['openinextwin'] = 'Deschide într-o fereastră nouă';
+$labels['emlsave'] = 'Salvează în format .eml';
+$labels['compose'] = 'Scrie un mesaj';
+$labels['editasnew'] = 'Editeză ca nou';
+$labels['savemessage'] = 'Salvează această ciornă';
 $labels['sendmessage'] = 'Trimite mesaj';
-$labels['addattachment'] = 'Ataseaza fisier';
+$labels['addattachment'] = 'Ataşează fişier';
 $labels['charset'] = 'Set de caractere';
 $labels['editortype'] = 'Tip de editor';
-$labels['returnreceipt'] = 'Returneaza confirmare';
-$labels['checkspelling'] = 'Verifica ortografie';
+$labels['returnreceipt'] = 'Returnează confirmare de primire';
+$labels['checkspelling'] = 'Verifică ortografie';
 $labels['resumeediting'] = 'Reia editarea';
-$labels['revertto'] = 'Revina la';
-$labels['attachments'] = 'Atasamente';
-$labels['upload'] = 'Incarca';
-$labels['close'] = 'Inchide';
-$labels['low'] = 'Mica';
-$labels['lowest'] = 'Cea mai mica';
-$labels['normal'] = 'Normala';
+$labels['revertto'] = 'Revină la';
+$labels['attachments'] = 'Ataşamente';
+$labels['upload'] = 'Încarcă';
+$labels['close'] = 'Închide';
+$labels['low'] = 'Mică';
+$labels['lowest'] = 'Cea mai mică';
+$labels['normal'] = 'Normală';
 $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['nosubject'] = '(fără subiect)';
+$labels['showimages'] = 'Afişează imagini';
+$labels['alwaysshow'] = 'Afişează întotdeauna imaginile de la $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Text simplu';
-$labels['savesentmessagein'] = 'Salveaza mesajele in';
+$labels['savesentmessagein'] = 'Salvează mesajele în';
 $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';
-$labels['mdnrequest'] = 'Expeditorul acestui mesaj a solicitat sa fie notificat la cititrea mesajului. Doriti sa notificati expeditorul?';
-$labels['receiptread'] = 'Returneaza confirmare (citit)';
-$labels['yourmessage'] = 'Aceasta este o confirmare a mesajului dumneavoastra.';
-$labels['receiptnote'] = 'Nota: Aceasta confirmare doar va informeaza ca mesajul a fost afisat pe calculatorul destinatarului. Nu este nici o garantie ca destinatarul a citit sau a inteles continutul mesajului.';
-$labels['name'] = 'Nume de afisat';
+$labels['maxuploadsize'] = 'Mărimea maximă admisă a fişierului este $size';
+$labels['addcc'] = 'Adaugă Cc ';
+$labels['addbcc'] = 'Adaugă Bcc';
+$labels['addreplyto'] = 'Adaugă Raspunde-La';
+$labels['mdnrequest'] = 'Expeditorul acestui mesaj a solicitat să fie notificat la cititrea mesajului. Doriţi să notificaţi expeditorul?';
+$labels['receiptread'] = 'Returnează confirmare (citit)';
+$labels['yourmessage'] = 'Aceasta este o confirmare de primire a mesajului dumneavoastră.';
+$labels['receiptnote'] = 'Notă: Această confirmare doar vă informează că mesajul a fost afişat pe calculatorul destinatarului. Nu există nici o garanţie că destinatarul a citit sau a inţeles conţinutul mesajului.';
+$labels['name'] = 'Numele Contactului';
 $labels['firstname'] = 'Nume';
 $labels['surname'] = 'Prenume';
 $labels['email'] = 'E-Mail';
-$labels['addcontact'] = 'Adauga contactul selectat in agenda';
-$labels['editcontact'] = 'Modifica contact';
-$labels['edit'] = 'Editeaza';
-$labels['cancel'] = 'Renunta';
-$labels['save'] = 'Salveaza';
-$labels['delete'] = 'Sterge';
-$labels['newcontact'] = 'Creaza contact nou';
-$labels['deletecontact'] = 'Sterge contactul selectat';
+$labels['addcontact'] = 'Adaugă contactul selectat în agendă';
+$labels['editcontact'] = 'Modifică contact';
+$labels['edit'] = 'Editează';
+$labels['cancel'] = 'Renunţă';
+$labels['save'] = 'Salvează';
+$labels['delete'] = 'Şterge';
+$labels['newcontact'] = 'Creează contact nou';
+$labels['deletecontact'] = 'Şterge contactul selectat';
 $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['contactsfromto'] = 'Contacte de la $from până la $to din $count';
+$labels['print'] = 'Listează';
+$labels['export'] = 'Exportă';
+$labels['exportvcards'] = 'Exportă contactele în format vCard';
+$labels['previouspage'] = 'Pagina anterioară';
+$labels['firstpage'] = 'Arată primul set';
+$labels['nextpage'] = 'Pagina următoare';
+$labels['lastpage'] = 'Arată 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['import'] = 'Importă';
+$labels['importcontacts'] = 'Importă contacte';
+$labels['importfromfile'] = 'Importă din fişier:';
+$labels['importreplace'] = 'Înlocuieşte întreaga agendă';
+$labels['importtext'] = 'Puteţi încărca contacte dintr-o agendă existentă.Se pot importa adresele în format vCard.';
 $labels['done'] = 'Finalizat';
-$labels['settingsfor'] = 'Setari pentru';
-$labels['preferences'] = 'Preferinte';
-$labels['userpreferences'] = 'Preferinte utilizator';
-$labels['editpreferences'] = 'Modifica preferinte utilizator';
-$labels['identities'] = 'Identitati';
-$labels['manageidentities'] = 'Administreaza identitati pentru acest cont';
-$labels['newidentity'] = 'Identitate noua';
-$labels['newitem'] = 'Item nou';
-$labels['edititem'] = 'Editeaza item';
-$labels['setdefault'] = 'Seteaza implicit';
+$labels['settingsfor'] = 'Setări pentru';
+$labels['preferences'] = 'Preferinţe';
+$labels['userpreferences'] = 'Preferinţe utilizator';
+$labels['editpreferences'] = 'Modifică preferinţe utilizator';
+$labels['identities'] = 'Identităţi';
+$labels['manageidentities'] = 'Administrează identităţi pentru acest cont';
+$labels['newidentity'] = 'Identitate nouă';
+$labels['newitem'] = 'Obiect nou';
+$labels['edititem'] = 'Editează obiect';
+$labels['setdefault'] = 'Setează implicit';
 $labels['autodetect'] = 'Automat';
 $labels['language'] = 'Limba';
 $labels['timezone'] = 'Fus orar';
-$labels['pagesize'] = 'Randuri pe pagina';
-$labels['signature'] = 'Semnatura';
-$labels['dstactive'] = 'Daylight savings';
+$labels['pagesize'] = 'Rânduri pe pagină';
+$labels['signature'] = 'Semnătură';
+$labels['dstactive'] = 'Reglare automată oră de vară';
 $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['htmlsignature'] = 'Semnatură HTML';
+$labels['previewpane'] = 'Previzualizare mail';
+$labels['skin'] = 'Temă interfaţă';
+$labels['logoutclear'] = 'Goleşte Coşul de Gunoi la deconectare';
+$labels['logoutcompact'] = 'Compactează dosarul Primite la deconectare';
+$labels['uisettings'] = 'Interfaţă utilizator';
+$labels['serversettings'] = 'Configuraţii server';
+$labels['mailboxview'] = 'Afişare Mailbox';
+$labels['mdnrequests'] = 'Notificări expeditor';
+$labels['askuser'] = 'întreabă 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['ignore'] = 'ignoră';
+$labels['readwhendeleted'] = 'Marchează mesajul ca şi citit la ştergere';
+$labels['flagfordeletion'] = 'Marchează mesajul pentru ştergere în loc de a-l şterge direct';
+$labels['skipdeleted'] = 'Nu arăta mesajele şterse';
+$labels['showremoteimages'] = 'Arată imaginile care nu fac parte din e-mail';
+$labels['fromknownsenders'] = 'de la expeditori cunoscuţi';
+$labels['always'] = 'întotdeauna';
+$labels['showinlineimages'] = 'Arată imaginile ataşate sub mesaj';
+$labels['autosavedraft'] = 'Salvează ciorna automat';
 $labels['everynminutes'] = 'fiecare $n minut(e)';
-$labels['keepalive'] = 'Verifica mesaje noi la';
-$labels['never'] = 'niciodata';
-$labels['messagesdisplaying'] = 'Afisarea Mesajelor';
+$labels['keepalive'] = 'Verifică mesaje noi la';
+$labels['never'] = 'niciodată';
+$labels['messagesdisplaying'] = 'Afişarea Mesajelor';
 $labels['messagescomposition'] = 'Compunerea Mesajelor';
-$labels['mimeparamfolding'] = 'Nume Atasamente';
+$labels['mimeparamfolding'] = 'Nume ataşamente';
 $labels['2231folding'] = 'RFC 2231 (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
 $labels['2047folding'] = 'RFC 2047 (Altele)';
-$labels['advancedoptions'] = 'Optiuni Avansate';
+$labels['advancedoptions'] = 'Opţiuni Avansate';
 $labels['focusonnewmessage'] = 'Focus pe fereastra browser-ului la mesaje noi';
-$labels['checkallfolders'] = 'Verifica toate dosarele pentru mesaje noi';
+$labels['checkallfolders'] = 'Verifică toate dosarele pentru mesaje noi';
+$labels['displaynext'] = 'După ştergerea sau mutarea unui mesaj afişează-l pe următorul din listă';
+$labels['indexsort'] = 'Folosiţi indexul de sortare după dată';
+$labels['mainoptions'] = 'Opţiuni principale';
+$labels['section'] = 'Secţiune';
+$labels['maintenance'] = 'Mentenanţă';
+$labels['newmessage'] = 'Mesaj Nou';
+$labels['listoptions'] = 'Opţiuni listă';
 $labels['folder'] = 'Dosar';
 $labels['folders'] = 'Dosare';
 $labels['foldername'] = 'Nume dosar';
-$labels['subscribed'] = 'Inscris';
+$labels['subscribed'] = 'Înscris';
 $labels['messagecount'] = 'Mesaje';
-$labels['create'] = 'Creaza';
-$labels['createfolder'] = 'Creaza dosar nou';
-$labels['rename'] = 'Redenumeste';
-$labels['renamefolder'] = 'Redenumeste dosar';
-$labels['deletefolder'] = 'Sterge dosar';
-$labels['managefolders'] = 'Administreaza dosare';
+$labels['create'] = 'Creează';
+$labels['createfolder'] = 'Creează dosar nou';
+$labels['rename'] = 'Redenumeşte';
+$labels['renamefolder'] = 'Redenumeşte dosar';
+$labels['deletefolder'] = 'Şterge dosar';
+$labels['managefolders'] = 'Administrează dosare';
 $labels['specialfolders'] = 'Dosare speciale';
-$labels['sortby'] = 'Sorteaza dupa';
-$labels['sortasc'] = 'Sorteaza ascendent';
-$labels['sortdesc'] = 'Sorteaza descendent';
+$labels['sortby'] = 'Sortează după';
+$labels['sortasc'] = 'Sortează ascendent';
+$labels['sortdesc'] = 'Sortează descendent';
 $labels['B'] = 'O';
 $labels['KB'] = 'KO';
 $labels['MB'] = 'MO';
 $labels['GB'] = 'GO';
-
-?>
+?>
\ No newline at end of file
index edfe48365eb127915246f47d8dbdee578fa5b8b3..890a0d8c1e2eefb9eab875955bbd73522b63e806 100644 (file)
 +-----------------------------------------------------------------------+
 | Author: Daniel Anechitoaie - danieLs <daniels@safereaction.ro>        |
 |         Zeno Popovici <zeno.popovici at ulbsibiu.ro>                  |
+|                Cristian Nastase <cristian.nastase@itcaffe.net>                               |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2494 2009-05-17 11:56:53Z yllar $
+@version $Id: messages.inc 2994 2009-09-27 14:16:33Z yllar $
 
 */
 
 $messages = array();
-$messages['loginfailed'] = 'Autentificare esuata';
-$messages['cookiesdisabled'] = 'Browserul dumneavoastra nu accepta cookies';
-$messages['sessionerror'] = 'Sesiunea dumneavoastra este invalida sau a expirat';
-$messages['imaperror'] = 'Conectarea la serverul IMAP a esuat';
-$messages['nomessagesfound'] = 'Nu a fost gasit nici un mesaj in aceasta casuta postala';
-$messages['loggedout'] = 'Sesiune incheiata cu succes. La revedere!';
-$messages['mailboxempty'] = 'Casuta postala este goala';
-$messages['loading'] = 'Se incarca...';
-$messages['loadingdata'] = 'Se incarca informatiile...';
-$messages['checkingmail'] = 'Verifica pentru mesaje noi...';
+$messages['loginfailed'] = 'Autentificare eşuată';
+$messages['cookiesdisabled'] = 'Browserul dumneavoastră nu acceptă cookies';
+$messages['sessionerror'] = 'Sesiunea dumneavoastră este invalidă sau a expirat';
+$messages['imaperror'] = 'Conectarea la serverul IMAP a eşuat';
+$messages['servererror'] = 'Eroare de server!';
+$messages['invalidrequest'] = 'Solicitare invalidă! Datele nu au fost salvate.';
+$messages['nomessagesfound'] = 'Nu a fost găsit nici un mesaj în această căsuţă poştală';
+$messages['loggedout'] = 'Sesiune încheiată cu succes. La revedere!';
+$messages['mailboxempty'] = 'Căsuţa poştală este goală';
+$messages['loading'] = 'Se încarcă...';
+$messages['loadingdata'] = 'Se încarcă informaţiile...';
+$messages['checkingmail'] = 'Se caută mesaje noi...';
 $messages['sendingmessage'] = 'Trimitere mesaj...';
 $messages['messagesent'] = 'Mesajul a fost trimis cu succes!';
 $messages['savingmessage'] = 'Salvare mesaj...';
-$messages['messagesaved'] = 'Mesajul a fost salvat in Ciorne';
+$messages['messagesaved'] = 'Mesajul a fost salvat în Ciorne';
 $messages['successfullysaved'] = 'Salvarea s-a efectuat cu succes';
-$messages['addedsuccessfully'] = 'Contactul a fost adaugat cu succes in agenda';
-$messages['contactexists'] = 'Mai exista un contact cu aceasta adresa de e-mail';
-$messages['blockedimages'] = 'Pentru a va proteja intimitatea imaginile externe au fost blocate.';
-$messages['encryptedmessage'] = 'Acesta este un mesaj criptat si nu poate fi afisat. Ne pare rau.';
-$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['addedsuccessfully'] = 'Contactul a fost adăugat cu succes în agendă';
+$messages['contactexists'] = 'Mai există un contact cu această adresă de e-mail';
+$messages['blockedimages'] = 'Pentru a vă proteja intimitatea, imaginile externe au fost blocate.';
+$messages['encryptedmessage'] = 'Acesta este un mesaj criptat şi nu poate fi afişat. Ne pare rău.';
+$messages['nocontactsfound'] = 'Nu s-a găsit nici un contact';
+$messages['contactnotfound'] = 'Contactul solicitat nu a fost găsit.';
+$messages['sendingfailed'] = 'Nu s-a reuşit trimiterea mesajului';
+$messages['senttooquickly'] = 'Vă rugăm aşteptaţi $sec sec. înainte de a trimite acest mesaj';
+$messages['errorsavingsent'] = 'A intervenit o eroare în timp ce se efectua salvarea mesajului trimis';
+$messages['errorsaving'] = 'A intervenit o eroare în timp ce se efectua salvarea';
 $messages['errormoving'] = 'Nu s-a putut muta mesajul';
-$messages['errordeleting'] = 'Nu s-a putut sterge mesajul';
-$messages['deletecontactconfirm'] = 'Sunteti sigur ca doriti sa stergeti contactul(ele) selectate?';
-$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['errordeleting'] = 'Nu s-a putut şterge mesajul';
+$messages['errormarking'] = 'Nu s-a putut marca mesajul';
+$messages['deletecontactconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi contactul(ele) selectate?';
+$messages['deletemessagesconfirm'] = 'Chiar doriţi să ştergeţi mesajele selectate ?';
+$messages['deletefolderconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi acest dosar?';
+$messages['purgefolderconfirm'] = 'Sunteţi sigur că doriţi să ştergeţi toate mesajele din acest dosar?';
+$messages['foldercreating'] = 'Se creează dosarul...';
+$messages['folderdeleting'] = 'Se şterge dosarul...';
+$messages['folderrenaming'] = 'Se redenumeşte dosarul...';
+$messages['foldermoving'] = 'Se mută 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?';
-$messages['notsentwarning'] = 'Mesajul nu a fost trimis. Vreti sa renuntatati la el?';
-$messages['noldapserver'] = 'Va rugam alegeti un server ldap pentru cautare';
-$messages['nocontactsreturned'] = 'Nu s-a gasit nici un contact';
-$messages['nosearchname'] = 'Va rugam introduceti un nume de contact sau adresa de e-mail';
-$messages['searchsuccessful'] = '$nr mesaje gasite';
-$messages['searchnomatch'] = 'Cautarea nu a returnat nici un rezultat';
-$messages['searching'] = 'Se cauta...';
-$messages['checking'] = 'Se verifica...';
-$messages['nospellerrors'] = 'Nu s-a gasit nicio greseala de ortografie';
-$messages['folderdeleted'] = 'Dosarul a fost sters cu succes';
-$messages['deletedsuccessfully'] = 'Mesaj sters cu succes !';
-$messages['converting'] = 'Resetez mesajul la parametrii initiali';
-$messages['messageopenerror'] = 'Nu am putut incarca mesajul din server';
-$messages['fileuploaderror'] = 'Incarcarea pe server a esuat';
-$messages['filesizeerror'] = 'Fisierul incarcat depaseste marimea de $size';
-$messages['copysuccess'] = 'Am copiat cu succes $nr de adrese';
-$messages['copyerror'] = 'Nu am putut copia nici o adresa';
-$messages['sourceisreadonly'] = 'Sursa adrese este "read-only"(se poate doar citi)';
-$messages['errorsavingcontact'] = 'Nu am putut salva adresa de contact';
+$messages['noemailwarning'] = 'Vă rugăm să introduceţi o adresă de e-mail validă';
+$messages['nonamewarning'] = 'Vă rugăm să introduceţi un nume';
+$messages['nopagesizewarning'] = 'Vă rugăm să introduceţi mărimea paginii';
+$messages['nosenderwarning'] = 'Vă rugăm să introduceţi adresa expeditorului';
+$messages['norecipientwarning'] = 'Vă rugăm să introduceţi cel puţin un destinatar';
+$messages['nosubjectwarning'] = 'Mesajul nu are subiect. Vreţi să introduceţi unul acum?';
+$messages['nobodywarning'] = 'Trimiteţi acest mesaj fără text?';
+$messages['notsentwarning'] = 'Mesajul nu a fost trimis. Vreţi să renunţaţi la el?';
+$messages['noldapserver'] = 'Vă rugăm să alegeţi un server ldap pentru căutare';
+$messages['nocontactsreturned'] = 'Nu s-a găsit nici un contact';
+$messages['nosearchname'] = 'Vă rugăm să introduceţi un nume de contact sau adresă de e-mail';
+$messages['searchsuccessful'] = '$nr mesaje găsite';
+$messages['searchnomatch'] = 'Căutarea nu a returnat nici un rezultat';
+$messages['searching'] = 'Se caută...';
+$messages['checking'] = 'Se verifică...';
+$messages['nospellerrors'] = 'Nu s-a găsit nici-o greşeală de ortografie';
+$messages['folderdeleted'] = 'Dosarul a fost şters cu succes';
+$messages['deletedsuccessfully'] = 'Mesaj şters cu succes !';
+$messages['converting'] = 'Resetez mesajul la parametrii iniţiali...';
+$messages['messageopenerror'] = 'Nu s-a putut încărca mesajul din server';
+$messages['fileuploaderror'] = 'Încărcarea pe server a eşuat';
+$messages['filesizeerror'] = 'Fişierul încărcat depăşeşte mărimea de $size';
+$messages['copysuccess'] = '$nr adrese s-au copiat cu succes';
+$messages['copyerror'] = 'Nu s-a putut copia nici-o adresă';
+$messages['sourceisreadonly'] = 'Sursa acestei adrese este "read-only"(se poate doar citi)';
+$messages['errorsavingcontact'] = 'Nu s-a putut salva adresa de contact';
 $messages['movingmessage'] = 'Mutare mesaj....';
-$messages['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['receiptsent'] = 'Confirmarea de citire a fost trimisă cu succes';
+$messages['errorsendingreceipt'] = 'Confirmarea nu a putut fi trimisă';
+$messages['nodeletelastidentity'] = 'Nu puteţi şterge această 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?';
-
-?>
+$messages['forbiddencharacter'] = 'Numele dosarului conţine un caracter nepermis.';
+$messages['selectimportfile'] = 'Va rugăm să selectaţi fişierul pentru încărcare';
+$messages['addresswriterror'] = 'Agenda selectată nu poate fi actualizată';
+$messages['importwait'] = 'Datele sunt importate, vă rugăm să aşteptaţi...';
+$messages['importerror'] = 'Importul a eşuat! Fişierul încărcat nu este un fişier vCard valid.';
+$messages['importconfirm'] = 'Contactele $inserted au fost importate cu succes, $skipped intrări au fost ignorate deoarece ele există deja:$names';
+$messages['opnotpermitted'] = 'Operaţia nu este permisă!';
+$messages['nofromaddress'] = 'Nu există o adresă de e-mail în identitatea selectată';
+$messages['editorwarning'] = 'Trecerea în mod text a editorului va cauza pierderea formatării textului. Doriţi să continuaţi?';
+$messages['httpreceivedencrypterror'] = 'Vă rugăm să luaţi legătura cu administratorul serverului de mail, deoarece există o eroare în configuraţia acestuia. Mesajul d-voastră nu a fost trimis.';
+$messages['smtpconnerror'] = 'Eroare SMTP  ($code): Conexiunea cu serverul a eşuat';
+$messages['smtpautherror'] = 'Eroare SMTP  ($code): Autentificare eşuată';
+$messages['smtpfromerror'] = 'Eroare SMTP  ($code): Nu s-a putut seta expeditorul "$from"';
+$messages['smtptoerror'] = 'Eroare SMTP  ($code): Nu s-a putut adăuga destinatarul "$to"';
+$messages['smtprecipientserror'] = 'Eroare SMTP: Nu s-a putut procesa lista cu destinatari';
+$messages['smtperror'] = 'Eroare SMTP: $msg';
+?>
\ No newline at end of file
index 6fce7f5eea47f976d7707d77004269d497aa370c..2bdfaa5c0276271d1d1434dfc64781572f6f353e 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Artur Smolkin <artsmolkin@ya.ru>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
+@version $Id: labels.inc 3061 2009-10-26 21:42:58Z yllar $
 
 */
 
@@ -251,6 +251,7 @@ $labels['advancedoptions'] = 'Дополнительные настройки';
 $labels['focusonnewmessage'] = 'Фокусировать окно браузера при новом сообщении';
 $labels['checkallfolders'] = 'Проверять новые сообщения во всех папках';
 $labels['displaynext'] = 'Показать следующее сообщение, после удаления или перемещения данного';
+$labels['indexsort'] = 'Использовать индекс сообщений для сортировки по дате';
 $labels['mainoptions'] = 'Основные настройки';
 $labels['section'] = 'Раздел';
 $labels['maintenance'] = 'Обслуживание';
index 42e623ddfb8bad3364c1ddb08533a28d1dd42a2c..652191ad1a84eb42fdfe33592c8cf22da6a7b2d8 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Artur Smolkin <artsmolkin@ya.ru>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2784 2009-07-22 12:23:12Z yllar $
+@version $Id: messages.inc 3061 2009-10-26 21:42:58Z yllar $
 
 */
 
@@ -28,6 +28,7 @@ $messages['nomessagesfound'] = 'Сообщений не найдено';
 $messages['loggedout'] = 'Ваша сессия завершена. Всего доброго!';
 $messages['mailboxempty'] = 'Почтовый ящик пуст';
 $messages['loading'] = 'Загрузка...';
+$messages['uploading'] = 'Файл загружается…';
 $messages['loadingdata'] = 'Загрузка данных...';
 $messages['checkingmail'] = 'Проверка новых сообщений...';
 $messages['sendingmessage'] = 'Отправка сообщения...';
@@ -68,6 +69,7 @@ $messages['notsentwarning'] = 'Сообщение не было отправле
 $messages['noldapserver'] = 'Пожалуйста, выберите LDAP сервер для поиска';
 $messages['nocontactsreturned'] = 'Контакты не найдены';
 $messages['nosearchname'] = 'Пожалуйста, введите имя или адрес E-Mail';
+$messages['notuploadedwarning'] = 'Вложения загружены не полностью. Подождите или отмените загрузку.';
 $messages['searchsuccessful'] = 'Найденных сообщений - $nr';
 $messages['searchnomatch'] = 'Сообщений не найдено';
 $messages['searching'] = 'Поиск...';
@@ -104,5 +106,6 @@ $messages['smtpfromerror'] = 'SMTP Error ($code): Невозможно уста
 $messages['smtptoerror'] = 'SMTP Error ($code): Невозможно добавить получателя "$to"';
 $messages['smtprecipientserror'] = 'SMTP Error ($code): Невозможно обработать список получателей';
 $messages['smtperror'] = 'SMTP Error ($code): $msg';
+$messages['emailformaterror'] = 'Неверный адрес: $email';
 
 ?>
index 9ecfbfe073766ef07f60c2ea647b0f321583aae3..a95ee2a005457e0ffb46d63459b1a3ee8800d01c 100644 (file)
@@ -15,7 +15,7 @@
 |         Andreas Henriksson <andreas@fatal.se>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
+@version $Id: labels.inc 3043 2009-10-14 11:45:28Z yllar $
 
 */
 
@@ -113,12 +113,12 @@ $labels['lastmessage'] = 'Visa sista meddelandet';
 $labels['lastmessages'] = 'Visa sista gruppen av meddelanden';
 $labels['backtolist'] = 'Tillbaka till meddelandelistan';
 $labels['viewsource'] = 'Visa källkod';
-$labels['markmessages'] = 'Markera meddelande';
+$labels['markmessages'] = 'Märk meddelande';
 $labels['markread'] = 'Läst';
 $labels['markunread'] = 'Oläst';
 $labels['markflagged'] = 'Flaggat';
 $labels['markunflagged'] = 'Oflaggat';
-$labels['messageactions'] = 'Fler hanteringsalternativ...';
+$labels['messageactions'] = 'Hanteringsalternativ';
 $labels['select'] = 'Välj';
 $labels['all'] = 'Alla';
 $labels['none'] = 'Ingen';
@@ -253,6 +253,7 @@ $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['displaynext'] = 'Visa nästa meddelande efter radering/flyttning av meddelande';
+$labels['indexsort'] = 'Använd meddelandets index vid sortering i datumordning';
 $labels['mainoptions'] = 'Huvudalternativ';
 $labels['section'] = 'Avdelning';
 $labels['maintenance'] = 'Underhåll';
index a944c581a5cec755da34eeea6b980a1a594440e0..5e6faaa6cec6d770f140f56575a8a2451ed15c48 100644 (file)
@@ -15,7 +15,7 @@
 |         Andreas Henriksson <andreas@fatal.se>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2850 2009-08-07 21:17:12Z yllar $
+@version $Id: messages.inc 3043 2009-10-14 11:45:28Z yllar $
 
 */
 
@@ -30,6 +30,7 @@ $messages['nomessagesfound'] = 'Inga meddelanden';
 $messages['loggedout'] = 'Du är utloggad. Välkommen åter!';
 $messages['mailboxempty'] = 'Katalogen är tom';
 $messages['loading'] = 'Laddar...';
+$messages['uploading'] = 'Överför fil...';
 $messages['loadingdata'] = 'Laddar data...';
 $messages['checkingmail'] = 'Letar efter nya meddelanden...';
 $messages['sendingmessage'] = 'Skickar meddelande...';
@@ -70,6 +71,7 @@ $messages['notsentwarning'] = 'Meddelandet har inte skickats. Vill du avbryta me
 $messages['noldapserver'] = 'Vänligen ange en LDAP-server att söka';
 $messages['nocontactsreturned'] = 'Inga kontakter hittades';
 $messages['nosearchname'] = 'Vänligen ange ett kontaktnamn eller en adress';
+$messages['notuploadedwarning'] = 'Alla bilagor har inte överförts ännu. Vänligen vänta eller avbryt överföringen.';
 $messages['searchsuccessful'] = '$nr meddelanden hittades';
 $messages['searchnomatch'] = 'Sökningen gav inget resultat';
 $messages['searching'] = 'Söker...';
index a27b67b09211b0cd95a28e6ef82bcfc6ebadeb24..bc082b67586b18cc6cf02287c6ff0998b4e98214 100644 (file)
@@ -25,23 +25,28 @@ if (!$OUTPUT->ajax_call)
 
 $cid = get_input_value('_cid', RCUBE_INPUT_POST);
 $target = get_input_value('_to', RCUBE_INPUT_POST);
-if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && strlen($target) && $target != $source)
+
+if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && strlen($target) && $target !== $source)
 {
-  $success = false;
+  $success = 0;
   $TARGET = $RCMAIL->get_address_book($target);
 
   if ($TARGET && $TARGET->ready && !$TARGET->readonly) {
-    $plugin = $RCMAIL->plugins->exec_hook('create_contact', array('record' => $CONTACTS->search($CONTACTS->primary_key, $cid), 'source' => $target));
+    $arr_cids = split(',', $cid);
+    foreach ($arr_cids as $cid) {
+      $plugin = $RCMAIL->plugins->exec_hook('create_contact', array('record' => $CONTACTS->get_record($cid, true), 'source' => $target));
     $a_record = $plugin['record'];
 
     if (!$plugin['abort'])
-      $success = $TARGET->insert($CONTACTS->search($a_record, true));
+        if ($TARGET->insert($a_record, true))
+          $success++;
+    }
   }
 
-  if (empty($success))
+  if ($success == 0)
     $OUTPUT->show_message('copyerror', 'error');
   else
-    $OUTPUT->show_message('copysuccess', 'notice', array('nr' => count($success)));
+    $OUTPUT->show_message('copysuccess', 'notice', array('nr' => $success));
     
   // close connection to second address directory
   $TARGET->close();
index 90a7796440ce9e509f001355466193caa1a7935f..6813958f25c8ea1bd30f378f0f4dbd1e1e92105f 100644 (file)
@@ -23,7 +23,7 @@ $cid = get_input_value('_cid', RCUBE_INPUT_GET);
 $recipients = null;
 $mailto = array();
 
-if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && $CONTACTS->ready)
+if ($cid && preg_match('/^[a-z0-9\-\+\/_=]+(,[a-z0-9\-\+\/_=]+)*$/i', $cid) && $CONTACTS->ready)
 {
   $CONTACTS->set_page(1);
   $CONTACTS->set_pagesize(100);
index 60157034559520b109bce97d965a4fcff7252a5f..d97b9c413a75b0d247ae9aeb10bb3fe407c3554f 100644 (file)
@@ -74,6 +74,8 @@ if (!is_array($_SESSION['compose']['attachments'])) {
 // clear all stored output properties (like scripts and env vars)
 $OUTPUT->reset();
 
+$uploadid = get_input_value('_uploadid', RCUBE_INPUT_GET);
+
 if (is_array($_FILES['_attachments']['tmp_name'])) {
   foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
     $attachment = array(
@@ -109,7 +111,11 @@ if (is_array($_FILES['_attachments']['tmp_name'])) {
 
       $content .= Q($attachment['name']);
       
-      $OUTPUT->command('add2attachment_list', "rcmfile$id", $content);
+      $OUTPUT->command('add2attachment_list', "rcmfile$id", array(
+        'html' => $content,
+        'name' => $attachment['name'],
+        'mimetype' => $attachment['mimetype'],
+        'complete' => true), $uploadid);
     }
     else {  // upload failed
       $err = $_FILES['_attachments']['error'][$i];
@@ -124,15 +130,22 @@ if (is_array($_FILES['_attachments']['tmp_name'])) {
       }
     
       $OUTPUT->command('display_message', $msg, 'error');
+      $OUTPUT->command('remove_from_attachment_list', $uploadid);
     }
   }
 }
 else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-  $OUTPUT->command('display_message', rcube_label('fileuploaderror'), 'error');
+  // if filesize exceeds post_max_size then $_FILES array is empty,
+  // show filesizeerror instead of fileuploaderror
+  if ($maxsize = ini_get('post_max_size'))
+    $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize)))));
+  else
+    $msg = rcube_label('fileuploaderror');
+  $OUTPUT->command('display_message', $msg, 'error');
+  $OUTPUT->command('remove_from_attachment_list', $uploadid);
 }
 
 // send html page with JS calls as response
-$OUTPUT->command('show_attachment_form', false);
 $OUTPUT->command('auto_save_start', false);
 $OUTPUT->send('iframe');
 
index 78b7fbbdf1e93de97bd545c1f989a1b8f217a102..094c429d4683a31848c53a6a038bd82e6828b0ea 100644 (file)
@@ -34,6 +34,7 @@ foreach ($a_mailboxes as $mbox_name) {
       }
       
       $unread_count = $IMAP->messagecount(NULL, 'UNSEEN', TRUE);
+      $_SESSION['unseen_count'][$mbox_name] = $unread_count;
 
       $OUTPUT->set_env('messagecount', $all_count);
       $OUTPUT->set_env('pagesize', $IMAP->page_size);
@@ -68,9 +69,12 @@ foreach ($a_mailboxes as $mbox_name) {
         rcmail_js_message_list($result_h, true, false);
       }
     }
+    else {
+      rcmail_send_unread_count($mbox_name, true);
+    }
   }
-  else if ($unseen = $IMAP->messagecount($mbox_name, 'UNSEEN', $check_all)) {
-    $OUTPUT->command('set_unread_count', $mbox_name, $unseen);
+  else if ($check_all) {
+    rcmail_send_unread_count($mbox_name, true);
   }
 }
 
index 19e0b030e63b96ce74d98c4dfebaa6f72e5ff0f4..ed281169a094134a6a055dcf5e536bfc2a48de26 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: compose.inc 2909 2009-09-03 06:49:00Z alec $
+ $Id: compose.inc 3021 2009-10-06 06:55:08Z thomasb $
 
 */
 
@@ -37,7 +37,7 @@ if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_v
 {
   rcmail_compose_cleanup();
   $_SESSION['compose'] = array(
-    'id' => uniqid(rand()),
+    'id' => uniqid(mt_rand()),
     'param' => request2param(RCUBE_INPUT_GET),
     'mailbox' => $IMAP->get_mailbox_name(),
   );
@@ -92,9 +92,9 @@ if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_v
 
 
 // add some labels to client
-$OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning',
-    'nobodywarning', 'notsentwarning', 'savingmessage', 'sendingmessage', 'messagesaved',
-    'converting', 'editorwarning', 'searching');
+$OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 'cancel',
+    'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage', 
+    'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'fileuploaderror');
 
 // add config parameters to client script
 if (!empty($CONFIG['drafts_mbox'])) {
@@ -781,6 +781,7 @@ function rcmail_compose_attachment_list($attrib)
     $attrib['id'] = 'rcmAttachmentList';
   
   $out = "\n";
+  $jslist = array();
   
   if (is_array($_SESSION['compose']['attachments']))
   {
@@ -798,18 +799,25 @@ function rcmail_compose_attachment_list($attrib)
       if (empty($a_prop))
         continue;
       
-      $out .= html::tag('li', array('id' => "rcmfile".$id),
+      $out .= html::tag('li', array('id' => 'rcmfile'.$id),
         html::a(array(
             'href' => "#delete",
             'title' => rcube_label('delete'),
             'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id)),
           $button) . Q($a_prop['name']));
+        
+        $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']);
     }
   }
 
   if ($attrib['deleteicon'])
     $_SESSION['compose']['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon'];
+  if ($attrib['cancelicon'])
+    $OUTPUT->set_env('cancelicon', $CONFIG['skin_path'] . $attrib['cancelicon']);
+  if ($attrib['loadingicon'])
+    $OUTPUT->set_env('loadingicon', $CONFIG['skin_path'] . $attrib['loadingicon']);
 
+  $OUTPUT->set_env('attachments', $jslist);
   $OUTPUT->add_gui_object('attachmentlist', $attrib['id']);
     
   return html::tag('ul', $attrib, $out, html::$common_attrib);
@@ -823,16 +831,23 @@ function rcmail_compose_attachment_form($attrib)
   // add ID if not given
   if (!$attrib['id'])
     $attrib['id'] = 'rcmUploadbox';
+
+  // find max filesize value
+  $max_filesize = parse_bytes(ini_get('upload_max_filesize'));
+  $max_postsize = parse_bytes(ini_get('post_max_size'));
+  if ($max_postsize && $max_postsize < $max_filesize)
+    $max_filesize = $max_postsize;
+  $max_filesize = show_bytes($max_filesize);
   
-  $button = new html_inputfield(array('type' => 'button', 'class' => 'button'));
+  $button = new html_inputfield(array('type' => 'button'));
   
   $out = html::div($attrib,
     $OUTPUT->form_tag(array('name' => 'form', 'method' => 'post', 'enctype' => 'multipart/form-data'),
-      html::div(null, rcmail_compose_attachment_field(array())) .
-      html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize'))))))) .
+      html::div(null, rcmail_compose_attachment_field(array('size' => $attrib[attachmentfieldsize]))) .
+      html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
       html::div('buttons',
-        $button->show(rcube_label('close'), array('onclick' => "document.getElementById('$attrib[id]').style.visibility='hidden'")) . ' ' .
-        $button->show(rcube_label('upload'), array('onclick' => JS_OBJECT_NAME . ".command('send-attachment', this.form)"))
+        $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "document.getElementById('$attrib[id]').style.visibility='hidden'")) . ' ' .
+        $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('send-attachment', this.form)"))
       )
     )
   );
index bd6a92664384d1baa82c96e51f7c08efdde3a994..4e731d0b1145fbb9d06c1e223cc77dd653387997 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: folders.inc 2758 2009-07-16 15:01:05Z thomasb $
+ $Id: folders.inc 2959 2009-09-17 12:07:58Z alec $
 */
 
 // only process ajax requests
@@ -60,6 +60,7 @@ else if ($RCMAIL->action=='purge' && ($mbox = get_input_value('_mbox', RCUBE_INP
       $OUTPUT->command('message_list.clear');
       $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text());
       $OUTPUT->command('set_unread_count', $mbox_name, 0);
+      $_SESSION['unseen_count'][$mbox_name] = 0;
     }
     else
       $commands = "// purged: $success";
@@ -67,4 +68,5 @@ else if ($RCMAIL->action=='purge' && ($mbox = get_input_value('_mbox', RCUBE_INP
 }
 
 $OUTPUT->send($commands);
+
 ?>
index d2c54a76b0dc51a0b266bce3b8025e427b5b1b9f..2f9060a561632bdfd9708681717097aba2b6bf56 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 2880 2009-08-27 09:52:52Z alec $
+ $Id: func.inc 3058 2009-10-24 19:09:23Z alec $
 
 */
 
@@ -152,10 +152,11 @@ function rcmail_message_list($attrib)
   $a_sort_cols = array('subject', 'date', 'from', 'to', 'size');
 
   $mbox = $IMAP->get_mailbox_name();
-  
-  // show 'to' instead of from in sent messages
-  if (($mbox==$CONFIG['sent_mbox'] || $mbox==$CONFIG['drafts_mbox']) && ($f = array_search('from', $a_show_cols))
-      && !array_search('to', $a_show_cols))
+  $delim = $IMAP->get_hierarchy_delimiter();
+
+  // show 'to' instead of 'from' in sent/draft messages
+  if ((strpos($mbox.$delim, $CONFIG['sent_mbox'].$delim)===0 || strpos($mbox.$delim, $CONFIG['drafts_mbox'].$delim)===0)
+      && ($f = array_search('from', $a_show_cols)) && !array_search('to', $a_show_cols))
     $a_show_cols[$f] = 'to';
   
   // add col definition
@@ -392,15 +393,23 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $replace=TRUE)
     $a_show_cols = $_SESSION['list_columns'];
 
   $mbox = $IMAP->get_mailbox_name();
-
-  // show 'to' instead of from in sent messages
-  if (($mbox == $CONFIG['sent_mbox'] || $mbox == $CONFIG['drafts_mbox'])
+  $delim = $IMAP->get_hierarchy_delimiter();
+  
+  // show 'to' instead of 'from' in sent/draft messages
+  if ((strpos($mbox.$delim, $CONFIG['sent_mbox'].$delim)===0 || strpos($mbox.$delim, $CONFIG['drafts_mbox'].$delim)===0)
       && (($f = array_search('from', $a_show_cols)) !== false) && array_search('to', $a_show_cols) === false)
     $a_show_cols[$f] = 'to';
 
   $browser = new rcube_browser;
 
   $OUTPUT->command('set_message_coltypes', $a_show_cols);
+
+  // remove 'attachment' and 'flag' columns, we don't need them here
+  if(($key = array_search('attachment', $a_show_cols)) !== FALSE)
+    unset($a_show_cols[$key]);
+  if(($key = array_search('flag', $a_show_cols)) !== FALSE)
+    unset($a_show_cols[$key]);
+
   if ($browser->ie && $replace)
     $OUTPUT->command('offline_message_list', true);
 
@@ -415,12 +424,6 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $replace=TRUE)
 
     $IMAP->set_charset(!empty($header->charset) ? $header->charset : $CONFIG['default_charset']);
 
-    // remove 'attachment' and 'flag' columns, we don't need them here
-    if(($key = array_search('attachment', $a_show_cols)) !== FALSE)
-      unset($a_show_cols[$key]);
-    if(($key = array_search('flag', $a_show_cols)) !== FALSE)
-      unset($a_show_cols[$key]);
-
     // format each col; similar as in rcmail_message_list()
     foreach ($a_show_cols as $col)
       {
@@ -454,7 +457,10 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $replace=TRUE)
       $a_msg_flags['forwarded'] = 1;
     if ($header->flagged)
       $a_msg_flags['flagged'] = 1;
-
+      
+    if ($browser->ie)
+      $a_msg_cols = rc_utf8_clean($a_msg_cols);
+    
     $OUTPUT->command('add_message_row',
       $header->uid,
       $a_msg_cols,
@@ -463,8 +469,8 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $replace=TRUE)
       $insert_top);
     }
 
-    if ($browser->ie && $replace)
-      $OUTPUT->command('offline_message_list', false);
+  if ($browser->ie && $replace)
+    $OUTPUT->command('offline_message_list', false);
   }
 
 
@@ -487,9 +493,6 @@ function rcmail_messagecontent_frame($attrib)
   }
 
 
-/**
- *
- */
 function rcmail_messagecount_display($attrib)
   {
   global $IMAP, $OUTPUT;
@@ -503,9 +506,6 @@ function rcmail_messagecount_display($attrib)
   }
 
 
-/**
- *
- */
 function rcmail_quota_display($attrib)
   {
   global $OUTPUT, $COMM_PATH;
@@ -517,69 +517,56 @@ function rcmail_quota_display($attrib)
     $_SESSION['quota_display'] = $attrib['display'];
 
   $OUTPUT->add_gui_object('quotadisplay', $attrib['id']);
-
-  return html::span($attrib, rcmail_quota_content(NULL, $attrib));
+  
+  $quota = rcmail_quota_content(NULL, $attrib);
+  
+  if (is_array($quota)) {
+    $OUTPUT->add_script('$(document).ready(function(){
+       rcmail.set_quota('.json_serialize($quota).')});', 'foot');
+    $quota = '';
+    }
+  
+  return html::span($attrib, $quota);
   }
 
 
-/**
- *
- */
 function rcmail_quota_content($quota=NULL, $attrib=NULL)
   {
   global $IMAP, $COMM_PATH, $RCMAIL;
 
   $display = isset($_SESSION['quota_display']) ? $_SESSION['quota_display'] : '';
 
-  if (is_array($quota) && !empty($quota['used']) && !empty($quota['total']))
-    {
-      if (!isset($quota['percent']))
-        $quota['percent'] = $quota['used'] / $quota['total'];
+  if (empty($quota)) {
+    if (!$IMAP->get_capability('QUOTA'))
+      return rcube_label('unknown');
+    else 
+      $quota = $IMAP->get_quota();
     }
-  elseif (!$IMAP->get_capability('QUOTA'))
-    return rcube_label('unknown');
-  else
-    $quota = $IMAP->get_quota();
 
   if ($quota && !($quota['total']==0 && $RCMAIL->config->get('quota_zero_as_unlimited')))
     {
-    $quota_text = sprintf('%s / %s (%.0f%%)',
-                          show_bytes($quota['used'] * 1024),
-                          show_bytes($quota['total'] * 1024),
-                          $quota['percent']);
-
-    // show quota as image (by Brett Patterson)
-    if ($display == 'image' && function_exists('imagegif'))
-      {
-      if (!$attrib['width'])
-        $attrib['width'] = isset($_SESSION['quota_width']) ? $_SESSION['quota_width'] : 100;
-      else
-       $_SESSION['quota_width'] = $attrib['width'];
-
-      if (!$attrib['height'])
-        $attrib['height'] = isset($_SESSION['quota_height']) ? $_SESSION['quota_height'] : 14;
-      else
-       $_SESSION['quota_height'] = $attrib['height'];
-           
-      $quota_text = sprintf('<img src="./bin/quotaimg.php?u=%s&amp;q=%d&amp;w=%d&amp;h=%d" width="%d" height="%d" alt="%s" title="%s / %s" />',
-                            $quota['used'], $quota['total'],
-                            $attrib['width'], $attrib['height'],
-                            $attrib['width'], $attrib['height'],
-                            $quota_text,
-                            show_bytes($quota['used'] * 1024),
-                            show_bytes($quota['total'] * 1024));
+    $quota_result = sprintf('%s / %s (%.0f%%)',
+        show_bytes($quota['used'] * 1024), show_bytes($quota['total'] * 1024),
+        $quota['percent']);
+
+    if ($display == 'image') {
+      $quota_result = array(       
+       'percent'       => $quota['percent'],
+        'title'                => $quota_result,
+       );
+      if ($attrib['width'])
+        $quota_result['width'] = $attrib['width'];
+      if ($attrib['height'])
+        $quota_result['height']        = $attrib['height'];
       }
     }
   else
-    $quota_text = rcube_label('unlimited');
+    return rcube_label('unlimited');
 
-  return $quota_text;
+  return $quota_result;
   }
 
 
-/**
- *
- */
 function rcmail_get_messagecount_text($count=NULL, $page=NULL)
   {
   global $IMAP, $MESSAGE;
@@ -608,26 +595,42 @@ function rcmail_get_messagecount_text($count=NULL, $page=NULL)
   return Q($out);
   }
 
-/**
- *
- */
+
 function rcmail_mailbox_name_display($attrib)
 {
-    global $RCMAIL;
+  global $RCMAIL;
 
-    if (!$attrib['id'])
-        $attrib['id'] = 'rcmmailboxname';
+  if (!$attrib['id'])
+    $attrib['id'] = 'rcmmailboxname';
 
-    $RCMAIL->output->add_gui_object('mailboxname', $attrib['id']);
+  $RCMAIL->output->add_gui_object('mailboxname', $attrib['id']);
 
-    return html::span($attrib, rcmail_get_mailbox_name_text());
+  return html::span($attrib, rcmail_get_mailbox_name_text());
 }
 
 function rcmail_get_mailbox_name_text()
 {
-    global $RCMAIL;
-    return rcmail_localize_foldername($RCMAIL->imap->get_mailbox_name());
+  global $RCMAIL;
+  return rcmail_localize_foldername($RCMAIL->imap->get_mailbox_name());
+}
+
+
+function rcmail_send_unread_count($mbox_name, $force=false)
+{
+  global $RCMAIL;
+    
+  $old_unseen = $_SESSION['unseen_count'][$mbox_name];
+  $unseen = $RCMAIL->imap->messagecount($mbox_name, 'UNSEEN', $force);
+
+  if ($unseen != $old_unseen || ($mbox_name == 'INBOX'))
+    $RCMAIL->output->command('set_unread_count', $mbox_name, $unseen, ($mbox_name == 'INBOX'));
+
+  // @TODO: this data is doubled (session and cache tables) if caching is enabled
+  $_SESSION['unseen_count'][$mbox_name] = $unseen;
+    
+  return $unseen;
 }
+                             
 
 /**
  * Sets message is_safe flag according to 'show_images' option value
@@ -687,7 +690,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
   $html = preg_replace($html_search, $html_replace, $html);
 
   // fix (unknown/malformed) HTML tags before "wash"
-  $html = preg_replace_callback('/(<[\/!]*)([^ >]+)/', 'rcmail_html_tag_callback', $html);
+  $html = preg_replace_callback('/(<[\/]*)([^\s>]+)/', 'rcmail_html_tag_callback', $html);
 
   // charset was converted to UTF-8 in rcube_imap::get_message_part(),
   // -> change charset specification in HTML accordingly
@@ -728,7 +731,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
 
   // allow CSS styles, will be sanitized by rcmail_washtml_callback()
   $washer->add_callback('style', 'rcmail_washtml_callback');
-    
+
   $html = $washer->wash($html);
   $REMOTE_OBJECTS = $washer->extlinks;
   
@@ -779,64 +782,76 @@ function rcmail_print_body($part, $p = array())
   unset($data['body']);
 
   // plaintext postprocessing
-  if ($part->ctype_secondary == 'plain') {
-    // make links and email-addresses clickable
-    $replacements = new rcube_string_replacer;
-    
-    // search for patterns like links and e-mail addresses
-    $body = preg_replace_callback($replacements->link_pattern, array($replacements, 'link_callback'), $body);
-    $body = preg_replace_callback($replacements->mailto_pattern, array($replacements, 'mailto_callback'), $body);
-
-    // split body into single lines
-    $a_lines = preg_split('/\r?\n/', $body);
-    $q_lines = array();
-    $quote_level = 0;
-
-    // find/mark quoted lines...
-    for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) {
-      $q = 0;
-    
-      if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) {
-        $q = strlen(preg_replace('/\s/', '', $regs[0]));
-       $a_lines[$n] = substr($a_lines[$n], strlen($regs[0]));
-
-        if ($q > $quote_level)
-          $q_lines[$n]['quote'] = $q - $quote_level;
-        else if ($q < $quote_level)
-          $q_lines[$n]['endquote'] = $quote_level - $q;
-      }
-      else if ($quote_level > 0)
-        $q_lines[$n]['endquote'] = $quote_level;
+  if ($part->ctype_secondary == 'plain')
+    $body = rcmail_plain_body($body);
 
-      $quote_level = $q;
-    }
-
-    // quote plain text
-    $body = Q(join("\n", $a_lines), 'replace', false);
+  // allow post-processing of the message body
+  $data = $RCMAIL->plugins->exec_hook('message_part_after', array('type' => $part->ctype_secondary, 'body' => $body) + $data);
 
-    // colorize signature
-    if (($sp = strrpos($body, '-- ')) !== false)
-      if (($sp == 0 || $body[$sp-1] == "\n") && $body[$sp+3] == "\n") {
-       $body = substr($body, 0, max(0, $sp))
-           .'<span class="sig">'.substr($body, $sp).'</span>';
-      }
+  return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']);
+}
 
-    // colorize quoted lines
-    $a_lines = preg_split('/\n/', $body);
-    foreach ($q_lines as $i => $q)
-      if ($q['quote'])
-        $a_lines[$i] = str_repeat('<blockquote>', $q['quote']) . $a_lines[$i];
-      else if ($q['endquote'])
-        $a_lines[$i] = str_repeat('</blockquote>', $q['endquote']) . $a_lines[$i];
+/**
+ * Handle links and citation marks in plain text message
+ *
+ * @param string  Plain text string 
+ * @return string Formatted HTML string
+ */
+function rcmail_plain_body($body)
+{
+  // make links and email-addresses clickable
+  $replacements = new rcube_string_replacer;
+    
+  // search for patterns like links and e-mail addresses
+  $body = preg_replace_callback($replacements->link_pattern, array($replacements, 'link_callback'), $body);
+  $body = preg_replace_callback($replacements->mailto_pattern, array($replacements, 'mailto_callback'), $body);
+
+  // split body into single lines
+  $a_lines = preg_split('/\r?\n/', $body);
+  $q_lines = array();
+  $quote_level = 0;
+
+  // find/mark quoted lines...
+  for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) {
+    $q = 0;
+
+    if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) {
+      $q = strlen(preg_replace('/\s/', '', $regs[0]));
+        $a_lines[$n] = substr($a_lines[$n], strlen($regs[0]));
+
+      if ($q > $quote_level)
+        $q_lines[$n]['quote'] = $q - $quote_level;
+      else if ($q < $quote_level)
+        $q_lines[$n]['endquote'] = $quote_level - $q;
+    }
+    else if ($quote_level > 0)
+      $q_lines[$n]['endquote'] = $quote_level;
 
-    // insert the links for urls and mailtos
-    $body = $replacements->resolve(join("\n", $a_lines));
+    $quote_level = $q;
   }
 
-  // allow post-processing of the message body
-  $data = $RCMAIL->plugins->exec_hook('message_part_after', array('type' => $part->ctype_secondary, 'body' => $body) + $data);
+  // quote plain text
+  $body = Q(join("\n", $a_lines), 'replace', false);
 
-  return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']);
+  // colorize signature
+  if (($sp = strrpos($body, '-- ')) !== false)
+    if (($sp == 0 || $body[$sp-1] == "\n") && $body[$sp+3] == "\n") {
+      $body = substr($body, 0, max(0, $sp))
+       .'<span class="sig">'.substr($body, $sp).'</span>';
+    }
+
+  // colorize quoted lines
+  $a_lines = preg_split('/\n/', $body);
+  foreach ($q_lines as $i => $q)
+    if ($q['quote'])
+      $a_lines[$i] = str_repeat('<blockquote>', $q['quote']) . $a_lines[$i];
+    else if ($q['endquote'])
+      $a_lines[$i] = str_repeat('</blockquote>', $q['endquote']) . $a_lines[$i];
+
+  // insert the links for urls and mailtos
+  $body = $replacements->resolve(join("\n", $a_lines));
+    
+  return $body;
 }
 
 
@@ -1017,7 +1032,8 @@ function rcmail_message_body($attrib)
       }
     }
   else
-    $out .= html::div('message-part', html::tag('pre', array(), Q($MESSAGE->body)));
+    $out .= html::div('message-part', html::tag('pre', array(),
+      rcmail_plain_body(Q($MESSAGE->body, 'strict', false))));
 
   $ctype_primary = strtolower($MESSAGE->structure->ctype_primary);
   $ctype_secondary = strtolower($MESSAGE->structure->ctype_secondary);
@@ -1425,7 +1441,7 @@ function rcmail_send_mdn($uid, &$smtp_error)
       'From' => $sender,
       'To'   => $message->headers->mdn_to,
       'Subject' => rcube_label('receiptread') . ': ' . $message->subject,
-      'Message-ID' => sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host'])),
+      'Message-ID' => sprintf('<%s@%s>', md5(uniqid('rcmail'.mt_rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host'])),
       'X-Sender' => $identity['email'],
       'Content-Type' => 'multipart/report; report-type=disposition-notification',
     );
index acec6c80a36349a2c03e9c3164f80d29e9d0e916..d20714a6cc80c6cff988b7d92140b4d27368ba53 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: get.inc 2912 2009-09-04 10:38:18Z thomasb $
+ $Id: get.inc 2979 2009-09-22 07:50:32Z alec $
 
 */
 
@@ -93,9 +93,7 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) {
     }
     else {
       // don't kill the connection if download takes more than 30 sec.
-      if (!ini_get('safe_mode')) {
-          set_time_limit(0);
-      }
+      @set_time_limit(0);
       
       $filename = $part->filename ? $part->filename : ($MESSAGE->subject ? $MESSAGE->subject : 'roundcube') . '.'.$ctype_secondary;
       
index f1140b48c95b18bdda0490ee2c63809d132bac3a..7dd7853df6356098ce5a2958c7083c215f4f79e9 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: getunread.inc 1917 2008-10-02 17:26:16Z alec $
+ $Id: getunread.inc 2966 2009-09-18 10:15:17Z alec $
 
 */
 
@@ -24,9 +24,16 @@ $a_folders = $IMAP->list_mailboxes();
 if (!empty($a_folders))
 {
   $inbox = ($IMAP->get_mailbox_name() == 'INBOX');
-  foreach ($a_folders as $mbox_row)
-    $OUTPUT->command('set_unread_count', $mbox_row, $IMAP->messagecount($mbox_row, 'UNSEEN'), $inbox && $mbox_row == 'INBOX');
+  foreach ($a_folders as $mbox_row) {
+    $unseen = $IMAP->messagecount($mbox_row, 'UNSEEN', !isset($_SESSION['unseen_count'][$mbox_row]));
+
+    if ($unseen || !isset($_SESSION['unseen_count'][$mbox_row])) {
+      $OUTPUT->command('set_unread_count', $mbox_row, $unseen, $inbox && $mbox_row == 'INBOX');
+    }
+    $_SESSION['unseen_count'][$mbox_row] = $unseen;
+  }
 }
 
 $OUTPUT->send();
+
 ?>
index 653fb964750777800ee41570664796111b23a67b..4e3f969bd23a5524cee64e298f5d7becb7bb79ec 100644 (file)
@@ -24,6 +24,11 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_POST))
 
   if ($source)
     {
+    $browser = new rcube_browser;
+    
+    if ($browser->ie)
+      $source = rc_utf8_clean($source);          
+
     $source = htmlspecialchars(trim($source));
     $source = preg_replace('/\t/', '&nbsp;&nbsp;&nbsp;&nbsp;', $source);
     $source = preg_replace('/^([a-z0-9_:-]+)/im', '<font class="bold">'.'\1'.'</font>', $source);
index 4df43722b5d1a2db01c4cc83162608a59d68e237..bd4080a762b6d418b2876ad557c9bdcb4e3afe39 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: list.inc 2634 2009-06-11 07:53:32Z alec $
+ $Id: list.inc 2983 2009-09-23 12:32:09Z alec $
 
 */
 
@@ -49,18 +49,17 @@ $mbox_name = $IMAP->get_mailbox_name();
 if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL')
 {
   $search_request = md5($mbox_name.$_SESSION['search_filter']);
-
   $IMAP->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET, $sort_col);
   $_SESSION['search'][$search_request] = $IMAP->get_search_set();
   $OUTPUT->set_env('search_request', $search_request);
 }
-                             
 
 // fetch message headers
 if ($count = $IMAP->messagecount($mbox_name, 'ALL', !empty($_REQUEST['_refresh'])))
   $a_headers = $IMAP->list_headers($mbox_name, NULL, $sort_col, $sort_order);
 
-$unseen = $count ? $IMAP->messagecount($mbox_name, 'UNSEEN', !empty($_REQUEST['_refresh'])) : 0;
+// update mailboxlist
+rcmail_send_unread_count($mbox_name, !empty($_REQUEST['_refresh']));
 
 // update message count display
 $pages = ceil($count/$IMAP->page_size);
@@ -80,9 +79,6 @@ else if ($search_request)
   $OUTPUT->show_message('searchnomatch', 'notice');
 else
   $OUTPUT->show_message('nomessagesfound', 'notice');
-  
-// update mailboxlist
-$OUTPUT->command('set_unread_count', $mbox_name, $unseen, ($mbox_name == 'INBOX'));
 
 // send response
 $OUTPUT->send();
index 718ac0dad9933baa052cff6bcd78f6889c64fa17..81b87d8a14cbc2c858da0a545288450715dcefb9 100644 (file)
@@ -14,7 +14,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: mark.inc 2758 2009-07-16 15:01:05Z thomasb $
+ $Id: mark.inc 2960 2009-09-17 12:36:32Z alec $
 
 */
 
@@ -61,8 +61,7 @@ if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_va
   }
     
   if ($flag == 'SEEN' || $flag == 'UNSEEN' || ($flag == 'DELETED' && !$CONFIG['skip_deleted'])) {
-    $mbox_name = $IMAP->get_mailbox_name();
-    $OUTPUT->command('set_unread_count', $mbox_name, $IMAP->messagecount($mbox_name, 'UNSEEN'), ($mbox_name == 'INBOX'));
+    rcmail_send_unread_count($IMAP->get_mailbox_name());
   }
   else if ($flag == 'DELETED' && $CONFIG['skip_deleted']) {
     if ($_POST['_from'] == 'show') {
@@ -96,7 +95,11 @@ if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_va
       // update mailboxlist
       $mbox = $IMAP->get_mailbox_name();
       $unseen_count = $msg_count ? $IMAP->messagecount($mbox, 'UNSEEN') : 0;
-      $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX'));
+      $old_unseen = $_SESSION['unseen_count'][$mbox];
+      if ($old_unseen != $unseen_count) {
+        $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX'));
+       $_SESSION['unseen_count'][$mbox] = $unseen_count;
+      }
       $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count));
 
       // add new rows from next page (if any)
index 2262b48c4bc1f2ab17cc22bbea68f3d65ecc59a2..967178a4ce5206e5bfa9416f70d0a4daf3213ee6 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: move_del.inc 2758 2009-07-16 15:01:05Z thomasb $
+ $Id: move_del.inc 2960 2009-09-17 12:36:32Z alec $
 
 */
 
@@ -33,10 +33,6 @@ if ($RCMAIL->action=='moveto' && !empty($_POST['_uid']) && !empty($_POST['_targe
     $target = get_input_value('_target_mbox', RCUBE_INPUT_POST);
     $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
 
-    // flag messages as read before moving them
-    if ($CONFIG['read_when_deleted'] && $target == $CONFIG['trash_mbox'])
-       $IMAP->set_flag($uids, 'SEEN');
-
     $moved = $IMAP->move_message($uids, $target, $mbox);
   
     if (!$moved) {
@@ -106,10 +102,15 @@ else
   // update mailboxlist
   $mbox = $IMAP->get_mailbox_name();
   $unseen_count = $msg_count ? $IMAP->messagecount($mbox, 'UNSEEN') : 0;
-  $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX'));
+  $old_unseen = $_SESSION['unseen_count'][$mbox];
+  
+  if ($old_unseen != $unseen_count) {
+    $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX'));
+    $_SESSION['unseen_count'][$mbox] = $unseen_count;
+  }
 
   if ($RCMAIL->action=='moveto' && $target) {
-    $OUTPUT->command('set_unread_count', $target, $IMAP->messagecount($target, 'UNSEEN'));
+    rcmail_send_unread_count($target, true);
   }
 
   $OUTPUT->command('set_quota', rcmail_quota_content($IMAP->get_quota()));
index b8fe716df81dfd58053060e0d5adafe917f288ca..54362c785cac4ce8af95691ac761115642461cad 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Sjon Hortensius <sjon@hortensius.net>                         |
  +-----------------------------------------------------------------------+
 
- $Id: rss.inc 2672 2009-06-22 16:20:34Z alec $
+ $Id: rss.inc 2927 2009-09-05 12:31:19Z alec $
 
 */
 
@@ -30,7 +30,7 @@ $REMOTE_REQUEST = TRUE;
 $OUTPUT_TYPE = 'rss';
 
 $webmail_url = 'http';
-if (strstr('HTTPS', $_SERVER['SERVER_PROTOCOL'] )!== FALSE)
+if (strstr('HTTPS', $_SERVER['SERVER_PROTOCOL'] )!== FALSE || $RCMAIL->config->get('use_https'))
   $webmail_url .= 's';
 $webmail_url .= '://'.$_SERVER['SERVER_NAME'];
 if ($_SERVER['SERVER_PORT'] != '80')
index d62b128d3ed14e9aa30083524e54041b7258d69b..9f054f9387057c95310b7058d2268c7ed003a3b7 100644 (file)
@@ -67,7 +67,6 @@ else if (preg_match("/^body:.*/i", $str))
   list(,$srch) = explode(":", $str);
   $subject['text'] = "TEXT";
 }
-// search in subject and sender by default
 else if(trim($str))
 {
   if ($headers) {
@@ -78,6 +77,7 @@ else if(trim($str))
         default: $subject[$header] = 'HEADER '.$header;
       }
   } else {
+    // search in subject by default
     $subject['subject'] = 'HEADER SUBJECT';
   }
 }
index 85ea8739fc3e74de371b4379f0819ab328a5b284..afd1735e76fe867a0416061d8083cb2622aff5d5 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: sendmail.inc 2713 2009-07-06 09:13:10Z alec $
+ $Id: sendmail.inc 3042 2009-10-14 10:52:27Z alec $
 
 */
 
@@ -151,6 +151,8 @@ function rcmail_attach_emoticons(&$mime_message)
 // parse email address input
 function rcmail_email_input_format($mailto)
 {
+  global $EMAIL_FORMAT_ERROR;
+
   $regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U');
   $replace = array(', ', ', ', '', ',', '\\1 \\2');
 
@@ -181,8 +183,16 @@ function rcmail_email_input_format($mailto)
         $address = '<'.$address.'>';
 
       $result[] = $name.' '.$address;
+      $item = $address;
     } else if (trim($item)) {
-      // @TODO: handle errors
+      continue;
+    }
+
+    // check address format
+    $item = trim($item, '<>');
+    if ($item && !check_email($item)) {
+      $EMAIL_FORMAT_ERROR = $item;
+      return;
     }
   }
 
@@ -194,16 +204,23 @@ function rcmail_email_input_format($mailto)
 if (strlen($_POST['_draft_saveid']) > 3)
   $olddraftmessageid = get_input_value('_draft_saveid', RCUBE_INPUT_POST);
 
-$message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host']));
+$message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.mt_rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host']));
 
 // set default charset
 $input_charset = $OUTPUT->get_charset();
 $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $input_charset;
 
+$EMAIL_FORMAT_ERROR = NULL;
+
 $mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset));
 $mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset));
 $mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset));
 
+if ($EMAIL_FORMAT_ERROR) {
+  $OUTPUT->show_message('emailformaterror', 'error', array('email' => $EMAIL_FORMAT_ERROR)); 
+  $OUTPUT->send('iframe');
+}
+
 if (empty($mailto) && !empty($mailcc)) {
   $mailto = $mailcc;
   $mailcc = null;
@@ -231,17 +248,40 @@ $headers = array();
 if ($CONFIG['http_received_header'])
 {
   $nldlm = $RCMAIL->config->header_delimiter() . "\t";
+  // FROM/VIA
   $http_header = 'from ';
   if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
-    $http_header .= rcmail_encrypt_header(gethostbyaddr($_SERVER['HTTP_X_FORWARDED_FOR'])) .
-      ' [' . rcmail_encrypt_header($_SERVER['HTTP_X_FORWARDED_FOR']) . ']';
+    $host = $_SERVER['HTTP_X_FORWARDED_FOR'];
+    $hostname = gethostbyaddr($host);
+    if ($CONFIG['http_received_header_encrypt']) {
+      $http_header .= rcmail_encrypt_header($hostname);
+      if ($host != $hostname)
+        $http_header .= ' ('. rcmail_encrypt_header($host) . ')';
+    } else {
+      $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']');
+      $http_header .= ' ('. ($host == $hostname ? '' : $hostname . ' ') .
+        '[' . $host .'])';
+    }
     $http_header .= $nldlm . ' via ';
   }
-  $http_header .= rcmail_encrypt_header(gethostbyaddr($_SERVER['REMOTE_ADDR'])) .
-      ' [' . rcmail_encrypt_header($_SERVER['REMOTE_ADDR']) .']';
+  $host = $_SERVER['REMOTE_ADDR'];
+  $hostname = gethostbyaddr($host);
+  if ($CONFIG['http_received_header_encrypt']) {
+    $http_header .= rcmail_encrypt_header($hostname);
+    if ($host != $hostname)
+      $http_header .= ' ('. rcmail_encrypt_header($host) . ')';
+  } else {
+    $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']');
+    $http_header .= ' ('. ($host == $hostname ? '' : $hostname . ' ') .
+      '[' . $host .'])';
+  }
+  // BY
+  $http_header .= $nldlm . 'by ' . $_SERVER['HTTP_HOST'];
+  // WITH
   $http_header .= $nldlm . 'with ' . $_SERVER['SERVER_PROTOCOL'] .
       ' ('.$_SERVER['REQUEST_METHOD'] . '); ' . date('r');
   $http_header = wordwrap($http_header, 69, $nldlm);
+
   $headers['Received'] = $http_header;
 }
 
index de30bead282127a21026b161b4252fbdf931ebe8..5f8790bfcac773802f73e665503c3b6b4e65c2cf 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: show.inc 2822 2009-07-31 09:07:54Z alec $
+ $Id: show.inc 2933 2009-09-08 08:04:17Z alec $
 
 */
 
@@ -74,8 +74,18 @@ if ($_GET['_uid']) {
   $OUTPUT->set_env('sender', $MESSAGE->sender['string']);
   $OUTPUT->set_env('permaurl', rcmail_url('show', array('_uid' => $MESSAGE->uid, '_mbox' => $mbox_name)));
   $OUTPUT->set_env('mailbox', $mbox_name);
+
   if ($CONFIG['trash_mbox'])
     $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
+  if ($CONFIG['flag_for_deletion'])
+    $OUTPUT->set_env('flag_for_deletion', true);
+  if ($CONFIG['read_when_deleted'])
+    $OUTPUT->set_env('read_when_deleted', true);
+  if ($CONFIG['skip_deleted'])
+    $OUTPUT->set_env('skip_deleted', true);
+  if ($CONFIG['display_next'])
+    $OUTPUT->set_env('display_next', true);
+
   if (!$OUTPUT->ajax_call)
     $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', 'movingmessage');
         
@@ -143,9 +153,6 @@ if ($_GET['_uid']) {
       $OUTPUT->set_env('last_uid', $last);
     }
 
-  if ($CONFIG['display_next'])
-    $OUTPUT->set_env('display_next', true);
-
   if (!$MESSAGE->headers->seen)
     $RCMAIL->plugins->exec_hook('message_read', array('uid' => $MESSAGE->uid,
       'mailbox' => $IMAP->mailbox, 'message' => $MESSAGE));
index 717b92ee580dededdd172a0cb5b0660588d60263..0abdc9ea1a0281a4baba89aadb46f8ea24c45e24 100644 (file)
@@ -43,7 +43,7 @@ $text = substr($data, $left+6, $right-($left+6));
 $text = html_entity_decode($text, ENT_QUOTES, RCMAIL_CHARSET);
 
 // tokenize
-$words = preg_split('/[ !"#$%&()*+\\,-.\/\n:;<=>?@\[\]^_{|}]+/', $text, NULL,  PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE );
+$words = preg_split('/[ !"#$%&()*+\\,\/\n:;<=>?@\[\]^_{|}-]+|\.[^\w]/', $text, NULL,  PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE );
 
 // init spellchecker
 $plink = pspell_new(get_input_value('lang', RCUBE_INPUT_GET), null, null, RCMAIL_CHARSET, PSPELL_FAST);
@@ -56,7 +56,8 @@ foreach ($words as $w) {
     $word = trim($w[0]);
     $pos  = $w[1] - $diff;
     $len  = mb_strlen($word);
-    if ($word && $plink && !pspell_check($plink, $word)) {
+    if ($word && $plink && preg_match('/[^0-9\.]/', $word)
+       && !pspell_check($plink, $word)) {
         $suggestions = pspell_suggest($plink, $word);
        if (sizeof($suggestions)>10)
          $suggestions = array_slice($suggestions, 0, MAX_SUGGESTIONS);
index 9fcbc426b976f7ebff6a1af8b1096b51fbca3644..06ae250b35674016d3c67863c0c96330c2817ec0 100644 (file)
@@ -24,10 +24,11 @@ if (!$OUTPUT->ajax_call)
 
 
 $CURR_SECTION = get_input_value('_section', RCUBE_INPUT_GPC);
+list($SECTIONS,) = rcmail_user_prefs($CURR_SECTION);
 
 function rcmail_user_prefs_form($attrib)
 {
-  global $RCMAIL, $CURR_SECTION;
+  global $RCMAIL, $CURR_SECTION, $SECTIONS;
 
   // add some labels to client
   $RCMAIL->output->add_label('nopagesizewarning');
@@ -38,468 +39,24 @@ function rcmail_user_prefs_form($attrib)
     array('name' => '_section', 'value' => $CURR_SECTION));
 
   $out = $form_start;
-  
-  $out .= rcmail_user_prefs_block($CURR_SECTION, $attrib);
-  
-  return $out . $form_end;
-}
-
-function rcmail_user_prefs_block($part, $attrib)
-{
-  global $RCMAIL;
-
-  $config = $RCMAIL->config->all();
-  $no_override = array_flip($RCMAIL->config->get('dont_override', array()));
-  
-  $blocks = array();
-  
-  switch ($part)
-  {
-  // General UI settings
-  case 'general':
-  
-    $blocks = array(
-      'main' => array('name' => Q(rcube_label('mainoptions'))),
-      'list' => array('name' => Q(rcube_label('listoptions'))),
-    );
-    
-    // language selection
-    if (!isset($no_override['language'])) {
-      $a_lang = $RCMAIL->list_languages();
-      asort($a_lang);
-
-      $field_id = 'rcmfd_lang';
-      $select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
-      $select_lang->add(array_values($a_lang), array_keys($a_lang));
-
-      $blocks['main']['options']['language'] = array(
-        'title' => html::label($field_id, Q(rcube_label('language'))),
-        'content' => $select_lang->show($RCMAIL->user->language),
-      );
-    }
-
-    // show page size selection
-    if (!isset($no_override['timezone'])) {
-      $field_id = 'rcmfd_timezone';
-      $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "document.getElementById('rcmfd_dst').disabled=this.selectedIndex==0"));
-      $select_timezone->add(rcube_label('autodetect'), 'auto');
-      $select_timezone->add('(GMT -11:00) Midway Island, Samoa', '-11');
-      $select_timezone->add('(GMT -10:00) Hawaii', '-10');
-      $select_timezone->add('(GMT -9:30) Marquesas Islands', '-9.5');
-      $select_timezone->add('(GMT -9:00) Alaska', '-9');
-      $select_timezone->add('(GMT -8:00) Pacific Time (US/Canada)', '-8');
-      $select_timezone->add('(GMT -7:00) Mountain Time (US/Canada)', '-7');
-      $select_timezone->add('(GMT -6:00) Central Time (US/Canada), Mexico City', '-6');
-      $select_timezone->add('(GMT -5:00) Eastern Time (US/Canada), Bogota, Lima', '-5');
-      $select_timezone->add('(GMT -4:30) Caracas', '-4.5');
-      $select_timezone->add('(GMT -4:00) Atlantic Time (Canada), La Paz', '-4');
-      $select_timezone->add('(GMT -3:30) Nfld Time (Canada), Nfld, S. Labador', '-3.5');
-      $select_timezone->add('(GMT -3:00) Brazil, Buenos Aires, Georgetown', '-3');
-      $select_timezone->add('(GMT -2:00) Mid-Atlantic', '-2');
-      $select_timezone->add('(GMT -1:00) Azores, Cape Verde Islands', '-1');
-      $select_timezone->add('(GMT) Western Europe, London, Lisbon, Casablanca', '0');
-      $select_timezone->add('(GMT +1:00) Central European Time', '1');
-      $select_timezone->add('(GMT +2:00) EET: Tallinn, Helsinki, Kaliningrad, South Africa', '2');
-      $select_timezone->add('(GMT +3:00) Baghdad, Kuwait, Riyadh, Moscow, Nairobi', '3');
-      $select_timezone->add('(GMT +3:30) Tehran', '3.5');
-      $select_timezone->add('(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '4');
-      $select_timezone->add('(GMT +4:30) Kabul', '4.5');
-      $select_timezone->add('(GMT +5:00) Ekaterinburg, Islamabad, Karachi', '5');
-      $select_timezone->add('(GMT +5:30) Chennai, Kolkata, Mumbai, New Delhi', '5.5');
-      $select_timezone->add('(GMT +5:45) Kathmandu', '5.75');
-      $select_timezone->add('(GMT +6:00) Almaty, Dhaka, Colombo', '6');
-      $select_timezone->add('(GMT +6:30) Cocos Islands, Myanmar', '6.5');
-      $select_timezone->add('(GMT +7:00) Bangkok, Hanoi, Jakarta', '7');
-      $select_timezone->add('(GMT +8:00) Beijing, Perth, Singapore, Taipei', '8');
-      $select_timezone->add('(GMT +8:45) Caiguna, Eucla, Border Village', '8.75');
-      $select_timezone->add('(GMT +9:00) Tokyo, Seoul, Yakutsk', '9');
-      $select_timezone->add('(GMT +9:30) Adelaide, Darwin', '9.5');
-      $select_timezone->add('(GMT +10:00) EAST/AEST: Sydney, Guam, Vladivostok', '10');
-      $select_timezone->add('(GMT +10:30) New South Wales', '10.5');
-      $select_timezone->add('(GMT +11:00) Magadan, Solomon Islands', '11');
-      $select_timezone->add('(GMT +11:30) Norfolk Island', '11.5');
-      $select_timezone->add('(GMT +12:00) Auckland, Wellington, Kamchatka', '12');
-      $select_timezone->add('(GMT +12:45) Chatham Islands', '12.75');
-      $select_timezone->add('(GMT +13:00) Tonga, Pheonix Islands', '13');
-      $select_timezone->add('(GMT +14:00) Kiribati', '14');
-
-      $blocks['main']['options']['timezone'] = array(
-        'title' => html::label($field_id, Q(rcube_label('timezone'))),
-        'content' => $select_timezone->show((string)$config['timezone']),
-      );
-    }
-
-    // daylight savings
-    if (!isset($no_override['dst_active'])) {
-      $field_id = 'rcmfd_dst';
-      $input_dst = new html_checkbox(array('name' => '_dst_active', 'id' => $field_id, 'value' => 1, 'disabled' => ($config['timezone'] === 'auto')));
-
-      $blocks['main']['options']['dstactive'] = array(
-        'title' => html::label($field_id, Q(rcube_label('dstactive'))),
-        'content' => $input_dst->show($config['dst_active']),
-      );
-    }
-
-    // MM: Show checkbox for toggling 'pretty dates' 
-    if (!isset($no_override['prettydate'])) {
-      $field_id = 'rcmfd_prettydate';
-      $input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['prettydate'] = array(
-        'title' => html::label($field_id, Q(rcube_label('prettydate'))),
-        'content' => $input_prettydate->show($config['prettydate']?1:0),
-      );
-    }
-
-    // show page size selection
-    if (!isset($no_override['pagesize'])) {
-      $field_id = 'rcmfd_pgsize';
-      $input_pagesize = new html_inputfield(array('name' => '_pagesize', 'id' => $field_id, 'size' => 5));
-
-      $blocks['list']['options']['pagesize'] = array(
-        'title' => html::label($field_id, Q(rcube_label('pagesize'))),
-        'content' => $input_pagesize->show($config['pagesize']),
-      );
-    }
-
-    // show drop-down for available skins
-    if (!isset($no_override['skin'])) {
-      $skins = rcmail_get_skins();
-
-      if (count($skins) > 1) {
-        $field_id = 'rcmfd_skin';
-        $input_skin = new html_select(array('name'=>'_skin', 'id'=>$field_id));
-
-        foreach($skins as $skin)
-          $input_skin->add($skin, $skin);
-
-        $blocks['main']['options']['skin'] = array(
-          'title' => html::label($field_id, Q(rcube_label('skin'))),
-          'content' => $input_skin->show($config['skin']),
-        );
-      }
-    }
-    
-    break;
-
-  // Mailbox view (mail screen)
-  case 'mailbox':
-
-    $blocks = array(
-      'main' => array('name' => Q(rcube_label('mainoptions'))),
-      'new_message' => array('name' => Q(rcube_label('newmessage'))),
-    );
-
-    // show config parameter for preview pane
-    if (!isset($no_override['preview_pane'])) {
-      $field_id = 'rcmfd_preview';
-      $input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['preview_pane'] = array(
-        'title' => html::label($field_id, Q(rcube_label('previewpane'))),
-        'content' => $input_preview->show($config['preview_pane']?1:0),
-      );
-    }
-
-    if (!isset($no_override['mdn_requests'])) {
-      $field_id = 'rcmfd_mdn_requests';
-      $select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
-      $select_mdn_requests->add(rcube_label('askuser'), 0);
-      $select_mdn_requests->add(rcube_label('autosend'), 1);
-      $select_mdn_requests->add(rcube_label('ignore'), 2);
-
-      $blocks['main']['options']['mdn_requests'] = array(
-        'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
-        'content' => $select_mdn_requests->show($config['mdn_requests']),
-      );
-    }
-
-    if (!isset($no_override['focus_on_new_message'])) {
-      $field_id = 'rcmfd_focus_on_new_message';
-      $input_focus_on_new_message = new html_checkbox(array('name' => '_focus_on_new_message', 'id' => $field_id, 'value' => 1));
-
-      $blocks['new_message']['options']['focus_on_new_message'] = array(
-        'title' => html::label($field_id, Q(rcube_label('focusonnewmessage'))),
-        'content' => $input_focus_on_new_message->show($config['focus_on_new_message']?1:0),
-      );
-    }
-
-    if (!isset($no_override['keep_alive'])) {
-      $field_id = 'rcmfd_keep_alive';
-      $select_keep_alive = new html_select(array('name' => '_keep_alive', 'id' => $field_id));
-
-      foreach(array(1, 3, 5, 10, 15, 30, 60) as $min)
-        if((!$config['min_keep_alive'] || $config['min_keep_alive'] <= $min * 60)
-            && (!$config['session_lifetime'] || $config['session_lifetime'] > $min)) {
-          $select_keep_alive->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min);
-        }
-
-      $blocks['new_message']['options']['keep_alive'] = array(
-        'title' => html::label($field_id, Q(rcube_label('keepalive'))),
-        'content' => $select_keep_alive->show($config['keep_alive']/60),
-      );
-    }
-
-    if (!isset($no_override['check_all_folders'])) {
-      $field_id = 'rcmfd_check_all_folders';
-      $input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
-
-      $blocks['new_message']['options']['check_all_folders'] = array(
-        'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
-        'content' => $input_check_all->show($config['check_all_folders']?1:0),
-      );
-    }
-
-    break;
-
-  // Message viewing
-  case 'mailview':
-
-    $blocks = array(
-      'main' => array('name' => Q(rcube_label('mainoptions'))),
-    );
-
-    // show checkbox for HTML/plaintext messages
-    if (!isset($no_override['prefer_html'])) {
-      $field_id = 'rcmfd_htmlmsg';
-      $input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
-        'onchange' => JS_OBJECT_NAME.'.toggle_prefer_html(this)'));
-
-      $blocks['main']['options']['prefer_html'] = array(
-        'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
-        'content' => $input_preferhtml->show($config['prefer_html']?1:0),
-      );
-    }
-
-    if (!isset($no_override['show_images'])) {
-      $field_id = 'rcmfd_show_images';
-      $input_show_images = new html_select(array('name' => '_show_images', 'id' => $field_id));
-      $input_show_images->add(rcube_label('never'), 0);
-      $input_show_images->add(rcube_label('fromknownsenders'), 1);
-      $input_show_images->add(rcube_label('always'), 2);
-
-      $blocks['main']['options']['show_images'] = array(
-        'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
-        'content' => $input_show_images->show($config['show_images']),
-      );
-    }
-
-    if (!isset($no_override['inline_images'])) {
-      $field_id = 'rcmfd_inline_images';
-      $input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
 
-      $blocks['main']['options']['inline_images'] = array(
-        'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
-        'content' => $input_inline_images->show($config['inline_images']?1:0),
-      );
-    }
-
-    // "display after delete" checkbox
-    if (!isset($no_override['display_next'])) {
-      $field_id = 'rcmfd_displaynext';
-      $input_displaynext = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['display_next'] = array(
-        'title' => html::label($field_id, Q(rcube_label('displaynext'))),
-        'content' => $input_displaynext->show($config['display_next']?1:0),
-      );
-    }
-
-    break;
-
-  // Mail composition
-  case 'compose':
-
-    $blocks = array(
-      'main' => array('name' => Q(rcube_label('mainoptions'))),
-    );
-
-    // Show checkbox for HTML Editor
-    if (!isset($no_override['htmleditor'])) {
-      $field_id = 'rcmfd_htmleditor';
-      $input_htmleditor = new html_checkbox(array('name' => '_htmleditor', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['htmleditor'] = array(
-        'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
-        'content' => $input_htmleditor->show($config['htmleditor']?1:0),
-      );
-    }
-
-    if (!isset($no_override['draft_autosave'])) {
-      $field_id = 'rcmfd_autosave';
-      $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
-      $select_autosave->add(rcube_label('never'), 0);
-      foreach (array(1, 3, 5, 10) as $i => $min)
-        $select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
-
-      $blocks['main']['options']['draft_autosave'] = array(
-        'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
-        'content' => $select_autosave->show($config['draft_autosave']),
-      );
-    }
-
-    if (!isset($no_override['mime_param_folding'])) {
-      $field_id = 'rcmfd_param_folding';
-      $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
-      $select_param_folding->add(rcube_label('2231folding'), 0);
-      $select_param_folding->add(rcube_label('miscfolding'), 1);
-      $select_param_folding->add(rcube_label('2047folding'), 2);
-
-      $blocks['main']['options']['mime_param_folding'] = array(
-       'advanced' => true,
-        'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
-        'content' => $select_param_folding->show($config['mime_param_folding']),
-      );
-    }
-
-    break;
-
-  // Special IMAP folders
-  case 'folders':
-
-    $blocks = array(
-      'main' => array('name' => Q(rcube_label('mainoptions'))),
-    );
-
-    // Configure special folders
-    if (!isset($no_override['default_imap_folders'])) {
-      $RCMAIL->imap_init(true);
-      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true, 'maxlength' => 30));
-
-      if (!isset($no_override['drafts_mbox']))
-        $blocks['main']['options']['drafts_mbox'] = array(
-          'title' => Q(rcube_label('drafts')),
-          'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox")),
-        );
-
-      if (!isset($no_override['sent_mbox']))
-        $blocks['main']['options']['sent_mbox'] = array(
-          'title' => Q(rcube_label('sent')),
-          'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox")),
-       );
-
-      if (!isset($no_override['junk_mbox']))
-        $blocks['main']['options']['junk_mbox'] = array(
-          'title' => Q(rcube_label('junk')),
-          'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox")),
-       );
-
-      if (!isset($no_override['trash_mbox']))
-        $blocks['main']['options']['trash_mbox'] = array(
-          'title' => Q(rcube_label('trash')),
-          'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox")),
-        );
-    }
-    break;
-
-  // Server settings
-  case 'server':
-
-    $blocks = array(
-      'main' => array('name' => Q(rcube_label('mainoptions'))),
-      'maintenance' => array('name' => Q(rcube_label('maintenance'))),
-    );
-
-    if (!isset($no_override['read_when_deleted'])) {
-      $field_id = 'rcmfd_read_deleted';
-      $input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['read_when_deleted'] = array(
-        'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
-        'content' => $input_readdeleted->show($config['read_when_deleted']?1:0),
-      );
-    }
-
-    if (!isset($no_override['flag_for_deletion'])) {
-      $field_id = 'rcmfd_flag_for_deletion';
-      $input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['flag_for_deletion'] = array(
-        'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
-        'content' => $input_flagfordeletion->show($config['flag_for_deletion']?1:0),
-      );
-    }
-
-    // don't show deleted messages
-    if (!isset($no_override['skip_deleted'])) {
-      $field_id = 'rcmfd_skip_deleted';
-      $input_purge = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
-
-      $blocks['main']['options']['skip_deleted'] = array(
-        'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
-        'content' => $input_purge->show($config['skip_deleted']?1:0),
-      );
-    }
-
-    // Trash purging on logout
-    if (!isset($no_override['logout_purge'])) {
-      $field_id = 'rcmfd_logout_purge';
-      $input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
-
-      $blocks['maintenance']['options']['logout_purge'] = array(
-        'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
-        'content' => $input_purge->show($config['logout_purge']?1:0),
-      );
-    }
-
-    // INBOX compacting on logout
-    if (!isset($no_override['logout_expunge'])) {
-      $field_id = 'rcmfd_logout_expunge';
-      $input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
-
-      $blocks['maintenance']['options']['logout_expunge'] = array(
-        'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
-        'content' => $input_expunge->show($config['logout_expunge']?1:0),
-      );
-    }
-
-    break;
-  }
-
-  $data = $RCMAIL->plugins->exec_hook('user_preferences', array('section' => $part, 'blocks' => $blocks));
-
-  // create output
-  foreach ($data['blocks'] as $idx => $block) {
+  foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $idx => $block) {
     if ($block['options']) {
       $table = new html_table(array('cols' => 2));
 
       foreach ($block['options'] as $option) {
-       if ($option['advanced'])
-          $table->set_row_attribs('advanced');
-       
+        if ($option['advanced'])
+         $table->set_row_attribs('advanced');
+    
         $table->add('title', $option['title']);
        $table->add(null, $option['content']);
-      }
-
+        }
+    
       $out .= html::tag('fieldset', null, html::tag('legend', null, $block['name']) . $table->show($attrib));
+      }
     }
-  }
-
-  return $out;
-}
-
-
-function rcmail_get_skins()
-{
-  $path = 'skins';
-  $skins = array();
-
-  $dir = opendir($path);
-  
-  if (!$dir)
-       return false;
-  
-  while (($file = readdir($dir)) !== false)
-  {
-    $filename = $path.'/'.$file;
-    if (is_dir($filename) && is_readable($filename) 
-       && !in_array($file, array('.', '..', '.svn')))
-      $skins[] = $file;
-  }
-
-  closedir($dir);
-
-  return $skins;
+                                                                     
+  return $out . $form_end;
 }
 
 function rcmail_prefs_section_name()
index 7a7c128acbe283b2cbd370602007cb29724505fc..0f6b2f477e351d9c177bdb829ea0ecb189039880 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 2830 2009-08-03 18:27:53Z alec $
+ $Id: func.inc 3055 2009-10-23 18:11:41Z alec $
 
 */
 
 if (!$OUTPUT->ajax_call)
   $OUTPUT->set_pagetitle(rcube_label('preferences'));
 
-// define sections list
-$SECTIONS['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
-$SECTIONS['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
-$SECTIONS['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
-$SECTIONS['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
-$SECTIONS['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
-$SECTIONS['server'] = array('id' => 'server',  'section' => rcube_label('serversettings'));
-
 
 // similar function as /steps/settings/identities.inc::rcmail_identity_frame()
 function rcmail_preferences_frame($attrib)
@@ -50,18 +42,16 @@ function rcmail_preferences_frame($attrib)
 
 function rcmail_sections_list($attrib)
   {
-  global $RCMAIL, $SECTIONS;
+  global $RCMAIL;
   
   // add id to message list table if not specified
   if (!strlen($attrib['id']))
     $attrib['id'] = 'rcmsectionslist';
 
-  // hook + define list cols
-  $plugin = $RCMAIL->plugins->exec_hook('list_prefs_sections',
-    array('list' => $SECTIONS, 'cols' => array('section')));
+  list($list, $cols) = rcmail_user_prefs();
            
   // create XHTML table
-  $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'id');
+  $out = rcube_table_output($attrib, $list, $cols, 'id');
 
   // set client env
   $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']);
@@ -123,6 +113,495 @@ function get_form_tags($attrib, $action, $id = null, $hidden = null)
   }
 
 
+function rcmail_user_prefs($current=null)
+{
+  global $RCMAIL;
+
+  $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
+  $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
+  $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
+  $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
+  $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
+  $sections['server'] = array('id' => 'server',  'section' => rcube_label('serversettings'));
+
+  // hook + define list cols
+  $plugin = $RCMAIL->plugins->exec_hook('list_prefs_sections',
+        array('list' => $sections, 'cols' => array('section')));
+
+  $sections = $plugin['list'];
+       
+  $config = $RCMAIL->config->all();
+  $no_override = array_flip($RCMAIL->config->get('dont_override', array()));
+  
+  foreach ($sections as $idx => $sect) {
+  
+    if ($current && $sect['id'] != $current)
+      continue;
+  
+    $blocks = array();
+    
+    switch ($sect['id']) {
+    // general
+    case 'general':
+    
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+      'list' => array('name' => Q(rcube_label('listoptions'))),
+    );
+    
+    // language selection
+    if (!isset($no_override['language'])) {
+      $a_lang = $RCMAIL->list_languages();
+      asort($a_lang);
+
+      $field_id = 'rcmfd_lang';
+      $select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
+      $select_lang->add(array_values($a_lang), array_keys($a_lang));
+
+      $blocks['main']['options']['language'] = array(
+        'title' => html::label($field_id, Q(rcube_label('language'))),
+        'content' => $select_lang->show($RCMAIL->user->language),
+      );
+    }
+
+    // show page size selection
+    if (!isset($no_override['timezone'])) {
+      $field_id = 'rcmfd_timezone';
+      $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "document.getElementById('rcmfd_dst').disabled=this.selectedIndex==0"));
+      $select_timezone->add(rcube_label('autodetect'), 'auto');
+      $select_timezone->add('(GMT -11:00) Midway Island, Samoa', '-11');
+      $select_timezone->add('(GMT -10:00) Hawaii', '-10');
+      $select_timezone->add('(GMT -9:30) Marquesas Islands', '-9.5');
+      $select_timezone->add('(GMT -9:00) Alaska', '-9');
+      $select_timezone->add('(GMT -8:00) Pacific Time (US/Canada)', '-8');
+      $select_timezone->add('(GMT -7:00) Mountain Time (US/Canada)', '-7');
+      $select_timezone->add('(GMT -6:00) Central Time (US/Canada), Mexico City', '-6');
+      $select_timezone->add('(GMT -5:00) Eastern Time (US/Canada), Bogota, Lima', '-5');
+      $select_timezone->add('(GMT -4:30) Caracas', '-4.5');
+      $select_timezone->add('(GMT -4:00) Atlantic Time (Canada), La Paz', '-4');
+      $select_timezone->add('(GMT -3:30) Nfld Time (Canada), Nfld, S. Labador', '-3.5');
+      $select_timezone->add('(GMT -3:00) Brazil, Buenos Aires, Georgetown', '-3');
+      $select_timezone->add('(GMT -2:00) Mid-Atlantic', '-2');
+      $select_timezone->add('(GMT -1:00) Azores, Cape Verde Islands', '-1');
+      $select_timezone->add('(GMT) Western Europe, London, Lisbon, Casablanca', '0');
+      $select_timezone->add('(GMT +1:00) Central European Time', '1');
+      $select_timezone->add('(GMT +2:00) EET: Tallinn, Helsinki, Kaliningrad, South Africa', '2');
+      $select_timezone->add('(GMT +3:00) Baghdad, Kuwait, Riyadh, Moscow, Nairobi', '3');
+      $select_timezone->add('(GMT +3:30) Tehran', '3.5');
+      $select_timezone->add('(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '4');
+      $select_timezone->add('(GMT +4:30) Kabul', '4.5');
+      $select_timezone->add('(GMT +5:00) Ekaterinburg, Islamabad, Karachi', '5');
+      $select_timezone->add('(GMT +5:30) Chennai, Kolkata, Mumbai, New Delhi', '5.5');
+      $select_timezone->add('(GMT +5:45) Kathmandu', '5.75');
+      $select_timezone->add('(GMT +6:00) Almaty, Dhaka, Colombo', '6');
+      $select_timezone->add('(GMT +6:30) Cocos Islands, Myanmar', '6.5');
+      $select_timezone->add('(GMT +7:00) Bangkok, Hanoi, Jakarta', '7');
+      $select_timezone->add('(GMT +8:00) Beijing, Perth, Singapore, Taipei', '8');
+      $select_timezone->add('(GMT +8:45) Caiguna, Eucla, Border Village', '8.75');
+      $select_timezone->add('(GMT +9:00) Tokyo, Seoul, Yakutsk', '9');
+      $select_timezone->add('(GMT +9:30) Adelaide, Darwin', '9.5');
+      $select_timezone->add('(GMT +10:00) EAST/AEST: Sydney, Guam, Vladivostok', '10');
+      $select_timezone->add('(GMT +10:30) New South Wales', '10.5');
+      $select_timezone->add('(GMT +11:00) Magadan, Solomon Islands', '11');
+      $select_timezone->add('(GMT +11:30) Norfolk Island', '11.5');
+      $select_timezone->add('(GMT +12:00) Auckland, Wellington, Kamchatka', '12');
+      $select_timezone->add('(GMT +12:45) Chatham Islands', '12.75');
+      $select_timezone->add('(GMT +13:00) Tonga, Pheonix Islands', '13');
+      $select_timezone->add('(GMT +14:00) Kiribati', '14');
+
+      $blocks['main']['options']['timezone'] = array(
+        'title' => html::label($field_id, Q(rcube_label('timezone'))),
+        'content' => $select_timezone->show((string)$config['timezone']),
+      );
+    }
+
+    // daylight savings
+    if (!isset($no_override['dst_active'])) {
+      $field_id = 'rcmfd_dst';
+      $input_dst = new html_checkbox(array('name' => '_dst_active', 'id' => $field_id, 'value' => 1, 'disabled' => ($config['timezone'] === 'auto')));
+
+      $blocks['main']['options']['dstactive'] = array(
+        'title' => html::label($field_id, Q(rcube_label('dstactive'))),
+        'content' => $input_dst->show($config['dst_active']),
+      );
+    }
+
+    // MM: Show checkbox for toggling 'pretty dates' 
+    if (!isset($no_override['prettydate'])) {
+      $field_id = 'rcmfd_prettydate';
+      $input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['prettydate'] = array(
+        'title' => html::label($field_id, Q(rcube_label('prettydate'))),
+        'content' => $input_prettydate->show($config['prettydate']?1:0),
+      );
+    }
+
+    // show page size selection
+    if (!isset($no_override['pagesize'])) {
+      $field_id = 'rcmfd_pgsize';
+      $input_pagesize = new html_inputfield(array('name' => '_pagesize', 'id' => $field_id, 'size' => 5));
+
+      $blocks['list']['options']['pagesize'] = array(
+        'title' => html::label($field_id, Q(rcube_label('pagesize'))),
+        'content' => $input_pagesize->show($config['pagesize']),
+      );
+    }
+
+    // Show checkbox for toggling 'index_sort' 
+    if (!isset($no_override['index_sort'])) {
+      $field_id = 'rcmfd_indexsort';
+      $input_indexsort = new html_checkbox(array('name' => '_index_sort', 'id' => $field_id, 'value' => 1));
+
+      $blocks['list']['options']['index_sort'] = array(
+        'title' => html::label($field_id, Q(rcube_label('indexsort'))),
+        'content' => $input_indexsort->show($config['index_sort']?1:0),
+      );
+    }
+
+    // show drop-down for available skins
+    if (!isset($no_override['skin'])) {
+      $skins = rcmail_get_skins();
+
+      if (count($skins) > 1) {
+        $field_id = 'rcmfd_skin';
+        $input_skin = new html_select(array('name'=>'_skin', 'id'=>$field_id));
+
+        foreach($skins as $skin)
+          $input_skin->add($skin, $skin);
+
+        $blocks['main']['options']['skin'] = array(
+          'title' => html::label($field_id, Q(rcube_label('skin'))),
+          'content' => $input_skin->show($config['skin']),
+        );
+      }
+    }
+    
+    break;    
+    
+    // Mailbox view (mail screen)
+    case 'mailbox':
+    
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+      'new_message' => array('name' => Q(rcube_label('newmessage'))),
+    );
+
+    // show config parameter for preview pane
+    if (!isset($no_override['preview_pane'])) {
+      $field_id = 'rcmfd_preview';
+      $input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['preview_pane'] = array(
+        'title' => html::label($field_id, Q(rcube_label('previewpane'))),
+        'content' => $input_preview->show($config['preview_pane']?1:0),
+      );
+    }
+
+    if (!isset($no_override['mdn_requests'])) {
+      $field_id = 'rcmfd_mdn_requests';
+      $select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
+      $select_mdn_requests->add(rcube_label('askuser'), 0);
+      $select_mdn_requests->add(rcube_label('autosend'), 1);
+      $select_mdn_requests->add(rcube_label('ignore'), 2);
+
+      $blocks['main']['options']['mdn_requests'] = array(
+        'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
+        'content' => $select_mdn_requests->show($config['mdn_requests']),
+      );
+    }
+
+    if (!isset($no_override['focus_on_new_message'])) {
+      $field_id = 'rcmfd_focus_on_new_message';
+      $input_focus_on_new_message = new html_checkbox(array('name' => '_focus_on_new_message', 'id' => $field_id, 'value' => 1));
+
+      $blocks['new_message']['options']['focus_on_new_message'] = array(
+        'title' => html::label($field_id, Q(rcube_label('focusonnewmessage'))),
+        'content' => $input_focus_on_new_message->show($config['focus_on_new_message']?1:0),
+      );
+    }
+
+    if (!isset($no_override['keep_alive'])) {
+      $field_id = 'rcmfd_keep_alive';
+      $select_keep_alive = new html_select(array('name' => '_keep_alive', 'id' => $field_id));
+
+      foreach(array(1, 3, 5, 10, 15, 30, 60) as $min)
+        if((!$config['min_keep_alive'] || $config['min_keep_alive'] <= $min * 60)
+            && (!$config['session_lifetime'] || $config['session_lifetime'] > $min)) {
+          $select_keep_alive->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min);
+        }
+
+      $blocks['new_message']['options']['keep_alive'] = array(
+        'title' => html::label($field_id, Q(rcube_label('keepalive'))),
+        'content' => $select_keep_alive->show($config['keep_alive']/60),
+      );
+    }
+
+    if (!isset($no_override['check_all_folders'])) {
+      $field_id = 'rcmfd_check_all_folders';
+      $input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
+
+      $blocks['new_message']['options']['check_all_folders'] = array(
+        'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
+        'content' => $input_check_all->show($config['check_all_folders']?1:0),
+      );
+    }
+
+    break;
+    
+    // Message viewing
+    case 'mailview':
+    
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+    );
+
+    // show checkbox for HTML/plaintext messages
+    if (!isset($no_override['prefer_html'])) {
+      $field_id = 'rcmfd_htmlmsg';
+      $input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
+        'onchange' => JS_OBJECT_NAME.'.toggle_prefer_html(this)'));
+
+      $blocks['main']['options']['prefer_html'] = array(
+        'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
+        'content' => $input_preferhtml->show($config['prefer_html']?1:0),
+      );
+    }
+
+    if (!isset($no_override['show_images'])) {
+      $field_id = 'rcmfd_show_images';
+      $input_show_images = new html_select(array('name' => '_show_images', 'id' => $field_id));
+      $input_show_images->add(rcube_label('never'), 0);
+      $input_show_images->add(rcube_label('fromknownsenders'), 1);
+      $input_show_images->add(rcube_label('always'), 2);
+
+      $blocks['main']['options']['show_images'] = array(
+        'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
+        'content' => $input_show_images->show($config['show_images']),
+      );
+    }
+
+    if (!isset($no_override['inline_images'])) {
+      $field_id = 'rcmfd_inline_images';
+      $input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['inline_images'] = array(
+        'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
+        'content' => $input_inline_images->show($config['inline_images']?1:0),
+      );
+    }
+
+    // "display after delete" checkbox
+    if (!isset($no_override['display_next'])) {
+      $field_id = 'rcmfd_displaynext';
+      $input_displaynext = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['display_next'] = array(
+        'title' => html::label($field_id, Q(rcube_label('displaynext'))),
+        'content' => $input_displaynext->show($config['display_next']?1:0),
+      );
+    }
+
+    break;
+    
+    // Mail composition
+    case 'compose':
+    
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+    );
+
+    // Show checkbox for HTML Editor
+    if (!isset($no_override['htmleditor'])) {
+      $field_id = 'rcmfd_htmleditor';
+      $input_htmleditor = new html_checkbox(array('name' => '_htmleditor', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['htmleditor'] = array(
+        'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
+        'content' => $input_htmleditor->show($config['htmleditor']?1:0),
+      );
+    }
+
+    if (!isset($no_override['draft_autosave'])) {
+      $field_id = 'rcmfd_autosave';
+      $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
+      $select_autosave->add(rcube_label('never'), 0);
+      foreach (array(1, 3, 5, 10) as $i => $min)
+        $select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
+
+      $blocks['main']['options']['draft_autosave'] = array(
+        'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
+        'content' => $select_autosave->show($config['draft_autosave']),
+      );
+    }
+
+    if (!isset($no_override['mime_param_folding'])) {
+      $field_id = 'rcmfd_param_folding';
+      $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
+      $select_param_folding->add(rcube_label('2231folding'), 0);
+      $select_param_folding->add(rcube_label('miscfolding'), 1);
+      $select_param_folding->add(rcube_label('2047folding'), 2);
+
+      $blocks['main']['options']['mime_param_folding'] = array(
+       'advanced' => true,
+        'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
+        'content' => $select_param_folding->show($config['mime_param_folding']),
+      );
+    }
+
+    break;
+    
+    // Special IMAP folders
+    case 'folders':
+    
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+    );
+
+    // Configure special folders
+    if (!isset($no_override['default_imap_folders'])) {
+      $RCMAIL->imap_init(true);
+      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true,
+        'maxlength' => 30, 'exceptions' => array('INBOX')));
+
+      if (!isset($no_override['drafts_mbox']))
+        $blocks['main']['options']['drafts_mbox'] = array(
+          'title' => Q(rcube_label('drafts')),
+          'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox")),
+        );
+
+      if (!isset($no_override['sent_mbox']))
+        $blocks['main']['options']['sent_mbox'] = array(
+          'title' => Q(rcube_label('sent')),
+          'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox")),
+       );
+
+      if (!isset($no_override['junk_mbox']))
+        $blocks['main']['options']['junk_mbox'] = array(
+          'title' => Q(rcube_label('junk')),
+          'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox")),
+       );
+
+      if (!isset($no_override['trash_mbox']))
+        $blocks['main']['options']['trash_mbox'] = array(
+          'title' => Q(rcube_label('trash')),
+          'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox")),
+        );
+    }
+
+    break;
+    
+    // Server settings
+    case 'server':
+    
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+      'maintenance' => array('name' => Q(rcube_label('maintenance'))),
+    );
+
+    if (!isset($no_override['read_when_deleted'])) {
+      $field_id = 'rcmfd_read_deleted';
+      $input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['read_when_deleted'] = array(
+        'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
+        'content' => $input_readdeleted->show($config['read_when_deleted']?1:0),
+      );
+    }
+
+    if (!isset($no_override['flag_for_deletion'])) {
+      $field_id = 'rcmfd_flag_for_deletion';
+      $input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['flag_for_deletion'] = array(
+        'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
+        'content' => $input_flagfordeletion->show($config['flag_for_deletion']?1:0),
+      );
+    }
+
+    // don't show deleted messages
+    if (!isset($no_override['skip_deleted'])) {
+      $field_id = 'rcmfd_skip_deleted';
+      $input_purge = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['skip_deleted'] = array(
+        'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
+        'content' => $input_purge->show($config['skip_deleted']?1:0),
+      );
+    }
+
+    // Trash purging on logout
+    if (!isset($no_override['logout_purge'])) {
+      $field_id = 'rcmfd_logout_purge';
+      $input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
+
+      $blocks['maintenance']['options']['logout_purge'] = array(
+        'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
+        'content' => $input_purge->show($config['logout_purge']?1:0),
+      );
+    }
+
+    // INBOX compacting on logout
+    if (!isset($no_override['logout_expunge'])) {
+      $field_id = 'rcmfd_logout_expunge';
+      $input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
+
+      $blocks['maintenance']['options']['logout_expunge'] = array(
+        'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
+        'content' => $input_expunge->show($config['logout_expunge']?1:0),
+      );
+    }
+    
+    break;
+    }
+
+    $data = $RCMAIL->plugins->exec_hook('user_preferences', array('section' => $sect['id'], 'blocks' => $blocks));
+    $found = false;
+    
+    // create output
+    foreach ($data['blocks'] as $block) {
+      if ($block['options']) {
+        foreach ($block['options'] as $option) {
+          $found = true;
+         break 2;
+       }
+      }
+    }
+
+    if (!$found)
+      unset($sections[$idx]);
+    else
+      $sections[$idx]['blocks'] = $data['blocks'];
+  }
+
+  return array($sections, $plugin['cols']);
+}
+
+
+function rcmail_get_skins()
+{
+  $path = 'skins';
+  $skins = array();
+
+  $dir = opendir($path);
+  
+  if (!$dir)
+       return false;
+  
+  while (($file = readdir($dir)) !== false)
+  {
+    $filename = $path.'/'.$file;
+    if (is_dir($filename) && is_readable($filename) 
+       && !in_array($file, array('.', '..', '.svn')))
+      $skins[] = $file;
+  }
+
+  closedir($dir);
+
+  return $skins;
+}
+
+
 // register UI objects
 $OUTPUT->add_handlers(array(
   'prefsframe' => 'rcmail_preferences_frame',
index 0653d8f9ef997c3e11802b63bda2800372f12c96..ebcd090f0f2e8abeaafa06c48adf83b37e443d1a 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: save_prefs.inc 2873 2009-08-27 06:18:54Z thomasb $
+ $Id: save_prefs.inc 2983 2009-09-23 12:32:09Z alec $
 
 */
 
@@ -32,6 +32,7 @@ switch ($CURR_SECTION)
       'timezone'     => isset($_POST['_timezone']) ? (is_numeric($_POST['_timezone']) ? floatval($_POST['_timezone']) : get_input_value('_timezone', RCUBE_INPUT_POST)) : $CONFIG['timezone'],
       'dst_active'   => isset($_POST['_dst_active']) ? TRUE : FALSE,
       'pagesize'     => is_numeric($_POST['_pagesize']) ? max(2, intval($_POST['_pagesize'])) : $CONFIG['pagesize'],
+      'index_sort'   => isset($_POST['_index_sort']) ? TRUE : FALSE,
       'prettydate'   => isset($_POST['_pretty_date']) ? TRUE : FALSE,
       'skin'        => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
     );
index 45dcf9bc4c2b2b0e099240dd006a9eb66e6614b6..4d831f84cd96cba4e32e3f5f730d3660f048811d 100644 (file)
   background-color: #FFFFA6;
 }
 
-
 #contacts-table
 {
   width: 100%;
   table-layout: fixed;
 }
 
-
 #contacts-table tbody td
 {
   cursor: default;
 }
 
-
 #contacts-box
 {
   position: absolute;
@@ -219,38 +216,10 @@ body.iframe,
 #contact-frame
 {
   border: none;
-/* visibility: hidden; */
-}
-
-#contact-title, #groups-title
-{
-  height: 12px !important;
-/*  height: 20px; */
-  padding: 4px 5px 3px 5px;
-  border-bottom: 1px solid #999;
-  color: #333;
-  font-size: 11px;
-  font-weight: bold;
-  background: url('images/listheader.gif') top left repeat-x #CCC;
-  white-space: nowrap;
-}
-
-#contact-title
-{
-  padding: 4px 10px 3px 10px;
-}
-
-#contact-details
-{
-  padding: 15px 10px 10px 10px;
 }
 
 #contact-details table td.title
 {
-  color: #666;
   font-weight: bold;
   text-align: right;
-  padding-right: 10px;
 }
-
-
index 43b3a92abd9675f4cd8d8daa5aa903a8ef77fda8..eeb316211ab6e47bbee15f2e1f541311d07891ba 100644 (file)
@@ -311,7 +311,7 @@ img
 .boxtitle
 {
   height: 12px !important;
-  padding: 2px 10px 5px 10px;
+  padding: 2px 10px 5px 5px;
   border-bottom: 1px solid #999;
   color: #333;
   font-size: 11px;
@@ -319,6 +319,18 @@ img
   background: url('images/listheader.gif') top left repeat-x #CCC;
 }
 
+.boxcontent
+{
+  padding: 15px 10px 10px 10px;
+}
+
+.boxcontent table td.title
+{
+  color: #666;
+  padding-right: 10px;
+}
+
+
 /***** common table settings ******/
 
 table.records-table thead tr td
@@ -500,9 +512,7 @@ a.rcmContactAddress:hover
 
 #login-form table td.title
 {
-  color: #666;
   text-align: right;
-  padding-right: 10px;
   white-space: nowrap;
 }
 
@@ -512,12 +522,78 @@ a.rcmContactAddress:hover
   margin: auto;
 }
 
-#login-form .boxcontent
+#rcmloginuser, #rcmloginpwd, #rcmloginhost
 {
-  padding: 20px 10px 10px 10px;
+  width: 200px;
 }
 
 #console
 {
   opacity: 0.8;
 }
+
+
+/***** onclick menu list *****/
+
+ul.toolbarmenu
+{
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+ul.toolbarmenu li
+{
+  font-size: 11px;
+  white-space: nowrap;
+  min-width: 130px;
+}
+
+ul.toolbarmenu li a
+{
+  display: block;
+  color: #a0a0a0;
+  padding: 2px 8px 3px 22px;
+  text-decoration: none;
+  min-height: 14px;
+}
+
+ul.toolbarmenu li a.active,
+ul.toolbarmenu li a.active:active,
+ul.toolbarmenu li a.active:visited
+{
+  color: #333;
+}
+
+ul.toolbarmenu li input
+{
+  vertical-align: middle;
+}
+
+ul.toolbarmenu li hr
+{
+  color: #ccc;
+  width: 130px;
+  height: 1px;
+  margin: 2px 1px 2px 1px;
+}
+
+ul.toolbarmenu li img
+{
+  float: left;
+  margin: 0 2px;
+}
+
+ul.toolbarmenu li.separator_below
+{
+  border-bottom: 1px solid #ccc;
+  margin-bottom: 2px;
+  padding-bottom: 2px;
+}
+
+ul.toolbarmenu li.separator_above
+{
+  border-top: 1px solid #ccc;
+  margin-top: 2px;
+  padding-top: 2px;
+}
index df8af15af84abb0cb3635e7f537dbddf717bc531..28af2e7e7bb3b5b2177a4332de6d0a9cf21cad8d 100644 (file)
@@ -13,6 +13,7 @@ function rcube_init_settings_tabs()
     tab = '#settingstab' + (rcmail.env.action=='preferences' ? 'default' : (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action.replace(/\./g, '')));
 
   $(tab).addClass('tablink-selected');
+  $(tab + '> a').removeAttr('onclick').unbind('click').bind('click', function(){return false});
 }
 
 function rcube_show_advanced(visible)
index 448bbf9227c613fe9bd4c8d0198bb9844a24939e..e256ea1c53b5bf82081e0e556a373e33855bb91e 100644 (file)
@@ -24,6 +24,11 @@ img
   background-image: url('images/icons/folders.gif');
 }
 
+#attachment-list
+{
+  height: expression(Math.min(16, parseInt(document.documentElement.clientHeight))+'px');
+}
+
 #messagetoolbar a
 {
   display: block;
@@ -50,6 +55,5 @@ ul.toolbarmenu li
 
 ul.toolbarmenu li a
 {
-  float: none;
-  padding: ;
-}
\ No newline at end of file
+  clear: left;
+}
index f074d8b59ed41c5e1711c8895e65a34e2db06b14..784c8d4ef4d3b72d2d594a75afdbb91fdcfa0b1a 100644 (file)
@@ -8,6 +8,11 @@ input, textarea
   background-color: expression(this.type=='checkbox' || this.type=='radio' ? 'transparent' : '#ffffff');
 }
 
+#login-form form
+{
+  margin-top: 0;
+}
+
 .pagenav a.buttonPas
 {
   filter: alpha(opacity=35);
@@ -66,12 +71,24 @@ input, textarea
   background-image: url('images/mail_toolbar.gif');
 }
 
+#listcontrols a.buttonPas,
+#mailboxcontrols a.buttonPas
+{
+  filter: alpha(opacity=35);
+  background-image: url('images/mail_footer.png');
+}
+
 #messagetoolbar select.mboxlist
 {
   margin: 0 8px;
   top: 8px;
 }
 
+#quicksearchbar
+{
+  z-index: 250;
+}
+
 #mainscreen
 {
   width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
@@ -154,17 +171,6 @@ input, textarea
   width: expression((parseInt(this.parentNode.offsetWidth)-20)+'px');
 }
 
-#printmessageframe
-{
-  width: expression((parseInt(document.documentElement.clientWidth)-220)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
-}
-
-#attachment-list
-{
-  height: expression(Math.min(16, parseInt(document.documentElement.clientHeight))+'px');
-}
-
 #countcontrols
 {
   width: 24em;
@@ -251,3 +257,13 @@ ul.toolbarmenu li a
   -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
   filter: alpha(opacity=80);
 }
+
+#countcontrols
+{
+  padding-right: 10px;
+}
+
+table.records-table thead tr td
+{
+  height: 19px;
+}
diff --git a/skins/default/images/display/loading_blue.gif b/skins/default/images/display/loading_blue.gif
new file mode 100644 (file)
index 0000000..2ea6b19
Binary files /dev/null and b/skins/default/images/display/loading_blue.gif differ
diff --git a/skins/default/images/mail_footer.png b/skins/default/images/mail_footer.png
new file mode 100644 (file)
index 0000000..b1b6361
Binary files /dev/null and b/skins/default/images/mail_footer.png differ
index 9a8fdc337ff13ff86f984f47e7ec3d2e644af4c3..4e2cecb8b6afc6b46c95dfee703386c2b33a5b7f 100644 (file)
Binary files a/skins/default/images/mail_toolbar.gif and b/skins/default/images/mail_toolbar.gif differ
index ece87ad5aa4e708d1d196e639b3f24bff8a63bf8..e6f80291b40783474e629f33a8ed50582ee25c66 100644 (file)
Binary files a/skins/default/images/mail_toolbar.png and b/skins/default/images/mail_toolbar.png differ
index 48e48efd86156a5d493a07e7fdc0f5c2f31adaf8..f74ea99834acbb9fd1c01cacef3eb1f19902cc73 100644 (file)
 }
 
 #messagetoolbar a.messagemenu {
-  width: 36px;
   background-position: -288px 0;
 }
 
 #messagetoolbar a.spellcheck {
-  background-position: -386px 0;
+  background-position: -384px 0;
 }
 
 #messagetoolbar a.spellcheckSel {
-  background-position: -386px -32px;
+  background-position: -384px -32px;
 }
 
 #messagetoolbar a.attach {
-  background-position: -354px 0;
+  background-position: -352px 0;
 }
 
 #messagetoolbar a.attachSel {
-  background-position: -354px -32px;
+  background-position: -352px -32px;
+}
+
+#messagetoolbar a.insertsig {
+  background-position: -448px 0;
+}
+
+#messagetoolbar a.insertsigSel {
+  background-position: -448px -32px;
 }
 
 #messagetoolbar a.savedraft {
 }
 
 #messagetoolbar a.send {
-  background-position: -418px 0;
+  background-position: -416px 0;
 }
 
 #messagetoolbar a.sendSel {
-  background-position: -418px -32px;
+  background-position: -416px -32px;
 }
 
 
   width: 172px;
 }
 
-ul.toolbarmenu
-{
-  margin: 0;
-  padding: 0;
-  list-style: none;
-}
-
-ul.toolbarmenu li
-{
-  font-size: 11px;
-  white-space: nowrap;
-  min-width: 130px;
-}
-
-ul.toolbarmenu li a
-{
-  display: block;
-  color: #a0a0a0;
-  padding: 2px 8px 3px 22px;
-  text-decoration: none;
-  min-height: 14px;
-}
-
-ul.toolbarmenu li a.active,
-ul.toolbarmenu li a.active:active,
-ul.toolbarmenu li a.active:visited
-{
-  color: #333;
-}
-
-ul.toolbarmenu li input
-{
-  vertical-align: middle;
-}
-
-ul.toolbarmenu li hr
-{
-  color: #ccc;
-  width: 130px;
-  height: 1px;
-  margin: 2px 1px 2px 1px;
-}
-
-ul.toolbarmenu li img
-{
-  float: left;
-  margin: 0 2px;
-}
-
-ul.toolbarmenu li.separator_below
-{
-  border-bottom: 1px solid #ccc;
-  margin-bottom: 2px;
-  padding-bottom: 2px;
-}
-
-ul.toolbarmenu li.separator_above
-{
-  border-top: 1px solid #ccc;
-  margin-top: 2px;
-  padding-top: 2px;
-}
-
 #messagemenu li a.active:hover,
 #markmessagemenu li a.active:hover
 {
@@ -312,12 +256,6 @@ ul.toolbarmenu li.separator_above
   font-size: 11px;
 }
 
-#listcontrols a,
-#listcontrols a:active,
-#listcontrols a:visited,
-#mailboxcontrols a,
-#mailboxcontrols a:active,
-#mailboxcontrols a:visited,
 td.formlinks a,
 td.formlinks a:visited
 {
@@ -326,46 +264,12 @@ td.formlinks a:visited
   text-decoration: none;
 }
 
-#listcontrols a.active,
-#listcontrols a.active:active,
-#listcontrols a.active:visited,
-#mailboxcontrols a.active,
-#mailboxcontrols a.active:active,
-#mailboxcontrols a.active:visited,
 td.formlinks a,
 td.formlinks a:visited
 {
   color: #CC0000;
 }
 
-#listcontrols a.active:hover,
-#mailboxcontrols a.active:hover
-{
-  text-decoration: underline;
-}
-
-#listcontrols
-{
-  padding-right: 2em;
-}
-
-#messagecountbar
-{
-  position: absolute;
-  bottom: 0px;
-  right: 0px;
-  width: 300px;
-  height: 16px;
-  text-align: right;
-  white-space: nowrap;
-}
-
-#messagecountbar span
-{
-  font-size: 11px;
-  color: #333333;
-}
-
 #mainscreen
 {
   position: absolute;
@@ -391,6 +295,7 @@ td.formlinks a:visited
   left: 170px;
   bottom: 0px;
   right: 0px;
+  min-width: 600px;
 }
 
 #mailrightcontent
@@ -629,48 +534,111 @@ td.formlinks a:visited
   font-weight: normal;
 }
 
-#mailfooter
+#listcontrols,
+#mailboxcontrols
 {
   position: absolute;
+  white-space: nowrap;
   left: 0px;
   bottom: 0px;
-  height: 16px;
-  width: 100%;
+  height: 15px;
+  width: auto;
+  min-width: 300px;
 }
 
-#mailfooter table tr td
+#listcontrols a,
+#listcontrols span,
+#mailboxcontrols a,
+#mailboxcontrols span
 {
-  white-space: nowrap;
-  vertical-align: bottom;
+  display: block;
+  float: left;
+  font-size: 11px;
 }
 
-#mailboxcontrols
+#listcontrols a.button,
+#listcontrols a.buttonPas,
+#mailboxcontrols a.button,
+#mailboxcontrols a.buttonPas
 {
-  position: absolute;
-  left: 0px;
-  bottom: 0px;
-  height: 16px;
-  width: auto;
-  font-size: 11px;
+  display: block;
+  float: left;
+  width: 15px;
+  height: 15px;
+  padding: 0;
+  margin-right: 2px;
+  overflow: hidden;
+  background: url('images/mail_footer.png') 0 0 no-repeat transparent;
+  opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
 }
 
-#listcontrols,
-#countcontrols,
-#quotabox
+#listcontrols a.buttonPas,
+#mailboxcontrols a.buttonPas
 {
-  white-space: nowrap;
-  font-size: 11px;
+  opacity: 0.35;
+}
+
+#mailboxcontrols a.expunge {
+  background-position: 0 0;
+}
+
+#mailboxcontrols a.expungesel {
+  background-position: 0 -15px;
+}
+
+#mailboxcontrols a.purge {
+  background-position: -15px 0;
+}
+
+#mailboxcontrols a.purgesel {
+  background-position: -15px -15px;
+}
+
+#listcontrols a.all {
+  background-position: -30px 0;
+}
+
+#listcontrols a.allsel {
+  background-position: -30px -15px;
+}
+
+#listcontrols a.unread {
+  background-position: -45px 0;
+}
+
+#listcontrols a.unreadsel {
+  background-position: -45px -15px;
+}
+
+#listcontrols a.invert {
+  background-position: -60px 0;
+}
+
+#listcontrols a.invertsel {
+  background-position: -60px -15px;
+}
+
+#listcontrols a.none {
+  background-position: -75px 0;
+}
+
+#listcontrols a.nonesel {
+  background-position: -75px -15px;
 }
 
 #countcontrols
 {
+  height: 15px;
+  position: absolute;
+  bottom: 0;
+  right: 0;
   min-width: 25em;
+  white-space: nowrap;
+  font-size: 11px;
 }
 
 #countcontrols a.button,
-#countcontrols a.buttonPas,
-#messagecountbar a.button,
-#messagecountbar a.buttonPas
+#countcontrols a.buttonPas
 {
   float: right;
 }
@@ -871,19 +839,21 @@ body.messagelist
   color: #CCCCCC;
 }
 
-#quotadisplay
-{
-  color: #666666;
-  font-size: 11px;
-}
-
-#quotadisplay img
-{
-  vertical-align: middle;
-  margin-left: 4px;
+.quota_text {
+  text-align: center;
+  font-size: 10px;
+  color: #666;
   border: 1px solid #999;
+  cursor: default;
 }
-
+.quota_bg { background-color: white; }
+.quota_high { background-color: #F33131; }
+.quota_mid { background-color: #F5AD3C; }
+.quota_low { background-color: #91E164; }
+.quota_text_high { color: white; }
+.quota_text_mid { color: #666; }
+.quota_text_low { color: #666; }
+         
 
 /** message view styles */
 
@@ -900,18 +870,6 @@ body.messagelist
   z-index: 1;
 }
 
-#printmessageframe
-{
-  position: absolute;
-  top: 0px;
-  left: 0px;
-  right: 0px;
-  bottom: 0px;
-  border: 1px solid #999;
-  background-color: #FFF;
-  overflow: auto;
-}
-
 div.messageheaderbox
 {
   margin: 6px 8px 0px 8px;
@@ -1221,7 +1179,7 @@ div.message-htmlpart div.rcmBody
   position: absolute;
   top: 100px;
   left: 20px;
-  width: 170px;
+  width: 175px;
 }
 
 #compose-attachments ul
@@ -1254,8 +1212,12 @@ div.message-htmlpart div.rcmBody
 
 #attachment-title
 {
+  color: #666666;
+  font-weight: bold;
+  font-size: 11px;
   background: url(images/icons/attachment.png) top left no-repeat;
-  padding: 0px 0px 3px 22px;
+  padding: 0px 0px 3px 18px;
+  margin-left: 3px;
 }
 
 #attachment-form
index 5522a05c9de32d379b8f1c00f9f60e0a3aafdb13..dada599cd949ca59b5269b0ad7002d9e3357f6f1 100644 (file)
@@ -31,11 +31,6 @@ a, a:active, a:visited
   margin: 0 5mm 3mm 5mm;
 }
 
-#messageframe
-{
-  position: relative;
-}
-
 table.headers-table
 {
   table-layout: fixed;
index 74388a4b6504048a7222d421b79054182cb13071..b08a85fa07eb6c9b7e3ab966f7be8e7b26089c94 100644 (file)
@@ -42,6 +42,7 @@ span.tablink-selected a
 span.tablink-selected a
 {
   color: #000000;
+  cursor: default;
 }
 
 #rcmfd_timezone
@@ -199,10 +200,8 @@ span.tablink-selected a
 
 #identity-details table td.title
 {
-  color: #666666;
   font-weight: bold;
   text-align: right;
-  padding-right: 10px;
 }
 
 input.disabled
@@ -219,19 +218,6 @@ input.disabled
   bottom: 20px;
 }
 
-#identity-title,
-#prefs-title,
-div.boxtitle
-{
-  height: 12px !important;
-  padding: 2px 10px 5px 10px;
-  border-bottom: 1px solid #999999;
-  color: #333333;
-  font-size: 11px;
-  font-weight: bold;
-  background: url('images/listheader.gif') top left repeat-x #CCC;
-}
-
 div.settingsbox
 {
   width: 600px;
@@ -239,12 +225,6 @@ div.settingsbox
   border: 1px solid #999999;
 }
 
-div.settingspart
-{
-  display: block;
-  padding: 10px;
-}
-
 fieldset 
 {
   margin-bottom: 0.5em;
@@ -305,17 +285,6 @@ body.iframe,
   border: none;
 }
 
-#prefs-details
-{
-  margin: 15px;
-}
-
-#prefs-details table td.title
-{
-  color: #666;
-  padding-right: 10px;
-}
-
 #formfooter
 {
   width: 100%;
@@ -323,14 +292,14 @@ body.iframe,
 
 #formfooter .footerleft
 {
-  padding-left: 20px;
+  padding-left: 15px;
   white-space: nowrap;
   float: left;
 }
 
 #formfooter .footerright
 {
-  padding-right: 20px;
+  padding-right: 15px;
   white-space: nowrap;
   text-align: right;
   float: right;
index 83506eecb1290789be1fa283e3dfba9b359ce5b1..b9318c0afb2e7cfb62bce8bd3552f842c75abfb7 100644 (file)
@@ -75,7 +75,7 @@ function rcube_splitter(attrib)
       this.layer.move(this.layer.x, Math.round(this.pos - lh / 2 + 1));
       if (bw.ie)
         {
-        var new_height = (parseInt(this.p2.parentNode.offsetHeight) - parseInt(this.p2.style.top));
+        var new_height = (parseInt(this.p2.parentNode.offsetHeight) - parseInt(this.p2.style.top) - (bw.ie8 ? 2 : 0));
         this.p2.style.height = (new_height > 0 ? new_height : 0) +'px';
         }
       }
@@ -228,7 +228,7 @@ function rcube_splitter(attrib)
     {
     if (this.horizontal)
       {
-      var new_height = (parseInt(this.p2.parentNode.offsetHeight) - parseInt(this.p2.style.top));
+      var new_height = (parseInt(this.p2.parentNode.offsetHeight) - parseInt(this.p2.style.top) - (bw.ie8 ? 2 : 0));
       this.p2.style.height = (new_height > 0 ? new_height : 0) +'px';
       }
     else
index 3b18ec5e742b600648efe1f36643dc1b8c27ed4d..08f5ca2b13635ec53188cb439387b8516983c80d 100644 (file)
@@ -8,7 +8,7 @@
 
 <div id="contact-title" class="boxtitle"><roundcube:label name="addcontact" /></div>
 
-<div id="contact-details">
+<div id="contact-details" class="boxcontent">
 <roundcube:object name="contacteditform" size="40" />
 
 <p><br />
index b0325b5afec758e70119893d154e848451aec29f..28bfb86378d5fb38db98dbd3d5bf69b58291b4c9 100644 (file)
@@ -47,7 +47,7 @@
 
 <roundcube:if condition="count(env:address_sources) &gt; 1" />
 <div id="directorylist">
-<div id="groups-title"><roundcube:label name="groups" /></div>
+<div id="groups-title" class="boxtitle"><roundcube:label name="groups" /></div>
 <roundcube:object name="directorylist" id="directories-list" />
 </div>
 <roundcube:endif />
@@ -72,7 +72,7 @@
 <div id="abookcountbar" class="pagenav">
   <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstpage" content=" " />
   <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previouspage" content=" " />
-  <roundcube:object name="recordsCountDisplay" style="padding:0 1em; float:left" />
+  <roundcube:object name="recordsCountDisplay" style="padding:0 .5em; float:left" />
   <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextpage" content=" " />
   <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastpage" content=" " />
 </div>
index 7a5aa8dc6f248766f720519ae0812e37b90ce5fc..d2b36e045c95c2711e272c600887a54f0a1a5574 100644 (file)
@@ -21,6 +21,7 @@
       <roundcube:button command="spellcheck" type="link" class="buttonPas spellcheck" classAct="button spellcheck" classSel="button spellcheckSel" title="checkspelling" content=" " />
       <roundcube:button command="add-attachment" type="link" class="buttonPas attach" classAct="button attach" classSel="button attachSel" title="addattachment" content=" " />
       <roundcube:button command="savedraft" type="link" class="buttonPas savedraft" classAct="button savedraft" classSel="button savedraftSel" title="savemessage" content=" " />
+      <roundcube:container name="toolbar" id="compose-toolbar" />
     </td>
     <td id="priority-selector">
       <label for="rcmcomposepriority"><roundcube:label name="priority" />:</label>&nbsp;<roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" />
 
 <div id="compose-attachments">
 <div id="attachment-title"><roundcube:label name="attachments" /></div>
-<roundcube:object name="composeAttachmentList" deleteIcon="/images/icons/delete.png" />
+<roundcube:object name="composeAttachmentList" deleteIcon="/images/icons/delete.png" cancelIcon="/images/icons/delete.png" loadingIcon="/images/display/loading_blue.gif" />
 <p><roundcube:button command="add-attachment" imagePas="/images/buttons/add_pas.png" imageSel="/images/buttons/add_sel.png" imageAct="/images/buttons/add_act.png" width="23" height="18" title="addattachment" /></p>
 </div>
 
 </form>
 
-<roundcube:object name="composeAttachmentForm" id="attachment-form" />
+<roundcube:object name="composeAttachmentForm" id="attachment-form" attachmentFieldSize="40" />
 
 </body>
 </html>
index 1fc1237f805865999a7520631940223818a9c216..44111959ea724d6e393da7b342ea8d394b8911ec 100644 (file)
@@ -8,7 +8,7 @@
 
 <div id="contact-title" class="boxtitle"><roundcube:label name="editcontact" /></div>
 
-<div id="contact-details">
+<div id="contact-details" class="boxcontent">
 <roundcube:object name="contacteditform" size="40" />
 
 <p><br />
index deff97990989ffe268cde2a7ec22f8c8ab8fe319..0cfec60d9fdf45fc301e898f64a68a3965758888 100644 (file)
@@ -20,9 +20,9 @@
 </p>
 
 <div id="identity-details">
-<div id="identity-title"><roundcube:object name="steptitle" /></div>
+<div id="identity-title" class="boxtitle"><roundcube:object name="steptitle" /></div>
 
-<div style="padding:15px;">
+<div class="boxcontent">
 <roundcube:object name="identityform" size="40" textareacols="60" textarearows="6" />
 
 <p><br />
index 9eff968745083e27d789e543de7ee105886dcca1..83ab4ab3d4a55e87600e918b06dcc7f91b2a99c6 100644 (file)
@@ -12,7 +12,7 @@
 <div id="importbox">
 <div class="boxtitle"><roundcube:label name="importcontacts" /></div>
 
-<div style="padding-left:12px; width:48em">
+<div class="boxcontent">
 <roundcube:object name="importstep" />
 
 <p><br />
index 2d16f62bf339f2e31d40b7b3eb3d5b6a941a3ead..db2f4fe16df857b162024fea90f468b14f0cbce1 100644 (file)
 </script>
 
 <div id="mailboxcontrols">
-  <roundcube:label name="folder" />:&nbsp;
-  <roundcube:button command="expunge" label="compact" classAct="active" />&nbsp;
-  <roundcube:button command="purge" label="empty" classAct="active" />&nbsp;
+  <span><roundcube:label name="folder" />:&nbsp;</span>
+  <roundcube:button command="expunge" type="link" title="compact" class="buttonPas expunge" classAct="button expunge" classSel="button expungesel" content=" " />
+  <roundcube:button command="purge" type="link" title="empty" class="buttonPas purge" classAct="button purge" classSel="button purgesel" content=" " />
+  <roundcube:container name="mailboxcontrols" id="mailboxcontrols" />
 </div>
 </div>
 
 <roundcube:endif />
 </div>
 
-<div id="mailfooter">
-<table cellpadding="1" cellspacing="0" width="100%"><tr>
-  <td>
-    <span id="listcontrols">
-      <roundcube:label name="select" />:&nbsp;
-      <roundcube:button command="select-all" label="all" classAct="active" />&nbsp;
-      <roundcube:button command="select-all" prop="unread" label="unread" classAct="active" />&nbsp;
-      <roundcube:button command="select-all" prop="invert" label="invert" classAct="active" />&nbsp;
-      <roundcube:button command="select-none" label="none" classAct="active" /> &nbsp;
+<div id="listcontrols">
+      <span><roundcube:label name="select" />:&nbsp;</span>
+      <roundcube:button command="select-all" type="link" title="all" class="buttonPas all" classAct="button all" classSel="button allsel" content=" " />
+      <roundcube:button command="select-all" type="link" prop="unread" title="unread" class="buttonPas unread" classAct="button unread" classSel="button unreadsel" content=" " />
+      <roundcube:button command="select-all" type="link" prop="invert" title="invert" class="buttonPas invert" classAct="button invert" classSel="button invertsel" content=" " />
+      <roundcube:button command="select-none" type="link" title="none" class="buttonPas none" classAct="button none" classSel="button nonesel" content=" " />
       <roundcube:container name="listcontrols" id="listcontrols" />
-    </span>
-  </td>
   <roundcube:if condition="env:quota" />
-  <td style="text-align:center">
-    <span id="quotabox"><roundcube:label name="quota" />: <roundcube:object name="quotaDisplay" display="image" width="100" id="quotadisplay" /></span>
-  </td>
+  <span style="margin-left: 20px; margin-right: 5px"><roundcube:label name="quota" />:</span>
+  <roundcube:object name="quotaDisplay" display="image" width="100" height="14" id="quotadisplay" />
   <roundcube:endif />
-  <td id="countcontrols" class="pagenav">
+</div>
+
+<div id="countcontrols" class="pagenav">
     <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastmessages" content=" " />
     <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextmessages" content=" " />
-    <roundcube:object name="messageCountDisplay" style="padding:0 1em; float:right" />
+    <roundcube:object name="messageCountDisplay" style="padding:0 .5em; float:right" />
     <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previousmessages" content=" " />
     <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstmessages" content=" " />
-  </td>
-</tr></table>
 </div>
 
 </div>
 </div>
 
-
 <div id="messagetoolbar">
 <roundcube:button command="checkmail" type="link" class="button checkmail" classAct="button checkmail" classSel="button checkmailSel" title="checkmail" content=" " />
 <roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
index 80f5df279419869b8f8acbc3b8514f9a48480bdd..97758880abf63904dcfc21c8321d446487c5d661 100644 (file)
@@ -24,7 +24,7 @@
 <div class="settingsbox">
 <div class="boxtitle"><roundcube:label name="createfolder" /></div>
 
-<div class="settingspart">
+<div class="boxcontent">
 <roundcube:label name="foldername" />:&nbsp;
 <roundcube:object name="createfolder" form="subscriptionform" hintbox="rcmailaddfolderhint" />
 <roundcube:button command="create-folder" type="input" class="button" label="create" />
index 852f4b44c9b462fcc7bb572b9bade2b80766f987..fcf55df0b42113a7eb93ffcc931040d05939d65c 100644 (file)
 </div>
 </div>
 
-<div id="messagecountbar" class="pagenav">
+<div id="countcontrols" class="pagenav">
   <roundcube:button command="lastmessage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastmessage" content=" " />
   <roundcube:button command="nextmessage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextmessage" content=" " />
-  <roundcube:object name="messageCountDisplay" style="padding:0 1em 0 1em; float:right" />
+  <roundcube:object name="messageCountDisplay" style="padding:0 .5em; float:right" />
   <roundcube:button command="previousmessage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previousmessage" content=" " />
   <roundcube:button command="firstmessage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstmessage" content=" " />
 </div>
index dcd5c5c2ebf11959fdcf636d1bc2d88a32eb0974..ec980a8f06d63cd1f56e0b0a50e51b91dcde2988 100644 (file)
@@ -9,9 +9,7 @@
 
 <div id="prefs-title" class="boxtitle"><roundcube:object name="sectionname" /></div>
 
-<form name="form" action="./" method="post">
-
-<div id="prefs-details">
+<div id="prefs-details" class="boxcontent">
 <roundcube:object name="userprefs" form="form" />
 </div>
 
 <div class="footerleft">
 <roundcube:button command="save" type="input" class="button mainaction" label="save" />
 </div>
-
 </div>
-<p>&nbsp;</p>
-
-</form>
 
 </body>
 </html>
index e50c6031c4b67f547d399b43355e4e94e44c804d..be663a78b0a1585c1ef607978c3a76bbb76c9b52 100644 (file)
@@ -8,7 +8,7 @@
 
 <div id="contact-title" class="boxtitle"><roundcube:object name="contactdetails" part="name" /></div>
 
-<div id="contact-details">
+<div id="contact-details" class="boxcontent">
 <roundcube:object name="contactdetails" />
 
 <p><br /><roundcube:button command="edit" type="input" class="button" label="editcontact" condition="!ENV:readonly" /></p>