From 94a8b6e87b507508c33536a4a1297961e6e06462 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Wed, 29 Oct 2014 11:07:35 +0000 Subject: [PATCH 01/44] Get taglist working properly again with updated magicsuggest --- etemplate/js/et2_widget_taglist.js | 4 ++-- etemplate/templates/default/etemplate2.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/etemplate/js/et2_widget_taglist.js b/etemplate/js/et2_widget_taglist.js index 17e143957f..f45faed1d5 100644 --- a/etemplate/js/et2_widget_taglist.js +++ b/etemplate/js/et2_widget_taglist.js @@ -14,7 +14,7 @@ /*egw:uses et2_core_inputWidget; - /phpgwapi/js/jquery/magicsuggest/src/magicsuggest-1.3.1.js; + /phpgwapi/js/jquery/magicsuggest/magicsuggest.js; */ /** @@ -602,4 +602,4 @@ et2_register_widget(et2_taglist_ro, ["taglist_ro","taglist_email_ro", "taglist_a // Require css // TODO: merge into etemplate2.css with all other widgets when done -if(typeof egw != 'undefined') egw(window).includeCSS(egw.webserverUrl + "/phpgwapi/js/jquery/magicsuggest/src/magicsuggest-1.3.1.css"); +if(typeof egw != 'undefined') egw(window).includeCSS(egw.webserverUrl + "/phpgwapi/js/jquery/magicsuggest/magicsuggest.css"); diff --git a/etemplate/templates/default/etemplate2.css b/etemplate/templates/default/etemplate2.css index a53c9fd8c1..9a4998bfde 100644 --- a/etemplate/templates/default/etemplate2.css +++ b/etemplate/templates/default/etemplate2.css @@ -6,7 +6,7 @@ /** * Magic suggest / tag list widget */ -@import url("../../../phpgwapi/js/jquery/magicsuggest/src/magicsuggest-1.3.1.css"); +@import url("../../../phpgwapi/js/jquery/magicsuggest/magicsuggest.css"); /** From e47d4e1dd025f1138fb3e20bca8200a5fd6797eb Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 29 Oct 2014 12:27:44 +0000 Subject: [PATCH 02/44] * eSync: fixed not working sending of mails after 14.1.20141021 package --- mail/inc/class.mail_activesync.inc.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mail/inc/class.mail_activesync.inc.php b/mail/inc/class.mail_activesync.inc.php index 7c1d1ae69a..cdb436abf0 100644 --- a/mail/inc/class.mail_activesync.inc.php +++ b/mail/inc/class.mail_activesync.inc.php @@ -474,7 +474,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($message->headers['from']):$message->headers['from'])) as $addressObject) { if (!$addressObject->valid) continue; if ($this->debugLevel>0) debugLog("Header Sentmail From: ".array2string($addressObject).' vs. '.array2string($message->headers['from'])); - $mailObject->From = $addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''); + $mailObject->From = $addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''); $mailObject->FromName = $addressObject->personal; } */ @@ -483,21 +483,21 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($message->headers["to"]):$message->headers["to"])) as $addressObject) { if (!$addressObject->valid) continue; if ($this->debugLevel>0) debugLog("Header Sentmail To: ".array2string($addressObject) ); - //$mailObject->AddAddress($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + //$mailObject->AddAddress($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); $toMailAddr[] = imap_rfc822_write_address($addressObject->mailbox, $addressObject->host, $addressObject->personal); } // CC foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($message->headers["cc"]):$message->headers["cc"])) as $addressObject) { if (!$addressObject->valid) continue; if ($this->debugLevel>0) debugLog("Header Sentmail CC: ".array2string($addressObject) ); - //$mailObject->AddCC($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + //$mailObject->AddCC($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); $ccMailAddr[] = imap_rfc822_write_address($addressObject->mailbox, $addressObject->host, $addressObject->personal); } // BCC foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($message->headers["bcc"]):$message->headers["bcc"])) as $addressObject) { if (!$addressObject->valid) continue; if ($this->debugLevel>0) debugLog("Header Sentmail BCC: ".array2string($addressObject) ); - //$mailObject->AddBCC($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + //$mailObject->AddBCC($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); $bccMailAddr[] = imap_rfc822_write_address($addressObject->mailbox, $addressObject->host, $addressObject->personal); } /* @@ -505,7 +505,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($message->headers['reply-to']):$message->headers['reply-to'])) as $addressObject) { if (!$addressObject->valid) continue; if ($this->debugLevel>0) debugLog("Header Sentmail REPLY-TO: ".array2string($addressObject) ); - $mailObject->AddReplyTo($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + $mailObject->AddReplyTo($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); } */ // save some headers when forwarding mails (content type & transfer-encoding) @@ -600,7 +600,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send //error_log(__METHOD__.__LINE__.array2string($toMailAddr)); foreach((array)$toMailAddr as $address) { foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($address):$address)) as $addressObject) { - $emailAddress = $addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''); + $emailAddress = $addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''); if ($ClientSideMeetingRequest === true && $allowSendingInvitations == 'sendifnocalnotif' && calendar_boupdate::email_update_requested($emailAddress,(isset($cSMRMethod)?$cSMRMethod:'REQUEST'))) continue; $mailObject->AddAddress($emailAddress, $addressObject->personal); $toCount++; @@ -609,7 +609,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send $ccCount = 0; foreach((array)$ccMailAddr as $address) { foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($address):$address)) as $addressObject) { - $emailAddress = $addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''); + $emailAddress = $addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''); if ($ClientSideMeetingRequest === true && $allowSendingInvitations == 'sendifnocalnotif' && calendar_boupdate::email_update_requested($emailAddress)) continue; $mailObject->AddCC($emailAddress, $addressObject->personal); $ccCount++; @@ -618,7 +618,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send $bccCount = 0; foreach((array)$bccMailAddr as $address) { foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($address):$address)) as $addressObject) { - $emailAddress = $addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''); + $emailAddress = $addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''); if ($ClientSideMeetingRequest === true && $allowSendingInvitations == 'sendifnocalnotif' && calendar_boupdate::email_update_requested($emailAddress)) continue; $mailObject->AddBCC($emailAddress, $addressObject->personal); $bccCount++; @@ -920,7 +920,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send if (count($folderArray) > 0) { foreach((array)$bccMailAddr as $address) { foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($address):$address)) as $addressObject) { - $emailAddress = $addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''); + $emailAddress = $addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''); $mailAddr[] = array($emailAddress, $addressObject->personal); } } @@ -1115,7 +1115,7 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($headers['FROM']):$headers['FROM'])) as $addressObject) { //debugLog(__METHOD__.__LINE__.'Address to add (FROM):'.array2string($addressObject)); if (!$addressObject->valid) continue; - $mailObject->From = $addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''); + $mailObject->From = $addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''); $mailObject->FromName = $addressObject->personal; //error_log(__METHOD__.__LINE__.'Address to add (FROM):'.array2string($addressObject)); } @@ -1123,19 +1123,19 @@ class mail_activesync implements activesync_plugin_write, activesync_plugin_send foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($headers['TO']):$headers['TO'])) as $addressObject) { //debugLog(__METHOD__.__LINE__.'Address to add (TO):'.array2string($addressObject)); if (!$addressObject->valid) continue; - $mailObject->AddAddress($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + $mailObject->AddAddress($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); } // CC foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($headers['CC']):$headers['CC'])) as $addressObject) { //debugLog(__METHOD__.__LINE__.'Address to add (CC):'.array2string($addressObject)); if (!$addressObject->valid) continue; - $mailObject->AddCC($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + $mailObject->AddCC($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); } // AddReplyTo foreach(emailadmin_imapbase::parseAddressList((get_magic_quotes_gpc()?stripslashes($headers['REPLY-TO']):$headers['REPLY-TO'])) as $addressObject) { //debugLog(__METHOD__.__LINE__.'Address to add (ReplyTO):'.array2string($addressObject)); if (!$addressObject->valid) continue; - $mailObject->AddReplyTo($addressObject->mailbox. (!empty($addressObject->host) ? '@'.$addressObject->host : ''),$addressObject->personal); + $mailObject->AddReplyTo($addressObject->mailbox. ($addressObject->host ? '@'.$addressObject->host : ''),$addressObject->personal); } $Header = $Body = ''; // we do not use Header and Body we use the MailObject if ($this->debugLevel>0) debugLog(__METHOD__.__LINE__." Creation of Mailobject succeeded."); From b707bde89f41e986d9260e1f23b6d37e733c4530 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Wed, 29 Oct 2014 15:27:40 +0000 Subject: [PATCH 03/44] When exporting if custom project is not set, use current project title for Project field --- timesheet/inc/class.timesheet_export_csv.inc.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/timesheet/inc/class.timesheet_export_csv.inc.php b/timesheet/inc/class.timesheet_export_csv.inc.php index d184b1e036..f6de975e9c 100644 --- a/timesheet/inc/class.timesheet_export_csv.inc.php +++ b/timesheet/inc/class.timesheet_export_csv.inc.php @@ -83,6 +83,12 @@ class timesheet_export_csv implements importexport_iface_export_plugin { // support other selectors atm. foreach ($selection as $identifier) { $record = new timesheet_egw_record($identifier); + + // If Project is not set, set it to current project title + if(!$record->ts_project && $record->pm_id) + { + $record->ts_project = egw_link::title ('projectmanager', $record->pm_id); + } if($options['convert']) { importexport_export_csv::convert($record, timesheet_egw_record::$types, 'timesheet', $this->selects); } else { From dd6ddebb8028ca60e40309965d485cfe1d3a4c8b Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 29 Oct 2014 16:03:22 +0000 Subject: [PATCH 04/44] delete user by account_id, not account_lid, as there might be a group with same name --- admin/inc/class.admin_account.inc.php | 2 +- admin/inc/class.admin_cmd_delete_account.inc.php | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/admin/inc/class.admin_account.inc.php b/admin/inc/class.admin_account.inc.php index ec301a4b53..913e7f0e3d 100644 --- a/admin/inc/class.admin_account.inc.php +++ b/admin/inc/class.admin_account.inc.php @@ -217,7 +217,7 @@ class admin_account } if ($content['delete']) { - $cmd = new admin_cmd_delete_account(accounts::id2name($content['account_id']), $content['new_owner'], true); + $cmd = new admin_cmd_delete_account($content['account_id'], $content['new_owner'], true); $msg = $cmd->run(); if ($content['contact_id']) { diff --git a/admin/inc/class.admin_cmd_delete_account.inc.php b/admin/inc/class.admin_cmd_delete_account.inc.php index 462ac3c84f..4bf1f7815e 100644 --- a/admin/inc/class.admin_cmd_delete_account.inc.php +++ b/admin/inc/class.admin_cmd_delete_account.inc.php @@ -49,16 +49,16 @@ class admin_cmd_delete_account extends admin_cmd $account_id = admin_cmd::parse_account($this->account,$this->is_user); admin_cmd::_instanciate_accounts(); $account_lid = admin_cmd::$accounts->id2name($account_id); - + if ($this->is_user && $this->new_user) { $new_user = admin_cmd::parse_account($this->new_user,true); // true = user, no group } // check creator is still admin and not explicitly forbidden to edit accounts if ($this->creator) $this->_check_admin($this->is_user ? 'account_access' : 'group_access',32); - + if ($check_only) return true; - + // delete the account $GLOBALS['hook_values'] = array( 'account_id' => $account_id, @@ -71,14 +71,14 @@ class admin_cmd_delete_account extends admin_cmd foreach(array_merge(array_diff(array_keys($GLOBALS['egw_info']['apps']),array('preferences','admin')),array('preferences','admin')) as $app) { $GLOBALS['egw']->hooks->single($GLOBALS['hook_values'],$app); - } + } if (!$this->is_user) $GLOBALS['egw']->accounts->delete($account_id); // groups get not deleted via the admin hook, as users - + if ($account_id < 0) { - return lang("Group '%1' deleted.",$this->account)."\n\n"; + return lang("Group '%1' deleted.",$account_lid)."\n\n"; } - return lang("Account '%1' deleted.",$this->account)."\n\n"; + return lang("Account '%1' deleted.",$account_lid)."\n\n"; } /** From 5098baf5385085f6ac20910c5bc8eca745e2f6d3 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Wed, 29 Oct 2014 17:01:17 +0000 Subject: [PATCH 05/44] Add item modification functionality to magicsuggest's selected items (Only if free entries is allowed) --- .../js/jquery/magicsuggest/magicsuggest.css | 14 +++++- .../js/jquery/magicsuggest/magicsuggest.js | 47 +++++++++++++++---- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/phpgwapi/js/jquery/magicsuggest/magicsuggest.css b/phpgwapi/js/jquery/magicsuggest/magicsuggest.css index 03ecac3814..4750c6b877 100644 --- a/phpgwapi/js/jquery/magicsuggest/magicsuggest.css +++ b/phpgwapi/js/jquery/magicsuggest/magicsuggest.css @@ -217,7 +217,7 @@ cursor: pointer; height: 7px; float: right; - margin: 6px 2px 0 10px; + margin: 2px 2px 0 10px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAOCAYAAADjXQYbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAEZ0FNQQAAsY58+1GTAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABSSURBVHjahI7BCQAwCAOTzpThHMHh3Kl9CVos9XckFwQAuPtGuWTWwMwaczKzyHsqg6+5JqMJr28BABHRwmTWQFJjTmYWOU1L4tdck9GE17dnALGAS+kAR/u2AAAAAElFTkSuQmCC); background-position: 0 -7px; } @@ -227,6 +227,18 @@ .ms-stacked .ms-sel-item .ms-close-btn { margin-left: 0px; } +.ms-sel-ctn .ms-sel-item .ms-edit-btn{ + width: 7px; + cursor: pointer; + height: 7px; + float: right; + margin: 12px -18px 0 10px; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAOCAYAAADjXQYbAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3godECY5jN7oQAAAAJxJREFUGNNtzyFSA1EMgOFvyzpMBVyBE2A6tJJ4nkDguAyCczAdVOpzgUVwCCSCQ2CWmWX7ojLzi+QbrKa1tscLnodVuMUjbrAdFqHhHl+4xuliDk+4wxaXOGbmNLbWdnO4wjemzPyADR7wih98Zub736kRh3l/y8xp+eCwplRVn1JVfUpV9SlVdUaJiGmsqjNKRPQpEdGnRMQ/yi9ivDd/aTuHLAAAAABJRU5ErkJggg=='); + background-position: 0 -7px; +} +.ms-sel-ctn .ms-sel-item .ms-edit-btn:hover{ + background-position: 0 0; +} .ms-helper{ color: #AAA; font-size: 10px; diff --git a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js index 3ff463df70..f52af79f90 100644 --- a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js +++ b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js @@ -635,7 +635,7 @@ { cfg.dataUrlParams = $.extend({},params); }; - + /********** PRIVATE ************/ var _selection = [], // selected objects _comboItemHeight = 0, // height for each combo item. @@ -644,6 +644,7 @@ _groups = null, _cbData = [], _ctrlDown = false, + _cntInMf = false, // Content is in modification mode. KEYCODES = { BACKSPACE: 8, TAB: 9, @@ -1023,7 +1024,7 @@ $.each(_selection, function(index, value){ - var selectedItemEl, delItemEl, + var selectedItemEl, delItemEl,editItemEl, selectedItemHtml = cfg.selectionRenderer !== null ? cfg.selectionRenderer.call(ref, value) : value[cfg.displayField]; var validCls = self._validateSingleItem(value[cfg.displayField]) ? '' : ' ms-sel-invalid'; @@ -1048,6 +1049,13 @@ }).data('json', value).appendTo(selectedItemEl); delItemEl.click($.proxy(handlers._onTagTriggerClick, ref)); + if (cfg.allowFreeEntries === true){ + // small pen img + editItemEl = $('', { + 'class': 'ms-edit-btn' + }).data('json', value).appendTo(selectedItemEl); + editItemEl.click($.proxy(handlers._onTagEditTriggerClick, ref)); + } } } @@ -1215,7 +1223,7 @@ } } return true; - } + } }; var handlers = { @@ -1226,6 +1234,7 @@ _onBlur: function() { ms.container.removeClass('ms-ctn-focus'); ms.collapse(); + _cntInMf = false; _hasFocus = false; if(ms.getRawValue() !== '' && cfg.allowFreeEntries === true){ var obj = {}; @@ -1275,8 +1284,15 @@ * Triggered when focusing on the container div. Will focus on the input field instead. * @private */ - _onFocus: function() { - ms.input.focus(); + _onFocus: function(e) { + if (!_cntInMf) + { + ms.input.focus(); + } + else + { + _cntInMf = false; + } }, /** @@ -1284,7 +1300,7 @@ * @private */ _onInputClick: function(){ - if (ms.isDisabled() === false && _hasFocus) { + if (ms.isDisabled() === false && _hasFocus && !_cntInMf) { if (cfg.toggleOnClick === true) { if (cfg.expanded){ ms.collapse(); @@ -1300,7 +1316,7 @@ * @private */ _onInputFocus: function() { - if(ms.isDisabled() === false && !_hasFocus) { + if(ms.isDisabled() === false && !_hasFocus && !_cntInMf) { _hasFocus = true; ms.container.addClass('ms-ctn-focus'); ms.container.removeClass(cfg.invalidCls); @@ -1478,7 +1494,22 @@ _onTagTriggerClick: function(e) { ms.removeFromSelection($(e.currentTarget).data('json')); }, - + + /** + * Triggerd whem clicking upon edit icon (pen) for modification + * @param e + * @private + */ + _onTagEditTriggerClick: function(e) { + var itemData = $(e.currentTarget).data('json'); + if (ms.input.val() === '') + { + ms.input.val(itemData.label); + ms.removeFromSelection(itemData); + _cntInMf = true; + } + }, + /** * Triggered when clicking on the small trigger in the right * @private From 2fe71bdc48f2a6f46b026d536fddcea13ea93d8e Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Wed, 29 Oct 2014 17:15:14 +0000 Subject: [PATCH 06/44] Cancel d-n-d action on taglist item edit button --- mail/js/app.js | 23 ++++++++++++----------- mail/templates/pixelegg/app.css | 4 +++- mail/templates/pixelegg/app.less | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/mail/js/app.js b/mail/js/app.js index 30f593afc6..e97b83b13f 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -3936,9 +3936,9 @@ app.classes.mail = AppJS.extend( set_dragging_dndCompose: function () { var zIndex = 100; - var self = this; - - jQuery('div.ms-sel-item:not(div.ui-draggable)').draggable({ + var dragItem = jQuery('div.ms-sel-item:not(div.ui-draggable)'); + + dragItem.draggable({ appendTo:'body', //Performance wise better to not add ui-draggable class to items since we are not using that class containment:'document', @@ -3946,7 +3946,7 @@ app.classes.mail = AppJS.extend( cursor:'move', cursorAt:{left:2}, //cancel dragging on close button to avoid conflict with close action - cancel:'.ms-close-btn', + cancel:'.ms-close-btn, .ms-edit-btn', /** * function to act on draggable item on revert's event * @returns {Boolean} return true @@ -3963,14 +3963,14 @@ app.classes.mail = AppJS.extend( */ start:function(event, ui) { - if (event.ctrlKey) + var dragItem = jQuery(this); + if (event.ctrlKey || event.metaKey) { - jQuery(this) - .addClass('mailCompose_copyEmail') + dragItem.addClass('mailCompose_copyEmail') .css('cursor','copy'); } - jQuery(this).css ('z-index',zIndex++); - jQuery(this).css('position','absolute'); + dragItem.css ('z-index',zIndex++); + dragItem.css('position','absolute'); }, /** * @@ -3992,12 +3992,13 @@ app.classes.mail = AppJS.extend( { var self = this; + var emailTags = jQuery('#mail-compose_to,#mail-compose_cc,#mail-compose_bcc'); //Call to make new items draggable - jQuery('#mail-compose_to,#mail-compose_cc,#mail-compose_bcc').hover(function(){ + emailTags.hover(function(){ self.set_dragging_dndCompose(); }); //Make used email-tag list widgets in mail compose droppable - jQuery('#mail-compose_to,#mail-compose_cc,#mail-compose_bcc').droppable({ + emailTags.droppable({ access:'.ms-sel-item', /** diff --git a/mail/templates/pixelegg/app.css b/mail/templates/pixelegg/app.css index 0226c8b39c..de85914d55 100755 --- a/mail/templates/pixelegg/app.css +++ b/mail/templates/pixelegg/app.css @@ -1310,7 +1310,9 @@ div#mail-index div#mail-index_mailPreview div#mail-index_mailPreviewHeadersSubje padding-right: 5px; } #mail-compose .mailComposeHeaders span.ms-close-btn, -#mail-compose .mailComposeHeadersSection span.ms-close-btn { +#mail-compose .mailComposeHeadersSection span.ms-close-btn, +#mail-compose .mailComposeHeaders span.ms-edit-btn, +#mail-compose .mailComposeHeadersSection span.ms-edit-btn { width: auto; background-repeat: no-repeat; padding-right: 8px; diff --git a/mail/templates/pixelegg/app.less b/mail/templates/pixelegg/app.less index e0bfb8a3d5..36dcbba42e 100755 --- a/mail/templates/pixelegg/app.less +++ b/mail/templates/pixelegg/app.less @@ -569,7 +569,7 @@ div#mail-index{ padding-right: 5px; } - span.ms-close-btn { + span.ms-close-btn, span.ms-edit-btn{ width: auto; background-repeat: no-repeat; padding-right: 8px; From c917cbd8652292d2c87fc3c6f8981bb0a31dc366 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Wed, 29 Oct 2014 23:03:35 +0000 Subject: [PATCH 07/44] Link enhancements: - Add confirm dialog to delete link - Log unlinking files into historylog --- etemplate/js/et2_widget_link.js | 23 ++++++++++++++++++----- phpgwapi/inc/class.egw_link.inc.php | 9 +++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/etemplate/js/et2_widget_link.js b/etemplate/js/et2_widget_link.js index 2b1be8c0a3..c56b353539 100644 --- a/etemplate/js/et2_widget_link.js +++ b/etemplate/js/et2_widget_link.js @@ -1533,7 +1533,10 @@ var et2_link_list = et2_link_string.extend( this.context.addItem("delete", this.egw().lang("Delete link"), this.egw().image("delete"), function(menu_item) { var link_id = isNaN(self.context.data.link_id) ? self.context.data : self.context.data.link_id; var row = jQuery('#link_'+(self.context.data.dom_id ? self.context.data.dom_id : self.context.data.link_id), self.list); - self._delete_link(link_id, row); + et2_dialog.show_dialog( + function(button) { debugger; if(button == et2_dialog.YES_BUTTON) self._delete_link(link_id,row);}, + egw.lang('Delete link?') + ); }); // Native DnD - Doesn't play nice with jQueryUI Sortable @@ -1660,10 +1663,20 @@ var et2_link_list = et2_link_string.extend( .appendTo(delete_button) // We don't use ui-icon because it assigns a bg image .addClass("delete icon") - .bind( 'click', function() {self._delete_link( - self.value && typeof self.value.to_id != 'object' && _link_data.link_id ? _link_data.link_id:_link_data, - row - );}); + .bind( 'click', function() { + et2_dialog.show_dialog( + function(button) { + if(button == et2_dialog.YES_BUTTON) + { + self._delete_link( + self.value && typeof self.value.to_id != 'object' && _link_data.link_id ? _link_data.link_id:_link_data, + row + ); + } + }, + egw.lang('Delete link?') + ); + }); // Context menu row.bind("contextmenu", function(e) { diff --git a/phpgwapi/inc/class.egw_link.inc.php b/phpgwapi/inc/class.egw_link.inc.php index 228414e35b..40e871d6d1 100644 --- a/phpgwapi/inc/class.egw_link.inc.php +++ b/phpgwapi/inc/class.egw_link.inc.php @@ -1231,6 +1231,15 @@ class egw_link extends solink { echo '

'.__METHOD__."('$app','$id','$fname') url=$url

\n"; } + // Log in history - Need to load it first + if((int)$app > 0) + { + $link = self::get_link(-$app); + if($link['app2'] && $link['id2']) + { + historylog::static_add($link['app2'],$link['id2'],$GLOBALS['egw_info']['user']['account_id'],'~file~','', basename($url)); + } + } if (($Ok = !file_exists($url) || egw_vfs::remove($url,true)) && ((int)$app > 0 || $fname)) { // try removing the dir, in case it's empty From c891d4610494a7df64e039aa15db73e352095f41 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 30 Oct 2014 08:33:46 +0000 Subject: [PATCH 08/44] * Calendar: allow admin to set a "default calendar view" used for first display of calendar, afterwards last selected view is used --- calendar/inc/class.calendar_hooks.inc.php | 26 +++++++++++++++++++++++ calendar/lang/egw_de.lang | 1 + calendar/lang/egw_en.lang | 1 + 3 files changed, 28 insertions(+) diff --git a/calendar/inc/class.calendar_hooks.inc.php b/calendar/inc/class.calendar_hooks.inc.php index 70532aca40..0180eb7738 100644 --- a/calendar/inc/class.calendar_hooks.inc.php +++ b/calendar/inc/class.calendar_hooks.inc.php @@ -735,6 +735,32 @@ class calendar_hooks ), ); + if ($hook_data['type'] === 'default') + { + $settings = array_slice($settings, 0, 1, true) + array( + 'defaultcalendar' => array( + 'type' => 'select', + 'label' => 'Default calendar view', + 'name' => 'defaultcalendar', + 'help' => 'Only used for first viewing of calendar, afterwards last selected view is used.', + 'values' => array( + 'day' => lang('Dayview'), + 'day4' => lang('four days view'), + 'week' => lang('Weekview'), + 'weekN' => lang('Multiple week view'), + 'month' => lang('Monthview'), + 'year' => lang('Yearview'), + 'planner' => lang('Planner'), + 'listview' => lang('listview'), + ), + 'xmlrpc' => True, + 'admin' => False, + 'default' => 'week', + + ), + ) + array_slice($settings, 1, count($settings)-1, true); + } + return $settings; } diff --git a/calendar/lang/egw_de.lang b/calendar/lang/egw_de.lang index 760535acb9..3331f79bdf 100644 --- a/calendar/lang/egw_de.lang +++ b/calendar/lang/egw_de.lang @@ -381,6 +381,7 @@ one week calendar de eine Woche one year calendar de ein Jahr only group-events calendar de nur Gruppentermine only the initial date of that recuring event is checked! calendar de Nur das Startdatum diese wiederholenden Termins wird geprüft! +only used for first viewing of calendar, afterwards last selected view is used. calendar de Wird nur bei der Erstanzeige des Kalenders benutzt, danach immer die zuletzt ausgewählte Anzeige. open todo's: calendar de unerledigte Aufgaben: optional calendar de Optional overlap holiday calendar de überlappender Feiertag diff --git a/calendar/lang/egw_en.lang b/calendar/lang/egw_en.lang index d2492dfb65..82070e586e 100644 --- a/calendar/lang/egw_en.lang +++ b/calendar/lang/egw_en.lang @@ -381,6 +381,7 @@ one week calendar en One week one year calendar en One year only group-events calendar en Only group events only the initial date of that recuring event is checked! calendar en Only the initial date of that recurring event is checked! +only used for first viewing of calendar, afterwards last selected view is used. calendar en Only used for first viewing of calendar, afterwards last selected view is used. open todo's: calendar en Open ToDo's: optional calendar en Optional overlap holiday calendar en Overlap holiday From 0429580f719d3675ce382016d47aa7eac00eb2e2 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 30 Oct 2014 09:45:49 +0000 Subject: [PATCH 09/44] Replace taglist item edit trigger from edit botton to doubleclick --- .../js/jquery/magicsuggest/magicsuggest.css | 17 +---------------- phpgwapi/js/jquery/magicsuggest/magicsuggest.js | 14 +++++--------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/phpgwapi/js/jquery/magicsuggest/magicsuggest.css b/phpgwapi/js/jquery/magicsuggest/magicsuggest.css index 4750c6b877..e2070dd180 100644 --- a/phpgwapi/js/jquery/magicsuggest/magicsuggest.css +++ b/phpgwapi/js/jquery/magicsuggest/magicsuggest.css @@ -217,28 +217,13 @@ cursor: pointer; height: 7px; float: right; - margin: 2px 2px 0 10px; + margin: 6px 2px 0 10px; background-image: url(data:image/png;base64,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); background-position: 0 -7px; } .ms-sel-ctn .ms-sel-item .ms-close-btn:hover{ background-position: 0 0; } -.ms-stacked .ms-sel-item .ms-close-btn { - margin-left: 0px; -} -.ms-sel-ctn .ms-sel-item .ms-edit-btn{ - width: 7px; - cursor: pointer; - height: 7px; - float: right; - margin: 12px -18px 0 10px; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAOCAYAAADjXQYbAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3godECY5jN7oQAAAAJxJREFUGNNtzyFSA1EMgOFvyzpMBVyBE2A6tJJ4nkDguAyCczAdVOpzgUVwCCSCQ2CWmWX7ojLzi+QbrKa1tscLnodVuMUjbrAdFqHhHl+4xuliDk+4wxaXOGbmNLbWdnO4wjemzPyADR7wih98Zub736kRh3l/y8xp+eCwplRVn1JVfUpV9SlVdUaJiGmsqjNKRPQpEdGnRMQ/yi9ivDd/aTuHLAAAAABJRU5ErkJggg=='); - background-position: 0 -7px; -} -.ms-sel-ctn .ms-sel-item .ms-edit-btn:hover{ - background-position: 0 0; -} .ms-helper{ color: #AAA; font-size: 10px; diff --git a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js index f52af79f90..07f1dbe2be 100644 --- a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js +++ b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js @@ -1050,15 +1050,11 @@ delItemEl.click($.proxy(handlers._onTagTriggerClick, ref)); if (cfg.allowFreeEntries === true){ - // small pen img - editItemEl = $('', { - 'class': 'ms-edit-btn' - }).data('json', value).appendTo(selectedItemEl); - editItemEl.click($.proxy(handlers._onTagEditTriggerClick, ref)); + selectedItemEl.dblclick($.proxy(handlers._onTagEditTriggerClick, ref)); } } } - + items.push(selectedItemEl); }); ms.selectionContainer.prepend(items); @@ -1332,7 +1328,7 @@ self._updateHelper(cfg.minCharsRenderer.call(this, cfg.minChars - curLength)); } - self._renderSelection(); + setTimeout(function(){self._renderSelection()},300); $(ms).trigger('focus', [ms]); } }, @@ -1496,7 +1492,7 @@ }, /** - * Triggerd whem clicking upon edit icon (pen) for modification + * Triggerd when double clicking upon selected item in order to edit its content * @param e * @private */ @@ -1506,7 +1502,7 @@ { ms.input.val(itemData.label); ms.removeFromSelection(itemData); - _cntInMf = true; + _cntInMf = true; // item is in modification mode } }, From f5c477174aa4acfae7b0b419520e3ab98dc80ed1 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 30 Oct 2014 09:54:29 +0000 Subject: [PATCH 10/44] Get compose email d-n-d working peacfully with taglist doubleclick item modification --- mail/js/app.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mail/js/app.js b/mail/js/app.js index e97b83b13f..a637ce2474 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -3946,7 +3946,7 @@ app.classes.mail = AppJS.extend( cursor:'move', cursorAt:{left:2}, //cancel dragging on close button to avoid conflict with close action - cancel:'.ms-close-btn, .ms-edit-btn', + cancel:'.ms-close-btn', /** * function to act on draggable item on revert's event * @returns {Boolean} return true @@ -3981,7 +3981,8 @@ app.classes.mail = AppJS.extend( { jQuery(this).css('css','move'); } - }); + }).draggable('disable'); + setTimeout(function(){dragItem.draggable('enable');},400) }, /** From a4389c7cbcc31b41b7afb0920145af812ec27fae Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 30 Oct 2014 10:24:11 +0000 Subject: [PATCH 11/44] fix javascript error when creating an exception --- calendar/js/app.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/calendar/js/app.js b/calendar/js/app.js index b947a85af1..5a9f81e32e 100644 --- a/calendar/js/app.js +++ b/calendar/js/app.js @@ -85,7 +85,7 @@ app.classes.calendar = AppJS.extend( this._init_sidebox(sidebox); var content = this.et2.getArrayMgr('content'); - + switch (_name) { case 'calendar.list': @@ -101,7 +101,8 @@ app.classes.calendar = AppJS.extend( { this.set_enddate_visibility(); this.check_recur_type(); - this.et2.getWidgetById('recur_exception').set_disabled(typeof content.data['recur_exception'][0] == 'undefined'); + this.et2.getWidgetById('recur_exception').set_disabled(!content.data.recur_exception || + typeof content.data.recur_exception[0] == 'undefined'); } else { @@ -175,15 +176,15 @@ app.classes.calendar = AppJS.extend( { var iframe = parent.jQuery(parent.document).find('.egw_fw_content_browser_iframe'); var calTab = iframe.parentsUntil(jQuery('.egw_fw_ui_tab_content'),'.egw_fw_ui_tab_content'); - - if (!calTab.is(':visible')) + + if (!calTab.is(':visible')) { - // F.F can not handle to style correctly an iframe which is hidden (display:none), therefore we need to + // F.F can not handle to style correctly an iframe which is hidden (display:none), therefore we need to // bind a handler to refresh the calendar views after it shows up iframe.one('show',function(){egw_refresh('','calendar');}) } else - { + { //window.location.reload(); window.egw_refresh('refreshing calendar','calendar'); } @@ -451,7 +452,7 @@ app.classes.calendar = AppJS.extend( { // bind on tooltip close event $ttp.on("tooltipclose", function (event, ui){ - // bind hover handler on tooltip helper in order to be able to freeze the tooltip and scrolling + // bind hover handler on tooltip helper in order to be able to freeze the tooltip and scrolling ui.tooltip.hover( function () { var $ttp_helper = jQuery(this); From f55380b8d7aca851ca03f82b29a4e410622d7bd0 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 30 Oct 2014 10:51:40 +0000 Subject: [PATCH 12/44] Mark all content of the item after double clicking to modify --- phpgwapi/js/jquery/magicsuggest/magicsuggest.js | 1 + 1 file changed, 1 insertion(+) diff --git a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js index 07f1dbe2be..e8e97eec09 100644 --- a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js +++ b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js @@ -1502,6 +1502,7 @@ { ms.input.val(itemData.label); ms.removeFromSelection(itemData); + ms.input.select(); _cntInMf = true; // item is in modification mode } }, From 6c7c29316ab8053d30dc89a59286b1e8f9dbbe70 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 30 Oct 2014 11:09:38 +0000 Subject: [PATCH 13/44] making popup resize a bit more relyable by using an extra timeout and trigger it for every load, not just first one --- phpgwapi/js/jsapi/egw.js | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/phpgwapi/js/jsapi/egw.js b/phpgwapi/js/jsapi/egw.js index 543e3ae844..d0576aa572 100644 --- a/phpgwapi/js/jsapi/egw.js +++ b/phpgwapi/js/jsapi/egw.js @@ -223,22 +223,23 @@ if(popup || window.opener) { // Resize popup when et2 load is done - jQuery(node).one("load",function() { - var $main_div = $j('#popupMainDiv'); - var $et2 = $j('.et2_container'); - var w = { - width: egw_getWindowInnerWidth(), - height: egw_getWindowInnerHeight() - }; - // Use et2_container for width since #popupMainDiv is full width, but we still need - // to take padding/margin into account - var delta_width = w.width - ($et2.outerWidth(true) + ($main_div.outerWidth(true) - $main_div.width())); - var delta_height = w.height - ($et2.outerHeight(true) + ($main_div.outerHeight(true) - $main_div.height())); - debugger; - if(delta_width != 0 || delta_height != 0) - { - window.resizeTo(egw_getWindowOuterWidth() - delta_width,egw_getWindowOuterHeight() - delta_height); - } + jQuery(node).on("load",function() { + window.setTimeout(function() { + var $main_div = $j('#popupMainDiv'); + var $et2 = $j('.et2_container'); + var w = { + width: egw_getWindowInnerWidth(), + height: egw_getWindowInnerHeight() + }; + // Use et2_container for width since #popupMainDiv is full width, but we still need + // to take padding/margin into account + var delta_width = w.width - ($et2.outerWidth(true) + ($main_div.outerWidth(true) - $main_div.width())); + var delta_height = w.height - ($et2.outerHeight(true) + ($main_div.outerHeight(true) - $main_div.height())); + if(delta_width != 0 || delta_height != 0) + { + window.resizeTo(egw_getWindowOuterWidth() - delta_width,egw_getWindowOuterHeight() - delta_height); + } + }, 200); }); } var et2 = new etemplate2(node, currentapp+".etemplate_new.ajax_process_content.etemplate"); From 0f362fa6a0c8b971ee5ad7659d5a94d132031375 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 30 Oct 2014 11:11:12 +0000 Subject: [PATCH 14/44] fix popup was never wide enought problem by removing width:100% from #popupMainDiv --- mail/templates/pixelegg/app.css | 8 ++------ mail/templates/pixelegg/app.less | 5 ----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/mail/templates/pixelegg/app.css b/mail/templates/pixelegg/app.css index de85914d55..cec3ee6956 100755 --- a/mail/templates/pixelegg/app.css +++ b/mail/templates/pixelegg/app.css @@ -525,7 +525,8 @@ div.mail-compose_fileselector { border: 0px !important; display: none !important; } -#mail-display { +#mail-display, +#mail-compose { min-height: 500px; } .mailDisplayContainer, @@ -1473,11 +1474,6 @@ div#mail-index div#mail-index_mailPreview div#mail-index_mailPreviewHeadersSubje * Preview * ################################################################################## */ -div#popupMainDiv { - padding: 8px; - margin: -6px 0px 6px -1px; - width: 100%; -} #mail-display { width: 870px; min-height: 500px; diff --git a/mail/templates/pixelegg/app.less b/mail/templates/pixelegg/app.less index 36dcbba42e..3507775d14 100755 --- a/mail/templates/pixelegg/app.less +++ b/mail/templates/pixelegg/app.less @@ -663,11 +663,6 @@ div#mail-index{ * Preview * ################################################################################## */ -div#popupMainDiv{ - padding: 8px; - margin: -6px 0px 6px -1px; - width: 100%; -} #mail-display{ // gesamtbreite From 0d1a1c3f4a5425cf11e698fb0acf4a18f6715914 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 30 Oct 2014 11:55:22 +0000 Subject: [PATCH 15/44] Adjust speed of double click trigger for taglist item modification --- mail/js/app.js | 94 ++++++++++--------- .../js/jquery/magicsuggest/magicsuggest.js | 10 +- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/mail/js/app.js b/mail/js/app.js index a637ce2474..4def2c5a05 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -3937,52 +3937,58 @@ app.classes.mail = AppJS.extend( { var zIndex = 100; var dragItem = jQuery('div.ms-sel-item:not(div.ui-draggable)'); - - dragItem.draggable({ - appendTo:'body', - //Performance wise better to not add ui-draggable class to items since we are not using that class - containment:'document', - distance: 0, - cursor:'move', - cursorAt:{left:2}, - //cancel dragging on close button to avoid conflict with close action - cancel:'.ms-close-btn', - /** - * function to act on draggable item on revert's event - * @returns {Boolean} return true - */ - revert: function (){ - this.parent().find('.ms-sel-item').css('position','relative'); - return true; - }, - /** - * function to act as draggable starts dragging - * - * @param {type} event - * @param {type} ui - */ - start:function(event, ui) - { - var dragItem = jQuery(this); - if (event.ctrlKey || event.metaKey) + if (dragItem.length > 0) + { + dragItem.draggable({ + appendTo:'body', + //Performance wise better to not add ui-draggable class to items since we are not using that class + containment:'document', + distance: 0, + cursor:'move', + cursorAt:{left:2}, + //cancel dragging on close button to avoid conflict with close action + cancel:'.ms-close-btn', + /** + * function to act on draggable item on revert's event + * @returns {Boolean} return true + */ + revert: function (){ + this.parent().find('.ms-sel-item').css('position','relative'); + return true; + }, + /** + * function to act as draggable starts dragging + * + * @param {type} event + * @param {type} ui + */ + start:function(event, ui) { - dragItem.addClass('mailCompose_copyEmail') - .css('cursor','copy'); + var dragItem = jQuery(this); + if (event.ctrlKey || event.metaKey) + { + dragItem.addClass('mailCompose_copyEmail') + .css('cursor','copy'); + } + dragItem.css ('z-index',zIndex++); + dragItem.css('position','absolute'); + }, + /** + * + * @param {type} event + * @param {type} ui + */ + create:function(event,ui) + { + jQuery(this).css('css','move'); } - dragItem.css ('z-index',zIndex++); - dragItem.css('position','absolute'); - }, - /** - * - * @param {type} event - * @param {type} ui - */ - create:function(event,ui) - { - jQuery(this).css('css','move'); - } - }).draggable('disable'); - setTimeout(function(){dragItem.draggable('enable');},400) + }).draggable('disable'); + window.setTimeout(function(){ + + if(dragItem && dragItem.data() && typeof dragItem.data()['uiDraggable'] !== 'undefined') dragItem.draggable('enable'); + },100); + } + }, /** diff --git a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js index e8e97eec09..53e9860c02 100644 --- a/phpgwapi/js/jquery/magicsuggest/magicsuggest.js +++ b/phpgwapi/js/jquery/magicsuggest/magicsuggest.js @@ -1024,7 +1024,7 @@ $.each(_selection, function(index, value){ - var selectedItemEl, delItemEl,editItemEl, + var selectedItemEl, delItemEl, selectedItemHtml = cfg.selectionRenderer !== null ? cfg.selectionRenderer.call(ref, value) : value[cfg.displayField]; var validCls = self._validateSingleItem(value[cfg.displayField]) ? '' : ' ms-sel-invalid'; @@ -1050,7 +1050,7 @@ delItemEl.click($.proxy(handlers._onTagTriggerClick, ref)); if (cfg.allowFreeEntries === true){ - selectedItemEl.dblclick($.proxy(handlers._onTagEditTriggerClick, ref)); + selectedItemEl.dblclick($.proxy(handlers._onTagEditTriggerDblClick, ref)); } } } @@ -1280,7 +1280,7 @@ * Triggered when focusing on the container div. Will focus on the input field instead. * @private */ - _onFocus: function(e) { + _onFocus: function() { if (!_cntInMf) { ms.input.focus(); @@ -1328,7 +1328,7 @@ self._updateHelper(cfg.minCharsRenderer.call(this, cfg.minChars - curLength)); } - setTimeout(function(){self._renderSelection()},300); + setTimeout(function(){self._renderSelection()},400); $(ms).trigger('focus', [ms]); } }, @@ -1496,7 +1496,7 @@ * @param e * @private */ - _onTagEditTriggerClick: function(e) { + _onTagEditTriggerDblClick: function(e) { var itemData = $(e.currentTarget).data('json'); if (ms.input.val() === '') { From a9c6c2a90e52197ce1d0492a091c838f3c7de9a4 Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 30 Oct 2014 12:26:42 +0000 Subject: [PATCH 16/44] Display account_fullname of event owner, creator, and participant in calendar customized link title --- calendar/inc/class.calendar_bo.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calendar/inc/class.calendar_bo.inc.php b/calendar/inc/class.calendar_bo.inc.php index 057167318e..a4749343fa 100644 --- a/calendar/inc/class.calendar_bo.inc.php +++ b/calendar/inc/class.calendar_bo.inc.php @@ -1885,13 +1885,13 @@ class calendar_bo case 'participants': foreach ($event[$val] as $key => $value) { - $extra_fields [$val] = accounts::id2name($key); + $extra_fields [$val] = accounts::id2name($key, 'account_fullname'); } break; case 'modifier': case 'creator': case 'owner': - $extra_fields [$val] = accounts::id2name($event[$val]); + $extra_fields [$val] = accounts::id2name($event[$val], 'account_fullname'); break; default: $extra_fields [] = $event[$val]; From 1c6524cf0be488621891cb33afcc5be3701f2cb1 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 30 Oct 2014 13:20:04 +0000 Subject: [PATCH 17/44] remove upper limit of number of characters at last domain-part to allow new domain-names like .hamburg --- etemplate/inc/class.etemplate_widget_url.inc.php | 2 +- etemplate/inc/class.url_widget.inc.php | 2 +- etemplate/js/et2_widget_url.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/etemplate/inc/class.etemplate_widget_url.inc.php b/etemplate/inc/class.etemplate_widget_url.inc.php index 639d4ead8f..7b84558a63 100644 --- a/etemplate/inc/class.etemplate_widget_url.inc.php +++ b/etemplate/inc/class.etemplate_widget_url.inc.php @@ -33,7 +33,7 @@ class etemplate_widget_url extends etemplate_widget * * Same preg is in et2_widget_url Javascript class, but no \x00 allowed and /u modifier for utf8! */ - const EMAIL_PREG = "/^(([^\042',<][^,<]+|\042[^\042]+\042|\'[^\']+\'|)\s?<)?[^\x01-\x20()<>@,;:\042\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,6}>?$/iu"; + const EMAIL_PREG = "/^(([^\042',<][^,<]+|\042[^\042]+\042|\'[^\']+\'|)\s?<)?[^\x01-\x20()<>@,;:\042\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,}>?$/iu"; /** * Validate input diff --git a/etemplate/inc/class.url_widget.inc.php b/etemplate/inc/class.url_widget.inc.php index 7407a95ec4..6ee5a10a72 100644 --- a/etemplate/inc/class.url_widget.inc.php +++ b/etemplate/inc/class.url_widget.inc.php @@ -63,7 +63,7 @@ class url_widget */ //const EMAIL_PREG = '([a-z0-9][a-z0-9._-]*)?[a-z0-9]@([a-z0-9](|[a-z0-9_-]*[a-z0-9])\.)+[a-z]{2,6}'; //const EMAIL_PREG = '([a-z0-9][a-z0-9._\'\&\+-]*)?[a-z0-9_]@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,6}'; - const EMAIL_PREG = '^[^\x00-\x20()<>@,;:\\"\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,6}'; + const EMAIL_PREG = '^[^\x00-\x20()<>@,;:\\"\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,}'; /** * pre-processing of the extension diff --git a/etemplate/js/et2_widget_url.js b/etemplate/js/et2_widget_url.js index 23915b99e2..eb0f1d6576 100644 --- a/etemplate/js/et2_widget_url.js +++ b/etemplate/js/et2_widget_url.js @@ -48,7 +48,7 @@ var et2_url = et2_textbox.extend( * * Same preg is in etemplate_widget_url PHP class! */ - EMAIL_PREG: new RegExp(/^(([^\042',<][^,<]+|\042[^\042]+\042|\'[^\']+\'|)\s?<)?[^\x00-\x20()<>@,;:\042\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,6}>?$/i), + EMAIL_PREG: new RegExp(/^(([^\042',<][^,<]+|\042[^\042]+\042|\'[^\']+\'|)\s?<)?[^\x00-\x20()<>@,;:\042\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,}>?$/i), /** * @memberOf et2_url */ From 836251277c495c28c1e3280ae069a58f0bf1a42d Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 30 Oct 2014 14:13:45 +0000 Subject: [PATCH 18/44] Style customfields' edit popup dialog --- admin/templates/default/customfield_edit.xet | 56 +++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/admin/templates/default/customfield_edit.xet b/admin/templates/default/customfield_edit.xet index b21c7d72c8..248910b289 100644 --- a/admin/templates/default/customfield_edit.xet +++ b/admin/templates/default/customfield_edit.xet @@ -4,11 +4,17 @@