forked from extern/egroupware
Add drag&drop for email and link lists
This commit is contained in:
parent
09f1d55a72
commit
6a8e85c3e1
@ -183,6 +183,7 @@ class etemplate_widget_link extends etemplate_widget
|
|||||||
}
|
}
|
||||||
$link['title'] = egw_vfs::decodePath($link['title']);
|
$link['title'] = egw_vfs::decodePath($link['title']);
|
||||||
$link['icon'] = egw_link::vfs_path($link['app2'],$link['id2'],$link['id'],true);
|
$link['icon'] = egw_link::vfs_path($link['app2'],$link['id2'],$link['id'],true);
|
||||||
|
$link['download_url'] = egw_vfs::download_url($link['icon']);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -916,8 +916,15 @@ var et2_grid = et2_DOMWidget.extend([et2_IDetachedDOM, et2_IAligned],
|
|||||||
// Add a new action object to the object manager
|
// Add a new action object to the object manager
|
||||||
var row = $j('tr', this.tbody)[i];
|
var row = $j('tr', this.tbody)[i];
|
||||||
var aoi = new et2_action_object_impl(this, row);
|
var aoi = new et2_action_object_impl(this, row);
|
||||||
|
var content = this.getArrayMgr('content').getEntry(i);
|
||||||
|
var obj = widget_object.addObject(content.id || "row_"+i, aoi);
|
||||||
|
|
||||||
|
// Set the data to the content so it's available for the action
|
||||||
|
if(content)
|
||||||
|
{
|
||||||
|
obj.data = content;
|
||||||
|
}
|
||||||
|
|
||||||
var obj = widget_object.addObject("row_"+i, aoi);
|
|
||||||
obj.updateActionLinks(action_links);
|
obj.updateActionLinks(action_links);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1511,6 +1511,11 @@ var et2_link_list = et2_link_string.extend(
|
|||||||
var row = jQuery('#link_'+(self.context.data.dom_id ? self.context.data.dom_id : self.context.data.link_id), self.list);
|
var row = jQuery('#link_'+(self.context.data.dom_id ? self.context.data.dom_id : self.context.data.link_id), self.list);
|
||||||
self._delete_link(link_id, row);
|
self._delete_link(link_id, row);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Native DnD - Doesn't play nice with jQueryUI Sortable
|
||||||
|
// Tell jQuery to include this property
|
||||||
|
jQuery.event.props.push('dataTransfer');
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -1569,6 +1574,7 @@ var et2_link_list = et2_link_string.extend(
|
|||||||
_add_link: function(_link_data) {
|
_add_link: function(_link_data) {
|
||||||
var row = $j(document.createElement("tr"))
|
var row = $j(document.createElement("tr"))
|
||||||
.attr("id", "link_"+(_link_data.dom_id ? _link_data.dom_id : _link_data.link_id))
|
.attr("id", "link_"+(_link_data.dom_id ? _link_data.dom_id : _link_data.link_id))
|
||||||
|
.attr("draggable", _link_data.app == 'file' ? "true" : "")
|
||||||
.appendTo(this.list);
|
.appendTo(this.list);
|
||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
@ -1646,12 +1652,72 @@ var et2_link_list = et2_link_string.extend(
|
|||||||
self.context.showAt(e.pageX, e.pageY, true);
|
self.context.showAt(e.pageX, e.pageY, true);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Drag - adapted from egw_action_dragdrop, sidestepping action system
|
||||||
|
// so all linked files get it
|
||||||
|
// // Unfortunately, dragging files is currently only supported by Chrome
|
||||||
|
if(navigator && navigator.userAgent.indexOf('Chrome') >= 0)
|
||||||
|
{
|
||||||
|
row.on("dragstart", _link_data, function(event) {
|
||||||
|
if(event.dataTransfer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var data = event.data || {};
|
||||||
|
if(data && data.type && data.download_url)
|
||||||
|
{
|
||||||
|
event.dataTransfer.dropEffect="copy";
|
||||||
|
event.dataTransfer.effectAllowed="copy";
|
||||||
|
|
||||||
|
var url = data.download_url;
|
||||||
|
|
||||||
|
// NEED an absolute URL
|
||||||
|
if (url[0] == '/') url = egw.link(url);
|
||||||
|
// egw.link adds the webserver, but that might not be an absolute URL - try again
|
||||||
|
if (url[0] == '/') url = window.location.origin+url;
|
||||||
|
|
||||||
|
// Unfortunately, dragging files is currently only supported by Chrome
|
||||||
|
if(navigator && navigator.userAgent.indexOf('Chrome'))
|
||||||
|
{
|
||||||
|
event.dataTransfer.setData("DownloadURL", data.type+':'+data.title+':'+url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include URL as a fallback
|
||||||
|
event.dataTransfer.setData("text/uri-list", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.dataTransfer.types.length == 0)
|
||||||
|
{
|
||||||
|
// No file data? Abort: drag does nothing
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//event.dataTransfer.setDragImage(event.delegate.target,0,0);
|
||||||
|
var div = $j(document.createElement("div"))
|
||||||
|
.attr('id', 'drag_helper')
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: '0px',
|
||||||
|
left: '0px',
|
||||||
|
width: '300px'
|
||||||
|
});
|
||||||
|
div.append(event.target.cloneNode(true));
|
||||||
|
|
||||||
|
self.list.append(div);
|
||||||
|
|
||||||
|
event.dataTransfer.setDragImage(div.get(0),0,0)
|
||||||
|
})
|
||||||
|
.on('drag', function() {
|
||||||
|
$j('#drag_helper',self.list).remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_delete_link: function(link_id, row) {
|
_delete_link: function(link_id, row) {
|
||||||
if(row)
|
if(row)
|
||||||
{
|
{
|
||||||
var delete_button = jQuery('.delete',row);
|
var delete_button = jQuery('.delete',row);
|
||||||
delete_button.removeClass("delete").addClass("loading");
|
delete_button.removeClass("delete").addClass("loading");
|
||||||
|
row.off();
|
||||||
}
|
}
|
||||||
if(typeof link_id != "object")
|
if(typeof link_id != "object")
|
||||||
{
|
{
|
||||||
|
@ -664,6 +664,12 @@ ul.et2_link_string {
|
|||||||
}
|
}
|
||||||
.et2_link_list {
|
.et2_link_list {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
.et2_link_list tr {
|
.et2_link_list tr {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -2057,6 +2057,7 @@ class mail_ui
|
|||||||
'onExecute' => 'javaScript:app.mail.drag_attachment'
|
'onExecute' => 'javaScript:app.mail.drag_attachment'
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
//_debug_array($content);
|
||||||
$readonlys = $preserv = $content;
|
$readonlys = $preserv = $content;
|
||||||
$etpl->exec('mail.mail_ui.displayMessage',$content,$sel_options,$readonlys,$preserv,2);
|
$etpl->exec('mail.mail_ui.displayMessage',$content,$sel_options,$readonlys,$preserv,2);
|
||||||
}
|
}
|
||||||
@ -2107,7 +2108,7 @@ class mail_ui
|
|||||||
$attachmentHTML[$key]['partID']=$value['partID'];
|
$attachmentHTML[$key]['partID']=$value['partID'];
|
||||||
$attachmentHTML[$key]['winmailFlag']=$value['is_winmail'];
|
$attachmentHTML[$key]['winmailFlag']=$value['is_winmail'];
|
||||||
$attachmentHTML[$key]['classSaveAllPossiblyDisabled'] = "mail_DisplayNone";
|
$attachmentHTML[$key]['classSaveAllPossiblyDisabled'] = "mail_DisplayNone";
|
||||||
|
|
||||||
switch(strtoupper($value['mimeType']))
|
switch(strtoupper($value['mimeType']))
|
||||||
{
|
{
|
||||||
case 'MESSAGE/RFC822':
|
case 'MESSAGE/RFC822':
|
||||||
|
@ -180,6 +180,12 @@ app.classes.mail = AppJS.extend(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.resizeTo((w_h[0]?w_h[0]:870),(w_h[1]?w_h[1]:(screen.availHeight>egw_getWindowOuterHeight()?screen.availHeight:egw_getWindowOuterHeight())));
|
window.resizeTo((w_h[0]?w_h[0]:870),(w_h[1]?w_h[1]:(screen.availHeight>egw_getWindowOuterHeight()?screen.availHeight:egw_getWindowOuterHeight())));
|
||||||
|
|
||||||
|
// Register attachments for drag
|
||||||
|
this.register_for_drag(
|
||||||
|
this.et2.getArrayMgr("content").getEntry('mail_id'),
|
||||||
|
this.et2.getArrayMgr("content").getEntry('mail_displayattachments')
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'mail.compose':
|
case 'mail.compose':
|
||||||
var that = this;
|
var that = this;
|
||||||
@ -987,6 +993,67 @@ app.classes.mail = AppJS.extend(
|
|||||||
{
|
{
|
||||||
egw.jsonq('mail_ui::ajax_refreshVacationNotice',[_server]);
|
egw.jsonq('mail_ui::ajax_refreshVacationNotice',[_server]);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 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 = {};
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var div = $j(document.createElement("div"))
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: '0px',
|
||||||
|
left: '0px',
|
||||||
|
width: '300px'
|
||||||
|
});
|
||||||
|
|
||||||
|
var data = _elems[0].data || {};
|
||||||
|
|
||||||
|
var text = $j(document.createElement('div')).css({left: '30px', position: 'absolute'});
|
||||||
|
// 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;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mail_refreshVacationNotice, function to call with appropriate data to refresh the vacationnotice for the active server
|
* mail_refreshVacationNotice, function to call with appropriate data to refresh the vacationnotice for the active server
|
||||||
|
@ -157,10 +157,10 @@ function egwDragActionImplementation()
|
|||||||
// Set file data
|
// Set file data
|
||||||
for(var i = 0; i < selected.length; i++)
|
for(var i = 0; i < selected.length; i++)
|
||||||
{
|
{
|
||||||
var data = egw.dataGetUIDdata(selected[i].id);
|
var data = selected[i].data || egw.dataGetUIDdata(selected[i].id).data || {};
|
||||||
if(data && data.data.mime && data.data.download_url)
|
if(data && data.mime && data.download_url)
|
||||||
{
|
{
|
||||||
var url = data.data.download_url;
|
var url = data.download_url;
|
||||||
|
|
||||||
// NEED an absolute URL
|
// NEED an absolute URL
|
||||||
if (url[0] == '/') url = egw.link(url);
|
if (url[0] == '/') url = egw.link(url);
|
||||||
@ -170,7 +170,7 @@ function egwDragActionImplementation()
|
|||||||
// Unfortunately, dragging files is currently only supported by Chrome
|
// Unfortunately, dragging files is currently only supported by Chrome
|
||||||
if(navigator && navigator.userAgent.indexOf('Chrome'))
|
if(navigator && navigator.userAgent.indexOf('Chrome'))
|
||||||
{
|
{
|
||||||
event.dataTransfer.setData("DownloadURL", data.data.mime+':'+data.data.name+':'+url);
|
event.dataTransfer.setData("DownloadURL", data.mime+':'+data.name+':'+url);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user