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
|