2013-02-12 18:48:04 +01:00
/ * *
* mail - static javaScript functions
*
* @ link http : //www.egroupware.org
2016-10-08 14:32:58 +02:00
* @ author EGroupware GmbH [ info @ egroupware . org ]
2020-07-20 12:08:53 +02:00
* @ copyright ( c ) 2013 - 2020 by EGroupware GmbH < info - AT - egroupware . org >
2013-02-12 18:48:04 +01:00
* @ package mail
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* /
2014-02-12 11:56:44 +01:00
/ * e g w : u s e s
* /
2021-06-11 10:11:13 +02:00
import { AppJS } from "../../api/js/jsapi/app_base.js" ;
import { et2 _createWidget } from "../../api/js/etemplate/et2_core_widget" ;
import { et2 _dialog } from "../../api/js/etemplate/et2_widget_dialog" ;
import { et2 _button } from "../../api/js/etemplate/et2_widget_button" ;
2023-07-10 16:02:30 +02:00
import { egw _getObjectManager } from '../../api/js/egw_action/egw_action' ;
import { egwIsMobile , egwSetBit } from "../../api/js/egw_action/egw_action_common" ;
import { EGW _AO _FLAG _DEFAULT _FOCUS } from "../../api/js/egw_action/egw_action_constants" ;
2022-06-22 00:34:57 +02:00
import {
egw _keycode _translation _function ,
egw _keycode _makeValid ,
egw _keyHandler
2023-07-10 16:02:30 +02:00
} from "../../api/js/egw_action/egw_keymanager" ;
2023-08-23 09:34:00 +02:00
import { initMailTree } from "../../api/js/etemplate/Et2TreeWidget/MailTree" ;
2021-06-11 10:11:13 +02:00
/ * r e q u i r e d d e p e n d e n c y , c o m m e n t e d o u t b e c a u s e n o m o d u l e , b u t e g w : u s e s i s n o l o n g e r p a r s e d
* /
2013-10-07 18:53:13 +02:00
/ * *
* UI for mail
2013-10-09 18:44:03 +02:00
*
2013-10-07 18:53:13 +02:00
* @ augments AppJS
* /
2013-11-04 21:54:23 +01:00
app . classes . mail = AppJS . extend (
2022-06-22 00:34:57 +02:00
{
2013-04-13 12:30:07 +02:00
appname : 'mail' ,
2020-07-22 17:01:19 +02:00
/ * *
* modified attribute in mail app to test new entries get added on top of list
* /
modification _field _name : 'date' ,
2013-08-21 12:47:20 +02:00
2013-06-12 13:50:30 +02:00
/ * *
* et2 widget container
* /
et2 : null ,
2013-04-13 12:30:07 +02:00
doStatus : null ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
mail _queuedFolders : [ ] ,
mail _queuedFoldersIndex : 0 ,
2013-05-21 10:46:54 +02:00
mail _selectedMails : [ ] ,
mail _currentlyFocussed : '' ,
2013-05-29 14:34:33 +02:00
mail _previewAreaActive : true , // we start with the area active
2013-07-25 17:35:44 +02:00
2014-05-23 12:11:17 +02:00
nm _index : 'nm' , // nm name of index
2013-09-23 10:33:30 +02:00
mail _fileSelectorWindow : null ,
2013-10-05 18:36:20 +02:00
mail _isMainWindow : true ,
2015-02-12 10:02:56 +01:00
2014-01-18 18:01:29 +01:00
// Some state variables to track preview pre-loading
preview _preload : {
timeout : null ,
request : null
} ,
2015-07-27 19:46:45 +02:00
/ * *
2015-08-20 09:02:06 +02:00
*
2015-07-27 19:46:45 +02:00
* /
subscription _treeLastState : "" ,
2015-08-20 09:02:06 +02:00
2013-12-09 12:17:32 +01:00
/ * *
* abbrevations for common access rights
* @ array
*
* /
2014-02-28 16:39:46 +01:00
aclCommonRights : [ 'lrs' , 'lprs' , 'ilprs' , 'ilprsw' , 'aeiklprstwx' , 'custom' ] ,
2013-12-09 12:17:32 +01:00
/ * *
* Demonstrates ACL rights
* @ array
*
* /
2017-05-11 16:47:31 +02:00
aclRights : [ 'l' , 'r' , 's' , 'w' , 'i' , 'p' , 'c' , 'd' , 'k' , 'x' , 't' , 'e' , 'a' ] ,
2015-02-12 10:02:56 +01:00
2014-12-16 11:26:44 +01:00
/ * *
* In order to store Intervals assigned to window
* @ array of setted intervals
* /
W _INTERVALS : [ ] ,
2013-12-09 12:17:32 +01:00
2018-09-06 16:03:48 +02:00
/ * *
*
* @ array of setted timeouts
* /
W _TIMEOUTS : [ ] ,
2020-07-09 11:54:52 +02:00
/ * *
* Replace http : // in external image urls with
* /
image _proxy : 'https://' ,
2020-08-05 15:38:14 +02:00
/ * *
* stores push activated acc ids
* /
push _active : { } ,
2013-04-13 12:30:07 +02:00
/ * *
* Initialize javascript for this application
2013-07-25 17:35:44 +02:00
*
2013-10-09 16:35:03 +02:00
* @ memberOf mail
2013-04-13 12:30:07 +02:00
* /
init : function ( ) {
this . _super . apply ( this , arguments ) ;
2014-11-20 16:05:25 +01:00
if ( ! this . egw . is _popup ( ) )
2014-11-11 12:46:16 +01:00
// 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' ,
// Called to determine cache key
this . nm _cache ,
// Called whenever cache is used
// TODO: Change this as needed
function ( server _query )
{
// Unlock tree if using a cache, since the server won't
if ( ! server _query ) this . unlock _tree ( ) ;
} ,
this
) ;
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-06-12 13:50:30 +02:00
/ * *
* Destructor
* /
destroy : function ( )
{
2014-01-11 15:16:36 +01:00
// Unbind from nm refresh
2014-02-03 17:41:10 +01:00
if ( this . et2 != null )
2014-01-11 15:16:36 +01:00
{
2014-05-20 12:02:21 +02:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
2014-02-03 17:41:10 +01:00
if ( nm != null )
{
2016-06-02 16:51:15 +02:00
jQuery ( nm ) . off ( 'refresh' ) ;
2014-02-03 17:41:10 +01:00
}
2014-01-11 15:16:36 +01:00
}
2014-08-13 13:45:55 +02:00
2014-07-28 23:21:23 +02:00
// Unregister client side cache
this . egw . dataCacheUnregister ( 'mail' ) ;
2013-10-09 18:44:03 +02:00
delete this . et2 _obj ;
2013-06-12 13:50:30 +02:00
// call parent
this . _super . apply ( this , arguments ) ;
} ,
2013-07-25 17:35:44 +02:00
2020-08-11 15:52:12 +02:00
/ * *
* Dynamic disable NM autorefresh on get _rows response depending on push support of imap - server
*
* @ param { bool } _disable
* /
disable _autorefresh : function ( _disable )
{
if ( this . checkET2 ( ) )
{
this . et2 . getWidgetById ( 'nm' ) . set _disable _autorefresh ( _disable ) ;
}
} ,
2014-07-17 16:39:56 +02:00
/ * *
* 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 ;
} ,
2013-06-12 13:50:30 +02:00
/ * *
* 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
2014-05-22 16:46:50 +02:00
* @ param { string } _name template name
2013-06-12 13:50:30 +02:00
* /
2014-05-22 16:46:50 +02:00
et2 _ready : function ( et2 , _name )
2013-06-12 13:50:30 +02:00
{
2013-09-02 17:15:35 +02:00
// call parent; somehow this function is called more often. (twice on a display and compose) why?
2013-06-12 13:50:30 +02:00
this . _super . apply ( this , arguments ) ;
2013-08-09 19:47:53 +02:00
this . et2 _obj = et2 ;
2020-08-05 15:38:14 +02:00
this . push _active = { } ;
2014-05-22 16:46:50 +02:00
switch ( _name )
2013-09-02 17:15:35 +02:00
{
2014-05-22 16:46:50 +02:00
case 'mail.sieve.vacation' :
this . vacationFilterStatusChange ( ) ;
break ;
case 'mail.index' :
2015-05-17 21:03:45 +02:00
var self = this ;
2021-11-22 19:56:42 +01:00
jQuery ( 'iframe#mail-index_messageIFRAME' ) . on ( 'load' , function ( )
2015-05-17 21:03:45 +02:00
{
// decrypt preview body if mailvelope is available
2015-05-19 20:56:12 +02:00
self . mailvelopeAvailable ( self . mailvelopeDisplay ) ;
2015-05-17 21:03:45 +02:00
self . mail _prepare _print ( ) ;
} ) ;
2014-05-22 16:46:50 +02:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
this . mail _isMainWindow = true ;
2017-11-10 11:13:12 +01:00
2021-11-22 19:56:42 +01:00
// Stop list from focussing next row on keypress
2022-04-14 00:41:20 +02:00
let aom = egw _getObjectManager ( 'mail' ) . getObjectById ( 'nm' ) ;
aom . flags = egwSetBit ( aom . flags , EGW _AO _FLAG _DEFAULT _FOCUS , false ) ;
2021-11-22 19:56:42 +01:00
2023-03-24 13:53:42 +01:00
let splitter = this . et2 . getWidgetById ( 'mailSplitter' ) ;
if ( splitter && egw . preference ( 'previewPane' , 'mail' ) == 'expand' )
{
splitter . style . setProperty ( '--max' , '100%' ) ;
splitter . dock ( )
}
2017-11-10 11:13:12 +01:00
// Set preview pane state
this . mail _disablePreviewArea ( ! this . getPreviewPaneState ( ) ) ;
2017-11-22 18:10:46 +01:00
2015-10-06 12:51:35 +02:00
//Get initial folder status
2021-11-22 19:56:42 +01:00
this . mail _refreshFolderStatus ( undefined , undefined , false ) ;
2015-10-27 12:44:54 +01:00
2014-05-22 16:46:50 +02:00
// Bind to nextmatch refresh to update folder status
2021-11-22 19:56:42 +01:00
if ( nm != null && ( typeof jQuery . _data ( nm ) . events == 'undefined' || typeof jQuery . _data ( nm ) . events . refresh == 'undefined' ) )
2014-05-22 16:46:50 +02:00
{
var self = this ;
2023-01-25 14:55:06 +01:00
jQuery ( nm ) . on ( 'refresh' , ( _event , _widget , _row _id , _type ) =>
2021-11-22 19:56:42 +01:00
{
2020-08-05 15:38:14 +02:00
if ( ! self . push _active [ _widget . settings . foldertree . split ( "::" ) [ 0 ] ] )
2020-08-05 10:43:04 +02:00
{
2023-01-25 14:55:06 +01:00
// defer calls to mail_refreshFolderStatus for 2s, to accumulate updates of multiple rows e.g. deleting multiple emails
if ( typeof self . refresh _timeout === 'undefined' )
{
self . refresh _timeout = window . setTimeout ( ( ) =>
{
delete self . refresh _timeout ;
self . mail _refreshFolderStatus . call ( self , undefined , undefined , false ) ;
} , 2000 ) ;
}
2020-08-05 10:43:04 +02:00
}
} ) ;
2014-05-22 16:46:50 +02:00
}
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 ) ) ;
}
2016-04-12 14:53:50 +02:00
// Show vacation notice on load for the current profile (if not called by mail_searchtype_change())
var alreadyrefreshed = this . mail _searchtype _change ( ) ;
if ( ! alreadyrefreshed ) this . mail _callRefreshVacationNotice ( ) ;
2023-02-21 17:55:17 +01:00
if ( ! egwIsMobile ( ) )
2023-02-15 16:41:19 +01:00
{
2023-02-21 17:55:17 +01:00
let splitter = this . et2 . getWidgetById ( 'mailSplitter' ) ;
let composeBtn = this . et2 . getWidgetById ( 'button[mailcreate]' ) ;
let composeBtnLabel = composeBtn . label ;
if ( splitter && ! splitter . vertical )
{
splitter . addEventListener ( 'sl-reposition' , function ( ) {
if ( this . position < 44 )
2023-02-15 16:41:19 +01:00
{
2023-02-21 17:55:17 +01:00
this . classList . add ( 'limitted' ) ;
2023-02-24 11:39:44 +01:00
if ( this . position < 38 )
2023-02-21 17:55:17 +01:00
{
this . classList . add ( 'squeezed' ) ;
composeBtn . label = '' ;
}
else
{
this . classList . remove ( 'squeezed' ) ;
}
2023-02-15 16:41:19 +01:00
}
else
{
2023-02-21 17:55:17 +01:00
this . classList . remove ( 'limitted' ) ;
2023-02-15 16:41:19 +01:00
this . classList . remove ( 'squeezed' ) ;
2023-02-21 17:55:17 +01:00
composeBtn . label = composeBtnLabel ;
2023-02-15 16:41:19 +01:00
}
2023-02-21 17:55:17 +01:00
} ) ;
}
2023-02-15 16:41:19 +01:00
}
2014-05-22 16:46:50 +02:00
break ;
case 'mail.display' :
2015-02-12 10:02:56 +01:00
var self = this ;
// Prepare display dialog for printing
// copies iframe content to a DIV, as iframe causes
// trouble for multipage printing
2015-05-29 13:04:09 +02:00
2015-06-03 12:48:43 +02:00
jQuery ( 'iframe#mail-display_mailDisplayBodySrc' ) . on ( 'load' , function ( e )
2015-05-17 21:03:45 +02:00
{
// encrypt body if mailvelope is available
2015-05-19 20:56:12 +02:00
self . mailvelopeAvailable ( self . mailvelopeDisplay ) ;
2015-05-17 21:03:45 +02:00
self . mail _prepare _print ( ) ;
2016-11-24 14:35:54 +01:00
self . resolveExternalImages ( this . contentWindow . document ) ;
2015-06-03 12:48:43 +02:00
// Trigger print command if the mail oppend for printing porpuse
// load event fires twice in IE and the first time the content is not ready
// Check if the iframe content is loaded then trigger the print command
if ( window . location . search . search ( '&print=' ) >= 0 && jQuery ( this . contentWindow . document . body ) . children ( ) . length > 0 )
{
self . mail _print ( ) ;
}
2015-05-17 21:03:45 +02:00
} ) ;
2015-02-12 10:02:56 +01:00
2014-05-22 16:46:50 +02:00
this . mail _isMainWindow = false ;
this . mail _display ( ) ;
2015-05-29 13:04:09 +02:00
2014-07-14 22:50:08 +02:00
// Register attachments for drag
this . register _for _drag (
this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) ,
this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_displayattachments' )
) ;
2023-03-23 12:08:23 +01:00
2014-05-22 16:46:50 +02:00
break ;
case 'mail.compose' :
2017-09-01 16:20:57 +02:00
var composeToolbar = this . et2 . getWidgetById ( 'composeToolbar' ) ;
if ( composeToolbar . _actionManager . getActionById ( 'pgp' ) &&
composeToolbar . _actionManager . getActionById ( 'pgp' ) . checked ||
2015-05-20 09:26:15 +02:00
this . et2 . getArrayMgr ( 'content' ) . data . mail _plaintext &&
this . et2 . getArrayMgr ( 'content' ) . data . mail _plaintext . indexOf ( this . begin _pgp _message ) != - 1 )
2015-05-19 20:56:12 +02:00
{
this . mailvelopeAvailable ( this . mailvelopeCompose ) ;
2015-05-17 21:03:45 +02:00
}
2014-06-02 18:57:30 +02:00
var that = this ;
2017-08-22 17:53:52 +02:00
var plainText = this . et2 . getWidgetById ( 'mail_plaintext' ) ;
2015-09-23 12:51:27 +02:00
var textAreaWidget = this . et2 . getWidgetById ( 'mail_htmltext' ) ;
2014-05-22 16:46:50 +02:00
this . mail _isMainWindow = false ;
2020-07-02 10:42:42 +02:00
var pca = egw . preference ( this . et2 . getWidgetById ( 'mailaccount' ) . getValue ( ) . split ( ":" ) [ 0 ] + '_predefined_compose_addresses' , 'mail' ) ;
for ( var p in pca )
{
2020-10-19 13:12:06 +02:00
if ( this . et2 . getWidgetById ( p ) . getValue ( ) && pca [ p ] )
{
pca [ p ] = pca [ p ] . concat ( this . et2 . getWidgetById ( p ) . getValue ( ) ) ;
}
2020-07-02 10:42:42 +02:00
this . et2 . getWidgetById ( p ) . set _value ( pca [ p ] ) ;
}
2014-10-20 14:25:43 +02:00
this . compose _fieldExpander _init ( ) ;
2014-12-02 20:18:37 +01:00
this . check _sharing _filemode ( ) ;
2015-10-27 12:44:54 +01:00
2014-12-12 16:28:53 +01:00
this . subject2title ( ) ;
2015-10-27 12:44:54 +01:00
2014-09-12 14:10:48 +02:00
// Set autosaving interval to 2 minutes for compose message
2014-12-16 11:26:44 +01:00
this . W _INTERVALS . push ( window . setInterval ( function ( ) {
2018-06-21 14:20:52 +02:00
if ( jQuery ( '.ms-editor-wrap' ) . length === 0 )
{
that . saveAsDraft ( null , 'autosaving' ) ;
}
2014-12-16 11:26:44 +01:00
} , 120000 ) ) ;
2014-09-23 10:42:31 +02:00
2014-06-02 18:57:30 +02:00
/* Control focus actions on subject to handle expanders properly.*/
jQuery ( "#mail-compose_subject" ) . on ( {
focus : function ( ) {
2014-10-20 14:25:43 +02:00
that . compose _fieldExpander _init ( ) ;
2014-06-02 18:57:30 +02:00
that . compose _fieldExpander ( ) ;
}
} ) ;
2023-07-05 19:23:28 +02:00
/*Trigger after the TinyMCE is fully loaded*/
2014-09-05 11:50:30 +02:00
jQuery ( '#mail-compose' ) . on ( 'load' , function ( ) {
2019-08-28 16:16:36 +02:00
2018-10-19 16:35:18 +02:00
if ( textAreaWidget && textAreaWidget . tinymce )
2015-09-23 12:51:27 +02:00
{
2023-07-05 19:23:28 +02:00
textAreaWidget . tinymce . then ( ( ) =>
{
// Clear explicit height so browser can manage it
textAreaWidget . tinymce _container . style . height = "" ;
if ( textAreaWidget . editor )
{
jQuery ( textAreaWidget . editor . iframeElement . contentWindow . document ) . on ( 'dragenter' , function ( )
{
// anything to bind on tinymce iframe
} ) ;
}
2019-08-28 16:16:36 +02:00
} ) ;
2015-09-23 12:51:27 +02:00
}
else
{
2015-10-27 12:44:54 +01:00
that . compose _fieldExpander ( ) ;
2015-09-23 12:51:27 +02:00
}
2014-09-05 11:50:30 +02:00
} ) ;
2015-10-27 12:44:54 +01:00
2014-11-28 17:18:46 +01:00
//Resize compose after window resize to not getting scrollbar
2016-06-01 14:07:20 +02:00
jQuery ( window ) . on ( 'resize' , function ( e ) {
// Stop immediately the resize event if we are in mobile template
if ( egwIsMobile ( ) )
{
e . stopImmediatePropagation ( ) ;
return false ;
}
2014-11-28 17:18:46 +01:00
} ) ;
2014-12-02 20:18:37 +01:00
2015-03-30 15:47:08 +02:00
// Set focus on To/body field
// depending on To field value
var to = this . et2 . getWidgetById ( 'to' ) ;
2017-09-28 18:26:55 +02:00
var content = this . et2 . getArrayMgr ( 'content' ) . data ;
2022-09-16 12:30:23 +02:00
if ( to && to . get _value ( ) && to . get _value ( ) . length > 0 )
2015-03-30 15:47:08 +02:00
{
2023-05-09 22:04:02 +02:00
if ( typeof to . blur == "function" )
{
// html area changes focus as part of its init, make sure it doesn't re-focus to
to . blur ( ) ;
}
2015-03-30 15:47:08 +02:00
if ( content . is _plain )
{
// focus
2022-08-07 10:12:26 +02:00
jQuery ( plainText . getDOMNode ( ) ) . focus ( ) ;
2015-03-30 15:47:08 +02:00
// get the cursor to the top of the textarea
2022-09-29 11:27:47 +02:00
if ( typeof plainText . getDOMNode ( ) . setSelectionRange != 'undefined' && ! jQuery ( plainText . getDOMNode ( ) ) . is ( ":hidden" ) )
{
2023-05-09 22:04:02 +02:00
setTimeout ( function ( )
{
plainText . getDOMNode ( ) . setSelectionRange ( 0 , 0 )
2022-09-29 11:27:47 +02:00
plainText . focus ( ) ;
2023-05-09 22:04:02 +02:00
plainText . shadowRoot . querySelector ( "textarea" ) . scrollTop = 0 ;
2022-09-29 11:27:47 +02:00
} , 2000 ) ;
}
2015-03-30 15:47:08 +02:00
}
2018-10-19 16:35:18 +02:00
else if ( textAreaWidget && textAreaWidget . tinymce )
2015-03-30 15:47:08 +02:00
{
2022-09-16 12:30:23 +02:00
textAreaWidget . tinymce . then ( ( ) => { setTimeout ( function ( ) { textAreaWidget . editor . focus ( ) } , 500 ) ; } ) ;
2015-03-30 15:47:08 +02:00
}
}
else if ( to )
{
2022-08-07 10:12:26 +02:00
jQuery ( 'input' , to . getDOMNode ( ) ) . focus ( ) ;
2017-09-28 18:26:55 +02:00
// set cursor to the begining of the textarea only for first focus
if ( content . is _plain
2022-08-07 10:12:26 +02:00
&& typeof plainText . getDOMNode ( ) . setSelectionRange != 'undefined' )
2017-09-28 18:26:55 +02:00
{
2022-08-07 10:12:26 +02:00
plainText . getDOMNode ( ) . setSelectionRange ( 0 , 0 ) ;
2017-09-28 18:26:55 +02:00
}
2015-03-30 15:47:08 +02:00
}
2017-09-01 16:20:57 +02:00
var smime _sign = this . et2 . getWidgetById ( 'smime_sign' ) ;
var smime _encrypt = this . et2 . getWidgetById ( 'smime_encrypt' ) ;
if ( composeToolbar . _actionManager . getActionById ( 'smime_sign' ) &&
composeToolbar . _actionManager . getActionById ( 'smime_encrypt' ) )
{
if ( smime _sign . getValue ( ) == 'on' ) composeToolbar . checkbox ( 'smime_sign' , true ) ;
if ( smime _encrypt . getValue ( ) == 'on' ) composeToolbar . checkbox ( 'smime_encrypt' , true ) ;
}
2014-05-22 16:46:50 +02:00
break ;
2015-07-27 19:46:45 +02:00
case 'mail.subscribe' :
if ( this . subscription _treeLastState != "" )
2015-08-20 09:02:06 +02:00
{
2015-07-27 19:46:45 +02:00
var tree = this . et2 . getWidgetById ( 'foldertree' ) ;
//Saved state of tree
var state = jQuery . parseJSON ( this . subscription _treeLastState ) ;
2015-08-20 09:02:06 +02:00
2015-07-27 19:46:45 +02:00
tree . input . loadJSONObject ( tree . _htmlencode _node ( state ) ) ;
}
2015-08-13 19:34:12 +02:00
break ;
case 'mail.folder_management' :
2017-02-01 18:12:18 +01:00
this . egw . message ( this . egw . lang ( 'If you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status.' ) , 'info' , 'mail:folder_management' ) ;
2016-03-03 15:10:08 +01:00
break ;
case 'mail.view' :
// we need to set mail_currentlyFocused var otherwise mail
// defined actions won't work
this . mail _currentlyFocussed = this . et2 . mail _currentlyFocussed ;
2016-03-29 17:49:33 +02:00
2013-10-16 13:22:53 +02:00
}
2020-07-09 11:54:52 +02:00
// set image_proxy for resolveExternalImages
this . image _proxy = this . et2 . getArrayMgr ( 'content' ) . getEntry ( 'image_proxy' ) || 'https://' ;
2018-06-25 11:34:16 +02:00
this . preSetToggledOnActions ( ) ;
2013-06-12 13:50:30 +02:00
} ,
2020-07-20 12:08:53 +02:00
/ * *
* Handle a push notification about entry changes from the websocket
*
* Get ' s called for data of all apps , but should only handle data of apps it displays ,
* which is by default only it ' s own , but can be for multiple apps eg . for calendar .
*
* @ param pushData
* @ param { string } pushData . app application name
* @ param { ( string | number ) } pushData . id id of entry to refresh or null
* @ param { string } pushData . 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 { object | null } pushData . acl Extra data for determining relevance . eg : owner or responsible to decide if update is necessary
* @ param { number } pushData . account _id User that caused the notification
* /
push : function ( pushData )
{
// don't care about other apps data, reimplement if your app does care eg. calendar
if ( pushData . app !== this . appname ) return ;
2020-08-05 15:38:14 +02:00
let id0 = typeof pushData . id === 'string' ? pushData . id : pushData . id [ 0 ] ;
let acc _id = id0 . split ( '::' ) [ 1 ] ;
let folder = acc _id + '::' + atob ( id0 . split ( '::' ) [ 2 ] ) ;
2020-08-06 09:02:17 +02:00
let foldertree = this . et2 ? this . et2 . getWidgetById ( 'nm[foldertree]' ) : null ;
2020-08-05 15:38:14 +02:00
this . push _active [ acc _id ] = true ;
2020-08-06 09:02:17 +02:00
// update unseen counter in folder-tree (also for delete)
2020-08-06 09:40:53 +02:00
if ( foldertree && pushData . acl . folder && typeof pushData . acl . unseen !== 'undefined' )
2020-08-06 09:02:17 +02:00
{
let folder _id = { } ;
2020-08-17 21:45:41 +02:00
folder _id [ folder ] = ( foldertree . getLabel ( folder ) || pushData . acl . folder )
. replace ( this . _unseen _regexp , '' ) +
2020-08-06 09:40:53 +02:00
( pushData . acl . unseen ? " (" + pushData . acl . unseen + ")" : '' ) ;
2020-08-06 09:02:17 +02:00
this . mail _setFolderStatus ( folder _id ) ;
}
2020-07-20 12:08:53 +02:00
// only handle delete by default, for simple case of uid === "$app::$id"
if ( pushData . type === 'delete' )
{
2020-09-08 17:17:25 +02:00
[ ] . concat ( pushData . id ) . forEach ( uid => {
pushData . id = uid ;
this . _super . call ( this , pushData ) ;
} ) ;
return ;
2020-07-20 12:08:53 +02:00
}
// notify user a new mail arrived
2020-08-06 14:46:28 +02:00
if ( pushData . type === 'add' && pushData . acl . event === 'MessageNew' )
2020-07-20 12:08:53 +02:00
{
2020-08-06 14:46:28 +02:00
// never notify for Trash, Junk, Drafts or Sent folder (user might use Sieve to move mails there!)
2020-08-06 13:00:35 +02:00
if ( pushData . acl . folder . match ( /^(INBOX.)?(Trash|Spam|Junk|Drafts|Sent)$/ ) ) return ;
2020-07-24 19:13:11 +02:00
// increment notification counter on (closed) mail tab
let framework = egw _getFramework ( ) ;
2020-12-17 16:01:43 +01:00
if ( framework && framework . notifyAppTab ) framework . notifyAppTab ( 'mail' ) ;
2020-07-30 12:10:53 +02:00
// check if user wants a new mail notification
this . notifyNew ( pushData ) ;
2020-07-20 12:08:53 +02:00
}
// check if we might not see it because we are on a different mail account or folder
let nm = this . et2 ? this . et2 . getWidgetById ( 'nm' ) : null ;
let nm _value = nm ? nm . getValue ( ) : null ;
2020-08-05 15:38:14 +02:00
2020-07-22 17:38:02 +02:00
// nm_value.selectedFolder is not always set, read it from foldertree, if not
let displayed _folder = ( nm _value ? nm _value . selectedFolder : null ) || ( foldertree ? foldertree . getValue ( ) : '' ) ;
2020-07-22 21:27:05 +02:00
if ( ! displayed _folder . match ( /::/ ) ) displayed _folder += '::INBOX' ;
2020-07-22 17:38:02 +02:00
if ( folder === displayed _folder )
2020-07-20 12:08:53 +02:00
{
2020-08-05 15:38:14 +02:00
switch ( pushData . acl . event )
{
case 'FlagsSet' :
2020-08-05 18:09:37 +02:00
// TB (probably other MUA too) mark mail as deleted, our UI removes/expunges it immediatly
if ( pushData . acl . flags . includes ( '\\Deleted' ) )
{
pushData . type = 'delete' ;
return this . _super . call ( this , pushData ) ;
}
2020-08-05 15:38:14 +02:00
this . pushUpdateFlags ( pushData ) ;
break ;
case 'FlagsClear' :
this . pushUpdateFlags ( pushData ) ;
break ;
default :
// Just update the nm (todo: pushData.message = total number of messages in folder)
nm . refresh ( pushData . id , pushData . type === 'update' ? 'update-in-place' : pushData . type , pushData . messages ) ;
}
2020-07-20 12:08:53 +02:00
}
} ,
2020-07-30 12:10:53 +02:00
/ * *
* Check if user want ' s new mail notification
*
* @ param pushData
* /
notifyNew : function ( pushData )
{
let framework = egw _getFramework ( ) ;
let notify = this . egw . preference ( 'new_mail_notification' , 'mail' ) ;
2023-08-02 17:39:40 +02:00
const message = egw . lang ( 'New mail from %1' , pushData . acl . from ) + '\n' + pushData . acl . subject + '\n' + pushData . acl . snippet ;
2020-07-30 12:10:53 +02:00
if ( typeof notify === 'undefined' || notify === 'always' ||
notify === 'not-mail' && framework && framework . activeApp . appName !== 'mail' )
{
2023-08-02 17:39:40 +02:00
this . egw . message ( message , 'success' ) ;
this . egw . notification ( egw . lang ( 'new mail' ) , { body : message , tag : 'mail' , icon : egw . image ( 'navbar' , 'mail' ) } ) ;
2020-07-30 12:10:53 +02:00
}
} ,
2020-08-05 15:38:14 +02:00
/ * *
* Updates flags on respective rows
*
* @ param { type } pushData
* /
pushUpdateFlags : function ( pushData )
{
let flag = pushData . acl . flags [ 0 ] || pushData . acl . keywords [ 0 ] ;
let unset = ( pushData . acl . flags _old && pushData . acl . flags _old . indexOf ( pushData . acl . flags [ 0 ] ) > - 1 )
|| ( pushData . acl . keywords _old && pushData . acl . keywords _old . indexOf ( pushData . acl . keywords [ 0 ] ) > - 1 ) ? true : false ;
let rowClass = '' ;
if ( flag [ 0 ] == '\\' || flag [ 0 ] == '$' ) flag = flag . slice ( 1 ) . toLowerCase ( ) ;
let ids = typeof pushData . id == "string" ? [ pushData . id ] : pushData . id ;
for ( let i in ids )
{
let msg = { msg : [ 'mail::' + ids [ i ] ] } ;
switch ( flag )
{
case 'seen' :
this . mail _removeRowClass ( msg , ( unset ) ? 'seen' : 'unseen' ) ;
rowClass = ( unset ) ? 'unseen' : 'seen' ;
break ;
case 'label1' :
case 'label2' :
case 'label3' :
case 'label4' :
case 'label5' :
2020-08-05 16:43:57 +02:00
case 'flagged' :
2020-08-05 15:38:14 +02:00
if ( unset )
{
this . mail _removeRowClass ( msg , flag ) ;
}
else
{
rowClass = flag ;
}
break ;
}
this . mail _setRowClass ( msg , rowClass ) ;
}
} ,
2014-05-23 11:21:59 +02:00
/ * *
* 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 )
2014-05-26 16:01:18 +02:00
* @ param { object | null } _links app => array of ids of linked entries
* or null , if not triggered on server - side , which adds that info
2014-05-23 11:21:59 +02:00
* @ return { false | * } false to stop regular refresh , thought all observers are run
* /
2014-05-26 16:01:18 +02:00
observer : function ( _msg , _app , _id , _type , _msg _type , _links )
2014-05-23 11:21:59 +02:00
{
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
}
2020-08-19 17:08:42 +02:00
// stop refresh, in case push has already deleted it
// (done here as it's hard to know if imap server supports push on delete
// and if both happen sometimes we "loose" a row as nextmatch removes it anyway)
if ( _type === 'delete' && ! this . egw . dataHasUID ( 'mail::' + _id ) ) return false ;
2014-05-23 11:21:59 +02:00
break ;
2021-09-01 16:23:38 +02:00
case 'mail-account' : // update tree with given mail account _id and _type
2014-07-18 19:22:28 +02:00
var tree = this . et2 ? this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) : null ;
2014-05-23 12:11:17 +02:00
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)
{
2014-05-27 14:05:23 +02:00
//tree.refreshItem(_id);
egw . json ( 'mail.mail_ui.ajax_reloadNode' , [ _id ] )
. sendRequest ( true ) ;
2014-05-23 12:11:17 +02:00
}
break ;
case 'add' :
2023-03-10 11:52:45 +01:00
const current _id = tree . getValue ( ) ;
2014-05-23 12:11:17 +02:00
tree . refreshItem ( 0 ) ; // refresh root
2023-03-10 11:52:45 +01:00
// ToDo: tree.refreshItem() and openItem() should return a promise
// need to wait tree is refreshed: current and new id are there AND current folder is selected again
const interval = window . setInterval ( ( ) => {
if ( tree . getNode ( _id ) && tree . getNode ( current _id ) )
{
if ( ! tree . getSelectedNode ( ) )
{
tree . reSelectItem ( current _id ) ;
}
else
{
window . clearInterval ( interval ) ;
// open new account
tree . openItem ( _id , true ) ;
// need to wait new folders are loaded AND current folder is selected again
const open _interval = window . setInterval ( ( ) => {
if ( tree . getNode ( _id + '::INBOX' ) ) {
if ( ! tree . getSelectedNode ( ) ) {
tree . reSelectItem ( current _id ) ;
} else {
window . clearInterval ( open _interval ) ;
this . mail _changeFolder ( _id + '::INBOX' , tree , current _id ) ;
tree . reSelectItem ( _id + '::INBOX' ) ;
}
}
} , 200 ) ;
}
}
} , 200 ) ;
2014-05-23 12:11:17 +02:00
break ;
2016-06-01 16:40:52 +02:00
default : // null
2014-05-23 12:11:17 +02:00
}
2014-05-23 11:21:59 +02:00
}
2016-06-01 16:40:52 +02:00
return undefined ;
2014-05-23 11:21:59 +02:00
} ,
2014-07-28 23:21:23 +02:00
/ * *
* 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 .
*
2014-08-20 18:12:19 +02:00
* We do not cache , if we dont find selectedFolder in query _context ,
* as looking it up in tree causes mails to be cached for wrong folder
* ( Probably because user already clicked on an other folder ) !
*
2014-07-28 23:21:23 +02:00
* @ 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
2014-08-20 18:12:19 +02:00
if ( ( ! query _context || ! query _context . start ) && query _context . count == 0 &&
2014-09-08 17:45:37 +02:00
query _context . filters && query _context . filters . selectedFolder &&
! ( ! query _context . filters || query _context . filters . search )
2014-07-28 23:21:23 +02:00
)
{
// Make sure keys match, even if some filters are not defined
2014-08-21 20:28:05 +02:00
// using JSON.stringfy() directly gave a crash in Safari 7.0.4
return this . egw . jsonEncode ( {
2014-09-08 17:45:37 +02:00
selectedFolder : query _context . filters . selectedFolder || '' ,
2016-02-25 13:26:50 +01:00
cat _id : query _context . filters . cat _id || '' ,
2014-09-08 17:45:37 +02:00
filter : query _context . filters . filter || '' ,
filter2 : query _context . filters . filter2 || '' ,
sort : query _context . filters . sort
2014-07-28 23:21:23 +02:00
} ) ;
}
return false ;
} ,
2014-05-20 12:02:21 +02:00
/ * *
* mail rebuild Action menu On nm - list
*
* @ param _actions
* /
mail _rebuildActionsOnList : function ( _actions )
{
this . et2 . getWidgetById ( this . nm _index ) . set _actions ( _actions ) ;
} ,
2013-05-21 10:46:54 +02:00
/ * *
* mail _fetchCurrentlyFocussed - implementation to decide wich mail of all the selected ones is the current
2013-07-25 17:35:44 +02:00
*
2013-05-21 10:46:54 +02:00
* @ 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' )
{
2013-05-21 14:02:58 +02:00
if ( _reset == true )
{
2014-08-06 23:13:27 +02:00
// Request updated data, if possible
if ( this . mail _currentlyFocussed != '' ) egw . dataRefreshUID ( this . mail _currentlyFocussed ) ;
for ( var k = 0 ; k < this . mail _selectedMails . length ; k ++ ) egw . dataRefreshUID ( this . mail _selectedMails [ k ] ) ;
2013-06-04 17:29:53 +02:00
//nm.refresh(this.mail_selectedMails,'delete');
2013-05-21 14:02:58 +02:00
}
2013-05-21 10:46:54 +02:00
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 ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _open - implementation of the open action
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _senders - the representation of the elements ( s ) the action is to be performed on
2013-07-20 09:23:55 +02:00
* @ param _mode - you may pass the mode . if not given view is used ( tryastext | tryashtml are supported )
2013-04-13 12:30:07 +02:00
* /
2013-07-20 09:23:55 +02:00
mail _open : function ( _action , _senders , _mode ) {
2014-03-07 11:06:04 +01:00
if ( typeof _senders == 'undefined' || _senders . length == 0 )
2013-10-05 11:03:51 +02:00
{
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _senders = [ ] ;
_senders . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _senders == 'undefined' || _senders . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _senders = [ ] ;
_senders . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2013-04-13 12:30:07 +02:00
var _id = _senders [ 0 ] . id ;
2013-05-21 10:46:54 +02:00
// reinitialize the buffer-info on selected mails
2014-04-17 11:59:08 +02:00
if ( ! ( _mode == 'tryastext' || _mode == 'tryashtml' || _mode == 'view' || _mode == 'print' ) ) _mode = 'view' ;
2013-05-21 10:46:54 +02:00
this . mail _selectedMails = [ ] ;
this . mail _selectedMails . push ( _id ) ;
this . mail _currentlyFocussed = _id ;
2013-04-13 12:30:07 +02:00
var dataElem = egw . dataGetUIDdata ( _id ) ;
var subject = dataElem . data . subject ;
2013-06-05 16:24:56 +02:00
//alert('Open Message:'+_id+' '+subject);
2014-09-09 14:08:08 +02:00
var h = egw ( ) . open ( _id , 'mail' , 'view' , _mode + '=' + _id . replace ( /=/g , "_" ) + '&mode=' + _mode ) ;
2013-07-17 14:01:01 +02:00
egw ( h ) . ready ( function ( ) {
h . document . title = subject ;
} ) ;
2014-02-07 15:34:04 +01:00
// 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' ;
2014-12-11 13:01:52 +01:00
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 ) )
2014-02-07 15:34:04 +01:00
{
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]);
}
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-05-13 16:42:42 +02:00
/ * *
* Open a single message in html mode
2013-07-25 17:35:44 +02:00
*
2013-05-13 16:42:42 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
mail _openAsHtml : function ( _action , _elems )
{
2013-07-20 09:23:55 +02:00
this . mail _open ( _action , _elems , 'tryashtml' ) ;
2013-05-13 16:42:42 +02:00
} ,
/ * *
* Open a single message in plain text mode
2013-07-25 17:35:44 +02:00
*
2013-05-13 16:42:42 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
mail _openAsText : function ( _action , _elems )
{
2013-07-20 09:23:55 +02:00
this . mail _open ( _action , _elems , 'tryastext' ) ;
} ,
/ * *
* Compose , reply or forward a message
2013-07-25 17:35:44 +02:00
*
2013-10-07 12:12:18 +02:00
* @ function
* @ memberOf mail
2013-07-20 09:23:55 +02:00
* @ 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 )
{
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 11:03:51 +02:00
{
2013-10-07 12:12:18 +02:00
if ( this . et2 && this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
2013-10-05 11:03:51 +02:00
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2013-10-04 19:45:33 +02:00
// Extra info passed to egw.open()
var settings = {
// 'Source' Mail UID
id : '' ,
// How to pull data from the Mail IDs for the compose
from : ''
} ;
2013-10-09 18:44:03 +02:00
2013-10-05 11:03:51 +02:00
// We only handle one for everything but forward
settings . id = ( typeof _elems == 'undefined' ? '' : _elems [ 0 ] . id ) ;
2017-09-01 16:20:57 +02:00
var content = egw . dataGetUIDdata ( settings . id ) ;
if ( content ) settings . smime _type = content . data [ 'smime' ] ;
2013-10-04 19:45:33 +02:00
switch ( _action . id )
2013-05-13 16:42:42 +02:00
{
2013-10-04 19:45:33 +02:00
case 'compose' :
if ( _elems . length == 1 )
{
2013-10-05 11:03:51 +02:00
//mail_parentRefreshListRowStyle(settings.id,settings.id);
2013-10-04 19:45:33 +02:00
}
else
{
return this . mail _compose ( 'forward' , _elems ) ;
}
break ;
case 'forward' :
case 'forwardinline' :
case 'forwardasattach' :
2013-10-08 16:23:46 +02:00
if ( _elems . length > 1 || _action . id == 'forwardasattach' )
2013-10-04 19:45:33 +02:00
{
2014-01-30 14:37:36 +01:00
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 ;
}
2019-02-26 11:58:20 +01:00
return egw . openWithinWindow ( "mail" , "setCompose" , { data : { emails : { ids : settings . id , processedmail _id : settings . id } } } , settings , /mail.mail_compose.compose/ ) ;
2013-10-04 19:45:33 +02:00
}
else
{
settings . from = 'forward' ;
settings . mode = 'forwardinline' ;
}
break ;
default :
// No further client side processing needed for these
settings . from = _action . id ;
2013-07-20 09:23:55 +02:00
}
2013-10-07 17:28:49 +02:00
var compose _list = egw . getOpenWindows ( "mail" , /^compose_/ ) ;
var window _name = 'compose_' + compose _list . length + '_' + ( settings . from || '' ) + '_' + settings . id ;
2013-10-07 12:12:18 +02:00
return egw ( ) . open ( '' , 'mail' , 'add' , settings , window _name , 'mail' ) ;
2013-10-04 19:45:33 +02:00
} ,
2013-10-09 18:44:03 +02:00
2013-10-07 12:12:18 +02:00
/ * *
* Set content into a compose window
2013-10-09 18:44:03 +02:00
*
2013-10-07 12:12:18 +02:00
* @ function
* @ memberOf mail
2013-10-09 18:44:03 +02:00
*
2018-03-09 17:48:09 +01:00
* @ param { window object } compose compose window object
2014-05-16 17:39:05 +02:00
* @ param { object } content
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ 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
2013-10-09 18:44:03 +02:00
*
2013-10-07 12:12:18 +02:00
* @ return { boolean } Success
* /
2018-03-09 17:48:09 +01:00
setCompose : function ( compose , content )
2013-10-07 12:12:18 +02:00
{
// Get window
if ( ! compose || compose . closed ) return false ;
2013-10-09 18:44:03 +02:00
2013-10-07 12:12:18 +02:00
// Get etemplate of popup
var compose _et2 = compose . etemplate2 . getByApplication ( 'mail' ) ;
if ( ! compose _et2 || compose _et2 . length != 1 || ! compose _et2 [ 0 ] . widgetContainer )
{
return false ;
}
2014-05-20 17:39:20 +02:00
2013-10-07 12:12:18 +02:00
// Set each field provided
var success = true ;
2014-05-16 17:39:05 +02:00
var arrContent = [ ] ;
2013-10-07 12:12:18 +02:00
for ( var field in content )
{
try
{
2018-07-11 14:39:28 +02:00
if ( field == 'data' )
2018-02-28 17:30:29 +01:00
{
2018-07-11 14:39:28 +02:00
var w = compose _et2 [ 0 ] . widgetContainer . getWidgetById ( 'appendix_data' ) ;
w . set _value ( JSON . stringify ( content [ field ] ) ) ;
2018-07-12 15:42:07 +02:00
var filemode = compose _et2 [ 0 ] . widgetContainer . getWidgetById ( 'filemode' ) ;
if ( content [ field ] [ 'files' ] && content [ field ] [ 'files' ] [ 'filemode' ]
&& filemode && filemode . get _value ( ) != content [ field ] [ 'files' ] [ 'filemode' ] )
{
2023-03-27 12:09:26 +02:00
var filemode _label = filemode . options . select _options . filter ( _item => { return _item . value == content [ field ] [ 'files' ] [ 'filemode' ] } ) [ 0 ] [ 'label' ] ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( function ( _button )
2018-07-12 15:42:07 +02:00
{
2022-07-20 22:23:55 +02:00
if ( _button == Et2Dialog . YES _BUTTON )
{
compose _et2 [ 0 ] . widgetContainer . _inst . submit ( ) ;
}
} ,
this . egw . lang (
'Be aware by adding all selected files as %1 mode, it will also change all existing attachments in the list to %2 mode as well. Would you like to proceed?' ,
filemode _label , filemode _label ) ,
this . egw . lang ( 'Add files as %1' , filemode _label ) , '' , Et2Dialog . BUTTONS _YES _NO , Et2Dialog . WARNING _MESSAGE ) ;
2018-07-12 15:42:07 +02:00
return ;
}
else
{
return compose _et2 [ 0 ] . widgetContainer . _inst . submit ( ) ;
}
2018-02-28 17:30:29 +01:00
}
2013-10-07 12:12:18 +02:00
var widget = compose _et2 [ 0 ] . widgetContainer . getWidgetById ( field ) ;
2014-05-20 17:39:20 +02:00
2013-10-07 12:12:18 +02:00
// Merge array values, replace strings
var value = widget . getValue ( ) || content [ field ] ;
2018-08-03 19:00:21 +02:00
if ( jQuery . isArray ( value ) || jQuery . isArray ( content [ field ] ) )
2013-10-07 12:12:18 +02:00
{
if ( jQuery . isArray ( content [ field ] ) )
{
2018-08-03 19:00:21 +02:00
value = value . concat ( content [ field ] ) ;
2013-10-07 12:12:18 +02:00
}
else
{
2014-05-16 17:39:05 +02:00
arrContent = content [ field ] . split ( ',' ) ;
for ( var k = 0 ; k < arrContent . length ; k ++ )
{
value . push ( arrContent [ k ] ) ;
}
2013-10-07 12:12:18 +02:00
}
}
widget . set _value ( value ) ;
}
catch ( e )
{
2018-08-03 19:00:21 +02:00
egw . debug ( "error" , "Unable to set field %s to '%s' in window '%s'" , field , content [ field ] , window . name ) ;
2013-10-07 12:12:18 +02:00
success = false ;
continue ;
}
}
2014-05-23 17:17:42 +02:00
if ( content [ 'cc' ] || content [ 'bcc' ] )
{
2014-06-02 18:57:30 +02:00
this . compose _fieldExpander ( ) ;
2014-10-20 14:25:43 +02:00
this . compose _fieldExpander _init ( ) ;
2014-05-23 17:17:42 +02:00
}
2013-10-07 12:12:18 +02:00
return success ;
} ,
2013-08-21 12:47:20 +02:00
2013-05-27 15:48:55 +02:00
/ * *
* mail _disablePreviewArea - implementation of the disablePreviewArea action
2013-07-25 17:35:44 +02:00
*
2013-05-27 15:48:55 +02:00
* @ param _value
* /
mail _disablePreviewArea : function ( _value ) {
2013-10-18 11:58:25 +02:00
var splitter = this . et2 . getWidgetById ( 'mailSplitter' ) ;
2023-04-03 13:17:27 +02:00
var previewPane = this . egw . preference ( 'previewPane' , 'mail' ) || 'vertical' ;
2015-02-27 15:47:27 +01:00
// return if there's no splitter we maybe in mobile mode
2023-03-13 16:08:19 +01:00
if ( typeof splitter == 'undefined' || splitter == null || previewPane == 'vertical' ) return ;
2023-03-07 14:50:09 +01:00
let dock = function ( ) {
splitter . style . setProperty ( '--max' , '100%' ) ;
splitter . dock ( ) ;
} ;
let undock = function ( )
{
splitter . style . setProperty ( '--max' , '70%' ) ;
splitter . undock ( ) ;
} ;
2013-11-21 00:35:27 +01:00
if ( splitter . isDocked ( ) )
{
this . mail _previewAreaActive = false ;
}
2013-10-18 11:58:25 +02:00
this . et2 . getWidgetById ( 'mailPreview' ) . set _disabled ( _value ) ;
2014-12-17 13:02:01 +01:00
//Dock the splitter always if we are browsing with mobile
2023-03-24 13:53:42 +01:00
if ( egwIsMobile ( ) )
{
this . mail _disablePreviewArea = _value = true ;
}
2015-02-27 15:47:27 +01:00
if ( _value == true )
2013-05-27 15:48:55 +02:00
{
2023-03-07 14:50:09 +01:00
if ( this . mail _previewAreaActive ) dock ( ) ;
2013-05-29 14:34:33 +02:00
this . mail _previewAreaActive = false ;
2013-07-25 17:35:44 +02:00
}
2013-05-27 15:48:55 +02:00
else
{
2015-10-15 15:02:26 +02:00
if ( ! this . mail _previewAreaActive )
{
2023-03-07 14:50:09 +01:00
undock ( ) ;
//window.setTimeout(function(){splitter.left.trigger('resize.et2_split.mailSplitter');},200);
2015-10-15 15:02:26 +02:00
}
2013-05-29 14:34:33 +02:00
this . mail _previewAreaActive = true ;
2013-05-27 15:48:55 +02:00
}
} ,
2014-02-04 13:51:15 +01:00
/ * *
* Set values for mail dispaly From , Sender , To , Cc , and Bcc
* Additionally , apply expand on click feature on thier widgets
2014-02-05 13:23:04 +01:00
*
2014-02-04 13:51:15 +01:00
* /
mail _display : function ( )
{
var dataElem = { data : { FROM : "" , SENDER : "" , TO : "" , CC : "" , BCC : "" } } ;
var content = this . et2 . getArrayMgr ( 'content' ) . data ;
if ( typeof content != 'undefiend' )
{
dataElem . data = jQuery . extend ( dataElem . data , content ) ;
2014-02-05 17:17:37 +01:00
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 ) ;
2014-02-04 13:51:15 +01:00
}
} ,
2022-07-27 14:21:21 +02:00
/ * *
* Handle actions from attachments block
* @ param _e
* @ param _widget
* /
attachmentsBlockActions : function ( _e , _widget )
{
const id = _widget . id . replace ( '[actions]' , '' ) ;
const action = _widget . value ;
2023-08-14 16:35:03 +02:00
_widget . label = this . egw . lang ( _widget . select _options . filter ( _item => { return _item . value == _widget . value } ) [ 0 ] . label ) ;
2022-07-27 14:21:21 +02:00
this . saveAttachmentHandler ( _widget , action , id ) ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _preview - implementation of the preview action
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param nextmatch et2 _nextmatch The widget whose row was selected
* @ param selected Array Selected row IDs . May be empty if user unselected all rows .
* /
2013-10-09 16:35:03 +02:00
mail _preview : function ( selected , nextmatch ) {
2022-07-22 15:08:23 +02:00
let data = { } ;
let rowId = '' ;
2022-07-27 14:21:21 +02:00
let sel _options = { }
2022-07-22 15:08:23 +02:00
let attachmentsBlock = this . et2 . getWidgetById ( 'attachmentsBlock' ) ;
let mailPreview = this . et2 . getWidgetById ( 'mailPreview' ) ;
2023-04-03 13:17:27 +02:00
let previewPane = this . egw . preference ( 'previewPane' , 'mail' ) || 'vertical' ;
2023-03-24 14:44:58 +01:00
// don't go further if the preview is supposed to be disabled and we're not in mobile view
if ( previewPane == 'hide' && ! egwIsMobile ( ) ) return ;
2013-06-04 17:29:53 +02:00
if ( typeof selected != 'undefined' && selected . length == 1 )
2013-02-19 17:30:59 +01:00
{
2022-07-22 15:08:23 +02:00
rowId = this . mail _fetchCurrentlyFocussed ( selected ) ;
data = egw . dataGetUIDdata ( rowId ) . data ;
2023-06-21 16:45:23 +02:00
data . emailTag = egw . preference ( 'emailTag' , 'mail' ) ? ? 'onlyname' ;
2015-11-27 17:17:59 +01:00
// Try to resolve winmail.data attachment
2022-07-22 15:08:23 +02:00
if ( data && data . attachmentsBlock [ 0 ]
&& data . attachmentsBlock [ 0 ] . winmailFlag
&& ( data . attachmentsBlock [ 0 ] . mimetype == 'application/ms-tnef' ||
data . attachmentsBlock [ 0 ] . filename == "winmail.dat" ) )
2015-11-27 17:17:59 +01:00
{
2022-07-22 15:08:23 +02:00
attachmentsBlock . getDOMNode ( ) . classList . add ( 'loading' ) ;
this . egw . jsonq ( 'mail.mail_ui.ajax_resolveWinmail' , [ rowId ] , jQuery . proxy ( function ( _data ) {
attachmentsBlock . getDOMNode ( ) . classList . remove ( 'loading' ) ;
2015-11-27 17:17:59 +01:00
if ( typeof _data == 'object' )
{
2022-07-22 15:08:23 +02:00
data . attachmentsBlock = _data ;
2023-02-07 12:22:23 +01:00
data . attachmentsBlockTitle = _data . length > 1 ? ` + ${ _data . length - 1 } ` : '' ;
2015-11-30 15:55:39 +01:00
// Update client cache to avoid resolving winmail.dat attachment again
2022-07-28 15:03:56 +02:00
egw . dataStoreUID ( data . uid , data ) ;
2023-03-03 11:05:34 +01:00
if ( ! egwIsMobile ( ) && mailPreview ) mailPreview . set _value ( { content : data } ) ;
2015-11-27 17:17:59 +01:00
}
else
{
console . log ( 'Can not resolve the winmail.data!' ) ;
}
2022-07-22 15:08:23 +02:00
} , data ) ) ;
2015-11-27 17:17:59 +01:00
}
2013-02-19 17:30:59 +01:00
}
2014-11-20 16:05:25 +01:00
2022-07-22 15:08:23 +02:00
if ( data . toaddress || data . fromaddress )
2013-10-05 18:36:20 +02:00
{
2022-07-22 15:08:23 +02:00
data . additionaltoaddress = ( data . additionaltoaddress ? ? [ ] ) . concat ( data . toaddress ) ;
2022-07-26 13:22:54 +02:00
data . additionaltoaddress = data . additionaltoaddress . filter ( ( i , item ) => {
return data . additionaltoaddress . indexOf ( i ) == item
} ) ;
2022-07-22 15:08:23 +02:00
data . additionalfromaddress = ( data . additionalfromaddress ? ? [ ] ) . concat ( data . fromaddress ) ;
2022-07-26 13:22:54 +02:00
data . additionalfromaddress = data . additionalfromaddress . filter ( ( i , item ) => {
return data . additionalfromaddress . indexOf ( i ) == item
} ) ;
2022-07-22 15:08:23 +02:00
}
2014-11-20 16:05:25 +01:00
2022-07-27 14:21:21 +02:00
if ( data . attachmentsBlock )
{
const actions = [
{
id : 'downloadOneAsFile' ,
2023-01-31 23:03:18 +01:00
label : 'Download' ,
icon : 'fileexport' ,
value : 'downloadOneAsFile'
2022-07-27 14:21:21 +02:00
} ,
{
id : 'saveOneToVfs' ,
2023-07-18 21:40:04 +02:00
label : 'Save to Filemanager' ,
2023-01-31 23:03:18 +01:00
icon : 'filemanager/navbar' ,
2022-07-27 14:21:21 +02:00
value : 'saveOneToVfs'
} ,
{
id : 'saveAllToVfs' ,
2023-07-18 21:40:04 +02:00
label : 'Save all attachments to Filemanager' ,
2022-07-27 14:21:21 +02:00
icon : 'mail/save_all' ,
value : 'saveAllToVfs'
} ,
{
id : 'downloadAllToZip' ,
label : 'Save as ZIP' ,
icon : 'mail/save_zip' ,
value : 'downloadAllToZip'
2023-08-03 18:16:35 +02:00
} ,
{
id : 'forward' ,
label : 'Forward to' ,
icon : 'mail/forward' ,
value : 'forward'
2022-07-27 14:21:21 +02:00
}
] ;
2023-02-01 16:57:31 +01:00
const collabora = {
id : 'collabora' ,
2023-02-10 18:02:30 +01:00
label : 'Collabora' ,
2023-02-01 16:57:31 +01:00
icon : 'collabora/navbar' ,
value : 'collabora'
} ;
2023-02-07 12:22:23 +01:00
data . attachmentsBlockTitle = data . attachmentsBlock . length > 1 ? ` + ${ data . attachmentsBlock . length - 1 } ` : '' ;
2023-02-01 16:57:31 +01:00
sel _options . attachmentsBlock = { } ;
2023-01-31 23:03:18 +01:00
data . attachmentsBlock . forEach ( _item =>
{
_item . actions = 'downloadOneAsFile' ;
2022-07-27 14:21:21 +02:00
// for some reason label needs to be set explicitly for the dropdown button. It needs more investigation.
2023-01-31 23:03:18 +01:00
_item . actionsDefaultLabel = 'Download' ;
2023-02-01 16:57:31 +01:00
2023-02-09 18:39:12 +01:00
if ( typeof this . egw . user ( 'apps' ) [ 'collabora' ] !== "undefined" && this . egw . isCollaborable ( _item . type ) )
2023-02-01 16:57:31 +01:00
{
2023-02-09 18:39:12 +01:00
// Start with download on top, Collabora on bottom
sel _options . attachmentsBlock [ _item . attachment _number + "[actions]" ] = [ ... actions , collabora ] ;
2023-02-06 16:15:21 +01:00
if ( egw . preference ( 'document_doubleclick_action' , 'filemanager' ) === 'collabora' )
{
2023-02-07 09:47:58 +01:00
_item . actions = 'collabora' ;
2023-02-06 16:15:21 +01:00
_item . actionsDefaultLabel = 'Collabora' ;
2023-02-09 18:39:12 +01:00
// Put Collabora on top
sel _options . attachmentsBlock [ _item . attachment _number + "[actions]" ] = [ collabora , ... actions ] ;
2023-02-06 16:15:21 +01:00
}
2023-02-01 16:57:31 +01:00
}
2022-07-27 14:21:21 +02:00
} ) ;
2023-02-01 16:57:31 +01:00
sel _options . attachmentsBlock . actions = actions ;
2022-07-27 14:21:21 +02:00
}
2023-03-03 11:05:34 +01:00
if ( ! egwIsMobile ( ) && mailPreview ) mailPreview . set _value ( { content : data , sel _options : sel _options } ) ;
2017-11-10 11:13:12 +01:00
2022-07-25 11:59:58 +02:00
if ( selected && selected . length > 1 )
2013-10-05 18:36:20 +02:00
{
2014-02-10 20:52:23 +01:00
// Leave if we're here and there is nothing selected, too many, or no data
2022-07-22 15:08:23 +02:00
if ( attachmentsBlock )
2015-02-27 15:47:27 +01:00
{
2023-03-07 14:50:09 +01:00
// check if the widget is attached before setting its content
if ( attachmentsBlock . parentNode )
{
attachmentsBlock . set _value ( { content : [ ] } ) ;
attachmentsBlock . set _class ( 'previewAttachmentArea noContent mail_DisplayNone' ) ;
}
2015-02-27 15:47:27 +01:00
var IframeHandle = this . et2 . getWidgetById ( 'messageIFRAME' ) ;
2023-03-07 14:50:09 +01:00
if ( IframeHandle ) IframeHandle . set _src ( 'about:blank' ) ;
2015-02-27 15:47:27 +01:00
this . mail _disablePreviewArea ( true ) ;
}
2016-04-27 15:03:52 +02:00
if ( ! egwIsMobile ( ) ) return ;
2013-10-05 18:36:20 +02:00
}
2016-04-27 15:03:52 +02:00
// Not applied to mobile preview
2023-03-24 13:53:42 +01:00
else if ( ! egwIsMobile ( ) && previewPane != 'hide' )
2016-04-27 15:03:52 +02:00
{
// Blank first, so we don't show previous email while loading
var IframeHandle = this . et2 . getWidgetById ( 'messageIFRAME' ) ;
IframeHandle . set _src ( 'about:blank' ) ;
2014-01-18 18:01:29 +01:00
2022-07-28 16:39:47 +02:00
this . smime _clear _flags ( [ this . et2 . getWidgetById ( 'mailPreviewContainer' ) . getDOMNode ( ) ] ) ;
2016-04-27 15:03:52 +02:00
// show iframe, in case we hide it from mailvelopes one and remove that
jQuery ( IframeHandle . getDOMNode ( ) ) . show ( )
. next ( this . mailvelope _iframe _selector ) . remove ( ) ;
2015-05-17 21:03:45 +02:00
2016-07-27 10:31:43 +02:00
// need to have the DOM ready for calculation.
2023-03-24 13:53:42 +01:00
this . mail _disablePreviewArea ( ( typeof selected == 'undefined' || selected . length == 0 && previewPane == 'expand' ) ) ;
2014-02-05 13:23:04 +01:00
2016-04-27 15:03:52 +02:00
// Update the internal list of selected mails, if needed
2022-07-22 15:08:23 +02:00
if ( this . mail _selectedMails . indexOf ( rowId ) < 0 )
2016-04-27 15:03:52 +02:00
{
2022-07-22 15:08:23 +02:00
this . mail _selectedMails . push ( rowId ) ;
2016-04-27 15:03:52 +02:00
}
2016-11-23 18:52:43 +01:00
var self = this ;
2014-01-18 18:01:29 +01:00
2018-09-06 16:03:48 +02:00
// Try to avoid sending so many request when user tries to scroll on list
// via key up/down quite fast.
for ( var t in this . W _TIMEOUTS ) { window . clearTimeout ( this . W _TIMEOUTS [ t ] ) ; }
this . W _TIMEOUTS . push ( window . setTimeout ( function ( ) {
2022-07-22 15:08:23 +02:00
console . log ( rowId ) ;
2018-09-06 16:03:48 +02:00
// Request email body from server
2022-07-22 15:08:23 +02:00
IframeHandle . set _src ( egw . link ( '/index.php' , { menuaction : 'mail.mail_ui.loadEmailBody' , _messageID : rowId } ) ) ;
2018-09-06 16:03:48 +02:00
jQuery ( IframeHandle . getDOMNode ( ) ) . on ( 'load' , function ( e ) {
self . resolveExternalImages ( this . contentWindow . document ) ;
} ) ;
} , 300 ) ) ;
2017-09-13 18:17:32 +02:00
}
2023-03-23 12:08:23 +01:00
2013-06-05 12:41:38 +02:00
var messages = { } ;
2022-07-22 15:08:23 +02:00
messages [ 'msg' ] = [ rowId ] ;
2014-01-13 15:22:58 +01:00
// When body is requested, mail is marked as read by the mail server. Update UI to match.
2022-07-22 15:08:23 +02:00
if ( typeof data != 'undefined' && typeof data != 'undefined' && typeof data . flags != 'undefined' && typeof data . flags . read != 'undefined' ) data . flags . read = 'read' ;
if ( typeof data != 'undefined' && typeof data != 'undefined' && typeof data [ 'class' ] != 'undefined' && ( data [ 'class' ] . indexOf ( 'unseen' ) >= 0 || data [ 'class' ] . indexOf ( 'recent' ) >= 0 ) )
2014-02-07 15:34:04 +01:00
{
this . mail _removeRowClass ( messages , 'recent' ) ;
this . mail _removeRowClass ( messages , 'unseen' ) ;
// reduce counter without server roundtrip
this . mail _reduceCounterWithoutServerRoundtrip ( ) ;
2022-07-22 15:08:23 +02:00
if ( typeof data . dispositionnotificationto != 'undefined' && data . dispositionnotificationto &&
typeof data . flags . mdnsent == 'undefined' && typeof data . flags . mdnnotsent == 'undefined' )
2014-03-25 17:20:28 +01:00
{
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Yes" ) , id : "mdnsent" , image : "check" } ,
{ label : this . egw . lang ( "No" ) , id : "mdnnotsent" , image : "cancelled" }
2014-03-25 17:20:28 +01:00
] ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( function ( _button _id , _value )
2014-03-25 17:20:28 +01:00
{
2022-07-20 22:23:55 +02:00
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 ] ) ;
}
} ,
2014-03-25 17:20:28 +01:00
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 ) ;
}
2014-02-07 15:34:04 +01:00
egw . jsonq ( 'mail.mail_ui.ajax_flagMessages' , [ 'read' , messages , false ] ) ;
}
2013-04-13 12:30:07 +02:00
} ,
2013-05-27 15:48:55 +02:00
2016-11-23 18:52:43 +01:00
resolveExternalImages : function ( _node )
{
2020-07-09 11:54:52 +02:00
let image _proxy = this . image _proxy ;
2016-12-02 10:09:56 +01:00
//Do not run resolve images if it's forced already to show them all
// or forced to not show them all.
var pref _img = egw . preference ( 'allowExternalIMGs' , 'mail' ) ;
2020-06-30 15:54:21 +02:00
if ( pref _img == 0 ) return ;
2016-12-02 10:09:56 +01:00
2016-11-23 18:52:43 +01:00
var external _images = jQuery ( _node ) . find ( 'img[alt*="[blocked external image:"]' ) ;
if ( external _images . length > 0 && jQuery ( _node ) . find ( '.mail_externalImagesMsg' ) . length == 0 )
{
var container = jQuery ( document . createElement ( 'div' ) )
2016-11-24 14:35:54 +01:00
. click ( function ( ) { jQuery ( this ) . remove ( ) ; } )
. addClass ( 'mail_externalImagesMsg' ) ;
2016-11-23 18:52:43 +01:00
var getUrlParts = function ( _rawUrl ) {
var u = _rawUrl . split ( '[blocked external image:' ) ;
u = u [ 1 ] . replace ( ']' , '' ) ;
var url = u ;
2020-06-25 16:34:40 +02:00
var protocol = '' ;
if ( u . substr ( 0 , 7 ) == 'http://' )
{
u = u . replace ( 'http://' , '' ) ;
2020-07-09 11:54:52 +02:00
url = url . replace ( 'http://' , image _proxy ) ;
2020-06-25 16:34:40 +02:00
protocol = 'http' ;
}
2020-06-30 15:54:21 +02:00
else if ( u . substr ( 0 , 8 ) == 'https://' )
2020-06-25 16:34:40 +02:00
{
u = u . replace ( 'https://' , '' ) ;
protocol = 'https' ;
}
2016-11-23 18:52:43 +01:00
var url _parts = u . split ( '/' ) ;
return {
url : url ,
2020-06-25 16:34:40 +02:00
domain : url _parts [ 0 ] ,
protocol : protocol
2016-11-23 18:52:43 +01:00
} ;
2017-07-04 13:25:38 +02:00
} ;
2016-11-23 18:52:43 +01:00
var host = getUrlParts ( external _images [ 0 ] . alt ) ;
2016-11-24 14:35:54 +01:00
var showImages = function ( _images , _save )
2016-11-23 18:52:43 +01:00
{
2016-11-24 14:35:54 +01:00
var save = _save || false ;
_images . each ( function ( i , node ) {
2016-11-23 18:52:43 +01:00
var parts = getUrlParts ( node . alt ) ;
2016-11-24 14:35:54 +01:00
if ( save )
{
if ( pref && pref . length )
{
if ( pref . indexOf ( parts . domain ) == - 1 )
{
pref . push ( parts . domain ) ;
2016-12-02 10:09:56 +01:00
egw . set _preference ( 'mail' , 'allowExternalDomains' , pref ) ;
2016-11-24 14:35:54 +01:00
}
}
else
{
pref = [ parts . domain ] ;
2016-12-02 10:09:56 +01:00
egw . set _preference ( 'mail' , 'allowExternalDomains' , pref ) ;
2016-11-24 14:35:54 +01:00
}
}
2016-11-23 18:52:43 +01:00
node . src = parts . url ;
} ) ;
2017-07-04 13:25:38 +02:00
} ;
2016-12-02 10:09:56 +01:00
var pref = egw . preference ( 'allowExternalDomains' , 'mail' ) || { } ;
2016-11-23 18:52:43 +01:00
pref = Object . values ( pref ) ;
if ( pref . indexOf ( host . domain ) > - 1 )
{
showImages ( external _images ) ;
return ;
}
2020-07-09 11:54:52 +02:00
let message = this . egw . lang ( 'In order to protect your privacy all external sources within this email are blocked.' ) ;
2020-06-25 16:34:40 +02:00
for ( let i in external _images )
{
if ( ! external _images [ i ] . alt ) continue ;
let r = getUrlParts ( external _images [ i ] . alt ) ;
if ( r && r . protocol == 'http' )
{
2020-07-09 11:54:52 +02:00
message = this . egw . lang ( 'This mail contains external images served via insecure HTTP protocol. Be aware showing or allowing them can compromise your security!' ) ;
2020-06-25 16:34:40 +02:00
container . addClass ( 'red' ) ;
break ;
}
}
2016-11-24 14:35:54 +01:00
jQuery ( document . createElement ( 'p' ) )
2020-07-09 11:54:52 +02:00
. text ( message )
2016-11-23 18:52:43 +01:00
. appendTo ( container ) ;
2016-11-24 14:35:54 +01:00
jQuery ( document . createElement ( 'button' ) )
. addClass ( 'closeBtn' )
2016-11-23 18:52:43 +01:00
. click ( function ( ) {
container . remove ( ) ;
} )
. appendTo ( container ) ;
2016-11-24 14:35:54 +01:00
jQuery ( document . createElement ( 'button' ) )
2018-01-04 11:34:26 +01:00
. text ( this . egw . lang ( 'Allow' ) )
. attr ( 'title' , this . egw . lang ( 'Always allow external sources from %1' , host . domain ) )
2016-11-23 18:52:43 +01:00
. click ( function ( ) {
2016-11-24 14:35:54 +01:00
showImages ( external _images , true ) ;
2016-11-23 18:52:43 +01:00
container . remove ( ) ;
} )
. appendTo ( container ) ;
2016-11-24 14:35:54 +01:00
jQuery ( document . createElement ( 'button' ) )
2018-01-04 11:34:26 +01:00
. text ( this . egw . lang ( 'Show' ) )
. attr ( 'title' , this . egw . lang ( 'Show them this time only' ) )
2016-11-23 18:52:43 +01:00
. click ( function ( ) {
showImages ( external _images ) ;
container . remove ( ) ;
} )
. appendTo ( container ) ;
2016-11-24 14:35:54 +01:00
container . appendTo ( _node . body ? _node . body : _node ) ;
2016-11-23 18:52:43 +01:00
}
} ,
2013-12-03 15:38:50 +01:00
/ * *
2013-12-23 23:37:40 +01:00
* 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 .
*
2013-12-03 15:38:50 +01:00
* requires : mainWindow , one mail selected for preview
2014-02-12 21:12:59 +01:00
*
2014-02-11 11:45:01 +01:00
* @ param { jQuery event } event
* @ param { Object } widget
2013-12-23 23:37:40 +01:00
* @ param { DOMNode } button
2013-12-03 15:38:50 +01:00
* /
2014-02-11 11:45:01 +01:00
showAllHeader : function ( event , widget , button ) {
2013-12-18 01:37:30 +01:00
// Show list as a list
var list = jQuery ( button ) . prev ( ) ;
2014-02-11 11:45:01 +01:00
/ * i f ( l i s t . l e n g t h < = 0 )
{
list = jQuery ( button . target ) . prev ( ) ;
} * /
2014-02-12 21:12:59 +01:00
2013-12-18 01:37:30 +01:00
list . toggleClass ( 'visible' ) ;
// Revert if user clicks elsewhere
2016-06-02 16:51:15 +02:00
jQuery ( 'body' ) . one ( 'click' , list , function ( ev ) {
2013-12-18 01:37:30 +01:00
ev . data . removeClass ( 'visible' ) ;
2013-12-03 17:46:32 +01:00
} ) ;
2013-12-03 15:38:50 +01:00
} ,
2013-04-13 12:30:07 +02:00
mail _setMailBody : function ( content ) {
2013-10-18 11:58:25 +02:00
var IframeHandle = this . et2 . getWidgetById ( 'messageIFRAME' ) ;
2013-04-13 12:30:07 +02:00
IframeHandle . set _value ( '' ) ;
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _refreshFolderStatus , function to call to read the counters of a folder and apply them
2013-07-25 17:35:44 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { stirng } _nodeID
* @ param { string } mode
* @ param { boolean } _refreshGridArea
* @ param { boolean } _refreshQuotaDisplay
2014-05-20 17:39:20 +02:00
*
2013-04-13 12:30:07 +02:00
* /
2014-01-21 12:28:43 +01:00
mail _refreshFolderStatus : function ( _nodeID , mode , _refreshGridArea , _refreshQuotaDisplay ) {
2014-01-09 09:36:22 +01:00
if ( typeof _nodeID != 'undefined' && typeof _nodeID [ _nodeID ] != 'undefined' && _nodeID [ _nodeID ] )
{
_refreshGridArea = _nodeID [ _refreshGridArea ] ;
mode = _nodeID [ mode ] ;
_nodeID = _nodeID [ _nodeID ] ;
}
2013-04-13 12:30:07 +02:00
var nodeToRefresh = 0 ;
var mode2use = "none" ;
2013-11-19 16:14:36 +01:00
if ( typeof _refreshGridArea == 'undefined' ) _refreshGridArea = true ;
2014-01-21 12:28:43 +01:00
if ( typeof _refreshQuotaDisplay == 'undefined' ) _refreshQuotaDisplay = true ;
2013-04-13 12:30:07 +02:00
if ( _nodeID ) nodeToRefresh = _nodeID ;
if ( mode ) {
if ( mode == "forced" ) { mode2use = mode ; }
}
try
{
2013-10-18 11:58:25 +02:00
var tree _wdg = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
var activeFolders = tree _wdg . getTreeNodeOpenItems ( nodeToRefresh , mode2use ) ;
//alert(activeFolders.join('#,#'));
2014-01-27 13:18:16 +01:00
this . mail _queueRefreshFolderList ( ( mode == 'thisfolderonly' && nodeToRefresh ? [ _nodeID ] : activeFolders ) ) ;
2013-11-19 16:14:36 +01:00
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 ( ) ;
}
2014-01-21 12:28:43 +01:00
if ( _refreshQuotaDisplay )
{
this . mail _refreshQuotaDisplay ( ) ;
}
2013-12-09 10:57:03 +01:00
//the two lines below are not working yet.
//var no =tree_wdg.getSelectedNode();
//tree_wdg.focusItem(no.id);
2013-04-13 12:30:07 +02:00
} catch ( e ) { } // ignore the error; maybe the template is not loaded yet
} ,
2013-07-25 17:35:44 +02:00
2013-10-18 11:58:25 +02:00
/ * *
* mail _refreshQuotaDisplay , function to call to read the quota for the active server
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _server
2013-10-18 11:58:25 +02:00
*
* /
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
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _data
2013-10-18 11:58:25 +02:00
*
* /
mail _setQuotaDisplay : function ( _data )
{
2014-07-17 16:39:56 +02:00
if ( ! this . et2 && ! this . checkET2 ( ) ) return ;
2014-04-15 13:57:15 +02:00
2013-10-18 11:58:25 +02:00
var quotabox = this . et2 . getWidgetById ( this . nm _index + '[quotainpercent]' ) ;
2014-05-20 17:39:20 +02:00
2014-04-02 22:20:49 +02:00
// 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 ) ;
2022-07-22 15:08:23 +02:00
if ( _data . quotawarning )
2017-03-10 11:22:51 +01:00
{
var self = this ;
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Empty Trash and Junk" ) , id : "cleanup" , class : "ui-priority-primary" , default : true , image : "delete" } ,
{ label : this . egw . lang ( "Cancel" ) , id : "cancel" }
2017-03-10 11:22:51 +01:00
] ;
var server = [ { iface : { id : _data . data . profileid + '::' } } ] ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( function ( _button _id )
2017-03-10 11:22:51 +01:00
{
2022-07-20 22:23:55 +02:00
if ( _button _id == "cleanup" )
{
self . mail _emptySpam ( null , server ) ;
self . mail _emptyTrash ( null , server ) ;
}
return ;
} ,
this . egw . lang ( "Your remaining quota %1 is too low, you may not be able to send/receive further emails.\n Although cleaning up emails in trash or junk folder might help you to get some free space back.\n If that didn't help, please ask your administrator for more quota." , _data . data . quotafreespace ) ,
this . egw . lang ( "Mail cleanup" ) ,
'' , buttons , Et2Dialog . WARNING _MESSAGE ) ;
2017-03-10 11:22:51 +01:00
}
2014-04-02 22:20:49 +02:00
}
2013-10-18 11:58:25 +02:00
} ,
2013-07-25 17:35:44 +02:00
2014-04-03 14:20:23 +02:00
/ * *
* mail _callRefreshVacationNotice , function to call the serverside function to refresh the vacationnotice for the active server
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _server
2014-04-03 14:20:23 +02:00
*
* /
mail _callRefreshVacationNotice : function ( _server )
{
2014-08-11 14:44:33 +02:00
egw . jsonq ( 'mail_ui::ajax_refreshVacationNotice' , [ _server ] ) ;
2014-04-03 14:20:23 +02:00
} ,
2014-07-14 22:50:08 +02:00
/ * *
* Make sure attachments have all needed data , so they can be found for
* HTML5 native dragging
*
* @ param { string } mail _id Mail UID
* @ param { array } attachments Attachment information .
* /
register _for _drag : function ( mail _id , attachments )
{
// Put required info in global store
var data = { } ;
2014-07-16 13:10:25 +02:00
if ( ! attachments ) return ;
2014-07-14 22:50:08 +02:00
for ( var i = 0 ; i < attachments . length ; i ++ )
{
var data = attachments [ i ] || { } ;
if ( ! data . filename || ! data . type ) continue ;
// Add required info
data . mime = data . type ;
data . download _url = egw . link ( '/index.php' , {
menuaction : 'mail.mail_ui.getAttachment' ,
id : mail _id ,
part : data . partID ,
is _winmail : data . winmailFlag
} ) ;
data . name = data . filename ;
}
} ,
/ * *
* Display helper for dragging attachments
*
* @ param { egwAction } _action
* @ param { egwActionElement [ ] } _elems
* @ returns { DOMNode }
* /
drag _attachment : function ( _action , _elems )
{
2016-06-02 16:51:15 +02:00
var div = jQuery ( document . createElement ( "div" ) )
2014-07-14 22:50:08 +02:00
. css ( {
position : 'absolute' ,
top : '0px' ,
left : '0px' ,
width : '300px'
} ) ;
var data = _elems [ 0 ] . data || { } ;
2014-07-15 11:37:08 +02:00
2016-06-02 16:51:15 +02:00
var text = jQuery ( document . createElement ( 'div' ) ) . css ( { left : '30px' , position : 'absolute' } ) ;
2014-07-14 22:50:08 +02:00
// add filename or number of files for multiple files
text . text ( _elems . length > 1 ? _elems . length + ' ' + this . egw . lang ( 'files' ) : data . name || '' ) ;
div . append ( text ) ;
// Add notice of Ctrl key, if supported
if ( window . FileReader && 'draggable' in document . createElement ( 'span' ) &&
navigator && navigator . userAgent . indexOf ( 'Chrome' ) >= 0 )
{
var key = [ "Mac68K" , "MacPPC" , "MacIntel" ] . indexOf ( window . navigator . platform ) < 0 ? 'Ctrl' : 'Command' ;
text . append ( '<br />' + this . egw . lang ( 'Hold %1 to drag files to your computer' , key ) ) ;
}
return div ;
} ,
2014-04-03 14:20:23 +02:00
/ * *
* mail _refreshVacationNotice , function to call with appropriate data to refresh the vacationnotice for the active server
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _data
2014-04-03 14:20:23 +02:00
*
* /
mail _refreshVacationNotice : function ( _data )
{
2014-07-17 16:39:56 +02:00
if ( ! this . et2 && ! this . checkET2 ( ) ) return ;
2014-04-03 14:20:23 +02:00
if ( _data == null )
{
2022-09-15 16:06:10 +02:00
this . et2 . getWidgetById ( 'mail.index.vacationnotice' ) . set _disabled ( true ) ;
2014-04-03 14:20:23 +02:00
this . et2 . getWidgetById ( this . nm _index + '[vacationnotice]' ) . set _value ( '' ) ;
this . et2 . getWidgetById ( this . nm _index + '[vacationrange]' ) . set _value ( '' ) ;
}
else
{
2022-09-15 16:06:10 +02:00
this . et2 . getWidgetById ( 'mail.index.vacationnotice' ) . set _disabled ( false ) ;
2014-04-03 14:20:23 +02:00
this . et2 . getWidgetById ( this . nm _index + '[vacationnotice]' ) . set _value ( _data . vacationnotice ) ;
this . et2 . getWidgetById ( this . nm _index + '[vacationrange]' ) . set _value ( _data . vacationrange ) ;
}
} ,
2016-04-12 14:53:50 +02:00
/ * *
* Enable or disable the date filter
*
* If the searchtype ( cat _id ) is set to something that needs dates , we enable the
* header _right template . Otherwise , it is disabled .
* /
mail _searchtype _change : function ( )
{
var filter = this . et2 . getWidgetById ( 'cat_id' ) ;
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
var dates = this . et2 . getWidgetById ( 'mail.index.datefilter' ) ;
if ( nm && filter )
{
switch ( filter . getValue ( ) )
{
case 'bydate' :
if ( filter && dates )
{
dates . set _disabled ( false ) ;
if ( this . et2 . getWidgetById ( 'startdate' ) ) jQuery ( this . et2 . getWidgetById ( 'startdate' ) . getDOMNode ( ) ) . find ( 'input' ) . focus ( ) ;
}
this . mail _callRefreshVacationNotice ( ) ;
return true ;
default :
if ( dates )
{
dates . set _disabled ( true ) ;
}
this . mail _callRefreshVacationNotice ( ) ;
return true ;
}
}
return false ;
} ,
2014-04-11 15:52:58 +02:00
/ * *
* mail _refreshFilter2Options , function to call with appropriate data to refresh the filter2 options for the active server
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _data
2014-04-11 15:52:58 +02:00
*
* /
mail _refreshFilter2Options : function ( _data )
{
//alert('mail_refreshFilter2Options');
if ( _data == null ) return ;
2014-07-17 16:39:56 +02:00
if ( ! this . et2 && ! this . checkET2 ( ) ) return ;
2014-04-11 15:52:58 +02:00
var filter2 = this . et2 . getWidgetById ( 'filter2' ) ;
var current = filter2 . value ;
var currentexists = false ;
for ( var k in _data )
{
if ( k == current ) currentexists = true ;
}
2016-02-25 13:26:50 +01:00
if ( ! currentexists ) filter2 . set _value ( '' ) ;
2014-04-11 15:52:58 +02:00
filter2 . set _select _options ( _data ) ;
} ,
/ * *
* mail _refreshFilterOptions , function to call with appropriate data to refresh the filter options for the active server
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _data
2014-04-11 15:52:58 +02:00
*
* /
mail _refreshFilterOptions : function ( _data )
{
//alert('mail_refreshFilterOptions');
if ( _data == null ) return ;
2014-07-17 16:39:56 +02:00
if ( ! this . et2 && ! this . checkET2 ( ) ) return ;
2014-04-11 15:52:58 +02:00
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 ) ;
} ,
2016-02-25 13:26:50 +01:00
/ * *
2016-04-12 14:53:50 +02:00
* mail _refreshCatIdOptions , function to call with appropriate data to refresh the filter options for the active server
2016-02-25 13:26:50 +01:00
*
* @ param { object } _data
*
* /
mail _refreshCatIdOptions : function ( _data )
{
2016-04-12 14:53:50 +02:00
//alert('mail_refreshCatIdOptions');
2016-02-25 13:26:50 +01:00
if ( _data == null ) return ;
if ( ! this . et2 && ! this . checkET2 ( ) ) return ;
var filter = this . et2 . getWidgetById ( 'cat_id' ) ;
var current = filter . value ;
var currentexists = false ;
for ( var k in _data )
{
if ( k == current ) currentexists = true ;
}
if ( ! currentexists ) filter . set _value ( 'quick' ) ;
filter . set _select _options ( _data ) ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
2017-03-08 15:11:42 +01:00
* Queues a refreshFolderList request for 500 ms . Actually this will just execute the
2013-04-13 12:30:07 +02:00
* code after the calling script has finished .
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { array } _folders description
2013-04-13 12:30:07 +02:00
* /
mail _queueRefreshFolderList : function ( _folders )
2013-02-13 15:02:02 +01:00
{
2014-08-07 17:56:25 +02:00
var self = this ;
2014-01-27 13:18:16 +01:00
// as jsonq is too fast wrap it to be delayed a bit, to ensure the folder actions
// are executed last of the queue
2013-04-13 12:30:07 +02:00
window . setTimeout ( function ( ) {
2014-08-15 13:22:43 +02:00
egw . jsonq ( 'mail.mail_ui.ajax_setFolderStatus' , [ _folders ] , function ( ) { self . unlock _tree ( ) ; } ) ;
2017-03-08 15:11:42 +01:00
} , 500 ) ;
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2014-02-11 16:20:44 +01:00
/ * *
* mail _CheckFolderNoSelect - implementation of the mail _CheckFolderNoSelect action to control right click options on the tree
*
2014-05-16 17:39:05 +02:00
* @ param { object } action
* @ param { object } _senders the representation of the tree leaf to be manipulated
* @ param { object } _currentNode
2014-02-11 16:20:44 +01:00
* /
mail _CheckFolderNoSelect : function ( action , _senders , _currentNode ) {
2014-05-20 17:39:20 +02:00
2014-02-11 16:20:44 +01:00
// Abort if user selected an un-selectable node
// Use image over anything else because...?
2014-02-12 14:10:04 +01:00
var ftree , node ;
ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
if ( ftree )
{
node = ftree . getNode ( _senders [ 0 ] . id ) ;
}
2014-02-11 17:01:31 +01:00
2014-02-12 14:10:04 +01:00
if ( node && node . im0 . indexOf ( 'NoSelect' ) !== - 1 )
2014-02-11 16:20:44 +01:00
{
//ftree.reSelectItem(_previous);
return false ;
}
2014-02-11 17:01:31 +01:00
2014-02-11 16:20:44 +01:00
return true ;
} ,
2015-02-19 13:01:18 +01:00
/ * *
* Check if SpamFolder is enabled on that account
*
* SpamFolder enabled is stored as data { spamfolder : true / false } on account node .
*
* @ param { object } _action
* @ param { object } _senders the representation of the tree leaf to be manipulated
* @ param { object } _currentNode
* /
spamfolder _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 . spamfolder ;
} ,
2016-04-29 13:23:05 +02:00
/ * *
* Check if archiveFolder is enabled on that account
*
* ArchiveFolder enabled is stored as data { archivefolder : true / false } on account node .
*
* @ param { object } _action
* @ param { object } _senders the representation of the tree leaf to be manipulated
* @ param { object } _currentNode
* /
archivefolder _enabled : function ( _action , _senders , _currentNode )
{
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
var acc _id = _senders [ 0 ] . id . split ( '::' ) [ 2 ] ; // this is operating on mails
var node = ftree ? ftree . getNode ( acc _id ) : null ;
return node && node . data && node . data . archivefolder ;
} ,
2014-05-22 09:36:02 +02:00
/ * *
* Check if Sieve is enabled on that account
*
2016-04-29 13:23:05 +02:00
* Sieve enabled is stored as data { sieve : true / false } on account node .
2014-05-22 09:36:02 +02:00
*
* @ 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 ;
2017-04-12 16:01:26 +02:00
return node && node . data && node . data . acl && this . mail _CheckFolderNoSelect ( _action , _senders , _currentNode ) ;
2014-05-22 09:36:02 +02:00
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _setFolderStatus , function to set the status for the visible folders
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { array } _status
2013-04-13 12:30:07 +02:00
* /
mail _setFolderStatus : function ( _status ) {
2014-07-17 16:39:56 +02:00
if ( ! this . et2 && ! this . checkET2 ( ) ) return ;
2013-10-18 11:58:25 +02:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2013-11-27 14:07:54 +01:00
for ( var i in _status ) {
ftree . setLabel ( i , _status [ i ] ) ;
2014-02-05 13:23:04 +01:00
// display folder-name bold for unseen mails
ftree . setStyle ( i , 'font-weight: ' + ( _status [ i ] . match ( this . _unseen _regexp ) ? 'bold' : 'normal' ) ) ;
2013-11-27 14:07:54 +01:00
//alert(i +'->'+_status[i]);
}
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-29 16:56:33 +02:00
/ * *
* mail _setLeaf , function to set the id and description for the folder given by status key
2014-05-16 17:39:05 +02:00
* @ param { array } _status status array with the required data ( new id , desc , old desc )
2013-05-07 10:26:17 +02:00
* key is the original id of the leaf to change
* multiple sets can be passed to mail _setLeaf
2013-04-29 16:56:33 +02:00
* /
mail _setLeaf : function ( _status ) {
2013-10-18 11:58:25 +02:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2013-05-07 10:26:17 +02:00
var selectedNode = ftree . getSelectedNode ( ) ;
2013-04-29 16:56:33 +02:00
for ( var i in _status )
{
2013-05-10 09:24:27 +02:00
// if olddesc is undefined or #skip# then skip the message, as we process subfolders
2021-04-21 09:39:10 +02:00
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' ] ) , 'success' ) ;
2013-04-29 16:56:33 +02:00
ftree . renameItem ( i , _status [ i ] [ 'id' ] , _status [ i ] [ 'desc' ] ) ;
2014-02-06 13:48:01 +01:00
ftree . setStyle ( i , 'font-weight: ' + ( _status [ i ] [ 'desc' ] . match ( this . _unseen _regexp ) ? 'bold' : 'normal' ) ) ;
2013-04-29 16:56:33 +02:00
//alert(i +'->'+_status[i]['id']+'+'+_status[i]['desc']);
2013-05-07 10:26:17 +02:00
if ( _status [ i ] [ 'id' ] == selectedNode . id )
{
2013-10-18 11:58:25 +02:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
2013-05-07 10:26:17 +02:00
nm . activeFilters [ "selectedFolder" ] = _status [ i ] [ 'id' ] ;
nm . applyFilters ( ) ;
}
2013-04-29 16:56:33 +02:00
}
} ,
2013-05-13 16:42:42 +02:00
/ * *
* mail _removeLeaf , function to remove the leaf represented by the given ID
2014-05-16 17:39:05 +02:00
* @ param { array } _status status array with the required data ( KEY id , VALUE desc )
2013-05-13 16:42:42 +02:00
* key is the id of the leaf to delete
* multiple sets can be passed to mail _deleteLeaf
* /
2013-05-21 10:46:54 +02:00
mail _removeLeaf : function ( _status ) {
2013-10-18 11:58:25 +02:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2013-05-13 16:42:42 +02:00
var selectedNode = ftree . getSelectedNode ( ) ;
for ( var i in _status )
{
// if olddesc is undefined or #skip# then skip the message, as we process subfolders
2021-04-21 09:39:10 +02:00
if ( typeof _status [ i ] !== 'undefined' && _status [ i ] !== '#skip-user-interaction-message#' ) this . egw . message ( this . egw . lang ( "Removed Folder %1 " , _status [ i ] ) , 'success' ) ;
2013-05-13 16:42:42 +02:00
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 )
{
2013-10-18 11:58:25 +02:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
2013-05-13 16:42:42 +02:00
nm . activeFilters [ "selectedFolder" ] = selectedNodeAfter . id ;
nm . applyFilters ( ) ;
}
}
} ,
2013-05-21 10:46:54 +02:00
/ * *
* mail _reloadNode , function to reload the leaf represented by the given ID
2014-01-11 12:58:31 +01:00
* @ param { Object . < string , string > | Object . < string , Object } } _status
* Object with the required data ( KEY id , VALUE desc ) , or ID => { new data }
2013-05-21 10:46:54 +02:00
* /
mail _reloadNode : function ( _status ) {
2014-07-18 19:22:28 +02:00
var ftree = this . et2 ? this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) : null ;
if ( ! ftree ) return ;
2013-05-21 10:46:54 +02:00
var selectedNode = ftree . getSelectedNode ( ) ;
for ( var i in _status )
{
// if olddesc is undefined or #skip# then skip the message, as we process subfolders
2014-01-11 12:58:31 +01:00
if ( typeof _status [ i ] !== 'undefined' && _status [ i ] !== '#skip-user-interaction-message#' )
2013-05-21 10:46:54 +02:00
{
2017-04-12 18:00:19 +02:00
this . egw . message ( this . egw . lang ( ( typeof _status [ i ] . parent !== 'undefined' ? "Reloaded Folder %1" : "Reloaded Account %1" ) ,
( typeof _status [ i ] == "string" ? _status [ i ] . replace ( this . _unseen _regexp , '' ) :
2021-04-21 09:39:10 +02:00
( _status [ i ] . text ? _status [ i ] . text . replace ( this . _unseen _regexp , '' ) : _status [ i ] . id ) ) ) , 'success' ) ;
2013-05-21 10:46:54 +02:00
}
2014-01-11 12:58:31 +01:00
ftree . refreshItem ( i , typeof _status [ i ] == "object" ? _status [ i ] : null ) ;
2014-02-06 13:48:01 +01:00
if ( typeof _status [ i ] == "string" ) ftree . setStyle ( i , 'font-weight: ' + ( _status [ i ] . match ( this . _unseen _regexp ) ? 'bold' : 'normal' ) ) ;
2014-01-11 12:58:31 +01:00
}
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 ( ) ;
2013-05-21 10:46:54 +02:00
}
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _refreshMessageGrid , function to call to reread ofthe current folder
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { boolean } _isPopup
2016-07-28 09:48:47 +02:00
* @ param { boolean } _refreshVacationNotice
2013-04-13 12:30:07 +02:00
* /
2016-04-12 14:53:50 +02:00
mail _refreshMessageGrid : function ( _isPopup , _refreshVacationNotice ) {
2013-10-05 11:03:51 +02:00
if ( typeof _isPopup == 'undefined' ) _isPopup = false ;
2016-04-12 14:53:50 +02:00
if ( typeof _refreshVacationNotice == 'undefined' ) _refreshVacationNotice = false ;
2013-10-05 11:03:51 +02:00
var nm ;
2013-10-14 15:30:04 +02:00
if ( _isPopup && ! this . mail _isMainWindow )
2013-10-05 11:03:51 +02:00
{
nm = window . opener . etemplate2 . getByApplication ( 'mail' ) [ 0 ] . widgetContainer . getWidgetById ( this . nm _index ) ;
}
else
{
2013-10-18 11:58:25 +02:00
nm = this . et2 . getWidgetById ( this . nm _index ) ;
2013-10-05 11:03:51 +02:00
}
2016-04-12 14:53:50 +02:00
var dates = this . et2 . getWidgetById ( 'mail.index.datefilter' ) ;
var filter = this . et2 . getWidgetById ( 'cat_id' ) ;
if ( nm && filter )
{
nm . activeFilters [ "startdate" ] = null ;
nm . activeFilters [ "enddate" ] = null ;
switch ( filter . getValue ( ) )
{
case 'bydate' :
if ( filter && dates )
{
2023-05-15 12:36:25 +02:00
if ( this . et2 . getWidgetById ( 'startdate' ) && this . et2 . getWidgetById ( 'startdate' ) . get _value ( ) ) nm . activeFilters [ "startdate" ] = this . et2 . getWidgetById ( 'startdate' ) . value ;
if ( this . et2 . getWidgetById ( 'enddate' ) && this . et2 . getWidgetById ( 'enddate' ) . get _value ( ) ) nm . activeFilters [ "enddate" ] = this . et2 . getWidgetById ( 'enddate' ) . value ;
2016-04-12 14:53:50 +02:00
}
}
}
2013-04-13 12:30:07 +02:00
nm . applyFilters ( ) ; // this should refresh the active folder
2016-04-12 14:53:50 +02:00
if ( _refreshVacationNotice ) this . mail _callRefreshVacationNotice ( ) ;
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _getMsg - gets the current Message
* @ return string
* /
mail _getMsg : function ( )
2013-02-13 15:02:02 +01:00
{
2013-10-18 11:58:25 +02:00
var msg _wdg = this . et2 . getWidgetById ( 'msg' ) ;
2013-04-13 12:30:07 +02:00
if ( msg _wdg )
{
return msg _wdg . valueOf ( ) . htmlNode [ 0 ] . innerHTML ;
}
return "" ;
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _setMsg - sets a Message , with the msg container , and controls if the container is enabled / disabled
2014-05-16 17:39:05 +02:00
* @ param { string } myMsg - the message
2013-04-13 12:30:07 +02:00
* /
mail _setMsg : function ( myMsg )
2013-02-13 15:02:02 +01:00
{
2013-10-18 11:58:25 +02:00
var msg _wdg = this . et2 . getWidgetById ( 'msg' ) ;
2013-04-13 12:30:07 +02:00
if ( msg _wdg )
{
msg _wdg . set _value ( myMsg ) ;
msg _wdg . set _disabled ( myMsg . trim ( ) . length == 0 ) ;
2013-02-28 10:28:08 +01:00
}
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* Delete mails
* takes in all arguments
* @ param _action
* @ param _elems
* /
mail _delete : function ( _action , _elems )
2014-06-26 17:05:04 +02:00
{
this . mail _checkAllSelected ( _action , _elems , null , true ) ;
} ,
/ * *
* call Delete mails
* takes in all arguments
2014-07-03 16:03:59 +02:00
* @ param { object } _action
* @ param { array } _elems
* @ param { boolean } _allMessagesChecked
2014-06-26 17:05:04 +02:00
* /
mail _callDelete : function ( _action , _elems , _allMessagesChecked )
2013-02-13 15:02:02 +01:00
{
2013-10-05 18:36:20 +02:00
var calledFromPopup = false ;
2014-06-26 17:05:04 +02:00
if ( typeof _allMessagesChecked == 'undefined' ) _allMessagesChecked = false ;
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 18:36:20 +02:00
{
calledFromPopup = true ;
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 18:36:20 +02:00
}
2013-04-13 12:30:07 +02:00
var msg = this . mail _getFormData ( _elems ) ;
2014-07-01 17:22:18 +02:00
msg [ 'all' ] = _allMessagesChecked ;
2014-06-26 17:05:04 +02:00
if ( msg [ 'all' ] == 'cancel' ) return false ;
2014-06-20 14:05:03 +02:00
if ( msg [ 'all' ] ) msg [ 'activeFilters' ] = this . mail _getActiveFilters ( _action ) ;
2013-04-13 12:30:07 +02:00
//alert(_action.id+','+ msg);
2013-10-05 18:36:20 +02:00
if ( ! calledFromPopup ) this . mail _setRowClass ( _elems , 'deleted' ) ;
this . mail _deleteMessages ( msg , 'no' , calledFromPopup ) ;
2016-03-03 15:10:08 +01:00
if ( calledFromPopup && this . mail _isMainWindow == false )
{
egw ( window ) . close ( ) ;
}
2016-03-29 17:49:33 +02:00
else if ( typeof this . et2 _view != 'undefined' && typeof this . et2 _view . close == 'function' )
2016-03-03 15:10:08 +01:00
{
2016-03-29 17:49:33 +02:00
this . et2 _view . close ( ) ;
2016-03-03 15:10:08 +01:00
}
2013-05-27 15:48:55 +02:00
} ,
2014-02-07 15:34:04 +01:00
/ * *
* function to find ( and reduce ) unseen count from folder - name
* /
mail _reduceCounterWithoutServerRoundtrip : function ( )
{
2014-03-03 14:10:27 +01:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2014-02-07 15:34:04 +01:00
var _foldernode = ftree . getSelectedNode ( ) ;
var counter = _foldernode . label . match ( this . _unseen _regexp ) ;
2014-02-11 13:18:03 +01:00
var icounter = 0 ;
if ( counter ) icounter = parseInt ( counter [ 0 ] . replace ( ' (' , '' ) . replace ( ')' , '' ) ) ;
2014-02-07 15:34:04 +01:00
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 ) ;
}
} ,
2014-02-05 13:23:04 +01:00
/ * *
* Regular expression to find ( and remove ) unseen count from folder - name
* /
2014-02-06 13:48:01 +01:00
_unseen _regexp : / \([0-9]+\)$/ ,
2014-02-05 13:23:04 +01:00
2014-02-12 11:56:44 +01:00
/ * *
* mail _splitRowId
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { string } _rowID
2014-05-20 17:39:20 +02:00
*
2014-02-12 11:56:44 +01:00
* /
mail _splitRowId : function ( _rowID )
{
2014-03-03 14:10:27 +01:00
var res = _rowID . split ( '::' ) ;
2014-02-12 11:56:44 +01:00
// as a rowID is perceeded by app::, should be mail!
2015-08-06 11:36:55 +02:00
if ( res . length == 4 && ! isNaN ( parseInt ( res [ 0 ] ) ) )
2014-02-12 11:56:44 +01:00
{
// we have an own created rowID; prepend app=mail
res . unshift ( 'mail' ) ;
}
return res ;
} ,
2013-05-27 15:48:55 +02:00
/ * *
* Delete mails - actually calls the backend function for deletion
* takes in all arguments
2014-05-16 17:39:05 +02:00
* @ param { string } _msg - message list
* @ param { object } _action - optional action
* @ param { object } _calledFromPopup
2013-05-27 15:48:55 +02:00
* /
2013-10-05 18:36:20 +02:00
mail _deleteMessages : function ( _msg , _action , _calledFromPopup )
2013-05-27 15:48:55 +02:00
{
2014-02-12 11:56:44 +01:00
var message , ftree , _foldernode , displayname ;
2014-02-04 12:31:13 +01:00
ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2014-02-12 11:56:44 +01:00
if ( ftree )
{
_foldernode = ftree . getSelectedNode ( ) ;
2014-02-04 12:31:13 +01:00
2014-02-12 11:56:44 +01:00
displayname = _foldernode . label . replace ( this . _unseen _regexp , '' ) ;
}
else
{
message = this . mail _splitRowId ( _msg [ 'msg' ] [ 0 ] ) ;
2021-07-01 10:14:26 +02:00
if ( message [ 3 ] ) _foldernode = displayname = atob ( message [ 3 ] ) ;
2014-02-12 11:56:44 +01:00
}
2014-07-02 09:48:24 +02:00
2014-01-17 19:00:36 +01:00
// Tell server
2021-11-22 19:56:42 +01:00
egw . json ( 'mail.mail_ui.ajax_deleteMessages' , [ _msg , ( typeof _action == 'undefined' ? 'no' : _action ) ] )
2014-01-17 19:00:36 +01:00
. sendRequest ( true ) ;
2014-11-20 16:05:25 +01:00
2014-06-26 17:05:04 +02:00
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');
2021-11-22 19:56:42 +01:00
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' ) ) ) , 'success' ) ;
2014-01-13 14:06:29 +01:00
} ,
/ * *
* 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 )
{
2014-02-12 11:56:44 +01:00
// Update list
2020-08-24 20:35:06 +02:00
2014-05-27 15:31:37 +02:00
//this.egw.message(_msg['egw_message']);
2014-06-20 14:05:03 +02:00
if ( _msg [ 'all' ] )
{
this . egw . refresh ( _msg [ 'egw_message' ] , 'mail' ) ;
}
else
{
2020-08-24 20:35:06 +02:00
for ( var i = 0 ; i < _msg [ 'msg' ] . length ; i ++ )
{
2021-11-22 19:56:42 +01:00
this . egw . refresh ( _msg [ 'egw_message' ] , 'mail' , _msg [ 'msg' ] [ i ] . replace ( /mail::/ , '' ) , 'delete' ) ;
2020-08-24 20:35:06 +02:00
}
2014-11-17 18:19:51 +01:00
// Nextmatch automatically selects the next row and calls preview.
// Unselect it and thanks to the timeout selectionMgr uses, preview
// will close when the selection callback fires.
this . et2 . getWidgetById ( this . nm _index ) . controller . _selectionMgr . resetSelection ( ) ;
2014-06-20 14:05:03 +02:00
}
2013-04-13 12:30:07 +02:00
} ,
2013-05-27 15:48:55 +02:00
/ * *
* retry to Delete mails
* @ param responseObject - >
* reason - reason to report
* messageList
* /
mail _retryForcedDelete : function ( responseObject )
{
var reason = responseObject [ 'response' ] ;
var messageList = responseObject [ 'messageList' ] ;
2014-03-03 14:10:27 +01:00
if ( confirm ( reason ) )
2013-05-27 15:48:55 +02:00
{
this . mail _deleteMessages ( messageList , 'remove_immediately' ) ;
}
else
{
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'canceled deletion due to user interaction' ) , 'success' ) ;
2013-05-27 15:48:55 +02:00
this . mail _removeRowClass ( messageList , 'deleted' ) ;
}
this . mail _refreshMessageGrid ( ) ;
this . mail _preview ( ) ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
* UnDelete mailMessages
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _messageList
* /
mail _undeleteMessages : function ( _messageList ) {
// setting class of row, the old style
} ,
2013-07-25 17:35:44 +02:00
2015-02-19 13:01:18 +01:00
/ * *
* mail _emptySpam
*
* @ param { object } action
* @ param { object } _senders
* /
mail _emptySpam : function ( action , _senders ) {
var server = _senders [ 0 ] . iface . id . split ( '::' ) ;
var activeFilters = this . mail _getActiveFilters ( ) ;
var self = this ;
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'empty junk' ) , 'success' ) ;
2015-02-19 13:01:18 +01:00
egw . json ( 'mail.mail_ui.ajax_emptySpam' , [ server [ 0 ] , activeFilters [ 'selectedFolder' ] ? activeFilters [ 'selectedFolder' ] : null ] , function ( ) { self . unlock _tree ( ) ; } )
. sendRequest ( true ) ;
// Directly delete any trash cache for selected server
if ( window . localStorage )
{
for ( var i = 0 ; i < window . localStorage . length ; i ++ )
{
var key = window . localStorage . key ( i ) ;
// Find directly by what the key would look like
if ( key . indexOf ( 'cached_fetch_mail::{"selectedFolder":"' + server [ 0 ] + '::' ) == 0 &&
key . toLowerCase ( ) . indexOf ( egw . lang ( 'junk' ) . toLowerCase ( ) ) > 0 )
{
window . localStorage . removeItem ( key ) ;
}
}
}
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _emptyTrash
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } action
2014-05-20 17:39:20 +02:00
* @ param { object } _senders
2013-04-13 12:30:07 +02:00
* /
2014-01-17 10:59:25 +01:00
mail _emptyTrash : function ( action , _senders ) {
var server = _senders [ 0 ] . iface . id . split ( '::' ) ;
2014-08-08 12:04:49 +02:00
var activeFilters = this . mail _getActiveFilters ( ) ;
2014-07-09 17:21:42 +02:00
var self = this ;
2014-08-13 13:45:55 +02:00
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'empty trash' ) , 'success' ) ;
2014-08-15 13:22:43 +02:00
egw . json ( 'mail.mail_ui.ajax_emptyTrash' , [ server [ 0 ] , activeFilters [ 'selectedFolder' ] ? activeFilters [ 'selectedFolder' ] : null ] , function ( ) { self . unlock _tree ( ) ; } )
2014-07-15 11:37:08 +02:00
. sendRequest ( true ) ;
2014-08-12 21:06:58 +02:00
// Directly delete any trash cache for selected server
if ( window . localStorage )
{
for ( var i = 0 ; i < window . localStorage . length ; i ++ )
{
var key = window . localStorage . key ( i ) ;
// Find directly by what the key would look like
if ( key . indexOf ( 'cached_fetch_mail::{"selectedFolder":"' + server [ 0 ] + '::' ) == 0 &&
key . toLowerCase ( ) . indexOf ( egw . lang ( 'trash' ) . toLowerCase ( ) ) > 0 )
{
window . localStorage . removeItem ( key ) ;
}
}
}
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _compressFolder
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } action
* @ param { object } _senders
2014-05-20 17:39:20 +02:00
*
2013-04-13 12:30:07 +02:00
* /
2014-01-17 10:59:25 +01:00
mail _compressFolder : function ( action , _senders ) {
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'compress folder' ) , 'success' ) ;
2014-01-21 15:46:00 +01:00
egw . jsonq ( 'mail.mail_ui.ajax_compressFolder' , [ _senders [ 0 ] . iface . id ] ) ;
// .sendRequest(true);
2014-05-27 15:31:37 +02:00
// since the json reply is using this.egw.refresh, we should not need to call refreshFolderStatus
2014-01-17 10:59:25 +01:00
// as the actions thereof are now bound to run after grid refresh
2014-02-11 16:20:44 +01:00
//this.mail_refreshFolderStatus();
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _changeProfile
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { string } folder the ID of the selected Node - > should be an integer
* @ param { object } _widget handle to the tree widget
2014-01-22 10:32:18 +01:00
* @ param { boolean } getFolders Flag to indicate that the profile needs the mail
2014-05-16 17:39:05 +02:00
* folders . False means they 're already loaded in the tree, and we don' t need
* them again
2013-04-13 12:30:07 +02:00
* /
2014-01-22 10:32:18 +01:00
mail _changeProfile : function ( folder , _widget , getFolders ) {
if ( typeof getFolders == 'undefined' )
{
getFolders = true ;
}
2013-04-13 12:30:07 +02:00
// alert(folder);
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'Connect to Profile %1' , _widget . getSelectedLabel ( ) . replace ( this . _unseen _regexp , '' ) ) , 'success' ) ;
2015-08-20 09:02:06 +02:00
2015-08-05 12:48:34 +02:00
//Open unloaded tree to get loaded
_widget . openItem ( folder , true ) ;
2015-08-20 09:02:06 +02:00
2014-01-22 10:32:18 +01:00
this . lock _tree ( ) ;
2014-08-20 16:58:12 +02:00
egw . json ( 'mail_ui::ajax_changeProfile' , [ folder , getFolders , this . et2 . _inst . etemplate _exec _id ] , jQuery . proxy ( function ( ) {
2014-01-22 10:32:18 +01:00
// Profile changed, select inbox
var inbox = folder + '::INBOX' ;
2014-05-16 17:39:05 +02:00
_widget . reSelectItem ( inbox ) ;
2014-01-22 10:32:18 +01:00
this . mail _changeFolder ( inbox , _widget , '' ) ;
this . unlock _tree ( ) ;
} , this ) )
. sendRequest ( true ) ;
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
return true ;
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _changeFolder
2014-05-16 17:39:05 +02:00
* @ param { string } _folder the ID of the selected Node
* @ param { widget object } _widget handle to the tree widget
2014-01-21 19:56:03 +01:00
* @ param { string } _previous - Previously selected node ID
2013-04-13 12:30:07 +02:00
* /
2014-01-21 19:56:03 +01:00
mail _changeFolder : function ( _folder , _widget , _previous ) {
2014-05-23 11:21:59 +02:00
2014-05-22 16:46:50 +02:00
// to reset iframes to the normal status
this . loadIframe ( ) ;
2018-07-11 14:39:28 +02:00
2018-07-05 16:34:30 +02:00
// reset nm action selection, seems actions system accumulate selected items
// and that leads to corruption for selected all actions
this . et2 . getWidgetById ( this . nm _index ) . controller . _selectionMgr . resetSelection ( ) ;
2014-05-23 11:21:59 +02:00
2014-01-21 19:56:03 +01:00
// 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 )
2013-02-20 12:31:57 +01:00
{
2014-01-21 19:56:03 +01:00
_widget . reSelectItem ( _previous ) ;
return ;
2013-02-20 12:31:57 +01:00
}
2014-01-21 19:56:03 +01:00
// 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
2014-01-22 10:32:18 +01:00
return this . mail _changeProfile ( _folder , _widget , _widget . getSelectedNode ( ) . childsCount == 0 ) ;
2014-01-21 19:56:03 +01:00
}
// Apply new selected folder to list, which updates data
2013-08-21 12:47:20 +02:00
var nm = _widget . getRoot ( ) . getWidgetById ( this . nm _index ) ;
2013-12-10 19:13:28 +01:00
if ( nm )
2013-02-13 15:02:02 +01:00
{
2014-01-21 12:28:43 +01:00
this . lock _tree ( ) ;
2014-01-21 19:56:03 +01:00
nm . applyFilters ( { 'selectedFolder' : _folder } ) ;
2013-12-10 19:13:28 +01:00
}
2014-01-21 19:56:03 +01:00
// Get nice folder name for message, if selected is not a profile
if ( ! profile _selected )
2014-02-05 13:23:04 +01:00
{
2014-02-06 13:48:01 +01:00
var displayname = _widget . getSelectedLabel ( ) ;
var myMsg = ( displayname ? displayname : _folder ) . replace ( this . _unseen _regexp , '' ) + ' ' + this . egw . lang ( 'selected' ) ;
2021-04-21 09:39:10 +02:00
this . egw . message ( myMsg , 'success' ) ;
2013-02-13 15:02:02 +01:00
}
2013-12-17 16:21:36 +01:00
2014-01-21 19:56:03 +01:00
// Update non-grid
this . mail _refreshFolderStatus ( _folder , 'forced' , false , false ) ;
2013-10-18 11:58:25 +02:00
this . mail _refreshQuotaDisplay ( server [ 0 ] ) ;
2013-05-21 10:46:54 +02:00
this . mail _preview ( ) ;
2017-08-17 17:28:36 +02:00
this . mail _callRefreshVacationNotice ( server [ 0 ] ) ;
2014-04-11 15:52:58 +02:00
if ( server [ 0 ] != previousServer [ 0 ] )
{
egw . jsonq ( 'mail.mail_ui.ajax_refreshFilters' , [ server [ 0 ] ] ) ;
}
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2014-05-27 14:05:23 +02:00
/ * *
* mail _checkAllSelected
*
* @ param _action
2014-06-26 17:05:04 +02:00
* @ param _elems
* @ param _target
* @ param _confirm
2014-05-27 14:05:23 +02:00
* /
2014-06-26 17:05:04 +02:00
mail _checkAllSelected : function ( _action , _elems , _target , _confirm )
2014-05-27 14:05:23 +02:00
{
2014-06-26 17:05:04 +02:00
if ( typeof _confirm == 'undefined' ) _confirm = false ;
2014-07-02 09:48:24 +02:00
// 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"
2014-07-08 11:30:24 +02:00
var obj _manager = egw _getObjectManager ( this . appname ) . getObjectById ( this . nm _index ) ;
2021-09-24 10:23:51 +02:00
let tree = this . et2 . getWidgetById ( 'nm[foldertree]' ) ;
2014-06-26 17:05:04 +02:00
var that = this ;
var rvMain = false ;
2014-11-19 21:13:46 +01:00
if ( ( obj _manager && _elems . length > 1 && obj _manager . getAllSelected ( ) && ! _action . paste ) || _action . id == 'readall' )
2014-05-27 14:05:23 +02:00
{
2021-09-27 10:50:44 +02:00
try {
2021-09-27 11:22:49 +02:00
let splitedID = [ ] ;
let mailbox = '' ;
2021-09-27 10:50:44 +02:00
// Avoid possibly doing select all action on not desired mailbox e.g. INBOX
for ( let n = 0 ; n < _elems . length ; n ++ )
{
2021-09-27 11:22:49 +02:00
splitedID = _elems [ n ] . id . split ( "::" ) ;
// find the mailbox from the constructed rowID, sometimes the rowID may not contain the app name
mailbox = splitedID . length == 4 ? atob ( splitedID [ 2 ] ) : atob ( splitedID [ 3 ] ) ;
2021-09-27 10:50:44 +02:00
// drop the action if there's a mixedup mailbox found in the selected messages
2021-09-27 11:22:49 +02:00
if ( mailbox != tree . getSelectedNode ( ) . id . split ( "::" ) [ 1 ] ) return ;
2021-09-27 10:50:44 +02:00
}
} catch ( e )
2021-09-24 10:23:51 +02:00
{
2021-09-27 10:50:44 +02:00
// continue
2021-09-24 10:23:51 +02:00
}
2021-09-27 10:50:44 +02:00
2014-05-27 14:05:23 +02:00
if ( _confirm )
{
2014-06-26 17:05:04 +02:00
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Yes" ) , id : "all" , "class" : "ui-priority-primary" , "default" : true , image : 'check' } ,
{ label : this . egw . lang ( "Cancel" ) , id : "cancel" }
2014-05-27 14:05:23 +02:00
] ;
2014-07-15 13:17:03 +02:00
var messageToDisplay = '' ;
2016-01-21 16:07:34 +01:00
var actionlabel = _action . id ;
2014-06-26 17:05:04 +02:00
switch ( _action . id )
{
2014-08-14 17:38:32 +02:00
case "readall" :
messageToDisplay = this . egw . lang ( "Do you really want to mark ALL messages as read in the current folder?" ) + " " ;
break ;
2014-06-26 17:05:04 +02:00
case "unlabel" :
2016-01-21 16:07:34 +01:00
messageToDisplay = this . egw . lang ( "Do you really want to remove ALL labels from ALL messages in the current folder?" ) + " " ;
break ;
2014-06-26 17:05:04 +02:00
case "label1" :
2016-01-21 16:07:34 +01:00
if ( _action . id == "label1" ) actionlabel = "important" ;
2014-06-26 17:05:04 +02:00
case "label2" :
2016-01-21 16:07:34 +01:00
if ( _action . id == "label2" ) actionlabel = "job" ;
2014-06-26 17:05:04 +02:00
case "label3" :
2016-01-21 16:07:34 +01:00
if ( _action . id == "label3" ) actionlabel = "personal" ;
2014-06-26 17:05:04 +02:00
case "label4" :
2016-01-21 16:07:34 +01:00
if ( _action . id == "label4" ) actionlabel = "to do" ;
2014-06-26 17:05:04 +02:00
case "label5" :
2016-01-21 16:07:34 +01:00
if ( _action . id == "label5" ) actionlabel = "later" ;
2014-06-26 17:05:04 +02:00
case "flagged" :
case "read" :
case "undelete" :
2016-01-21 16:07:34 +01:00
messageToDisplay = this . egw . lang ( "Do you really want to toggle flag %1 for ALL messages in the current view?" , this . egw . lang ( actionlabel ) ) + " " ;
if ( _action . id . substr ( 0 , 5 ) == 'label' ) messageToDisplay = this . egw . lang ( "Do you really want to toggle label %1 for ALL messages in the current view?" , this . egw . lang ( actionlabel ) ) + " " ;
2014-06-26 17:05:04 +02:00
break ;
2014-07-15 13:17:03 +02:00
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' ;
}
2014-07-15 13:35:47 +02:00
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 ) ) + " " ;
2014-06-26 17:05:04 +02:00
}
2022-07-20 22:23:55 +02:00
return Et2Dialog . show _dialog ( function ( _button _id )
2014-05-27 14:05:23 +02:00
{
2022-07-20 22:23:55 +02:00
var rv = false ;
switch ( _button _id )
{
case "all" :
rv = true ;
break ;
case "cancel" :
rv = 'cancel' ;
}
if ( rv != "cancel" )
{
that . lock _tree ( ) ;
}
switch ( _action . id )
2014-06-26 17:05:04 +02:00
{
case "delete" :
that . mail _callDelete ( _action , _elems , rv ) ;
break ;
2014-08-14 17:38:32 +02:00
case "readall" :
2014-06-26 17:05:04 +02:00
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 :
2014-07-01 11:23:29 +02:00
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 ) ;
2014-05-27 14:05:23 +02:00
}
} ,
2014-06-26 17:05:04 +02:00
messageToDisplay ,
2014-05-27 14:05:23 +02:00
this . egw . lang ( "Confirm" ) ,
2022-09-09 09:36:37 +02:00
null , buttons ) ;
2014-05-27 14:05:23 +02:00
}
else
{
2014-06-26 17:05:04 +02:00
rvMain = true ;
2014-05-27 14:05:23 +02:00
}
}
2014-06-26 17:05:04 +02:00
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 :
2014-07-01 14:09:10 +02:00
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 ) ;
2014-06-26 17:05:04 +02:00
}
2014-05-27 14:05:23 +02:00
} ,
2014-06-26 17:05:04 +02:00
/ * *
* mail _doActionCall
*
* @ param _action
* @ param _elems
* /
mail _doActionCall : function ( _action , _elems )
{
} ,
2014-07-08 11:22:21 +02:00
2014-05-27 14:05:23 +02:00
/ * *
* mail _getActiveFilters
*
* @ param _action
* @ return mixed boolean / activeFilters object
* /
mail _getActiveFilters : function ( _action )
{
2014-07-08 11:22:21 +02:00
// 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"
2014-07-08 11:30:24 +02:00
var obj _manager = egw _getObjectManager ( this . appname ) . getObjectById ( this . nm _index ) ;
2014-05-27 14:05:23 +02:00
if ( obj _manager && obj _manager . manager && obj _manager . manager . data && obj _manager . manager . data . nextmatch && obj _manager . manager . data . nextmatch . activeFilters )
{
2016-04-12 15:37:38 +02:00
var af = obj _manager . manager . data . nextmatch . activeFilters ;
// merge startdate and enddate into the active filters (if set)
if ( this . et2 . getWidgetById ( 'startdate' ) && this . et2 . getWidgetById ( 'startdate' ) . get _value ( ) ) af [ "startdate" ] = this . et2 . getWidgetById ( 'startdate' ) . date ;
if ( this . et2 . getWidgetById ( 'enddate' ) && this . et2 . getWidgetById ( 'enddate' ) . get _value ( ) ) af [ "enddate" ] = this . et2 . getWidgetById ( 'enddate' ) . date ;
return af ;
2014-05-27 14:05:23 +02:00
}
return false ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
* Flag mail as 'read' , 'unread' , 'flagged' or 'unflagged'
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action _action . id is 'read' , 'unread' , 'flagged' or 'unflagged'
* @ param _elems
* /
mail _flag : function ( _action , _elems )
2014-06-26 17:05:04 +02:00
{
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 )
2013-02-13 15:02:02 +01:00
{
2015-09-21 16:04:48 +02:00
/ * *
* vars
* /
var folder = '' ,
tree = { } ,
formData = { } ,
data = {
msg : [ this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) ] || '' ,
all : _allMessagesChecked || false ,
2016-03-29 17:49:33 +02:00
popup : typeof this . et2 _view != 'undefined' || egw ( window ) . is _popup ( ) || false ,
2015-09-21 16:04:48 +02:00
activeFilters : _action . id == 'readall' ? false : this . mail _getActiveFilters ( _action )
} ,
rowClass = _action . id ;
2015-10-27 12:44:54 +01:00
2015-09-21 16:04:48 +02:00
if ( typeof _elems === 'undefined' || _elems . length == 0 )
{
if ( this . mail _isMainWindow && this . mail _currentlyFocussed )
2013-10-05 11:03:51 +02:00
{
2015-09-21 16:04:48 +02:00
data . msg = [ this . mail _currentlyFocussed ] ;
_elems = data ;
data . msg = this . mail _getFormData ( _elems ) . msg ;
2013-10-14 15:30:04 +02:00
}
2013-10-05 11:03:51 +02:00
}
2015-09-21 16:04:48 +02:00
else // action called by contextmenu
{
data . msg = this . mail _getFormData ( _elems ) . msg ;
}
switch ( _action . id )
{
case 'read' :
rowClass = 'seen' ;
if ( data . popup )
2013-12-06 11:35:39 +01:00
{
2016-03-29 17:49:33 +02:00
var et _2 = typeof this . et2 _view != 'undefined' ? etemplate2 : opener . etemplate2 ;
2016-03-03 15:10:08 +01:00
tree = et _2 . getByApplication ( 'mail' ) [ 0 ] . widgetContainer . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2013-12-06 11:35:39 +01:00
}
else
{
2015-09-21 16:04:48 +02:00
tree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2013-12-06 11:35:39 +01:00
}
2015-09-21 16:04:48 +02:00
folder = tree . getSelectedNode ( ) . id ;
break ;
case 'readall' :
rowClass = 'seen' ;
break ;
case 'label1' :
2020-08-05 15:38:14 +02:00
rowClass = 'label1' ;
2015-09-21 16:04:48 +02:00
break ;
case 'label2' :
2020-08-05 15:38:14 +02:00
rowClass = 'label2' ;
2015-09-21 16:04:48 +02:00
break ;
case 'label3' :
2020-08-05 15:38:14 +02:00
rowClass = 'label3' ;
2015-09-21 16:04:48 +02:00
break ;
case 'label4' :
2020-08-05 15:38:14 +02:00
rowClass = 'label4' ;
2015-09-21 16:04:48 +02:00
break ;
case 'label5' :
2020-08-05 15:38:14 +02:00
rowClass = 'label5' ;
2015-09-21 16:04:48 +02:00
break ;
default :
2015-10-27 12:44:54 +01:00
break ;
2015-09-21 16:04:48 +02:00
}
jQuery ( data ) . extend ( { } , data , formData ) ;
if ( data [ 'all' ] == 'cancel' ) return false ;
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
2014-08-14 17:38:32 +02:00
{
2020-08-05 15:38:14 +02:00
var labels = [ 'label1' , 'label2' , 'label3' , 'label4' , 'label5' ] ;
2015-09-21 16:04:48 +02:00
for ( var i = 0 ; i < labels . length ; i ++ ) this . mail _removeRowClass ( _elems , labels [ i ] ) ;
this . mail _flagMessages ( _action . id , data ) ;
2014-08-14 17:38:32 +02:00
}
2013-10-05 11:03:51 +02:00
else
{
2015-09-21 16:04:48 +02:00
this . mail _removeRowClass ( _elems , _action . id . substring ( 2 ) ) ;
this . mail _setRowClass ( _elems , _action . id ) ;
this . mail _flagMessages ( _action . id , data ) ;
}
}
else if ( _action . id == 'readall' )
{
this . mail _flagMessages ( 'read' , data ) ;
}
else
{
var msg _set = { msg : [ ] } ;
var msg _unset = { msg : [ ] } ;
var dataElem ;
var flags ;
var classes = '' ;
for ( var i = 0 ; i < data . msg . length ; i ++ )
{
dataElem = egw . dataGetUIDdata ( data . msg [ i ] ) ;
if ( typeof dataElem . data . flags == 'undefined' )
2013-12-06 11:35:39 +01:00
{
2015-09-21 16:04:48 +02:00
dataElem . data . flags = { } ;
2013-12-06 11:35:39 +01:00
}
2015-09-21 16:04:48 +02:00
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 ( rowClass ) >= 0 )
2013-12-06 11:35:39 +01:00
{
2015-09-21 16:04:48 +02:00
classes . splice ( classes . indexOf ( rowClass ) , 1 ) ;
2013-12-06 11:35:39 +01:00
}
2015-09-21 16:04:48 +02:00
if ( classes . indexOf ( 'un' + rowClass ) >= 0 )
2013-12-06 11:35:39 +01:00
{
2015-09-21 16:04:48 +02:00
classes . splice ( classes . indexOf ( 'un' + rowClass ) , 1 ) ;
2013-12-06 11:35:39 +01:00
}
2015-09-21 16:04:48 +02:00
if ( flags [ _action . id ] )
{
msg _unset [ 'msg' ] . push ( data . msg [ i ] ) ;
classes . push ( 'un' + rowClass ) ;
delete flags [ _action . id ] ;
}
else
{
msg _set [ 'msg' ] . push ( data . msg [ i ] ) ;
flags [ _action . id ] = _action . id ;
classes . push ( rowClass ) ;
}
// Update cache & call callbacks - updates list
dataElem . data [ 'class' ] = classes . join ( ' ' ) ;
egw . dataStoreUID ( data . msg [ i ] , dataElem . data ) ;
//Refresh the nm rows after we told dataComponent about all changes, since the dataComponent doesn't talk to nm, we need to do it manually
this . updateFilter _data ( data . msg [ i ] , _action . id , data . activeFilters ) ;
2013-10-05 11:03:51 +02:00
}
2015-09-21 16:04:48 +02:00
// Notify server of changes
if ( msg _unset [ 'msg' ] && msg _unset [ 'msg' ] . length )
{
if ( ! data [ 'all' ] ) this . mail _flagMessages ( 'un' + _action . id , msg _unset ) ;
}
if ( msg _set [ 'msg' ] && msg _set [ 'msg' ] . length )
{
if ( ! data [ 'all' ] ) this . mail _flagMessages ( _action . id , msg _set ) ;
}
//server must do the toggle, as we apply to ALL, not only the visible
if ( data [ 'all' ] ) this . mail _flagMessages ( _action . id , data ) ;
// 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 ;
2013-10-04 11:33:44 +02:00
}
2013-04-13 12:30:07 +02:00
} ,
2014-09-03 12:34:14 +02:00
2014-09-03 11:58:21 +02:00
/ * *
* Update changes on filtered mail rows in nm , triggers manual refresh
2014-09-03 12:34:14 +02:00
*
* @ param { type } _uid mail uid
2014-09-03 11:58:21 +02:00
* @ param { type } _actionId action id sended by nm action
* @ param { type } _filters activefilters
* /
updateFilter _data : function ( _uid , _actionId , _filters )
{
var uid = _uid . replace ( 'mail::' , '' ) ;
var action = '' ;
switch ( _actionId )
{
case 'flagged' :
action = 'flagged' ;
break ;
case 'read' :
if ( _filters . filter == 'seen' )
{
action = 'seen' ;
}
else if ( _filters . filter == 'unseen' )
{
action = 'unseen' ;
}
break ;
case 'label1' :
action = 'keyword1' ;
break ;
2014-09-03 12:34:14 +02:00
case 'label2' :
2014-09-03 11:58:21 +02:00
action = 'keyword2' ;
break ;
2014-09-03 12:34:14 +02:00
case 'label3' :
2014-09-03 11:58:21 +02:00
action = 'keyword3' ;
break ;
2014-09-03 12:34:14 +02:00
case 'label4' :
2014-09-03 11:58:21 +02:00
action = 'keyword4' ;
break ;
2014-09-03 12:34:14 +02:00
case 'label4' :
2014-09-03 11:58:21 +02:00
action = 'keyword4' ;
break ;
}
if ( action == _filters . filter )
{
egw . refresh ( '' , 'mail' , uid , 'delete' ) ;
}
} ,
2014-09-03 12:34:14 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* Flag mail as 'read' , 'unread' , 'flagged' or 'unflagged'
2013-07-25 17:35:44 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _flag
* @ param { object } _elems
* @ param { boolean } _isPopup
2013-04-13 12:30:07 +02:00
* /
2014-01-13 15:22:58 +01:00
mail _flagMessages : function ( _flag , _elems , _isPopup )
2013-02-19 17:30:59 +01:00
{
2014-01-21 15:46:00 +01:00
egw . jsonq ( 'mail.mail_ui.ajax_flagMessages' , [ _flag , _elems ] ) ;
// .sendRequest(true);
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* display header lines , or source of mail , depending on the url given
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _url
* /
mail _displayHeaderLines : function ( _url ) {
// only used by right clickaction
2020-03-23 16:57:06 +01:00
egw . openPopup ( _url , '870' , '600' , null , 'mail' ) ;
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* View header of a message
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
mail _header : function ( _action , _elems )
{
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 11:03:51 +02:00
{
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2013-04-13 12:30:07 +02:00
//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 ) ;
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* View message source
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
mail _mailsource : function ( _action , _elems )
{
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 11:03:51 +02:00
{
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2013-04-13 12:30:07 +02:00
//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 ) ;
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* Save a message
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
mail _save : function ( _action , _elems )
{
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 11:03:51 +02:00
{
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2017-05-09 15:09:00 +02:00
for ( var i in _elems )
{
//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 [ i ] . id ;
var a = document . createElement ( 'a' ) ;
a = jQuery ( a )
. prop ( 'href' , url )
. prop ( 'download' , "" )
. appendTo ( this . et2 . getDOMNode ( ) ) ;
var evt = document . createEvent ( 'MouseEvent' ) ;
evt . initMouseEvent ( 'click' , true , true , window , 1 , 0 , 0 , 0 , 0 , false , false , false , false , 0 , null ) ;
a [ 0 ] . dispatchEvent ( evt ) ;
a . remove ( ) ;
}
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-07-19 17:13:01 +02:00
/ * *
* User clicked an address ( FROM , TO , etc )
2013-10-16 13:22:53 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } tag _info with values for attributes id , label , title , ...
* @ param { widget object } widget
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ todo seems this function is not implemented , need to be checked if it is neccessary at all
2013-07-19 17:13:01 +02:00
* /
2013-10-09 19:29:36 +02:00
address _click : function ( tag _info , widget )
2013-07-19 17:13:01 +02:00
{
2014-05-20 17:39:20 +02:00
2013-07-19 17:13:01 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-10-16 13:25:46 +02:00
/ * *
2014-01-30 10:35:56 +01:00
* displayAttachment
2014-05-20 17:39:20 +02:00
*
* @ param { object } tag _info
2014-05-16 17:39:05 +02:00
* @ param { widget object } widget
* @ param { object } calledForCompose
2013-10-16 13:25:46 +02:00
* /
2014-01-30 10:35:56 +01:00
displayAttachment : function ( tag _info , widget , calledForCompose )
2013-10-16 13:25:46 +02:00
{
2013-10-21 15:07:32 +02:00
var mailid ;
var attgrid ;
2014-02-11 11:01:48 +01:00
if ( typeof calledForCompose == 'undefined' || typeof calledForCompose == 'object' ) calledForCompose = false ;
if ( calledForCompose === false )
2013-10-21 15:07:32 +02:00
{
2014-01-30 10:35:56 +01:00
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\]/ , '' ) ] ;
}
2013-10-21 15:07:32 +02:00
}
2014-02-11 11:01:48 +01:00
if ( calledForCompose === true )
2013-10-21 15:07:32 +02:00
{
2014-01-31 11:21:58 +01:00
// CALLED FOR COMPOSE; processedmail_id could hold several IDs seperated by comma
2014-01-30 10:35:56 +01:00
attgrid = this . et2 . getArrayMgr ( "content" ) . getEntry ( 'attachments' ) [ widget . id . replace ( /\[name\]/ , '' ) ] ;
2014-01-31 11:21:58 +01:00
var mailids = this . et2 . getArrayMgr ( "content" ) . getEntry ( 'processedmail_id' ) ;
var mailida = mailids . split ( ',' ) ;
2015-02-12 16:19:24 +01:00
// either several attachments of one email, or multiple emlfiles
mailid = mailida . length == 1 ? mailida [ 0 ] : mailida [ widget . id . replace ( /\[name\]/ , '' ) ] ;
2014-01-31 11:21:58 +01:00
if ( typeof attgrid . uid != 'undefined' && attgrid . uid && mailid . indexOf ( attgrid . uid ) == - 1 )
{
2014-03-03 14:10:27 +01:00
for ( var i = 0 ; i < mailida . length ; i ++ )
2014-01-31 11:21:58 +01:00
{
if ( mailida [ i ] . indexOf ( '::' + attgrid . uid ) > - 1 ) mailid = mailida [ i ] ;
}
}
2013-10-21 15:07:32 +02:00
}
2013-10-16 13:25:46 +02:00
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
2014-07-11 15:49:27 +02:00
url += '&mode=display' ; //message/rfc822 attachments should be opened in display mode
2013-10-16 13:25:46 +02:00
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' ) ;
2014-02-10 11:25:09 +01:00
if ( typeof reg2 [ 'view' ] != 'undefined' && typeof reg2 [ 'view_popup' ] != 'undefined' )
2013-10-16 13:25:46 +02:00
{
2014-02-10 11:25:09 +01:00
reg = reg2 [ 'view_popup' ] ;
2013-10-16 13:25:46 +02:00
}
}
if ( attgrid . type . toUpperCase ( ) == 'TEXT/X-VCARD' || attgrid . type . toUpperCase ( ) == 'TEXT/VCARD' )
{
windowName = 'maildisplayContact_' + mailid + '_' + attgrid . partID ;
reg2 = egw . link _get _registry ( 'addressbook' ) ;
2014-02-10 11:25:09 +01:00
if ( typeof reg2 [ 'add' ] != 'undefined' && typeof reg2 [ 'add_popup' ] != 'undefined' )
2013-10-16 13:25:46 +02:00
{
2014-02-10 11:25:09 +01:00
reg = reg2 [ 'add_popup' ] ;
2013-10-16 13:25:46 +02:00
}
}
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 ;
2014-10-08 22:02:59 +02:00
break ;
2013-10-16 13:25:46 +02:00
}
egw _openWindowCentered ( url , windowName , width , height ) ;
} ,
2014-01-30 10:35:56 +01:00
/ * *
* displayUploadedFile
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } tag _info
* @ param { widget object } widget
2014-01-30 10:35:56 +01:00
* /
displayUploadedFile : function ( tag _info , widget )
{
var attgrid ;
attgrid = this . et2 . getArrayMgr ( "content" ) . getEntry ( 'attachments' ) [ widget . id . replace ( /\[name\]/ , '' ) ] ;
2014-06-23 18:31:43 +02:00
2014-01-31 11:21:58 +01:00
if ( attgrid . uid && ( attgrid . partID || attgrid . folder ) )
2014-01-30 10:35:56 +01:00
{
this . displayAttachment ( tag _info , widget , true ) ;
return ;
}
2015-02-14 21:10:26 +01:00
var get _param = {
menuaction : 'mail.mail_compose.getAttachment' , // todo compose for Draft folder
tmpname : attgrid . tmp _name ,
etemplate _exec _id : this . et2 . _inst . etemplate _exec _id
} ;
2014-01-30 10:35:56 +01:00
var width ;
var height ;
2015-02-14 21:10:26 +01:00
var windowName = 'maildisplayAttachment_' + attgrid . file . replace ( /\//g , "_" ) ;
2014-01-30 10:35:56 +01:00
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' :
case 'TEXT/X-VCARD' :
case 'TEXT/VCARD' :
case 'TEXT/CALENDAR' :
case 'TEXT/X-VCALENDAR' :
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' ) ;
2014-02-10 11:25:09 +01:00
if ( typeof reg2 [ 'view' ] != 'undefined' && typeof reg2 [ 'view_popup' ] != 'undefined' )
2014-01-30 10:35:56 +01:00
{
2014-02-10 11:25:09 +01:00
reg = reg2 [ 'view_popup' ] ;
2014-01-30 10:35:56 +01:00
}
}
if ( attgrid . type . toUpperCase ( ) == 'TEXT/X-VCARD' || attgrid . type . toUpperCase ( ) == 'TEXT/VCARD' )
{
windowName = 'maildisplayContact_' + attgrid . file . replace ( /\//g , "_" ) ;
reg2 = egw . link _get _registry ( 'addressbook' ) ;
2014-02-10 11:25:09 +01:00
if ( typeof reg2 [ 'add' ] != 'undefined' && typeof reg2 [ 'add_popup' ] != 'undefined' )
2014-01-30 10:35:56 +01:00
{
2014-02-10 11:25:09 +01:00
reg = reg2 [ 'add_popup' ] ;
2014-01-30 10:35:56 +01:00
}
}
var w _h = reg . split ( 'x' ) ;
width = w _h [ 0 ] ;
height = w _h [ 1 ] ;
break ;
case 'MESSAGE/RFC822' :
default :
2015-02-14 21:10:26 +01:00
get _param . mode = 'save' ;
2014-01-30 10:35:56 +01:00
width = 870 ;
height = 600 ;
2014-10-08 22:02:59 +02:00
break ;
2014-01-30 10:35:56 +01:00
}
2015-02-14 21:10:26 +01:00
egw . openPopup ( egw . link ( '/index.php' , get _param ) , width , height , windowName ) ;
2014-01-30 10:35:56 +01:00
} ,
2017-11-08 19:07:04 +01:00
/ * *
* Callback function to handle vfsSave response messages
*
* @ param { type } _data
* /
vfsSaveCallback : function ( _data )
2013-10-16 13:25:46 +02:00
{
2017-11-08 19:07:04 +01:00
egw . message ( _data . msg , _data . success ? "success" : "error" ) ;
2013-10-16 13:25:46 +02:00
} ,
2017-11-08 19:07:04 +01:00
/ * *
* A handler for saving to VFS / downloading attachments
*
* @ param { type } widget
* @ param { type } action
* @ param { type } row _id
* /
saveAttachmentHandler : function ( widget , action , row _id )
2014-07-08 14:01:29 +02:00
{
2017-11-08 19:07:04 +01:00
var mail _id , attachments ;
2014-07-08 14:01:29 +02:00
2013-10-21 15:07:32 +02:00
if ( this . mail _isMainWindow )
{
2017-11-08 19:07:04 +01:00
mail _id = this . mail _currentlyFocussed ;
2013-10-21 15:07:32 +02:00
var p = widget . getParent ( ) ;
2017-11-08 19:07:04 +01:00
attachments = p . getArrayMgr ( "content" ) . data ;
2013-10-21 15:07:32 +02:00
}
else
{
2017-11-08 19:07:04 +01:00
mail _id = this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) ;
attachments = this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_displayattachments' ) ;
2013-10-21 15:07:32 +02:00
}
2013-10-16 13:25:46 +02:00
2017-11-08 19:07:04 +01:00
switch ( action )
2013-10-21 15:07:32 +02:00
{
2017-11-08 19:07:04 +01:00
case 'saveOneToVfs' :
case 'saveAllToVfs' :
var ids = [ ] ;
attachments = action === 'saveOneToVfs' ? [ attachments [ row _id ] ] : attachments ;
for ( var i = 0 ; i < attachments . length ; i ++ )
{
if ( attachments [ i ] != null )
{
ids . push ( mail _id + '::' + attachments [ i ] . partID + '::' + attachments [ i ] . winmailFlag + '::' + attachments [ i ] . filename ) ;
}
}
var vfs _select = et2 _createWidget ( 'vfs-select' , {
mode : action === 'saveOneToVfs' ? 'saveas' : 'select-dir' ,
method : 'mail.mail_ui.ajax_vfsSave' ,
2018-05-30 19:43:41 +02:00
button _label : this . egw . lang ( action === 'saveOneToVfs' ? 'Save' : 'Save all' ) ,
dialog _title : this . egw . lang ( action === 'saveOneToVfs' ? 'Save attachment' : 'Save attachments' ) ,
2023-01-31 23:03:18 +01:00
method _id : ids . length > 1 ? { ids : ids , action : 'attachment' } : { ids : ids [ 0 ] , action : 'attachment' } ,
2017-11-08 19:07:04 +01:00
name : action === 'saveOneToVfs' ? attachments [ 0 ] [ 'filename' ] : null
} ) ;
vfs _select . click ( ) ;
break ;
2023-01-31 23:03:18 +01:00
case 'collabora' :
attachment = attachments [ row _id ] ;
let id = mail _id + '::' + attachment . partID + '::' + attachment . winmailFlag + '::' + attachment . filename ;
// This can take a few seconds, show loader
this . egw . loading _prompt ( 'mail_open_file' , true , attachment . filename ) ;
// Temp save to VFS
this . egw . request ( 'mail.mail_ui.ajax_vfsOpen' , [ id , attachment . filename ] ) . then ( ( temp _path ) =>
{
if ( temp _path )
{
// Open in Collabora
window . open ( this . egw . link ( '/index.php' , {
'menuaction' : 'collabora.EGroupware\\collabora\\Ui.editor' ,
'path' : temp _path ,
'cd' : 'no' // needed to not reload framework in sharing
} ) ) ;
}
} ) . finally ( ( ) =>
{
// Hide load prompt
this . egw . loading _prompt ( 'mail_open_file' , false ) ;
} ) ;
break ;
2017-10-12 13:20:23 +02:00
2017-11-08 19:07:04 +01:00
case 'downloadOneAsFile' :
case 'downloadAllToZip' :
var attachment = attachments [ row _id ] ;
var url = window . egw _webserverUrl + '/index.php?' ;
url += jQuery . param ( {
menuaction : action === 'downloadOneAsFile' ?
'mail.mail_ui.getAttachment' : 'mail.mail_ui.download_zip' ,
mode : 'save' ,
id : mail _id ,
part : attachment . partID ,
is _winmail : attachment . winmailFlag ,
smime _type : ( attachment . smime _type ? attachment . smime _type : '' )
} ) ;
this . et2 . _inst . download ( url ) ;
break ;
2023-08-03 18:16:35 +02:00
case 'forward' :
// Give some UI feedback, this might take a second
document . body . style . cursor = 'wait' ;
// Move the attachment to VFS
const file _id = mail _id + '::' + attachments [ row _id ] . partID + '::' + attachments [ row _id ] . winmailFlag + '::' + attachments [ row _id ] . filename ;
this . egw . request ( "mail.mail_ui.ajax_vfsOpen" , [ file _id , attachments [ row _id ] . filename ] )
. then ( ( vfs _path ) => {
if ( ! vfs _path )
{
// Server call will also display an error on failure
return ;
}
// File is in VFS, put it in a compose window
const params = { } ;
let content = { data : { files : { file : [ ] } } } ;
params [ 'preset[file][]' ] = 'vfs://default' + vfs _path ;
content . data . files . file . push ( 'vfs://default' + vfs _path ) ;
content . data . files [ "filemode" ] = params [ 'preset[filemode]' ] ;
// always open compose in html mode, as attachment links look a lot nicer in html
params [ "mimeType" ] = 'html' ;
egw . openWithinWindow ( "mail" , "setCompose" , content , params , /mail.mail_compose.compose/ , true ) ;
} )
. finally ( ( ) => {
// No matter what, clear the waiting style
document . body . style . cursor = '' ;
} ) ;
break ;
2013-10-16 13:25:46 +02:00
}
} ,
2013-04-13 12:30:07 +02:00
/ * *
* Save a message to filemanager
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
mail _save2fm : function ( _action , _elems )
{
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 11:03:51 +02:00
{
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2017-10-12 13:20:23 +02:00
var ids = [ ] , names = [ ] ;
2017-05-09 15:09:00 +02:00
for ( var i in _elems )
{
var _id = _elems [ i ] . id ;
var dataElem = egw . dataGetUIDdata ( _id ) ;
var subject = dataElem ? dataElem . data . subject : _elems [ i ] . subject ;
2019-08-21 12:12:20 +02:00
if ( this . egw . is _popup ( ) && this . et2 . _inst . name == 'mail.display' )
2019-08-01 12:30:55 +02:00
{
subject = this . et2 . getArrayMgr ( 'content' ) . getEntry ( 'mail_displaysubject' ) ;
}
2018-01-15 19:52:15 +01:00
// Replace these now, they really cause problems later
2020-01-06 15:48:02 +01:00
var filename = subject ? subject . replace ( /[\f\n\t\v\x0b\:*#?<>%"\/\\\?]/g , "_" ) : 'unknown' ;
2017-10-12 13:20:23 +02:00
ids . push ( _id ) ;
2017-10-12 17:45:46 +02:00
names . push ( filename + '.eml' ) ;
2017-10-12 13:20:23 +02:00
}
var vfs _select = et2 _createWidget ( 'vfs-select' , {
mode : _elems . length > 1 ? 'select-dir' : 'saveas' ,
2017-10-12 17:45:46 +02:00
mime : 'message/rfc822' ,
2017-11-08 19:07:04 +01:00
method : 'mail.mail_ui.ajax_vfsSave' ,
2017-10-12 13:20:23 +02:00
button _label : _elems . length > 1 ? egw . lang ( 'Save all' ) : egw . lang ( 'save' ) ,
2018-09-13 22:26:54 +02:00
dialog _title : this . egw . lang ( "Save email" ) ,
2017-11-08 19:07:04 +01:00
method _id : _elems . length > 1 ? { ids : ids , action : 'message' } : { ids : ids [ 0 ] , action : 'message' } ,
2017-10-12 13:20:23 +02:00
name : _elems . length > 1 ? names : names [ 0 ] ,
} ) ;
vfs _select . click ( ) ;
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
2015-04-15 13:23:59 +02:00
* Integrate mail message into another app ' s entry
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _elems _elems [ 0 ] . id is the row - id
* /
2015-04-15 13:23:59 +02:00
mail _integrate : function ( _action , _elems )
2013-02-19 17:30:59 +01:00
{
2015-04-15 13:23:59 +02:00
var app = _action . id ;
2015-04-20 16:31:21 +02:00
var w _h = [ '750' , '580' ] ; // define a default wxh if there's no popup size registered
2015-05-17 21:03:45 +02:00
2015-04-20 16:31:21 +02:00
if ( typeof _action . data != 'undefined' )
2015-04-15 13:23:59 +02:00
{
2015-05-12 15:21:08 +02:00
if ( typeof _action . data . popup != 'undefined' && _action . data . popup ) w _h = _action . data . popup . split ( 'x' ) ;
2015-04-20 16:31:21 +02:00
if ( typeof _action . data . mail _import != 'undefined' ) var mail _import _hook = _action . data . mail _import ;
2013-10-05 11:03:51 +02:00
}
2013-07-25 17:35:44 +02:00
2014-03-07 11:06:04 +01:00
if ( typeof _elems == 'undefined' || _elems . length == 0 )
2013-10-05 11:03:51 +02:00
{
if ( this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) )
{
var _elems = [ ] ;
_elems . push ( { id : this . et2 . getArrayMgr ( "content" ) . getEntry ( 'mail_id' ) || '' } ) ;
}
2014-03-07 11:06:04 +01:00
if ( ( typeof _elems == 'undefined' || _elems . length == 0 ) && this . mail _isMainWindow )
2013-10-14 15:30:04 +02:00
{
if ( this . mail _currentlyFocussed )
{
var _elems = [ ] ;
_elems . push ( { id : this . mail _currentlyFocussed } ) ;
}
}
2013-10-05 11:03:51 +02:00
}
2015-05-17 21:03:45 +02:00
2015-04-15 13:23:59 +02:00
var url = window . egw _webserverUrl + '/index.php?menuaction=mail.mail_integration.integrate&rowid=' + _elems [ 0 ] . id + '&app=' + app ;
2015-05-17 21:03:45 +02:00
2016-08-18 17:30:44 +02:00
if ( mail _import _hook && typeof mail _import _hook . app _entry _method != 'undefined' )
2015-04-20 16:31:21 +02:00
{
var data = egw . dataGetUIDdata ( _elems [ 0 ] . id ) ;
2017-11-22 18:10:46 +01:00
var title = egw . lang ( 'Select' ) + ' ' + egw . lang ( app ) + ' ' + ( egw . link _get _registry ( app , 'entry' ) ? egw . link _get _registry ( app , 'entry' ) : egw . lang ( 'entry' ) ) ;
2015-04-20 16:31:21 +02:00
var subject = ( data && typeof data . data != 'undefined' ) ? data . data . subject : '' ;
2017-11-22 18:10:46 +01:00
this . integrate _checkAppEntry ( title , app , subject , url , mail _import _hook . app _entry _method , function ( args ) {
2016-08-18 17:30:44 +02:00
egw _openWindowCentered ( args . url + ( args . entryid ? '&entry_id=' + args . entryid : '' ) , 'import_mail_' + _elems [ 0 ] . id , w _h [ 0 ] , w _h [ 1 ] ) ;
} ) ;
2015-04-20 16:31:21 +02:00
}
else
{
egw _openWindowCentered ( url , 'import_mail_' + _elems [ 0 ] . id , w _h [ 0 ] , w _h [ 1 ] ) ;
}
2015-05-17 21:03:45 +02:00
2013-04-13 12:30:07 +02:00
} ,
2013-07-25 17:35:44 +02:00
2016-08-18 17:30:44 +02:00
/ * *
* Checks the application entry existance and offers user
* to select desire app id to append mail content into it ,
* or add the mail content as a new app entry
*
* @ param { string } _title select app entry title
* @ param { string } _appName app to be integrated
* @ param { string } _subject
* @ param { string } _url
* @ param { string } _appCheckCallback registered mail _import hook method
* @ param { function } _execCallback function to get called on dialog actions
* /
integrate _checkAppEntry : function ( _title , _appName , _subject , _url , _appCheckCallback , _execCallback )
{
var subject = _subject || '' ;
var execCallback = _execCallback ;
egw . json ( _appCheckCallback , subject , function ( _entryId ) {
// if there's no entry saved already
// open dialog in order to select one
if ( ! _entryId )
{
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : app . mail . egw . lang ( 'Append' ) , id : 'append' , image : 'check' , default : true } ,
{ label : app . mail . egw . lang ( 'Add as new' ) , id : 'new' , image : 'check' } ,
{ label : app . mail . egw . lang ( 'Cancel' ) , id : 'cancel' , image : 'check' }
2016-08-18 17:30:44 +02:00
] ;
2022-10-19 16:39:13 +02:00
const dialog = new Et2Dialog ( this . egw ) ;
dialog . transformAttributes ( {
2022-07-20 22:23:55 +02:00
callback : function ( _buttons , _value )
2016-08-18 17:30:44 +02:00
{
2022-07-20 22:23:55 +02:00
if ( _buttons == 'cancel' )
{
return ;
}
2016-08-18 17:30:44 +02:00
if ( _buttons == 'append' && _value )
{
_entryId = _value . id ;
}
2022-07-20 22:23:55 +02:00
execCallback . call ( this , { entryid : _entryId , url : _url } ) ;
2016-08-18 17:30:44 +02:00
} ,
title : egw . lang ( _title ) ,
2022-07-20 22:23:55 +02:00
buttons : buttons || Et2Dialog . BUTTONS _OK _CANCEL ,
value : {
content : {
appName : _appName // appName to search on its list later
}
} ,
template : egw . webserverUrl + '/mail/templates/default/integration_to_entry_dialog.xet'
2022-10-19 16:39:13 +02:00
} ) ;
document . body . appendChild ( dialog ) ;
2016-08-18 17:30:44 +02:00
}
else // there is an entry saved related to this mail's subject
{
execCallback . call ( this , { entryid : _entryId , url : _url } ) ;
}
} , this , true , this ) . sendRequest ( ) ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _getFormData
2013-07-25 17:35:44 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _actionObjects the senders
2014-05-20 17:39:20 +02:00
*
2013-04-13 12:30:07 +02:00
* @ return structured array of message ids : array ( msg => message - ids )
* /
mail _getFormData : function ( _actionObjects ) {
var messages = { } ;
2014-02-05 13:23:04 +01:00
// if
2014-01-27 13:18:16 +01:00
if ( typeof _actionObjects [ 'msg' ] != 'undefined' && _actionObjects [ 'msg' ] . length > 0 ) return _actionObjects ;
2013-04-13 12:30:07 +02:00
if ( _actionObjects . length > 0 )
2013-02-19 17:30:59 +01:00
{
2013-04-13 12:30:07 +02:00
messages [ 'msg' ] = [ ] ;
2013-02-19 17:30:59 +01:00
}
2013-07-25 17:35:44 +02:00
2013-04-30 16:16:52 +02:00
for ( var i = 0 ; i < _actionObjects . length ; i ++ )
2013-02-28 10:28:08 +01:00
{
2013-04-13 12:30:07 +02:00
if ( _actionObjects [ i ] . id . length > 0 )
{
messages [ 'msg' ] [ i ] = _actionObjects [ i ] . id ;
}
2013-02-28 10:28:08 +01:00
}
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
return messages ;
} ,
2013-07-25 17:35:44 +02:00
2013-04-13 12:30:07 +02:00
/ * *
* mail _setRowClass
2013-07-25 17:35:44 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { object } _actionObjects the senders
* @ param { string } _class
2013-04-13 12:30:07 +02:00
* /
mail _setRowClass : function ( _actionObjects , _class ) {
if ( typeof _class == 'undefined' ) return false ;
2013-07-25 17:35:44 +02:00
2013-12-06 11:35:39 +01:00
if ( typeof _actionObjects [ 'msg' ] == 'undefined' )
2013-04-13 12:30:07 +02:00
{
2013-12-06 11:35:39 +01:00
for ( var i = 0 ; i < _actionObjects . length ; i ++ )
{
2014-11-17 21:37:17 +01:00
// Check that the ID & interface is there. Paste is missing iface.
if ( _actionObjects [ i ] . id . length > 0 && _actionObjects [ i ] . iface )
2013-12-06 11:35:39 +01:00
{
2016-06-02 16:51:15 +02:00
var dataElem = jQuery ( _actionObjects [ i ] . iface . getDOMNode ( ) ) ;
2013-12-06 11:35:39 +01:00
dataElem . addClass ( _class ) ;
}
}
}
else
{
for ( var i = 0 ; i < _actionObjects [ 'msg' ] . length ; i ++ )
2013-04-13 12:30:07 +02:00
{
2014-01-13 15:22:58 +01:00
var mail _uid = _actionObjects [ 'msg' ] [ i ] ;
2013-07-25 17:35:44 +02:00
2014-01-13 15:22:58 +01:00
// Get the record from data cache
var dataElem = egw . dataGetUIDdata ( mail _uid ) ;
if ( dataElem == null || typeof dataElem == undefined )
{
// Unknown ID, nothing to update
return ;
2013-12-06 11:35:39 +01:00
}
2014-01-13 15:22:58 +01:00
// Update class
2014-12-11 13:01:52 +01:00
dataElem . data [ 'class' ] += ' ' + _class ;
2014-01-13 15:22:58 +01:00
2014-09-03 12:34:14 +02:00
// need to update flags too
switch ( _class )
{
case 'unseen' :
delete dataElem . data . flags . read ;
break ;
}
2014-01-13 15:22:58 +01:00
// Update record, which updates all listeners (including nextmatch)
egw . dataStoreUID ( mail _uid , dataElem . data ) ;
2013-04-13 12:30:07 +02:00
}
}
} ,
2013-07-25 17:35:44 +02:00
2013-05-27 15:48:55 +02:00
/ * *
2014-01-13 15:22:58 +01:00
* mail _removeRowFlag
* Removes a flag and updates the CSS class . Updates the UI , but not the server .
2013-07-25 17:35:44 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { action object } _actionObjects the senders , or a messages object
* @ param { string } _class the class to be removed
2013-05-27 15:48:55 +02:00
* /
mail _removeRowClass : function ( _actionObjects , _class ) {
if ( typeof _class == 'undefined' ) return false ;
if ( typeof _actionObjects [ 'msg' ] == 'undefined' )
{
2013-07-25 17:35:44 +02:00
for ( var i = 0 ; i < _actionObjects . length ; i ++ )
2013-05-27 15:48:55 +02:00
{
if ( _actionObjects [ i ] . id . length > 0 )
{
2016-06-02 16:51:15 +02:00
var dataElem = jQuery ( _actionObjects [ i ] . iface . getDOMNode ( ) ) ;
2013-05-27 15:48:55 +02:00
dataElem . removeClass ( _class ) ;
2013-07-25 17:35:44 +02:00
2013-05-27 15:48:55 +02:00
}
}
}
else
{
2013-07-25 17:35:44 +02:00
for ( var i = 0 ; i < _actionObjects [ 'msg' ] . length ; i ++ )
2013-05-27 15:48:55 +02:00
{
2014-01-13 15:22:58 +01:00
var mail _uid = _actionObjects [ 'msg' ] [ i ] ;
// Get the record from data cache
var dataElem = egw . dataGetUIDdata ( mail _uid ) ;
if ( dataElem == null || typeof dataElem == undefined )
2013-05-27 15:48:55 +02:00
{
2014-01-13 15:22:58 +01:00
// Unknown ID, nothing to update
return ;
}
2013-07-25 17:35:44 +02:00
2014-01-13 15:22:58 +01:00
// Update class
2014-12-11 13:01:52 +01:00
var classes = dataElem . data [ 'class' ] || "" ;
2014-01-13 15:22:58 +01:00
classes = classes . split ( ' ' ) ;
if ( classes . indexOf ( _class ) >= 0 )
{
2020-08-05 16:43:57 +02:00
for ( var c in classes )
{
classes . splice ( classes . indexOf ( _class ) , 1 ) ;
if ( classes . indexOf ( _class ) < 0 ) break ;
}
2014-12-11 13:01:52 +01:00
dataElem . data [ 'class' ] = classes . join ( ' ' ) ;
2014-01-13 15:22:58 +01:00
2014-09-03 12:34:14 +02:00
// need to update flags too
switch ( _class )
{
case 'unseen' :
dataElem . data . flags . read = true ;
break ;
}
2014-01-13 15:22:58 +01:00
// Update record, which updates all listeners (including nextmatch)
egw . dataStoreUID ( mail _uid , dataElem . data ) ;
2013-07-25 17:35:44 +02:00
}
2013-05-27 15:48:55 +02:00
}
}
} ,
2014-05-20 12:02:21 +02:00
/ * *
* mail _move2folder - implementation of the move action from action menu
*
2014-07-14 17:56:34 +02:00
* @ param _action _action . id holds folder target information
2014-05-20 12:02:21 +02:00
* @ param _elems - the representation of the elements to be affected
* /
mail _move2folder : function ( _action , _elems ) {
this . mail _move ( _action , _elems , null ) ;
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _move - implementation of the move action from drag n drop
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _senders - the representation of the elements dragged
* @ param _target - the representation of the target
* /
mail _move : function ( _action , _senders , _target ) {
2014-06-26 17:05:04 +02:00
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 ) {
2013-04-13 12:30:07 +02:00
var target = _action . id == 'drop_move_mail' ? _target . iface . id : _action . id . substr ( 5 ) ;
var messages = this . mail _getFormData ( _senders ) ;
2014-06-26 17:05:04 +02:00
if ( typeof _allMessagesChecked == 'undefined' ) _allMessagesChecked = false ;
2014-08-18 22:53:23 +02:00
// Directly delete any cache for target
if ( window . localStorage )
{
for ( var i = 0 ; i < window . localStorage . length ; i ++ )
{
var key = window . localStorage . key ( i ) ;
// Find directly by what the key would look like
2014-08-19 15:54:04 +02:00
if ( key . indexOf ( 'cached_fetch_mail::{"selectedFolder":"' + target + '"' ) == 0 )
2014-08-18 22:53:23 +02:00
{
window . localStorage . removeItem ( key ) ;
}
}
}
2013-04-13 12:30:07 +02:00
// TODO: Write move/copy function which cares about doing the same stuff
// as the "onNodeSelect" function!
2014-07-01 17:22:18 +02:00
messages [ 'all' ] = _allMessagesChecked ;
2014-06-26 17:05:04 +02:00
if ( messages [ 'all' ] == 'cancel' ) return false ;
2014-06-20 14:05:03 +02:00
if ( messages [ 'all' ] ) messages [ 'activeFilters' ] = this . mail _getActiveFilters ( _action ) ;
2014-10-20 20:08:03 +02:00
// Make sure a default target folder is set in case of drop target is parent 0 (mail account name)
2014-10-14 10:01:52 +02:00
if ( ! target . match ( /::/g ) ) target += '::INBOX' ;
2014-10-20 20:08:03 +02:00
2014-07-14 17:56:34 +02:00
var self = this ;
2013-10-18 11:58:25 +02:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
2021-03-10 18:31:24 +01:00
// Nextmatch automatically selects the next row and calls preview.
// Stop it for now, we'll put it back when the copy is done
let on _select = nm . options . onselect ;
2021-03-16 17:52:31 +01:00
nm . options . onselect = null ;
2021-03-15 21:41:26 +01:00
_senders [ 0 ] . parent . setAllSelected ( false ) ;
this . mail _preview ( [ ] , nm ) ;
2021-03-16 17:52:31 +01:00
// Restore onselect handler
nm . options . onselect = on _select ;
2016-04-29 15:19:32 +02:00
// thev 4th param indicates if it is a normal move messages action. if not the action is a move2.... (archiveFolder) action
egw . json ( 'mail.mail_ui.ajax_copyMessages' , [ target , messages , 'move' , ( _action . id . substr ( 0 , 4 ) == 'move' && _action . id . substr ( 4 , 1 ) == '2' ? '2' : '_' ) ] , function ( ) {
2014-11-17 18:19:51 +01:00
self . unlock _tree ( ) ;
2021-03-10 18:31:24 +01:00
2014-12-15 18:26:04 +01:00
// Server response may contain refresh, but it's always delete
// Refresh list if current view is the target (happens when pasting)
var tree = self . et2 . getWidgetById ( 'nm[foldertree]' ) ;
if ( nm && tree && target == tree . getValue ( ) )
{
// Can't trust the sorting, needs to be full refresh
nm . refresh ( ) ;
}
2014-11-17 18:19:51 +01:00
} )
. sendRequest ( ) ;
2013-06-04 17:29:53 +02:00
this . mail _setRowClass ( _senders , 'deleted' ) ;
2014-12-15 18:26:04 +01:00
// Server response may contain refresh, not needed here
2013-04-13 12:30:07 +02:00
} ,
2014-03-10 12:13:51 +01:00
2013-04-13 12:30:07 +02:00
/ * *
2014-06-26 17:05:04 +02:00
* mail _copy - implementation of the move action from drag n drop
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _senders - the representation of the elements dragged
* @ param _target - the representation of the target
* /
mail _copy : function ( _action , _senders , _target ) {
2014-06-26 17:05:04 +02:00
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 ) {
2013-04-29 16:56:33 +02:00
var target = _action . id == 'drop_copy_mail' ? _target . iface . id : _action . id . substr ( 5 ) ;
2013-04-13 12:30:07 +02:00
var messages = this . mail _getFormData ( _senders ) ;
2014-06-26 17:05:04 +02:00
if ( typeof _allMessagesChecked == 'undefined' ) _allMessagesChecked = false ;
2013-04-13 12:30:07 +02:00
// TODO: Write move/copy function which cares about doing the same stuff
// as the "onNodeSelect" function!
2014-07-01 17:22:18 +02:00
messages [ 'all' ] = _allMessagesChecked ;
2014-06-26 17:05:04 +02:00
if ( messages [ 'all' ] == 'cancel' ) return false ;
2014-06-20 14:05:03 +02:00
if ( messages [ 'all' ] ) messages [ 'activeFilters' ] = this . mail _getActiveFilters ( _action ) ;
2014-07-14 17:56:34 +02:00
var self = this ;
egw . json ( 'mail.mail_ui.ajax_copyMessages' , [ target , messages ] , function ( ) { self . unlock _tree ( ) ; } )
2014-07-15 11:37:08 +02:00
. sendRequest ( ) ;
2014-02-27 01:22:25 +01:00
// Server response contains refresh
2013-04-13 12:30:07 +02:00
} ,
2013-05-21 10:46:54 +02:00
/ * *
* mail _AddFolder - implementation of the AddFolder action of right click options on the tree
2013-07-25 17:35:44 +02:00
*
2013-05-21 10:46:54 +02:00
* @ param _action
* @ param _senders - the representation of the tree leaf to be manipulated
* /
2014-02-12 21:12:59 +01:00
mail _AddFolder : function ( _action , _senders ) {
2013-05-21 10:46:54 +02:00
//action.id == 'add'
//_senders.iface.id == target leaf / leaf to edit
2013-10-18 11:58:25 +02:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2014-03-03 14:10:27 +01:00
var OldFolderName = ftree . getLabel ( _senders [ 0 ] . id ) . replace ( this . _unseen _regexp , '' ) ;
2013-12-12 16:44:47 +01:00
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Add" ) , id : "add" , "class" : "ui-priority-primary" , "default" : true } ,
{ label : this . egw . lang ( "Cancel" ) , id : "cancel" }
2013-12-12 16:44:47 +01:00
] ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _prompt ( function ( _button _id , _value )
2013-12-12 16:44:47 +01:00
{
2022-07-20 22:23:55 +02:00
var NewFolderName = null ;
if ( _value . length > 0 )
2013-12-12 16:44:47 +01:00
{
2022-07-20 22:23:55 +02:00
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 ;
2013-12-12 16:44:47 +01:00
case "cancel" :
}
}
} ,
this . egw . lang ( "Enter the name for the new Folder:" ) ,
this . egw . lang ( "Add a new Folder to %1:" , OldFolderName ) ,
'' , buttons ) ;
2013-05-21 10:46:54 +02:00
} ,
2013-04-13 12:30:07 +02:00
/ * *
* mail _RenameFolder - implementation of the RenameFolder action of right click options on the tree
2013-07-25 17:35:44 +02:00
*
2013-04-13 12:30:07 +02:00
* @ param _action
* @ param _senders - the representation of the tree leaf to be manipulated
* /
2014-02-12 21:12:59 +01:00
mail _RenameFolder : function ( _action , _senders ) {
2013-04-13 12:30:07 +02:00
//action.id == 'rename'
//_senders.iface.id == target leaf / leaf to edit
2013-10-18 11:58:25 +02:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2014-03-03 14:10:27 +01:00
var OldFolderName = ftree . getLabel ( _senders [ 0 ] . id ) . replace ( this . _unseen _regexp , '' ) ;
2013-12-12 16:10:25 +01:00
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Rename" ) , id : "rename" , "class" : "ui-priority-primary" , image : 'edit' , "default" : true } ,
{ label : this . egw . lang ( "Cancel" ) , id : "cancel" }
2013-12-12 16:10:25 +01:00
] ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _prompt ( function ( _button _id , _value )
2013-12-12 16:10:25 +01:00
{
2022-07-20 22:23:55 +02:00
var NewFolderName = null ;
if ( _value . length > 0 )
2013-12-12 16:10:25 +01:00
{
2022-07-20 22:23:55 +02:00
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 ;
2013-12-12 16:10:25 +01:00
case "cancel" :
}
}
} ,
this . egw . lang ( "Rename Folder %1 to:" , OldFolderName ) ,
this . egw . lang ( "Rename Folder %1 ?" , OldFolderName ) ,
OldFolderName , buttons ) ;
2013-05-13 16:42:42 +02:00
} ,
2014-01-06 10:51:24 +01:00
/ * *
2014-01-11 12:58:31 +01:00
* mail _MoveFolder - implementation of the MoveFolder action on the tree
2014-01-06 10:51:24 +01:00
*
2014-01-11 12:58:31 +01:00
* @ param { egwAction } _action
* @ param { egwActionObject [ ] } _senders - the representation of the tree leaf to be manipulated
* @ param { egwActionObject } destination Drop target egwActionObject representing the destination
2014-01-06 10:51:24 +01:00
* /
2014-01-11 12:58:31 +01:00
mail _MoveFolder : function ( _action , _senders , destination ) {
if ( ! destination || ! destination . id )
{
egw . debug ( 'warn' , "Move folder, but no target" ) ;
return ;
}
2016-02-04 14:54:58 +01:00
var sourceProfile = _senders [ 0 ] . id . split ( '::' ) ;
var targetProfile = destination . id . split ( '::' ) ;
if ( sourceProfile [ 0 ] != targetProfile [ 0 ] )
{
egw . message ( this . egw . lang ( 'Moving Folders from one Mailaccount to another is not supported' ) , 'error' ) ;
return ;
}
2016-01-07 12:12:32 +01:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2016-02-04 14:54:58 +01:00
var src _label = _senders [ 0 ] . id . replace ( /^[0-9]+::/ , '' ) ;
var dest _label = destination . id . replace ( /^[0-9]+::/ , '' ) ;
2016-03-29 12:13:32 +02:00
2016-01-07 12:31:17 +01:00
var callback = function ( _button )
{
2022-07-20 22:23:55 +02:00
if ( _button == Et2Dialog . YES _BUTTON )
2016-01-07 12:31:17 +01:00
{
2022-07-20 22:23:55 +02:00
egw . appName = 'mail' ;
egw . message ( egw . lang ( 'Folder %1 is moving to folder %2' , src _label , dest _label ) ) ;
egw . loading _prompt ( 'mail_moveFolder' , true , '' , '#egw_fw_basecontainer' ) ;
for ( var i = 0 ; i < _senders . length ; i ++ )
2016-01-07 12:31:17 +01:00
{
2023-04-19 19:57:23 +02:00
egw . request ( 'mail.mail_ui.ajax_MoveFolder' , [ _senders [ i ] . id , destination . id ] )
. finally ( ( ) =>
{
// Move is done (successfully or not), remove loading
var id = destination . id . split ( '::' ) ;
//refersh the top parent
ftree . refreshItem ( id [ 0 ] , null ) ;
egw . loading _prompt ( 'mail_moveFolder' , false ) ;
}
) ;
2016-01-07 12:12:32 +01:00
}
2016-01-07 12:31:17 +01:00
}
} ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( callback , this . egw . lang ( 'Are you sure you want to move folder %1 to folder %2?' ,
src _label , dest _label ) , this . egw . lang ( 'Move folder' ) , { } , Et2Dialog . BUTTONS _YES _NO , Et2Dialog . WARNING _MESSAGE ) ;
2014-01-06 10:51:24 +01:00
} ,
2013-05-13 16:42:42 +02:00
/ * *
* mail _DeleteFolder - implementation of the DeleteFolder action of right click options on the tree
2013-07-25 17:35:44 +02:00
*
2013-05-13 16:42:42 +02:00
* @ param _action
* @ param _senders - the representation of the tree leaf to be manipulated
* /
2022-07-20 22:23:55 +02:00
mail _DeleteFolder : function ( _action , _senders )
{
2013-05-13 16:42:42 +02:00
//action.id == 'delete'
//_senders.iface.id == target leaf / leaf to edit
2022-07-20 22:23:55 +02:00
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
var OldFolderName = ftree . getLabel ( _senders [ 0 ] . id ) . replace ( this . _unseen _regexp , '' ) ;
2013-12-12 14:34:35 +01:00
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Yes" ) , id : "delete" , "class" : "ui-priority-primary" , "default" : true , image : "check" } ,
{ label : this . egw . lang ( "Cancel" ) , id : "cancel" , image : "cancel" }
2013-12-12 14:34:35 +01:00
] ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( function ( _button _id , _value )
2013-12-12 14:34:35 +01:00
{
2022-07-20 22:23:55 +02:00
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 ) ;
2013-07-25 17:35:44 +02:00
} ,
2013-09-02 17:15:35 +02:00
/ * *
* Send names of uploaded files ( again ) to server , to process them : either copy to vfs or ask overwrite / rename
2013-10-09 18:44:03 +02:00
*
2013-09-02 17:15:35 +02:00
* @ param _event
* @ param _file _count
2014-02-12 21:12:59 +01:00
* @ param { string ? } _path where the file is uploaded to , default current directory
2013-09-02 17:15:35 +02:00
* /
uploadForImport : function ( _event , _file _count , _path )
{
2013-09-05 16:52:11 +02:00
// path is probably not needed when uploading for file; maybe it is when from vfs
2013-09-02 17:15:35 +02:00
if ( typeof _path == 'undefined' )
{
//_path = this.get_path();
}
if ( _file _count && ! jQuery . isEmptyObject ( _event . data . getValue ( ) ) )
{
2013-09-05 16:52:11 +02:00
var widget = _event . data ;
// var request = new egw_json_request('mail_ui::ajax_importMessage', ['upload', widget.getValue(), _path], this);
2013-09-02 17:15:35 +02:00
// widget.set_value('');
2013-09-05 16:52:11 +02:00
// request.sendRequest();//false, this._upload_callback, this);
2013-09-10 15:39:44 +02:00
this . et2 _obj . submit ( ) ;
}
} ,
/ * *
* Send names of uploaded files ( again ) to server , to process them : either copy to vfs or ask overwrite / rename
2013-10-09 18:44:03 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { event object } _event
* @ param { string } _file _count
* @ param { string } _path [ _path = current directory ] Where the file is uploaded to .
2013-09-10 15:39:44 +02:00
* /
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 ;
2013-09-11 15:46:00 +02:00
this . et2 _obj . submit ( ) ;
2013-09-02 17:15:35 +02:00
}
} ,
2014-09-03 14:42:34 +02:00
/ * *
* Visible attachment box in compose dialog as soon as the file starts to upload
* /
composeUploadStart : function ( )
{
2014-09-04 11:01:43 +02:00
var boxAttachment = this . et2 . getWidgetById ( 'attachments' ) ;
2014-09-03 14:42:34 +02:00
if ( boxAttachment )
{
var groupbox = boxAttachment . getParent ( ) ;
if ( groupbox ) groupbox . set _disabled ( false ) ;
}
return true ;
} ,
2014-09-08 17:45:37 +02:00
2014-05-16 17:39:05 +02:00
/ * *
* Upload for import ( VFS )
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { egw object } _egw
* @ param { widget object } _widget
* @ param { window object } _window
* /
2013-10-03 18:09:25 +02:00
vfsUploadForImport : function ( _egw , _widget , _window ) {
2013-11-22 14:55:09 +01:00
if ( jQuery . isEmptyObject ( _widget ) ) return ;
2013-10-03 18:09:25 +02:00
if ( ! jQuery . isEmptyObject ( _widget . getValue ( ) ) )
{
this . et2 _obj . submit ( ) ;
}
} ,
2014-05-16 17:39:05 +02:00
/ * *
* Upload for compose ( VFS )
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { egw object } _egw
* @ param { widget object } _widget
* @ param { window object } _window
* /
2013-10-02 16:50:24 +02:00
vfsUploadForCompose : function ( _egw , _widget , _window )
{
2013-11-22 14:55:09 +01:00
if ( jQuery . isEmptyObject ( _widget ) ) return ;
2013-10-04 13:17:45 +02:00
if ( ! jQuery . isEmptyObject ( _widget . getValue ( ) ) )
{
this . et2 _obj . submit ( ) ;
}
} ,
2014-05-16 17:39:05 +02:00
/ * *
* Submit on change ( VFS )
2014-05-20 17:39:20 +02:00
*
2014-05-16 17:39:05 +02:00
* @ param { egw object } _egw
* @ param { widget object } _widget
* /
2014-08-13 14:55:28 +02:00
submitOnChange : function ( _egw , _widget )
{
2013-11-22 14:55:09 +01:00
if ( ! jQuery . isEmptyObject ( _widget ) )
2013-10-02 16:50:24 +02:00
{
2014-08-13 14:55:28 +02:00
if ( typeof _widget . id !== 'undefined' ) var widgetId = _widget . id ;
switch ( widgetId )
2013-11-22 14:55:09 +01:00
{
2014-08-13 14:55:28 +02:00
case 'mimeType' :
this . et2 _obj . submit ( ) ;
break ;
default :
if ( ! jQuery . isEmptyObject ( _widget . getValue ( ) ) )
{
this . et2 _obj . submit ( ) ;
}
2013-11-22 14:55:09 +01:00
}
2013-10-02 16:50:24 +02:00
}
} ,
2014-09-23 10:42:31 +02:00
2014-05-16 17:39:05 +02:00
/ * *
2014-09-12 13:52:38 +02:00
* Save as Draft ( VFS )
* - handel both actions save as draft and save as draft and print
2014-09-23 10:42:31 +02:00
*
2015-02-18 11:10:10 +01:00
* @ param { egwAction } _egw _action
* @ param { array | string } _action string "autosaving" , if that triggered the action
2017-10-12 15:22:41 +02:00
*
* @ return Promise
2014-09-12 13:52:38 +02:00
* /
2015-01-07 12:57:34 +01:00
saveAsDraft : function ( _egw _action , _action )
2013-10-02 16:50:24 +02:00
{
2017-10-12 15:22:41 +02:00
var self = this ;
return new Promise ( function ( _resolve , _reject ) {
var content = self . et2 . getArrayMgr ( 'content' ) . data ;
var action = _action ;
if ( _egw _action && _action !== 'autosaving' )
{
action = _egw _action . id ;
}
2014-09-23 10:42:31 +02:00
2017-10-12 15:22:41 +02:00
var widgets = [ 'from' , 'to' , 'cc' , 'bcc' , 'subject' , 'folder' , 'replyto' , 'mailaccount' ,
'mail_htmltext' , 'mail_plaintext' , 'lastDrafted' , 'filemode' , 'expiration' , 'password' ] ;
var widget = { } ;
for ( var index in widgets )
2014-09-12 13:52:38 +02:00
{
2017-10-12 15:22:41 +02:00
widget = self . et2 . getWidgetById ( widgets [ index ] ) ;
if ( widget )
{
content [ widgets [ index ] ] = widget . get _value ( ) ;
}
2014-09-12 13:52:38 +02:00
}
2017-10-12 15:22:41 +02:00
if ( content )
2015-05-20 09:26:15 +02:00
{
2017-10-12 15:22:41 +02:00
// if we compose an encrypted message, we have to get the encrypted content
if ( self . mailvelope _editor )
{
self . mailvelope _editor . encrypt ( [ ] ) . then ( function ( _armored )
{
content [ 'mail_plaintext' ] = _armored ;
self . egw . json ( 'mail.mail_compose.ajax_saveAsDraft' , [ content , action ] , function ( _data ) {
var res = self . savingDraft _response ( _data , action ) ;
if ( res )
{
_resolve ( ) ;
}
else
{
_reject ( ) ;
}
} ) . sendRequest ( true ) ;
} , function ( _err )
{
self . egw . message ( _err . message , 'error' ) ;
_reject ( ) ;
} ) ;
return false ;
}
else
2015-05-20 09:26:15 +02:00
{
2022-10-05 22:30:43 +02:00
// Send request through framework main window, so it works even if the main window is reloaded
framework . egw _appWindow ( ) . egw . json ( 'mail.mail_compose.ajax_saveAsDraft' , [ content , action ] , function ( _data )
{
var res = self . savingDraft _response ( _data , action ) ;
2017-10-12 15:22:41 +02:00
if ( res )
{
_resolve ( ) ;
}
else
{
_reject ( ) ;
}
2015-05-20 09:26:15 +02:00
} ) . sendRequest ( true ) ;
2017-10-12 15:22:41 +02:00
}
2015-05-20 09:26:15 +02:00
}
2017-10-12 15:22:41 +02:00
} ) ;
2014-09-12 13:52:38 +02:00
} ,
/ * *
* Set content of drafted message with new information sent back from server
* This function would be used as callback of send request to ajax _saveAsDraft .
2014-09-23 10:42:31 +02:00
*
2014-09-12 13:52:38 +02:00
* @ param { object } _responseData response data sent back from server by ajax _saveAsDraft function .
* the object conatins below items :
* - draftedId : new drafted id created by server
* - message : resault message
* - success : true if saving was successful otherwise false
2014-09-22 11:07:48 +02:00
* - draftfolder : Name of draft folder including its delimiter
2014-09-23 10:42:31 +02:00
*
2014-09-12 13:52:38 +02:00
* @ param { string } _action action is the element which caused saving draft , it could be as such :
* - button [ saveAsDraft ]
* - button [ saveAsDraftAndPrint ]
* - autosaving
2017-10-12 15:22:41 +02:00
*
* @ return boolean return true if successful otherwise false
2014-09-12 13:52:38 +02:00
* /
savingDraft _response : function ( _responseData , _action )
2013-10-07 17:02:35 +02:00
{
2014-09-12 13:52:38 +02:00
//Make sure there's a response from server otherwise shoot an error message
if ( jQuery . isEmptyObject ( _responseData ) )
{
2014-09-22 11:07:48 +02:00
this . egw . message ( 'Could not saved the message. Because, the response from server failed.' , 'error' ) ;
2014-09-12 13:52:38 +02:00
return false ;
}
2014-09-23 10:42:31 +02:00
2014-09-12 13:52:38 +02:00
if ( _responseData . success )
{
var content = this . et2 . getArrayMgr ( 'content' ) ;
var lastDrafted = this . et2 . getWidgetById ( 'lastDrafted' ) ;
2014-10-06 11:57:50 +02:00
var folderTree = typeof opener . etemplate2 . getByApplication ( 'mail' ) [ 0 ] != 'undefined' ?
2014-09-23 14:19:28 +02:00
opener . etemplate2 . getByApplication ( 'mail' ) [ 0 ] . widgetContainer . getWidgetById ( 'nm[foldertree]' ) : null ;
2014-09-22 11:07:48 +02:00
var activeFolder = folderTree ? folderTree . getSelectedNode ( ) : null ;
2014-09-12 13:52:38 +02:00
if ( content )
{
var prevDraftedId = content . data . lastDrafted ;
content . data . lastDrafted = _responseData . draftedId ;
this . et2 . setArrayMgr ( 'content' , content ) ;
lastDrafted . set _value ( _responseData . draftedId ) ;
2014-09-23 14:19:28 +02:00
if ( folderTree && activeFolder )
2014-09-12 13:52:38 +02:00
{
2014-09-23 14:19:28 +02:00
if ( typeof activeFolder . id != 'undefined' && _responseData . draftfolder == activeFolder . id )
2014-09-22 11:07:48 +02:00
{
2014-09-23 14:19:28 +02:00
if ( prevDraftedId )
{
opener . egw _refresh ( _responseData . message , 'mail' , prevDraftedId , 'delete' ) ;
}
this . egw . refresh ( _responseData . message , 'mail' , _responseData . draftedId ) ;
2014-09-22 11:07:48 +02:00
}
2014-10-06 11:57:50 +02:00
}
2014-09-12 13:52:38 +02:00
switch ( _action )
{
case 'button[saveAsDraftAndPrint]' :
this . mail _compose _print ( 'mail::' + _responseData . draftedId ) ;
2014-09-22 10:12:54 +02:00
this . egw . message ( _responseData . message ) ;
2014-09-12 13:52:38 +02:00
break ;
case 'autosaving' :
//Any sort of thing if it's an autosaving action
default :
2014-09-22 10:12:54 +02:00
this . egw . message ( _responseData . message ) ;
2014-09-12 13:52:38 +02:00
}
}
2017-10-12 15:22:41 +02:00
return true ;
2014-09-12 13:52:38 +02:00
}
else
{
this . egw . message ( _responseData . message , 'error' ) ;
2017-10-12 15:22:41 +02:00
return false ;
2014-09-12 13:52:38 +02:00
}
2013-10-07 17:02:35 +02:00
} ,
2014-09-23 10:42:31 +02:00
2013-10-09 19:29:36 +02:00
/ * *
* Focus handler for folder , address , reject textbox / taglist to automatic check associated radio button
2014-02-27 18:47:06 +01:00
*
* @ param { event } _ev
2014-02-13 18:06:16 +01:00
* @ param { object } _widget taglist
2014-02-27 18:47:06 +01:00
*
2013-10-09 19:29:36 +02:00
* /
sieve _focus _radioBtn : function ( _ev , _widget )
2013-08-09 19:47:53 +02:00
{
2013-10-09 19:29:36 +02:00
_widget . getRoot ( ) . getWidgetById ( 'action' ) . set _value ( _widget . id . replace ( /^action_([^_]+)_text$/ , '$1' ) ) ;
2013-08-09 19:47:53 +02:00
} ,
2013-10-09 19:29:36 +02:00
2013-08-09 19:47:53 +02:00
/ * *
2014-02-13 18:06:16 +01:00
* Select all aliases
2014-02-27 18:47:06 +01:00
*
2013-08-09 19:47:53 +02:00
* /
sieve _vac _all _aliases : function ( )
{
2014-04-25 12:38:31 +02:00
var aliases = [ ] ;
2014-08-01 15:40:45 +02:00
var tmp = [ ] ;
2013-08-09 19:47:53 +02:00
var addr = this . et2 . getWidgetById ( 'addresses' ) ;
2014-04-25 12:38:31 +02:00
var addresses = this . et2 . getArrayMgr ( 'sel_options' ) . data . addresses ;
2014-05-20 17:39:20 +02:00
2014-04-25 12:38:31 +02:00
for ( var id in addresses ) aliases . push ( id ) ;
2014-08-01 15:40:45 +02:00
if ( addr )
{
tmp = aliases . concat ( addr . get _value ( ) ) ;
2014-08-13 13:45:55 +02:00
2014-08-01 15:40:45 +02:00
// returns de-duplicate items of an array
2014-08-15 13:22:43 +02:00
var deDuplicator = function ( item , pos )
{
return tmp . indexOf ( item ) == pos ;
2014-08-01 15:40:45 +02:00
} ;
2014-08-13 13:45:55 +02:00
2014-08-01 15:40:45 +02:00
aliases = tmp . filter ( deDuplicator ) ;
addr . set _value ( aliases ) ;
}
2013-08-09 19:47:53 +02:00
} ,
2013-10-16 13:22:53 +02:00
/ * *
* 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" ) ;
}
} ,
2013-07-25 17:35:44 +02:00
/ * *
* 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 ;
2014-02-14 10:37:59 +01:00
var linkData = '' ;
2013-07-25 17:35:44 +02:00
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 )
{
2022-07-20 22:23:55 +02:00
if ( button _id == Et2Dialog . YES _BUTTON )
2013-07-25 17:35:44 +02:00
{
actionData = _type . parent . data . widget . getArrayMgr ( 'content' ) ;
2022-07-20 22:23:55 +02:00
that . _do _action ( typeId , actionData [ 'data' ] , ruleID ) ;
2013-07-25 17:35:44 +02:00
}
2014-05-16 17:39:05 +02:00
} ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( callbackDeleteDialog , this . egw . lang ( "Do you really want to DELETE this Rule" ) , this . egw . lang ( "Delete" ) , { } , Et2Dialog . BUTTONS _YES _CANCEL , Et2Dialog . WARNING _MESSAGE ) ;
2013-07-25 17:35:44 +02:00
break ;
case 'add' :
2014-02-14 10:37:59 +01:00
linkData = "mail.mail_sieve.edit" ;
2022-09-07 11:31:16 +02:00
this . egw . open _link ( linkData , '_blank' , "600x680" ) ;
2013-07-25 17:35:44 +02:00
break ;
case 'edit' :
2014-02-14 10:37:59 +01:00
linkData = "mail.mail_sieve.edit&ruleID=" + ruleID ;
2022-09-07 11:31:16 +02:00
this . egw . open _link ( linkData , '_blank' , "600x680" ) ;
2013-07-25 17:35:44 +02:00
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 ;
}
}
} ,
2014-02-13 18:06:16 +01:00
/ * *
2014-06-26 17:05:04 +02:00
* Send back sieve action result to server
2014-02-27 18:47:06 +01:00
*
2014-05-16 17:39:05 +02:00
* @ param { string } _typeID action name
2014-02-13 18:06:16 +01:00
* @ param { object } _data content
* @ param { string } _selectedID selected row id
* @ param { string } _msg message
2014-02-27 18:47:06 +01:00
*
2014-02-13 18:06:16 +01:00
* /
2013-08-09 19:47:53 +02:00
_do _action : function ( _typeID , _data , _selectedID , _msg )
2013-07-25 17:35:44 +02:00
{
if ( _typeID && _data )
{
2014-05-22 17:22:19 +02:00
var request = this . egw . json ( 'mail.mail_sieve.ajax_action' , [ _typeID , _selectedID , _msg ] , null , null , true ) ;
2013-08-09 19:47:53 +02:00
request . sendRequest ( ) ;
2013-07-25 17:35:44 +02:00
}
} ,
2014-02-13 18:06:16 +01:00
/ * *
2014-05-16 17:39:05 +02:00
* Send ajax request to server to refresh the sieve grid
2014-02-13 18:06:16 +01:00
* /
2014-02-13 20:00:11 +01:00
sieve _refresh : function ( )
2013-07-25 17:35:44 +02:00
{
2014-05-22 16:46:50 +02:00
this . et2 . _inst . submit ( ) ;
2013-07-25 17:35:44 +02:00
} ,
2013-08-09 19:47:53 +02:00
2013-11-29 15:59:34 +01:00
/ * *
2014-02-06 13:48:01 +01:00
* Select the right combination of the rights for radio buttons from the selected common right
*
2014-02-13 18:06:16 +01:00
* @ @ param { jQuery event } event
2014-02-06 13:48:01 +01:00
* @ param { widget } widget common right selectBox
*
* /
2014-02-13 18:06:16 +01:00
acl _common _rights _selector : function ( event , widget )
2013-11-29 15:59:34 +01:00
{
2013-12-09 12:17:32 +01:00
var rowId = widget . id . replace ( /[^0-9.]+/g , '' ) ;
2015-08-06 11:27:10 +02:00
var rights = [ ] ;
2015-08-20 09:02:06 +02:00
2015-08-06 11:27:10 +02:00
switch ( widget . get _value ( ) )
2013-11-29 15:59:34 +01:00
{
2015-08-06 11:27:10 +02:00
case 'custom' :
break ;
case 'aeiklprstwx' :
rights = widget . get _value ( ) . replace ( /[k,x,t,e]/g , "cd" ) . split ( "" ) ;
break ;
default :
rights = widget . get _value ( ) . split ( "" ) ;
}
if ( rights . length > 0 )
{
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 ) ;
2017-05-11 16:47:31 +02:00
if ( ( rights . indexOf ( 'c' ) == - 1 && [ 'k' , 'x' ] . indexOf ( this . aclRights [ i ] ) > - 1 )
|| ( rights . indexOf ( 'd' ) == - 1 && [ 'e' , 'x' , 't' ] . indexOf ( this . aclRights [ i ] ) > - 1 ) )
{
rightsWidget . set _readonly ( false ) ;
}
2015-08-06 11:27:10 +02:00
}
2013-11-29 15:59:34 +01:00
}
} ,
2013-12-09 12:17:32 +01:00
/ * *
2014-02-06 13:48:01 +01:00
*
* Choose the right common right option for common ACL selecBox
*
2014-02-13 18:06:16 +01:00
* @ param { jQuery event } event
2014-02-06 13:48:01 +01:00
* @ param { widget } widget radioButton rights
*
* /
2014-02-13 18:06:16 +01:00
acl _common _rights : function ( event , widget )
2014-02-06 13:48:01 +01:00
{
2017-05-11 16:47:31 +02:00
var rowId = widget . id . replace ( /[^0-9.]+/g , '' ) ;
var aclCommonWidget = this . et2 . getWidgetById ( rowId + '[acl]' ) ;
var rights = '' ;
var selectedBox = widget . id ;
var virtualDelete = [ 'e' , 't' , 'x' ] ;
var virtualCreate = [ 'k' , 'x' ] ;
for ( var i = 0 ; i < this . aclRights . length ; i ++ )
{
var rightsWidget = this . et2 . getWidgetById ( rowId + '[acl_' + this . aclRights [ i ] + ']' ) ;
if ( selectedBox == rowId + '[acl_c]' && virtualCreate . indexOf ( this . aclRights [ i ] ) > - 1 )
{
rightsWidget . set _value ( false ) ;
rightsWidget . set _readonly ( widget . get _value ( ) == "true" ? true : false ) ;
}
if ( selectedBox == rowId + '[acl_d]' && virtualDelete . indexOf ( this . aclRights [ i ] ) > - 1 )
{
rightsWidget . set _value ( false ) ;
rightsWidget . set _readonly ( widget . get _value ( ) == "true" ? true : false ) ;
}
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 ) ;
}
2014-02-06 13:48:01 +01:00
} ,
/ * *
2014-02-13 20:00:11 +01:00
* Open seive filter list
2014-02-27 18:47:06 +01:00
*
2014-05-21 19:44:10 +02:00
* @ param { action } _action
* @ param { sender } _senders
2014-02-06 13:48:01 +01:00
*
* /
2014-05-21 19:44:10 +02:00
edit _sieve : function ( _action , _senders )
2014-02-06 13:48:01 +01:00
{
2014-05-21 19:44:10 +02:00
var acc _id = parseInt ( _senders [ 0 ] . id ) ;
2014-05-23 11:21:59 +02:00
2014-05-22 16:46:50 +02:00
var url = this . egw . link ( '/index.php' , {
'menuaction' : 'mail.mail_sieve.index' ,
'acc_id' : acc _id ,
'ajax' : 'true'
} ) ;
2015-03-18 17:20:11 +01:00
2015-02-27 17:28:51 +01:00
// an ugly hack for idots to show up sieve rules not in an iframe
// but as new link, better to remove it after get rid of idots template
if ( typeof window . framework == 'undefined' )
2014-05-22 16:46:50 +02:00
{
this . egw . open _link ( url ) ;
}
2015-02-27 17:28:51 +01:00
else
{
this . loadIframe ( url ) ;
}
2014-05-22 16:46:50 +02:00
} ,
2014-05-23 11:21:59 +02:00
2014-05-22 16:46:50 +02:00
/ * *
* Load an url on an iframe
*
2014-05-23 11:21:59 +02:00
* @ param { string } _url string egw url
2014-05-22 16:46:50 +02:00
* @ param { iframe widget } _iFrame an iframe to be set if non , extra _iframe is default
*
2014-05-23 11:21:59 +02:00
* @ return { boolean } return TRUE if success , and FALSE if iframe not given
2014-05-22 16:46:50 +02:00
* /
loadIframe : function ( _url , _iFrame )
{
2016-08-02 12:32:57 +02:00
var mailSplitter = this . et2 . getWidgetById ( 'splitter' ) ;
2014-05-22 16:46:50 +02:00
var quotaipercent = this . et2 . getWidgetById ( 'nm[quotainpercent]' ) ;
var iframe = _iFrame || this . et2 . getWidgetById ( 'extra_iframe' ) ;
2015-02-27 15:47:27 +01:00
if ( typeof iframe != 'undefined' && iframe )
2014-05-22 16:46:50 +02:00
{
if ( _url )
2014-05-21 19:44:10 +02:00
{
2014-05-22 16:46:50 +02:00
iframe . set _src ( _url ) ;
}
2015-02-27 15:47:27 +01:00
if ( typeof mailSplitter != 'undefined' && mailSplitter && typeof quotaipercent != 'undefined' )
2014-05-22 16:46:50 +02:00
{
mailSplitter . set _disabled ( ! ! _url ) ;
quotaipercent . set _disabled ( ! ! _url ) ;
iframe . set _disabled ( ! _url ) ;
}
2015-02-27 17:28:51 +01:00
// extra_iframe used for showing up sieve rules
// need some special handling for mobile device
// as we wont have splitter, and also a fix for
// iframe with display none
if ( iframe . id == "extra_iframe" )
2015-02-27 15:47:27 +01:00
{
if ( egwIsMobile ( ) )
{
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
2015-05-17 21:03:45 +02:00
nm . set _disabled ( ! ! _url ) ;
2015-02-27 15:47:27 +01:00
iframe . set _disabled ( ! _url ) ;
}
// Set extra_iframe a class with height and width
// and position relative, seems iframe display none
// with 100% height/width covers mail tree and block
// therefore block the click handling
if ( ! iframe . disabled )
{
iframe . set _class ( 'mail-index-extra-iframe' ) ;
}
else
{
iframe . set _class ( '' ) ;
}
}
2014-05-22 16:46:50 +02:00
return true ;
}
return false ;
2014-02-06 13:48:01 +01:00
} ,
2013-12-17 18:06:44 +01:00
2014-02-06 13:48:01 +01:00
/ * *
2014-05-20 17:39:20 +02:00
* Edit vacation message
2014-02-06 13:48:01 +01:00
*
2014-05-20 17:39:20 +02:00
* @ param { action } _action
* @ param { sender } _senders
2014-02-06 13:48:01 +01:00
* /
2014-05-20 17:39:20 +02:00
edit _vacation : function ( _action , _senders )
2014-02-06 13:48:01 +01:00
{
2022-12-06 00:43:48 +01:00
let acc _id ;
if ( ! Array . isArray ( _senders ) )
{
// Coming from "on vacation" in nm header
acc _id = parseInt ( this . et2 . getWidgetById ( 'nm[foldertree]' ) . value ) ;
}
else
{
// Coming from tree
acc _id = parseInt ( _senders [ 0 ] . id ) ;
}
2023-07-11 14:56:49 +02:00
this . egw . open _link ( 'mail.mail_sieve.editVacation&acc_id=' + acc _id , '_blank' , '700x660' ) ;
2014-02-06 13:48:01 +01:00
} ,
2015-08-20 09:02:06 +02:00
2015-07-27 19:46:45 +02:00
subscription _refresh : function ( _data )
{
console . log ( _data ) ;
} ,
2015-08-20 09:02:06 +02:00
2015-07-27 19:46:45 +02:00
/ * *
* Submit on apply button and save current tree state
2015-08-20 09:02:06 +02:00
*
2015-07-27 19:46:45 +02:00
* @ param { type } _egw
* @ param { type } _widget
* @ returns { undefined }
* /
subscription _apply : function ( _egw , _widget )
{
var tree = etemplate2 . getByApplication ( 'mail' ) [ 0 ] . widgetContainer . getWidgetById ( 'foldertree' ) ;
if ( tree )
{
tree . input . _xfullXML = true ;
this . subscription _treeLastState = tree . input . serializeTreeToJSON ( ) ;
}
this . et2 . _inst . submit ( _widget ) ;
} ,
2015-08-20 09:02:06 +02:00
2015-07-28 11:58:32 +02:00
/ * *
* Show ajax - loader when the autoloading get started
2015-08-20 09:02:06 +02:00
*
2015-07-28 11:58:32 +02:00
* @ param { type } _id item id
* @ param { type } _widget tree widget
* @ returns { Boolean }
* /
subscription _autoloadingStart : function ( _id , _widget )
{
var node = _widget . input . _globalIdStorageFind ( _id ) ;
if ( node && typeof node . htmlNode != 'undefined' )
{
var img = jQuery ( 'img' , node . htmlNode ) [ 0 ] ;
img . src = egw . image ( 'ajax-loader' , 'admin' ) ;
}
return true ;
} ,
2015-08-20 09:02:06 +02:00
2015-07-28 11:58:32 +02:00
/ * *
* Revert back the icon after autoloading is finished
* @ returns { Boolean }
* /
subscription _autoloadingEnd : function ( )
{
return true ;
} ,
2015-08-20 09:02:06 +02:00
2014-02-06 18:18:12 +01:00
/ * *
* Popup the subscription dialog
*
* @ param { action } _action
* @ param { sender } _senders
* /
edit _subscribe : function ( _action , _senders )
{
var acc _id = parseInt ( _senders [ 0 ] . id ) ;
2022-08-31 15:37:11 +02:00
this . egw . open _link ( 'mail.mail_ui.subscription&acc_id=' + acc _id , '_blank' , '720x580' ) ;
2014-02-06 18:18:12 +01:00
} ,
2013-12-20 17:17:12 +01:00
2014-02-06 13:48:01 +01:00
/ * *
* 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]' ) ;
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'Subscribe to Folder %1' , ftree . getLabel ( _senders [ 0 ] . id ) . replace ( this . _unseen _regexp , '' ) ) , 'success' ) ;
2014-02-06 13:48:01 +01:00
egw . json ( 'mail.mail_ui.ajax_foldersubscription' , [ acc _id , folder , true ] )
2013-12-20 17:17:12 +01:00
. sendRequest ( ) ;
2014-02-06 13:48:01 +01:00
} ,
2013-12-20 17:17:12 +01:00
2014-02-06 13:48:01 +01:00
/ * *
* Unsubscribe selected subscribed folder
*
* @ param { action } _action
* @ param { sender } _senders
* /
unsubscribe _folder : function ( _action , _senders )
{
2014-02-07 09:33:23 +01:00
var mailbox = _senders [ 0 ] . id . split ( '::' ) ;
var folder = mailbox [ 1 ] , acc _id = mailbox [ 0 ] ;
var ftree = this . et2 . getWidgetById ( this . nm _index + '[foldertree]' ) ;
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'Unsubscribe from Folder %1' , ftree . getLabel ( _senders [ 0 ] . id ) . replace ( this . _unseen _regexp , '' ) ) , 'success' ) ;
2014-02-07 09:33:23 +01:00
egw . json ( 'mail.mail_ui.ajax_foldersubscription' , [ acc _id , folder , false ] )
2013-12-20 11:48:04 +01:00
. sendRequest ( ) ;
2014-02-06 13:48:01 +01:00
} ,
2013-12-20 11:48:04 +01:00
2014-08-15 13:22:43 +02:00
/ * *
* Onclick for node / foldername in subscription popup
*
* Used to ( un ) check node including all children
*
* @ param { string } _id id of clicked node
* @ param { et2 _tree } _widget reference to tree widget
* /
subscribe _onclick : function ( _id , _widget )
{
_widget . setSubChecked ( _id , "toggle" ) ;
} ,
2013-11-15 18:22:46 +01:00
/ * *
* 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 )
{
2013-12-20 17:17:12 +01:00
var mailbox = _senders [ 0 ] . id . split ( '::' ) ;
2014-08-28 14:30:16 +02:00
var folder = mailbox [ 1 ] || 'INBOX' , acc _id = mailbox [ 0 ] ;
2021-06-30 17:10:35 +02:00
this . egw . open _link ( 'mail.mail_acl.edit&mailbox=' + btoa ( folder ) + '&acc_id=' + acc _id , '_blank' , '640x480' ) ;
2013-11-15 18:22:46 +01:00
} ,
2014-10-06 11:57:50 +02:00
2014-09-24 14:02:35 +02:00
/ * *
2014-09-24 14:08:10 +02:00
* Submit new selected folder back to server in order to read its acl ' s rights
2014-09-24 14:02:35 +02:00
* /
acl _folderChange : function ( )
{
var mailbox = this . et2 . getWidgetById ( 'mailbox' ) ;
2014-10-06 11:57:50 +02:00
2014-09-24 14:02:35 +02:00
if ( mailbox )
{
2022-08-31 21:34:15 +02:00
if ( mailbox . value . length > 0 )
2014-09-24 14:02:35 +02:00
{
this . et2 . _inst . submit ( ) ;
2014-10-06 11:57:50 +02:00
}
2014-09-24 14:02:35 +02:00
}
} ,
2014-10-06 11:57:50 +02:00
2013-11-03 11:24:09 +01:00
/ * *
* 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 ) ;
2022-09-01 12:04:03 +02:00
this . egw . open _link ( 'mail.mail_wizard.edit&acc_id=' + acc _id , '_blank' , '740x670' ) ;
2014-01-18 15:01:07 +01:00
} ,
/ * *
2014-10-20 14:25:43 +02:00
* Set expandable fields ( Folder , Cc and Bcc ) based on their content
* - Only fields which have no content should get hidden
2014-01-18 15:01:07 +01:00
* /
2014-10-20 14:25:43 +02:00
compose _fieldExpander _init : function ( )
2014-01-18 15:01:07 +01:00
{
2014-10-16 10:29:10 +02:00
var widgets = {
cc : {
widget : { } ,
jQClass : '.mailComposeJQueryCc'
} ,
bcc : {
widget : { } ,
jQClass : '.mailComposeJQueryBcc'
} ,
folder : {
widget : { } ,
jQClass : '.mailComposeJQueryFolder'
2014-11-20 16:05:25 +01:00
} ,
replyto : {
widget : { } ,
jQClass : '.mailComposeJQueryReplyto'
2014-10-16 10:29:10 +02:00
} } ;
2018-11-16 14:55:40 +01:00
var actions = egw . preference ( 'toggledOnActions' , 'mail' ) ;
actions = actions ? actions . split ( ',' ) : [ ] ;
2014-06-02 18:57:30 +02:00
for ( var widget in widgets )
{
2014-10-16 10:29:10 +02:00
var expanderBtn = widget + '_expander' ;
widgets [ widget ] . widget = this . et2 . getWidgetById ( widget ) ;
// Add expander button widget to the widgets object
widgets [ expanderBtn ] = { widget : this . et2 . getWidgetById ( expanderBtn ) } ;
2014-10-20 20:08:03 +02:00
if ( typeof widgets [ widget ] . widget != 'undefined'
2014-10-16 10:29:10 +02:00
&& typeof widgets [ expanderBtn ] . widget != 'undefined'
2023-11-15 15:13:58 +01:00
&& ( ! widgets [ widget ] . widget . value || ! widgets [ widget ] . widget . value . length )
2018-11-16 14:55:40 +01:00
&& actions . indexOf ( expanderBtn ) < 0 )
2014-07-02 09:48:24 +02:00
{
2014-10-16 10:29:10 +02:00
widgets [ expanderBtn ] . widget . set _disabled ( false ) ;
jQuery ( widgets [ widget ] . jQClass ) . hide ( ) ;
2014-07-02 09:48:24 +02:00
}
2014-06-02 18:57:30 +02:00
}
2014-01-18 15:01:07 +01:00
} ,
2014-07-02 09:48:24 +02:00
2023-07-05 19:23:28 +02:00
/ * *
2014-06-02 18:57:30 +02:00
* Display Folder , Cc or Bcc fields in compose popup
2014-01-18 15:01:07 +01:00
*
2014-02-13 09:16:14 +01:00
* @ param { jQuery event } event
2014-06-02 18:57:30 +02:00
* @ param { widget object } widget clicked label ( Folder , Cc or Bcc ) from compose popup
2014-01-18 15:01:07 +01:00
*
* /
2014-06-02 18:57:30 +02:00
compose _fieldExpander : function ( event , widget )
2014-01-18 15:01:07 +01:00
{
2014-11-20 16:05:25 +01:00
var expWidgets = { cc : { } , bcc : { } , folder : { } , replyto : { } } ;
2014-06-02 18:57:30 +02:00
for ( var name in expWidgets )
2014-01-18 15:01:07 +01:00
{
2014-06-02 18:57:30 +02:00
expWidgets [ name ] = this . et2 . getWidgetById ( name + '_expander' ) ;
2014-01-18 15:01:07 +01:00
}
2014-07-02 09:48:24 +02:00
2014-06-02 18:57:30 +02:00
if ( typeof widget != 'undefined' )
2014-01-18 15:01:07 +01:00
{
2014-06-02 18:57:30 +02:00
switch ( widget . id )
2014-01-18 15:01:07 +01:00
{
2014-06-02 18:57:30 +02:00
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 ) ;
}
2014-11-20 16:05:25 +01:00
break ;
case 'replyto_expander' :
jQuery ( ".mailComposeJQueryReplyto" ) . show ( ) ;
if ( typeof expWidgets . replyto != 'undefined' )
{
expWidgets . replyto . set _disabled ( true ) ;
}
break ;
2014-01-18 15:01:07 +01:00
}
}
2014-01-23 14:59:10 +01:00
else if ( typeof widget == "undefined" )
{
2014-11-20 16:05:25 +01:00
var widgets = { cc : { } , bcc : { } , folder : { } , replyto : { } } ;
2014-07-02 09:48:24 +02:00
2014-06-02 18:57:30 +02:00
for ( var widget in widgets )
2014-01-23 14:59:10 +01:00
{
2014-06-02 18:57:30 +02:00
widgets [ widget ] = this . et2 . getWidgetById ( widget ) ;
2014-07-02 09:48:24 +02:00
2021-12-09 14:02:35 +01:00
if ( widgets [ widget ] . get _value ( ) && widgets [ widget ] . get _value ( ) . length )
2014-01-23 14:59:10 +01:00
{
2014-06-02 18:57:30 +02:00
switch ( widget )
{
case 'cc' :
jQuery ( ".mailComposeJQueryCc" ) . show ( ) ;
if ( typeof expWidgets . cc != 'undefiend' )
{
2014-06-23 18:22:30 +02:00
expWidgets . cc . set _disabled ( true ) ;
2014-06-02 18:57:30 +02:00
}
break ;
case 'bcc' :
jQuery ( ".mailComposeJQueryBcc" ) . show ( ) ;
if ( typeof expWidgets . bcc != 'undefiend' )
{
2014-06-23 18:22:30 +02:00
expWidgets . bcc . set _disabled ( true ) ;
2014-06-02 18:57:30 +02:00
}
break ;
case 'folder' :
jQuery ( ".mailComposeJQueryFolder" ) . show ( ) ;
if ( typeof expWidgets . folder != 'undefiend' )
{
2014-06-23 18:22:30 +02:00
expWidgets . folder . set _disabled ( true ) ;
2014-06-02 18:57:30 +02:00
}
2014-11-20 16:05:25 +01:00
break ;
case 'replyto' :
jQuery ( ".mailComposeJQueryReplyto" ) . show ( ) ;
if ( typeof expWidgets . replyto != 'undefiend' )
{
expWidgets . replyto . set _disabled ( true ) ;
}
break ;
2014-06-02 18:57:30 +02:00
}
2014-01-23 14:59:10 +01:00
}
}
}
2014-01-18 15:01:07 +01:00
} ,
2014-01-21 11:21:59 +01:00
/ * *
* 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 ( ) ;
2014-01-21 14:34:02 +01:00
} ,
/ * *
* 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 ( ) ;
}
2014-02-12 21:12:59 +01:00
} ,
/ * *
* Print a mail from list
* @ param _action
* @ param _senders - the representation of the tree leaf to be manipulated
* /
mail _print : function ( _action , _senders )
{
2014-04-17 11:59:08 +02:00
var currentTemp = this . et2 . _inst . name ;
2014-05-20 17:39:20 +02:00
2014-04-17 11:59:08 +02:00
switch ( currentTemp )
{
case 'mail.index' :
2014-09-09 14:08:08 +02:00
this . mail _prev _print ( _action , _senders ) ;
2014-04-17 11:59:08 +02:00
break ;
case 'mail.display' :
this . mail _display _print ( ) ;
}
2014-05-20 17:39:20 +02:00
2014-04-17 11:59:08 +02:00
} ,
2014-09-23 10:42:31 +02:00
2014-09-09 14:08:08 +02:00
/ * *
* Print a mail from compose
* @ param { stirng } _id id of new draft
* /
mail _compose _print : function ( _id )
{
this . egw . open ( _id , 'mail' , 'view' , '&print=' + _id + '&mode=print' ) ;
} ,
2014-09-23 10:42:31 +02:00
2014-09-09 14:08:08 +02:00
/ * *
2014-09-23 10:42:31 +02:00
* Bind special handler on print media .
* - FF and IE have onafterprint event , and as Chrome does not have that event we bind afterprint function to onFocus
2014-09-09 14:08:08 +02:00
* /
print _for _compose : function ( )
{
var afterprint = function ( ) {
2014-12-12 15:21:04 +01:00
egw ( window ) . close ( ) ;
2014-09-09 14:08:08 +02:00
} ;
2014-09-23 10:42:31 +02:00
2014-09-09 14:08:08 +02:00
if ( ! window . onafterprint )
{
2014-09-09 15:55:43 +02:00
// For browsers which does not support onafterprint event, eg. Chrome
setTimeout ( function ( ) {
2014-12-12 15:21:04 +01:00
egw ( window ) . close ( ) ;
2014-09-09 15:55:43 +02:00
} , 2000 ) ;
2014-09-09 14:08:08 +02:00
}
else
{
window . onafterprint = afterprint ;
}
2014-09-23 10:42:31 +02:00
} ,
2014-04-17 11:59:08 +02:00
/ * *
2015-02-12 10:02:56 +01:00
* Prepare display dialog for printing
* copies iframe content to a DIV , as iframe causes
* trouble for multipage printing
2016-03-01 18:00:28 +01:00
* @ param { jQuery object } _iframe mail body iframe
2015-02-12 10:02:56 +01:00
* @ returns { undefined }
2014-04-17 11:59:08 +02:00
* /
2016-03-01 18:00:28 +01:00
mail _prepare _print : function ( _iframe )
2014-04-17 11:59:08 +02:00
{
2016-03-01 18:00:28 +01:00
var $mainIframe = _iframe || jQuery ( '#mail-display_mailDisplayBodySrc' ) ;
2014-11-28 14:51:00 +01:00
var tmpPrintDiv = jQuery ( '#tempPrintDiv' ) ;
2014-12-02 20:18:37 +01:00
2014-11-28 14:51:00 +01:00
if ( tmpPrintDiv . length == 0 && tmpPrintDiv . children ( ) )
2014-04-16 19:16:42 +02:00
{
2014-11-28 14:51:00 +01:00
tmpPrintDiv = jQuery ( document . createElement ( 'div' ) )
2014-04-16 19:16:42 +02:00
. attr ( 'id' , 'tempPrintDiv' )
. addClass ( 'tmpPrintDiv' ) ;
2014-11-28 14:51:00 +01:00
var notAttached = true ;
}
2014-12-02 20:18:37 +01:00
2016-03-01 18:00:28 +01:00
if ( $mainIframe )
2014-11-28 14:51:00 +01:00
{
2017-09-08 15:58:04 +02:00
window . setTimeout ( function ( ) {
tmpPrintDiv [ 0 ] . innerHTML = $mainIframe . contents ( ) . find ( 'body' ) . html ( ) ;
} , 600 ) ;
2014-04-16 19:16:42 +02:00
}
2014-11-28 14:51:00 +01:00
// Attach the element to the DOM after maniupulation
2016-03-01 18:00:28 +01:00
if ( notAttached ) $mainIframe . after ( tmpPrintDiv ) ;
2014-11-28 14:51:00 +01:00
tmpPrintDiv . find ( '#divAppboxHeader' ) . remove ( ) ;
2014-04-16 19:16:42 +02:00
2015-02-12 10:02:56 +01:00
} ,
/ * *
* Print a mail from Display
* /
mail _display _print : function ( )
{
2021-04-21 09:39:10 +02:00
this . egw . message ( this . egw . lang ( 'Printing' ) + ' ...' , 'success' ) ;
2014-12-02 20:18:37 +01:00
2014-11-28 14:51:00 +01:00
// Make sure the print happens after the content is loaded. Seems Firefox and IE can't handle timing for print command correctly
setTimeout ( function ( ) {
egw ( window ) . window . print ( ) ;
2017-09-08 15:58:04 +02:00
} , 1000 ) ;
2014-04-17 11:59:08 +02:00
} ,
2014-05-20 17:39:20 +02:00
2014-04-17 11:59:08 +02:00
/ * *
* Print a mail from list
2014-05-20 17:39:20 +02:00
*
* @ param { Object } _action
* @ param { Object } _elems
*
2014-04-17 11:59:08 +02:00
* /
mail _prev _print : function ( _action , _elems )
{
this . mail _open ( _action , _elems , 'print' ) ;
2014-05-20 10:48:50 +02:00
} ,
2014-05-20 17:39:20 +02:00
2014-05-20 10:48:50 +02:00
/ * *
* Print a mail from list
2014-05-20 17:39:20 +02:00
*
* @ param { egw object } _egw
2014-05-20 10:48:50 +02:00
* @ param { widget object } _widget mail account selectbox
2014-05-20 17:39:20 +02:00
*
2014-05-20 10:48:50 +02:00
* /
vacation _change _account : function ( _egw , _widget )
{
_widget . getInstanceManager ( ) . submit ( ) ;
2014-08-15 13:22:43 +02:00
} ,
2014-08-14 16:44:16 +02:00
/ * *
2015-05-20 17:24:08 +02:00
* OnChange callback for recipients :
* - make them draggable
* - check if we have keys for recipients , if we compose an encrypted mail
2014-08-14 16:44:16 +02:00
* * /
2015-05-26 18:33:35 +02:00
recipients _onchange : function ( )
2014-08-14 16:44:16 +02:00
{
2015-05-20 17:24:08 +02:00
// if we compose an encrypted mail, check if we have keys for new recipient
if ( this . mailvelope _editor )
{
var self = this ;
this . mailvelopeGetCheckRecipients ( ) . catch ( function ( _err )
{
self . egw . message ( _err . message , 'error' ) ;
} ) ;
}
2015-05-26 18:33:35 +02:00
this . set _dragging _dndCompose ( ) ;
} ,
/ * *
* Make recipients draggable
* /
set _dragging _dndCompose : function ( )
{
2014-08-14 16:44:16 +02:00
var zIndex = 100 ;
2015-05-22 17:24:50 +02:00
var dragItems = jQuery ( 'div.ms-sel-item:not(div.ui-draggable)' ) ;
dragItems . each ( function ( i , item ) {
var $isErr = jQuery ( item ) . find ( '.ui-state-error' ) ;
if ( $isErr . length > 0 )
{
delete dragItems . splice ( i , 1 ) ;
}
} ) ;
if ( dragItems . length > 0 )
2014-10-30 12:55:22 +01:00
{
2015-05-22 17:24:50 +02:00
dragItems . draggable ( {
2014-10-30 12:55:22 +01:00
appendTo : 'body' ,
//Performance wise better to not add ui-draggable class to items since we are not using that class
containment : 'document' ,
distance : 0 ,
cursor : 'move' ,
cursorAt : { left : 2 } ,
//cancel dragging on close button to avoid conflict with close action
cancel : '.ms-close-btn' ,
2015-05-19 18:12:28 +02:00
delay : '300' ,
2014-10-30 12:55:22 +01:00
/ * *
* function to act on draggable item on revert ' s event
* @ returns { Boolean } return true
* /
revert : function ( ) {
this . parent ( ) . find ( '.ms-sel-item' ) . css ( 'position' , 'relative' ) ;
2016-06-22 18:39:00 +02:00
var $input = this . parent ( ) . children ( 'input' ) ;
// Make sure input field not getting into second line after revert
$input . width ( $input . width ( ) - 10 ) ;
2014-10-30 12:55:22 +01:00
return true ;
} ,
/ * *
* function to act as draggable starts dragging
*
* @ param { type } event
* @ param { type } ui
* /
start : function ( event , ui )
{
var dragItem = jQuery ( this ) ;
if ( event . ctrlKey || event . metaKey )
{
dragItem . addClass ( 'mailCompose_copyEmail' )
. css ( 'cursor' , 'copy' ) ;
}
dragItem . css ( 'z-index' , zIndex ++ ) ;
dragItem . css ( 'position' , 'absolute' ) ;
} ,
/ * *
*
* @ param { type } event
* @ param { type } ui
* /
create : function ( event , ui )
2014-08-14 16:44:16 +02:00
{
2014-10-30 12:55:22 +01:00
jQuery ( this ) . css ( 'css' , 'move' ) ;
2014-08-14 16:44:16 +02:00
}
2014-10-30 12:55:22 +01:00
} ) . draggable ( 'disable' ) ;
window . setTimeout ( function ( ) {
2014-11-20 16:05:25 +01:00
2015-05-22 17:24:50 +02:00
if ( dragItems && dragItems . data ( ) && typeof dragItems . data ( ) [ 'uiDraggable' ] !== 'undefined' ) dragItems . draggable ( 'enable' ) ;
2014-10-30 12:55:22 +01:00
} , 100 ) ;
}
2014-11-20 16:05:25 +01:00
2014-08-14 16:44:16 +02:00
} ,
2014-08-15 13:22:43 +02:00
2014-12-02 20:18:37 +01:00
/ * *
* Check sharing mode and disable not available options
*
* @ param { DOMNode } _node
* @ param { et2 _widget } _widget
* /
check _sharing _filemode : function ( _node , _widget )
{
2022-11-04 11:43:52 +01:00
if ( ! this . et2 || this . et2 . getArrayMgr ( 'content' ) . getEntry ( 'no_griddata' ) ) return ;
2014-12-02 20:18:37 +01:00
if ( ! _widget ) _widget = this . et2 . getWidgetById ( 'filemode' ) ;
var extended _settings = _widget . get _value ( ) != 'attach' && this . egw . app ( 'stylite' ) ;
2014-12-03 17:25:10 +01:00
this . et2 . getWidgetById ( 'expiration' ) . set _readonly ( ! extended _settings ) ;
this . et2 . getWidgetById ( 'password' ) . set _readonly ( ! extended _settings ) ;
2020-07-30 21:56:57 +02:00
this . et2 . getWidgetById ( 'password' ) . set _suggest ( ! extended _settings ? 0 : 8 ) ;
2014-12-02 20:18:37 +01:00
if ( _widget . get _value ( ) == 'share_rw' && ! this . egw . app ( 'stylite' ) )
{
2015-04-25 09:21:26 +02:00
this . egw . message ( this . egw . lang ( 'Writable sharing requires EPL version!' ) , 'info' ) ;
_widget . set _value ( 'share_ro' ) ;
2014-12-02 20:18:37 +01:00
}
2018-07-12 15:42:07 +02:00
if ( typeof _node != 'undefined' )
{
2022-04-30 12:11:37 +02:00
const mode = _widget . get _value ( ) ;
const mode _label = _widget . select _options . filter ( option => option . value == mode ) [ 0 ] ? . label ;
2022-07-20 22:23:55 +02:00
Et2Dialog . alert ( this . egw . lang ( 'Be aware that all attachments will be sent as %1!' , mode _label ) ,
this . egw . lang ( 'Filemode has been switched to %1' , mode _label ) ,
Et2Dialog . WARNING _MESSAGE ) ;
2022-04-30 12:11:37 +02:00
const content = this . et2 . getArrayMgr ( 'content' ) ;
const attachments = this . et2 . getWidgetById ( 'attachments' ) ;
for ( let i in content . data . attachments )
2018-07-12 15:42:07 +02:00
{
if ( content . data . attachments [ i ] == null )
{
content . data . attachments . splice ( i , 1 ) ;
continue ;
}
content . data . attachments [ i ] [ 'filemode_icon' ] = ! content . data . attachments [ i ] [ 'is_dir' ] &&
2022-04-30 12:11:37 +02:00
( mode == 'share_rw' || mode == 'share_ro' ) ? 'link' : mode ;
2018-07-12 15:42:07 +02:00
}
this . et2 . setArrayMgr ( 'content' , content ) ;
attachments . set _value ( { content : content . data . attachments } ) ;
}
2014-12-12 16:28:53 +01:00
} ,
/ * *
* Write / update compose window title with subject
*
* @ param { DOMNode } _node
* @ param { et2 _widget } _widget
* /
subject2title : function ( _node , _widget )
{
if ( ! _widget ) _widget = this . et2 . getWidgetById ( 'subject' ) ;
if ( _widget && _widget . get _value ( ) )
{
document . title = _widget . get _value ( ) ;
}
2014-12-16 11:26:44 +01:00
} ,
2015-02-12 10:02:56 +01:00
2014-12-16 11:26:44 +01:00
/ * *
* Clear intervals stored in W _INTERVALS which assigned to window
* /
clearIntevals : function ( )
{
for ( var i = 0 ; i < this . W _INTERVALS . length ; i ++ )
{
clearInterval ( this . W _INTERVALS [ i ] ) ;
delete this . W _INTERVALS [ i ] ;
}
2015-01-05 15:28:35 +01:00
} ,
2015-02-12 10:02:56 +01:00
2015-01-05 15:28:35 +01:00
/ * *
* Window title getter function in order to set the window title
2015-02-12 10:02:56 +01:00
*
2016-06-01 16:40:52 +02:00
* @ returns { string | undefined } window title
2015-01-05 15:28:35 +01:00
* /
getWindowTitle : function ( )
{
var widget = { } ;
switch ( this . et2 . _inst . name )
{
case 'mail.display' :
widget = this . et2 . getWidgetById ( 'mail_displaysubject' ) ;
if ( widget ) return widget . options . value ;
break ;
case 'mail.compose' :
widget = this . et2 . getWidgetById ( 'subject' ) ;
if ( widget ) return widget . get _value ( ) ;
break ;
}
2016-06-01 16:40:52 +02:00
return undefined ;
2015-01-07 12:57:34 +01:00
} ,
2015-08-20 09:02:06 +02:00
2015-06-02 13:01:45 +02:00
/ * *
2015-08-20 09:02:06 +02:00
*
2015-06-02 13:01:45 +02:00
* @ returns { undefined }
* /
prepareMailvelopePrint : function ( )
{
var tempPrint = jQuery ( 'div#tempPrintDiv' ) ;
var mailvelopeTopContainer = jQuery ( 'div.mailDisplayContainer' ) ;
2015-06-02 17:26:51 +02:00
var originFrame = jQuery ( '#mail-display_mailDisplayBodySrc' ) ;
2015-06-02 13:01:45 +02:00
var iframe = jQuery ( this . mailvelope _iframe _selector ) ;
2015-08-20 09:02:06 +02:00
2015-06-02 13:01:45 +02:00
if ( tempPrint . length > 0 )
{
2015-06-02 17:26:51 +02:00
// Mailvelope iframe height is approximately equal to the height of encrypted origin message
// we add an arbitary plus pixels to make sure it's covering the full content in print view and
// it is not getting acrollbar in normal view
// @TODO: after Mailvelope plugin provides a hieght value, we can replace the height with an accurate value
iframe . addClass ( 'mailvelopeIframe' ) . height ( originFrame [ 0 ] . contentWindow . document . body . scrollHeight + 400 ) ;
2015-06-02 13:01:45 +02:00
tempPrint . hide ( ) ;
mailvelopeTopContainer . addClass ( 'mailvelopeTopContainer' ) ;
}
} ,
2015-08-20 09:02:06 +02:00
2015-05-20 09:26:15 +02:00
/ * *
* Mailvelope ( clientside PGP ) integration :
* - detect Mailvelope plugin and open "egroupware" keyring ( app _base . mailvelopeAvailable and _mailvelopeOpenKeyring )
* - display and preview of encrypted messages ( mailvelopeDisplay )
* - button to toggle between regular and encrypted mail ( togglePgpEncrypt )
* - compose encrypted messages ( mailvelopeCompose , compose _submitAction )
* - fix autosave and save as draft to store encrypted content ( saveAsDraft )
* - fix inline reply to encrypted message to clientside decrypt message and add signature ( mailvelopeCompose )
* /
2015-05-17 21:03:45 +02:00
/ * *
* Called on load of preview or display iframe , if mailvelope is available
*
2015-05-19 20:56:12 +02:00
* @ param { Keyring } _keyring Mailvelope keyring to use
2015-05-17 21:03:45 +02:00
* @ ToDo signatures
* /
2015-05-19 20:56:12 +02:00
mailvelopeDisplay : function ( _keyring )
2015-05-17 21:03:45 +02:00
{
2023-05-15 14:49:10 +02:00
let self = this ;
let iframe = jQuery ( 'iframe#mail-display_mailDisplayBodySrc,iframe#mail-index_messageIFRAME' ) ;
let armored = iframe . contents ( ) . find ( 'td.td_display > pre' ) . text ( ) . trim ( ) ;
2015-05-17 21:03:45 +02:00
2015-05-20 09:26:15 +02:00
if ( armored == "" || armored . indexOf ( this . begin _pgp _message ) === - 1 ) return ;
2015-05-17 21:03:45 +02:00
2023-05-15 14:49:10 +02:00
let container = iframe . parent ( ) [ 0 ] ;
let container _selector = this . et2 . _inst . name == 'mail.display' ? '.mailDisplayContainer' : ` # ${ container . dom _id } ` ;
let options = {
2015-08-20 09:02:06 +02:00
showExternalContent : this . egw . preference ( 'allowExternalIMGs' ) == 1 // "1", or "0", undefined --> true or false
} ;
// get sender address, so Mailvelope can check signature
2023-05-15 14:49:10 +02:00
let from = this . et2 . _inst . name == 'mail.display' ? this . et2 . getArrayMgr ( 'content' ) . data . from : this . et2 . getWidgetById ( 'additionalfromaddress' ) . value ;
if ( from )
2015-08-20 09:02:06 +02:00
{
2023-05-15 14:49:10 +02:00
options . senderAddress = from [ 0 ] . replace ( /^.*<([^<>]+)>$/ , '$1' ) ;
2015-08-20 09:02:06 +02:00
}
2023-05-15 14:49:10 +02:00
window . mailvelope . createDisplayContainer ( container _selector , armored , _keyring , options ) . then ( function ( )
2015-05-17 21:03:45 +02:00
{
2015-05-19 20:56:12 +02:00
// hide our iframe to give space for mailvelope iframe with encrypted content
iframe . hide ( ) ;
2015-06-02 13:01:45 +02:00
self . prepareMailvelopePrint ( ) ;
2015-05-17 21:03:45 +02:00
} ,
function ( _err )
{
self . egw . message ( _err . message , 'error' ) ;
} ) ;
} ,
/ * *
* Editor object of active compose
*
* @ var { Editor }
* /
mailvelope _editor : undefined ,
/ * *
* Called on compose , if mailvelope is available
2015-05-19 20:56:12 +02:00
*
* @ param { Keyring } _keyring Mailvelope keyring to use
2015-05-17 21:03:45 +02:00
* /
2015-05-19 20:56:12 +02:00
mailvelopeCompose : function ( _keyring )
2015-05-17 21:03:45 +02:00
{
delete this . mailvelope _editor ;
2015-05-19 20:56:12 +02:00
// currently Mailvelope only supports plain-text, to this is unnecessary
var mimeType = this . et2 . getWidgetById ( 'mimeType' ) ;
var is _html = mimeType . get _value ( ) ;
var container = is _html ? '.mailComposeHtmlContainer' : '.mailComposeTextContainer' ;
var editor = this . et2 . getWidgetById ( is _html ? 'mail_htmltext' : 'mail_plaintext' ) ;
2015-05-20 09:26:15 +02:00
var options = { predefinedText : editor . get _value ( ) } ;
// check if we have some sort of reply to an encrypted message
// --> parse header, encrypted mail to quote and signature so Mailvelope understands it
var start _pgp = options . predefinedText . indexOf ( this . begin _pgp _message ) ;
if ( start _pgp != - 1 )
{
var end _pgp = options . predefinedText . indexOf ( this . end _pgp _message ) ;
if ( end _pgp != - 1 )
{
options = {
quotedMailHeader : options . predefinedText . slice ( 0 , start _pgp ) . replace ( /> /mg , '' ) . trim ( ) + "\n" ,
quotedMail : options . predefinedText . slice ( start _pgp , end _pgp + this . end _pgp _message . length + 1 ) . replace ( /> /mg , '' ) ,
quotedMailIndent : start _pgp != 0 ,
2015-08-20 09:02:06 +02:00
predefinedText : options . predefinedText . slice ( end _pgp + this . end _pgp _message . length + 1 ) . replace ( /^> \s*/m , '' ) ,
signMsg : true // for now (no UI) always sign, when we encrypt
2015-05-20 09:26:15 +02:00
} ;
// set encrypted checkbox, if not already set
2015-05-20 17:18:00 +02:00
var composeToolbar = this . et2 . getWidgetById ( 'composeToolbar' ) ;
2015-05-26 17:25:54 +02:00
if ( ! composeToolbar . checkbox ( 'pgp' ) )
2015-05-20 09:26:15 +02:00
{
2015-05-20 17:18:00 +02:00
composeToolbar . checkbox ( 'pgp' , true ) ;
2015-05-20 09:26:15 +02:00
}
}
}
2015-05-19 20:56:12 +02:00
var self = this ;
2015-05-20 09:26:15 +02:00
mailvelope . createEditorContainer ( container , _keyring , options ) . then ( function ( _editor )
2015-05-19 20:56:12 +02:00
{
self . mailvelope _editor = _editor ;
editor . set _disabled ( true ) ;
mimeType . set _readonly ( true ) ;
2015-05-17 21:03:45 +02:00
} ,
function ( _err )
{
2015-05-19 20:56:12 +02:00
self . egw . message ( _err . message , 'error' ) ;
2015-05-17 21:03:45 +02:00
} ) ;
} ,
2015-05-19 20:56:12 +02:00
/ * *
* Switch sending PGP encrypted mail on and off
*
* @ param { object } _action toolbar action
* /
togglePgpEncrypt : function ( _action )
{
2015-05-20 17:24:08 +02:00
var self = this ;
2015-05-19 20:56:12 +02:00
if ( _action . checked )
{
if ( typeof mailvelope == 'undefined' )
{
2015-09-15 18:42:52 +02:00
this . mailvelopeInstallationOffer ( ) ;
2015-05-20 17:24:08 +02:00
// switch encrypt button off again
this . et2 . getWidgetById ( 'composeToolbar' ) . _actionManager . getActionById ( 'pgp' ) . set _checked ( false ) ;
jQuery ( 'button#composeToolbar-pgp' ) . toggleClass ( 'toolbar_toggled' ) ;
2015-05-19 20:56:12 +02:00
return ;
}
2015-05-20 17:24:08 +02:00
// check if we have keys for all recipents, before switching
this . mailvelopeGetCheckRecipients ( ) . then ( function ( _recipients )
2015-05-19 20:56:12 +02:00
{
2015-05-20 17:24:08 +02:00
var mimeType = self . et2 . getWidgetById ( 'mimeType' ) ;
// currently Mailvelope only supports plain-text, switch to it if necessary
if ( mimeType . get _value ( ) )
{
mimeType . set _value ( false ) ;
self . et2 . _inst . submit ( ) ;
return ; // ToDo: do that without reload
}
2015-05-26 18:19:28 +02:00
self . mailvelopeOpenKeyring ( ) . then ( function ( _keyring )
{
self . mailvelopeCompose ( _keyring ) ;
} ) ;
2015-05-20 17:24:08 +02:00
} )
. catch ( function ( _err )
{
self . egw . message ( _err . message , 'error' ) ;
self . et2 . getWidgetById ( 'composeToolbar' ) . _actionManager . getActionById ( 'pgp' ) . set _checked ( false ) ;
jQuery ( 'button#composeToolbar-pgp' ) . toggleClass ( 'toolbar_toggled' ) ;
return ;
} ) ;
2015-05-19 20:56:12 +02:00
}
else
{
2015-05-20 09:26:15 +02:00
// switch Mailvelop off again, but warn user he will loose his content
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( function ( _button _id )
2015-05-20 09:26:15 +02:00
{
2022-07-20 22:23:55 +02:00
if ( _button _id == Et2Dialog . YES _BUTTON )
{
self . et2 . getWidgetById ( 'mimeType' ) . set _readonly ( false ) ;
self . et2 . getWidgetById ( 'mail_plaintext' ) . set _disabled ( false ) ;
jQuery ( self . mailvelope _iframe _selector ) . remove ( ) ;
}
else
{
self . et2 . getWidgetById ( 'composeToolbar' ) . checkbox ( 'pgp' , true ) ;
}
} ,
this . egw . lang ( 'You will loose current message body, unless you save it to your clipboard!' ) ,
this . egw . lang ( 'Switch off encryption?' ) ,
{ } , Et2Dialog . BUTTONS _YES _NO , Et2Dialog . WARNING _MESSAGE , undefined , this . egw ) ;
2015-05-19 20:56:12 +02:00
}
} ,
2015-05-20 17:24:08 +02:00
/ * *
* Check if we have a key for all recipients
*
* @ returns { Promise . < Array , Error > } Array of recipients or Error with recipients without key
* /
mailvelopeGetCheckRecipients : function ( )
{
// collect all recipients
var recipients = this . et2 . getWidgetById ( 'to' ) . get _value ( ) ;
2015-05-28 16:40:33 +02:00
recipients = recipients . concat ( this . et2 . getWidgetById ( 'cc' ) . get _value ( ) ) ;
recipients = recipients . concat ( this . et2 . getWidgetById ( 'bcc' ) . get _value ( ) ) ;
2015-05-20 17:24:08 +02:00
return this . _super . call ( this , recipients ) ;
} ,
2015-01-07 12:57:34 +01:00
/ * *
* Set the relevant widget to toolbar actions and submit
2015-05-20 09:26:15 +02:00
*
2016-08-18 17:30:44 +02:00
* @ param { object | boolean } _action toolbar action or boolean value to stop extra call on
* compose _integrated _submit
2015-01-07 12:57:34 +01:00
* /
compose _submitAction : function ( _action )
{
2016-08-18 17:30:44 +02:00
if ( this . compose _integrate _submit ( ) && _action ) return false ;
2015-05-17 21:03:45 +02:00
if ( this . mailvelope _editor )
{
var self = this ;
2015-05-20 17:24:08 +02:00
this . mailvelopeGetCheckRecipients ( ) . then ( function ( _recipients )
{
return self . mailvelope _editor . encrypt ( _recipients ) ;
} ) . then ( function ( _armored )
2015-05-17 21:03:45 +02:00
{
self . et2 . getWidgetById ( 'mimeType' ) . set _value ( false ) ;
self . et2 . getWidgetById ( 'mail_plaintext' ) . set _disabled ( false ) ;
self . et2 . getWidgetById ( 'mail_plaintext' ) . set _value ( _armored ) ;
2018-02-05 18:56:23 +01:00
self . et2 . _inst . submit ( ) ;
2015-05-20 17:24:08 +02:00
} ) . catch ( function ( _err )
2015-05-17 21:03:45 +02:00
{
self . egw . message ( _err . message , 'error' ) ;
} ) ;
return false ;
}
2018-10-04 17:22:15 +02:00
this . et2 . _inst . submit ( null , 'Please wait while sending your mail' ) ;
2015-01-13 16:52:00 +01:00
} ,
2015-02-12 10:02:56 +01:00
2016-08-18 17:30:44 +02:00
/ * *
* This function runs before client submit ( send ) mail to server
* and takes care of mail integration modules to popup entry selection
* dialog to give user a choice to which entry of selected app the compose
* should be integereated .
2016-09-19 16:44:24 +02:00
* @ param { int | boolean } _integIndex
2016-10-08 14:32:58 +02:00
*
2016-08-18 17:30:44 +02:00
* @ returns { Boolean } return true if to _tracker is checked otherwise false
* /
compose _integrate _submit : function ( _integIndex )
{
if ( _integIndex == false ) return false ;
var index = _integIndex || 0 ;
var integApps = [ 'to_tracker' , 'to_infolog' , 'to_calendar' ] ;
var subject = this . et2 . getWidgetById ( 'subject' ) ;
var toolbar = this . et2 . getWidgetById ( 'composeToolbar' ) ;
var to _integrate _ids = this . et2 . getWidgetById ( 'to_integrate_ids' ) ;
var integWidget = { } ;
var self = this ;
integWidget = this . et2 . getWidgetById ( integApps [ index ] ) ;
if ( toolbar . options . actions [ integApps [ index ] ] &&
typeof toolbar . options . actions [ integApps [ index ] ] [ 'mail_import' ] != 'undefined' &&
typeof toolbar . options . actions [ integApps [ index ] ] [ 'mail_import' ] [ 'app_entry_method' ] != 'unefined' )
{
var mail _import _hook = toolbar . options . actions [ integApps [ index ] ] [ 'mail_import' ] [ 'app_entry_method' ] ;
if ( integWidget . get _value ( ) == 'on' )
{
2017-11-22 18:10:46 +01:00
var title = egw . lang ( 'Select' ) + ' ' + egw . lang ( integApps [ index ] ) + ' ' + ( egw . link _get _registry ( integApps [ index ] , 'entry' ) ? egw . link _get _registry ( integApps [ index ] , 'entry' ) : egw . lang ( 'entry' ) ) ;
this . integrate _checkAppEntry ( title , integApps [ index ] . substr ( 3 ) , subject . get _value ( ) , '' , mail _import _hook , function ( args ) {
2023-02-14 19:46:42 +01:00
var oldValue = to _integrate _ids . get _value ( ) || [ ] ;
to _integrate _ids . set _value ( [ integApps [ index ] + ":" + args . entryid , ... oldValue ] ) ;
index = index < integApps . length ? ++ index : false ;
2016-08-18 17:30:44 +02:00
self . compose _integrate _submit ( index ) ;
} ) ;
return true ;
}
}
2021-04-27 11:51:16 +02:00
// the to_tracker action might not be presented because lack of app permissions
else if ( integApps [ index ] == "to_tracker" && ! toolbar . options . actions [ integApps [ index ] ] )
{
return false ;
}
2016-08-18 17:30:44 +02:00
else if ( index < integApps . length )
{
this . compose _integrate _submit ( ++ index ) ;
}
else
{
this . compose _submitAction ( false ) ;
}
2022-05-23 19:36:04 +02:00
// apply default font and -size before submitting to server for sending
this . et2 ? . getWidgetById ( 'mail_htmltext' ) ? . applyDefaultFont ( ) ;
2016-08-18 17:30:44 +02:00
return false ;
} ,
2015-01-13 16:52:00 +01:00
/ * *
* Set the selected checkbox action
2015-02-12 10:02:56 +01:00
*
2015-01-13 16:52:00 +01:00
* @ param { type } _action selected toolbar action with checkbox
* @ returns { undefined }
* /
compose _setToggle : function ( _action )
{
var widget = this . et2 . getWidgetById ( _action . id ) ;
if ( widget && typeof _action . checkbox != 'undefined' && _action . checkbox )
2015-01-07 12:57:34 +01:00
{
2015-01-13 16:52:00 +01:00
widget . set _value ( _action . checked ? "on" : "off" ) ;
2015-01-07 12:57:34 +01:00
}
} ,
2015-02-12 10:02:56 +01:00
2015-01-13 13:14:41 +01:00
/ * *
* Set the selected priority value
* @ param { type } _action selected action
* @ returns { undefined }
* /
compose _priorityChange : function ( _action )
{
var widget = this . et2 . getWidgetById ( 'priority' ) ;
if ( widget )
{
widget . set _value ( _action . id ) ;
}
} ,
2015-02-12 10:02:56 +01:00
2015-01-07 12:57:34 +01:00
/ * *
* Triger relative widget via its toolbar identical action
* @ param { type } _action toolbar action
* /
compose _triggerWidget : function ( _action )
{
var widget = this . et2 . getWidgetById ( _action . id ) ;
if ( widget )
{
switch ( widget . id )
{
case 'uploadForCompose' :
document . getElementById ( 'mail-compose_uploadForCompose' ) . click ( ) ;
break ;
default :
widget . click ( ) ;
}
}
} ,
2015-02-12 10:02:56 +01:00
2015-01-08 18:06:56 +01:00
/ * *
* Save drafted compose as eml file into VFS
* @ param { type } _action action
* /
compose _saveDraft2fm : function ( _action )
{
var content = this . et2 . getArrayMgr ( 'content' ) . data ;
var subject = this . et2 . getWidgetById ( 'subject' ) ;
var elem = { 0 : { id : "" , subject : "" } } ;
2017-10-12 15:22:41 +02:00
var self = this ;
2015-01-08 18:06:56 +01:00
if ( typeof content != 'undefined' && content . lastDrafted && subject )
{
elem [ 0 ] . id = content . lastDrafted ;
elem [ 0 ] . subject = subject . get _value ( ) ;
this . mail _save2fm ( _action , elem ) ;
}
2017-10-12 15:22:41 +02:00
else // need to save as draft first
2015-01-08 18:06:56 +01:00
{
2017-10-12 15:22:41 +02:00
this . saveAsDraft ( null , 'autosaving' ) . then ( function ( ) {
self . compose _saveDraft2fm ( _action ) ;
} , function ( ) {
2022-07-20 22:23:55 +02:00
Et2Dialog . alert ( 'You need to save the message as draft first before to be able to save it into VFS' , 'Save to filemanager' , 'info' ) ;
2017-10-12 15:22:41 +02:00
} ) ;
2015-01-08 18:06:56 +01:00
}
2015-08-10 17:45:22 +02:00
} ,
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
* Folder Management , opens the folder magnt . dialog
* with the selected acc _id from index tree
2015-08-20 09:02:06 +02:00
*
2015-08-10 17:45:22 +02:00
* @ param { egw action object } _action actions
* @ param { object } _senders selected node
* /
folderManagement : function ( _action , _senders )
{
var acc _id = parseInt ( _senders [ 0 ] . id ) ;
2022-08-31 15:37:11 +02:00
this . egw . open _link ( 'mail.mail_ui.folderManagement&acc_id=' + acc _id , '_blank' , '720x580' ) ;
2015-08-10 17:45:22 +02:00
} ,
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
* Show ajax - loader when the autoloading get started
2015-08-20 09:02:06 +02:00
*
2015-08-10 17:45:22 +02:00
* @ param { type } _id item id
* @ param { type } _widget tree widget
* @ returns { Boolean }
* /
folderMgmt _autoloadingStart : function ( _id , _widget )
{
return this . subscription _autoloadingStart ( _id , _widget ) ;
} ,
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
* Revert back the icon after autoloading is finished
2015-08-20 09:02:06 +02:00
* @ param { type } _id item id
* @ param { type } _widget tree widget
2015-08-10 17:45:22 +02:00
* @ returns { Boolean }
* /
folderMgmt _autoloadingEnd : function ( _id , _widget )
{
return true ;
} ,
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
2015-08-20 09:02:06 +02:00
*
2015-08-10 17:45:22 +02:00
* @ param { type } _ids
* @ param { type } _widget
* @ returns { undefined }
* /
folderMgmt _onSelect : function ( _ids , _widget )
{
// Flag to reset selected items
var resetSelection = false ;
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
var self = this ;
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
* helper function to multiselect range of nodes in same level
2015-08-20 09:02:06 +02:00
*
2015-08-10 17:45:22 +02:00
* @ param { string } _a start node id
* @ param { string } _b end node id
* @ param { string } _branch totall node ids in the level
* /
var rangeSelector = function ( _a , _b , _branch )
{
var branchItems = _branch . split ( _widget . input . dlmtr ) ;
var _aIndex = _widget . input . getIndexById ( _a ) ;
var _bIndex = _widget . input . getIndexById ( _b ) ;
if ( _bIndex < _aIndex )
{
var tmpIndex = _aIndex ;
_aIndex = _bIndex ;
_bIndex = tmpIndex ;
}
for ( var i = _aIndex ; i <= _bIndex ; i ++ )
{
self . folderMgmt _setCheckbox ( _widget , branchItems [ i ] , ! _widget . input . isItemChecked ( branchItems [ i ] ) ) ;
}
} ;
2015-08-20 09:02:06 +02:00
2015-08-11 18:28:59 +02:00
// extract items ids
var itemIds = _ids . split ( _widget . input . dlmtr ) ;
if ( itemIds . length == 2 ) // there's a range selected
2015-08-10 17:45:22 +02:00
{
2015-08-11 18:28:59 +02:00
var branch = _widget . input . getSubItems ( _widget . input . getParentId ( itemIds [ 0 ] ) ) ;
// Set range of selected/unselected
rangeSelector ( itemIds [ 0 ] , itemIds [ 1 ] , branch ) ;
}
else if ( itemIds . length != 1 )
{
resetSelection = true ;
2015-08-10 17:45:22 +02:00
}
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
if ( resetSelection )
{
_widget . input . _unselectItems ( ) ;
}
} ,
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
* Set enable / disable checkbox
2015-08-20 09:02:06 +02:00
*
2015-08-10 17:45:22 +02:00
* @ param { object } _widget tree widget
* @ param { string } _itemId item tree id
* @ param { boolean } _stat - status to be set on checkbox true / false
* /
folderMgmt _setCheckbox : function ( _widget , _itemId , _stat )
{
if ( _widget )
{
_widget . input . setCheck ( _itemId , _stat ) ;
_widget . input . setSubChecked ( _itemId , _stat ) ;
}
} ,
2015-08-20 09:02:06 +02:00
2015-08-10 17:45:22 +02:00
/ * *
2015-08-20 09:02:06 +02:00
*
2015-08-10 17:45:22 +02:00
* @ param { type } _id
* @ param { type } _widget
* @ TODO : Implement onCheck handler in order to select or deselect subItems
* of a checked parent node
* /
folderMgmt _onCheck : function ( _id , _widget )
{
2015-08-13 19:34:12 +02:00
var selected = _widget . input . getAllChecked ( ) ;
if ( selected && selected . split ( _widget . input . dlmtr ) . length > 5 )
{
2021-04-21 09:39:10 +02:00
egw . message ( egw . lang ( 'If you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status.' ) , 'success' ) ;
2015-08-13 19:34:12 +02:00
}
2015-08-11 18:28:59 +02:00
} ,
2015-08-20 09:02:06 +02:00
2015-08-11 18:28:59 +02:00
/ * *
* Detele button handler
* triggers longTask dialog and send delete operation url
2015-08-20 09:02:06 +02:00
*
2015-08-11 18:28:59 +02:00
* /
2015-08-13 12:29:51 +02:00
folderMgmt _deleteBtn : function ( )
2015-08-11 18:28:59 +02:00
{
2015-08-13 12:29:51 +02:00
var tree = etemplate2 . getByApplication ( 'mail' ) [ 0 ] . widgetContainer . getWidgetById ( 'tree' ) ;
2015-08-11 18:28:59 +02:00
var menuaction = 'mail.mail_ui.ajax_folderMgmt_delete' ;
2015-08-20 09:02:06 +02:00
2015-08-13 13:54:50 +02:00
var callbackDialog = function ( _btn )
2015-08-11 18:28:59 +02:00
{
2016-02-05 12:47:54 +01:00
egw . appName = 'mail' ;
2022-07-20 22:23:55 +02:00
if ( _btn === Et2Dialog . YES _BUTTON )
2015-08-11 18:28:59 +02:00
{
2015-08-13 13:54:50 +02:00
if ( tree )
{
var selFolders = tree . input . getAllChecked ( ) ;
if ( selFolders )
2015-08-11 18:28:59 +02:00
{
2015-08-13 13:54:50 +02:00
var selFldArr = selFolders . split ( tree . input . dlmtr ) ;
2015-08-13 19:34:12 +02:00
var msg = egw . lang ( 'Deleting %1 folders in progress ...' , selFldArr . length ) ;
2022-07-20 22:23:55 +02:00
Et2Dialog . long _task ( function ( _val , _resp )
{
2015-08-13 13:54:50 +02:00
console . log ( _val , _resp ) ;
if ( _val && _resp . type !== 'error' )
{
var stat = [ ] ;
var folderName = '' ;
2022-07-20 22:23:55 +02:00
for ( var i = 0 ; i < selFldArr . length ; i ++ )
2015-08-13 13:54:50 +02:00
{
folderName = selFldArr [ i ] . split ( '::' ) ;
stat [ selFldArr [ i ] ] = folderName [ 1 ] ;
}
// delete the item from index folderTree
egw . window . app . mail . mail _removeLeaf ( stat ) ;
2015-08-13 19:34:12 +02:00
}
else
{
2015-08-13 13:54:50 +02:00
// submit
etemplate2 . getByApplication ( 'mail' ) [ 0 ] . widgetContainer . _inst . submit ( ) ;
}
2016-02-05 12:47:54 +01:00
} , msg , egw . lang ( 'Deleting folders' ) , menuaction , selFldArr , 'mail' ) ;
2015-08-13 13:54:50 +02:00
return true ;
2015-08-11 18:28:59 +02:00
}
2015-08-13 13:54:50 +02:00
}
2015-08-11 18:28:59 +02:00
}
2015-08-13 13:54:50 +02:00
} ;
2022-07-20 22:23:55 +02:00
Et2Dialog . show _dialog ( callbackDialog , this . egw . lang ( 'Are you sure you want to delete all selected folders?' ) , this . egw . lang ( 'Delete folder' ) , { } ,
Et2Dialog . BUTTON _YES _NO , Et2Dialog . WARNING _MESSAGE , undefined , egw ) ;
2016-03-01 18:00:28 +01:00
} ,
2016-03-29 12:13:32 +02:00
2017-05-30 16:19:37 +02:00
/ * *
2017-05-31 17:38:09 +02:00
* Spam Actions handler
2017-05-30 16:19:37 +02:00
*
* @ param { object } _action egw action
2017-07-04 13:25:38 +02:00
* @ param { object } _senders nm row
2017-05-30 16:19:37 +02:00
* /
2017-06-12 15:25:21 +02:00
spam _actions : function ( _action , _senders )
2017-05-30 16:19:37 +02:00
{
2017-06-12 15:25:21 +02:00
var id , fromaddress , domain , email = '' ;
var data = { } ;
var items = [ ] ;
2018-01-03 17:30:03 +01:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
2017-06-12 15:25:21 +02:00
// called action for a single row from toolbar
if ( _senders . length == 0 )
2017-06-02 17:17:15 +02:00
{
2017-06-22 10:09:15 +02:00
_senders = [ { id : nm . getSelection ( ) . ids [ 0 ] } ] ;
2017-06-02 17:17:15 +02:00
}
2017-06-12 15:25:21 +02:00
for ( var i in _senders )
2017-06-02 17:17:15 +02:00
{
2017-06-12 15:25:21 +02:00
id = _senders [ i ] . id ;
data = egw . dataGetUIDdata ( id ) ;
fromaddress = data . data . fromaddress . match ( /<([^\'\" <>]+)>$/ ) ;
email = ( fromaddress && fromaddress [ 1 ] ) ? fromaddress [ 1 ] : data . data . fromaddress ;
domain = '@' + email . split ( '@' ) [ 1 ] ;
items [ i ] = {
2017-06-02 17:17:15 +02:00
'acc_id' : id . split ( '::' ) [ 2 ] ,
'row_id' : data . data . row _id ,
'uid' : data . data . uid ,
'sender' : _action . id . match ( /domain/ ) ? domain : email
2017-06-12 15:25:21 +02:00
} ;
}
this . egw . json ( 'mail.mail_ui.ajax_spamAction' , [
_action . id , items
] , function ( _data ) {
if ( _data [ 1 ] && _data [ 1 ] . length > 0 )
{
egw . refresh ( _data [ 0 ] , 'mail' , _data [ 1 ] , 'delete' ) ;
2018-01-03 17:30:03 +01:00
nm . controller . _selectionMgr . resetSelection ( ) ;
2017-06-12 15:25:21 +02:00
}
else
{
egw . message ( _data [ 0 ] ) ;
2017-06-02 17:17:15 +02:00
}
2017-06-12 15:25:21 +02:00
} ) . sendRequest ( true ) ;
2017-05-30 16:19:37 +02:00
} ,
2017-06-02 17:17:15 +02:00
spamTitan _setActionTitle : function ( _action , _sender )
{
2017-06-13 15:54:52 +02:00
var id = _sender [ 0 ] . id != 'nm' ? _sender [ 0 ] . id : _sender [ 1 ] . id ;
2018-05-17 17:18:29 +02:00
var email = this . egw . lang ( 'emails' ) ;
var domain = this . egw . lang ( 'domains' ) ;
2017-06-02 17:17:15 +02:00
var data = egw . dataGetUIDdata ( id ) ;
2018-05-17 17:18:29 +02:00
if ( _sender . length === 1 && data && data . data && data . data . fromaddress )
{
var fromaddress = data . data . fromaddress . match ( /<([^\'\" <>]+)>$/ ) ;
email = ( fromaddress && fromaddress [ 1 ] ) ? fromaddress [ 1 ] : data . data . fromaddress ;
domain = email . split ( '@' ) [ 1 ] ;
}
2017-06-02 17:17:15 +02:00
switch ( _action . id )
{
case 'whitelist_email_add' :
_action . set _caption ( this . egw . lang ( 'Add "%1" into whitelisted emails' , email ) ) ;
break ;
case 'whitelist_email_remove' :
_action . set _caption ( this . egw . lang ( 'Remove "%1" from whiltelisted emails' , email ) ) ;
break ;
case 'whitelist_domain_add' :
_action . set _caption ( this . egw . lang ( 'Add "%1" into whiltelisted domains' , domain ) ) ;
break ;
case 'whitelist_domain_remove' :
_action . set _caption ( this . egw . lang ( 'Remove "%1" from whiltelisted domains' , domain ) ) ;
break ;
case 'blacklist_email_add' :
_action . set _caption ( this . egw . lang ( 'Add "%1" into blacklisted emails' , email ) ) ;
break ;
case 'blacklist_email_remove' :
_action . set _caption ( this . egw . lang ( 'Remove "%1" from blacklisted emails' , email ) ) ;
break ;
case 'blacklist_domain_add' :
_action . set _caption ( this . egw . lang ( 'Add "%1" into blacklisted domains' , domain ) ) ;
break ;
case 'blacklist_domain_remove' :
_action . set _caption ( this . egw . lang ( 'Remove "%1" from blacklisted domains' , domain ) ) ;
break ;
}
return true ;
} ,
2016-03-01 18:00:28 +01:00
/ * *
* Implement mobile view
2016-03-29 12:13:32 +02:00
*
2016-03-01 18:00:28 +01:00
* @ param { type } _action
* @ param { type } _sender
* /
mobileView : function ( _action , _sender )
{
2016-03-03 15:10:08 +01:00
// row id in nm
2016-03-01 18:00:28 +01:00
var id = _sender [ 0 ] . id ;
2016-03-29 12:13:32 +02:00
2016-03-03 15:10:08 +01:00
var defaultActions = {
actions : [ 'delete' , 'forward' , 'reply' , 'flagged' ] , // default actions to display
check : function ( _action ) {
for ( var i = 0 ; i <= this . actions . length ; i ++ )
{
if ( _action == this . actions [ i ] ) return true ;
}
return false ;
}
} ;
2016-03-29 12:13:32 +02:00
2016-03-01 18:00:28 +01:00
var content = { } ;
2016-03-03 15:10:08 +01:00
var self = this ;
2016-03-29 12:13:32 +02:00
2016-03-01 18:00:28 +01:00
if ( id ) {
content = egw . dataGetUIDdata ( id ) ;
2016-03-03 15:10:08 +01:00
content . data [ 'toolbar' ] = this . et2 . getArrayMgr ( 'sel_options' ) . getEntry ( 'toolbar' ) ;
2023-08-10 17:47:36 +02:00
if ( content . data . toaddress || content . data . fromaddress )
{
content . data . additionaltoaddress = ( content . data . additionaltoaddress ? ? [ ] ) . concat ( content . data . toaddress ) ;
content . data . additionaltoaddress = content . data . additionaltoaddress . filter ( ( i , item ) => {
return content . data . additionaltoaddress . indexOf ( i ) == item
} ) ;
content . data . additionalfromaddress = ( content . data . additionalfromaddress ? ? [ ] ) . concat ( content . data . fromaddress ) ;
content . data . additionalfromaddress = content . data . additionalfromaddress . filter ( ( i , item ) => {
return content . data . additionalfromaddress . indexOf ( i ) == item
} ) ;
}
2016-03-03 15:10:08 +01:00
// Set default actions
for ( var action in content . data [ 'toolbar' ] )
{
content . data . toolbar [ action ] [ 'toolbarDefault' ] = defaultActions . check ( action ) ;
}
// update local storage with added toolbar actions
egw . dataStoreUID ( id , content . data ) ;
2016-03-01 18:00:28 +01:00
}
2016-03-29 12:13:32 +02:00
2016-03-03 15:10:08 +01:00
this . viewEntry ( _action , _sender , true , function ( etemplate ) {
2016-03-01 18:00:28 +01:00
// et2 object in view
var et2 = etemplate . widgetContainer ;
// iframe to load message
var iframe = et2 . getWidgetById ( 'iframe' ) ;
// toolbar widget
var toolbar = et2 . getWidgetById ( 'toolbar' ) ;
// attachments details title DOM node
var $attachment = jQuery ( '.attachments span.et2_details_title' ) ;
// details DOM
var $details = jQuery ( '.et2_details.details' ) ;
// Content
var content = et2 . getArrayMgr ( 'content' ) . data ;
2016-03-29 12:13:32 +02:00
2016-03-03 15:10:08 +01:00
// set the current selected row
et2 . mail _currentlyFocussed = id ;
2016-03-29 12:13:32 +02:00
2016-03-01 18:00:28 +01:00
if ( content . attachmentsBlock . length > 0 && content . attachmentsBlock [ 0 ] . filename )
{
2017-01-10 17:30:00 +01:00
$attachment . text ( self . egw . lang ( '%1 attachments' , content . attachmentsBlock . length ) ) ;
2016-03-01 18:00:28 +01:00
}
else
{
// disable attachments area if there's no attachments
$attachment . parent ( ) . hide ( ) ;
}
// disable the detials if there's no details
2016-05-24 15:25:55 +02:00
if ( ! content . ccaddress && ! content . additionaltoaddress ) $details . hide ( ) ;
2016-03-29 12:13:32 +02:00
2016-03-01 18:00:28 +01:00
toolbar . set _actions ( content . toolbar ) ;
2016-05-24 15:25:55 +02:00
var toaddressdetails = self . et2 _view . widgetContainer . getWidgetById ( 'toaddressdetails' ) ;
if ( toaddressdetails && content . additionaltoaddress )
{
toaddressdetails . set _value ( '... ' + content . additionaltoaddress . length + egw . lang ( ' more' ) ) ;
jQuery ( toaddressdetails . getDOMNode ( ) ) . off ( ) . on ( 'click' , function ( ) {
$details . find ( '.et2_details_toggle' ) . click ( ) ;
} ) ;
}
2016-05-24 12:39:06 +02:00
2016-03-01 18:00:28 +01:00
// Request email body from server
iframe . set _src ( egw . link ( '/index.php' , { menuaction : 'mail.mail_ui.loadEmailBody' , _messageID : id } ) ) ;
jQuery ( iframe . getDOMNode ( ) ) . on ( 'load' , function ( ) {
2016-04-20 11:54:33 +02:00
if ( jQuery ( this . contentWindow . document . body ) . find ( '#calendar-meeting' ) . length > 0 )
{
var frame = this ;
jQuery ( this ) . show ( ) ;
// calendar meeting mails still need to be in iframe, therefore, we calculate the height
// and set the iframe with a fixed height to be able to see all content without getting
// scrollbar becuase of scrolling issue in iframe
window . setTimeout ( function ( ) { jQuery ( frame ) . height ( frame . contentWindow . document . body . scrollHeight ) ; } , 500 ) ;
}
else
{
2017-07-04 13:25:38 +02:00
self . resolveExternalImages ( this . contentWindow . document ) ;
2016-04-20 11:54:33 +02:00
// Use prepare print function to copy iframe content into div
// as we don't want to show content in iframe (scrolling problem).
2017-09-14 11:28:27 +02:00
if ( jQuery ( this . contentWindow . document . body ) . find ( '#smimePasswordRequest' ) . length == 0 )
{
iframe . set _disabled ( true ) ;
self . mail _prepare _print ( jQuery ( this ) ) ;
}
2016-04-20 11:54:33 +02:00
}
2016-03-01 18:00:28 +01:00
} ) ;
} ) ;
2017-01-19 18:52:28 +01:00
} ,
/ * *
* Open smime certificate
2017-01-23 09:47:45 +01:00
*
2017-01-19 18:52:28 +01:00
* @ param { type } egw
* @ param { type } widget
* @ returns { undefined }
* /
smimeSigBtn : function ( egw , widget )
{
2017-01-23 09:47:45 +01:00
var url = '' ;
if ( this . mail _isMainWindow )
{
var content = this . egw . dataGetUIDdata ( this . mail _currentlyFocussed ) ;
url = content . data . smimeSigUrl ;
}
else
{
url = this . et2 . getArrayMgr ( "content" ) . getEntry ( 'smimeSigUrl' ) ;
}
2017-01-19 18:52:28 +01:00
window . egw . openPopup ( url , '700' , '400' ) ;
2017-02-15 12:23:27 +01:00
} ,
/ * *
* smime password dialog
2017-07-10 12:57:14 +02:00
*
* @ param { string } _msg message
* /
smimePassDialog : function ( _msg )
2017-02-15 12:23:27 +01:00
{
var self = this ;
2017-08-28 16:14:56 +02:00
var pass _exp = egw . preference ( 'smime_pass_exp' , 'mail' ) ;
2017-02-15 12:23:27 +01:00
et2 _createWidget ( "dialog" ,
{
callback : function ( _button _id , _value )
{
2017-07-10 12:57:14 +02:00
if ( _button _id == 'send' && _value )
2017-02-15 12:23:27 +01:00
{
var pass = self . et2 . getWidgetById ( 'smime_passphrase' ) ;
pass . set _value ( _value . value ) ;
2017-07-10 12:57:14 +02:00
var toolbar = self . et2 . getWidgetById ( 'composeToolbar' ) ;
toolbar . value = 'send' ;
2017-08-28 16:14:56 +02:00
egw . set _preference ( 'mail' , 'smime_pass_exp' , _value . pass _exp ) ;
2017-07-10 12:57:14 +02:00
self . compose _submitAction ( false ) ;
2017-02-15 12:23:27 +01:00
}
} ,
title : egw . lang ( 'Request for passphrase' ) ,
2017-07-10 12:57:14 +02:00
buttons : [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Send" ) , id : "send" , "class" : "ui-priority-primary" , "default" : true } ,
{ label : this . egw . lang ( "Cancel" ) , id : "cancel" }
2017-07-10 12:57:14 +02:00
] ,
2017-02-15 12:23:27 +01:00
value : {
content : {
value : '' ,
2017-08-28 16:14:56 +02:00
message : _msg ,
'exp_min' : pass _exp
2017-02-15 12:23:27 +01:00
} } ,
template : egw . webserverUrl + '/api/templates/default/password.xet' ,
resizable : false
} , et2 _dialog . _create _parent ( 'mail' ) ) ;
2017-07-12 18:40:56 +02:00
} ,
2017-09-13 18:17:32 +02:00
/ * *
* set attachments of smime message for mobile view
* @ param { type } _attachments
* /
set _smimeAttachmentsMobile : function ( _attachments )
{
var attachmentsBlock = this . et2 _view . widgetContainer . getWidgetById ( 'attachmentsBlock' ) ;
var $attachment = jQuery ( '.et2_details.attachments' ) ;
if ( attachmentsBlock && _attachments . length > 0 )
{
attachmentsBlock . set _value ( { content : _attachments } ) ;
$attachment . show ( ) ;
}
} ,
2017-07-12 18:40:56 +02:00
/ * *
* Set attachments of smime message
*
* @ param { object } _attachments
* /
set _smimeAttachments : function ( _attachments )
{
2017-09-13 18:17:32 +02:00
if ( egwIsMobile ( ) )
{
this . set _smimeAttachmentsMobile ( _attachments ) ;
return ;
}
2023-03-23 12:08:23 +01:00
let data = { } ;
let selected = [ ] ;
2023-04-21 11:57:21 +02:00
let cmprAttchObjs = function ( _obj1 , _obj2 )
{
for ( let i = 0 ; i < _obj1 . length ; i ++ )
{
if ( _obj1 [ i ] [ 'mail_id' ] != _obj2 [ i ] [ 'mail_id' ] || _obj1 [ i ] [ 'partID' ] != _obj2 [ i ] [ 'partID' ] ) return false ;
}
2023-06-19 17:05:37 +02:00
if ( _obj1 . length != _obj2 . length ) return false ;
2023-04-21 11:57:21 +02:00
return true ;
} ;
2023-04-27 12:42:27 +02:00
if ( _attachments && _attachments . length )
2023-03-23 12:08:23 +01:00
{
selected = [ _attachments [ 0 ] [ 'mail_id' ] ] ;
data = egw . dataGetUIDdata ( selected [ 0 ] ) ;
// do not call mail_preview if we have the attachments already resolved, avoid infinit loop
2023-04-21 11:57:21 +02:00
if ( data . data . attachmentsBlock . length > 0 && cmprAttchObjs ( data . data . attachmentsBlock , _attachments ) ) return ;
2023-03-23 12:08:23 +01:00
data . data . attachmentsBlock = _attachments ;
data . data . attachmentsBlockTitle = _attachments . lenght ;
2023-04-21 11:57:21 +02:00
egw . dataStoreUID ( data . data . uid , data . data ) ;
2023-03-23 12:08:23 +01:00
this . mail _preview ( selected , this . et2 . getWidgetById ( 'nm' ) ) ;
2017-08-31 17:33:23 +02:00
}
2017-07-12 18:40:56 +02:00
} ,
/ * *
* This function helps to trigger the Push notification immidiately .
* @ todo : Must be removed after socket push notification is implemented
* /
smimeAttachmentsCheckerInterval : function ( )
{
var self = this ;
2017-07-19 18:16:22 +02:00
var attachmentArea = this . et2 . getWidgetById ( 'previewAttachmentArea' ) ;
if ( attachmentArea ) attachmentArea . getDOMNode ( ) . classList . add ( 'loading' ) ;
2017-07-12 18:40:56 +02:00
var interval = window . setInterval ( function ( ) {
self . egw . json ( 'mail.mail_ui.ajax_smimeAttachmentsChecker' , null , function ( _stop ) {
if ( _stop )
{
window . clearInterval ( interval ) ;
}
} ) . sendRequest ( true ) ;
} , 1000 ) ;
2017-07-19 18:16:22 +02:00
} ,
/ * *
*
* @ param { object } _data smime resolved certificate data
* @ returns { undefined }
* /
set _smimeFlags : function ( _data )
{
if ( ! _data ) return ;
2017-08-25 12:26:13 +02:00
var self = this ;
2017-09-14 11:28:27 +02:00
var et2 _object = egwIsMobile ( ) ? this . et2 _view . widgetContainer : this . et2 ;
2017-08-25 12:26:13 +02:00
var data = _data ;
2017-09-14 11:28:27 +02:00
var attachmentArea = et2 _object . getWidgetById ( 'previewAttachmentArea' ) ;
2017-07-19 18:16:22 +02:00
if ( attachmentArea ) attachmentArea . getDOMNode ( ) . classList . remove ( 'loading' ) ;
2017-09-14 11:28:27 +02:00
var smime _signature = et2 _object . getWidgetById ( 'smime_signature' ) ;
var smime _encryption = et2 _object . getWidgetById ( 'smime_encryption' ) ;
2022-07-28 16:39:47 +02:00
var mail _container = egwIsMobile ( ) ? document . getElementsByClassName ( 'mail-d-h1' ) . next ( ) :
egw ( window ) . is _popup ( ) ? document . getElementsByClassName ( 'mailDisplayContainer' ) :
et2 _object . getWidgetById ( 'mailPreviewContainer' ) . getDOMNode ( ) ;
2017-08-25 12:26:13 +02:00
smime _signature . set _disabled ( ! data . signed ) ;
smime _encryption . set _disabled ( ! data . encrypted ) ;
if ( ! data . signed )
2017-07-25 17:13:49 +02:00
{
2022-07-28 16:39:47 +02:00
this . smime _clear _flags ( [ mail _container ] ) ;
2017-08-25 12:26:13 +02:00
return ;
2017-07-25 17:13:49 +02:00
}
2017-08-25 12:26:13 +02:00
else if ( data . verify )
2017-07-25 17:13:49 +02:00
{
2022-07-28 16:39:47 +02:00
mail _container . classList . add ( ( data . class = 'smime_cert_verified' ) ) ;
2017-08-25 16:07:09 +02:00
smime _signature . set _class ( data . class ) ;
2017-08-25 12:26:13 +02:00
smime _signature . set _statustext ( data . msg ) ;
2017-07-25 17:13:49 +02:00
}
2017-08-25 12:26:13 +02:00
else if ( ! data . verify && data . cert )
2017-07-25 17:13:49 +02:00
{
2022-07-28 16:39:47 +02:00
mail _container . classList . add ( ( data . class = 'smime_cert_notverified' ) ) ;
2017-08-25 16:07:09 +02:00
smime _signature . set _class ( data . class ) ;
2017-08-25 12:26:13 +02:00
smime _signature . set _statustext ( data . msg ) ;
2017-07-25 17:13:49 +02:00
}
2017-08-25 12:26:13 +02:00
else if ( ! data . verify && ! data . cert )
2017-07-25 18:00:22 +02:00
{
2022-07-28 16:39:47 +02:00
mail _container . classList . add ( ( data . class = 'smime_cert_notvalid' ) ) ;
2017-08-25 16:07:09 +02:00
smime _signature . set _class ( data . class ) ;
2017-08-25 12:26:13 +02:00
smime _signature . set _statustext ( data . msg ) ;
2017-07-25 18:00:22 +02:00
}
2017-08-25 16:07:09 +02:00
if ( data . unknownemail )
{
2022-07-28 16:39:47 +02:00
mail _container . classList . add ( ( data . class = 'smime_cert_unknownemail' ) ) ;
2017-08-25 16:07:09 +02:00
smime _signature . set _class ( data . class ) ;
}
2022-10-26 13:19:15 +02:00
data . class = data . class ? data . class : "" ;
2022-07-28 16:39:47 +02:00
jQuery ( smime _signature . getDOMNode ( ) , smime _encryption . getDOMNode ( ) ) . off ( ) . on ( 'click' , function ( ) {
2017-08-25 12:26:13 +02:00
self . smime _certAddToContact ( data , true ) ;
2017-08-25 16:46:34 +02:00
} ) . addClass ( 'et2_clickable' ) ;
2022-07-28 16:39:47 +02:00
jQuery ( smime _encryption . getDOMNode ( ) ) . off ( ) . on ( 'click' , function ( ) {
2017-08-25 12:26:13 +02:00
self . smime _certAddToContact ( data , true ) ;
2017-08-25 16:46:34 +02:00
} ) . addClass ( 'et2_clickable' ) ;
2017-07-25 17:13:49 +02:00
} ,
2017-08-25 12:26:13 +02:00
/ * *
* Reset flags classes and click handler
*
* @ param { jQuery Object } _nodes
* /
2017-07-25 17:13:49 +02:00
smime _clear _flags : function ( _nodes )
{
for ( var i = 0 ; i < _nodes . length ; i ++ )
{
2022-07-28 16:39:47 +02:00
_nodes [ i ] . classList . remove ( ... [ 'smime_cert_verified' ,
'smime_cert_notverified' ,
'smime_cert_notvalid' , 'smime_cert_unknownemail' ] ) ;
2017-07-25 17:13:49 +02:00
}
2017-08-21 10:59:02 +02:00
} ,
2017-07-19 18:16:22 +02:00
2017-08-21 10:59:02 +02:00
/ * *
* Inform user about sender ' s certificate and offers to add it into
* relevant contact in addressbook .
2017-08-22 17:25:29 +02:00
*
2017-08-21 10:59:02 +02:00
* @ param { type } _metadata
2017-08-25 12:26:13 +02:00
* @ param { boolean } _display if set to true will only show close button
2017-08-21 10:59:02 +02:00
* /
2017-08-25 12:26:13 +02:00
smime _certAddToContact : function ( _metadata , _display )
2017-08-21 10:59:02 +02:00
{
if ( ! _metadata || _metadata . length < 1 ) return ;
var self = this ;
2017-08-25 12:26:13 +02:00
var content = jQuery . extend ( true , { message : _metadata . msg } , _metadata ) ;
var buttons = [
2022-07-20 22:23:55 +02:00
{ label : this . egw . lang ( "Close" ) , id : "close" }
2017-08-25 12:26:13 +02:00
] ;
if ( ! _display )
{
buttons [ 1 ] = {
2022-07-20 22:23:55 +02:00
label : this . egw . lang ( "Add this certificate into contact" ) ,
2017-08-25 12:26:13 +02:00
id : "contact" ,
2022-07-20 22:23:55 +02:00
image : "add" ,
2017-08-25 12:26:13 +02:00
"class" : "ui-priority-primary" ,
"default" : true
} ;
content . message2 = egw . lang ( 'You may add this certificate into your contact, if you trust this signature.' ) ;
}
2017-09-12 17:23:24 +02:00
var extra = {
'presets[email]' : _metadata . email ,
'presets[n_given]' : _metadata . certDetails . subject . commonName ,
'presets[pubkey]' : _metadata . cert ,
'presets[org_name]' : _metadata . certDetails . subject . organizationName ,
'presets[org_unit]' : _metadata . certDetails . subject . organizationUnitName
} ;
2022-10-26 13:19:15 +02:00
content . class = "" ;
2017-08-25 12:26:13 +02:00
et2 _createWidget ( "dialog" ,
{
callback : function ( _button _id , _value )
2017-08-21 10:59:02 +02:00
{
2017-08-25 12:26:13 +02:00
if ( _button _id == 'contact' && _value )
{
self . egw . json ( 'mail.mail_ui.ajax_smimeAddCertToContact' ,
2017-09-12 17:23:24 +02:00
_metadata , function ( _result ) {
if ( ! _result )
{
egw . open ( '' , 'addressbook' , 'add' , extra ) ;
}
egw . message ( _result ) ;
} ) . sendRequest ( true ) ;
2017-08-25 12:26:13 +02:00
}
} ,
title : egw . lang ( 'Certificate info for email %1' , _metadata . email ) ,
buttons : buttons ,
2017-10-12 13:20:23 +02:00
minWidth : 500 ,
minHeight : 500 ,
2017-08-25 12:26:13 +02:00
value : { content : content } ,
2017-09-13 17:08:07 +02:00
template : egw . webserverUrl + '/mail/templates/default/smimeCertAddToContact.xet?1' ,
2017-08-25 12:26:13 +02:00
resizable : false
} , et2 _dialog . _create _parent ( 'mail' ) ) ;
2017-11-10 11:13:12 +01:00
} ,
/ * *
* get preview pane state base on selected preference .
*
* It also set a right css class for vertical state .
*
* @ returns { Boolean } returns true for visible Pane and false for hiding
* /
getPreviewPaneState : function ( )
{
2023-04-03 13:17:27 +02:00
var previewPane = this . egw . preference ( 'previewPane' , 'mail' ) || 'vertical' ;
2017-11-10 11:13:12 +01:00
var nm = this . et2 . getWidgetById ( this . nm _index ) ;
var state = false ;
switch ( previewPane )
{
case true :
case '1' :
case 'hide' :
case 'expand' :
state = false ;
break ;
case 'fixed' :
state = true ;
break ;
default : // default is vertical
state = true ;
nm . header . right _div . addClass ( 'vertical_splitter' ) ;
}
return state ;
2018-02-20 18:00:30 +01:00
} ,
/ * *
* Creates a dialog for changing meesage subject
*
2018-02-26 17:53:59 +01:00
* @ param { object } _action | _widget
* @ param { object } _sender | _content
2018-02-20 18:00:30 +01:00
* /
modifyMessageSubjectDialog : function ( _action , _sender )
{
2018-12-07 11:18:06 +01:00
_sender = _sender ? _sender : [ { id : this . mail _currentlyFocussed } ] ;
2018-02-26 17:53:59 +01:00
var id = ( _sender && _sender . uid ) ? _sender . row _id :
_sender [ 0 ] . id != 'nm' ? _sender [ 0 ] . id : _sender [ 1 ] . id ;
var data = ( _sender && _sender . uid ) ? { data : _sender } : egw . dataGetUIDdata ( id ) ;
2018-02-20 18:00:30 +01:00
var subject = data && data . data ? data . data . subject : "" ;
et2 _createWidget ( "dialog" ,
{
callback : function ( _button _id , _value ) {
var newSubject = null ;
2018-02-26 12:34:08 +01:00
if ( _value && _value . value ) newSubject = _value . value ;
2018-02-20 18:00:30 +01:00
if ( newSubject && newSubject . length > 0 )
{
switch ( _button _id )
{
2022-07-20 22:23:55 +02:00
case Et2Dialog . OK _BUTTON :
2018-12-07 11:18:06 +01:00
egw . loading _prompt ( 'modifyMessageSubjectDialog' , true ) ;
2022-07-20 22:23:55 +02:00
egw . json ( 'mail.mail_ui.ajax_saveModifiedMessageSubject' , [ id , newSubject ] , function ( _data )
{
2018-12-07 11:18:06 +01:00
egw . loading _prompt ( 'modifyMessageSubjectDialog' , false ) ;
2018-02-26 12:34:08 +01:00
if ( _data && ! _data . success )
{
egw . message ( _data . msg , "error" ) ;
return ;
}
var nm = app . mail . et2 . getWidgetById ( 'nm' ) ;
2022-07-20 22:23:55 +02:00
if ( nm )
{
nm . applyFilters ( ) ;
}
2018-02-26 12:34:08 +01:00
} ) . sendRequest ( true ) ;
2018-02-20 18:00:30 +01:00
return ;
case "cancel" :
}
}
} ,
title : this . egw . lang ( "Modify subject" ) ,
2022-07-20 22:23:55 +02:00
buttons : Et2Dialog . BUTTONS _OK _CANCEL ,
value : { content : { value : subject } } ,
template : egw . webserverUrl + '/mail/templates/default/modifyMessageSubjectDialog.xet?1' ,
2020-07-13 16:30:11 +02:00
resizable : false ,
width : 500
2018-02-20 18:00:30 +01:00
} , et2 _dialog . _create _parent ( 'mail' ) ) ;
2018-06-25 11:34:16 +02:00
} ,
/ * *
* Pre set toggled actions
* /
preSetToggledOnActions : function ( )
{
var actions = egw . preference ( 'toggledOnActions' , 'mail' ) ;
var toolbar = this . et2 . getWidgetById ( 'composeToolbar' ) ;
if ( actions )
{
actions = actions . split ( ',' ) ;
for ( var i = 0 ; i < actions . length ; i ++ )
{
2018-06-25 14:58:57 +02:00
if ( toolbar && toolbar . options . actions [ actions [ i ] ] )
2018-06-25 11:34:16 +02:00
{
2022-09-06 13:08:20 +02:00
let d = document . getElementById ( 'mail-compose_composeToolbar-' + actions [ i ] ) ;
if ( d && toolbar . _actionManager . getActionById ( actions [ i ] ) . checkbox
2018-06-25 11:34:16 +02:00
&& ! toolbar . _actionManager . getActionById ( actions [ i ] ) . checked )
{
2022-09-06 13:08:20 +02:00
d . click ( ) ;
2018-06-25 11:34:16 +02:00
}
}
else
{
var widget = this . et2 . getWidgetById ( actions [ i ] ) ;
if ( widget )
{
jQuery ( widget . getDOMNode ( ) ) . trigger ( 'click' ) ;
}
}
}
}
2020-07-02 10:42:42 +02:00
} ,
/ * *
* Set predefined addresses for compose dialog
*
* @ param { type } action
* @ param { type } _senders
* @ returns { undefined }
* /
set _predefined _addresses : function ( action , _senders )
{
var pref _id = _senders [ 0 ] . id . split ( '::' ) [ 0 ] + '_predefined_compose_addresses' ;
var prefs = egw . preference ( pref _id , 'mail' ) ;
et2 _createWidget ( "dialog" ,
{
2022-07-20 22:23:55 +02:00
callback : function ( _button _id , _value )
{
2020-07-02 10:42:42 +02:00
switch ( _button _id )
{
2022-07-20 22:23:55 +02:00
case Et2Dialog . OK _BUTTON :
2020-07-02 10:42:42 +02:00
egw . set _preference ( 'mail' , pref _id , _value ) ;
return ;
case "cancel" :
}
} ,
title : this . egw . lang ( "Predefined addresses for compose" ) ,
2022-07-20 22:23:55 +02:00
buttons : Et2Dialog . BUTTONS _OK _CANCEL ,
value : { content : prefs || { } } ,
2020-07-02 10:42:42 +02:00
minWidth : 410 ,
2022-07-20 22:23:55 +02:00
template : egw . webserverUrl + '/mail/templates/default/predefinedAddressesDialog.xet?' ,
2020-07-02 10:42:42 +02:00
resizable : false ,
} , et2 _dialog . _create _parent ( 'mail' ) ) ;
2023-01-25 16:23:11 +01:00
} ,
/ * *
* open
* @ param _node
* @ param _address
* /
onclickCompose ( _node , _address )
{
2023-03-22 20:41:13 +01:00
if ( _address . value && this . egw . preference ( 'force_mailto' , 'addressbook' ) != '1' )
{
this . egw . open _link ( 'mailto:' + _address . value ) ;
}
else
{
window . open ( "mailto:" + _address . value ) ;
}
2016-03-01 18:00:28 +01:00
}
2022-04-30 12:11:37 +02:00
} ) ;