mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
MTP: Popup a dialog asking the user if they want to manage the device with calibre the first time it is detected
This commit is contained in:
parent
e4739c1334
commit
fa026406bb
@ -99,6 +99,12 @@ class DevicePlugin(Plugin):
|
||||
#: after the books lists have been loaded to get the driveinfo.
|
||||
SLOW_DRIVEINFO = False
|
||||
|
||||
#: If set to True, calibre will ask the user if they want to manage the
|
||||
#: device with calibre, the first time it is detected. If you set this to
|
||||
#: True you must implement :meth:`get_device_uid()` and
|
||||
#: :meth:`ignore_connected_device()`.
|
||||
ASK_TO_ALLOW_CONNECT = False
|
||||
|
||||
@classmethod
|
||||
def get_gui_name(cls):
|
||||
if hasattr(cls, 'gui_name'):
|
||||
@ -587,6 +593,24 @@ class DevicePlugin(Plugin):
|
||||
'''
|
||||
pass
|
||||
|
||||
def get_device_uid(self):
|
||||
'''
|
||||
Must return a unique id for the currently connected device (this is
|
||||
called immediately after a successful call to open()). You must
|
||||
implement this method if you set ASK_TO_ALLOW_CONNECT = True
|
||||
'''
|
||||
raise NotImplementedError()
|
||||
|
||||
def ignore_connected_device(self, uid):
|
||||
'''
|
||||
Should ignore the device identified by uid (the result of a call to
|
||||
get_device_uid()) in the future. You must implement this method if you
|
||||
set ASK_TO_ALLOW_CONNECT = True. Note that this function is called
|
||||
immediately after open(), so if open() caches some state, the driver
|
||||
should reset that state.
|
||||
'''
|
||||
raise NotImplementedError()
|
||||
|
||||
# Dynamic control interface.
|
||||
# The following methods are probably called on the GUI thread. Any driver
|
||||
# that implements these methods must take pains to be thread safe, because
|
||||
|
@ -38,6 +38,7 @@ class MTP_DEVICE(BASE):
|
||||
FORMATS = ['epub', 'azw3', 'mobi', 'pdf']
|
||||
DEVICE_PLUGBOARD_NAME = 'MTP_DEVICE'
|
||||
SLOW_DRIVEINFO = True
|
||||
ASK_TO_ALLOW_CONNECT = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
BASE.__init__(self, *args, **kwargs)
|
||||
@ -90,6 +91,17 @@ class MTP_DEVICE(BASE):
|
||||
|
||||
self.current_device_defaults = self.device_defaults(device, self)
|
||||
|
||||
def get_device_uid(self):
|
||||
return self.current_serial_num
|
||||
|
||||
def ignore_connected_device(self, uid):
|
||||
bl = self.prefs['blacklist']
|
||||
if uid not in bl:
|
||||
bl.append(uid)
|
||||
self.prefs['blacklist'] = bl
|
||||
if self.is_mtp_device_connected:
|
||||
self.eject()
|
||||
|
||||
# Device information {{{
|
||||
def _update_drive_info(self, storage, location_code, name=None):
|
||||
import uuid
|
||||
|
@ -294,7 +294,9 @@ def question_dialog(parent, title, msg, det_msg='', show_copy_button=False,
|
||||
# Set skip_dialog_name to a unique name for this dialog
|
||||
# Set skip_dialog_msg to a message displayed to the user
|
||||
skip_dialog_name=None, skip_dialog_msg=_('Show this confirmation again'),
|
||||
skip_dialog_skipped_value=True, skip_dialog_skip_precheck=True):
|
||||
skip_dialog_skipped_value=True, skip_dialog_skip_precheck=True,
|
||||
# Override icon (QIcon to be used as the icon for this dialog)
|
||||
override_icon=None):
|
||||
from calibre.gui2.dialogs.message_box import MessageBox
|
||||
|
||||
auto_skip = set(gprefs.get('questions_to_auto_skip', []))
|
||||
@ -302,7 +304,8 @@ def question_dialog(parent, title, msg, det_msg='', show_copy_button=False,
|
||||
return bool(skip_dialog_skipped_value)
|
||||
|
||||
d = MessageBox(MessageBox.QUESTION, title, msg, det_msg, parent=parent,
|
||||
show_copy_button=show_copy_button, default_yes=default_yes)
|
||||
show_copy_button=show_copy_button, default_yes=default_yes,
|
||||
q_icon=override_icon)
|
||||
|
||||
if skip_dialog_name is not None and skip_dialog_msg:
|
||||
tc = d.toggle_checkbox
|
||||
|
@ -20,7 +20,7 @@ from calibre.utils.ipc.job import BaseJob
|
||||
from calibre.devices.scanner import DeviceScanner
|
||||
from calibre.gui2 import (config, error_dialog, Dispatcher, dynamic,
|
||||
warning_dialog, info_dialog, choose_dir, FunctionDispatcher,
|
||||
show_restart_warning)
|
||||
show_restart_warning, gprefs, question_dialog)
|
||||
from calibre.ebooks.metadata import authors_to_string
|
||||
from calibre import preferred_encoding, prints, force_unicode, as_unicode
|
||||
from calibre.utils.filenames import ascii_filename
|
||||
@ -122,7 +122,7 @@ def device_name_for_plugboards(device_class):
|
||||
class DeviceManager(Thread): # {{{
|
||||
|
||||
def __init__(self, connected_slot, job_manager, open_feedback_slot,
|
||||
open_feedback_msg, sleep_time=2):
|
||||
open_feedback_msg, allow_connect_slot, sleep_time=2):
|
||||
'''
|
||||
:sleep_time: Time to sleep between device probes in secs
|
||||
'''
|
||||
@ -136,6 +136,7 @@ class DeviceManager(Thread): # {{{
|
||||
x.MANAGES_DEVICE_PRESENCE]
|
||||
self.sleep_time = sleep_time
|
||||
self.connected_slot = connected_slot
|
||||
self.allow_connect_slot = allow_connect_slot
|
||||
self.jobs = Queue.Queue(0)
|
||||
self.job_steps = Queue.Queue(0)
|
||||
self.keep_going = True
|
||||
@ -193,6 +194,21 @@ class DeviceManager(Thread): # {{{
|
||||
return False
|
||||
|
||||
def after_device_connect(self, dev, device_kind):
|
||||
allow_connect = True
|
||||
try:
|
||||
uid = dev.get_device_uid()
|
||||
except NotImplementedError:
|
||||
uid = None
|
||||
asked = gprefs.get('ask_to_manage_device', [])
|
||||
if (dev.ASK_TO_ALLOW_CONNECT and uid and uid not in asked):
|
||||
if not self.allow_connect_slot(dev.get_gui_name()):
|
||||
allow_connect = False
|
||||
asked.append(uid)
|
||||
gprefs.set('ask_to_manage_device', asked)
|
||||
if not allow_connect:
|
||||
dev.ignore_connected_device(uid)
|
||||
return
|
||||
|
||||
self.connected_device = dev
|
||||
self.connected_device_kind = device_kind
|
||||
self.connected_slot(True, device_kind)
|
||||
@ -829,12 +845,19 @@ class DeviceMixin(object): # {{{
|
||||
self.device_error_dialog.setModal(Qt.NonModal)
|
||||
self.device_manager = DeviceManager(FunctionDispatcher(self.device_detected),
|
||||
self.job_manager, Dispatcher(self.status_bar.show_message),
|
||||
Dispatcher(self.show_open_feedback))
|
||||
Dispatcher(self.show_open_feedback),
|
||||
FunctionDispatcher(self.allow_connect))
|
||||
self.device_manager.start()
|
||||
self.device_manager.devices_initialized.wait()
|
||||
if tweaks['auto_connect_to_folder']:
|
||||
self.connect_to_folder_named(tweaks['auto_connect_to_folder'])
|
||||
|
||||
def allow_connect(self, name):
|
||||
return question_dialog(self, _('Mange the %s?')%name,
|
||||
_('Detected the <b>%s</b>. Do you want calibre to manage it?')%
|
||||
name, show_copy_button=False,
|
||||
override_icon=QIcon(I('reader.png')))
|
||||
|
||||
def debug_detection(self, done):
|
||||
self.debug_detection_callback = weakref.ref(done)
|
||||
self.device_manager.debug_detection(FunctionDispatcher(self.debug_detection_done))
|
||||
|
Loading…
x
Reference in New Issue
Block a user