egroupware/mail/js/app.js
Hadi Nategh 9d1727d077 Backport commit 47927 committed by NathanGray.Don't send mail rows when opening mail app, but use client side cache instead.
Gives large speed improvements when changing to previously opened folders.
2014-08-04 09:44:35 +00:00

3553 lines
106 KiB
JavaScript

/**
* mail - static javaScript functions
*
* @link http://www.egroupware.org
* @author Stylite AG [info@stylite.de]
* @copyright (c) 2013-2014 by Stylite AG <info-AT-stylite.de>
* @package mail
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
/*egw:uses
phpgwapi.jquery.jquery.base64;
*/
/**
* UI for mail
*
* @augments AppJS
*/
app.classes.mail = AppJS.extend(
{
appname: 'mail',
/**
* et2 widget container
*/
et2: null,
doStatus: null,
mail_queuedFolders: [],
mail_queuedFoldersIndex: 0,
mail_selectedMails: [],
mail_currentlyFocussed: '',
mail_previewAreaActive: true, // we start with the area active
nm_index: 'nm', // nm name of index
mail_fileSelectorWindow: null,
mail_isMainWindow: true,
// Some state variables to track preview pre-loading
preview_preload: {
timeout: null,
request: null
},
/**
* abbrevations for common access rights
* @array
*
*/
aclCommonRights:['lrs','lprs','ilprs', 'ilprsw', 'aeiklprstwx', 'custom'],
/**
* Demonstrates ACL rights
* @array
*
*/
aclRights:['l','r','s','w','i','p','c','d','a'],
/**
* Initialize javascript for this application
*
* @memberOf mail
*/
init: function() {
this._super.apply(this,arguments);
// Turn on client side, persistent cache
// egw.data system runs encapsulated below etemplate, so this must be
// done before the nextmatch is created.
this.egw.dataCacheRegister('mail',this.nm_cache, this);
},
/**
* Destructor
*/
destroy: function()
{
// Unbind from nm refresh
if(this.et2 != null)
{
var nm = this.et2.getWidgetById(this.nm_index);
if(nm != null)
{
$j(nm).off('refresh');
}
}
// Unregister client side cache
this.egw.dataCacheUnregister('mail');
delete this.et2_obj;
// call parent
this._super.apply(this, arguments);
},
/**
* check and try to reinitialize et2 of module
*/
checkET2: function()
{
//this.et2 should do the same as etemplate2.getByApplication('mail')[0].widgetContainer
if (!this.et2) // if not defined try this in order to recover
{
try
{
this.et2 = etemplate2.getByApplication('mail')[0].widgetContainer;
}
catch(e)
{
return false;
}
}
return true;
},
/**
* This function is called when the etemplate2 object is loaded
* and ready. If you must store a reference to the et2 object,
* make sure to clean it up in destroy().
*
* @param et2 etemplate2 Newly ready object
* @param {string} _name template name
*/
et2_ready: function(et2, _name)
{
// call parent; somehow this function is called more often. (twice on a display and compose) why?
this._super.apply(this, arguments);
this.et2_obj = et2;
switch (_name)
{
case 'mail.sieve.vacation':
this.vacationFilterStatusChange();
break;
case 'mail.index':
var nm = this.et2.getWidgetById(this.nm_index);
this.mail_isMainWindow = true;
this.mail_disablePreviewArea(true);
// Bind to nextmatch refresh to update folder status
if(nm != null && (typeof jQuery._data(nm).events=='undefined'||typeof jQuery._data(nm).events.refresh == 'undefined'))
{
var self = this;
$j(nm).on('refresh',function() {self.mail_refreshFolderStatus.call(self,undefined,undefined,false);});
}
var tree_wdg = this.et2.getWidgetById(this.nm_index+'[foldertree]');
if (tree_wdg)
{
tree_wdg.set_onopenstart(jQuery.proxy(this.openstart_tree, this));
tree_wdg.set_onopenend(jQuery.proxy(this.openend_tree, this));
}
break;
case 'mail.display':
var subject = this.et2.getWidgetById('mail_displaysubject');
var body = this.et2.getWidgetById('mailDisplayBodySrc');
this.mail_isMainWindow = false;
this.mail_display();
body.node.parentNode.style.top=subject.node.offsetTop+40+'px';
var app_registry = egw.link_get_registry('mail');
var w=870;
if (typeof app_registry['view'] != 'undefined' && typeof app_registry['view_popup'] != 'undefined' )
{
var w_h =app_registry['view_popup'].split('x');
if (w_h[1] == 'egw_getWindowOuterHeight()')
{
w_h[1] = (screen.availHeight>egw_getWindowOuterHeight()?screen.availHeight:egw_getWindowOuterHeight());
}
}
window.resizeTo((w_h[0]?w_h[0]:870),(w_h[1]?w_h[1]:(screen.availHeight>egw_getWindowOuterHeight()?screen.availHeight:egw_getWindowOuterHeight())));
break;
case 'mail.compose':
var that = this;
this.mail_isMainWindow = false;
this.compose_fieldExpander_hide();
/* Control focus actions on subject to handle expanders properly.*/
jQuery("#mail-compose_subject").on({
focus:function(){
that.compose_fieldExpander_hide();
that.compose_fieldExpander();
}
});
/*Trigger compose_resizeHandler after the CKEditor is fully loaded*/
jQuery('#mail-compose').load ('load', function() {that.compose_resizeHandler();});
this.compose_fieldExpander();
break;
}
},
/**
* Observer method receives update notifications from all applications
*
* App is responsible for only reacting to "messages" it is interested in!
*
* @param {string} _msg message (already translated) to show, eg. 'Entry deleted'
* @param {string} _app application name
* @param {(string|number)} _id id of entry to refresh or null
* @param {string} _type either 'update', 'edit', 'delete', 'add' or null
* - update: request just modified data from given rows. Sorting is not considered,
* so if the sort field is changed, the row will not be moved.
* - edit: rows changed, but sorting may be affected. Requires full reload.
* - delete: just delete the given rows clientside (no server interaction neccessary)
* - add: requires full reload for proper sorting
* @param {string} _msg_type 'error', 'warning' or 'success' (default)
* @param {object|null} _links app => array of ids of linked entries
* or null, if not triggered on server-side, which adds that info
* @return {false|*} false to stop regular refresh, thought all observers are run
*/
observer: function(_msg, _app, _id, _type, _msg_type, _links)
{
switch(_app)
{
case 'mail':
if (_id === 'sieve')
{
var iframe = this.et2.getWidgetById('extra_iframe');
if (iframe && iframe.getDOMNode())
{
var contentWindow = iframe.getDOMNode().contentWindow;
if (contentWindow && contentWindow.app && contentWindow.app.mail)
{
contentWindow.app.mail.sieve_refresh();
}
}
return false; // mail nextmatch needs NOT to be refreshed
}
break;
case 'emailadmin': // update tree with given mail account _id and _type
var tree = this.et2 ? this.et2.getWidgetById(this.nm_index+'[foldertree]') : null;
if (!tree) break;
var node = tree.getNode(_id);
switch(_type)
{
case 'delete':
if (node) // we dont care for deleted accounts not shown (eg. other users)
{
tree.deleteItem(_id);
// ToDo: blank list, if _id was active account
}
break
case 'update':
case 'edit':
if (node) // we dont care for updated accounts not shown (eg. other users)
{
//tree.refreshItem(_id);
egw.json('mail.mail_ui.ajax_reloadNode',[_id])
.sendRequest(true);
}
break;
case 'add':
tree.refreshItem(0); // refresh root
break;
}
}
},
/**
* Callback function for dataFetch caching.
*
* We only cache the first chunk (50 rows), and only if search filter is not set,
* but we cache this for every combination of folder, filter & filter2.
*
* @param {object} query_context Query information from egw.dataFetch()
* @returns {string|false} Cache key, or false to not cache
*/
nm_cache: function(query_context)
{
// Only cache first chunk of rows, if no search filter
if((!query_context || !query_context.start) && query_context.count == 0 && !(
query_context.self._filters.search || false)
)
{
// Make sure keys match, even if some filters are not defined
return JSON.stringify({
selectedFolder: query_context.self._filters.selectedFolder || '',
filter: query_context.self._filters.filter || '',
filter2: query_context.self._filters.filter2
});
}
return false;
},
/**
* mail rebuild Action menu On nm-list
*
* @param _actions
*/
mail_rebuildActionsOnList: function(_actions)
{
this.et2.getWidgetById(this.nm_index).set_actions(_actions);
},
/**
* mail_fetchCurrentlyFocussed - implementation to decide wich mail of all the selected ones is the current
*
* @param _selected array of the selected mails
* @param _reset bool - tell the function to reset the global vars used
*/
mail_fetchCurrentlyFocussed: function(_selected, _reset) {
// reinitialize the buffer-info on selected mails
if (_reset == true || typeof _selected == 'undefined')
{
if (_reset == true)
{
//var nm = this.et2.getWidgetById(nm_index);
//if (this.mail_currentlyFocussed!='') nm.refresh([this.mail_currentlyFocussed],'delete');//egw.dataDeleteUID(this.mail_currentlyFocussed);
if (this.mail_currentlyFocussed!='') egw.dataDeleteUID(this.mail_currentlyFocussed);
for(var k = 0; k < this.mail_selectedMails.length; k++) egw.dataDeleteUID(this.mail_selectedMails[k]);
//nm.refresh(this.mail_selectedMails,'delete');
}
this.mail_selectedMails = [];
this.mail_currentlyFocussed = '';
return '';
}
for(var k = 0; k < _selected.length; k++)
{
if (jQuery.inArray(_selected[k],this.mail_selectedMails)==-1)
{
this.mail_currentlyFocussed = _selected[k];
break;
}
}
this.mail_selectedMails = _selected;
return this.mail_currentlyFocussed;
},
/**
* mail_open - implementation of the open action
*
* @param _action
* @param _senders - the representation of the elements(s) the action is to be performed on
* @param _mode - you may pass the mode. if not given view is used (tryastext|tryashtml are supported)
*/
mail_open: function(_action, _senders, _mode) {
if (typeof _senders == 'undefined' || _senders.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _senders = [];
_senders.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _senders == 'undefined' || _senders.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _senders = [];
_senders.push({id:this.mail_currentlyFocussed});
}
}
}
var _id = _senders[0].id;
// reinitialize the buffer-info on selected mails
if (!(_mode == 'tryastext' || _mode == 'tryashtml' || _mode == 'view' || _mode == 'print')) _mode = 'view';
this.mail_selectedMails = [];
this.mail_selectedMails.push(_id);
this.mail_currentlyFocussed = _id;
var dataElem = egw.dataGetUIDdata(_id);
var subject = dataElem.data.subject;
//alert('Open Message:'+_id+' '+subject);
var h = egw().open( _id,'mail','view',_mode+'='+_id.replace(/=/g,"_") );
egw(h).ready(function() {
h.document.title = subject;
});
// THE FOLLOWING IS PROBABLY NOT NEEDED, AS THE UNEVITABLE PREVIEW IS HANDLING THE COUNTER ISSUE
var messages = {};
messages['msg'] = [_id];
// When body is requested, mail is marked as read by the mail server. Update UI to match.
if (typeof dataElem != 'undefined' && typeof dataElem.data != 'undefined' && typeof dataElem.data.flags != 'undefined' && typeof dataElem.data.flags.read != 'undefined') dataElem.data.flags.read = 'read';
if (typeof dataElem != 'undefined' && typeof dataElem.data != 'undefined' && (dataElem.data.class.indexOf('unseen') >= 0 || dataElem.data.class.indexOf('recent') >= 0))
{
this.mail_removeRowClass(messages,'recent');
this.mail_removeRowClass(messages,'unseen');
// reduce counter without server roundtrip
this.mail_reduceCounterWithoutServerRoundtrip();
// not needed, as an explizit read flags the message as seen anyhow
//egw.jsonq('mail.mail_ui.ajax_flagMessages',['read', messages, false]);
}
},
/**
* Open a single message in html mode
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_openAsHtml: function(_action, _elems)
{
this.mail_open(_action, _elems,'tryashtml');
},
/**
* Open a single message in plain text mode
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_openAsText: function(_action, _elems)
{
this.mail_open(_action, _elems,'tryastext');
},
/**
* Compose, reply or forward a message
*
* @function
* @memberOf mail
* @param _action _action.id is 'compose', 'composeasnew', 'reply', 'reply_all' or 'forward' (forward can be multiple messages)
* @param _elems _elems[0].id is the row-id
*/
mail_compose: function(_action, _elems)
{
if (typeof _elems == 'undefined' || _elems.length==0)
{
if (this.et2 && this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
}
// Extra info passed to egw.open()
var settings = {
// 'Source' Mail UID
id: '',
// How to pull data from the Mail IDs for the compose
from: ''
};
// We only handle one for everything but forward
settings.id = (typeof _elems == 'undefined'?'':_elems[0].id);
switch(_action.id)
{
case 'compose':
if (_elems.length == 1)
{
//mail_parentRefreshListRowStyle(settings.id,settings.id);
}
else
{
return this.mail_compose('forward',_elems);
}
break;
case 'forward':
case 'forwardinline':
case 'forwardasattach':
if (_elems.length>1||_action.id == 'forwardasattach')
{
settings.from = 'forward';
settings.mode = 'forwardasattach';
if (typeof _elems != 'undefined' && _elems.length>1)
{
for(var j = 1; j < _elems.length; j++)
settings.id = settings.id + ',' + _elems[j].id;
}
}
else
{
settings.from = 'forward';
settings.mode = 'forwardinline';
}
break;
default:
// No further client side processing needed for these
settings.from = _action.id;
}
var compose_list = egw.getOpenWindows("mail", /^compose_/);
var window_name = 'compose_' + compose_list.length + '_'+ (settings.from || '') + '_' + settings.id;
return egw().open('','mail','add',settings,window_name,'mail');
},
/**
* Set content into a compose window
*
* @function
* @memberOf mail
*
* @param {String} window_name The name of an open content window.
* @param {object} content
*
* @description content Data to set into the window's fields
* content.to Addresses to add to the to line
* content.cc Addresses to add to the CC line
* content.bcc Addresses to add to the BCC line
*
* @return {boolean} Success
*/
setCompose: function(window_name, content)
{
// Get window
var compose = window.open('', window_name);
if(!compose || compose.closed) return false;
// Get etemplate of popup
var compose_et2 = compose.etemplate2.getByApplication('mail');
if(!compose_et2 || compose_et2.length != 1 || !compose_et2[0].widgetContainer)
{
return false;
}
// Set each field provided
var success = true;
var arrContent = [];
for(var field in content)
{
try
{
var widget = compose_et2[0].widgetContainer.getWidgetById(field);
// Merge array values, replace strings
var value = widget.getValue() || content[field];
if(jQuery.isArray(value))
{
if(jQuery.isArray(content[field]))
{
value.concat(content[field]);
}
else
{
arrContent = content[field].split(',');
for (var k=0;k < arrContent.length;k++)
{
value.push(arrContent[k]);
}
}
}
widget.set_value(value);
}
catch(e)
{
egw.log("error", "Unable to set field %s to '%s' in window '%s'", field, content[field],window_name);
success = false;
continue;
}
}
if (content['cc'] || content['bcc'])
{
this.compose_fieldExpander();
}
return success;
},
/**
* mail_disablePreviewArea - implementation of the disablePreviewArea action
*
* @param _value
*/
mail_disablePreviewArea: function(_value) {
var splitter = this.et2.getWidgetById('mailSplitter');
if (typeof splitter == 'undefined' || splitter == null) return;
var splitterDN = splitter.getDOMNode();
if(splitter.isDocked())
{
this.mail_previewAreaActive = false;
}
//this.et2.getWidgetById('mailPreviewHeadersFrom').set_disabled(_value);
//this.et2.getWidgetById('mailPreviewHeadersTo').set_disabled(_value);
//this.et2.getWidgetById('mailPreviewHeadersDate').set_disabled(_value);
//this.et2.getWidgetById('mailPreviewHeadersSubject').set_disabled(_value);
this.et2.getWidgetById('mailPreview').set_disabled(_value);
if (_value==true)
{
if (this.mail_previewAreaActive) splitter.dock();
this.mail_previewAreaActive = false;
}
else
{
if (!this.mail_previewAreaActive) splitter.undock();
this.mail_previewAreaActive = true;
}
},
/**
* Create an expand on click box
*
* @param {object} _expContent an object with at least these elements
* {build_children, data_one, data, widget, line}
*
* @param {object} _dataElem includes data of the widget which need to be expand
*
* @return _dataElem content of widgets
*/
url_email_expandOnClick: function (_expContent, _dataElem)
{
for(var j = 0; j < _expContent.length; j++)
{
var field = _expContent[j] || [];
var content = _dataElem.data[field.data] || [];
// Add in single address, if there
if(typeof field.data_one != 'undefined')
{
content.unshift(_dataElem.data[field.data_one]);
// Unique
content = content.filter(function(value, index, self) {
return self.indexOf(value) === index;
});
}
// Disable whole box if there are none
var line = this.et2.getWidgetById(field.line);
if(line != null) line.set_disabled(content.length == 0);
var widget = this.et2.getWidgetById(field.widget);
if(widget == null) continue;
$j(widget.getDOMNode()).removeClass('visible');
// Programatically build the child elements
if(field.build_children)
{
// Remove any existing
var children = widget.getChildren();
for(var i = children.length-1; i >= 0; i--)
{
children[i].destroy();
widget.removeChild(children[i]);
}
if (content.length == 1 && typeof content[0] != 'undefined' && content[0])
{
content = content[0].split(',');
}
// Add for current record
for(var i = 0; i < content.length; i++)
{
var value = content[i];
var email = et2_createWidget('url-email',{id:widget.id+'_'+i, value:value,readonly:true},widget);
email.loadingFinished();
}
}
else
{
widget.set_value({content: content});
}
// Show or hide button, as needed
line.iterateOver(function(button) {
// Avoid binding to any child buttons
if(button.getParent() != line) return;
button.set_disabled(
// Disable if only 1 address
content.length <=1 || (
// Disable if all content is visible
$j(widget.getDOMNode()).innerWidth() >= widget.getDOMNode().scrollWidth &&
$j(widget.getDOMNode()).innerHeight() >= widget.getDOMNode().scrollHeight)
);
},this,et2_button);
}
return _dataElem;
},
/**
* Set values for mail dispaly From,Sender,To,Cc, and Bcc
* Additionally, apply expand on click feature on thier widgets
*
*/
mail_display: function()
{
var dataElem = {data:{FROM:"",SENDER:"",TO:"",CC:"",BCC:""}};
var content = this.et2.getArrayMgr('content').data;
var expand_content = [
{build_children: true, data_one: 'FROM', data: 'FROM', widget: 'FROM', line: 'mailDisplayHeadersFrom'},
{build_children: true, data: 'SENDER', widget: 'SENDER', line: 'mailDisplayHeadersSender'},
{build_children: true, data: 'TO', widget: 'TO', line: 'mailDisplayHeadersTo'},
{build_children: true, data: 'CC', widget: 'CC', line: 'mailDisplayHeadersCc'},
{build_children: true, data: 'BCC', widget:'BCC', line: 'mailDisplayHeadersBcc'}
];
if (typeof content != 'undefiend')
{
dataElem.data = jQuery.extend(dataElem.data, content);
this.url_email_expandOnClick(expand_content, dataElem);
var toolbaractions = ((typeof dataElem != 'undefined' && typeof dataElem.data != 'undefined' && typeof dataElem.data.displayToolbaractions != 'undefined')?JSON.parse(dataElem.data.displayToolbaractions):undefined);
if (toolbaractions) this.et2.getWidgetById('displayToolbar').set_actions(toolbaractions);
}
// Trigger print command if the mail oppend for printing porpuse
if (window.location.search.search('&print=') >= 0)
{
var that = this;
jQuery('#mail-display_mailDisplayBodySrc').bind('load',function(){that.mail_print();});
}
},
/**
* mail_preview - implementation of the preview action
*
* @param nextmatch et2_nextmatch The widget whose row was selected
* @param selected Array Selected row IDs. May be empty if user unselected all rows.
*/
mail_preview: function(selected, nextmatch) {
// Empty values, just in case selected is empty (user cleared selection)
//dataElem.data is populated, when available with fromaddress(string),toaddress(string),additionaltoaddress(array),ccaddress (array)
var dataElem = {data:{subject:"",fromaddress:"",toaddress:"",ccaddress:"",date:"",attachmentsBlock:""}};
if(typeof selected != 'undefined' && selected.length == 1)
{
var _id = this.mail_fetchCurrentlyFocussed(selected);
dataElem = jQuery.extend(dataElem, egw.dataGetUIDdata(_id));
}
//get_class does not exist yet
//var pAAClass = this.et2.getWidgetById('previewAttachmentArea').get_class();
if (this.et2.getWidgetById('previewAttachmentArea') && typeof _id != 'undefined' && _id !='' && typeof dataElem !== 'undefined')
{
this.et2.getWidgetById('previewAttachmentArea').set_class('previewAttachmentArea');
}
else
{
// Leave if we're here and there is nothing selected, too many, or no data
this.et2.getWidgetById('previewAttachmentArea').set_value({content:[]});
this.et2.getWidgetById('previewAttachmentArea').set_class('previewAttachmentArea noContent mail_DisplayNone');
var IframeHandle = this.et2.getWidgetById('messageIFRAME');
IframeHandle.set_src('about:blank');
this.mail_disablePreviewArea(true);
return;
}
// Widget ID:data key map of widgets we can directly set from cached data
var data_widgets = {
'previewFromAddress': 'fromaddress',
'previewDate': 'date',
'previewSubject': 'subject'
};
// Set widget values from cached data
for(var id in data_widgets)
{
var widget = this.et2.getWidgetById(id);
if(widget == null) continue;
widget.set_value(dataElem.data[data_widgets[id]] || "");
}
// Blank first, so we don't show previous email while loading
var IframeHandle = this.et2.getWidgetById('messageIFRAME');
IframeHandle.set_src('about:blank');
// Set up additional content that can be expanded.
// We add a new URL widget for each address, so they get all the UI
// TO addresses have the first one split out, not all together
// list of keys:
var expand_content = [
{build_children: true, data_one: 'toaddress', data: 'additionaltoaddress', widget: 'additionalToAddress', line: 'mailPreviewHeadersTo'},
{build_children: true, data: 'ccaddress', widget: 'additionalCCAddress', line: 'mailPreviewHeadersCC'},
{build_children: false, data: 'attachmentsBlock', widget:'previewAttachmentArea', line: 'mailPreviewHeadersAttachments'}
];
dataElem = this.url_email_expandOnClick(expand_content,dataElem);
// Update the internal list of selected mails, if needed
if(this.mail_selectedMails.indexOf(_id) < 0)
{
this.mail_selectedMails.push(_id);
}
this.mail_disablePreviewArea(false);
// Request email body from server
IframeHandle.set_src(egw.link('/index.php',{menuaction:'mail.mail_ui.loadEmailBody',_messageID:_id}));
var messages = {};
messages['msg'] = [_id];
// When body is requested, mail is marked as read by the mail server. Update UI to match.
if (typeof dataElem != 'undefined' && typeof dataElem.data != 'undefined' && typeof dataElem.data.flags != 'undefined' && typeof dataElem.data.flags.read != 'undefined') dataElem.data.flags.read = 'read';
if (typeof dataElem != 'undefined' && typeof dataElem.data != 'undefined' && typeof dataElem.data.class != 'undefined' && (dataElem.data.class.indexOf('unseen') >= 0 || dataElem.data.class.indexOf('recent') >= 0))
{
this.mail_removeRowClass(messages,'recent');
this.mail_removeRowClass(messages,'unseen');
// reduce counter without server roundtrip
this.mail_reduceCounterWithoutServerRoundtrip();
if (typeof dataElem.data.dispositionnotificationto != 'undefined' && dataElem.data.dispositionnotificationto &&
typeof dataElem.data.flags.mdnsent == 'undefined' && typeof dataElem.data.flags.mdnnotsent == 'undefined')
{
var buttons = [
{text: this.egw.lang("Yes"), id: "mdnsent"},
{text: this.egw.lang("No"), id:"mdnnotsent"}
];
et2_dialog.show_dialog(function(_button_id, _value) {
switch (_button_id)
{
case "mdnsent":
egw.jsonq('mail.mail_ui.ajax_sendMDN',[messages]);
egw.jsonq('mail.mail_ui.ajax_flagMessages',['mdnsent', messages, true]);
return;
case "mdnnotsent":
egw.jsonq('mail.mail_ui.ajax_flagMessages',['mdnnotsent', messages, true]);
}
},
this.egw.lang("The message sender has requested a response to indicate that you have read this message. Would you like to send a receipt?"),
this.egw.lang("Confirm"),
messages, buttons);
}
egw.jsonq('mail.mail_ui.ajax_flagMessages',['read', messages, false]);
}
// Pre-load next email already so user gets it faster
// Browser will cache the file for us
/*
var fO = egw_getObjectManager('mail',false,1).getObjectById(this.nm_index).getFocusedObject();
var next = false;
if (fO) next = fO.getNext(1);
// Stop until we get all the details worked out - server marks as seen automatically
if(false && next && next.id)
{
if(this.preview_preload.timer != null)
{
window.clearTimeout(this.preview_preload.timer);
}
// Wait 0.5s to avoid flooding server if user is scrolling through their mail
this.preview_preload.timer = window.setTimeout( jQuery.proxy(function() {
this.preview_preload.request = jQuery.get(
egw.link('/index.php',{menuaction:'mail.mail_ui.loadEmailBody',_messageID:next.id})
);
},this),500);
}
*/
},
/**
* If a preview header is partially hidden, this is the handler for clicking the
* expand button that shows all the content for that header.
* The button must be directly after the widget to be expanded in the template.
* The widget to be expended is set in the event data.
*
* requires: mainWindow, one mail selected for preview
*
* @param {jQuery event} event
* @param {Object} widget
* @param {DOMNode} button
*/
showAllHeader: function(event,widget,button) {
// Show list as a list
var list = jQuery(button).prev();
/* if (list.length <= 0)
{
list = jQuery(button.target).prev();
}*/
list.toggleClass('visible');
// Revert if user clicks elsewhere
$j('body').one('click', list, function(ev) {
ev.data.removeClass('visible');
});
},
mail_setMailBody: function(content) {
var IframeHandle = this.et2.getWidgetById('messageIFRAME');
IframeHandle.set_value('');
},
/**
* mail_refreshFolderStatus, function to call to read the counters of a folder and apply them
*
* @param {stirng} _nodeID
* @param {string} mode
* @param {boolean} _refreshGridArea
* @param {boolean} _refreshQuotaDisplay
*
*/
mail_refreshFolderStatus: function(_nodeID,mode,_refreshGridArea,_refreshQuotaDisplay) {
if (typeof _nodeID != 'undefined' && typeof _nodeID[_nodeID] != 'undefined' && _nodeID[_nodeID])
{
_refreshGridArea = _nodeID[_refreshGridArea];
mode = _nodeID[mode];
_nodeID = _nodeID[_nodeID];
}
var nodeToRefresh = 0;
var mode2use = "none";
if (typeof _refreshGridArea == 'undefined') _refreshGridArea=true;
if (typeof _refreshQuotaDisplay == 'undefined') _refreshQuotaDisplay=true;
if (_nodeID) nodeToRefresh = _nodeID;
if (mode) {
if (mode == "forced") {mode2use = mode;}
}
try
{
var tree_wdg = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var activeFolders = tree_wdg.getTreeNodeOpenItems(nodeToRefresh,mode2use);
//alert(activeFolders.join('#,#'));
this.mail_queueRefreshFolderList((mode=='thisfolderonly'&&nodeToRefresh?[_nodeID]:activeFolders));
if (_refreshGridArea)
{
// maybe to use the mode forced as trigger for grid reload and using the grids own autorefresh
// would solve the refresh issue more accurately
//if (mode == "forced") this.mail_refreshMessageGrid();
this.mail_refreshMessageGrid();
}
if (_refreshQuotaDisplay)
{
this.mail_refreshQuotaDisplay();
}
//the two lines below are not working yet.
//var no =tree_wdg.getSelectedNode();
//tree_wdg.focusItem(no.id);
} catch(e) { } // ignore the error; maybe the template is not loaded yet
},
/**
* mail_refreshQuotaDisplay, function to call to read the quota for the active server
*
* @param {object} _server
*
*/
mail_refreshQuotaDisplay: function(_server)
{
egw.json('mail.mail_ui.ajax_refreshQuotaDisplay',[_server])
.sendRequest(true);
},
/**
* mail_setQuotaDisplay, function to call to read the quota for the active server
*
* @param {object} _data
*
*/
mail_setQuotaDisplay: function(_data)
{
if (!this.et2 && !this.checkET2()) return;
var quotabox = this.et2.getWidgetById(this.nm_index+'[quotainpercent]');
// Check to make sure it's there
if(quotabox)
{
//try to set it via set_value and set label
quotabox.set_class(_data.data.quotaclass);
quotabox.set_value(_data.data.quotainpercent);
quotabox.set_label(_data.data.quota);
}
},
/**
* mail_callRefreshVacationNotice, function to call the serverside function to refresh the vacationnotice for the active server
*
* @param {object} _server
*
*/
mail_callRefreshVacationNotice: function(_server)
{
egw.jsonq('mail.mail_ui.ajax_refreshVacationNotice',[_server]);
},
/**
* mail_refreshVacationNotice, function to call with appropriate data to refresh the vacationnotice for the active server
*
* @param {object} _data
*
*/
mail_refreshVacationNotice: function(_data)
{
if (!this.et2 && !this.checkET2()) return;
if (_data == null)
{
this.et2.getWidgetById(this.nm_index+'[vacationnotice]').set_value('');
this.et2.getWidgetById(this.nm_index+'[vacationrange]').set_value('');
}
else
{
this.et2.getWidgetById(this.nm_index+'[vacationnotice]').set_value(_data.vacationnotice);
this.et2.getWidgetById(this.nm_index+'[vacationrange]').set_value(_data.vacationrange);
}
},
/**
* mail_refreshFilter2Options, function to call with appropriate data to refresh the filter2 options for the active server
*
* @param {object} _data
*
*/
mail_refreshFilter2Options: function(_data)
{
//alert('mail_refreshFilter2Options');
if (_data == null) return;
if (!this.et2 && !this.checkET2()) return;
var filter2 = this.et2.getWidgetById('filter2');
var current = filter2.value;
var currentexists=false;
for (var k in _data)
{
if (k==current) currentexists=true;
}
if (!currentexists) filter2.set_value('subject');
filter2.set_select_options(_data);
},
/**
* mail_refreshFilterOptions, function to call with appropriate data to refresh the filter options for the active server
*
* @param {object} _data
*
*/
mail_refreshFilterOptions: function(_data)
{
//alert('mail_refreshFilterOptions');
if (_data == null) return;
if (!this.et2 && !this.checkET2()) return;
var filter = this.et2.getWidgetById('filter');
var current = filter.value;
var currentexists=false;
for (var k in _data)
{
if (k==current) currentexists=true;
}
if (!currentexists) filter.set_value('any');
filter.set_select_options(_data);
},
/**
* Queues a refreshFolderList request for 10ms. Actually this will just execute the
* code after the calling script has finished.
*
* @param {array} _folders description
*/
mail_queueRefreshFolderList: function(_folders)
{
// as jsonq is too fast wrap it to be delayed a bit, to ensure the folder actions
// are executed last of the queue
window.setTimeout(function() {
egw.jsonq('mail.mail_ui.ajax_setFolderStatus',[_folders]);
}, 100);
},
/**
* mail_CheckFolderNoSelect - implementation of the mail_CheckFolderNoSelect action to control right click options on the tree
*
* @param {object} action
* @param {object} _senders the representation of the tree leaf to be manipulated
* @param {object} _currentNode
*/
mail_CheckFolderNoSelect: function(action,_senders,_currentNode) {
// Abort if user selected an un-selectable node
// Use image over anything else because...?
var ftree, node;
ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
if (ftree)
{
node = ftree.getNode(_senders[0].id);
}
if (node && node.im0.indexOf('NoSelect') !== -1)
{
//ftree.reSelectItem(_previous);
return false;
}
return true;
},
/**
* Check if Sieve is enabled on that account
*
* Sieve enabled is stored as data { acl: true/false } on account node.
*
* @param {object} _action
* @param {object} _senders the representation of the tree leaf to be manipulated
* @param {object} _currentNode
*/
sieve_enabled: function(_action,_senders,_currentNode)
{
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var acc_id = _senders[0].id.split('::')[0];
var node = ftree ? ftree.getNode(acc_id) : null;
return node && node.data && node.data.sieve;
},
/**
* Check if ACL is enabled on that account
*
* ACL enabled is stored as data { acl: true/false } on INBOX node.
* We also need to check if folder is marked as no-select!
*
* @param {object} _action
* @param {object} _senders the representation of the tree leaf to be manipulated
* @param {object} _currentNode
*/
acl_enabled: function(_action,_senders,_currentNode)
{
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var inbox = _senders[0].id.split('::')[0]+'::INBOX';
var node = ftree ? ftree.getNode(inbox) : null;
return node && node.data.acl && this.mail_CheckFolderNoSelect(_action,_senders,_currentNode);
},
/**
* mail_setFolderStatus, function to set the status for the visible folders
*
* @param {array} _status
*/
mail_setFolderStatus: function(_status) {
if (!this.et2 && !this.checkET2()) return;
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
for (var i in _status) {
ftree.setLabel(i,_status[i]);
// display folder-name bold for unseen mails
ftree.setStyle(i, 'font-weight: '+(_status[i].match(this._unseen_regexp) ? 'bold' : 'normal'));
//alert(i +'->'+_status[i]);
}
},
/**
* mail_setLeaf, function to set the id and description for the folder given by status key
* @param {array} _status status array with the required data (new id, desc, old desc)
* key is the original id of the leaf to change
* multiple sets can be passed to mail_setLeaf
*/
mail_setLeaf: function(_status) {
var ftree = this.et2.getWidgetById(this.nm_index+'[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]['olddesc'] !== 'undefined' && _status[i]['olddesc'] !== '#skip-user-interaction-message#') this.egw.message(this.egw.lang("Renamed Folder %1 to %2",_status[i]['olddesc'],_status[i]['desc']));
ftree.renameItem(i,_status[i]['id'],_status[i]['desc']);
ftree.setStyle(i, 'font-weight: '+(_status[i]['desc'].match(this._unseen_regexp) ? 'bold' : 'normal'));
//alert(i +'->'+_status[i]['id']+'+'+_status[i]['desc']);
if (_status[i]['id']==selectedNode.id)
{
var nm = this.et2.getWidgetById(this.nm_index);
nm.activeFilters["selectedFolder"] = _status[i]['id'];
nm.applyFilters();
}
}
},
/**
* 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_removeLeaf: function(_status) {
var ftree = this.et2.getWidgetById(this.nm_index+'[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#') this.egw.message(this.egw.lang("Removed Folder %1 ",_status[i]));
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 = this.et2.getWidgetById(this.nm_index);
nm.activeFilters["selectedFolder"] = selectedNodeAfter.id;
nm.applyFilters();
}
}
},
/**
* mail_reloadNode, function to reload the leaf represented by the given ID
* @param {Object.<string,string>|Object.<string,Object}} _status
* Object with the required data (KEY id, VALUE desc), or ID => {new data}
*/
mail_reloadNode: function(_status) {
var ftree = this.et2?this.et2.getWidgetById(this.nm_index+'[foldertree]'):null;
if (!ftree) return;
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#')
{
this.egw.message(this.egw.lang("Reloaded Folder %1 ",typeof _status[i] == "string" ? _status[i].replace(this._unseen_regexp, '') : _status[i].text.replace(this._unseen_regexp, '')));
}
ftree.refreshItem(i,typeof _status[i] == "object" ? _status[i] : null);
if (typeof _status[i] == "string") ftree.setStyle(i, 'font-weight: '+(_status[i].match(this._unseen_regexp) ? 'bold' : 'normal'));
}
var selectedNodeAfter = ftree.getSelectedNode();
// If selected folder changed, refresh nextmatch
if (selectedNodeAfter != null && selectedNodeAfter.id!=selectedNode.id)
{
var nm = this.et2.getWidgetById(this.nm_index);
nm.activeFilters["selectedFolder"] = selectedNodeAfter.id;
nm.applyFilters();
}
},
/**
* mail_refreshMessageGrid, function to call to reread ofthe current folder
*
* @param {boolean} _isPopup
*/
mail_refreshMessageGrid: function(_isPopup) {
if (typeof _isPopup == 'undefined') _isPopup = false;
var nm;
if (_isPopup && !this.mail_isMainWindow)
{
nm = window.opener.etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById(this.nm_index);
}
else
{
nm = this.et2.getWidgetById(this.nm_index);
}
nm.applyFilters(); // this should refresh the active folder
},
/**
* mail_getMsg - gets the current Message
* @return string
*/
mail_getMsg: function()
{
var msg_wdg = this.et2.getWidgetById('msg');
if (msg_wdg)
{
return msg_wdg.valueOf().htmlNode[0].innerHTML;
}
return "";
},
/**
* mail_setMsg - sets a Message, with the msg container, and controls if the container is enabled/disabled
* @param {string} myMsg - the message
*/
mail_setMsg: function(myMsg)
{
var msg_wdg = this.et2.getWidgetById('msg');
if (msg_wdg)
{
msg_wdg.set_value(myMsg);
msg_wdg.set_disabled(myMsg.trim().length==0);
}
},
/**
* Delete mails
* takes in all arguments
* @param _action
* @param _elems
*/
mail_delete: function(_action,_elems)
{
this.mail_checkAllSelected(_action,_elems,null,true);
},
/**
* call Delete mails
* takes in all arguments
* @param {object} _action
* @param {array} _elems
* @param {boolean} _allMessagesChecked
*/
mail_callDelete: function(_action,_elems,_allMessagesChecked)
{
var calledFromPopup = false;
if (typeof _allMessagesChecked == 'undefined') _allMessagesChecked=false;
if (typeof _elems == 'undefined' || _elems.length==0)
{
calledFromPopup = true;
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
}
var msg = this.mail_getFormData(_elems);
msg['all'] = _allMessagesChecked;
if (msg['all']=='cancel') return false;
if (msg['all']) msg['activeFilters'] = this.mail_getActiveFilters(_action);
//alert(_action.id+','+ msg);
if (!calledFromPopup) this.mail_setRowClass(_elems,'deleted');
this.mail_deleteMessages(msg,'no',calledFromPopup);
if (calledFromPopup && this.mail_isMainWindow==false) window.close();
},
/**
* function to find (and reduce) unseen count from folder-name
*/
mail_reduceCounterWithoutServerRoundtrip: function()
{
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var _foldernode = ftree.getSelectedNode();
var counter = _foldernode.label.match(this._unseen_regexp);
var icounter = 0;
if ( counter ) icounter = parseInt(counter[0].replace(' (','').replace(')',''));
if (icounter>0)
{
var newcounter = icounter-1;
if (newcounter>0) _foldernode.label = _foldernode.label.replace(' ('+String(icounter)+')',' ('+String(newcounter)+')');
if (newcounter==0) _foldernode.label = _foldernode.label.replace(' ('+String(icounter)+')','');
ftree.setLabel(_foldernode.id,_foldernode.label);
}
},
/**
* Regular expression to find (and remove) unseen count from folder-name
*/
_unseen_regexp: / \([0-9]+\)$/,
/**
* mail_splitRowId
*
* @param {string} _rowID
*
*/
mail_splitRowId: function(_rowID)
{
var res = _rowID.split('::');
// as a rowID is perceeded by app::, should be mail!
if (res.length==4 && parseInt(res[0])!=NaN )
{
// we have an own created rowID; prepend app=mail
res.unshift('mail');
}
return res;
},
/**
* Delete mails - actually calls the backend function for deletion
* takes in all arguments
* @param {string} _msg - message list
* @param {object} _action - optional action
* @param {object} _calledFromPopup
*/
mail_deleteMessages: function(_msg,_action,_calledFromPopup)
{
var message, ftree, _foldernode, displayname;
ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
if (ftree)
{
_foldernode = ftree.getSelectedNode();
displayname = _foldernode.label.replace(this._unseen_regexp, '');
}
else
{
message = this.mail_splitRowId(_msg['msg'][0]);
if (message[3]) _foldernode = displayname = jQuery.base64Decode(message[3]);
}
// Tell server
egw.json('mail.mail_ui.ajax_deleteMessages',[_msg,(typeof _action == 'undefined'?'no':_action)])
.sendRequest(true);
// Update list
//var ids = [];
//for (var i = 0; i < _msg['msg'].length; i++)
//{
// ids.push(_msg['msg'][i].replace(/mail::/,''));
//}
if (_msg['all']) this.egw.refresh(this.egw.lang("deleted %1 messages in %2",(_msg['all']?egw.lang('all'):_msg['msg'].length),(displayname?displayname:egw.lang('current folder'))),'mail');//,ids,'delete');
this.egw.message(this.egw.lang("deleted %1 messages in %2",(_msg['all']?egw.lang('all'):_msg['msg'].length),(displayname?displayname:egw.lang('current Folder'))));
},
/**
* Delete mails show result - called from the backend function for display of deletionmessages
* takes in all arguments
* @param _msg - message list
*/
mail_deleteMessagesShowResult: function(_msg)
{
// Update list
var ids = [];
for (var i = 0; i < _msg['msg'].length; i++)
{
ids.push(_msg['msg'][i].replace(/mail::/,''));
}
//this.egw.message(_msg['egw_message']);
if (_msg['all'])
{
this.egw.refresh(_msg['egw_message'],'mail');
}
else
{
this.egw.refresh(_msg['egw_message'],'mail',ids,'delete');
}
},
/**
* retry to Delete mails
* @param responseObject ->
* reason - reason to report
* messageList
*/
mail_retryForcedDelete: function(responseObject)
{
var reason = responseObject['response'];
var messageList = responseObject['messageList'];
if (confirm(reason))
{
this.mail_deleteMessages(messageList,'remove_immediately');
}
else
{
this.egw.message(this.egw.lang('canceled deletion due to userinteraction'));
this.mail_removeRowClass(messageList,'deleted');
}
this.mail_refreshMessageGrid();
this.mail_preview();
},
/**
* UnDelete mailMessages
*
* @param _messageList
*/
mail_undeleteMessages: function(_messageList) {
// setting class of row, the old style
},
/**
* mail_emptyTrash
*
* @param {object} action
* @param {object} _senders
*/
mail_emptyTrash: function(action,_senders) {
var server = _senders[0].iface.id.split('::');
var self = this;
this.egw.message(this.egw.lang('empty trash'));
egw.json('mail.mail_ui.ajax_emptyTrash',[server[0]],function(){self.lock_tree();})
.sendRequest(true);
},
/**
* mail_compressFolder
*
* @param {object} action
* @param {object} _senders
*
*/
mail_compressFolder: function(action,_senders) {
this.egw.message(this.egw.lang('compress folder'));
egw.jsonq('mail.mail_ui.ajax_compressFolder',[_senders[0].iface.id]);
// .sendRequest(true);
// since the json reply is using this.egw.refresh, we should not need to call refreshFolderStatus
// as the actions thereof are now bound to run after grid refresh
//this.mail_refreshFolderStatus();
},
/**
* mail_changeProfile
*
* @param {string} folder the ID of the selected Node -> should be an integer
* @param {object} _widget handle to the tree widget
* @param {boolean} getFolders Flag to indicate that the profile needs the mail
* folders. False means they're already loaded in the tree, and we don't need
* them again
*/
mail_changeProfile: function(folder,_widget, getFolders) {
if(typeof getFolders == 'undefined')
{
getFolders = true;
}
// alert(folder);
this.egw.message(this.egw.lang('Connect to Profile %1',_widget.getSelectedLabel().replace(this._unseen_regexp, '')));
this.lock_tree();
egw.json('mail.mail_ui.ajax_changeProfile',[folder, getFolders], jQuery.proxy(function() {
// Profile changed, select inbox
var inbox = folder + '::INBOX';
_widget.reSelectItem(inbox);
this.mail_changeFolder(inbox,_widget,'');
this.unlock_tree();
},this))
.sendRequest(true);
return true;
},
/**
* mail_changeFolder
* @param {string} _folder the ID of the selected Node
* @param {widget object} _widget handle to the tree widget
* @param {string} _previous - Previously selected node ID
*/
mail_changeFolder: function(_folder,_widget, _previous) {
// to reset iframes to the normal status
this.loadIframe();
// Abort if user selected an un-selectable node
// Use image over anything else because...?
var img = _widget.getSelectedNode().images[0];
if (img.indexOf('NoSelect') !== -1)
{
_widget.reSelectItem(_previous);
return;
}
// Check if this is a top level node and
// change profile if server has changed
var server = _folder.split('::');
var previousServer = _previous.split('::');
var profile_selected = (_folder.indexOf('::') === -1);
if (server[0] != previousServer[0] && profile_selected)
{
// mail_changeProfile triggers a refresh, no need to do any more
return this.mail_changeProfile(_folder,_widget, _widget.getSelectedNode().childsCount == 0);
}
// Apply new selected folder to list, which updates data
var nm = _widget.getRoot().getWidgetById(this.nm_index);
if(nm)
{
this.lock_tree();
nm.applyFilters({'selectedFolder': _folder});
}
// Get nice folder name for message, if selected is not a profile
if(!profile_selected)
{
var displayname = _widget.getSelectedLabel();
var myMsg = (displayname?displayname:_folder).replace(this._unseen_regexp, '')+' '+this.egw.lang('selected');
this.egw.message(myMsg);
}
// Update non-grid
this.mail_refreshFolderStatus(_folder,'forced',false,false);
this.mail_refreshQuotaDisplay(server[0]);
this.mail_fetchCurrentlyFocussed(null,true);
this.mail_preview();
if (server[0]!=previousServer[0])
{
this.mail_callRefreshVacationNotice(server[0]);
egw.jsonq('mail.mail_ui.ajax_refreshFilters',[server[0]]);
}
},
/**
* mail_checkAllSelected
*
* @param _action
* @param _elems
* @param _target
* @param _confirm
*/
mail_checkAllSelected: function(_action, _elems, _target, _confirm)
{
if (typeof _confirm == 'undefined') _confirm = false;
// we can NOT query global object manager for this.nm_index="nm", as we might not get the one from mail,
// if other tabs are open, we have to query for obj_manager for "mail" and then it's child with id "nm"
var obj_manager = egw_getObjectManager(this.appname).getObjectById(this.nm_index);
var that = this;
var rvMain = false;
if (obj_manager && _elems.length>1 && obj_manager.getAllSelected())
{
if (_confirm)
{
var buttons = [
{text: this.egw.lang("Yes"), id: "all", class: "ui-priority-primary", "default": true},
{text: this.egw.lang("Cancel"), id:"cancel"}
];
var messageToDisplay = '';
switch (_action.id)
{
case "unlabel":
case "label1":
case "label2":
case "label3":
case "label4":
case "label5":
case "flagged":
case "read":
case "undelete":
messageToDisplay = this.egw.lang("Do you really want to toggle flag %1 for ALL messages in the current view?",this.egw.lang(_action.id))+" ";
break;
default:
var type = null;
if (_action.id.substr(0,4)=='move' || _action.id === "drop_move_mail")
{
type = 'Move';
}
if (_action.id.substr(0,4)=='copy' || _action.id === "drop_copy_mail")
{
type = 'Copy';
}
messageToDisplay = this.egw.lang("Do you really want to apply %1 to ALL messages in the current view?",this.egw.lang(type?type:_action.id))+" ";
}
return et2_dialog.show_dialog(function(_button_id) {
var rv = false;
switch (_button_id)
{
case "all":
rv = true;
break;
case "cancel":
rv = 'cancel';
}
if (rv !="cancel") that.lock_tree();
switch (_action.id)
{
case "delete":
that.mail_callDelete(_action, _elems,rv);
break;
case "unlabel":
case "label1":
case "label2":
case "label3":
case "label4":
case "label5":
case "flagged":
case "read":
case "undelete":
that.mail_callFlagMessages(_action, _elems,rv);
break;
case "drop_move_mail":
that.mail_callMove(_action, _elems,_target, rv);
break;
case "drop_copy_mail":
that.mail_callCopy(_action, _elems,_target, rv);
break;
default:
if (_action.id.substr(0,4)=='move') that.mail_callMove(_action, _elems,_target, rv);
if (_action.id.substr(0,4)=='copy') that.mail_callCopy(_action, _elems,_target, rv);
}
},
messageToDisplay,
this.egw.lang("Confirm"),
_action.id, buttons);
}
else
{
rvMain = true;
}
}
switch (_action.id)
{
case "delete":
this.mail_callDelete(_action, _elems,rvMain);
break;
case "unlabel":
case "label1":
case "label2":
case "label3":
case "label4":
case "label5":
case "flagged":
case "read":
case "undelete":
this.mail_callFlagMessages(_action, _elems,rvMain);
break;
case "drop_move_mail":
this.mail_callMove(_action, _elems,_target, rvMain);
break;
case "drop_copy_mail":
this.mail_callCopy(_action, _elems,_target, rvMain);
break;
default:
if (_action.id.substr(0,4)=='move') this.mail_callMove(_action, _elems,_target, rvMain);
if (_action.id.substr(0,4)=='copy') this.mail_callCopy(_action, _elems,_target, rvMain);
}
},
/**
* mail_doActionCall
*
* @param _action
* @param _elems
*/
mail_doActionCall: function(_action, _elems)
{
},
/**
* mail_getActiveFilters
*
* @param _action
* @return mixed boolean/activeFilters object
*/
mail_getActiveFilters: function(_action)
{
// we can NOT query global object manager for this.nm_index="nm", as we might not get the one from mail,
// if other tabs are open, we have to query for obj_manager for "mail" and then it's child with id "nm"
var obj_manager = egw_getObjectManager(this.appname).getObjectById(this.nm_index);
if (obj_manager && obj_manager.manager && obj_manager.manager.data && obj_manager.manager.data.nextmatch && obj_manager.manager.data.nextmatch.activeFilters)
{
return obj_manager.manager.data.nextmatch.activeFilters;
}
return false;
},
/**
* Flag mail as 'read', 'unread', 'flagged' or 'unflagged'
*
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
* @param _elems
*/
mail_flag: function(_action, _elems)
{
this.mail_checkAllSelected(_action,_elems,null,true);
},
/**
* Flag mail as 'read', 'unread', 'flagged' or 'unflagged'
*
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
* @param _elems
* @param _allMessagesChecked
*/
mail_callFlagMessages: function(_action, _elems, _allMessagesChecked)
{
var do_nmactions = true;
var msg;
var ftree;
var _folder;
if (typeof _allMessagesChecked=='undefined') _allMessagesChecked=false;
if (_action.id=='read')
{
ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var _foldernode = ftree.getSelectedNode();
_folder = _foldernode.id;
}
if (typeof _elems == 'undefined'|| _elems.length==0)
{
do_nmactions = false;//indicates that this action is probably a popup?
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
msg = {};
msg['msg'] = [this.et2.getArrayMgr('content').getEntry('mail_id') || ''];
}
if ((typeof _elems == 'undefined'|| _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
msg = {};
msg['msg'] = [this.mail_currentlyFocussed];
_elems = msg;
do_nmactions = true;// is triggered from preview
}
}
}
var classToProcess = _action.id;
if (_action.id=='read') classToProcess='seen';
else if (_action.id=='label1') classToProcess='labelone';
else if (_action.id=='label2') classToProcess='labeltwo';
else if (_action.id=='label3') classToProcess='labelthree';
else if (_action.id=='label4') classToProcess='labelfour';
else if (_action.id=='label5') classToProcess='labelfive';
if (do_nmactions)
{
msg = this.mail_getFormData(_elems);
msg['all'] = _allMessagesChecked;
if (msg['all']=='cancel') return false;
msg['activeFilters'] = this.mail_getActiveFilters(_action);
if (_action.id.substring(0,2)=='un') {
//old style, only available for undelete and unlabel (no toggle)
if ( _action.id=='unlabel') // this means all labels should be removed
{
var labels = ['labelone','labeltwo','labelthree','labelfour','labelfive'];
for (var i=0; i<labels.length; i++) this.mail_removeRowClass(_elems,labels[i]);
this.mail_flagMessages(_action.id,msg,(do_nmactions?false:true));
}
else
{
this.mail_removeRowClass(_elems,_action.id.substring(2));
this.mail_setRowClass(_elems,_action.id);
this.mail_flagMessages(_action.id,msg,(do_nmactions?false:true));
}
}
else
{
var msg_set = {msg:[]};
var msg_unset = {msg:[]};
var dataElem;
var flags;
var classes = '';
for (var i=0; i<msg.msg.length; i++)
{
dataElem = egw.dataGetUIDdata(msg.msg[i]);
if(typeof dataElem.data.flags == 'undefined')
{
dataElem.data.flags = {};
}
flags = dataElem.data.flags;
classes = dataElem.data.class || "";
classes = classes.split(' ');
// since we toggle we need to unset the ones already set, and set the ones not set
// flags is data, UI is done by class, so update both
// Flags are there or not, class names are flag or 'un'+flag
if(classes.indexOf(classToProcess) >= 0)
{
classes.splice(classes.indexOf(classToProcess),1);
}
if(classes.indexOf('un' + classToProcess) >= 0)
{
classes.splice(classes.indexOf('un' + classToProcess),1);
}
if (flags[_action.id])
{
msg_unset['msg'].push(msg.msg[i]);
classes.push('un'+classToProcess);
delete flags[_action.id];
}
else
{
msg_set['msg'].push(msg.msg[i]);
flags[_action.id] = _action.id;
classes.push(classToProcess);
}
// Update cache & call callbacks - updates list
dataElem.data.class = classes.join(' ');
egw.dataStoreUID(msg.msg[i],dataElem.data);
}
// Notify server of changes
if (msg_unset['msg'] && msg_unset['msg'].length)
{
if (!msg['all']) this.mail_flagMessages('un'+_action.id,msg_unset);
}
if (msg_set['msg'] && msg_set['msg'].length)
{
if (!msg['all']) this.mail_flagMessages(_action.id,msg_set);
}
//server must do the toggle, as we apply to ALL, not only the visible
if (msg['all']) this.mail_flagMessages(_action.id,msg);
// No further update needed, only in case of read, the counters should be refreshed
if (_action.id=='read') this.mail_refreshFolderStatus(_folder,'thisfolderonly',false,true);
return;
}
}
else
{
this.mail_flagMessages(_action.id,msg,(do_nmactions?false:true));
}
// only refresh counter. not grid as the ajaxmethod is called asyncronously
// on flagging, only seen/unseen has effect on counterdisplay
if (_action.id=='read') this.mail_refreshFolderStatus(_folder,'thisfolderonly',false,true);
//this.mail_refreshFolderStatus();
},
/**
* Flag mail as 'read', 'unread', 'flagged' or 'unflagged'
*
* @param {object} _flag
* @param {object} _elems
* @param {boolean} _isPopup
*/
mail_flagMessages: function(_flag, _elems,_isPopup)
{
egw.jsonq('mail.mail_ui.ajax_flagMessages',[_flag, _elems]);
// .sendRequest(true);
},
/**
* display header lines, or source of mail, depending on the url given
*
* @param _url
*/
mail_displayHeaderLines: function(_url) {
// only used by right clickaction
egw_openWindowCentered(_url,'mail_display_headerLines','870','600',window.outerWidth/2,window.outerHeight/2);
},
/**
* View header of a message
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_header: function(_action, _elems)
{
if (typeof _elems == 'undefined'|| _elems.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
}
//alert('mail_header('+_elems[0].id+')');
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=mail.mail_ui.displayHeader'; // todo compose for Draft folder
url += '&id='+_elems[0].id;
this.mail_displayHeaderLines(url);
},
/**
* View message source
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_mailsource: function(_action, _elems)
{
if (typeof _elems == 'undefined' || _elems.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined'|| _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
}
//alert('mail_mailsource('+_elems[0].id+')');
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=mail.mail_ui.saveMessage'; // todo compose for Draft folder
url += '&id='+_elems[0].id;
url += '&location=display';
this.mail_displayHeaderLines(url);
},
/**
* Save a message
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_save: function(_action, _elems)
{
if (typeof _elems == 'undefined' || _elems.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
}
//alert('mail_save('+_elems[0].id+')');
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=mail.mail_ui.saveMessage'; // todo compose for Draft folder
url += '&id='+_elems[0].id;
//window.open(url,'_blank','dependent=yes,width=100,height=100,scrollbars=yes,status=yes');
document.location = url;
},
/**
* User clicked an address (FROM, TO, etc)
*
* @param {object} tag_info with values for attributes id, label, title, ...
* @param {widget object} widget
*
* @todo seems this function is not implemented, need to be checked if it is neccessary at all
*/
address_click: function(tag_info, widget)
{
},
/**
* displayAttachment
*
* @param {object} tag_info
* @param {widget object} widget
* @param {object} calledForCompose
*/
displayAttachment: function(tag_info, widget, calledForCompose)
{
var mailid;
var attgrid;
if (typeof calledForCompose == 'undefined' || typeof calledForCompose == 'object') calledForCompose=false;
if (calledForCompose===false)
{
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[filename\]/,'')];
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[filename\]/,'')];
}
}
if (calledForCompose===true)
{
// CALLED FOR COMPOSE; processedmail_id could hold several IDs seperated by comma
attgrid = this.et2.getArrayMgr("content").getEntry('attachments')[widget.id.replace(/\[name\]/,'')];
var mailids = this.et2.getArrayMgr("content").getEntry('processedmail_id');
var mailida = mailids.split(',');
mailid = mailida[widget.id.replace(/\[name\]/,'')];
if (typeof attgrid.uid != 'undefined' && attgrid.uid && mailid.indexOf(attgrid.uid)==-1)
{
for (var i=0; i<mailida.length; i++)
{
if (mailida[i].indexOf('::'+attgrid.uid)>-1) mailid = mailida[i];
}
}
}
var url = window.egw_webserverUrl+'/index.php?';
var width;
var height;
var windowName ='mail';
switch(attgrid.type.toUpperCase())
{
case 'MESSAGE/RFC822':
url += 'menuaction=mail.mail_ui.displayMessage'; // todo compose for Draft folder
url += '&mode=display';//message/rfc822 attachments should be opened in display mode
url += '&id='+mailid;
url += '&part='+attgrid.partID;
url += '&is_winmail='+attgrid.winmailFlag;
windowName = windowName+'displayMessage_'+mailid+'_'+attgrid.partID;
width = 870;
height = egw_getWindowOuterHeight();
break;
case 'IMAGE/JPEG':
case 'IMAGE/PNG':
case 'IMAGE/GIF':
case 'IMAGE/BMP':
case 'APPLICATION/PDF':
case 'TEXT/PLAIN':
case 'TEXT/HTML':
case 'TEXT/DIRECTORY':
/*
$sfxMimeType = $value['mimeType'];
$buff = explode('.',$value['name']);
$suffix = '';
if (is_array($buff)) $suffix = array_pop($buff); // take the last extension to check with ext2mime
if (!empty($suffix)) $sfxMimeType = mime_magic::ext2mime($suffix);
if (strtoupper($sfxMimeType) == 'TEXT/VCARD' || strtoupper($sfxMimeType) == 'TEXT/X-VCARD')
{
$attachments[$key]['mimeType'] = $sfxMimeType;
$value['mimeType'] = strtoupper($sfxMimeType);
}
*/
case 'TEXT/X-VCARD':
case 'TEXT/VCARD':
case 'TEXT/CALENDAR':
case 'TEXT/X-VCALENDAR':
url += 'menuaction=mail.mail_ui.getAttachment'; // todo compose for Draft folder
url += '&id='+mailid;
url += '&part='+attgrid.partID;
url += '&is_winmail='+attgrid.winmailFlag;
windowName = windowName+'displayAttachment_'+mailid+'_'+attgrid.partID;
var reg = '800x600';
var reg2;
// handle calendar/vcard
if (attgrid.type.toUpperCase()=='TEXT/CALENDAR')
{
windowName = 'maildisplayEvent_'+mailid+'_'+attgrid.partID;
reg2 = egw.link_get_registry('calendar');
if (typeof reg2['view'] != 'undefined' && typeof reg2['view_popup'] != 'undefined' )
{
reg = reg2['view_popup'];
}
}
if (attgrid.type.toUpperCase()=='TEXT/X-VCARD' || attgrid.type.toUpperCase()=='TEXT/VCARD')
{
windowName = 'maildisplayContact_'+mailid+'_'+attgrid.partID;
reg2 = egw.link_get_registry('addressbook');
if (typeof reg2['add'] != 'undefined' && typeof reg2['add_popup'] != 'undefined' )
{
reg = reg2['add_popup'];
}
}
var w_h =reg.split('x');
width = w_h[0];
height = w_h[1];
break;
default:
url += 'menuaction=mail.mail_ui.getAttachment'; // todo compose for Draft folder
url += '&id='+mailid;
url += '&part='+attgrid.partID;
url += '&is_winmail='+attgrid.winmailFlag;
windowName = windowName+'displayAttachment_'+mailid+'_'+attgrid.partID;
width = 870;
height = 600;
//document.location = url;
//return;
}
egw_openWindowCentered(url,windowName,width,height);
},
/**
* displayUploadedFile
*
* @param {object} tag_info
* @param {widget object} widget
*/
displayUploadedFile: function(tag_info, widget)
{
var attgrid;
attgrid = this.et2.getArrayMgr("content").getEntry('attachments')[widget.id.replace(/\[name\]/,'')];
if (attgrid.uid && (attgrid.partID||attgrid.folder))
{
this.displayAttachment(tag_info, widget, true);
return;
}
var url = window.egw_webserverUrl+'/index.php?';
var width;
var height;
var windowName ='mail';
switch(attgrid.type.toUpperCase())
{
case 'IMAGE/JPEG':
case 'IMAGE/PNG':
case 'IMAGE/GIF':
case 'IMAGE/BMP':
case 'APPLICATION/PDF':
case 'TEXT/PLAIN':
case 'TEXT/HTML':
case 'TEXT/DIRECTORY':
/*
$sfxMimeType = $value['mimeType'];
$buff = explode('.',$value['name']);
$suffix = '';
if (is_array($buff)) $suffix = array_pop($buff); // take the last extension to check with ext2mime
if (!empty($suffix)) $sfxMimeType = mime_magic::ext2mime($suffix);
if (strtoupper($sfxMimeType) == 'TEXT/VCARD' || strtoupper($sfxMimeType) == 'TEXT/X-VCARD')
{
$attachments[$key]['mimeType'] = $sfxMimeType;
$value['mimeType'] = strtoupper($sfxMimeType);
}
*/
case 'TEXT/X-VCARD':
case 'TEXT/VCARD':
case 'TEXT/CALENDAR':
case 'TEXT/X-VCALENDAR':
url += 'menuaction=mail.mail_compose.getAttachment'; // todo compose for Draft folder
url += '&filename='+attgrid.file;
url += '&tmpname='+attgrid.tmp_name;
url += '&name='+attgrid.name;
//url += '&size='+attgrid.size;
url += '&type='+attgrid.type;
windowName = windowName+'displayAttachment_'+attgrid.file.replace(/\//g,"_");
var reg = '800x600';
var reg2;
// handle calendar/vcard
if (attgrid.type.toUpperCase()=='TEXT/CALENDAR')
{
windowName = 'maildisplayEvent_'+attgrid.file.replace(/\//g,"_");
reg2 = egw.link_get_registry('calendar');
if (typeof reg2['view'] != 'undefined' && typeof reg2['view_popup'] != 'undefined' )
{
reg = reg2['view_popup'];
}
}
if (attgrid.type.toUpperCase()=='TEXT/X-VCARD' || attgrid.type.toUpperCase()=='TEXT/VCARD')
{
windowName = 'maildisplayContact_'+attgrid.file.replace(/\//g,"_");
reg2 = egw.link_get_registry('addressbook');
if (typeof reg2['add'] != 'undefined' && typeof reg2['add_popup'] != 'undefined' )
{
reg = reg2['add_popup'];
}
}
var w_h =reg.split('x');
width = w_h[0];
height = w_h[1];
break;
case 'MESSAGE/RFC822':
/*
url += 'menuaction=mail.mail_ui.displayMessage'; // todo compose for Draft folder
url += '&id='+mailid;
url += '&part='+attgrid.partID;
url += '&is_winmail='+attgrid.winmailFlag;
windowName = windowName+'displayMessage_'+mailid+'_'+attgrid.partID;
width = 870;
height = egw_getWindowOuterHeight();
break;
*/
default:
url += 'menuaction=mail.mail_compose.getAttachment'; // todo compose for Draft folder
url += '&filename='+attgrid.file;
url += '&tmpname='+attgrid.tmp_name;
url += '&name='+attgrid.name;
//url += '&size='+attgrid.size;
url += '&type='+attgrid.type;
url += '&mode='+'save';
windowName = windowName+'displayAttachment_'+attgrid.file.replace(/\//g,"_");
width = 870;
height = 600;
//document.location = url;
//return;
}
egw_openWindowCentered(url,windowName,width,height);
},
saveAttachment: function(tag_info, widget)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[save\]/,'')];
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[save\]/,'')];
}
var url = window.egw_webserverUrl+'/index.php?';
var width;
var height;
var windowName ='mail';
url += 'menuaction=mail.mail_ui.getAttachment'; // todo compose for Draft folder
url += '&mode=save';
url += '&id='+mailid;
url += '&part='+attgrid.partID;
url += '&is_winmail='+attgrid.winmailFlag;
document.location = url;
},
saveAllAttachmentsToZip: function(tag_info, widget)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[save\]/,'')];
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[save\]/,'')];
}
var url = window.egw_webserverUrl+'/index.php?';
var width;
var height;
var windowName ='mail';
url += 'menuaction=mail.mail_ui.download_zip'; // todo compose for Draft folder
url += '&mode=save';
url += '&id='+mailid;
document.location = url;
},
saveAttachmentToVFS: function(tag_info, widget)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[saveAsVFS\]/,'')];
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[saveAsVFS\]/,'')];
}
var url = window.egw_webserverUrl+'/index.php?';
var width=640;
var height=570;
var windowName ='mail';
url += 'menuaction=filemanager.filemanager_select.select'; // todo compose for Draft folder
url += '&mode=saveas';
url += '&id='+mailid+'::'+attgrid.partID+'::'+attgrid.winmailFlag;
url += '&name='+attgrid.filename;
url += '&type='+attgrid.type.toLowerCase();
url += '&method=mail.mail_ui.vfsSaveAttachment';
url += '&label='+egw.lang('Save');
egw_openWindowCentered(url,windowName,width,height);
},
saveAllAttachmentsToVFS: function(tag_info, widget)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
attgrid = p.getArrayMgr("content").data;
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments');
}
var url = window.egw_webserverUrl+'/index.php?';
var width=640;
var height=570;
var windowName ='mail';
url += 'menuaction=filemanager.filemanager_select.select'; // todo compose for Draft folder
url += '&mode=select-dir';
url += '&method=mail.mail_ui.vfsSaveAttachment';
url += '&label='+egw.lang('Save all');
for (var i=0;i<attgrid.length;i++)
{
if (attgrid[i] != null) url += '&id['+i+']='+mailid+'::'+attgrid[i].partID+'::'+attgrid[i].winmailFlag+'::'+attgrid[i].filename;
}
egw_openWindowCentered(url,windowName,width,height);
},
/**
* Save a message to filemanager
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_save2fm: function(_action, _elems)
{
if (typeof _elems == 'undefined' || _elems.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
}
var _id = _elems[0].id;
var dataElem = egw.dataGetUIDdata(_id);
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=filemanager.filemanager_select.select'; // todo compose for Draft folder
url += '&mode=saveas';
var filename =dataElem.data.subject.replace(/[\f\n\t\v/\\:*#?<>\|]/g,"_");
url += '&name='+encodeURIComponent(filename+'.eml');
url += '&mime=message'+encodeURIComponent('/')+'rfc822';
url += '&method=mail.mail_ui.vfsSaveMessage';
url += '&id='+_elems[0].id;
url += '&label=Save';
//window.open(url,'_blank','dependent=yes,width=100,height=100,scrollbars=yes,status=yes')
//document.location = url;
egw_openWindowCentered(url,'vfs_save_message_'+_elems[0].id,'640','570',window.outerWidth/2,window.outerHeight/2);
},
/**
* Save message as InfoLog
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_infolog: function(_action, _elems)
{
if (typeof _elems == 'undefined' || _elems.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
if (typeof _action.data.width == 'undefined' && typeof _action.data.height == 'undefined' && !(typeof _action.data.event == 'undefined' &&typeof _action.data.event.popup == 'undefined'))
{
if (_action.data.event.popup)
{
var app_registry = _action.data.event.popup;
}
else
{
var app_registry = egw.link_get_registry('infolog');//this.appname);
}
if (typeof app_registry['edit'] != 'undefined' && typeof app_registry['edit_popup'] != 'undefined' )
{
var w_h =app_registry['edit_popup'].split('x');
}
}
}
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=infolog.infolog_ui.import_mail'; // todo compose for Draft folder
url += '&rowid='+_elems[0].id;
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,(_action.data.width?_action.data.width:w_h[0]),(_action.data.height?_action.data.height:w_h[1]));
},
/**
* Save message as ticket
*
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
* @param _elems
*/
mail_tracker: function(_action, _elems)
{
if (typeof _elems == 'undefined' || _elems.length==0)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
}
}
if (typeof _action.data.width == 'undefined' && typeof _action.data.height == 'undefined' && !(typeof _action.data.event == 'undefined' &&typeof _action.data.event.popup == 'undefined'))
{
if (_action.data.event.popup)
{
var app_registry = _action.data.event.popup;
}
else
{
var app_registry = egw.link_get_registry('tracker');//this.appname);
}
if (typeof app_registry['add'] != 'undefined' && typeof app_registry['add_popup'] != 'undefined' )
{
var w_h =app_registry['add_popup'].split('x');
}
}
}
//alert('mail_tracker('+_elems[0].id+')');
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=tracker.tracker_ui.import_mail'; // todo compose for Draft folder
url += '&rowid='+_elems[0].id;
egw_openWindowCentered(url,'import_tracker_'+_elems[0].id,(_action.data.width?_action.data.width:w_h[0]),(_action.data.height?_action.data.height:w_h[1]));
},
/**
* mail_getFormData
*
* @param {object} _actionObjects the senders
*
* @return structured array of message ids: array(msg=>message-ids)
*/
mail_getFormData: function(_actionObjects) {
var messages = {};
// if
if (typeof _actionObjects['msg'] != 'undefined' && _actionObjects['msg'].length>0) return _actionObjects;
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;
},
/**
* mail_setRowClass
*
* @param {object} _actionObjects the senders
* @param {string} _class
*/
mail_setRowClass: function(_actionObjects,_class) {
if (typeof _class == 'undefined') return false;
if (typeof _actionObjects['msg'] == 'undefined')
{
for (var i = 0; i < _actionObjects.length; i++)
{
if (_actionObjects[i].id.length>0)
{
var dataElem = $j(_actionObjects[i].iface.getDOMNode());
dataElem.addClass(_class);
}
}
}
else
{
for (var i = 0; i < _actionObjects['msg'].length; i++)
{
var mail_uid = _actionObjects['msg'][i];
// Get the record from data cache
var dataElem = egw.dataGetUIDdata(mail_uid);
if(dataElem == null || typeof dataElem == undefined)
{
// Unknown ID, nothing to update
return;
}
// Update class
dataElem.data.class += ' ' + _class;
// Update record, which updates all listeners (including nextmatch)
egw.dataStoreUID(mail_uid,dataElem.data);
}
}
},
/**
* mail_removeRowFlag
* Removes a flag and updates the CSS class. Updates the UI, but not the server.
*
* @param {action object} _actionObjects the senders, or a messages object
* @param {string} _class the class to be removed
*/
mail_removeRowClass: function(_actionObjects,_class) {
if (typeof _class == 'undefined') return false;
if (typeof _actionObjects['msg'] == 'undefined')
{
for (var i = 0; i < _actionObjects.length; i++)
{
if (_actionObjects[i].id.length>0)
{
var dataElem = $j(_actionObjects[i].iface.getDOMNode());
dataElem.removeClass(_class);
}
}
}
else
{
for (var i = 0; i < _actionObjects['msg'].length; i++)
{
var mail_uid = _actionObjects['msg'][i];
// Get the record from data cache
var dataElem = egw.dataGetUIDdata(mail_uid);
if(dataElem == null || typeof dataElem == undefined)
{
// Unknown ID, nothing to update
return;
}
// Update class
var classes = dataElem.data.class || "";
classes = classes.split(' ');
if(classes.indexOf(_class) >= 0)
{
classes.splice(classes.indexOf(_class),1);
dataElem.data.class = classes.join(' ');
// Update record, which updates all listeners (including nextmatch)
egw.dataStoreUID(mail_uid,dataElem.data);
}
}
}
},
// Tree widget stubs
/**
* mail_dragStart - displays information while dragging
*
* @param action
* @param _senders - the representation of the elements dragged
* @return the ddhelper
*/
mail_dragStart: function(action,_senders) {
return $j("<div class=\"ddhelper\">" + _senders.length + " Mails selected </div>");
},
/**
* mail_move2folder - implementation of the move action from action menu
*
* @param _action _action.id holds folder target information
* @param _elems - the representation of the elements to be affected
*/
mail_move2folder: function(_action, _elems) {
this.mail_move(_action, _elems, null);
},
/**
* mail_move - implementation of the move action from drag n drop
*
* @param _action
* @param _senders - the representation of the elements dragged
* @param _target - the representation of the target
*/
mail_move: function(_action,_senders,_target) {
this.mail_checkAllSelected(_action,_senders,_target,true);
},
/**
* mail_move - implementation of the move action from drag n drop
*
* @param _action
* @param _senders - the representation of the elements dragged
* @param _target - the representation of the target
* @param _allMessagesChecked
*/
mail_callMove: function(_action,_senders,_target,_allMessagesChecked) {
var target = _action.id == 'drop_move_mail' ? _target.iface.id : _action.id.substr(5);
var messages = this.mail_getFormData(_senders);
if (typeof _allMessagesChecked=='undefined') _allMessagesChecked=false;
// TODO: Write move/copy function which cares about doing the same stuff
// as the "onNodeSelect" function!
messages['all'] = _allMessagesChecked;
if (messages['all']=='cancel') return false;
if (messages['all']) messages['activeFilters'] = this.mail_getActiveFilters(_action);
var self = this;
egw.json('mail.mail_ui.ajax_copyMessages',[target, messages, 'move'], function(){self.unlock_tree();})
.sendRequest();
var nm = this.et2.getWidgetById(this.nm_index);
this.mail_setRowClass(_senders,'deleted');
// Server response contains refresh
},
/**
* mail_copy - implementation of the move action from drag n drop
*
* @param _action
* @param _senders - the representation of the elements dragged
* @param _target - the representation of the target
*/
mail_copy: function(_action,_senders,_target) {
this.mail_checkAllSelected(_action,_senders,_target,true);
},
/**
* mail_callCopy - implementation of the copy action from drag n drop
*
* @param _action
* @param _senders - the representation of the elements dragged
* @param _target - the representation of the target
* @param _allMessagesChecked
*/
mail_callCopy: function(_action,_senders,_target,_allMessagesChecked) {
var target = _action.id == 'drop_copy_mail' ? _target.iface.id : _action.id.substr(5);
var messages = this.mail_getFormData(_senders);
if (typeof _allMessagesChecked=='undefined') _allMessagesChecked=false;
// TODO: Write move/copy function which cares about doing the same stuff
// as the "onNodeSelect" function!
messages['all'] = _allMessagesChecked;
if (messages['all']=='cancel') return false;
if (messages['all']) messages['activeFilters'] = this.mail_getActiveFilters(_action);
var self = this;
egw.json('mail.mail_ui.ajax_copyMessages',[target, messages],function (){self.unlock_tree();})
.sendRequest();
// Server response contains refresh
},
/**
* mail_AddFolder - implementation of the AddFolder action of right click options on the tree
*
* @param _action
* @param _senders - the representation of the tree leaf to be manipulated
*/
mail_AddFolder: function(_action,_senders) {
//action.id == 'add'
//_senders.iface.id == target leaf / leaf to edit
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var OldFolderName = ftree.getLabel(_senders[0].id).replace(this._unseen_regexp,'');
var buttons = [
{text: this.egw.lang("Add"), id: "add", class: "ui-priority-primary", "default": true},
{text: this.egw.lang("Cancel"), id:"cancel"}
];
et2_dialog.show_prompt(function(_button_id, _value) {
var NewFolderName = null;
if (_value.length>0) NewFolderName = _value;
//alert(NewFolderName);
if (NewFolderName && NewFolderName.length>0)
{
switch (_button_id)
{
case "add":
egw.json('mail.mail_ui.ajax_addFolder',[_senders[0].id, NewFolderName])
.sendRequest(true);
return;
case "cancel":
}
}
},
this.egw.lang("Enter the name for the new Folder:"),
this.egw.lang("Add a new Folder to %1:",OldFolderName),
'', buttons);
},
/**
* mail_RenameFolder - implementation of the RenameFolder action of right click options on the tree
*
* @param _action
* @param _senders - the representation of the tree leaf to be manipulated
*/
mail_RenameFolder: function(_action,_senders) {
//action.id == 'rename'
//_senders.iface.id == target leaf / leaf to edit
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var OldFolderName = ftree.getLabel(_senders[0].id).replace(this._unseen_regexp,'');
var buttons = [
{text: this.egw.lang("Rename"), id: "rename", class: "ui-priority-primary", image: 'edit', "default": true},
{text: this.egw.lang("Cancel"), id:"cancel"}
];
et2_dialog.show_prompt(function(_button_id, _value) {
var NewFolderName = null;
if (_value.length>0) NewFolderName = _value;
//alert(NewFolderName);
if (NewFolderName && NewFolderName.length>0)
{
switch (_button_id)
{
case "rename":
egw.json('mail.mail_ui.ajax_renameFolder',[_senders[0].id, NewFolderName])
.sendRequest(true);
return;
case "cancel":
}
}
},
this.egw.lang("Rename Folder %1 to:",OldFolderName),
this.egw.lang("Rename Folder %1 ?",OldFolderName),
OldFolderName, buttons);
},
/**
* mail_MoveFolder - implementation of the MoveFolder action on the tree
*
* @param {egwAction} _action
* @param {egwActionObject[]} _senders - the representation of the tree leaf to be manipulated
* @param {egwActionObject} destination Drop target egwActionObject representing the destination
*/
mail_MoveFolder: function(_action,_senders,destination) {
if(!destination || !destination.id)
{
egw.debug('warn', "Move folder, but no target");
return;
}
// Some UI feedback while the folder is moved - using just the iface DOMNode would
// put the load image in every row
var load_node = $j(destination.iface.getDOMNode()).closest('td').prev()
.addClass('loading');
for(var i = 0; i < _senders.length; i++)
{
egw.jsonq('mail.mail_ui.ajax_MoveFolder',[_senders[i].id, destination.id],
// Move is done (successfully or not), remove loading
function() {load_node.removeClass('loading');}
);
}
},
/**
* 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) {
//action.id == 'delete'
//_senders.iface.id == target leaf / leaf to edit
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
var OldFolderName = ftree.getLabel(_senders[0].id).replace(this._unseen_regexp,'');
var buttons = [
{text: this.egw.lang("Yes"), id: "delete", class: "ui-priority-primary", "default": true},
{text: this.egw.lang("Cancel"), id:"cancel"}
];
et2_dialog.show_dialog(function(_button_id, _value) {
switch (_button_id)
{
case "delete":
egw.json('mail.mail_ui.ajax_deleteFolder',[_senders[0].id])
.sendRequest(true);
return;
case "cancel":
}
},
this.egw.lang("Do you really want to DELETE Folder %1 ?",OldFolderName)+" "+(ftree.hasChildren(_senders[0].id)?this.egw.lang("All subfolders will be deleted too, and all messages in all affected folders will be lost"):this.egw.lang("All messages in the folder will be lost")),
this.egw.lang("DELETE Folder %1 ?",OldFolderName),
OldFolderName, buttons);
},
/**
* Send names of uploaded files (again) to server, to process them: either copy to vfs or ask overwrite/rename
*
* @param _event
* @param _file_count
* @param {string?} _path where the file is uploaded to, default current directory
*/
uploadForImport: function(_event, _file_count, _path)
{
// path is probably not needed when uploading for file; maybe it is when from vfs
if(typeof _path == 'undefined')
{
//_path = this.get_path();
}
if (_file_count && !jQuery.isEmptyObject(_event.data.getValue()))
{
var widget = _event.data;
// var request = new egw_json_request('mail_ui::ajax_importMessage', ['upload', widget.getValue(), _path], this);
// widget.set_value('');
// request.sendRequest();//false, this._upload_callback, this);
this.et2_obj.submit();
}
},
/**
* Send names of uploaded files (again) to server, to process them: either copy to vfs or ask overwrite/rename
*
* @param {event object} _event
* @param {string} _file_count
* @param {string} _path [_path=current directory] Where the file is uploaded to.
*/
uploadForCompose: function(_event, _file_count, _path)
{
// path is probably not needed when uploading for file; maybe it is when from vfs
if(typeof _path == 'undefined')
{
//_path = this.get_path();
}
if (_file_count && !jQuery.isEmptyObject(_event.data.getValue()))
{
var widget = _event.data;
// var request = new egw_json_request('mail_ui::ajax_importMessage', ['upload', widget.getValue(), _path], this);
// widget.set_value('');
// request.sendRequest();//false, this._upload_callback, this);
this.et2_obj.submit();
}
},
/**
* Upload for import (VFS)
*
* @param {egw object} _egw
* @param {widget object} _widget
* @param {window object} _window
*/
vfsUploadForImport: function(_egw, _widget, _window) {
if (jQuery.isEmptyObject(_widget)) return;
if (!jQuery.isEmptyObject(_widget.getValue()))
{
this.et2_obj.submit();
}
},
/**
* Upload for compose (VFS)
*
* @param {egw object} _egw
* @param {widget object} _widget
* @param {window object} _window
*/
vfsUploadForCompose: function(_egw, _widget, _window)
{
if (jQuery.isEmptyObject(_widget)) return;
if (!jQuery.isEmptyObject(_widget.getValue()))
{
this.et2_obj.submit();
}
},
/**
* Submit on change (VFS)
*
* @param {egw object} _egw
* @param {widget object} _widget
* @param {window object} _window
*/
submitOnChange: function(_egw, _widget, _window) {
if (!jQuery.isEmptyObject(_widget))
{
if (!jQuery.isEmptyObject(_widget.getValue()))
{
this.et2_obj.submit();
}
}
},
/**
* Save as Draft (VFS)
*
* @param {egw object} _egw
* @param {widget object} _widget
* @param {window object} _window
*/
saveAsDraft: function(_egw, _widget, _window)
{
this.et2_obj.submit();
},
/**
* Save as Draf and pring (VFS)
*
* @param {egw object} _egw
* @param {widget object} _widget
* @param {window object} _window
*/
saveAsDraftAndPrint: function(_egw, _widget, _window)
{
this.et2_obj.submit();
},
/**
* Focus handler for folder, address, reject textbox/taglist to automatic check associated radio button
*
* @param {event} _ev
* @param {object} _widget taglist
*
*/
sieve_focus_radioBtn: function(_ev, _widget)
{
_widget.getRoot().getWidgetById('action').set_value(_widget.id.replace(/^action_([^_]+)_text$/, '$1'));
},
/**
* Select all aliases
*
*/
sieve_vac_all_aliases: function()
{
var aliases = [];
var addr = this.et2.getWidgetById('addresses');
var addresses = this.et2.getArrayMgr('sel_options').data.addresses;
for(var id in addresses) aliases.push(id);
addr.set_value(aliases);
},
/**
* Disable/Enable date widgets on vacation seive rules form when status is "by_date"
*
*/
vacationFilterStatusChange: function()
{
var status = this.et2.getWidgetById('status');
var s_date = this.et2.getWidgetById('start_date');
var e_date = this.et2.getWidgetById('end_date');
var by_date_label = this.et2.getWidgetById('by_date_label');
if (status && s_date && e_date && by_date_label)
{
s_date.set_disabled(status.get_value() != "by_date");
e_date.set_disabled(status.get_value() != "by_date");
by_date_label.set_disabled(status.get_value() != "by_date");
}
},
/**
* action - handling actions on sieve rules
*
* @param _type - action name
* @param _selected - selected row from the sieve rule list
*/
action: function(_type, _selected)
{
var actionData ;
var that = this;
var typeId = _type.id;
var linkData = '';
var ruleID = ((_selected[0].id.split("_").pop()) - 1); // subtract the row id from 1 because the first row id is reserved by grid header
if (_type)
{
switch (_type.id)
{
case 'delete':
var callbackDeleteDialog = function (button_id)
{
if (button_id == et2_dialog.YES_BUTTON )
{
actionData = _type.parent.data.widget.getArrayMgr('content');
that._do_action(typeId, actionData['data'],ruleID);
}
};
var confirmDeleteDialog = et2_dialog.show_dialog(callbackDeleteDialog, this.egw.lang("Do you really want to DELETE this Rule"),this.egw.lang("Delete"), {},et2_dialog.BUTTONS_YES_CANCEL, et2_dialog.WARNING_MESSAGE);
break;
case 'add' :
linkData = "mail.mail_sieve.edit";
this.egw.open_link(linkData,'_blank',"600x480");
break;
case 'edit' :
linkData = "mail.mail_sieve.edit&ruleID="+ruleID;
this.egw.open_link(linkData,'_blank',"600x480");
break;
case 'enable':
actionData = _type.parent.data.widget.getArrayMgr('content');
this._do_action(typeId,actionData['data'],ruleID);
break;
case 'disable':
actionData = _type.parent.data.widget.getArrayMgr('content');
this._do_action(typeId,actionData['data'],ruleID);
break;
}
}
},
/**
* Send back sieve action result to server
*
* @param {string} _typeID action name
* @param {object} _data content
* @param {string} _selectedID selected row id
* @param {string} _msg message
*
*/
_do_action: function(_typeID, _data,_selectedID,_msg)
{
if (_typeID && _data)
{
var request = this.egw.json('mail.mail_sieve.ajax_action', [_typeID,_selectedID,_msg],null,null,true);
request.sendRequest();
}
},
/**
* Send ajax request to server to refresh the sieve grid
*/
sieve_refresh: function()
{
this.et2._inst.submit();
},
/**
* Select the right combination of the rights for radio buttons from the selected common right
*
* @@param {jQuery event} event
* @param {widget} widget common right selectBox
*
*/
acl_common_rights_selector: function(event,widget)
{
var rowId = widget.id.replace(/[^0-9.]+/g, '');
var rights = (widget.get_value() == "custom"?[]:widget.get_value() == "aeiklprstwx")?
widget.get_value().replace(/[k,x,t,e]/g,"cd").split(""):widget.get_value().split("");
for (var i=0;i<this.aclRights.length;i++)
{
var rightsWidget = this.et2.getWidgetById(rowId+'[acl_' + this.aclRights[i]+ ']');
rightsWidget.set_value((jQuery.inArray(this.aclRights[i],rights) != -1 )?true:false);
}
},
/**
*
* Choose the right common right option for common ACL selecBox
*
* @param {jQuery event} event
* @param {widget} widget radioButton rights
*
*/
acl_common_rights: function(event, widget)
{
var rowId = widget.id.replace(/[^0-9.]+/g, '');
var aclCommonWidget = this.et2.getWidgetById(rowId + '[acl]');
var rights = '';
for (var i=0;i<this.aclRights.length;i++)
{
var rightsWidget = this.et2.getWidgetById(rowId+'[acl_' + this.aclRights[i]+ ']');
if (rightsWidget.get_value() == "true")
rights += this.aclRights[i];
}
for (var i=0;i<this.aclCommonRights.length;i++)
{
if (rights.split("").sort().toString() == this.aclCommonRights[i].split("").sort().toString())
rights = this.aclCommonRights[i];
}
if (jQuery.inArray(rights,this.aclCommonRights ) == -1 && rights !='lrswipcda')
{
aclCommonWidget.set_value('custom');
}
else if (rights =='lrswipcda')
{
aclCommonWidget.set_value('aeiklprstwx');
}
else
{
aclCommonWidget.set_value(rights);
}
},
/**
* Open seive filter list
*
* @param {action} _action
* @param {sender} _senders
*
*/
edit_sieve: function(_action, _senders)
{
var acc_id = parseInt(_senders[0].id);
var url = this.egw.link('/index.php',{
'menuaction': 'mail.mail_sieve.index',
'acc_id': acc_id,
'ajax': 'true'
});
if (!this.loadIframe(url))
{
this.egw.open_link(url);
}
},
/**
* Load an url on an iframe
*
* @param {string} _url string egw url
* @param {iframe widget} _iFrame an iframe to be set if non, extra_iframe is default
*
* @return {boolean} return TRUE if success, and FALSE if iframe not given
*/
loadIframe: function (_url, _iFrame)
{
var mailSplitter = this.et2.getWidgetById('mailSplitter');
var quotaipercent = this.et2.getWidgetById('nm[quotainpercent]');
var iframe = _iFrame || this.et2.getWidgetById('extra_iframe');
if (typeof iframe != 'undefined')
{
if (_url)
{
iframe.set_src(_url);
}
if (typeof mailSplitter != 'undefined' && typeof quotaipercent != 'undefined')
{
mailSplitter.set_disabled(!!_url);
quotaipercent.set_disabled(!!_url);
iframe.set_disabled(!_url);
}
return true;
}
return false;
},
/**
* Edit vacation message
*
* @param {action} _action
* @param {sender} _senders
*/
edit_vacation: function(_action, _senders)
{
var acc_id = parseInt(_senders[0].id);
this.egw.open_link('mail.mail_sieve.editVacation&acc_id='+acc_id,'_blank','700x480');
},
/**
* Popup the subscription dialog
*
* @param {action} _action
* @param {sender} _senders
*/
edit_subscribe: function (_action,_senders)
{
var acc_id = parseInt(_senders[0].id);
this.egw.open_link('mail.mail_ui.subscription&acc_id='+acc_id, '_blank', '720x500');
},
/**
* Subscribe selected unsubscribed folder
*
* @param {action} _action
* @param {sender} _senders
*/
subscribe_folder: function(_action,_senders)
{
var mailbox = _senders[0].id.split('::');
var folder = mailbox[1], acc_id = mailbox[0];
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
this.egw.message(this.egw.lang('Subscribe to Folder %1',ftree.getLabel(_senders[0].id).replace(this._unseen_regexp,'')));
egw.json('mail.mail_ui.ajax_foldersubscription',[acc_id,folder,true])
.sendRequest();
},
/**
* Unsubscribe selected subscribed folder
*
* @param {action} _action
* @param {sender} _senders
*/
unsubscribe_folder: function(_action,_senders)
{
var mailbox = _senders[0].id.split('::');
var folder = mailbox[1], acc_id = mailbox[0];
var ftree = this.et2.getWidgetById(this.nm_index+'[foldertree]');
this.egw.message(this.egw.lang('Unsubscribe from Folder %1',ftree.getLabel(_senders[0].id).replace(this._unseen_regexp,'')));
egw.json('mail.mail_ui.ajax_foldersubscription',[acc_id,folder,false])
.sendRequest();
},
/**
* Edit a folder acl for account(s)
*
* @param _action
* @param _senders - the representation of the tree leaf to be manipulated
*/
edit_acl: function(_action, _senders)
{
var mailbox = _senders[0].id.split('::');
var folder = mailbox[1], acc_id = mailbox[0];
this.egw.open_link('mail.mail_acl.edit&mailbox='+ jQuery.base64Encode(folder)+'&acc_id='+acc_id, '_blank', '640x480');
},
/**
* Edit a mail account
*
* @param _action
* @param _senders - the representation of the tree leaf to be manipulated
*/
edit_account: function(_action, _senders)
{
var acc_id = parseInt(_senders[0].id);
this.egw.open_link('mail.mail_wizard.edit&acc_id='+acc_id, '_blank', '720x500');
},
/**
* Hide Folder, Cc and Bcc rows from the compose popup
*
*/
compose_fieldExpander_hide: function ()
{
var widgets = {cc:{},bcc:{},folder:{}};
for(var widget in widgets)
{
widgets[widget] = this.et2.getWidgetById(widget+'_expander');
if (typeof widgets[widget] != 'undefined')
{
widgets[widget].set_disabled(false);
}
}
jQuery(".mailComposeJQueryCc,.mailComposeJQueryBcc,.mailComposeJQueryFolder").hide();
},
/**
* Control textArea size based on available free space at the bottom
*
*/
compose_resizeHandler: function()
{
var bodyH = jQuery('body').height();
var textArea = this.et2.getWidgetById('mail_plaintext');
var toolbar = jQuery('.mailSignature');
if (typeof textArea != 'undefined')
{
var textAreaH = textArea.node.clientHeight;
if (textArea.getParent().disabled)
{
textArea = this.et2.getWidgetById('mail_htmltext');
textAreaH = parseInt(textArea.getParent().node.clientHeight);
}
var freeSpace = (bodyH - Math.round(toolbar.height() + toolbar.offset().top) - 65);
if (textArea.id != "mail_htmltext")
{
textArea.set_height(textAreaH + freeSpace);
}
else if (typeof textArea != 'undefined' && textArea.id == 'mail_htmltext' && typeof textArea.getParent().node.children[1] != 'undefined')
{
jQuery(textArea.getParent().node.children[1].children[1].children[1]).css('height',textAreaH + (freeSpace - 90));
}
else
{
textArea.set_height(textAreaH + (freeSpace - 90));
}
}
},
/**
* Display Folder,Cc or Bcc fields in compose popup
*
* @param {jQuery event} event
* @param {widget object} widget clicked label (Folder, Cc or Bcc) from compose popup
*
*/
compose_fieldExpander: function(event,widget)
{
var expWidgets = {cc:{},bcc:{},folder:{}};
for (var name in expWidgets)
{
expWidgets[name] = this.et2.getWidgetById(name+'_expander');
}
if (typeof widget !='undefined')
{
switch (widget.id)
{
case 'cc_expander':
jQuery(".mailComposeJQueryCc").show();
if (typeof expWidgets.cc !='undefined')
{
expWidgets.cc.set_disabled(true);
}
break;
case 'bcc_expander':
jQuery(".mailComposeJQueryBcc").show();
if (typeof expWidgets.bcc !='undefined')
{
expWidgets.bcc.set_disabled(true);
}
break;
case 'folder_expander':
jQuery(".mailComposeJQueryFolder").show();
if (typeof expWidgets.folder !='undefined')
{
expWidgets.folder.set_disabled(true);
}
}
}
else if (typeof widget == "undefined")
{
var widgets = {cc:{},bcc:{},folder:{}};
for(var widget in widgets)
{
widgets[widget] = this.et2.getWidgetById(widget);
if (widgets[widget].get_value().length)
{
switch (widget)
{
case 'cc':
jQuery(".mailComposeJQueryCc").show();
if (typeof expWidgets.cc != 'undefiend')
{
expWidgets.cc.set_disabled(true);
}
break;
case 'bcc':
jQuery(".mailComposeJQueryBcc").show();
if (typeof expWidgets.bcc != 'undefiend')
{
expWidgets.bcc.set_disabled(true);
}
break;
case 'folder':
jQuery(".mailComposeJQueryFolder").show();
if (typeof expWidgets.folder != 'undefiend')
{
expWidgets.folder.set_disabled(true);
}
}
}
}
}
this.compose_resizeHandler();
},
/**
* Lock tree so it does NOT receive any more mouse-clicks
*/
lock_tree: function()
{
if (!document.getElementById('mail_folder_lock_div'))
{
var parent = jQuery('#mail-index_nm\\[foldertree\\]');
var lock_div = jQuery(document.createElement('div'));
lock_div.attr('id', 'mail_folder_lock_div')
.addClass('mail_folder_lock');
parent.prepend(lock_div);
}
},
/**
* Unlock tree so it receives again mouse-clicks after calling lock_tree()
*/
unlock_tree: function()
{
jQuery('#mail_folder_lock_div').remove();
},
/**
* Called when tree opens up an account or folder
*
* @param {String} _id account-id[::folder-name]
* @param {et2_widget_tree} _widget
* @param {Number} _hasChildren 0 - item has no child nodes, -1 - item is closed, 1 - item is opened
*/
openstart_tree: function(_id, _widget, _hasChildren)
{
if (_id.indexOf('::') == -1 && // it's an account, not a folder in an account
!_hasChildren)
{
this.lock_tree();
}
return true; // allow opening of node
},
/**
* Called when tree opens up an account or folder
*
* @param {String} _id account-id[::folder-name]
* @param {et2_widget_tree} _widget
* @param {Number} _hasChildren 0 - item has no child nodes, -1 - item is closed, 1 - item is opened
*/
openend_tree: function(_id, _widget, _hasChildren)
{
if (_id.indexOf('::') == -1 && // it's an account, not a folder in an account
_hasChildren == 1)
{
this.unlock_tree();
}
},
/**
* Print a mail from list
* @param _action
* @param _senders - the representation of the tree leaf to be manipulated
*/
mail_print: function(_action, _senders)
{
var currentTemp = this.et2._inst.name;
switch (currentTemp)
{
case 'mail.index':
this.mail_prev_print();
break;
case 'mail.display':
this.mail_display_print();
}
},
/**
* Print a mail from Display
*
*/
mail_display_print: function ()
{
var mainIframe = jQuery('#mail-display_mailDisplayBodySrc');
if (jQuery('#tempPrintDiv').length == 0)
{
var tmpPrintDiv = jQuery(document.createElement('div'))
.attr('id', 'tempPrintDiv')
.addClass('tmpPrintDiv');
if (mainIframe)
{
tmpPrintDiv[0].innerHTML = mainIframe.contents().find('body').html();
}
jQuery('#mail-display_mailDisplayBodySrc').after(tmpPrintDiv);
tmpPrintDiv.find('#divAppboxHeader').remove();
}
this.egw.message('Printing....');
var display = this;
// Make sure the print happens after the content is loaded. Seems Firefox can't handle timing for print command correctly
setTimeout(function(){display.egw.window.print();},1);
},
/**
* Print a mail from list
*
* @param {Object} _action
* @param {Object} _elems
*
*/
mail_prev_print: function (_action, _elems)
{
this.mail_open(_action, _elems, 'print');
},
/**
* Print a mail from list
*
* @param {egw object} _egw
* @param {widget object} _widget mail account selectbox
*
*/
vacation_change_account: function (_egw, _widget)
{
_widget.getInstanceManager().submit();
}
});
// Bind a mouseenter event once for every read-only email
$j(function() {
// If user doesn't have access to addressbook, stop
if(!egw.app('addressbook')) return;
$j('body').on('mouseenter', 'a[id^="mail-"].et2_email', function() {
$j(this).tooltip({
items: 'a.et2_email',
position: {my:"left top", at:"left bottom", collision:"flipfit"},
tooltipClass: "et2_email_popup",
content: function() {
// Here we could do all sorts of things
var extra = {
'presets[email]': $j(this).text()
};
return $j('<a href="#">'+ egw.lang('Add a new contact') + '</a>')
.on('click', function() {
egw.open('','addressbook','add',extra);
});
},
close: function( event, ui ) {
ui.tooltip.hover(
function () {
$j(this).stop(true).fadeTo(400, 1);
//.fadeIn("slow"); // doesn't work because of stop()
},
function () {
$j(this).fadeOut("400", function(){ $j(this).remove(); });
}
);
}
}).tooltip("open");
});
});