lots of stuff like: css for attachments, flagged, message stati (recent answered, ...); display of all available accounts in sidebar, (ToDo: on open should connect and retrieve the folders); getCounters for current tree; flagging of messages

This commit is contained in:
Klaus Leithoff 2013-02-19 16:30:59 +00:00
parent 9b88b849f6
commit acd70575c6
6 changed files with 775 additions and 93 deletions

View File

@ -2327,6 +2327,123 @@ class mail_bo
}
}
/**
* flag a Message
*
* @param string _flag (readable name)
* @param mixed array/string _messageUID array of ids to flag, or 'all'
* @param string _folder foldername
*
* @todo handle handle icserver->setFlags returnValue
*
* @return bool true, as we do not handle icserver->setFlags returnValue
*/
function flagMessages($_flag, $_messageUID,$_folder=NULL)
{
//error_log(__METHOD__.__LINE__.'->' .$_flag." ".array2string($_messageUID).",$_folder /".$this->sessionData['mailbox']);
if(!is_array($_messageUID)) {
#return false;
if ($_messageUID=='all')
{
//all is an allowed value to be passed
}
else
{
$_messageUID=array($_messageUID);
}
}
$this->icServer->selectMailbox(($_folder?$_folder:$this->sessionData['mailbox']));
switch($_flag) {
case "undelete":
$ret = $this->icServer->setFlags($_messageUID, '\\Deleted', 'remove', true);
break;
case "flagged":
$ret = $this->icServer->setFlags($_messageUID, '\\Flagged', 'add', true);
break;
case "read":
$ret = $this->icServer->setFlags($_messageUID, '\\Seen', 'add', true);
break;
case "forwarded":
$ret = $this->icServer->setFlags($_messageUID, '$Forwarded', 'add', true);
case "answered":
$ret = $this->icServer->setFlags($_messageUID, '\\Answered', 'add', true);
break;
case "unflagged":
$ret = $this->icServer->setFlags($_messageUID, '\\Flagged', 'remove', true);
break;
case "unread":
$ret = $this->icServer->setFlags($_messageUID, '\\Seen', 'remove', true);
$ret = $this->icServer->setFlags($_messageUID, '\\Answered', 'remove', true);
$ret = $this->icServer->setFlags($_messageUID, '$Forwarded', 'remove', true);
break;
case "mdnsent":
$ret = $this->icServer->setFlags($_messageUID, 'MDNSent', 'add', true);
break;
case "mdnnotsent":
$ret = $this->icServer->setFlags($_messageUID, 'MDNnotSent', 'add', true);
break;
case "label1":
case "labelone":
$ret = $this->icServer->setFlags($_messageUID, '$label1', 'add', true);
break;
case "unlabel1":
case "unlabelone":
$this->icServer->setFlags($_messageUID, '$label1', 'remove', true);
break;
case "label2":
case "labeltwo":
$ret = $this->icServer->setFlags($_messageUID, '$label2', 'add', true);
break;
case "unlabel2":
case "unlabeltwo":
$ret = $this->icServer->setFlags($_messageUID, '$label2', 'remove', true);
break;
case "label3":
case "labelthree":
$ret = $this->icServer->setFlags($_messageUID, '$label3', 'add', true);
break;
case "unlabel3":
case "unlabelthree":
$ret = $this->icServer->setFlags($_messageUID, '$label3', 'remove', true);
break;
case "label4":
case "labelfour":
$ret = $this->icServer->setFlags($_messageUID, '$label4', 'add', true);
break;
case "unlabel4":
case "unlabelfour":
$ret = $this->icServer->setFlags($_messageUID, '$label4', 'remove', true);
break;
case "label5":
case "labelfive":
$ret = $this->icServer->setFlags($_messageUID, '$label5', 'add', true);
break;
case "unlabel5":
case "unlabelfive":
$ret = $this->icServer->setFlags($_messageUID, '$label5', 'remove', true);
break;
}
if (PEAR::isError($ret))
{
if (stripos($ret->message,'Too long argument'))
{
$c = count($_messageUID);
$h =ceil($c/2);
error_log(__METHOD__.__LINE__.$ret->message." $c messages given for flagging. Trying with chunks of $h");
$this->flagMessages($_flag, array_slice($_messageUID,0,$h),($_folder?$_folder:$this->sessionData['mailbox']));
$this->flagMessages($_flag, array_slice($_messageUID,$h),($_folder?$_folder:$this->sessionData['mailbox']));
}
}
$this->sessionData['folderStatus'][$this->profileID][$this->sessionData['mailbox']]['uidValidity'] = 0;
$this->saveSessionData();
//error_log(__METHOD__.__LINE__.'->' .$_flag." ".array2string($_messageUID).",".($_folder?$_folder:$this->sessionData['mailbox']));
return true; // as we do not catch/examine setFlags returnValue
}
/**
* Helper function to handle wrong or unrecognized timezones
* returns the date as it is parseable by strtotime, or current timestamp if everything failes
@ -2370,6 +2487,324 @@ class mail_bo
return $_string;
}
/**
* Header and Bodystructure stuff
*/
/**
* _getStructure
* fetc the structure of a mail, represented by uid
* @param string/int $_uid the messageuid,
* @param boolean $byUid=true, is the messageuid given by UID or ID
* @param boolean $_ignoreCache=false, use or disregard cache, when fetching
* @param string $_folder='', if given search within that folder for the given $_uid, else use sessionData['mailbox'], or servers getCurrentMailbox
* @return array an structured array of information about the mail
*/
function _getStructure($_uid, $byUid=true, $_ignoreCache=false, $_folder = '')
{
static $structure;
if (empty($_folder)) $_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
//error_log(__METHOD__.__LINE__.'User:'.trim($GLOBALS['egw_info']['user']['account_id'])." UID: $_uid, ".$this->icServer->ImapServerId.','.$_folder);
if (is_null($structure)) $structure = egw_cache::getCache(egw_cache::INSTANCE,'email','structureCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
//error_log(__METHOD__.__LINE__." UID: $_uid, ".$this->icServer->ImapServerId.','.$_folder.'->'.array2string(array_keys($structure)));
if (isset($structure[$this->icServer->ImapServerId]) && !empty($structure[$this->icServer->ImapServerId]) &&
isset($structure[$this->icServer->ImapServerId][$_folder]) && !empty($structure[$this->icServer->ImapServerId][$_folder]) &&
isset($structure[$this->icServer->ImapServerId][$_folder][$_uid]) && !empty($structure[$this->icServer->ImapServerId][$_folder][$_uid]))
{
if ($_ignoreCache===false)
{
//error_log(__METHOD__.__LINE__.' Using cache for structure on Server:'.$this->icServer->ImapServerId.' for uid:'.$_uid." in Folder:".$_folder.'->'.array2string($structure[$this->icServer->ImapServerId][$_folder][$_uid]));
return $structure[$this->icServer->ImapServerId][$_folder][$_uid];
}
}
$structure[$this->icServer->ImapServerId][$_folder][$_uid] = $this->icServer->getStructure($_uid, $byUid);
egw_cache::setCache(egw_cache::INSTANCE,'email','structureCache'.trim($GLOBALS['egw_info']['user']['account_id']),$structure,$expiration=60*60*1);
//error_log(__METHOD__.__LINE__.' Using query for structure on Server:'.$this->icServer->ImapServerId.' for uid:'.$_uid." in Folder:".$_folder.'->'.array2string($structure[$this->icServer->ImapServerId][$_folder][$_uid]));
return $structure[$this->icServer->ImapServerId][$_folder][$_uid];
}
/**
* getMessageAttachments
* parse the structure for attachments, it returns not the attachments itself, but an array of information about the attachment
* @param string/int $_uid the messageuid,
* @param string/int $_partID='' , the partID, may be omitted
* @param array $_structure='', if given use structure for parsing
* @param boolean $fetchEmbeddedImages=true,
* @param boolean $fetchTextCalendar=false,
* @param boolean $resolveTNEF=true
* @return array an array of information about the attachment: array of array(name, size, mimeType, partID, encoding)
*/
function getMessageAttachments($_uid, $_partID='', $_structure='', $fetchEmbeddedImages=true, $fetchTextCalendar=false, $resolveTNEF=true)
{
if (self::$debug) echo __METHOD__."$_uid, $_partID<br>";
if(is_object($_structure)) {
$structure = $_structure;
} else {
$structure = $this->_getStructure($_uid, true);
if($_partID != '' && $_partID !=0) {
$structure = $this->_getSubStructure($structure, $_partID);
}
}
if (self::$debug) _debug_array($structure);
$attachments = array();
// this kind of messages contain only the attachment and no body
if($structure->type == 'APPLICATION' || $structure->type == 'AUDIO' || $structure->type == 'VIDEO' || $structure->type == 'IMAGE' || ($structure->type == 'TEXT' && $structure->disposition == 'ATTACHMENT') )
{
$newAttachment = array();
$newAttachment['name'] = $this->getFileNameFromStructure($structure,$_uid,$structure->partID);
$newAttachment['size'] = $structure->bytes;
$newAttachment['mimeType'] = $structure->type .'/'. $structure->subType;
$newAttachment['partID'] = $structure->partID;
$newAttachment['encoding'] = $structure->encoding;
// try guessing the mimetype, if we get the application/octet-stream
if (strtolower($newAttachment['mimeType']) == 'application/octet-stream') $newAttachment['mimeType'] = mime_magic::filename2mime($newAttachment['name']);
if(isset($structure->cid)) {
$newAttachment['cid'] = $structure->cid;
}
# if the new attachment is a winmail.dat, we have to decode that first
if ( $resolveTNEF && $newAttachment['name'] == 'winmail.dat' &&
( $wmattachments = $this->decode_winmail( $_uid, $newAttachment['partID'] ) ) )
{
$attachments = array_merge( $attachments, $wmattachments );
}
elseif ( $resolveTNEF===false && $newAttachment['name'] == 'winmail.dat' )
{
$attachments[] = $newAttachment;
} else {
$fetchit = $fetchEmbeddedImages;
if ($fetchEmbeddedImages === false && (!in_array(strtoupper($structure->subtype),array('JPG','JPEG','GIF','PNG')))) $fetchit = true;
if ( ($fetchit && isset($newAttachment['cid']) && strlen($newAttachment['cid'])>0) ||
!isset($newAttachment['cid']) ||
empty($newAttachment['cid'])) $attachments[] = $newAttachment;
}
//$attachments[] = $newAttachment;
#return $attachments;
}
// outlook sometimes sends a TEXT/CALENDAR;REQUEST as plain ics, nothing more.
if ($structure->type == 'TEXT' && $structure->subType == 'CALENDAR' &&
isset($structure->parameters['METHOD'] ) && strtoupper($structure->parameters['METHOD']) == 'REQUEST')
{
$newAttachment = array();
$newAttachment['name'] = 'event.ics';
$newAttachment['size'] = $structure->bytes;
$newAttachment['mimeType'] = $structure->type .'/'. $structure->subType;//.';'.$structure->parameters['METHOD'];
$newAttachment['partID'] = $structure->partID;
$newAttachment['encoding'] = $structure->encoding;
$newAttachment['method'] = $structure->parameters['METHOD'];
$newAttachment['charset'] = $structure->parameters['CHARSET'];
$attachments[] = $newAttachment;
}
// this kind of message can have no attachments
if(($structure->type == 'TEXT' && !($structure->disposition == 'INLINE' && $structure->dparameters['FILENAME'])) ||
($structure->type == 'MULTIPART' && $structure->subType == 'ALTERNATIVE' && !is_array($structure->subParts)) ||
!is_array($structure->subParts))
{
if (count($attachments) == 0) return array();
}
#$attachments = array();
foreach((array)$structure->subParts as $subPart) {
// skip all non attachment parts
if(($subPart->type == 'TEXT' && ($subPart->subType == 'PLAIN' || $subPart->subType == 'HTML') && ($subPart->disposition != 'ATTACHMENT' &&
!($subPart->disposition == 'INLINE' && $subPart->dparameters['FILENAME']))) ||
($subPart->type == 'MULTIPART' && $subPart->subType == 'ALTERNATIVE') ||
($subPart->type == 'MULTIPART' && $subPart->subType == 'APPLEFILE') ||
($subPart->type == 'MESSAGE' && $subPart->subType == 'delivery-status'))
{
if ($subPart->type == 'MULTIPART' && $subPart->subType == 'ALTERNATIVE')
{
$attachments = array_merge($this->getMessageAttachments($_uid, '', $subPart, $fetchEmbeddedImages, $fetchTextCalendar, $resolveTNEF), $attachments);
}
if (!($subPart->type=='TEXT' && $subPart->disposition =='INLINE' && $subPart->filename)) continue;
}
// fetch the subparts for this part
if($subPart->type == 'MULTIPART' &&
($subPart->subType == 'RELATED' ||
$subPart->subType == 'MIXED' ||
$subPart->subType == 'SIGNED' ||
$subPart->subType == 'APPLEDOUBLE'))
{
$attachments = array_merge($this->getMessageAttachments($_uid, '', $subPart, $fetchEmbeddedImages,$fetchTextCalendar, $resolveTNEF), $attachments);
} else {
if (!$fetchTextCalendar && $subPart->type == 'TEXT' &&
$subPart->subType == 'CALENDAR' &&
$subPart->parameters['METHOD'] &&
$subPart->disposition !='ATTACHMENT') continue;
$newAttachment = array();
$newAttachment['name'] = $this->getFileNameFromStructure($subPart,$_uid,$subPart->partID);
$newAttachment['size'] = $subPart->bytes;
$newAttachment['mimeType'] = $subPart->type .'/'. $subPart->subType;
$newAttachment['partID'] = $subPart->partID;
$newAttachment['encoding'] = $subPart->encoding;
$newAttachment['method'] = $this->getMethodFromStructure($subPart,$_uid,$subPart->partID);
$newAttachment['charset'] = $subPart->parameters['CHARSET'];
if (isset($subPart->disposition) && !empty($subPart->disposition)) $newAttachment['disposition'] = $subPart->disposition;
// try guessing the mimetype, if we get the application/octet-stream
if (strtolower($newAttachment['mimeType']) == 'application/octet-stream') $newAttachment['mimeType'] = mime_magic::filename2mime($newAttachment['name']);
if(isset($subPart->cid)) {
$newAttachment['cid'] = $subPart->cid;
}
# if the new attachment is a winmail.dat, we have to decode that first
if ( $resolveTNEF && $newAttachment['name'] == 'winmail.dat' &&
( $wmattachments = $this->decode_winmail( $_uid, $newAttachment['partID'] ) ) )
{
$attachments = array_merge( $attachments, $wmattachments );
}
elseif ( $resolveTNEF===false && $newAttachment['name'] == 'winmail.dat' )
{
$attachments[] = $newAttachment;
} else {
$fetchit = $fetchEmbeddedImages;
if ($fetchEmbeddedImages === false && (!in_array(strtoupper($structure->subtype),array('JPG','JPEG','GIF','PNG')))) $fetchit = true;
if ( ($fetchit && isset($newAttachment['cid']) && strlen($newAttachment['cid'])>0) ||
!isset($newAttachment['cid']) ||
empty($newAttachment['cid']) || $newAttachment['cid'] == 'NIL')
{
$attachments[] = $newAttachment;
}
else
{
// embedded images should be INLINE, so we check this too, 'cause we want to show/list non embedded images
if ($fetchEmbeddedImages==false &&
isset($newAttachment['mimeType']) &&
!empty($newAttachment['mimeType']) &&
stripos($newAttachment['mimeType'],'IMAGE') !== false &&
isset($newAttachment['disposition']) &&
!empty($newAttachment['disposition']) &&
trim(strtoupper($newAttachment['disposition']))!='INLINE') $attachments[] = $newAttachment;
}
}
//$attachments[] = $newAttachment;
}
}
//_debug_array($attachments); exit;
return $attachments;
}
/**
* getFileNameFromStructure
* parse the structure for the filename of an attachment
* @param array $_structure='', structure used for parsing
* @param string/int $_uid the messageuid,
* @param string/int $_partID='', the partID, may be omitted
* @return string a string representing the filename of an attachment
*/
function getFileNameFromStructure(&$structure, $_uid = false, $partID = false)
{
static $namecounter;
if (is_null($namecounter)) $namecounter = 0;
//if ( $_uid && $partID) error_log(__METHOD__.__LINE__.array2string($structure).' Uid:'.$_uid.' PartID:'.$partID.' -> '.array2string($this->icServer->getParsedHeaders($_uid, true, $partID, true)));
if(isset($structure->parameters['NAME'])) {
if (is_array($structure->parameters['NAME'])) $structure->parameters['NAME'] = implode(' ',$structure->parameters['NAME']);
return rawurldecode(self::decode_header($structure->parameters['NAME']));
} elseif(isset($structure->dparameters['FILENAME'])) {
return rawurldecode(self::decode_header($structure->dparameters['FILENAME']));
} elseif(isset($structure->dparameters['FILENAME*'])) {
return rawurldecode(self::decode_header($structure->dparameters['FILENAME*']));
} elseif ( isset($structure->filename) && !empty($structure->filename) && $structure->filename != 'NIL') {
return rawurldecode(self::decode_header($structure->filename));
} else {
if ( $_uid && $partID)
{
$headers = $this->icServer->getParsedHeaders($_uid, true, $partID, true);
if ($headers)
{
if (!PEAR::isError($headers))
{
// simple parsing of the headers array for a usable name
//error_log( __METHOD__.__LINE__.array2string($headers));
foreach(array('CONTENT-TYPE','CONTENT-DISPOSITION') as $k => $v)
{
$headers[$v] = rawurldecode(self::decode_header($headers[$v]));
foreach(array('filename','name') as $sk => $n)
{
if (stripos($headers[$v],$n)!== false)
{
$buff = explode($n,$headers[$v]);
//error_log(__METHOD__.__LINE__.array2string($buff));
$namepart = array_pop($buff);
//error_log(__METHOD__.__LINE__.$namepart);
$fp = strpos($namepart,'"');
//error_log(__METHOD__.__LINE__.' Start:'.$fp);
if ($fp !== false)
{
$np = strpos($namepart,'"', $fp+1);
//error_log(__METHOD__.__LINE__.' End:'.$np);
if ($np !== false)
{
$name = trim(substr($namepart,$fp+1,$np-$fp-1));
if (!empty($name)) return $name;
}
}
}
}
}
}
}
}
$namecounter++;
return lang("unknown").$namecounter.($structure->subType ? ".".$structure->subType : "");
}
}
/**
* getMethodFromStructure
* parse the structure for the METHOD of an ics event (attachment)
* @param array $_structure='', structure used for parsing
* @param string/int $_uid the messageuid,
* @param string/int $_partID='', the partID, may be omitted
* @return string a string representing the filename of an attachment
*/
function getMethodFromStructure(&$structure, $_uid = false, $partID = false)
{
//if ( $_uid && $partID) error_log(__METHOD__.__LINE__.array2string($structure).' Uid:'.$_uid.' PartID:'.$partID.' -> '.array2string($this->icServer->getParsedHeaders($_uid, true, $partID, true)));
if(isset($subPart->parameters['METHOD'])) {
return $subPart->parameters['METHOD'];
}
else
{
if ( $_uid && $partID && $structure->type=='TEXT' && $structure->subType=='CALENDAR' && $structure->filename=='NIL')
{
$attachment = $this->getAttachment($_uid, $partID);
if ($attachment['attachment'])
{
if (!PEAR::isError($attachment['attachment']))
{
// simple parsing of the attachment for a usable method
//error_log( __METHOD__.__LINE__.array2string($attachment['attachment']));
foreach(explode("\r\n",$attachment['attachment']) as $k => $v)
{
if (strpos($v,':') !== false)
{
list($first,$rest) = explode(':',$v,2);
$first = trim($first);
if ($first=='METHOD')
{
return trim($rest);
}
}
}
}
}
}
}
}
/**
* Hook stuff
*/
/**
* hook to add account
*

View File

@ -54,7 +54,7 @@ class mail_ui
}
$this->mail_bo = mail_bo::getInstance(false,$icServerID);
error_log(__METHOD__.__LINE__.' Fetched IC Server:'.$icServerID.function_backtrace());
// no icServer Object: something failed big time
if (!isset($this->mail_bo->icServer)) exit; // ToDo: Exception or the dialog for setting up a server config
if (!($this->mail_bo->icServer->_connected == 1)) $this->mail_bo->openConnection($icServerID);
@ -88,7 +88,7 @@ class mail_ui
'start' => 0, // IO position in list
'order' => 'date', // IO name of the column to sort after (optional for the sortheaders)
'sort' => 'ASC', // IO direction of the sort: 'ASC' or 'DESC'
'default_cols' => 'subject,fromaddress,date,size', // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
'default_cols' => 'status,attachments,subject,fromaddress,date,size', // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
'csv_fields' => false, // I false=disable csv export, true or unset=enable it with auto-detected fieldnames,
//or array with name=>label or name=>array('label'=>label,'type'=>type) pairs (type is a eT widget-type)
'actions' => self::get_actions(),
@ -123,14 +123,18 @@ class mail_ui
$content['nm']['foldertree'] = '/INBOX/sub';
*/
if ($this->mail_bo->folderExists($this->mail_bo->sessionData['maibox']))
$del = $this->mail_bo->getHierarchyDelimiter(false);
$sel_options['nm']['foldertree'] = $this->getFolderTree(false);
$sessionFolder = $this->mail_bo->sessionData['maibox'];
if ($this->mail_bo->folderExists($sessionFolder))
{
$content['nm']['selectedFolder'] = $this->mail_bo->sessionData['maibox'];
$content['nm']['selectedFolder'] = $this->mail_bo->profileID.$del.$this->mail_bo->sessionData['maibox'];
}
$sel_options['nm']['foldertree'] = $this->getFolderTree();
if (!isset($content['nm']['foldertree'])) $content['nm']['foldertree'] = 'INBOX';
if (!isset($content['nm']['selectedFolder'])) $content['nm']['selectedFolder'] = 'INBOX';
if (!isset($content['nm']['foldertree'])) $content['nm']['foldertree'] = $this->mail_bo->profileID.$del.'INBOX';
if (!isset($content['nm']['selectedFolder'])) $content['nm']['selectedFolder'] = $this->mail_bo->profileID.$del.'INBOX';
$content['nm']['foldertree'] = $content['nm']['selectedFolder'];
$sel_options['cat_id'] = array(1=>'none');
if (!isset($content['nm']['cat_id'])) $content['nm']['cat_id'] = 'All';
@ -281,7 +285,7 @@ class mail_ui
// retrieve data for/from user defined accounts
$selectedID = 0;
if($this->preferences->userDefinedAccounts) $allAccountData = $this->bopreferences->getAllAccountData($this->preferences);
if($preferences->userDefinedAccounts) $allAccountData = $this->mail_bo->bopreferences->getAllAccountData($preferences);
if ($allAccountData) {
foreach ($allAccountData as $tmpkey => $accountData)
{
@ -291,7 +295,7 @@ class mail_ui
//_debug_array($icServer);
//error_log(__METHOD__.__LINE__.' Userdefined Profiles ImapServerId:'.$icServer->ImapServerId);
if (empty($icServer->host)) continue;
$identities[$identity->id]=$identity->realName.' '.$identity->organization.' &lt;'.$identity->emailAddress.'&gt';
$identities[$identity->id]=$identity->realName.' '.$identity->organization.' &lt;'.$identity->emailAddress.'&gt;';
if (!empty($identity->default)) $identities[$identity->id] = $identities[$identity->id].'<b>('.lang('selected').')</b>';
}
}
@ -301,7 +305,7 @@ class mail_ui
_debug_array($identities);
}
if (empty($imapServer->host) && count($identities)==0 && $this->preferences->userDefinedAccounts)
if (empty($imapServer->host) && count($identities)==0 && $preferences->userDefinedAccounts)
{
// redirect to new personal account
egw::redirect_link('/index.php',array('menuaction'=>'mail.uipreferences.editAccountData',
@ -336,8 +340,35 @@ class mail_ui
if (isset($sentFolder) && $sentFolder != 'none') $userDefinedFunctionFolders['Sent'] = $sentFolder;
if (isset($draftFolder) && $draftFolder != 'none') $userDefinedFunctionFolders['Drafts'] = $draftFolder;
if (isset($templateFolder) && $templateFolder != 'none') $userDefinedFunctionFolders['Templates'] = $templateFolder;
//_debug_array($folderObjects);
$out = array('id' => 0);
$del = $this->mail_bo->getHierarchyDelimiter(false);
if($this->mail_bo->mailPreferences->userDefinedAccounts) $allAccountData = $this->mail_bo->bopreferences->getAllAccountData($this->mail_bo->mailPreferences);
if ($allAccountData) {
foreach ($allAccountData as $tmpkey => $accountData)
{
$identity =& $accountData['identity'];
$icServer =& $accountData['icServer'];
//_debug_array($identity);
//_debug_array($icServer);
//if ($icServer->ImapServerId<>6) continue;
//error_log(__METHOD__.__LINE__.' Userdefined Profiles ImapServerId:'.$icServer->ImapServerId);
if (empty($icServer->host)) continue;
$identities[$icServer->ImapServerId]=$identity->realName.' '.$identity->organization.' &lt;'.$identity->emailAddress.'&gt;';
$oA = array('id'=>$icServer->ImapServerId,
'text'=>$identities[$icServer->ImapServerId], //$this->mail_bo->profileID,
'tooltip'=>'('.$icServer->ImapServerId.') '.htmlspecialchars_decode($identities[$icServer->ImapServerId]),
'im0' => 'thunderbird.png',
'im1' => 'thunderbird.png',
'im2' => 'thunderbird.png',
'path'=> array($icServer->ImapServerId),
'child'=> 1,
'parent' => ''
);
$this->setOutStructure($oA,$out,$del);
}
}
//_debug_array($folderObjects);
$c = 0;
foreach($folderObjects as $key => $obj)
{
@ -350,10 +381,11 @@ class mail_ui
// the rest of the array is the name of the parent
$parentName = implode((array)$folderParts,$obj->delimiter);
$path = $key; //$obj->folderName; //$obj->delimiter
$parentName = $this->mail_bo->profileID.$obj->delimiter.$parentName;
$oA =array('text'=> $obj->shortDisplayName, 'tooltip'=> $obj->displayName);
array_unshift($fFP,$this->mail_bo->profileID);
$oA['path'] = $fFP;
$path = $key; //$obj->folderName; //$obj->delimiter
if ($fS['unseen']) $oA['text'] = '<b>'.$oA['text'].' ('.$fS['unseen'].')</b>';
if ($path=='INBOX')
{
@ -377,6 +409,7 @@ class mail_ui
$oA['im1'] = "folderOpen.gif";
$oA['im2'] = "MailFolderClosed.png"; // has Children
}
$path = $this->mail_bo->profileID.$obj->delimiter.$key; //$obj->folderName; //$obj->delimiter
$oA['id'] = $path; // ID holds the PATH
if (stripos(array2string($fS['attributes']),'\noselect')!== false)
{
@ -389,10 +422,11 @@ class mail_ui
$oA['child']=1; // translates to: hasChildren -> dynamicLoading
}
$oA['parent'] = $parentName;
//_debug_array($oA);
$this->setOutStructure($oA,$out,$obj->delimiter);
$c++;
}
return ($c?$out:array('id'=>0, 'item'=>array('text'=>'INBOX','tooltip'=>'INBOX'.' '.lang('(not connected)'),'im0'=>'kfm_home.png')));
}
@ -417,7 +451,10 @@ class mail_ui
{
$parent = implode($del, $parents);
if ($parent) $parent .= $del;
if (!is_array($insert) || !isset($insert['item'])) throw new egw_exception_assertion_failed(__METHOD__.':'.__LINE__." id=$data[id]: Parent '$parent' '$component' not found! out=".array2string($out));
if (!is_array($insert) || !isset($insert['item']))
{
throw new egw_exception_assertion_failed(__METHOD__.':'.__LINE__." id=$data[id]: Parent '$parent' '$component' not found! out=".array2string($out));
}
foreach($insert['item'] as &$item)
{
if ($item['id'] == $parent.$component)
@ -777,7 +814,7 @@ class mail_ui
{
unset($query['actions']);
//error_log(__METHOD__.__LINE__.array2string($query));
error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Start:'.$query['start'].' NumRows:'.$query['num_rows']);
//error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Start:'.$query['start'].' NumRows:'.$query['num_rows']);
$starttime = microtime(true);
//error_log(__METHOD__.__LINE__.array2string($query['search']));
//$query['search'] is the phrase in the searchbox
@ -793,6 +830,16 @@ $starttime = microtime(true);
$sRToFetch = null;
$_folderName=$query['selectedFolder'];
$del = $this->mail_bo->getHierarchyDelimiter(false);
$splitFolder = explode($del,$_folderName);
if (is_numeric($splitFolder[0]))
{
array_shift($splitFolder);
$_folderName = implode($del,$splitFolder);
}
//save selected Folder to sessionData (mailbox)->currentFolder
if (isset($query['selectedFolder'])) $this->mail_bo->sessionData['maibox']=$_folderName;
$this->mail_bo->saveSessionData();
$rowsFetched['messages'] = null;
$offset = $query['start']+1; // we always start with 1
$maxMessages = $query['num_rows'];
@ -869,7 +916,7 @@ $starttime = microtime(true);
if (empty($rowsFetched['messages'])) $rowsFetched['messages'] = $rowsFetched['rowsFetched'];
//error_log(__METHOD__.__LINE__.' Rows fetched:'.$rowsFetched.' Data:'.array2string($sortResult));
$cols = array('row_id','uid','check','status','attachments','subject','toaddress','fromaddress','date','size','modified');
$cols = array('row_id','uid','status','attachments','subject','toaddress','fromaddress','date','size','modified');
if ($GLOBALS['egw_info']['user']['preferences']['common']['select_mode']=='EGW_SELECTMODE_TOGGLE') unset($cols[0]);
$rows = $this->header2gridelements($sortResult['header'],$cols, $_folderName, $folderType,$previewMessage);
//error_log(__METHOD__.__LINE__.array2string($rows));
@ -879,6 +926,31 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
return $rowsFetched['messages'];
}
/**
* function createRowID - create a unique rowID for the grid
*
* @param string $_folderName, used to ensure the uniqueness of the uid over all folders
* @param string $message_uid, the message_Uid to be used for creating the rowID
* @return string - a colon separated string in the form accountID:profileID:folder:message_uid
*/
function createRowID($_folderName, $message_uid)
{
return trim($GLOBALS['egw_info']['user']['account_id']).'::'.$this->mail_bo->profileID.'::'.base64_encode($_folderName).'::'.$message_uid;
}
/**
* function splitRowID - split the rowID into its parts
*
* @param string $_rowID, string - a colon separated string in the form accountID:profileID:folder:message_uid
* @return array populated named result array (accountID,profileID,folder,msgUID)
*/
function splitRowID($_rowID)
{
$res = explode('::',$_rowID);
// as a rowID is perceeded by app::, we ignore the first part
return array('accountID'=>$res[1], 'profileID'=>$res[2], 'folder'=>base64_decode($res[3]), 'msgUID'=>$res[4]);
}
/**
* function header2gridelements - to populate the grid elements with the collected Data
*
@ -910,7 +982,7 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
);
$message_uid = $header['uid'];
$data['uid'] = $message_uid;
$data['row_id']=trim($GLOBALS['egw_info']['user']['account_id']).':'.$this->mail_bo->profileID.':'.md5($_folderName).':'.$message_uid;
$data['row_id']=$this->createRowID($_folderName,$message_uid);
//_debug_array($header);
#if($i<10) {$i++;continue;}
@ -973,19 +1045,19 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
$css_styles[] = 'forwarded';
}
if ($header['label1']) {
$css_styles[] = 'label1';
$css_styles[] = 'labelone';
}
if ($header['label2']) {
$css_styles[] = 'label2';
$css_styles[] = 'labeltwo';
}
if ($header['label3']) {
$css_styles[] = 'label3';
$css_styles[] = 'labelthree';
}
if ($header['label4']) {
$css_styles[] = 'label4';
$css_styles[] = 'labelfour';
}
if ($header['label5']) {
$css_styles[] = 'label5';
$css_styles[] = 'labelfive';
}
//error_log(__METHOD__.array2string($css_styles));
@ -1019,41 +1091,7 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
$subject = @htmlspecialchars('('. lang('no subject') .')', ENT_QUOTES, $this->charset);
}
if($_folderType == 2 || $_folderType == 3) {
$linkData = array (
'menuaction' => 'mail.uicompose.composeFromDraft',
'icServer' => 0,
'folder' => base64_encode($_folderName),
'uid' => $header['uid'],
'id' => $header['id'],
);
$url_read_message = $GLOBALS['egw']->link('/index.php',$linkData);
$windowName = 'composeFromDraft_'.$header['uid'];
$read_message_windowName = $windowName;
$preview_message_windowName = $windowName;
} else {
# _debug_array($header);
$linkData = array (
'menuaction' => 'mail.uidisplay.display',
'showHeader' => 'false',
'mailbox' => base64_encode($_folderName),
'uid' => $header['uid'],
'id' => $header['id'],
);
$url_read_message = $GLOBALS['egw']->link('/index.php',$linkData);
$windowName = ($_readInNewWindow == 1 ? 'displayMessage' : 'displayMessage_'.$header['uid']);
if ($this->use_preview) $windowName = 'MessagePreview_'.$header['uid'].'_'.$_folderType;
$preview_message_windowName = $windowName;
}
$data["subject"] = /*'<a class="'.$css_style.'" name="subject_url" href="#"
onclick="fm_handleMessageClick(false, \''.$url_read_message.'\', \''.$preview_message_windowName.'\', this); return false;"
ondblclick="fm_handleMessageClick(true, \''.$url_read_message.'\', \''.$read_message_windowName.'\', this); return false;"
title="'.$fullSubject.'">'.$subject.'</a>';//*/ $subject; // the mailsubject
$data["subject"] = $subject; // the mailsubject
}
//_debug_array($header);
@ -1089,7 +1127,7 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
$this->mail_bo->openConnection($this->profileID); // connect to the current server
$this->mail_bo->reopen($_folderName);
}
//$attachments = $this->mail_bo->getMessageAttachments($header['uid'],$_partID='', $_structure='', $fetchEmbeddedImages=true, $fetchTextCalendar=false, $resolveTNEF=false);
$attachments = $this->mail_bo->getMessageAttachments($header['uid'],$_partID='', $_structure='', $fetchEmbeddedImages=true, $fetchTextCalendar=false, $resolveTNEF=false);
if (count($attachments)<1) $image = '&nbsp;';
}
if (count($attachments)>0) $image = "<a name=\"subject_url\" href=\"#\"
@ -1224,6 +1262,47 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
return $rv;
}
/**
* getFolderStatus - its called via json, so the function must start with ajax (or the class-name must contain ajax)
* gets the counters and sets the text of a treenode if needed (unread Messages found)
* @return nothing
*/
function ajax_setFolderStatus($_folder)
{
//error_log(__METHOD__.__LINE__.array2string($_folder));
if ($_folder)
{
$del = $this->mail_bo->getHierarchyDelimiter(false);
$oA = array();
foreach ($_folder as $_folderName)
{
$splitFolder = explode($del,$_folderName);
if (is_numeric($splitFolder[0]))
{
$fPID = array_shift($splitFolder);
if ($fPID != $this->mail_bo->profileID) continue; // only current connection
$folderName = implode($del,$splitFolder);
if ($folderName)
{
$fS = $this->mail_bo->getFolderStatus($folderName,false);
//error_log(__METHOD__.__LINE__.array2string($fS));
if ($fS['unseen'])
{
$oA[$_folderName] = '<b>'.$fS['shortDisplayName'].' ('.$fS['unseen'].')</b>';
}
}
}
}
//error_log(__METHOD__.__LINE__.array2string($oA));
if ($oA)
{
$response = egw_json_response::get();
$response->call('mail_setFolderStatus',$oA,'mail');
}
}
}
/**
* empty trash folder - its called via json, so the function must start with ajax (or the class-name must contain ajax)
*
@ -1258,4 +1337,51 @@ error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Star
}
}
/**
* flag messages as read, unread, flagged, ...
*
* @param string _flag name of the flag
* @param array _messageList list of UID's
*
* @return xajax response
*/
function ajax_flagMessages($_flag, $_messageList)
{
if($this->_debug) error_log(__METHOD__."->".$_flag.':'.print_r($_messageList,true));
if ($_messageList=='all' || !empty($_messageList['msg']))
{
if ($_messageList=='all')
{
// we have no folder information
$folder=null;
}
else
{
$uidA = $this->splitRowID($_messageList['msg'][0]);
$folder = $uidA['folder']; // all messages in one set are supposed to be within the same folder
}
foreach($_messageList['msg'] as $rowID)
{
$hA = $this->splitRowID($rowID);
$messageList[] = $hA['msgUID'];
}
$this->mail_bo->flagMessages($_flag, ($_messageList=='all' ? 'all':$messageList),$folder);
}
else
{
if($this->_debug) error_log(__METHOD__."-> No messages selected.");
}
// unset preview, as refresh would mark message again read
/*
if ($_flag == 'unread' && in_array($this->sessionData['previewMessage'], $_messageList['msg']))
{
unset($this->sessionData['previewMessage']);
$this->saveSessionData();
}
*/
$response = egw_json_response::get();
$response->call('egw_refresh',lang('flagged %1 messages as %2 in %3',count($_messageList['msg']),$_flag,$folder),'mail');
}
}

