hydrus/include/ClientDragDrop.py

246 lines
6.6 KiB
Python
Raw Normal View History

2019-06-26 21:27:18 +00:00
from . import ClientGUIFunctions
2019-01-09 22:59:03 +00:00
from . import HydrusGlobals as HG
from . import HydrusPaths
2017-12-20 22:55:48 +00:00
import json
2018-03-28 21:55:58 +00:00
import os
2019-11-14 03:56:30 +00:00
from qtpy import QtCore as QC
from qtpy import QtGui as QG
from qtpy import QtWidgets as QW
from . import QtPorting as QP
2015-07-29 19:11:35 +00:00
2019-02-13 22:26:43 +00:00
def DoFileExportDragDrop( window, page_key, media, alt_down ):
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
drop_source = QG.QDrag( window )
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
data_object = QC.QMimeData()
2018-03-28 21:55:58 +00:00
#
2019-11-14 03:56:30 +00:00
new_options = HG.client_controller.new_options
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
do_secret_discord_dnd_fix = new_options.GetBoolean( 'secret_discord_dnd_fix' ) and alt_down
2018-03-28 21:55:58 +00:00
#
client_files_manager = HG.client_controller.client_files_manager
original_paths = []
2019-02-13 22:26:43 +00:00
total_size = 0
2018-03-28 21:55:58 +00:00
for m in media:
hash = m.GetHash()
mime = m.GetMime()
2019-02-13 22:26:43 +00:00
total_size += m.GetSize()
2018-09-12 21:36:26 +00:00
original_path = client_files_manager.GetFilePath( hash, mime, check_file_exists = False )
2018-03-28 21:55:58 +00:00
original_paths.append( original_path )
#
2019-02-13 22:26:43 +00:00
discord_dnd_fix_possible = new_options.GetBoolean( 'discord_dnd_fix' ) and len( original_paths ) <= 50 and total_size < 200 * 1048576
2018-03-28 21:55:58 +00:00
temp_dir = HG.client_controller.temp_dir
2019-11-14 03:56:30 +00:00
if do_secret_discord_dnd_fix:
2019-02-13 22:26:43 +00:00
dnd_paths = original_paths
2019-11-14 03:56:30 +00:00
flags = QC.Qt.MoveAction
2019-02-13 22:26:43 +00:00
elif discord_dnd_fix_possible and os.path.exists( temp_dir ):
2018-03-28 21:55:58 +00:00
dnd_paths = []
for original_path in original_paths:
filename = os.path.basename( original_path )
dnd_path = os.path.join( temp_dir, filename )
if not os.path.exists( dnd_path ):
HydrusPaths.MirrorFile( original_path, dnd_path )
dnd_paths.append( dnd_path )
2019-11-14 03:56:30 +00:00
flags = QC.Qt.MoveAction | QC.Qt.CopyAction
2018-03-28 21:55:58 +00:00
else:
dnd_paths = original_paths
2019-11-14 03:56:30 +00:00
flags = QC.Qt.CopyAction
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
uri_list = []
2018-03-28 21:55:58 +00:00
for path in dnd_paths:
2019-11-14 03:56:30 +00:00
uri_list.append( QC.QUrl.fromLocalFile( path ) )
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
data_object.setUrls( uri_list )
2018-03-28 21:55:58 +00:00
#
2019-11-14 03:56:30 +00:00
hashes = [ m.GetHash() for m in media ]
if page_key is None:
encoded_page_key = None
else:
encoded_page_key = page_key.hex()
data_obj = ( encoded_page_key, [ hash.hex() for hash in hashes ] )
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
data_str = json.dumps( data_obj )
data_bytes = bytes( data_str, 'utf-8' )
data_object.setData( 'application/hydrus-media', data_bytes )
#
drop_source.setMimeData( data_object )
result = drop_source.exec_( flags, QC.Qt.CopyAction )
2018-03-28 21:55:58 +00:00
return result
2019-11-14 03:56:30 +00:00
class FileDropTarget( QC.QObject ):
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
def __init__( self, parent, filenames_callable = None, url_callable = None, media_callable = None ):
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
QC.QObject.__init__( self, parent )
2015-07-29 19:11:35 +00:00
2017-11-22 21:03:07 +00:00
self._parent = parent
2019-11-14 03:56:30 +00:00
if parent:
parent.setAcceptDrops( True )
2017-05-17 21:53:02 +00:00
self._filenames_callable = filenames_callable
self._url_callable = url_callable
2017-12-20 22:55:48 +00:00
self._media_callable = media_callable
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
def eventFilter( self, object, event ):
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
if event.type() == QC.QEvent.Drop:
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
if self.OnDrop( event.pos().x(), event.pos().y() ):
event.setDropAction( self.OnData( event.mimeData(), event.proposedAction() ) )
event.accept()
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
elif event.type() == QC.QEvent.DragEnter:
2017-05-17 21:53:02 +00:00
2019-11-14 03:56:30 +00:00
event.accept()
return False
def OnData( self, mime_data, result ):
if mime_data.formats():
if mime_data.formats().count( 'application/hydrus-media' ) and self._media_callable is not None:
mview = mime_data.data( 'application/hydrus-media' )
data_bytes = mview.data()
data_str = str( data_bytes, 'utf-8' )
(encoded_page_key, encoded_hashes) = json.loads( data_str )
if encoded_page_key is not None:
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
page_key = bytes.fromhex( encoded_page_key )
hashes = [ bytes.fromhex( encoded_hash ) for encoded_hash in encoded_hashes ]
QP.CallAfter( self._media_callable, page_key, hashes ) # callafter so we can terminate dnd event now
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
result = QC.Qt.MoveAction
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
elif mime_data.hasUrls() and self._filenames_callable is not None:
paths = []
urls = []
for url in mime_data.urls():
2017-12-20 22:55:48 +00:00
2019-11-14 03:56:30 +00:00
if url.isLocalFile():
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
paths.append( os.path.normpath( url.toLocalFile() ) )
2018-03-28 21:55:58 +00:00
2019-11-14 03:56:30 +00:00
else:
urls.append( url.url() )
2018-03-28 21:55:58 +00:00
2015-07-29 19:11:35 +00:00
2019-11-14 03:56:30 +00:00
if len( paths ) > 0:
2018-01-03 22:37:30 +00:00
2019-11-14 03:56:30 +00:00
QP.CallAfter( self._filenames_callable, paths ) # callafter to terminate dnd event now
2017-08-23 21:34:25 +00:00
2019-11-14 03:56:30 +00:00
if len( urls ) > 0:
2017-09-27 21:52:54 +00:00
2019-11-14 03:56:30 +00:00
for url in urls:
QP.CallAfter( self._url_callable, url ) # callafter to terminate dnd event now
2017-08-23 21:34:25 +00:00
2019-11-14 03:56:30 +00:00
result = QC.Qt.IgnoreAction
elif mime_data.hasText() and self._url_callable is not None:
text = mime_data.text()
QP.CallAfter( self._url_callable, text ) # callafter to terminate dnd event now
result = QC.Qt.CopyAction
else:
result = QC.Qt.MoveAction
2015-07-29 19:11:35 +00:00
return result
2017-11-22 21:03:07 +00:00
def OnDrop( self, x, y ):
2019-06-26 21:27:18 +00:00
screen_position = ClientGUIFunctions.ClientToScreen( self._parent, ( x, y ) )
2017-11-29 21:48:23 +00:00
2019-11-14 03:56:30 +00:00
drop_tlp = QW.QApplication.topLevelAt( screen_position )
my_tlp = self._parent.window()
2017-11-22 21:03:07 +00:00
if drop_tlp == my_tlp:
return True
else:
return False
2017-09-27 21:52:54 +00:00
# setting OnDragOver to return copy gives Linux trouble with page tab drops with shift held down