|
new file 100644
|
|
|
from PyQt5 import QtGui, QtCore, QtWidgets
|
|
|
from PyQt5.QtWidgets import QSizePolicy
|
|
|
|
|
|
from cdemu import CDEmuException
|
|
|
from .device_menu import QDeviceMenu
|
|
|
from mount import mount
|
|
|
from urllib.parse import unquote
|
|
|
|
|
|
class KCDEmuDevice(QtWidgets.QLabel):
|
|
|
def __init__(self, device, width=32, height=32):
|
|
|
super().__init__()
|
|
|
self.setAcceptDrops(True)
|
|
|
self.device = None
|
|
|
self.empty_icon = ':/dropper_empty.png'
|
|
|
self.full_icon = ':/dropper_full.png'
|
|
|
self.refresh(device)
|
|
|
self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
|
|
|
self.setAlignment(QtCore.Qt.AlignCenter)
|
|
|
self.setMinimumSize(width, height)
|
|
|
self.setBaseSize(width, height)
|
|
|
self.setMaximumSize(width, height)
|
|
|
self.ctx_menu = QDeviceMenu(device)
|
|
|
|
|
|
def set_size(self, width, height):
|
|
|
self.setMinimumSize(width, height)
|
|
|
self.setBaseSize(width, height)
|
|
|
self.setMaximumSize(width, height)
|
|
|
self.adjustSize()
|
|
|
|
|
|
def set_icons(self, empty_icon, full_icon):
|
|
|
self.empty_icon = empty_icon
|
|
|
self.full_icon = full_icon
|
|
|
self.refresh()
|
|
|
|
|
|
def refresh(self, device=None):
|
|
|
if device is not None:
|
|
|
if self.device and self.device != device:
|
|
|
self.device.remove_handler('change')
|
|
|
if self.device != device:
|
|
|
self.device = device
|
|
|
self.device.add_handler('change', self.refresh)
|
|
|
self.setText(
|
|
|
'<img src="{}"></img>'.format(
|
|
|
self.full_icon if self.device.get_img() else self.empty_icon))
|
|
|
if self.device.get_img():
|
|
|
self.setToolTip('Click to unload "{}"'.format(self.device.get_img()))
|
|
|
else:
|
|
|
self.setToolTip('Click to load')
|
|
|
|
|
|
def dragEnterEvent(self, event):
|
|
|
if event.mimeData().hasFormat('text/plain'):
|
|
|
text = event.mimeData().text()
|
|
|
if text.startswith('file://'):
|
|
|
event.acceptProposedAction()
|
|
|
|
|
|
def dragLeaveEvent(self, event):
|
|
|
pass
|
|
|
|
|
|
def dropEvent(self, event):
|
|
|
if event.mimeData().hasFormat('text/plain'):
|
|
|
text = event.mimeData().text()
|
|
|
if text.startswith('file://'):
|
|
|
text = unquote(text.replace('file://', '').replace('\n', '').replace('\r', ''))
|
|
|
self.device.load(text)
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
if event.button() == QtCore.Qt.RightButton:
|
|
|
self.ctx_menu.popup(QtCore.QPoint(event.globalX(), event.globalY()))
|
|
|
elif event.button() == QtCore.Qt.LeftButton:
|
|
|
if self.device.get_img():
|
|
|
try:
|
|
|
self.device.unload()
|
|
|
except Exception as e:
|
|
|
QtWidgets.QMessageBox.critical(None, 'Error', str(e))
|
|
|
else:
|
|
|
fd = QtWidgets.QFileDialog(self)
|
|
|
fd.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen)
|
|
|
if fd.exec() == QtWidgets.QDialog.Accepted:
|
|
|
self.device.load(fd.selectedFiles()[0])
|
|
|
|
|
|
class KCDEmuDropperWidget(QtWidgets.QWidget):
|
|
|
changed = QtCore.pyqtSignal()
|
|
|
|
|
|
def __init__(self, cdemu, config):
|
|
|
"""
|
|
|
:type cdemu: cdemu.CDEmu
|
|
|
:type config: config.config.ConfigFile
|
|
|
"""
|
|
|
super().__init__(None, QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
|
|
|
self.config = config
|
|
|
self.setWindowTitle('KCDEmu')
|
|
|
self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum))
|
|
|
layout = QtWidgets.QHBoxLayout(self)
|
|
|
layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
|
|
layout.setContentsMargins(0,0,0,0)
|
|
|
layout.setSpacing(0)
|
|
|
self.setLayout(layout)
|
|
|
self.cdemu = cdemu
|
|
|
self.devices = []
|
|
|
|
|
|
self.cdemu.add_handler('devices_changed', self.on_devices_changed)
|
|
|
self.cdemu.add_handler('daemon_stopped', self.on_daemon_stopped)
|
|
|
self.cdemu.add_handler('daemon_started', self.on_daemon_started)
|
|
|
self.config.add_handler('changed', self.reload_config)
|
|
|
self.reload_config()
|
|
|
|
|
|
if self.cdemu.is_daemon_ready():
|
|
|
self.on_devices_changed()
|
|
|
|
|
|
def on_devices_changed(self, number=None):
|
|
|
devices = self.cdemu.get_devices()
|
|
|
while len(self.devices) > len(devices):
|
|
|
dev = self.devices.pop()
|
|
|
self.layout().removeWidget(dev)
|
|
|
dev.hide()
|
|
|
for index, device in enumerate(devices):
|
|
|
if len(self.devices) <= index:
|
|
|
icon_size = self.config.get_icon_size()
|
|
|
dev = KCDEmuDevice(device, icon_size[0], icon_size[1])
|
|
|
dev.set_icons(self.config.get_empty_icon(), self.config.get_full_icon())
|
|
|
self.devices.append(dev)
|
|
|
self.layout().addWidget(dev)
|
|
|
else:
|
|
|
self.devices[index].refresh(device)
|
|
|
self.updateGeometry()
|
|
|
|
|
|
def resizeEvent(self, event):
|
|
|
print(self.sizeHint().width())
|
|
|
self.changed.emit()
|
|
|
|
|
|
def on_daemon_stopped(self):
|
|
|
while len(self.devices) > 0:
|
|
|
dev = self.devices.pop()
|
|
|
self.layout().removeWidget(dev)
|
|
|
|
|
|
def on_daemon_started(self):
|
|
|
self.on_devices_changed()
|
|
|
|
|
|
def reload_config(self):
|
|
|
for i in range(self.layout().count()):
|
|
|
widget = self.layout().itemAt(i).widget()
|
|
|
if widget:
|
|
|
icon_size = self.config.get_icon_size()
|
|
|
widget.set_size(icon_size[0], icon_size[1])
|
|
|
widget.set_icons(self.config.get_empty_icon(), self.config.get_full_icon())
|