From 2a001498a1f140fc707066823b01cb6b7964bc2a Mon Sep 17 00:00:00 2001 From: Klaus Leithoff Date: Mon, 13 May 2013 14:42:42 +0000 Subject: [PATCH] implement delete action on tree; only the deletion of leafs (Items without children) is allowed and implemented by now --- mail/inc/class.mail_bo.inc.php | 21 +++++++ mail/inc/class.mail_ui.inc.php | 85 ++++++++++++++++++++++++++- mail/js/app.js | 101 +++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 1 deletion(-) diff --git a/mail/inc/class.mail_bo.inc.php b/mail/inc/class.mail_bo.inc.php index 5a88db2b2d..1e7323f7f7 100644 --- a/mail/inc/class.mail_bo.inc.php +++ b/mail/inc/class.mail_bo.inc.php @@ -1628,6 +1628,27 @@ class mail_bo } + /** + * delete an existing folder + * + * @param string _folderName the name of the folder to be deleted + * + * @return bool true on success, PEAR Error on failure + */ + function deleteFolder($_folderName) + { + $folderName = $this->_encodeFolderName($_folderName); + + $this->icServer->unsubscribeMailbox($folderName); + $rv = $this->icServer->deleteMailbox($folderName); + if ( PEAR::isError($rv) ) { + if (self::$debug) error_log(__METHOD__." failed for $folderName with error: ".print_r($rv->message,true)); + return $rv; + } + + return true; + } + function subscribe($_folderName, $_status) { if (self::$debug) error_log(__METHOD__."::".($_status?"":"un")."subscribe:".$_folderName); diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php index 8193cc1dca..4f74990960 100644 --- a/mail/inc/class.mail_ui.inc.php +++ b/mail/inc/class.mail_ui.inc.php @@ -210,11 +210,16 @@ class mail_ui 'acceptedTypes' => 'mail', 'type' => 'drop', ), - // Tree doesn't support this one - yet + // Tree does support this one 'rename' => array( 'caption' => 'Rename', 'type' => 'popup', 'onExecute' => 'javaScript:app.mail.mail_RenameFolder' + ), + 'delete' => array( + 'caption' => 'Delete', + 'type' => 'popup', + 'onExecute' => 'javaScript:app.mail.mail_DeleteFolder' ) )); @@ -763,6 +768,20 @@ class mail_ui 'onExecute' => 'javaScript:app.mail.mail_mailsource', 'allowOnMultiple' => false, ), + 'openastext' => array( + 'caption' => lang('Open in Text mode'), + 'group' => ++$group, + 'icon' => egw_vfs::mime_icon('text/plain'), + 'onExecute' => 'javaScript:app.mail.mail_openAsText', + 'allowOnMultiple' => false, + ), + 'openashtml' => array( + 'caption' => lang('Open in HTML mode'), + 'group' => $group, + 'icon' => egw_vfs::mime_icon('text/html'), + 'onExecute' => 'javaScript:app.mail.mail_openAsHtml', + 'allowOnMultiple' => false, + ), ), ), 'mark' => array( @@ -2290,6 +2309,70 @@ blockquote[type=cite] { } } + /** + * ajax_deleteFolder - its called via json, so the function must start with ajax (or the class-name must contain ajax) + * @param string $_folderName folder to delete + * @return nothing + */ + function ajax_deleteFolder($_folderName) + { + error_log(__METHOD__.__LINE__.' OldFolderName:'.array2string($_folderName)); + $success = false; + if ($_folderName) + { + $decodedFolderName = $this->mail_bo->decodeEntityFolderName($_folderName); + $del = $this->mail_bo->getHierarchyDelimiter(false); + $oA = array(); + list($profileID,$folderName) = explode(self::$delimiter,$decodedFolderName,2); + $hasChildren = false; + if (is_numeric($profileID)) + { + if ($profileID != $this->mail_bo->profileID) return; // only current connection + $pA = explode($del,$folderName); + array_pop($pA); + $parentFolder = implode($del,$pA); + if (strtoupper($folderName)!= 'INBOX') + { + //error_log(__METHOD__.__LINE__."$folderName, $parentFolder, $_newName"); + $oA = array(); + $oldFolderInfo = $this->mail_bo->getFolderStatus($folderName,false); + //error_log(__METHOD__.__LINE__.array2string($oldFolderInfo)); + if (!empty($oldFolderInfo['attributes']) && stripos(array2string($oldFolderInfo['attributes']),'\hasnochildren')=== false) + { + $hasChildren=true; // translates to: hasChildren -> dynamicLoading + $msg = lang("refused to delete folder with subfolders"); + } + else + { + $success = $this->mail_bo->deleteFolder($folderName); + if (PEAR::isError($success)) + { + $msg = $success->message; + $success = false; + } + else + { + $oA[$_folderName] = $oldFolderInfo['shortDisplayName']; + } + } + } + else + { + $msg = lang("refused to delete folder INBOX"); + } + } + $response = egw_json_response::get(); + if ($success) + { + $response->call('app.mail.mail_removeLeaf',$oA,'mail'); + } + else + { + $response->call('egw_refresh',lang('failed to delete %1 ! Reason: %2',$oldFolderInfo['shortDisplayName'],$msg),'mail'); + } + } + } + /** * empty changeProfile - its called via json, so the function must start with ajax (or the class-name must contain ajax) * diff --git a/mail/js/app.js b/mail/js/app.js index b8eb23c1c0..b1ad62e708 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -48,6 +48,56 @@ app.mail = AppJS.extend( var sw = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('previewSubject'); }, + /** + * Open a single message in html mode + * + * @param _action + * @param _elems _elems[0].id is the row-id + */ + mail_openAsHtml: function(_action, _elems) + { + //alert('mail_open('+_elems[0].id+')'); + if (activeFolderB64 == draftFolderB64 || activeFolderB64 == templateFolderB64) + { +// _action.id='composefromdraft'; +// mail_compose(_action,_elems); + } + else + { + var url = window.egw_webserverUrl+'/index.php?'; + url += 'menuaction=felamimail.uidisplay.display'; // todo compose for Draft folder + url += '&uid='+_elems[0].id; + url += '&tryashtml=1'; + + egw_openWindowCentered(_url,'displayMessage_'+_elems[0].id,'700','600',window.outerWidth/2,window.outerHeight/2); + } + }, + + /** + * Open a single message in plain text mode + * + * @param _action + * @param _elems _elems[0].id is the row-id + */ + mail_openAsText: function(_action, _elems) + { + //alert('mail_open('+_elems[0].id+')'); + if (activeFolderB64 == draftFolderB64 || activeFolderB64 == templateFolderB64) + { +// _action.id='composefromdraft'; +// mail_compose(_action,_elems); + } + else + { + var url = window.egw_webserverUrl+'/index.php?'; + url += 'menuaction=felamimail.uidisplay.display'; // todo compose for Draft folder + url += '&uid='+_elems[0].id; + url += '&tryastext=1'; + + egw_openWindowCentered(_url,'displayMessage_'+_elems[0].id,'700','600',window.outerWidth/2,window.outerHeight/2); + } + }, + /** * mail_preview - implementation of the preview action * @@ -201,6 +251,32 @@ app.mail = AppJS.extend( } }, + /** + * mail_removeLeaf, function to remove the leaf represented by the given ID + * @param array _status status array with the required data (KEY id, VALUE desc) + * key is the id of the leaf to delete + * multiple sets can be passed to mail_deleteLeaf + */ + mail_removelLeaf: function(_status) { + //console.log('mail_setLeaf',_status); + var ftree = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm[foldertree]'); + var selectedNode = ftree.getSelectedNode(); + for (var i in _status) + { + // if olddesc is undefined or #skip# then skip the message, as we process subfolders + if (typeof _status[i] !== 'undefined' && _status[i] !== '#skip-user-interaction-message#') app.mail.app_refresh(egw.lang("Removed Folder %1 ",_status[i], 'mail')); + ftree.deleteItem(i,(selectedNode.id==i)); + var selectedNodeAfter = ftree.getSelectedNode(); + //alert(i +'->'+_status[i]['id']+'+'+_status[i]['desc']); + if (selectedNodeAfter.id!=selectedNode.id && selectedNode.id==i) + { + var nm = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm'); + nm.activeFilters["selectedFolder"] = selectedNodeAfter.id; + nm.applyFilters(); + } + } + }, + /** * mail_refreshMessageGrid, function to call to reread ofthe current folder */ @@ -651,5 +727,30 @@ app.mail = AppJS.extend( var request = new egw_json_request('mail.mail_ui.ajax_renameFolder',[_senders[0].iface.id, NewFolderName]); request.sendRequest(true); } + }, + + /** + * mail_DeleteFolder - implementation of the DeleteFolder action of right click options on the tree + * + * @param _action + * @param _senders - the representation of the tree leaf to be manipulated + */ + mail_DeleteFolder: function(action,_senders) { + //console.log(action,_senders); + //action.id == 'delete' + //_senders.iface.id == target leaf / leaf to edit + var ftree = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm[foldertree]'); + OldFolderName = ftree.getLabel(_senders[0].iface.id); + if (jQuery(OldFolderName).text().length>0) OldFolderName = jQuery(OldFolderName).text(); + OldFolderName = OldFolderName.trim(); + OldFolderName = OldFolderName.replace(/\([0-9]*\)/g,'').trim(); + //console.log(OldFolderName); + reallyDelete = confirm(egw.lang("Do you really want to DELETE Folder %1 ? \r\nAll messages in the folder will be lost",OldFolderName)); + if (reallyDelete) + { + app.mail.app_refresh(egw.lang("Deleting Folder %1",OldFolderName, 'mail')); + var request = new egw_json_request('mail.mail_ui.ajax_deleteFolder',[_senders[0].iface.id]); + request.sendRequest(true); + } } });