mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
GRiker's changes
This commit is contained in:
commit
b2e934a28a
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
resources/images/devices/itunes.png
Normal file
BIN
resources/images/devices/itunes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -277,7 +277,6 @@ class ITUNES(DriverBase):
|
||||
|
||||
# Fetch a list of books from iPod device connected to iTunes
|
||||
|
||||
|
||||
if 'iPod' in self.sources:
|
||||
booklist = BookList(self.log)
|
||||
cached_books = {}
|
||||
@ -366,7 +365,7 @@ class ITUNES(DriverBase):
|
||||
self._dump_cached_books('returning from books()',indent=2)
|
||||
return booklist
|
||||
else:
|
||||
return []
|
||||
return BookList(self.log)
|
||||
|
||||
def can_handle(self, device_info, debug=False):
|
||||
'''
|
||||
@ -377,7 +376,7 @@ class ITUNES(DriverBase):
|
||||
|
||||
Confirm that:
|
||||
- iTunes is running
|
||||
- there is an iPod-type device connected
|
||||
- there is an iDevice connected
|
||||
This gets called first when the device fingerprint is read, so it needs to
|
||||
instantiate iTunes if necessary
|
||||
This gets called ~1x/second while device fingerprint is sensed
|
||||
@ -2049,8 +2048,13 @@ class ITUNES(DriverBase):
|
||||
running_apps = appscript.app('System Events')
|
||||
if not 'iTunes' in running_apps.processes.name():
|
||||
if DEBUG:
|
||||
self.log.info( "ITUNES:open(): Launching iTunes" )
|
||||
self.log.info( "ITUNES:_launch_iTunes(): Launching iTunes" )
|
||||
try:
|
||||
self.iTunes = iTunes= appscript.app('iTunes', hide=True)
|
||||
except:
|
||||
self.iTunes = None
|
||||
raise UserFeedback(' ITUNES._launch_iTunes(): unable to find installed iTunes', details=None, level=UserFeedback.WARN)
|
||||
|
||||
iTunes.run()
|
||||
self.initial_status = 'launched'
|
||||
else:
|
||||
@ -2091,7 +2095,12 @@ class ITUNES(DriverBase):
|
||||
os.path.normpath("//server/share") returns "\\\\server\\share"
|
||||
'''
|
||||
# Instantiate iTunes
|
||||
try:
|
||||
self.iTunes = win32com.client.Dispatch("iTunes.Application")
|
||||
except:
|
||||
self.iTunes = None
|
||||
raise UserFeedback(' ITUNES._launch_iTunes(): unable to find installed iTunes', details=None, level=UserFeedback.WARN)
|
||||
|
||||
if not DEBUG:
|
||||
self.iTunes.Windows[0].Minimized = True
|
||||
self.initial_status = 'launched'
|
||||
@ -2564,6 +2573,225 @@ class ITUNES(DriverBase):
|
||||
db_added.Genre = tag
|
||||
break
|
||||
|
||||
class ITUNES_ASYNC(ITUNES):
|
||||
'''
|
||||
This subclass allows the user to interact directly with iTunes via a menu option
|
||||
'Connect to iTunes' in Send to device.
|
||||
'''
|
||||
name = 'iTunes interface'
|
||||
gui_name = 'Apple iTunes'
|
||||
icon = I('devices/itunes.png')
|
||||
description = _('Communicate with iTunes.')
|
||||
|
||||
connected = False
|
||||
|
||||
def __init__(self,path):
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC:__init__()")
|
||||
|
||||
if isosx and appscript is None:
|
||||
self.connected = False
|
||||
raise UserFeedback('OSX 10.5 or later required', details=None, level=UserFeedback.WARN)
|
||||
return
|
||||
else:
|
||||
self.connected = True
|
||||
|
||||
if isosx:
|
||||
self._launch_iTunes()
|
||||
|
||||
if iswindows:
|
||||
try:
|
||||
pythoncom.CoInitialize()
|
||||
self._launch_iTunes()
|
||||
except:
|
||||
raise UserFeedback('unable to launch iTunes', details=None, level=UserFeedback.WARN)
|
||||
finally:
|
||||
pythoncom.CoUninitialize()
|
||||
|
||||
self.manual_sync_mode = False
|
||||
|
||||
def books(self, oncard=None, end_session=True):
|
||||
"""
|
||||
Return a list of ebooks on the device.
|
||||
@param oncard: If 'carda' or 'cardb' return a list of ebooks on the
|
||||
specific storage card, otherwise return list of ebooks
|
||||
in main memory of device. If a card is specified and no
|
||||
books are on the card return empty list.
|
||||
@return: A BookList.
|
||||
|
||||
Implementation notes:
|
||||
iTunes does not sync purchased books, they are only on the device. They are visible, but
|
||||
they are not backed up to iTunes. Since calibre can't manage them, don't show them in the
|
||||
list of device books.
|
||||
|
||||
"""
|
||||
if not oncard:
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC:books(oncard=%s)" % oncard)
|
||||
|
||||
# Fetch a list of books from iTunes
|
||||
|
||||
booklist = BookList(self.log)
|
||||
cached_books = {}
|
||||
|
||||
if isosx:
|
||||
library_books = self._get_library_books()
|
||||
book_count = float(len(library_books))
|
||||
for (i,book) in enumerate(library_books):
|
||||
this_book = Book(library_books[book].name(), library_books[book].artist())
|
||||
this_book.path = self.path_template % (library_books[book].name(),
|
||||
library_books[book].artist())
|
||||
try:
|
||||
this_book.datetime = parse_date(str(library_books[book].date_added())).timetuple()
|
||||
except:
|
||||
pass
|
||||
this_book.db_id = None
|
||||
this_book.device_collections = []
|
||||
#this_book.library_id = library_books[this_book.path] if this_book.path in library_books else None
|
||||
this_book.library_id = library_books[book]
|
||||
this_book.size = library_books[book].size()
|
||||
this_book.uuid = library_books[book].album()
|
||||
# Hack to discover if we're running in GUI environment
|
||||
if self.report_progress is not None:
|
||||
this_book.thumbnail = self._generate_thumbnail(this_book.path, library_books[book])
|
||||
else:
|
||||
this_book.thumbnail = None
|
||||
booklist.add_book(this_book, False)
|
||||
|
||||
cached_books[this_book.path] = {
|
||||
'title':library_books[book].name(),
|
||||
'author':[library_books[book].artist()],
|
||||
'lib_book':library_books[book],
|
||||
'dev_book':None,
|
||||
'uuid': library_books[book].composer(),
|
||||
#'format': 'pdf' if book.KindAsString.startswith('PDF') else 'epub'
|
||||
}
|
||||
|
||||
if self.report_progress is not None:
|
||||
self.report_progress(i+1/book_count, _('%d of %d') % (i+1, book_count))
|
||||
|
||||
elif iswindows:
|
||||
try:
|
||||
pythoncom.CoInitialize()
|
||||
self.iTunes = win32com.client.Dispatch("iTunes.Application")
|
||||
library_books = self._get_library_books()
|
||||
book_count = float(len(library_books))
|
||||
for (i,book) in enumerate(library_books):
|
||||
this_book = Book(library_books[book].Name, library_books[book].Artist)
|
||||
this_book.path = self.path_template % (library_books[book].Name,
|
||||
library_books[book].Artist)
|
||||
try:
|
||||
this_book.datetime = parse_date(str(library_books[book].DateAdded)).timetuple()
|
||||
except:
|
||||
pass
|
||||
this_book.db_id = None
|
||||
this_book.device_collections = []
|
||||
this_book.library_id = library_books[book]
|
||||
this_book.size = library_books[book].Size
|
||||
# Hack to discover if we're running in GUI environment
|
||||
if self.report_progress is not None:
|
||||
this_book.thumbnail = self._generate_thumbnail(this_book.path, library_books[book])
|
||||
else:
|
||||
this_book.thumbnail = None
|
||||
booklist.add_book(this_book, False)
|
||||
|
||||
cached_books[this_book.path] = {
|
||||
'title':library_books[book].Name,
|
||||
'author':library_books[book].Artist,
|
||||
'lib_book':library_books[book],
|
||||
'uuid': library_books[book].Composer,
|
||||
'format': 'pdf' if library_books[book].KindAsString.startswith('PDF') else 'epub'
|
||||
}
|
||||
|
||||
if self.report_progress is not None:
|
||||
self.report_progress(i+1/book_count,
|
||||
_('%d of %d') % (i+1, book_count))
|
||||
|
||||
finally:
|
||||
pythoncom.CoUninitialize()
|
||||
|
||||
if self.report_progress is not None:
|
||||
self.report_progress(1.0, _('finished'))
|
||||
self.cached_books = cached_books
|
||||
if DEBUG:
|
||||
self._dump_booklist(booklist, 'returning from books()', indent=2)
|
||||
self._dump_cached_books('returning from books()',indent=2)
|
||||
return booklist
|
||||
|
||||
else:
|
||||
return BookList(self.log)
|
||||
|
||||
def disconnect_from_folder(self):
|
||||
'''
|
||||
'''
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC:disconnect_from_folder()")
|
||||
self.connected = False
|
||||
|
||||
def eject(self):
|
||||
'''
|
||||
Un-mount / eject the device from the OS. This does not check if there
|
||||
are pending GUI jobs that need to communicate with the device.
|
||||
'''
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC:eject()")
|
||||
self.iTunes = None
|
||||
self.connected = False
|
||||
|
||||
def free_space(self, end_session=True):
|
||||
"""
|
||||
Get free space available on the mountpoints:
|
||||
1. Main memory
|
||||
2. Card A
|
||||
3. Card B
|
||||
|
||||
@return: A 3 element list with free space in bytes of (1, 2, 3). If a
|
||||
particular device doesn't have any of these locations it should return -1.
|
||||
"""
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC:free_space()")
|
||||
free_space = 0
|
||||
if isosx:
|
||||
s = os.statvfs(os.sep)
|
||||
free_space = s.f_bavail * s.f_frsize
|
||||
elif iswindows:
|
||||
free_bytes = ctypes.c_ulonglong(0)
|
||||
ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(os.sep), None, None, ctypes.pointer(free_bytes))
|
||||
free_space = free_bytes.value
|
||||
return (free_space,-1,-1)
|
||||
|
||||
def get_device_information(self, end_session=True):
|
||||
"""
|
||||
Ask device for device information. See L{DeviceInfoQuery}.
|
||||
@return: (device name, device version, software version on device, mime type)
|
||||
"""
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC:get_device_information()")
|
||||
|
||||
return ('iTunes','hw v1.0','sw v1.0', 'mime type normally goes here')
|
||||
|
||||
def is_usb_connected(self, devices_on_system, debug=False,
|
||||
only_presence=False):
|
||||
return self.connected, self
|
||||
|
||||
def sync_booklists(self, booklists, end_session=True):
|
||||
'''
|
||||
Update metadata on device.
|
||||
@param booklists: A tuple containing the result of calls to
|
||||
(L{books}(oncard=None), L{books}(oncard='carda'),
|
||||
L{books}(oncard='cardb')).
|
||||
'''
|
||||
|
||||
if DEBUG:
|
||||
self.log.info("ITUNES_ASYNC.sync_booklists()")
|
||||
|
||||
# Inform user of any problem books
|
||||
if self.problem_titles:
|
||||
raise UserFeedback(self.problem_msg,
|
||||
details='\n'.join(self.problem_titles), level=UserFeedback.WARN)
|
||||
self.problem_titles = []
|
||||
self.problem_msg = None
|
||||
self.update_list = []
|
||||
|
||||
class BookList(list):
|
||||
'''
|
||||
|
@ -29,6 +29,7 @@ from calibre.utils.filenames import ascii_filename
|
||||
from calibre.devices.errors import FreeSpaceError
|
||||
from calibre.utils.smtp import compose_mail, sendmail, extract_email_address, \
|
||||
config as email_config
|
||||
from calibre.devices.apple.driver import ITUNES_ASYNC
|
||||
from calibre.devices.folder_device.driver import FOLDER_DEVICE
|
||||
|
||||
# }}}
|
||||
@ -105,10 +106,11 @@ class DeviceManager(Thread): # {{{
|
||||
self.scanner = DeviceScanner()
|
||||
self.connected_device = None
|
||||
self.ejected_devices = set([])
|
||||
self.connected_device_is_folder = False
|
||||
self.folder_connection_requests = Queue.Queue(0)
|
||||
self.mount_connection_requests = Queue.Queue(0)
|
||||
self.open_feedback_slot = open_feedback_slot
|
||||
|
||||
ITUNES_STRING = '#itunes#'
|
||||
|
||||
def report_progress(self, *args):
|
||||
pass
|
||||
|
||||
@ -120,7 +122,7 @@ class DeviceManager(Thread): # {{{
|
||||
def device(self):
|
||||
return self.connected_device
|
||||
|
||||
def do_connect(self, connected_devices, is_folder_device):
|
||||
def do_connect(self, connected_devices, device_kind):
|
||||
for dev, detected_device in connected_devices:
|
||||
if dev.OPEN_FEEDBACK_MESSAGE is not None:
|
||||
self.open_feedback_slot(dev.OPEN_FEEDBACK_MESSAGE)
|
||||
@ -133,8 +135,8 @@ class DeviceManager(Thread): # {{{
|
||||
traceback.print_exc()
|
||||
continue
|
||||
self.connected_device = dev
|
||||
self.connected_device_is_folder = is_folder_device
|
||||
self.connected_slot(True, is_folder_device)
|
||||
self.connected_device_kind = device_kind
|
||||
self.connected_slot(True, device_kind)
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -152,7 +154,7 @@ class DeviceManager(Thread): # {{{
|
||||
if self.connected_device in self.ejected_devices:
|
||||
self.ejected_devices.remove(self.connected_device)
|
||||
else:
|
||||
self.connected_slot(False, self.connected_device_is_folder)
|
||||
self.connected_slot(False, self.connected_device_kind)
|
||||
self.connected_device = None
|
||||
|
||||
def detect_device(self):
|
||||
@ -174,18 +176,18 @@ class DeviceManager(Thread): # {{{
|
||||
possibly_connected_devices.append((device, detected_device))
|
||||
if possibly_connected_devices:
|
||||
if not self.do_connect(possibly_connected_devices,
|
||||
is_folder_device=False):
|
||||
device_kind='device'):
|
||||
prints('Connect to device failed, retrying in 5 seconds...')
|
||||
time.sleep(5)
|
||||
if not self.do_connect(possibly_connected_devices,
|
||||
is_folder_device=False):
|
||||
device_kind='usb'):
|
||||
prints('Device connect failed again, giving up')
|
||||
|
||||
def umount_device(self, *args):
|
||||
if self.is_device_connected and not self.job_manager.has_device_jobs():
|
||||
self.connected_device.eject()
|
||||
self.ejected_devices.add(self.connected_device)
|
||||
self.connected_slot(False, self.connected_device_is_folder)
|
||||
self.connected_slot(False, self.connected_device_kind)
|
||||
|
||||
def next(self):
|
||||
if not self.jobs.empty():
|
||||
@ -196,20 +198,19 @@ class DeviceManager(Thread): # {{{
|
||||
|
||||
def run(self):
|
||||
while self.keep_going:
|
||||
folder_path = None
|
||||
kls = None
|
||||
while True:
|
||||
try:
|
||||
folder_path = self.folder_connection_requests.get_nowait()
|
||||
(kls,device_kind, folder_path) = \
|
||||
self.mount_connection_requests.get_nowait()
|
||||
except Queue.Empty:
|
||||
break
|
||||
if not folder_path or not os.access(folder_path, os.R_OK):
|
||||
folder_path = None
|
||||
if not self.is_device_connected and folder_path is not None:
|
||||
if kls is not None:
|
||||
try:
|
||||
dev = FOLDER_DEVICE(folder_path)
|
||||
self.do_connect([[dev, None],], is_folder_device=True)
|
||||
dev = kls(folder_path)
|
||||
self.do_connect([[dev, None],], device_kind=device_kind)
|
||||
except:
|
||||
prints('Unable to open folder as device', folder_path)
|
||||
prints('Unable to open %s as device (%s)'%(device_kind, folder_path))
|
||||
traceback.print_exc()
|
||||
else:
|
||||
self.detect_device()
|
||||
@ -251,13 +252,14 @@ class DeviceManager(Thread): # {{{
|
||||
|
||||
# This will be called on the GUI thread. Because of this, we must store
|
||||
# information that the scanner thread will use to do the real work.
|
||||
def connect_to_folder(self, path):
|
||||
self.folder_connection_requests.put(path)
|
||||
# Note: this is used for iTunes
|
||||
def mount_device(self, kls, kind, path):
|
||||
self.mount_connection_requests.put((kls, kind, path))
|
||||
|
||||
# This is called on the GUI thread. No problem here, because it calls the
|
||||
# device driver, telling it to tell the scanner when it passes by that the
|
||||
# folder has disconnected.
|
||||
def disconnect_folder(self):
|
||||
# folder has disconnected. Note: this is also used for iTunes
|
||||
def unmount_device(self):
|
||||
if self.connected_device is not None:
|
||||
if hasattr(self.connected_device, 'disconnect_from_folder'):
|
||||
# As we are on the wrong thread, this call must *not* do
|
||||
@ -375,7 +377,8 @@ class DeviceMenu(QMenu): # {{{
|
||||
|
||||
fetch_annotations = pyqtSignal()
|
||||
connect_to_folder = pyqtSignal()
|
||||
disconnect_from_folder = pyqtSignal()
|
||||
connect_to_itunes = pyqtSignal()
|
||||
disconnect_mounted_device = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QMenu.__init__(self, parent)
|
||||
@ -492,8 +495,18 @@ class DeviceMenu(QMenu): # {{{
|
||||
|
||||
mitem = self.addAction(QIcon(I('eject.svg')), _('Disconnect from folder'))
|
||||
mitem.setEnabled(False)
|
||||
mitem.triggered.connect(lambda x : self.disconnect_from_folder.emit())
|
||||
self.disconnect_from_folder_action = mitem
|
||||
mitem.triggered.connect(lambda x : self.disconnect_mounted_device.emit())
|
||||
self.disconnect_mounted_device_action = mitem
|
||||
|
||||
mitem = self.addAction(QIcon(I('document_open.svg')), _('Connect to iTunes (BETA TEST)'))
|
||||
mitem.setEnabled(True)
|
||||
mitem.triggered.connect(lambda x : self.connect_to_itunes.emit())
|
||||
self.connect_to_itunes_action = mitem
|
||||
|
||||
mitem = self.addAction(QIcon(I('eject.svg')), _('Disconnect from iTunes (BETA TEST)'))
|
||||
mitem.setEnabled(False)
|
||||
mitem.triggered.connect(lambda x : self.disconnect_mounted_device.emit())
|
||||
self.disconnect_from_itunes_action = mitem
|
||||
|
||||
self.addSeparator()
|
||||
self.addMenu(self.set_default_menu)
|
||||
@ -630,11 +643,16 @@ class DeviceMixin(object): # {{{
|
||||
def connect_to_folder(self):
|
||||
dir = choose_dir(self, 'Select Device Folder',
|
||||
_('Select folder to open as device'))
|
||||
if dir is not None:
|
||||
self.device_manager.connect_to_folder(dir)
|
||||
kls = FOLDER_DEVICE
|
||||
self.device_manager.mount_device(kls=kls, kind='folder', path=dir)
|
||||
|
||||
def disconnect_from_folder(self):
|
||||
self.device_manager.disconnect_folder()
|
||||
def connect_to_itunes(self):
|
||||
kls = ITUNES_ASYNC
|
||||
self.device_manager.mount_device(kls=kls, kind='itunes', path=None)
|
||||
|
||||
# disconnect from both folder and itunes devices
|
||||
def disconnect_mounted_device(self):
|
||||
self.device_manager.unmount_device()
|
||||
|
||||
def _sync_action_triggered(self, *args):
|
||||
m = getattr(self, '_sync_menu', None)
|
||||
@ -649,16 +667,22 @@ class DeviceMixin(object): # {{{
|
||||
self.dispatch_sync_event)
|
||||
self._sync_menu.fetch_annotations.connect(self.fetch_annotations)
|
||||
self._sync_menu.connect_to_folder.connect(self.connect_to_folder)
|
||||
self._sync_menu.disconnect_from_folder.connect(self.disconnect_from_folder)
|
||||
self._sync_menu.connect_to_itunes.connect(self.connect_to_itunes)
|
||||
self._sync_menu.disconnect_mounted_device.connect(self.disconnect_mounted_device)
|
||||
if self.device_connected:
|
||||
self._sync_menu.connect_to_folder_action.setEnabled(False)
|
||||
self._sync_menu.connect_to_itunes_action.setEnabled(False)
|
||||
if self.device_connected == 'folder':
|
||||
self._sync_menu.disconnect_from_folder_action.setEnabled(True)
|
||||
self._sync_menu.disconnect_mounted_device_action.setEnabled(True)
|
||||
if self.device_connected == 'itunes':
|
||||
self._sync_menu.disconnect_from_itunes_action.setEnabled(True)
|
||||
else:
|
||||
self._sync_menu.disconnect_from_folder_action.setEnabled(False)
|
||||
self._sync_menu.disconnect_mounted_device_action.setEnabled(False)
|
||||
else:
|
||||
self._sync_menu.connect_to_folder_action.setEnabled(True)
|
||||
self._sync_menu.disconnect_from_folder_action.setEnabled(False)
|
||||
self._sync_menu.disconnect_mounted_device_action.setEnabled(False)
|
||||
self._sync_menu.connect_to_itunes_action.setEnabled(True)
|
||||
self._sync_menu.disconnect_from_itunes_action.setEnabled(False)
|
||||
|
||||
|
||||
|
||||
@ -694,26 +718,31 @@ class DeviceMixin(object): # {{{
|
||||
|
||||
# Device connected {{{
|
||||
|
||||
def set_device_menu_items_state(self, connected, is_folder_device):
|
||||
def set_device_menu_items_state(self, connected, device_kind):
|
||||
if connected:
|
||||
self._sync_menu.connect_to_folder_action.setEnabled(False)
|
||||
if is_folder_device:
|
||||
self._sync_menu.disconnect_from_folder_action.setEnabled(True)
|
||||
self._sync_menu.connect_to_itunes_action.setEnabled(False)
|
||||
if device_kind == 'folder':
|
||||
self._sync_menu.disconnect_mounted_device_action.setEnabled(True)
|
||||
elif device_kind == 'itunes':
|
||||
self._sync_menu.disconnect_from_itunes_action.setEnabled(True)
|
||||
self._sync_menu.enable_device_actions(True,
|
||||
self.device_manager.device.card_prefix(),
|
||||
self.device_manager.device)
|
||||
self.eject_action.setEnabled(True)
|
||||
else:
|
||||
self._sync_menu.connect_to_folder_action.setEnabled(True)
|
||||
self._sync_menu.disconnect_from_folder_action.setEnabled(False)
|
||||
self._sync_menu.connect_to_itunes_action.setEnabled(True)
|
||||
self._sync_menu.disconnect_mounted_device_action.setEnabled(False)
|
||||
self._sync_menu.disconnect_from_itunes_action.setEnabled(False)
|
||||
self._sync_menu.enable_device_actions(False)
|
||||
self.eject_action.setEnabled(False)
|
||||
|
||||
def device_detected(self, connected, is_folder_device):
|
||||
def device_detected(self, connected, device_kind):
|
||||
'''
|
||||
Called when a device is connected to the computer.
|
||||
'''
|
||||
self.set_device_menu_items_state(connected, is_folder_device)
|
||||
self.set_device_menu_items_state(connected, device_kind)
|
||||
if connected:
|
||||
self.device_manager.get_device_information(\
|
||||
Dispatcher(self.info_read))
|
||||
@ -722,7 +751,7 @@ class DeviceMixin(object): # {{{
|
||||
self.status_bar.show_message(_('Device: ')+\
|
||||
self.device_manager.device.__class__.get_gui_name()+\
|
||||
_(' detected.'), 3000)
|
||||
self.device_connected = 'device' if not is_folder_device else 'folder'
|
||||
self.device_connected = device_kind
|
||||
self.location_view.model().device_connected(self.device_manager.device)
|
||||
self.refresh_ondevice_info (device_connected = True, reset_only = True)
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user