View File

@ -9,7 +9,7 @@
*/
var mail_doTimedRefresh;
var mail_refreshTimeOut = 1000*60*3;
var mail_refreshTimeOut = 1000*10; // initial call
mail_startTimerFolderStatusUpdate(mail_refreshTimeOut);
/**
@ -27,25 +27,74 @@ function mail_startTimerFolderStatusUpdate(_refreshTimeOut) {
if(mail_doTimedRefresh) {
window.clearTimeout(mail_doTimedRefresh);
}
if(_refreshTimeOut > 59000) {//we do not set _refreshTimeOut's less than a minute
if(_refreshTimeOut > 9999) {//we do not set _refreshTimeOut's less than 10 seconds (our initial call)
mail_doTimedRefresh = window.setInterval("mail_refreshFolderStatus()", _refreshTimeOut);
}
}
/**
* mail_refreshFolderStatus, function to call to read the counters of a folder and apply them
*
* @param _nodeID
* @param mode
*/
function mail_refreshFolderStatus(_nodeID,mode) {
/*
var nodeToRefresh = 0;
var mode2use = "none";
if (_nodeID) nodeToRefresh = _nodeID;
if (mode) {
if (mode == "forced") {mode2use = mode;}
}
var activeFolders = getTreeNodeOpenItems(nodeToRefresh,mode2use);
queueRefreshFolderList(activeFolders);
var tree_wdg = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm[foldertree]');
var activeFolders = tree_wdg.getTreeNodeOpenItems(nodeToRefresh,mode2use);
//alert(activeFolders.join('#,#'));
mail_queueRefreshFolderList(activeFolders);
mail_refreshMessageGrid();
}
var mail_queuedFolders = [];
var mail_queuedFoldersIndex = 0;
/**
* Queues a refreshFolderList request for 1ms. Actually this will just execute the
* code after the calling script has finished.
*/
function mail_queueRefreshFolderList(_folders)
{
mail_queuedFolders.push(_folders);
mail_queuedFoldersIndex++;
// Copy idx onto the anonymous function scope
var idx = mail_queuedFoldersIndex;
window.setTimeout(function() {
if (idx == mail_queuedFoldersIndex)
{
//var folders = mail_queuedFolders.join(",");
mail_queuedFoldersIndex = 0;
mail_queuedFolders = [];
var request = new egw_json_request('mail.mail_ui.ajax_setFolderStatus',[_folders]);
request.sendRequest();
}
}, 10);
}
/**
* mail_setFolderStatus, function to set the status for the visible folders
*/
function mail_setFolderStatus(_status) {
var ftree = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm[foldertree]');
for (var i in _status) ftree.setLabel(i,_status[i]);//alert(i +'->'+_status[i]);
}
/**
* mail_refreshMessageGrid, function to call to reread ofthe current folder
*/
function mail_refreshMessageGrid() {
var nm = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm');
nm.applyFilters(); // this should refresh the active folder
}
/**
@ -59,7 +108,7 @@ function mail_refreshFolderStatus(_nodeID,mode) {
* @param string _type=null either 'edit', 'delete', 'add' or null
*/
var doStatus;
function app_refresh(_msg, _app, _id, _type)
window.register_app_refresh("mail", function(_msg, _app, _id, _type)
{
var bufferExists = false;
window.clearInterval(doStatus); // whatever message was up to be activated
@ -77,8 +126,9 @@ function app_refresh(_msg, _app, _id, _type)
// TODO: more actions
}
if (bufferExists) doStatus = window.setInterval("egw_appWindow('mail').setMsg(myMessageBuffer);", 10000);
if (bufferExists) doStatus = window.setInterval("egw_appWindow('mail').mail_setMsg(myMessageBuffer);", 10000);
}
);
/**
* mail_getMsg - gets the current Message
@ -131,9 +181,9 @@ function mail_compressFolder() {
*/
function mail_changeFolder(folder,_widget) {
//alert('change Folder called:'+folder);
app_refresh(egw.lang('change folder'), 'mail');
app_refresh(egw.lang('change folder')+'...', 'mail');
var img = _widget.getSelectedNode().images[0]; // fetch first image
if (!(img.search(eval('/'+'NoSelect'+'/'))<0))
if (!(img.search(eval('/'+'NoSelect'+'/'))<0) || !(img.search(eval('/'+'thunderbird'+'/'))<0))
{
if (_widget.event_args.length==2)
{
@ -153,9 +203,68 @@ function mail_changeFolder(folder,_widget) {
{
window.clearInterval(doStatus);
displayname = _widget.getSelectedLabel();
inBraket = displayname.search(/\(/);
if (inBraket!=-1)
{
outBraket = displayname.search(/\)/);
if (outBraket!=-1) displayname = displayname.replace(/\((.*?)\)/,"");
}
myMsg = (displayname?displayname:folder)+' '+egw.lang('selected');
app_refresh(myMsg, 'mail');
}
mail_refreshFolderStatus(folder,'forced');
}
/**
* Flag mail as 'read', 'unread', 'flagged' or 'unflagged'
*
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
* @param _elems
*/
function mail_flag(_action, _elems)
{
//alert(_action.id+' - '+_elems[0].id);
var msg = mail_getFormData(_elems);
//
mail_flagMessages(_action.id,msg);
}
/**
* Flag mail as 'read', 'unread', 'flagged' or 'unflagged'
*
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
* @param _elems
*/
function mail_flagMessages(_flag, _elems)
{
app_refresh(egw.lang('flag messages'), 'mail');
var request = new egw_json_request('mail.mail_ui.ajax_flagMessages',[_flag, _elems]);
request.sendRequest(false);
mail_refreshMessageGrid()
}
/**
* mail_getFormData
*
* @param _actionObjects, the senders
* @return structured array of message ids: array(msg=>message-ids)
*/
function mail_getFormData(_actionObjects) {
var messages = {};
if (_actionObjects.length>0)
{
messages['msg'] = [];
}
for (var i = 0; i < _actionObjects.length; i++)
{
if (_actionObjects[i].id.length>0)
{
messages['msg'][i] = _actionObjects[i].id;
}
}
return messages;
}
// Tree widget stubs
@ -168,3 +277,4 @@ console.log(action,sender);
mail_copy = function(action,sender) {
console.log(action,sender);
}

View File

@ -2,7 +2,7 @@
/**
* EGroupware - eTemplates for Application mail
* http://www.egroupware.org
* generated by soetemplate::dump4setup() 2013-02-18 16:15
* generated by soetemplate::dump4setup() 2013-02-19 17:21
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package mail
@ -14,7 +14,7 @@ $templ_version=1;
$templ_data[] = array('name' => 'mail.index','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:3:{i:0;a:4:{s:7:"onclick";s:47:"mail_changeFolder(widget.event_args[0],widget);";s:4:"name";s:14:"nm[foldertree]";s:4:"type";s:4:"tree";s:11:"parent_node";s:11:"tree_target";}i:1;a:2:{s:4:"type";s:4:"html";s:4:"name";s:3:"msg";}i:2;a:3:{s:4:"name";s:2:"nm";s:4:"size";s:15:"mail.index.rows";s:4:"type";s:9:"nextmatch";}}','size' => '','style' => '','modified' => '1360682502',);
$templ_data[] = array('name' => 'mail.index.rows','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:7:{s:2:"c1";s:2:"th";s:1:"A";s:2:"25";s:1:"F";s:2:"50";s:1:"E";s:3:"120";s:1:"D";s:3:"120";s:1:"C";s:2:"95";s:2:"c2";s:16:"$row_cont[class]";}i:1;a:6:{s:1:"A";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:2:"ID";s:4:"name";s:3:"uid";s:8:"readonly";s:1:"1";}s:1:"B";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:7:"subject";s:5:"label";s:7:"subject";}s:1:"C";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"date";s:4:"name";s:4:"date";s:5:"align";s:6:"center";}s:1:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:2:"to";s:4:"name";s:9:"toaddress";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"from";s:4:"name";s:11:"fromaddress";}s:1:"F";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"size";s:4:"name";s:4:"size";s:5:"align";s:6:"center";}}i:2;a:6:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"name";s:11:"${row}[uid]";s:8:"readonly";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[subject]";}s:1:"C";a:4:{s:4:"type";s:15:"date-time_today";s:4:"name";s:12:"${row}[date]";s:8:"readonly";s:1:"1";s:5:"align";s:6:"center";}s:1:"D";a:3:{s:4:"type";s:9:"url-email";s:4:"name";s:17:"${row}[toaddress]";s:8:"readonly";s:1:"1";}s:1:"E";a:3:{s:4:"type";s:9:"url-email";s:4:"name";s:19:"${row}[fromaddress]";s:8:"readonly";s:1:"1";}s:1:"F";a:5:{s:4:"type";s:8:"vfs-size";s:4:"name";s:12:"${row}[size]";s:7:"no_lang";s:1:"1";s:8:"readonly";s:1:"1";s:5:"align";s:5:"right";}}}s:4:"rows";i:2;s:4:"cols";i:6;}}','size' => '','style' => '','modified' => '1360252030',);
$templ_data[] = array('name' => 'mail.index.rows','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:9:{s:2:"c1";s:2:"th";s:1:"A";s:2:"25";s:1:"F";s:3:"120";s:1:"E";s:2:"95";s:2:"c2";s:16:"$row_cont[class]";s:1:"G";s:3:"120";s:1:"H";s:2:"50";s:1:"C";s:2:"20";s:1:"B";s:2:"20";}i:1;a:8:{s:1:"A";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:2:"ID";s:4:"name";s:3:"uid";s:8:"readonly";s:1:"1";}s:1:"B";a:4:{s:4:"type";s:16:"nextmatch-header";s:4:"name";s:6:"status";s:5:"label";s:3:"St.";s:4:"help";s:6:"Status";}s:1:"C";a:4:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:3:"...";s:4:"name";s:11:"attachments";s:4:"help";s:16:"attachments, ...";}s:1:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:7:"subject";s:5:"label";s:7:"subject";}s:1:"E";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"date";s:4:"name";s:4:"date";s:5:"align";s:6:"center";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:2:"to";s:4:"name";s:9:"toaddress";}s:1:"G";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"from";s:4:"name";s:11:"fromaddress";}s:1:"H";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"size";s:4:"name";s:4:"size";s:5:"align";s:6:"center";}}i:2;a:8:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"name";s:11:"${row}[uid]";s:8:"readonly";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"span";s:12:"1,status_img";}s:1:"C";a:2:{s:4:"type";s:4:"html";s:4:"name";s:19:"${row}[attachments]";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[subject]";}s:1:"E";a:4:{s:4:"type";s:15:"date-time_today";s:4:"name";s:12:"${row}[date]";s:8:"readonly";s:1:"1";s:5:"align";s:6:"center";}s:1:"F";a:3:{s:4:"type";s:9:"url-email";s:4:"name";s:17:"${row}[toaddress]";s:8:"readonly";s:1:"1";}s:1:"G";a:3:{s:4:"type";s:9:"url-email";s:4:"name";s:19:"${row}[fromaddress]";s:8:"readonly";s:1:"1";}s:1:"H";a:5:{s:4:"type";s:8:"vfs-size";s:4:"name";s:12:"${row}[size]";s:7:"no_lang";s:1:"1";s:8:"readonly";s:1:"1";s:5:"align";s:5:"right";}}}s:4:"rows";i:2;s:4:"cols";i:8;}}','size' => '','style' => '','modified' => '1360252030',);
$templ_data[] = array('name' => 'mail.TestConnection','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:1;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1360585356',);

View File

@ -29,34 +29,34 @@ tr.unseen a {
font-weight: bold;
}
tr.label1 div,
tr.label1 span,
tr.label1 time,
tr.label1 a {
tr.labelone div,
tr.labelone span,
tr.labelone time,
tr.labelone a {
color: #ff0080 !important;
}
tr.label2 div,
tr.label2 span,
tr.label2 time,
tr.label2 a {
tr.labeltwo div,
tr.labeltwo span,
tr.labeltwo time,
tr.labeltwo a {
color: #ff8000 !important;
}
tr.label3 div,
tr.label3 span,
tr.label3 time,
tr.label3 a {
tr.labelthree div,
tr.labelthree span,
tr.labelthree time,
tr.labelthree a {
color: #008000 !important;
}
tr.label4 div,
tr.label4 span,
tr.label4 time,
tr.label4 a {
tr.labelfour div,
tr.labelfour span,
tr.labelfour time,
tr.labelfour a {
color: #0000ff !important;
}
tr.label5 div,
tr.label5 span,
tr.label5 time,
tr.label5 a {
tr.labelfive div,
tr.labelfive span,
tr.labelfive time,
tr.labelfive a {
color: #8000ff !important;
}
@ -210,7 +210,12 @@ pre {
white-space: -o-pre-wrap; /* Opera 7 */
width: 99%;
}
/*
.dhtmlxTree {
max-height: 300px;
overflow: scroll;
}
*/
.dtree {
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 11px;

View File

@ -5,6 +5,8 @@
<grid>
<columns>
<column width="25"/>
<column width="20"/>
<column width="20"/>
<column/>
<column width="95"/>
<column width="120"/>
@ -14,6 +16,8 @@
<rows>
<row class="th">
<nextmatch-header label="ID" id="uid" readonly="true"/>
<nextmatch-header statustext="Status" label="St." id="status"/>
<nextmatch-header statustext="attachments, ..." label="..." id="attachments"/>
<nextmatch-sortheader label="subject" id="subject"/>
<nextmatch-sortheader align="center" label="date" id="date"/>
<nextmatch-sortheader label="to" id="toaddress"/>
@ -22,6 +26,8 @@
</row>
<row class="$row_cont[class]">
<description id="${row}[uid]" readonly="true"/>
<description span="1" class="status_img"/>
<html id="${row}[attachments]"/>
<description id="${row}[subject]"/>
<date-time_today align="center" id="${row}[date]" readonly="true"/>
<url-email id="${row}[toaddress]" readonly="true"/>