Files
LorenEteval_Furious/Furious/Widget/Widget.py
T
2023-08-11 17:57:20 +08:00

275 lines
7.2 KiB
Python

from Furious.Gui.Action import Action, Seperator
from Furious.Utility.Constants import APP
from Furious.Utility.Utility import (
StateContext,
SupportConnectedCallback,
bootstrapIcon,
moveToCenter,
)
from Furious.Utility.Translator import Translatable, gettext as _
from PySide6 import QtCore
from PySide6.QtGui import QBrush, QColor, QFont
from PySide6.QtWidgets import (
QHeaderView,
QInputDialog,
QLineEdit,
QListWidget,
QMenu,
QMessageBox,
QPlainTextEdit,
QPushButton,
QStyledItemDelegate,
QTableWidget,
QTabWidget,
QTextBrowser,
)
class HeaderView(SupportConnectedCallback, QHeaderView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setSectionsClickable(True)
self.setStyleSheet(
f'QHeaderView::section:hover {{ background-color: #008AE1; }}'
)
def connectedCallback(self):
self.setStyleSheet(
f'QHeaderView::section:hover {{ background-color: #EB212E; }}'
)
def disconnectedCallback(self):
self.setStyleSheet(
f'QHeaderView::section:hover {{ background-color: #008AE1; }}'
)
class ListWidget(QListWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@property
def selectedIndex(self):
return sorted(list(set(index.row() for index in self.selectedIndexes())))
class Menu(Translatable, QMenu):
def __init__(self, *actions, **kwargs):
super().__init__(**kwargs)
for action in actions:
if isinstance(action, Seperator):
self.addSeparator()
else:
assert isinstance(action, Action)
self.addAction(action)
self.setStyleSheet(
f'QMenu::item {{'
f' background-color: solid;'
f'}}'
f''
f'QMenu::item:selected {{'
f' background-color: #43ACED;'
f'}}'
)
def retranslate(self):
with StateContext(self):
self.setTitle(_(self.title()))
class MessageBox(Translatable, SupportConnectedCallback, QMessageBox):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
def moveToCenter(self):
moveToCenter(self, self.parentWidget())
return self
def connectedCallback(self):
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
def disconnectedCallback(self):
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
def retranslate(self):
with StateContext(self):
self.setWindowTitle(_(self.windowTitle()))
self.setText(_(self.text()))
try:
self.setInformativeText(_(self.informativeText()))
except KeyError:
# Any translatable informative text
pass
for button in self.buttons():
if button.text().count('OK') > 0:
# &OK...
pass
else:
button.setText(_(button.text()))
self.moveToCenter()
def exec(self):
self.show()
self.moveToCenter()
return super().exec()
def open(self):
self.show()
self.moveToCenter()
return super().open()
class PushButton(Translatable, QPushButton):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def retranslate(self):
self.setText(_(self.text()))
class StyledItemDelegate(QStyledItemDelegate):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def createEditor(self, parent, option, index):
editor = QLineEdit(parent)
editor.setFont(QFont(APP().customFontName))
return editor
class TableWidget(QTableWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@property
def selectedIndex(self):
return sorted(list(set(index.row() for index in self.selectedIndexes())))
def setSelectionColor(self, color):
self.setStyleSheet(f'QTableWidget {{ selection-background-color: {color}; }}')
def activateItemByIndex(self, index, activate=True):
if activate:
for column in range(self.columnCount()):
item = self.item(int(index), column)
if item is None:
# Do nothing
continue
font = item.font()
font.setBold(True)
item.setFont(font)
if APP().tray is None:
# Initializing
item.setForeground(QColor('#008AE1'))
else:
if APP().tray.ConnectAction.isConnected():
item.setForeground(QColor('#EB212E'))
else:
item.setForeground(QColor('#008AE1'))
else:
for column in range(self.columnCount()):
item = self.item(int(index), column)
if item is None:
# Do nothing
continue
font = item.font()
font.setBold(False)
item.setFont(font)
item.setForeground(QBrush())
class TabWidget(Translatable, QTabWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def retranslate(self):
for index in range(self.count()):
self.setTabText(index, _(self.tabText(index)))
class ZoomablePlainTextEdit(QPlainTextEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@staticmethod
def getIndent(line):
indent = ''
for char in line:
if char.isspace():
indent += char
else:
break
return indent
def smartIndent(self, event):
cursor = self.textCursor()
indent = self.getIndent(cursor.block().text())
# Do newline action
super().keyPressEvent(event)
# Add last line indent
cursor.insertText(indent)
self.setTextCursor(cursor)
def keyPressEvent(self, event):
if (
event.key() == QtCore.Qt.Key.Key_Return
or event.key() == QtCore.Qt.Key.Key_Enter
):
self.smartIndent(event)
else:
super().keyPressEvent(event)
def wheelEvent(self, event):
if event.modifiers() == QtCore.Qt.KeyboardModifier.ControlModifier:
delta = event.angleDelta().y()
if delta > 0:
self.zoomIn()
if delta < 0:
self.zoomOut()
else:
super().wheelEvent(event)
class ZoomableTextBrowser(QTextBrowser):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def wheelEvent(self, event):
if event.modifiers() == QtCore.Qt.KeyboardModifier.ControlModifier:
delta = event.angleDelta().y()
if delta > 0:
self.zoomIn()
if delta < 0:
self.zoomOut()
else:
super().wheelEvent(event)