diff --git a/CHANGELOG b/CHANGELOG index 50e454855..9dcc5b0d7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,18 @@ CHANGELOG RoundCube Webmail --------------------------- +2006/03/20 +---------- +- Fixed hard-coded cols selection for sent folder (Bug #1354586) +- Enable some HTML links for use with "open in new window" or "save target" +- Check meta-key instead of ctrl on Macs +- Ignore double clicks when holding down a modifier key +- Fixed reloading of the login page +- Fixed typo in compose template (Bug #1446852) +- Added compose button to message read step (Request #1433288) +- New config parameter for persistent database connections (Bug #1431817) + + 2006/03/14 ---------- - Don't remove internal HTML tags in plaintext messages diff --git a/UPGRADING b/UPGRADING index 47771dbc2..624262d63 100644 --- a/UPGRADING +++ b/UPGRADING @@ -101,3 +101,13 @@ from version 0.1-20051021 $rcmail_config['db_sequence_cache_ids'] = 'cache_ids'; $rcmail_config['db_sequence_message_ids'] = 'message_ids'; + +form version 0.1-beta +---------------------------------------- +- replace index.php +- replace all files in folder /program/ +- replace all files in folder /skins/default/ +- add these lines to /config/db.inc.php + $rcmail_config['db_persistent'] = TRUE; + + diff --git a/index.php b/index.php index 7443aaf81..72a682694 100644 --- a/index.php +++ b/index.php @@ -2,7 +2,7 @@ /* +-----------------------------------------------------------------------+ | RoundCube Webmail IMAP Client | - | Version 0.1-20060314 | + | Version 0.1-20060320 | | | | Copyright (C) 2005, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | @@ -40,14 +40,15 @@ */ -define('RCMAIL_VERSION', '0.1-20060220'); +define('RCMAIL_VERSION', '0.1-20060320'); // define global vars -$INSTALL_PATH = dirname($_SERVER['SCRIPT_FILENAME']); +$CHARSET = 'UTF-8'; $OUTPUT_TYPE = 'html'; $JS_OBJECT_NAME = 'rcmail'; -$CHARSET = 'UTF-8'; +$INSTALL_PATH = dirname($_SERVER['SCRIPT_FILENAME']); +$MAIN_TASKS = array('mail','settings','addressbook','logout'); if (empty($INSTALL_PATH)) $INSTALL_PATH = './'; @@ -331,11 +332,9 @@ if ($_task=='settings') } -// only allow these templates to be included -$valid_tasks = array('mail','settings','addressbook'); - // parse main template -if (in_array($_task, $valid_tasks)) +// only allow these templates to be included +if (in_array($_task, $MAIN_TASKS)) parse_template($_task); diff --git a/program/include/main.inc b/program/include/main.inc index e6a26b773..d3ee5e95c 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -72,7 +72,7 @@ function rcmail_startup($task='mail') // prepare DB connection require_once('include/rcube_'.(empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend']).'.inc'); - $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr']); + $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr'], $CONFIG['db_persistent']); $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql'; $DB->db_connect('w'); @@ -1123,7 +1123,12 @@ function rcube_xml_command($command, $str_attrib, $a_attrib=NULL) // execute object handler function if ($object_handlers[$object] && function_exists($object_handlers[$object])) return call_user_func($object_handlers[$object], $attrib); - + + else if ($object=='productname') + { + $name = !empty($CONFIG['product_name']) ? $CONFIG['product_name'] : 'RoundCube Webmail'; + return rep_specialchars_output($name, 'html', 'all'); + } else if ($object=='pagetitle') { $task = $GLOBALS['_task']; @@ -1151,7 +1156,7 @@ function rcube_xml_command($command, $str_attrib, $a_attrib=NULL) // create and register a button function rcube_button($attrib) { - global $CONFIG, $OUTPUT, $JS_OBJECT_NAME, $BROWSER; + global $CONFIG, $OUTPUT, $JS_OBJECT_NAME, $BROWSER, $COMM_PATH, $MAIN_TASKS; static $sa_buttons = array(); static $s_button_count = 100; @@ -1223,6 +1228,7 @@ function rcube_button($attrib) // register button in the system if ($attrib['command']) + { $OUTPUT->add_script(sprintf("%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');", $JS_OBJECT_NAME, $command, @@ -1232,6 +1238,11 @@ function rcube_button($attrib) $attirb['imagesel'] ? $skin_path.$attirb['imagesel'] : $attrib['classsel'], $attrib['imageover'] ? $skin_path.$attrib['imageover'] : '')); + // make valid href to task buttons + if (in_array($attrib['command'], $MAIN_TASKS)) + $attrib['href'] = ereg_replace('_task=[a-z]+', '_task='.$attrib['command'], $COMM_PATH); + } + // overwrite attributes if (!$attrib['href']) $attrib['href'] = '#'; diff --git a/program/js/app.js b/program/js/app.js index 35afe8671..47137887c 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -7,7 +7,8 @@ | Licensed under the GNU GPL | | | +-----------------------------------------------------------------------+ - | Author: Thomas Bruederli | + | Authors: Thomas Bruederli | + | Charles McNulty | +-----------------------------------------------------------------------+ $Id$ @@ -231,7 +232,7 @@ function rcube_webmail() this.enable_command('logout', true); // disable browser's contextmenus - document.oncontextmenu = function(){ return false; } + // document.oncontextmenu = function(){ return false; } // load body click event document.onmousedown = function(){ return rcube_webmail_client.reset_click(); }; @@ -248,7 +249,7 @@ function rcube_webmail() // start interval for keep-alive/recent_check signal if (this.kepp_alive_interval && this.task=='mail' && this.gui_objects.messagelist) this.kepp_alive_int = setInterval(this.ref+'.check_for_recent()', this.kepp_alive_interval); - else + else if (this.task!='login') this.kepp_alive_int = setInterval(this.ref+'.send_keep_alive()', this.kepp_alive_interval); }; @@ -275,7 +276,7 @@ function rcube_webmail() var keyCode = document.layers ? e.which : document.all ? event.keyCode : document.getElementById ? e.keyCode : 0; var mod_key = this.get_modifier(e); var scroll_to = 0; - + var last_selected_row = this.list_rows[this.last_selected]; if (keyCode == 40) { // down arrow key pressed @@ -1089,6 +1090,7 @@ function rcube_webmail() // onmouseup-handler of message list row this.click_row = function(e, id) { + var mod_key = this.get_modifier(e); // don't do anything (another action processed before) if (this.dont_select) @@ -1098,15 +1100,14 @@ function rcube_webmail() } // unselects currently selected row - if (!this.drag_active && this.in_selection_before==id) { - var mod_key = this.get_modifier(e); + if (!this.drag_active && this.in_selection_before==id) this.select_row(id,mod_key); - } + this.drag_start = false; this.in_selection_before = false; // row was double clicked - if (this.task=='mail' && this.list_rows && this.list_rows[id].clicked) + if (this.task=='mail' && this.list_rows && this.list_rows[id].clicked && !mod_key) { this.show_message(id); return false; @@ -2934,6 +2935,8 @@ function rcube_webmail() }; +/* deprecated methods + // check if Shift-key is pressed on event this.check_shiftkey = function(e) { @@ -2963,22 +2966,29 @@ function rcube_webmail() else return false; } +*/ - -// returns modifier key (constants defined at top of file) + // returns modifier key (constants defined at top of file) this.get_modifier = function(e) { var opcode = 0; - if (e = e || window.event) - { + 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 opcode; + } if (e.cancelBubble) - { + { e.cancelBubble = true; e.returnValue = false; - } + } else if (e.preventDefault) e.preventDefault(); } diff --git a/program/lib/imap.inc b/program/lib/imap.inc index 285022247..bef2de9ed 100644 --- a/program/lib/imap.inc +++ b/program/lib/imap.inc @@ -39,6 +39,7 @@ - Added BCC and REFERENCE to the list of headers to fetch in iil_C_FetchHeaders() - Leave messageID unchanged in iil_C_FetchHeaders() - Avoid stripslahes in iil_Connect() + - Removed
from error messages (better for logging) - Removed some debuggers (echo ...) ********************************************************/ @@ -209,7 +210,7 @@ function iil_C_Authenticate(&$conn, $user, $pass, $encChallenge){ $conn->errorNum = 0; return $conn->fp; }else{ - $conn->error .= 'Authentication failed (AUTH):
"'.htmlspecialchars($line)."\""; + $conn->error .= 'Authentication for '.$user.' failed (AUTH): "'.htmlspecialchars($line)."\""; $conn->errorNum = -2; return false; } @@ -230,7 +231,7 @@ function iil_C_Login(&$conn, $user, $password){ }else{ $result=false; fclose($conn->fp); - $conn->error .= 'Authentication failed (LOGIN):
"'.htmlspecialchars($line)."\""; + $conn->error .= 'Authentication for '.$user.' failed (LOGIN): "'.htmlspecialchars($line)."\""; $conn->errorNum = -2; } return $result; @@ -335,9 +336,9 @@ function iil_Connect($host, $user, $password){ //echo ''; //check input - if (empty($host)) $iil_error .= "Invalid host
\n"; - if (empty($user)) $iil_error .= "Invalid user
\n"; - if (empty($password)) $iil_error .= "Invalid password
\n"; + if (empty($host)) $iil_error .= "Invalid host\n"; + if (empty($user)) $iil_error .= "Invalid user\n"; + if (empty($password)) $iil_error .= "Invalid password\n"; if (!empty($iil_error)) return false; if (!$ICL_PORT) $ICL_PORT = 143; @@ -1576,12 +1577,12 @@ function iil_C_Search(&$conn, $folder, $criteria){ $result_code=iil_ParseResult($line); if ($result_code==0) return $messages; else{ - $conn->error = "iil_C_Search: ".$line."
\n"; + $conn->error = "iil_C_Search: ".$line."\n"; return false; } }else{ - $conn->error = "iil_C_Search: Couldn't select \"$folder\"
\n"; + $conn->error = "iil_C_Search: Couldn't select \"$folder\"\n"; return false; } } @@ -1929,11 +1930,11 @@ function iil_C_Append(&$conn, $folder, &$message){ }while($line[0]!="A"); $result = (iil_ParseResult($line)==0); - if (!$result) $conn->error .= $line."
\n"; + if (!$result) $conn->error .= $line."\n"; return $result; }else{ - $conn->error .= "Couldn't send command \"$request\"
\n"; + $conn->error .= "Couldn't send command \"$request\"\n"; return false; } } @@ -1946,7 +1947,7 @@ function iil_C_AppendFromFile(&$conn, $folder, $path){ $in_fp = false; if (file_exists(realpath($path))) $in_fp = fopen($path, "r"); if (!$in_fp){ - $conn->error .= "Couldn't open $path for reading
\n"; + $conn->error .= "Couldn't open $path for reading\n"; return false; } @@ -1976,11 +1977,11 @@ function iil_C_AppendFromFile(&$conn, $folder, $path){ }while($line[0]!="A"); $result = (iil_ParseResult($line)==0); - if (!$result) $conn->error .= $line."
\n"; + if (!$result) $conn->error .= $line."\n"; return $result; }else{ - $conn->error .= "Couldn't send command \"$request\"
\n"; + $conn->error .= "Couldn't send command \"$request\"\n"; return false; } } diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 865aff0bf..418c52b0a 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -161,7 +161,7 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') // return html for a structured list
    for the mailbox tree function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox, $maxlength, $nestLevel=0) { - global $JS_OBJECT_NAME, $IMAP, $CONFIG, $OUTPUT; + global $JS_OBJECT_NAME, $COMM_PATH, $IMAP, $CONFIG, $OUTPUT; $idx = 0; $out = ''; @@ -190,7 +190,7 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox, $maxlen // add unread message count display if ($unread_count = $IMAP->messagecount($folder['id'], 'RECENT', ($folder['id']==$mbox))) $foldername .= sprintf(' (%d)', $unread_count); - + // make folder name safe for ids and class names $folder_css = $class_name = preg_replace('/[^a-z0-9\-_]/', '', $folder_lc); @@ -204,13 +204,16 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox, $maxlen else if ($folder['id']==$CONFIG['junk_mbox']) $class_name = 'junk'; - $out .= sprintf('
  • %s', + $out .= sprintf('
  • %s', $folder_css, $class_name, $zebra_class, $unread_count ? ' unread' : '', $folder['id']==$mbox ? ' selected' : '', - $folder['id'], + $COMM_PATH, + urlencode($folder['id']), $JS_OBJECT_NAME, $folder['id'], $JS_OBJECT_NAME, @@ -295,9 +298,10 @@ function rcmail_message_list($attrib) $a_sort_cols = array('subject', 'date', 'from', 'to'); // show 'to' instead of from in sent messages - if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols))) + if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols)) + && !array_search('to', $a_show_cols)) $a_show_cols[$f] = 'to'; - + // add col definition $out .= ''; $out .= ''; @@ -478,7 +482,8 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE) $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject'); // show 'to' instead of from in sent messages - if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols))) + if (strtolower($IMAP->get_mailbox_name())=='sent' && ($f = array_search('from', $a_show_cols)) + && !array_search('to', $a_show_cols)) $a_show_cols[$f] = 'to'; // loop through message headers diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc index 992d06f79..49b83772b 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -95,18 +95,13 @@ function rcmail_message_attachments($attrib) $attach_prop['filename'], show_bytes($attach_prop['size'])); else - $out .= sprintf('
  • %s
  • '."\n", + $out .= sprintf('
  • %s
  • '."\n", + $GET_URL, + $attach_prop['part_id'], $JS_OBJECT_NAME, $attach_prop['part_id'], $attach_prop['mimetype'], $attach_prop['filename']); - /* direct link - else - $out .= sprintf('
  • %s
  • '."\n", - $GET_URL, - $attach_prop['part_id'], - $attach_prop['filename']); - */ } $out .= "
";