You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.7 KiB
181 lines
5.7 KiB
# coding:utf-8
|
|
from typing import List
|
|
from pathlib import Path
|
|
|
|
from PySide6.QtCore import Qt, Signal, QRectF
|
|
from PySide6.QtGui import QPainter, QIcon
|
|
from PySide6.QtWidgets import (QPushButton, QFileDialog, QWidget, QLabel,
|
|
QHBoxLayout, QToolButton)
|
|
|
|
from ...common.config import ConfigItem, qconfig
|
|
from ...common.icon import drawIcon
|
|
from ...common.icon import FluentIcon as FIF
|
|
from ..dialog_box.dialog import Dialog
|
|
from .expand_setting_card import ExpandSettingCard
|
|
|
|
|
|
class ToolButton(QToolButton):
|
|
""" Tool button """
|
|
|
|
def __init__(self, icon, size: tuple, iconSize: tuple, parent=None):
|
|
super().__init__(parent=parent)
|
|
self.isPressed = False
|
|
self._icon = icon
|
|
self._iconSize = iconSize
|
|
self.setFixedSize(*size)
|
|
|
|
def mousePressEvent(self, e):
|
|
self.isPressed = True
|
|
super().mousePressEvent(e)
|
|
|
|
def mouseReleaseEvent(self, e):
|
|
self.isPressed = False
|
|
super().mouseReleaseEvent(e)
|
|
|
|
def paintEvent(self, e):
|
|
super().paintEvent(e)
|
|
painter = QPainter(self)
|
|
painter.setRenderHints(QPainter.Antialiasing |
|
|
QPainter.SmoothPixmapTransform)
|
|
painter.setOpacity(0.63 if self.isPressed else 1)
|
|
w, h = self._iconSize
|
|
drawIcon(self._icon, painter, QRectF(
|
|
(self.width()-w)/2, (self.height()-h)/2, w, h))
|
|
|
|
|
|
class PushButton(QPushButton):
|
|
""" Push button """
|
|
|
|
def __init__(self, icon, text: str, parent=None):
|
|
super().__init__(parent=parent)
|
|
self.isPressed = False
|
|
self._icon = icon
|
|
self.setText(text)
|
|
|
|
def mousePressEvent(self, e):
|
|
self.isPressed = True
|
|
super().mousePressEvent(e)
|
|
|
|
def mouseReleaseEvent(self, e):
|
|
self.isPressed = False
|
|
super().mouseReleaseEvent(e)
|
|
|
|
def paintEvent(self, e):
|
|
super().paintEvent(e)
|
|
painter = QPainter(self)
|
|
painter.setRenderHints(QPainter.Antialiasing)
|
|
painter.setOpacity(0.63 if self.isPressed else 1)
|
|
drawIcon(self._icon, painter, QRectF(12, 8, 16, 16))
|
|
|
|
|
|
class FolderItem(QWidget):
|
|
""" Folder item """
|
|
|
|
removed = Signal(QWidget)
|
|
|
|
def __init__(self, folder: str, parent=None):
|
|
super().__init__(parent=parent)
|
|
self.folder = folder
|
|
self.hBoxLayout = QHBoxLayout(self)
|
|
self.folderLabel = QLabel(folder, self)
|
|
self.removeButton = ToolButton(FIF.CLOSE, (39, 29), (12, 12), self)
|
|
|
|
self.setFixedHeight(53)
|
|
self.hBoxLayout.setContentsMargins(48, 0, 60, 0)
|
|
self.hBoxLayout.addWidget(self.folderLabel, 0, Qt.AlignLeft)
|
|
self.hBoxLayout.addSpacing(16)
|
|
self.hBoxLayout.addStretch(1)
|
|
self.hBoxLayout.addWidget(self.removeButton, 0, Qt.AlignRight)
|
|
self.hBoxLayout.setAlignment(Qt.AlignVCenter)
|
|
|
|
self.removeButton.clicked.connect(
|
|
lambda: self.removed.emit(self))
|
|
|
|
|
|
class FolderListSettingCard(ExpandSettingCard):
|
|
""" Folder list setting card """
|
|
|
|
folderChanged = Signal(list)
|
|
|
|
def __init__(self, configItem: ConfigItem, title: str, content: str = None, directory="./", parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
configItem: RangeConfigItem
|
|
configuration item operated by the card
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
directory: str
|
|
working directory of file dialog
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(FIF.FOLDER, title, content, parent)
|
|
self.configItem = configItem
|
|
self._dialogDirectory = directory
|
|
self.addFolderButton = PushButton(FIF.FOLDER_ADD, self.tr('Add folder'), self)
|
|
|
|
self.folders = qconfig.get(configItem).copy() # type:List[str]
|
|
self.__initWidget()
|
|
|
|
def __initWidget(self):
|
|
self.addWidget(self.addFolderButton)
|
|
|
|
# initialize layout
|
|
self.viewLayout.setSpacing(0)
|
|
self.viewLayout.setAlignment(Qt.AlignTop)
|
|
self.viewLayout.setContentsMargins(0, 0, 0, 0)
|
|
for folder in self.folders:
|
|
self.__addFolderItem(folder)
|
|
|
|
self.addFolderButton.clicked.connect(self.__showFolderDialog)
|
|
|
|
def __showFolderDialog(self):
|
|
""" show folder dialog """
|
|
folder = QFileDialog.getExistingDirectory(
|
|
self, self.tr("Choose folder"), self._dialogDirectory)
|
|
|
|
if not folder or folder in self.folders:
|
|
return
|
|
|
|
self.__addFolderItem(folder)
|
|
self.folders.append(folder)
|
|
qconfig.set(self.configItem, self.folders)
|
|
self.folderChanged.emit(self.folders)
|
|
|
|
def __addFolderItem(self, folder: str):
|
|
""" add folder item """
|
|
item = FolderItem(folder, self.view)
|
|
item.removed.connect(self.__showConfirmDialog)
|
|
self.viewLayout.addWidget(item)
|
|
self._adjustViewSize()
|
|
|
|
def __showConfirmDialog(self, item: FolderItem):
|
|
""" show confirm dialog """
|
|
name = Path(item.folder).name
|
|
title = self.tr('Are you sure you want to delete the folder?')
|
|
content = self.tr("If you delete the ") + f'"{name}"' + \
|
|
self.tr(" folder and remove it from the list, the folder will no "
|
|
"longer appear in the list, but will not be deleted.")
|
|
w = Dialog(title, content, self.window())
|
|
w.yesSignal.connect(lambda: self.__removeFolder(item))
|
|
w.exec_()
|
|
|
|
def __removeFolder(self, item: FolderItem):
|
|
""" remove folder """
|
|
if item.folder not in self.folders:
|
|
return
|
|
|
|
self.folders.remove(item.folder)
|
|
self.viewLayout.deleteWidget(item)
|
|
self._adjustViewSize()
|
|
|
|
self.folderChanged.emit(self.folders)
|
|
qconfig.set(self.configItem, self.folders)
|