def _int_field( self, min_val: int, max_val: int, placeholder: str = "", tooltip: str = "", ) -> QLineEdit: result = QLineEdit() # TODO derive the max width from the text repr of min_val, max_val. result.setMaximumWidth(self._FIELD_WIDTH) result.setAlignment(Qt.AlignRight) validator = QIntValidator(min_val, max_val) result.setValidator(validator) if placeholder: result.setPlaceholderText(placeholder) if tooltip: result.setToolTip(tooltip) return result
class TransferWidget(AbstractOperationDetails): def __init__(self, parent=None): AbstractOperationDetails.__init__(self, parent) self.name = "Transfer" self.operation_type = LedgerTransaction.Transfer self.from_date_label = QLabel(self) self.from_account_label = QLabel(self) self.from_amount_label = QLabel(self) self.to_date_label = QLabel(self) self.to_account_label = QLabel(self) self.to_amount_label = QLabel(self) self.fee_account_label = QLabel(self) self.fee_amount_label = QLabel(self) self.comment_label = QLabel(self) self.arrow_account = QLabel(self) self.copy_date_btn = QPushButton(self) self.copy_amount_btn = QPushButton(self) self.main_label.setText(self.tr("Transfer")) self.from_date_label.setText(self.tr("Date/Time")) self.from_account_label.setText(self.tr("From")) self.from_amount_label.setText(self.tr("Amount")) self.to_date_label.setText(self.tr("Date/Time")) self.to_account_label.setText(self.tr("To")) self.to_amount_label.setText(self.tr("Amount")) self.fee_account_label.setText(self.tr("Fee from")) self.fee_amount_label.setText(self.tr("Fee amount")) self.comment_label.setText(self.tr("Note")) self.arrow_account.setText(" ➜ ") self.copy_date_btn.setText("➜") self.copy_date_btn.setFixedWidth( self.copy_date_btn.fontMetrics().horizontalAdvance("XXXX")) self.copy_amount_btn.setText("➜") self.copy_amount_btn.setFixedWidth( self.copy_amount_btn.fontMetrics().horizontalAdvance("XXXX")) self.withdrawal_timestamp = QDateTimeEdit(self) self.withdrawal_timestamp.setCalendarPopup(True) self.withdrawal_timestamp.setTimeSpec(Qt.UTC) self.withdrawal_timestamp.setFixedWidth( self.withdrawal_timestamp.fontMetrics().horizontalAdvance( "00/00/0000 00:00:00") * 1.25) self.withdrawal_timestamp.setDisplayFormat("dd/MM/yyyy hh:mm:ss") self.deposit_timestamp = QDateTimeEdit(self) self.deposit_timestamp.setCalendarPopup(True) self.deposit_timestamp.setTimeSpec(Qt.UTC) self.deposit_timestamp.setFixedWidth( self.deposit_timestamp.fontMetrics().horizontalAdvance( "00/00/0000 00:00:00") * 1.25) self.deposit_timestamp.setDisplayFormat("dd/MM/yyyy hh:mm:ss") self.from_account_widget = AccountSelector(self) self.to_account_widget = AccountSelector(self) self.fee_account_widget = AccountSelector(self) self.withdrawal = QLineEdit(self) self.withdrawal.setAlignment(Qt.AlignRight) self.deposit = QLineEdit(self) self.deposit.setAlignment(Qt.AlignRight) self.fee = QLineEdit(self) self.fee.setAlignment(Qt.AlignRight) self.comment = QLineEdit(self) self.layout.addWidget(self.from_date_label, 1, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.from_account_label, 2, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.from_amount_label, 3, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.comment_label, 5, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.withdrawal_timestamp, 1, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.from_account_widget, 2, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.withdrawal, 3, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.comment, 5, 1, 1, 4) self.layout.addWidget(self.copy_date_btn, 1, 2, 1, 1) self.layout.addWidget(self.arrow_account, 2, 2, 1, 1, Qt.AlignCenter) self.layout.addWidget(self.copy_amount_btn, 3, 2, 1, 1) self.layout.addWidget(self.to_date_label, 1, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.to_account_label, 2, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.to_amount_label, 3, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.fee_account_label, 4, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.fee_amount_label, 4, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.deposit_timestamp, 1, 4, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.to_account_widget, 2, 4, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.deposit, 3, 4, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.fee_account_widget, 4, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.fee, 4, 4, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.commit_button, 0, 6, 1, 1) self.layout.addWidget(self.revert_button, 0, 7, 1, 1) self.layout.addItem(self.verticalSpacer, 6, 0, 1, 1) self.layout.addItem(self.horizontalSpacer, 1, 5, 1, 1) self.copy_date_btn.clicked.connect(self.onCopyDate) self.copy_amount_btn.clicked.connect(self.onCopyAmount) super()._init_db("transfers") self.mapper.setItemDelegate(TransferWidgetDelegate(self.mapper)) self.from_account_widget.changed.connect(self.mapper.submit) self.to_account_widget.changed.connect(self.mapper.submit) self.fee_account_widget.changed.connect(self.mapper.submit) self.mapper.addMapping(self.withdrawal_timestamp, self.model.fieldIndex("withdrawal_timestamp")) self.mapper.addMapping(self.from_account_widget, self.model.fieldIndex("withdrawal_account")) self.mapper.addMapping(self.withdrawal, self.model.fieldIndex("withdrawal")) self.mapper.addMapping(self.deposit_timestamp, self.model.fieldIndex("deposit_timestamp")) self.mapper.addMapping(self.to_account_widget, self.model.fieldIndex("deposit_account")) self.mapper.addMapping(self.deposit, self.model.fieldIndex("deposit")) self.mapper.addMapping(self.fee_account_widget, self.model.fieldIndex("fee_account")) self.mapper.addMapping(self.fee, self.model.fieldIndex("fee")) self.mapper.addMapping(self.comment, self.model.fieldIndex("note")) self.model.select() @Slot() def saveChanges(self): record = self.model.record(0) # Set related fields NULL if we don't have fee. This is required for correct transfer processing fee_amount = record.value(self.model.fieldIndex("fee")) if not fee_amount: fee_amount = 0 if abs(float(fee_amount)) < Setup.CALC_TOLERANCE: self.model.setData( self.model.index(0, self.model.fieldIndex("fee_account")), None) self.model.setData( self.model.index(0, self.model.fieldIndex("fee")), None) super().saveChanges() def prepareNew(self, account_id): new_record = super().prepareNew(account_id) new_record.setValue( "withdrawal_timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("withdrawal_account", account_id) new_record.setValue("withdrawal", 0) new_record.setValue( "deposit_timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("deposit_account", 0) new_record.setValue("deposit", 0) new_record.setValue("fee_account", 0) new_record.setValue("fee", 0) new_record.setValue("asset", None) new_record.setValue("note", None) return new_record def copyToNew(self, row): new_record = self.model.record(row) new_record.setNull("id") new_record.setValue( "withdrawal_timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue( "deposit_timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) return new_record @Slot() def onCopyDate(self): self.deposit_timestamp.setDateTime( self.withdrawal_timestamp.dateTime()) # mapper.submit() isn't needed here as 'changed' signal of 'deposit_timestamp' is linked with it @Slot() def onCopyAmount(self): self.deposit.setText(self.withdrawal.text()) self.mapper.submit()
class TradeWidget(AbstractOperationDetails): def __init__(self, parent=None): AbstractOperationDetails.__init__(self, parent) self.name = "Trade" self.date_label = QLabel(self) self.settlement_label = QLabel() self.number_label = QLabel(self) self.account_label = QLabel(self) self.symbol_label = QLabel(self) self.qty_label = QLabel(self) self.price_label = QLabel(self) self.fee_label = QLabel(self) self.comment_label = QLabel(self) self.main_label.setText(self.tr("Buy / Sell")) self.date_label.setText(self.tr("Date/Time")) self.settlement_label.setText(self.tr("Settlement")) self.number_label.setText(self.tr("#")) self.account_label.setText(self.tr("Account")) self.symbol_label.setText(self.tr("Asset")) self.qty_label.setText(self.tr("Qty")) self.price_label.setText(self.tr("Price")) self.fee_label.setText(self.tr("Fee")) self.comment_label.setText(self.tr("Note")) self.timestamp_editor = QDateTimeEdit(self) self.timestamp_editor.setCalendarPopup(True) self.timestamp_editor.setTimeSpec(Qt.UTC) self.timestamp_editor.setFixedWidth(self.timestamp_editor.fontMetrics().horizontalAdvance("00/00/0000 00:00:00") * 1.25) self.timestamp_editor.setDisplayFormat("dd/MM/yyyy hh:mm:ss") self.settlement_editor = QDateEdit(self) self.settlement_editor.setCalendarPopup(True) self.settlement_editor.setTimeSpec(Qt.UTC) self.settlement_editor.setFixedWidth(self.settlement_editor.fontMetrics().horizontalAdvance("00/00/0000") * 1.5) self.settlement_editor.setDisplayFormat("dd/MM/yyyy") self.account_widget = AccountSelector(self) self.asset_widget = AssetSelector(self) self.qty_edit = QLineEdit(self) self.qty_edit.setAlignment(Qt.AlignRight) self.price_edit = QLineEdit(self) self.price_edit.setAlignment(Qt.AlignRight) self.fee_edit = QLineEdit(self) self.fee_edit.setAlignment(Qt.AlignRight) self.number = QLineEdit(self) self.comment = QLineEdit(self) self.layout.addWidget(self.date_label, 1, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.account_label, 2, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.symbol_label, 3, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.comment_label, 4, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.timestamp_editor, 1, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.account_widget, 2, 1, 1, 4) self.layout.addWidget(self.asset_widget, 3, 1, 1, 4) self.layout.addWidget(self.comment, 4, 1, 1, 4) self.layout.addWidget(self.settlement_label, 1, 2, 1, 1, Qt.AlignRight) self.layout.addWidget(self.settlement_editor, 1, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.number_label, 1, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.qty_label, 2, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.price_label, 3, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.fee_label, 4, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.number, 1, 6, 1, 1) self.layout.addWidget(self.qty_edit, 2, 6, 1, 1) self.layout.addWidget(self.price_edit, 3, 6, 1, 1) self.layout.addWidget(self.fee_edit, 4, 6, 1, 1) self.layout.addWidget(self.commit_button, 0, 8, 1, 1) self.layout.addWidget(self.revert_button, 0, 9, 1, 1) self.layout.addItem(self.verticalSpacer, 6, 6, 1, 1) self.layout.addItem(self.horizontalSpacer, 1, 6, 1, 1) super()._init_db("trades") self.mapper.setItemDelegate(TradeWidgetDelegate(self.mapper)) self.account_widget.changed.connect(self.mapper.submit) self.asset_widget.changed.connect(self.mapper.submit) self.mapper.addMapping(self.timestamp_editor, self.model.fieldIndex("timestamp")) self.mapper.addMapping(self.settlement_editor, self.model.fieldIndex("settlement")) self.mapper.addMapping(self.account_widget, self.model.fieldIndex("account_id")) self.mapper.addMapping(self.asset_widget, self.model.fieldIndex("asset_id")) self.mapper.addMapping(self.number, self.model.fieldIndex("number")) self.mapper.addMapping(self.qty_edit, self.model.fieldIndex("qty")) self.mapper.addMapping(self.price_edit, self.model.fieldIndex("price")) self.mapper.addMapping(self.fee_edit, self.model.fieldIndex("fee")) self.mapper.addMapping(self.comment, self.model.fieldIndex("note")) self.model.select() def prepareNew(self, account_id): new_record = self.model.record() new_record.setNull("id") new_record.setValue("timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("settlement", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("number", '') new_record.setValue("account_id", account_id) new_record.setValue("asset_id", 0) new_record.setValue("qty", 0) new_record.setValue("price", 0) new_record.setValue("fee", 0) new_record.setValue("note", None) return new_record def copyToNew(self, row): new_record = self.model.record(row) new_record.setNull("id") new_record.setValue("timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("settlement", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("number", '') return new_record
class DividendWidget(AbstractOperationDetails): def __init__(self, parent=None): AbstractOperationDetails.__init__(self, parent) self.name = "Dividend" self.operation_type = LedgerTransaction.Dividend self.combo_model = None self.date_label = QLabel(self) self.ex_date_label = QLabel(self) self.number_label = QLabel(self) self.type_label = QLabel(self) self.account_label = QLabel(self) self.symbol_label = QLabel(self) self.amount_label = QLabel(self) self.price_label = QLabel(self) self.tax_label = QLabel(self) self.comment_label = QLabel(self) self.main_label.setText(self.tr("Dividend")) self.date_label.setText(self.tr("Date/Time")) self.ex_date_label.setText(self.tr("Ex-Date")) self.type_label.setText(self.tr("Type")) self.number_label.setText(self.tr("#")) self.account_label.setText(self.tr("Account")) self.symbol_label.setText(self.tr("Asset")) self.amount_label.setText(self.tr("Dividend")) self.price_label.setText(self.tr("Price")) self.tax_label.setText(self.tr("Tax")) self.comment_label.setText(self.tr("Note")) self.timestamp_editor = QDateTimeEdit(self) self.timestamp_editor.setCalendarPopup(True) self.timestamp_editor.setTimeSpec(Qt.UTC) self.timestamp_editor.setFixedWidth(self.timestamp_editor.fontMetrics().horizontalAdvance("00/00/0000 00:00:00") * 1.25) self.timestamp_editor.setDisplayFormat("dd/MM/yyyy hh:mm:ss") self.ex_date_editor = QDateEdit(self) self.ex_date_editor.setCalendarPopup(True) self.ex_date_editor.setTimeSpec(Qt.UTC) self.ex_date_editor.setFixedWidth(self.ex_date_editor.fontMetrics().horizontalAdvance("00/00/0000") * 1.5) self.ex_date_editor.setDisplayFormat("dd/MM/yyyy") self.type = QComboBox(self) self.account_widget = AccountSelector(self) self.asset_widget = AssetSelector(self) self.dividend_edit = QLineEdit(self) self.dividend_edit.setAlignment(Qt.AlignRight) self.price_edit = QLineEdit(self) self.price_edit.setAlignment(Qt.AlignRight) self.price_edit.setReadOnly(True) self.tax_edit = QLineEdit(self) self.tax_edit.setAlignment(Qt.AlignRight) self.number = QLineEdit(self) self.comment = QLineEdit(self) self.layout.addWidget(self.date_label, 1, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.account_label, 2, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.symbol_label, 3, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.comment_label, 4, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.timestamp_editor, 1, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.account_widget, 2, 1, 1, 4) self.layout.addWidget(self.asset_widget, 3, 1, 1, 4) self.layout.addWidget(self.comment, 4, 1, 1, 8) self.layout.addWidget(self.ex_date_label, 1, 2, 1, 1, Qt.AlignRight) self.layout.addWidget(self.ex_date_editor, 1, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.type_label, 1, 5, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.amount_label, 2, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.tax_label, 3, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.type, 1, 6, 1, 1) self.layout.addWidget(self.dividend_edit, 2, 6, 1, 1) self.layout.addWidget(self.tax_edit, 3, 6, 1, 1) self.layout.addWidget(self.number_label, 1, 7, 1, 1, Qt.AlignRight) self.layout.addWidget(self.price_label, 2, 7, 1, 1, Qt.AlignRight) self.layout.addWidget(self.number, 1, 8, 1, 1) self.layout.addWidget(self.price_edit, 2, 8, 1, 1) self.layout.addWidget(self.commit_button, 0, 9, 1, 1) self.layout.addWidget(self.revert_button, 0, 10, 1, 1) self.layout.addItem(self.verticalSpacer, 5, 0, 1, 1) self.layout.addItem(self.horizontalSpacer, 1, 8, 1, 1) super()._init_db("dividends") self.combo_model = QStringListModel([self.tr("N/A"), self.tr("Dividend"), self.tr("Bond Interest"), self.tr("Stock Dividend")]) self.type.setModel(self.combo_model) self.mapper.setItemDelegate(DividendWidgetDelegate(self.mapper)) self.account_widget.changed.connect(self.mapper.submit) self.asset_widget.changed.connect(self.assetChanged) self.type.currentIndexChanged.connect(self.typeChanged) self.timestamp_editor.dateTimeChanged.connect(self.refreshAssetPrice) self.mapper.addMapping(self.timestamp_editor, self.model.fieldIndex("timestamp")) self.mapper.addMapping(self.ex_date_editor, self.model.fieldIndex("ex_date")) self.mapper.addMapping(self.account_widget, self.model.fieldIndex("account_id")) self.mapper.addMapping(self.asset_widget, self.model.fieldIndex("asset_id")) self.mapper.addMapping(self.type, self.model.fieldIndex("type"), QByteArray().setRawData("currentIndex", 12)) self.mapper.addMapping(self.number, self.model.fieldIndex("number")) self.mapper.addMapping(self.dividend_edit, self.model.fieldIndex("amount")) self.mapper.addMapping(self.tax_edit, self.model.fieldIndex("tax")) self.mapper.addMapping(self.comment, self.model.fieldIndex("note")) self.model.select() @Slot() def assetChanged(self): self.mapper.submit() self.refreshAssetPrice() @Slot() def typeChanged(self, dividend_type_id): self.price_label.setVisible(dividend_type_id == Dividend.StockDividend) self.price_edit.setVisible(dividend_type_id == Dividend.StockDividend) self.refreshAssetPrice() def refreshAssetPrice(self): if self.type.currentIndex() == Dividend.StockDividend: price = JalDB().get_quote(self.asset_widget.selected_id, JalDB().get_account_currency(self.account_widget.selected_id), self.timestamp_editor.dateTime().toSecsSinceEpoch()) if price is not None: self.price_edit.setText(str(price)) self.price_edit.setStyleSheet('') self.price_edit.setToolTip("") else: self.price_edit.setText(self.tr("No quote")) self.price_edit.setStyleSheet("color: red") self.price_edit.setToolTip( self.tr("You should set quote via Data->Quotes menu for Date/Time of the dividend")) def prepareNew(self, account_id): new_record = super().prepareNew(account_id) new_record.setValue("timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("ex_date", 0) new_record.setValue("type", 0) new_record.setValue("number", '') new_record.setValue("account_id", account_id) new_record.setValue("asset_id", 0) new_record.setValue("amount", 0) new_record.setValue("tax", 0) new_record.setValue("note", None) return new_record def copyToNew(self, row): new_record = self.model.record(row) new_record.setNull("id") new_record.setValue("timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("ex_date", 0) new_record.setValue("number", '') return new_record
class PlaylistPopup(QWidget): def __init__(self, result, parent=None): # Popup when "Add song to playlist" is clicked on # How this works is a QWidget that encompasses the entire window area, representing an unclickable translucent background. # Another QWidget is then contained inside that QWidget representing the popup. # result: (dict) Python dict containing information of the song clicked QWidget.__init__(self) self.setParent(parent) self.result = result # Signals are used to indicate to close the window self.SIGNALS = self.TranslucentWidgetSignals() # Make the window frameless and expanding. self.setWindowFlags(Qt.FramelessWindowHint) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # Makes the window background colour translucent self.setAttribute(Qt.WA_StyledBackground) self.setStyleSheet( "PlaylistPopup { background-color: rgba(255, 255, 255, 0.5)}") # Sets the grid settings of the "background" and the "popup" layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) playlistAdd = QWidget(self) playlistAdd.setFixedSize(800, 300) playlistAdd.setStyleSheet( ".QWidget { background-color: rgba(255, 255, 255, 1)}") innerLayout = QGridLayout() innerLayout.setContentsMargins(20, 20, 20, 20) innerLayout.setSpacing(30) # Heading font font = QFont() font.setPointSize(24) # Default label font font2 = QFont() font2.setPointSize(16) # Heading label = QLabel("添加到播放列表/Add to Playlist", self) label.setAlignment(Qt.AlignCenter) label.setFont(font) innerLayout.addWidget(label, 0, 0) # Playlist selection self.comboBox = QComboBox(self) self.comboBox.setFont(font) playlists = DB.getPlaylists("") for playlist in playlists: self.comboBox.addItem(playlist["playlist_name"]) self.comboBox.setCurrentIndex(-1) innerLayout.addWidget(self.comboBox, 1, 0) # Textbox to create a new playlist self.textBox = QLineEdit(self) self.textBox.setFont(font2) self.textBox.setAlignment(Qt.AlignCenter) self.textBox.setPlaceholderText( "输入以创建新的播放列表/Type to create a new playlist") self.textBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) # TODO: resize textbox with window self.textBox.setFixedWidth(760) innerLayout.addWidget(self.textBox, 2, 0, Qt.AlignCenter) # Add actions for then the QComboBox or QLineEdit is changed. # This is done so there is only one action between "Add to existing Playlist" or "Add to new Playlist" self.comboBox.currentIndexChanged.connect(self.comboBoxChanged) self.textBox.textEdited.connect(self.textBoxChanged) # Confirm button confirmButton = QToolButton(self) confirmButton.setText("确认/Confirm") confirmButton.setFont(font) confirmButton.clicked.connect(self.processPlaylistRequest) innerLayout.addWidget(confirmButton, 3, 0, Qt.AlignCenter) # Exit button btn = QToolButton(self) btn.setFixedSize(44, 44) btn.setText("X") btn.setFont(font) btn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) btn.clicked.connect(lambda: self.SIGNALS.CLOSE.emit()) innerLayout.addWidget(btn, 0, 0, Qt.AlignRight) playlistAdd.setLayout(innerLayout) layout.addWidget(playlistAdd, 0, 0, Qt.AlignCenter) self.setLayout(layout) def comboBoxChanged(self): # Called when the ComboBox is changed # Clears the text in the "Create Playlist" TextBox if self.textBox.text() != "": self.textBox.setText("") def textBoxChanged(self): # Called when the TextBox is changed # Clears the selection in the "Add to Playlist" ComboBox if self.comboBox.currentIndex != -1: self.comboBox.setCurrentIndex(-1) def processPlaylistRequest(self): # Called when the Confirm button is clicked def addToPlaylist(self, playlistID): # Adds the song to the playlist # Get song ID song = self.result["song_id"] DB.addPlaylistSong(playlistID, song) if self.textBox.text() != "": # New playlist playlistName = self.textBox.text() counter = 1 while DB.checkPlaylist(playlistName): playlistName = "{} ({})".format(self.textBox.text(), counter) counter += 1 playlistID = DB.newPlaylist(playlistName)[0]["playlist_id"] addToPlaylist(self, playlistID) self.SIGNALS.CLOSE.emit() elif self.comboBox.currentIndex != -1: playlistID = DB.checkPlaylist( self.comboBox.currentText())[0]["playlist_id"] # Add to existing playlist addToPlaylist(self, playlistID) self.SIGNALS.CLOSE.emit() # Taken from https://stackoverflow.com/questions/44264852/pyside-pyqt-overlay-widget class TranslucentWidgetSignals(QtCore.QObject): CLOSE = QtCore.Signal()
class DividendWidget(AbstractOperationDetails): def __init__(self, parent=None): AbstractOperationDetails.__init__(self, parent) self.name = "Dividend" self.combo_model = None self.date_label = QLabel(self) self.ex_date_label = QLabel(self) self.number_label = QLabel(self) self.type_label = QLabel(self) self.account_label = QLabel(self) self.symbol_label = QLabel(self) self.amount_label = QLabel(self) self.tax_label = QLabel(self) self.comment_label = QLabel(self) self.main_label.setText(self.tr("Dividend")) self.date_label.setText(self.tr("Date/Time")) self.ex_date_label.setText(self.tr("Ex-Date")) self.type_label.setText(self.tr("Type")) self.number_label.setText(self.tr("#")) self.account_label.setText(self.tr("Account")) self.symbol_label.setText(self.tr("Asset")) self.amount_label.setText(self.tr("Dividend")) self.tax_label.setText(self.tr("Tax")) self.comment_label.setText(self.tr("Note")) self.timestamp_editor = QDateTimeEdit(self) self.timestamp_editor.setCalendarPopup(True) self.timestamp_editor.setTimeSpec(Qt.UTC) self.timestamp_editor.setFixedWidth(self.timestamp_editor.fontMetrics().horizontalAdvance("00/00/0000 00:00:00") * 1.25) self.timestamp_editor.setDisplayFormat("dd/MM/yyyy hh:mm:ss") self.ex_date_editor = QDateEdit(self) self.ex_date_editor.setCalendarPopup(True) self.ex_date_editor.setTimeSpec(Qt.UTC) self.ex_date_editor.setFixedWidth(self.ex_date_editor.fontMetrics().horizontalAdvance("00/00/0000") * 1.5) self.ex_date_editor.setDisplayFormat("dd/MM/yyyy") self.type = QComboBox(self) self.account_widget = AccountSelector(self) self.asset_widget = AssetSelector(self) self.dividend_edit = QLineEdit(self) self.dividend_edit.setAlignment(Qt.AlignRight) self.tax_edit = QLineEdit(self) self.tax_edit.setAlignment(Qt.AlignRight) self.number = QLineEdit(self) self.comment = QLineEdit(self) self.layout.addWidget(self.date_label, 1, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.account_label, 2, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.symbol_label, 3, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.comment_label, 4, 0, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.timestamp_editor, 1, 1, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.account_widget, 2, 1, 1, 4) self.layout.addWidget(self.asset_widget, 3, 1, 1, 4) self.layout.addWidget(self.comment, 4, 1, 1, 8) self.layout.addWidget(self.ex_date_label, 1, 2, 1, 1, Qt.AlignRight) self.layout.addWidget(self.ex_date_editor, 1, 3, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.type_label, 1, 5, 1, 1, Qt.AlignLeft) self.layout.addWidget(self.amount_label, 2, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.tax_label, 3, 5, 1, 1, Qt.AlignRight) self.layout.addWidget(self.type, 1, 6, 1, 1) self.layout.addWidget(self.dividend_edit, 2, 6, 1, 1) self.layout.addWidget(self.tax_edit, 3, 6, 1, 1) self.layout.addWidget(self.number_label, 1, 7, 1, 1, Qt.AlignRight) self.layout.addWidget(self.number, 1, 8, 1, 1) self.layout.addWidget(self.commit_button, 0, 9, 1, 1) self.layout.addWidget(self.revert_button, 0, 10, 1, 1) self.layout.addItem(self.verticalSpacer, 5, 0, 1, 1) self.layout.addItem(self.horizontalSpacer, 1, 8, 1, 1) super()._init_db("dividends") self.combo_model = QStringListModel([self.tr("N/A"), self.tr("Dividend"), self.tr("Bond Interest")]) self.type.setModel(self.combo_model) self.mapper.setItemDelegate(DividendWidgetDelegate(self.mapper)) self.account_widget.changed.connect(self.mapper.submit) self.asset_widget.changed.connect(self.mapper.submit) self.mapper.addMapping(self.timestamp_editor, self.model.fieldIndex("timestamp")) self.mapper.addMapping(self.ex_date_editor, self.model.fieldIndex("ex_date")) self.mapper.addMapping(self.account_widget, self.model.fieldIndex("account_id")) self.mapper.addMapping(self.asset_widget, self.model.fieldIndex("asset_id")) self.mapper.addMapping(self.type, self.model.fieldIndex("type"), QByteArray().setRawData("currentIndex", 12)) self.mapper.addMapping(self.number, self.model.fieldIndex("number")) self.mapper.addMapping(self.dividend_edit, self.model.fieldIndex("amount")) self.mapper.addMapping(self.tax_edit, self.model.fieldIndex("tax")) self.mapper.addMapping(self.comment, self.model.fieldIndex("note")) self.model.select() def prepareNew(self, account_id): new_record = self.model.record() new_record.setNull("id") new_record.setValue("timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("ex_date", 0) new_record.setValue("type", 0) new_record.setValue("number", '') new_record.setValue("account_id", account_id) new_record.setValue("asset_id", 0) new_record.setValue("amount", 0) new_record.setValue("tax", 0) new_record.setValue("note", None) return new_record def copyToNew(self, row): new_record = self.model.record(row) new_record.setNull("id") new_record.setValue("timestamp", int(datetime.now().replace(tzinfo=tz.tzutc()).timestamp())) new_record.setValue("ex_date", 0) new_record.setValue("number", '') return new_record
class Ui_Img(object): def setupUi(self, Img): if not Img.objectName(): Img.setObjectName(u"Img") Img.resize(620, 559) self.gridLayout = QGridLayout(Img) self.gridLayout.setObjectName(u"gridLayout") self.graphicsView = QGraphicsView(Img) self.graphicsView.setObjectName(u"graphicsView") self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 1) self.verticalLayout = QVBoxLayout() self.verticalLayout.setObjectName(u"verticalLayout") self.line_3 = QFrame(Img) self.line_3.setObjectName(u"line_3") self.line_3.setFrameShape(QFrame.VLine) self.line_3.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line_3) self.verticalLayout_2 = QVBoxLayout() self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.line_5 = QFrame(Img) self.line_5.setObjectName(u"line_5") self.line_5.setFrameShape(QFrame.VLine) self.line_5.setFrameShadow(QFrame.Sunken) self.verticalLayout_2.addWidget(self.line_5) self.checkBox = QCheckBox(Img) self.checkBox.setObjectName(u"checkBox") self.checkBox.setMaximumSize(QSize(100, 16777215)) self.checkBox.setChecked(True) self.verticalLayout_2.addWidget(self.checkBox) self.ttaModel = QCheckBox(Img) self.ttaModel.setObjectName(u"ttaModel") self.ttaModel.setMaximumSize(QSize(70, 16777215)) self.verticalLayout_2.addWidget(self.ttaModel) self.horizontalLayout_3 = QHBoxLayout() self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") self.scaleRadio = QRadioButton(Img) self.buttonGroup_2 = QButtonGroup(Img) self.buttonGroup_2.setObjectName(u"buttonGroup_2") self.buttonGroup_2.addButton(self.scaleRadio) self.scaleRadio.setObjectName(u"scaleRadio") self.scaleRadio.setMaximumSize(QSize(80, 16777215)) self.scaleRadio.setChecked(True) self.horizontalLayout_3.addWidget(self.scaleRadio) self.scaleEdit = QLineEdit(Img) self.scaleEdit.setObjectName(u"scaleEdit") self.scaleEdit.setMaximumSize(QSize(160, 16777215)) self.scaleEdit.setAlignment(Qt.AlignCenter) self.horizontalLayout_3.addWidget(self.scaleEdit) self.verticalLayout_2.addLayout(self.horizontalLayout_3) self.horizontalLayout_4 = QHBoxLayout() self.horizontalLayout_4.setObjectName(u"horizontalLayout_4") self.heighRadio = QRadioButton(Img) self.buttonGroup_2.addButton(self.heighRadio) self.heighRadio.setObjectName(u"heighRadio") self.heighRadio.setMaximumSize(QSize(80, 16777215)) self.horizontalLayout_4.addWidget(self.heighRadio) self.widthEdit = QLineEdit(Img) self.widthEdit.setObjectName(u"widthEdit") self.widthEdit.setEnabled(False) self.widthEdit.setMaximumSize(QSize(60, 16777215)) self.widthEdit.setAlignment(Qt.AlignCenter) self.horizontalLayout_4.addWidget(self.widthEdit) self.label_2 = QLabel(Img) self.label_2.setObjectName(u"label_2") self.label_2.setMaximumSize(QSize(20, 16777215)) self.horizontalLayout_4.addWidget(self.label_2) self.heighEdit = QLineEdit(Img) self.heighEdit.setObjectName(u"heighEdit") self.heighEdit.setEnabled(False) self.heighEdit.setMaximumSize(QSize(60, 16777215)) self.heighEdit.setAlignment(Qt.AlignCenter) self.horizontalLayout_4.addWidget(self.heighEdit) self.verticalLayout_2.addLayout(self.horizontalLayout_4) self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") self.label_4 = QLabel(Img) self.label_4.setObjectName(u"label_4") self.label_4.setMaximumSize(QSize(60, 16777215)) self.horizontalLayout_5.addWidget(self.label_4) self.noiseCombox = QComboBox(Img) self.noiseCombox.addItem("") self.noiseCombox.addItem("") self.noiseCombox.addItem("") self.noiseCombox.addItem("") self.noiseCombox.addItem("") self.noiseCombox.setObjectName(u"noiseCombox") self.noiseCombox.setMaximumSize(QSize(160, 16777215)) self.horizontalLayout_5.addWidget(self.noiseCombox) self.verticalLayout_2.addLayout(self.horizontalLayout_5) self.horizontalLayout_6 = QHBoxLayout() self.horizontalLayout_6.setObjectName(u"horizontalLayout_6") self.label_5 = QLabel(Img) self.label_5.setObjectName(u"label_5") self.label_5.setMaximumSize(QSize(60, 16777215)) self.horizontalLayout_6.addWidget(self.label_5) self.comboBox = QComboBox(Img) self.comboBox.addItem("") self.comboBox.addItem("") self.comboBox.addItem("") self.comboBox.setObjectName(u"comboBox") self.comboBox.setMaximumSize(QSize(160, 16777215)) self.horizontalLayout_6.addWidget(self.comboBox) self.verticalLayout_2.addLayout(self.horizontalLayout_6) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setObjectName(u"horizontalLayout_7") self.changeJpg = QPushButton(Img) self.changeJpg.setObjectName(u"changeJpg") self.changeJpg.setMaximumSize(QSize(100, 16777215)) self.horizontalLayout_7.addWidget(self.changeJpg) self.changePng = QPushButton(Img) self.changePng.setObjectName(u"changePng") self.changePng.setMaximumSize(QSize(100, 16777215)) self.horizontalLayout_7.addWidget(self.changePng) self.changeLabel = QLabel(Img) self.changeLabel.setObjectName(u"changeLabel") self.changeLabel.setMaximumSize(QSize(100, 16777215)) self.changeLabel.setAlignment(Qt.AlignCenter) self.horizontalLayout_7.addWidget(self.changeLabel) self.verticalLayout_2.addLayout(self.horizontalLayout_7) self.horizontalLayout_11 = QHBoxLayout() self.horizontalLayout_11.setObjectName(u"horizontalLayout_11") self.verticalLayout_2.addLayout(self.horizontalLayout_11) self.verticalLayout.addLayout(self.verticalLayout_2) self.line = QFrame(Img) self.line.setObjectName(u"line") self.line.setFrameShape(QFrame.VLine) self.line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line) self.line_4 = QFrame(Img) self.line_4.setObjectName(u"line_4") self.line_4.setFrameShape(QFrame.HLine) self.line_4.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line_4) self.verticalLayout_3 = QVBoxLayout() self.verticalLayout_3.setObjectName(u"verticalLayout_3") self.horizontalLayout_8 = QHBoxLayout() self.horizontalLayout_8.setObjectName(u"horizontalLayout_8") self.label_8 = QLabel(Img) self.label_8.setObjectName(u"label_8") self.label_8.setMaximumSize(QSize(60, 16777215)) self.horizontalLayout_8.addWidget(self.label_8) self.resolutionLabel = QLabel(Img) self.resolutionLabel.setObjectName(u"resolutionLabel") self.resolutionLabel.setMaximumSize(QSize(160, 16777215)) self.horizontalLayout_8.addWidget(self.resolutionLabel) self.verticalLayout_3.addLayout(self.horizontalLayout_8) self.horizontalLayout_9 = QHBoxLayout() self.horizontalLayout_9.setObjectName(u"horizontalLayout_9") self.label_10 = QLabel(Img) self.label_10.setObjectName(u"label_10") self.label_10.setMaximumSize(QSize(60, 16777215)) self.horizontalLayout_9.addWidget(self.label_10) self.sizeLabel = QLabel(Img) self.sizeLabel.setObjectName(u"sizeLabel") self.sizeLabel.setMaximumSize(QSize(160, 16777215)) self.horizontalLayout_9.addWidget(self.sizeLabel) self.verticalLayout_3.addLayout(self.horizontalLayout_9) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName(u"horizontalLayout") self.label = QLabel(Img) self.label.setObjectName(u"label") self.label.setMaximumSize(QSize(60, 16777215)) self.horizontalLayout.addWidget(self.label) self.gpuName = QLabel(Img) self.gpuName.setObjectName(u"gpuName") self.gpuName.setMaximumSize(QSize(160, 16777215)) self.horizontalLayout.addWidget(self.gpuName) self.verticalLayout_3.addLayout(self.horizontalLayout) self.horizontalLayout_10 = QHBoxLayout() self.horizontalLayout_10.setObjectName(u"horizontalLayout_10") self.label_6 = QLabel(Img) self.label_6.setObjectName(u"label_6") self.label_6.setMaximumSize(QSize(60, 16777215)) self.horizontalLayout_10.addWidget(self.label_6) self.tickLabel = QLabel(Img) self.tickLabel.setObjectName(u"tickLabel") self.tickLabel.setMaximumSize(QSize(160, 16777215)) self.horizontalLayout_10.addWidget(self.tickLabel) self.verticalLayout_3.addLayout(self.horizontalLayout_10) self.oepnButton = QPushButton(Img) self.oepnButton.setObjectName(u"oepnButton") self.oepnButton.setMaximumSize(QSize(100, 16777215)) self.verticalLayout_3.addWidget(self.oepnButton) self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.verticalLayout_3.addLayout(self.horizontalLayout_2) self.pushButton_3 = QPushButton(Img) self.pushButton_3.setObjectName(u"pushButton_3") self.pushButton_3.setMaximumSize(QSize(100, 16777215)) self.verticalLayout_3.addWidget(self.pushButton_3) self.pushButton = QPushButton(Img) self.pushButton.setObjectName(u"pushButton") self.pushButton.setMaximumSize(QSize(100, 16777215)) self.verticalLayout_3.addWidget(self.pushButton) self.saveButton = QPushButton(Img) self.saveButton.setObjectName(u"saveButton") self.saveButton.setMaximumSize(QSize(100, 16777215)) self.verticalLayout_3.addWidget(self.saveButton) self.verticalLayout.addLayout(self.verticalLayout_3) self.line_6 = QFrame(Img) self.line_6.setObjectName(u"line_6") self.line_6.setFrameShape(QFrame.HLine) self.line_6.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line_6) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout.addItem(self.verticalSpacer) self.line_2 = QFrame(Img) self.line_2.setObjectName(u"line_2") self.line_2.setFrameShape(QFrame.VLine) self.line_2.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line_2) self.gridLayout.addLayout(self.verticalLayout, 0, 1, 1, 1) self.retranslateUi(Img) self.checkBox.clicked.connect(Img.SwithPicture) self.saveButton.clicked.connect(Img.SavePicture) self.heighEdit.textChanged.connect(Img.CheckScaleRadio) self.pushButton_3.clicked.connect(Img.ReduceScalePic) self.heighRadio.clicked.connect(Img.CheckScaleRadio) self.ttaModel.clicked.connect(Img.CheckScaleRadio) self.oepnButton.clicked.connect(Img.OpenPicture) self.widthEdit.textChanged.connect(Img.CheckScaleRadio) self.pushButton.clicked.connect(Img.AddScalePic) self.scaleEdit.textChanged.connect(Img.CheckScaleRadio) self.scaleRadio.clicked.connect(Img.CheckScaleRadio) self.comboBox.currentIndexChanged.connect(Img.ChangeModel) self.changeJpg.clicked.connect(Img.StartWaifu2x) self.noiseCombox.currentIndexChanged.connect(Img.CheckScaleRadio) self.changePng.clicked.connect(Img.StartWaifu2xPng) self.changeJpg.clicked.connect(Img.StartWaifu2xJPG) QMetaObject.connectSlotsByName(Img) # setupUi def retranslateUi(self, Img): Img.setWindowTitle(QCoreApplication.translate("Img", u"Form", None)) self.checkBox.setText( QCoreApplication.translate("Img", u"waifu2x", None)) #if QT_CONFIG(tooltip) self.ttaModel.setToolTip( QCoreApplication.translate( "Img", u"\u753b\u8d28\u63d0\u5347\uff0c\u8017\u65f6\u589e\u52a0", None)) #endif // QT_CONFIG(tooltip) self.ttaModel.setText( QCoreApplication.translate("Img", u"tta\u6a21\u5f0f", None)) self.scaleRadio.setText( QCoreApplication.translate("Img", u"\u500d\u6570\u653e\u5927", None)) self.scaleEdit.setText(QCoreApplication.translate("Img", u"2", None)) self.heighRadio.setText( QCoreApplication.translate("Img", u"\u56fa\u5b9a\u957f\u5bbd", None)) self.label_2.setText(QCoreApplication.translate("Img", u"x", None)) self.label_4.setText( QCoreApplication.translate("Img", u"\u964d\u566a\uff1a", None)) self.noiseCombox.setItemText( 0, QCoreApplication.translate("Img", u"3", None)) self.noiseCombox.setItemText( 1, QCoreApplication.translate("Img", u"2", None)) self.noiseCombox.setItemText( 2, QCoreApplication.translate("Img", u"1", None)) self.noiseCombox.setItemText( 3, QCoreApplication.translate("Img", u"0", None)) self.noiseCombox.setItemText( 4, QCoreApplication.translate("Img", u"-1", None)) self.label_5.setText( QCoreApplication.translate("Img", u"\u6a21\u578b\uff1a", None)) self.comboBox.setItemText( 0, QCoreApplication.translate("Img", u"cunet", None)) self.comboBox.setItemText( 1, QCoreApplication.translate("Img", u"photo", None)) self.comboBox.setItemText( 2, QCoreApplication.translate("Img", u"anime_style_art_rgb", None)) self.changeJpg.setText( QCoreApplication.translate("Img", u"\u8f6c\u6362JPG", None)) self.changePng.setText( QCoreApplication.translate("Img", u"\u8f6c\u6362PNG", None)) self.changeLabel.setText("") self.label_8.setText( QCoreApplication.translate("Img", u"\u5206\u8fa8\u7387\uff1a", None)) self.resolutionLabel.setText( QCoreApplication.translate("Img", u"TextLabel", None)) self.label_10.setText( QCoreApplication.translate("Img", u"\u5927 \u5c0f\uff1a", None)) self.sizeLabel.setText( QCoreApplication.translate("Img", u"TextLabel", None)) self.label.setText(QCoreApplication.translate("Img", u"GPU:", None)) self.gpuName.setText( QCoreApplication.translate("Img", u"TextLabel", None)) self.label_6.setText( QCoreApplication.translate("Img", u"\u8017\u65f6\uff1a", None)) self.tickLabel.setText("") self.oepnButton.setText( QCoreApplication.translate("Img", u"\u6253\u5f00\u56fe\u7247", None)) self.pushButton_3.setText( QCoreApplication.translate("Img", u"\u7f29\u5c0f", None)) self.pushButton.setText( QCoreApplication.translate("Img", u"\u653e\u5927", None)) self.saveButton.setText( QCoreApplication.translate("Img", u"\u4fdd\u5b58\u56fe\u7247", None))
class AddSteamWidget(TritonWidget): def __init__(self, base, *args, **kwargs): TritonWidget.__init__(self, base, *args, **kwargs) self.sharedSecret = None self.identitySecret = None self.steamId = None self.type = Globals.SteamAuth self.setWindowTitle('Add Steam') self.setBackgroundColor(self, Qt.white) self.boxLayout = QVBoxLayout(self) self.boxLayout.setContentsMargins(20, 20, 20, 20) self.nameWidget = TextboxWidget(base, 'Name:') self.steamIdWidget = TextboxWidget(base, 'Steam ID:') self.sharedWidget = TextboxWidget(base, 'Shared Secret:') self.identityWidget = TextboxWidget(base, 'Identity Secret:') self.verifyLabel = QLabel() self.verifyLabel.setText('Click the Verify button to check the first code.') self.verifyLabel.setFont(QFont('Helvetica', 10)) self.verifyBox = QLineEdit() self.verifyBox.setFixedWidth(150) self.verifyBox.setFont(QFont('Helvetica', 10)) self.verifyBox.setEnabled(False) palette = QPalette() palette.setColor(QPalette.Text, Qt.black) self.verifyBox.setPalette(palette) self.verifyBox.setAlignment(Qt.AlignCenter) self.verifyButton = QPushButton('Verify') self.verifyButton.clicked.connect(self.checkVerify) self.verifyButton.setFixedWidth(150) self.addButton = QPushButton('OK') self.addButton.clicked.connect(self.add) self.boxLayout.addWidget(self.nameWidget) self.boxLayout.addWidget(self.steamIdWidget) self.boxLayout.addWidget(self.sharedWidget) self.boxLayout.addWidget(self.identityWidget) self.boxLayout.addSpacing(10) self.boxLayout.addWidget(self.verifyLabel) self.boxLayout.addWidget(self.verifyBox, 0, Qt.AlignCenter) self.boxLayout.addWidget(self.verifyButton, 0, Qt.AlignCenter) self.boxLayout.addSpacing(10) self.boxLayout.addWidget(self.addButton, 0, Qt.AlignRight) self.setFixedSize(self.sizeHint()) self.center() self.show() def getName(self): return self.nameWidget.box.text() def getAccount(self): return {'name': self.getName(), 'type': self.type, 'sharedSecret': self.sharedSecret, 'identitySecret': self.identitySecret, 'steamId': self.steamId, 'icon': 'icons/SteamIcon.png'} def invalidateSecret(self, text=''): self.sharedSecret = None self.identitySecret = None self.steamId = None self.verifyBox.setText(text) def checkVerify(self): self.sharedSecret = self.sharedWidget.box.text() self.identitySecret = self.identityWidget.box.text() self.steamId = self.steamIdWidget.box.text() if not self.sharedSecret or not self.identitySecret or not self.steamId: self.invalidateSecret('Invalid') return try: self.verifyBox.setText(self.base.getAuthCode(self.getAccount())) except: self.invalidateSecret('Invalid') def add(self): if not self.sharedSecret or not self.getName(): return self.base.addAccount(self.getAccount()) self.close()
class CalQtator(QWidget): def __init__(self, parent=None): super().__init__(parent) self._expression = '0' self.result = None self.operator = QLabel() self.display = QLineEdit() self.display.setReadOnly(True) self.display.setAlignment(Qt.AlignmentFlag.AlignRight) self.display.setText(Symbol.ZERO.value) self.button_grid = ButtonGrid() self.button_grid.button_clicked.connect(self.handle_button_clicked) layout = QGridLayout() layout.addWidget(self.display, 0, 0) layout.addWidget(self.operator, 0, 1) layout.addWidget(self.button_grid, 1, 0) self.setLayout(layout) @property def expression(self) -> str: return self._expression @expression.setter def expression(self, value) -> None: self._expression = value @property def last_symbol(self) -> Symbol: return Symbol(self.last_statement[-1]) @property def last_statement(self) -> str: return self.expression.strip().split(' ')[-1] def handle_button_clicked(self, symbol: Symbol): last_statement = self.last_statement last_symbol = self.last_symbol if symbol == Symbol.EQUALS: if last_symbol in OPERATORS: self.expression = self.expression.removesuffix(last_symbol.value) operator_values = [o.value for o in OPERATORS] prepared_stmts = [] stmts = self.expression.split() for stmt in stmts: if stmt not in operator_values: stmt = f'Decimal("{stmt}")' if stmt == Symbol.MULTIPLICATION.value: stmt = '*' prepared_stmts.append(stmt) prepared_expr = ' '.join(prepared_stmts) equals: Decimal = eval(prepared_expr) self.result = str(equals).removesuffix('.0') self.expression = self.result self.display.setText(self.result) elif symbol == Symbol.CLEAR: if last_symbol in OPERATORS: self.expression = self.expression.removesuffix(last_symbol.value) else: self.expression = self.expression.removesuffix(last_statement) if not self.expression: self.expression = '0' self.display.setText('0') elif symbol == Symbol.ALL_CLEAR: self.expression = '0' self.result = None self.display.setText(self.expression) elif symbol in NUMBERS: if self.result: self.result = None self.expression = symbol.value self.display.setText(self.expression) elif last_statement == '0': self.result = None self.display.setText(symbol.value) self.expression = self.expression.removesuffix('0') self.expression += symbol.value elif last_symbol in NUMBERS: self.result = None self.expression = self.expression.removesuffix(last_statement) last_statement += symbol.value self.expression += last_statement self.display.setText(last_statement) elif last_symbol in OPERATORS: self.result = None self.expression += f' {symbol.value}' self.display.setText(self.last_statement) elif last_symbol == Symbol.POINT: self.expression += symbol.value self.display.setText(self.last_statement) elif symbol in OPERATORS: self.result = None if last_symbol in OPERATORS: self.expression = self.expression.removesuffix(last_statement) self.expression += f' {symbol.value}' elif symbol == Symbol.POINT: if self.result: self.result = None self.expression = '0' + symbol.value self.display.setText(self.expression) elif last_symbol in OPERATORS: self.expression = '0' + symbol.value self.display.setText(self.expression) elif last_symbol in NUMBERS: if Symbol.POINT.value not in last_statement: self.expression += symbol.value self.display.setText(self.last_statement)
class TableClothGenerator(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # Main UI settings self.setWindowTitle('Tablecloth Generator') self.setWindowIcon(QIcon('icon.ico')) self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) self.resize(350, 350) self.center() self._createMenuBar() self.MainUI() def MainUI(self): # Obtain the configs fp_config = open(THISDIR + "\\config\\config.json", "r", encoding="utf-8") self.config = json.loads(fp_config.read()) fp_config.close() # Obtain and List the teams fp_teams = open(THISDIR + "\\config\\teams.json", "r", encoding="utf-8") conf_teams = json.loads(fp_teams.read()) fp_teams.close() self.teams = conf_teams["teams"] self.players = conf_teams["players"] # Obtain all images needed to create the tablecloth self.background = Image.open(THISDIR + "\\images\\mat.png") self.table_border = Image.open(THISDIR + "\\images\\table_border.png") self.tech_lines = Image.open(THISDIR + "\\images\\technical_lines.png") # Check if there's no configuration set up # and prompt to create/import one if self.config["total_teams"] == 0: self.no_config = QMessageBox.question(self, "No configuration", "No configuration has been found. Do you wish to set up a new one?", QMessageBox.Yes | QMessageBox.No) if self.no_config == QMessageBox.Yes: self.CreateTeamsWindow() self.bg_image = self.config["image_route"] self.players_combobox = QComboBox() self.UpdatePlayersList() self.players_combobox.setEditable(True) self.players_combobox.completer()\ .setCompletionMode(QCompleter.PopupCompletion) self.players_combobox.setInsertPolicy(QComboBox.NoInsert) # Set up the GUI self.statusBar().showMessage("Remember: Rig responsibly.") # Bottom (EAST) self.label_east = QLabel(self) self.label_east.setText("<h1>East Seat</h1>") self.label_east.setAlignment(QtCore.Qt.AlignCenter) self.image_east = QLabel(self) self.image_east.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_east.setAlignment(QtCore.Qt.AlignCenter) self.search_east = QLineEdit() self.search_east.setAlignment(QtCore.Qt.AlignCenter) self.search_east.editingFinished.connect( lambda: self.searchPlayer(self.search_east.text(), self.cloth_east)) self.cloth_east = QComboBox() self.cloth_east.setModel(self.players_combobox.model()) self.cloth_east.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_east, self.image_east)) # Right (SOUTH) self.label_south = QLabel(self) self.label_south.setText("<h1>South Seat</h1>") self.label_south.setAlignment(QtCore.Qt.AlignCenter) self.image_south = QLabel(self) self.image_south.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_south.setAlignment(QtCore.Qt.AlignCenter) self.image_south.show() self.search_south = QLineEdit() self.search_south.setAlignment(QtCore.Qt.AlignCenter) self.search_south.editingFinished.connect( lambda: self.searchPlayer(self.search_south.text(), self.cloth_south)) self.cloth_south = QComboBox() self.cloth_south.setModel(self.players_combobox.model()) self.cloth_south.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_south, self.image_south)) # Top (WEST) self.label_west = QLabel(self) self.label_west.setText("<h1>West Seat</h1>") self.label_west.setAlignment(QtCore.Qt.AlignCenter) self.image_west = QLabel(self) self.image_west.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_west.setAlignment(QtCore.Qt.AlignCenter) self.image_west.show() self.cloth_west = QComboBox() self.search_west = QLineEdit() self.search_west.setAlignment(QtCore.Qt.AlignCenter) self.search_west.editingFinished.connect( lambda: self.searchPlayer(self.search_west.text(), self.cloth_west)) self.cloth_west.setModel(self.players_combobox.model()) self.cloth_west.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_west, self.image_west)) # Left (NORTH) self.label_north = QLabel(self) self.label_north.setText("<h1>North Seat</h1>") self.label_north.setAlignment(QtCore.Qt.AlignCenter) self.image_north = QLabel(self) self.image_north.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_north.setAlignment(QtCore.Qt.AlignCenter) self.image_north.show() self.cloth_north = QComboBox() self.search_north = QLineEdit() self.search_north.setAlignment(QtCore.Qt.AlignCenter) self.search_north.editingFinished.connect( lambda: self.searchPlayer(self.search_north.text(), self.cloth_north)) self.cloth_north.setModel(self.players_combobox.model()) self.cloth_north.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_north, self.image_north)) # Technical lines self.technical_lines = QCheckBox("Show Technical lines", self) # Generate button self.generate = QPushButton(self) self.generate.setText("Generate Tablecloth") self.generate.clicked.connect(self.GeneratePreview) # Add custom mat self.custom_mat = QPushButton(self) self.custom_mat.setText("Add Mat") self.custom_mat.clicked.connect(self.MatDialog) # Create the layout grid_layout = QGridLayout() grid_layout.setAlignment(QtCore.Qt.AlignCenter) grid_layout.setAlignment(QtCore.Qt.AlignTop) # Labels East, West grid_layout.addWidget(self.label_east, 1, 1) grid_layout.addWidget(self.label_west, 1, 2) # Image preview East, West grid_layout.addWidget(self.image_east, 2, 1) grid_layout.addWidget(self.image_west, 2, 2) # Search player East, West grid_layout.addWidget(self.search_east, 3, 1) grid_layout.addWidget(self.search_west, 3, 2) # Player combobox East, West grid_layout.addWidget(self.cloth_east, 4, 1) grid_layout.addWidget(self.cloth_west, 4, 2) # Labes South, North grid_layout.addWidget(self.label_south, 5, 1) grid_layout.addWidget(self.label_north, 5, 2) # Image preview South, North grid_layout.addWidget(self.image_south, 6, 1) grid_layout.addWidget(self.image_north, 6, 2) # Search player South, North grid_layout.addWidget(self.search_south, 7, 1) grid_layout.addWidget(self.search_north, 7, 2) # Player combobox South, North grid_layout.addWidget(self.cloth_south, 8, 1) grid_layout.addWidget(self.cloth_north, 8, 2) # Technical lines grid_layout.addWidget(self.technical_lines, 9, 1) # Custom mat/bg grid_layout.addWidget(self.custom_mat, 10, 1) # Generate grid_layout.addWidget(self.generate, 10, 2) self.centralWidget.setLayout(grid_layout) # Create the window self.show() def _createMenuBar(self): # Settings and stuff for the toolbar menubar = QMenuBar(self) file_menu = QMenu("&File", self) file_menu.addAction("Create Team(s)", self.CreateTeamsWindow) file_menu.addAction("Edit Team(s)", self.EditTeamsWindow) file_menu.addAction("Exit", self.close) settings_menu = QMenu("&Settings", self) settings_menu.addAction("Version", self.SeeVersion) settings_menu.addAction("Help", self.GetHelp) menubar.addMenu(file_menu) menubar.addMenu(settings_menu) self.setMenuBar(menubar) def _createProgressBar(self): self.progress_bar = QProgressBar() self.progress_bar.minimum = 0 self.progress_bar.maximum = 100 self.progress_bar.setValue(0) self.progress_bar.setTextVisible(False) self.progress_bar.setGeometry(50, 50, 10, 10) self.progress_bar.setAlignment(QtCore.Qt.AlignRight) self.progress_bar.adjustSize() self.statusBar().addPermanentWidget(self.progress_bar) self.ChangeAppStatus(False) def SwitchImage(self, cloth, image): # It shows you the team logo. No way you can miss those, right? team_id = self.SearchTeamID(cloth, True) image.setPixmap(QPixmap( "images/logos/team%d.png" % team_id).scaled(100,100)) def searchPlayer(self, text, combobox): # It even searches the player for you. What more could you want? search_index = combobox.findText(text, QtCore.Qt.MatchContains) if search_index == -1: QMessageBox.warning(self, "Error", "No player found") else: combobox.setCurrentIndex(search_index) def CreateTeamsWindow(self): self.teamcreation_wid = EditionWidget() self.teamcreation_wid.resize(400, 200) self.teamcreation_wid.setWindowTitle("Teams configuration") self.new_config = {} id_label = QLabel(self) id_label.setText("Team ID: ") self.num_id = QLabel(self) current_id = str(self.config["total_teams"] + 1) self.num_id.setText(current_id) name_label = QLabel(self) name_label.setText("Team Name:") name_label.setFocus() self.name_input = QLineEdit(self) members_label = QLabel(self) members_label.setText("Members (write and press enter):") members_input = QLineEdit(self) members_input.editingFinished.connect( lambda: self.AddMember(members_input)) self.members_list = QListWidget(self) import_image = QPushButton(self) import_image.setText("Import Team Image") import_image.clicked.connect(self.ImportTeamImage) add_team = QPushButton(self) add_team.setText("Add Team") add_team.clicked.connect( lambda: self.addTeamFunction(self.name_input.text(), self.members_list)) import_config = QPushButton(self) import_config.setText("Import configuration") import_config.clicked.connect(self.importTeamFunction) config_lay = QGridLayout() config_lay.addWidget(id_label, 1, 0) config_lay.addWidget(self.num_id, 1, 1) config_lay.addWidget(name_label, 2, 0) config_lay.addWidget(self.name_input, 2, 1) config_lay.addWidget(members_label, 3, 0) config_lay.addWidget(members_input, 3, 1) config_lay.addWidget(self.members_list, 4, 0, 2, 2) config_lay.addWidget(add_team, 6, 0) config_lay.addWidget(import_image, 6, 1) config_lay.addWidget(import_config, 7, 0, 1, 2) self.teamcreation_wid.setLayout(config_lay) self.teamcreation_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.teamcreation_wid.activateWindow() self.teamcreation_wid.raise_() self.teamcreation_wid.show() def addTeamFunction(self, name, members): fp_teams = open(THISDIR + "\\config\\teams.json", "r", encoding="utf-8") current_teams = json.loads(fp_teams.read()) fp_teams.close() team = {} current_teams["teams"].append(name) current_teams["players"][name] = [str(self.members_list.item(i).text())\ for i in range(self.members_list.count())] new_team = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") add_config = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") self.teams = current_teams["teams"] self.players = current_teams["players"] self.config["total_teams"] += 1 new_id = self.config["total_teams"] + 1 self.num_id.setText(str(new_id)) add_config.write(json.dumps(self.config, indent=4)) new_team.write(json.dumps(current_teams, indent=4)) new_team.close() self.name_input.clear() self.members_list.clear() self.UpdatePlayersList() def ImportTeamImage(self): image_dialog = QFileDialog(self) image_dialog = QFileDialog.getOpenFileName(filter="Images (*.png)", selectedFilter="Images (*.png)") if image_dialog[0] != "": new_team_logo = Image.open(image_dialog[0]).convert("RGBA") if new_team_logo.size != (250, 250): new_team_logo.resize((250, 250)) new_team_logo.save(THISDIR+"\\images\\logos\\team%s.png"\ % self.num_id.text()) QMessageBox.information(self, "Team Image", "Team image added.") def importTeamFunction(self): file_dialog = QFileDialog(self) file_dialog = QFileDialog.getOpenFileName( filter="Team Files (*.json *.zip)", selectedFilter="Team Files (*.json *.zip)") if file_dialog[0] != "": if is_zipfile(file_dialog[0]): with ZipFile(file_dialog[0]) as zip_import: list_of_files = zip_import.namelist() for fimp in list_of_files: if fimp.startswith('logos'): zip_import.extract(fimp, path=THISDIR+'\\images\\') imported_teams = zip_import.read('teams.json') imported_teams = imported_teams.decode('utf-8') else: imported_teams = open(file_dialog[0], "r", encoding="utf-8").read() json_teams = json.loads(imported_teams) self.teams = json_teams["teams"] self.players = json_teams["players"] new_teams = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") new_teams.write(json.dumps(json_teams, indent=4)) new_teams.close() old_config = open(THISDIR + "\\config\\config.json", "r", encoding="utf-8").read() old_config = json.loads(old_config) old_config["total_teams"] = len(json_teams["teams"]) self.config = old_config new_config = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") new_config.write(json.dumps(self.config, indent=4)) new_config.close() self.UpdatePlayersList() self.image_east.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_east.setModel(self.players_combobox.model()) self.image_south.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_south.setModel(self.players_combobox.model()) self.image_west.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_west.setModel(self.players_combobox.model()) self.image_north.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_north.setModel(self.players_combobox.model()) self.statusBar().showMessage("Teams imported successfully.") self.teamcreation_wid.close() def AddMember(self, member): self.members_list.addItem(member.text()) member.clear() def EditTeamsWindow(self): self.teamedit_wid = EditionWidget() self.teamedit_wid.resize(400, 320) self.teamedit_wid.setWindowTitle("Edit Teams") self.teams_list = QComboBox(self) self.teams_list.addItem("--- Select a team ---") for team in self.teams: self.teams_list.addItem(team) self.teams_list.currentIndexChanged.connect(self.UpdateTeamInfo) team_id_label = QLabel(self) team_id_label.setText("Team ID: ") self.config_team_id = QLabel(self) team_name_label = QLabel(self) team_name_label.setText("Team name: ") self.config_team_name = QLabel(self) team_members_label = QLabel(self) team_members_label.setText("Team members: ") self.config_team_members = QListWidget(self) add_member_label = QLabel(self) add_member_label.setText("Add new member: ") add_member_input = QLineEdit(self) add_member_input.editingFinished.connect(self.AddNewMember) delete_member = QPushButton(self) delete_member.setText("Delete member") delete_member.clicked.connect(self.DeleteMember) delete_team = QPushButton(self) delete_team.setText("Delete Team") delete_team.clicked.connect(self.DeleteTeam) save_changes = QPushButton(self) save_changes.setText("Save changes") save_changes.clicked.connect(self.SaveEdits) export_config = QPushButton(self) export_config.setText("Export Configuration") export_config.clicked.connect(self.ExportTeams) config_lay = QGridLayout() config_lay.addWidget(self.teams_list, 1, 0) config_lay.addWidget(team_id_label, 2, 0) config_lay.addWidget(self.config_team_id, 2, 1) config_lay.addWidget(team_name_label, 3, 0) config_lay.addWidget(self.config_team_name, 3, 1, 1, 2) config_lay.addWidget(team_members_label, 4, 0) config_lay.addWidget(self.config_team_members, 5, 0) config_lay.addWidget(add_member_label, 6, 0) config_lay.addWidget(add_member_input, 6, 1, 1, 2) config_lay.addWidget(delete_member, 7, 0) config_lay.addWidget(delete_team, 7, 1) config_lay.addWidget(save_changes, 8, 0) config_lay.addWidget(export_config, 8, 1) self.teamedit_wid.setLayout(config_lay) self.teamedit_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.teamedit_wid.activateWindow() self.teamedit_wid.raise_() self.teamedit_wid.show() def UpdateTeamInfo(self): sender = self.sender() if sender.currentIndex() > 0: team_id = sender.currentIndex() self.config_team_id.setText(str(team_id)) self.config_team_name.setText(sender.currentText()) if self.config_team_members.count() > 0: self.config_team_members.clear() self.config_team_members.addItems( self.players[sender.currentText()]) def AddNewMember(self): sender = self.sender() self.config_team_members.addItem(sender.text()) sender.clear() def DeleteMember(self): list_members = self.config_team_members.selectedItems() if len(list_members) == 0: QMessageBox.warning(self, "Error", "No player selected") else: for member in list_members: self.config_team_members.takeItem( self.config_team_members.row(member)) def DeleteTeam(self): team_id = int(self.config_team_id.text()) is_last_item = self.teams[self.teams.index( self.config_team_name.text())] == (self.teams[len(self.teams)-1]) self.teams.pop(self.teams.index(self.config_team_name.text())) self.players.pop(self.config_team_name.text()) new_teamlist = {} new_teamlist["teams"] = self.teams new_teamlist["players"] = self.players current_teams = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") current_teams.write(json.dumps(new_teamlist, indent=4)) current_teams.close() if is_last_item == True: self.teams_list.setCurrentIndex(1) else: self.teams_list.setCurrentIndex(team_id+1) self.teams_list.removeItem(team_id) self.UpdatePlayersList() self.cloth_east.setModel(self.players_combobox.model()) self.cloth_south.setModel(self.players_combobox.model()) self.cloth_west.setModel(self.players_combobox.model()) self.cloth_north.setModel(self.players_combobox.model()) def ExportTeams(self): export_dir = self.config["save_route"] if self.config["save_route"] \ is not None else THISDIR exported_file = QFileDialog.getSaveFileName(self, "Save File", export_dir, "Save files (*.zip)") if exported_file[0] != "": export_filename = exported_file[0] if export_filename.endswith(".zip") is False: export_filename += ".zip" files_to_export = [] files_to_export.append("config\\teams.json") for root, directories, files in os.walk(THISDIR+"\\images\\logos"): for filename in files: filepath = os.path.join(root, filename) files_to_export.append(filepath) with ZipFile(export_filename, "w") as export_zip: for exp_file in files_to_export: export_name = exp_file if exp_file.endswith(".json"): split_name = exp_file.split("\\") export_name = split_name[-1] if exp_file.endswith(".png"): split_name = exp_file.split("\\") export_name = "\\logos\\" + split_name[-1] export_zip.write(exp_file, arcname=export_name) export_zip.close() if os.path.exists(export_filename): QMessageBox.information(self, "Export", "The export was successful") def SaveEdits(self): list_members = [str(self.config_team_members.item(i).text()) for i in \ range(self.config_team_members.count())] self.players[self.config_team_name.text()] = list_members new_teamlist = {} new_teamlist["teams"] = self.teams new_teamlist["players"] = self.players current_teams = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") current_teams.write(json.dumps(new_teamlist, indent=4)) current_teams.close() self.teamedit_wid.close() self.statusBar().showMessage("Settings saved.") def MatDialog(self): mat_dialog = QFileDialog(self) mat_dialog = QFileDialog.getOpenFileName(filter="Images (*.png *.jpg)", selectedFilter="Images (*.png *.jpg)") if mat_dialog[0] != "": self.GenerateMat(mat_dialog[0]) def GenerateMat(self, image): self.background = image background = Image.open(self.background).resize((2048,2048))\ .convert("RGBA") self.mat_thread = QThread() east_id = self.SearchTeamID(self.cloth_east, True) south_id = self.SearchTeamID(self.cloth_south, True) west_id = self.SearchTeamID(self.cloth_west, True) north_id = self.SearchTeamID(self.cloth_north, True) if self.config["save_route"] is None: save_to_route = THISDIR else: save_to_route = self.config["save_route"] self._createProgressBar() self.mat_worker = GenerateImageThread(background, self.table_border, east_id, south_id, west_id, north_id, self.technical_lines.isChecked(), save_to_route, self.bg_image, True) self.mat_worker.moveToThread(self.mat_thread) self.mat_thread.started.connect(self.mat_worker.run) self.mat_worker.update_progress.connect(self.UpdateStatus) self.mat_worker.finished.connect(self.mat_thread.quit) self.mat_worker.finished.connect(self.mat_worker.deleteLater) self.mat_thread.finished.connect(self.mat_thread.deleteLater) self.mat_thread.finished.connect(self.MatPreviewWindow) self.mat_thread.start() def MatPreviewWindow(self): self.statusBar().showMessage('Mat preview generated.') self.statusBar().removeWidget(self.progress_bar) # Now you can go back to rigging self.ChangeAppStatus(True) self.mat_wid = QWidget() self.mat_wid.resize(600, 600) self.mat_wid.setWindowTitle("Background preview") mat_preview_title = QLabel(self) mat_preview_title.setText("Selected image (1/4 scale)") mat_preview = QLabel(self) mat_preview.setPixmap(QPixmap(tempfile.gettempdir()+"\\Table_Dif.jpg")\ .scaled(512,512)) confirm = QPushButton(self) confirm.setText("Confirm") confirm.clicked.connect( lambda: self.ChangeMatImage(self.background)) vbox = QVBoxLayout() vbox.setAlignment(QtCore.Qt.AlignCenter) vbox.addWidget(mat_preview_title) vbox.addWidget(mat_preview) vbox.addWidget(confirm) self.mat_wid.setLayout(vbox) self.mat_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.mat_wid.activateWindow() self.mat_wid.raise_() self.mat_wid.show() def ChangeMatImage(self, image): new_bg = Image.open(image) if new_bg.size != (2048, 2048): new_bg = new_bg.resize((2048, 2048)) if new_bg.mode != "RGBA": new_bg = new_bg.convert("RGBA") if self.config["save_route"] is not None: new_bg.save(self.config["save_route"]+"\\images\\mat.png") self.bg_image = self.config["save_route"]+"\\images\\mat.png" else: new_bg.save(THISDIR+"\\images\\mat.png") self.bg_image = THISDIR+"\\images\\mat.png" self.background = new_bg self.config["image_route"] = self.bg_image new_file = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") new_file.write(json.dumps(self.config, indent=4)) new_file.close() self.statusBar().showMessage('New background added.') self.statusBar().removeWidget(self.progress_bar) self.ChangeAppStatus(True) self.mat_wid.close() def GeneratePreview(self): self.preview_thread = QThread() east_id = self.SearchTeamID(self.cloth_east, True) south_id = self.SearchTeamID(self.cloth_south, True) west_id = self.SearchTeamID(self.cloth_west, True) north_id = self.SearchTeamID(self.cloth_north, True) if self.config["save_route"] is None: save_to_route = THISDIR else: save_to_route = self.config["save_route"] self._createProgressBar() self.preview_worker = GenerateImageThread(self.background, self.table_border, east_id, south_id, west_id, north_id, self.technical_lines.isChecked(), save_to_route, self.bg_image, True) self.preview_worker.moveToThread(self.preview_thread) self.preview_thread.started.connect(self.preview_worker.run) self.preview_worker.update_progress.connect(self.UpdateStatus) self.preview_worker.finished.connect(self.preview_thread.quit) self.preview_worker.finished.connect(self.preview_worker.deleteLater) self.preview_thread.finished.connect(self.preview_thread.deleteLater) self.preview_thread.finished.connect(self.PreviewWindow) self.preview_thread.start() def PreviewWindow(self): self.statusBar().showMessage('Tablecloth preview generated.') self.statusBar().removeWidget(self.progress_bar) # Now you can go back to rigging self.ChangeAppStatus(True) self.preview_wid = QWidget() self.preview_wid.resize(600, 600) self.preview_wid.setWindowTitle("Tablecloth preview") tablecloth = QPixmap(tempfile.gettempdir()+"\\Table_Dif.jpg") tablecloth_preview_title = QLabel(self) tablecloth_preview_title.setText("Tablecloth preview (1/4 scale)") tablecloth_preview = QLabel(self) tablecloth_preview.setPixmap(tablecloth.scaled(512,512)) confirm = QPushButton(self) confirm.setText("Confirm") confirm.clicked.connect(self.GenerateImage) confirm.clicked.connect(self.preview_wid.close) vbox = QVBoxLayout() vbox.setAlignment(QtCore.Qt.AlignCenter) vbox.addWidget(tablecloth_preview_title) vbox.addWidget(tablecloth_preview) vbox.addWidget(confirm) self.preview_wid.setLayout(vbox) self.preview_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.preview_wid.activateWindow() self.preview_wid.raise_() self.preview_wid.show() def GeneratedDialog(self): self.statusBar().showMessage('Tablecloth generated. Happy rigging!') self.statusBar().removeWidget(self.progress_bar) # Now you can go back to rigging self.ChangeAppStatus(True) mbox = QMessageBox() mbox.setWindowTitle("Tablecloth Generator") mbox.setText("Tablecloth Generated!") mbox.setStandardButtons(QMessageBox.Ok) mbox.exec() def UpdateStatus(self, status): self.progress_bar.setValue(status) def GenerateImage(self): self.statusBar().showMessage('Generating image...') self._createProgressBar() if self.config["save_route"] is None: self.config["save_route"] = THISDIR save_to_route = QFileDialog.getExistingDirectory(self, "Where to save the image", self.config["save_route"], QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if self.config["save_route"] != save_to_route: temp_file = open(THISDIR + "\\config\\config.json", "r", encoding="utf-8") fp_teams = json.loads(temp_file.read()) fp_teams["save_route"] = save_to_route fp_teams["image_route"] = self.bg_image new_file = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") new_file.write(json.dumps(fp_teams, indent=4)) new_file.close() self.background = Image.open(THISDIR + "\\images\\mat.png") self.table_border = Image.open(THISDIR + "\\images\\table_border.png") self.tech_lines = Image.open(THISDIR + "\\images\\technical_lines.png") self.thread = QThread() east_id = self.SearchTeamID(self.cloth_east, True) south_id = self.SearchTeamID(self.cloth_south, True) west_id = self.SearchTeamID(self.cloth_west, True) north_id = self.SearchTeamID(self.cloth_north, True) self.worker = GenerateImageThread(self.background, self.table_border, east_id, south_id, west_id, north_id, self.technical_lines.isChecked(), save_to_route, self.bg_image) self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.worker.update_progress.connect(self.UpdateStatus) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) self.thread.finished.connect(self.GeneratedDialog) self.thread.start() def ChangeAppStatus(self, status): # True for enable, False for disable. self.cloth_east.setEnabled(status) self.search_east.setEnabled(status) self.cloth_south.setEnabled(status) self.search_south.setEnabled(status) self.cloth_west.setEnabled(status) self.search_west.setEnabled(status) self.cloth_north.setEnabled(status) self.search_north.setEnabled(status) self.generate.setEnabled(status) def SearchTeamID(self, cloth, plus_one=False): team_id = self.teams.index(cloth.itemData(cloth.currentIndex())) if plus_one: team_id += 1 return team_id def UpdatePlayersList(self): for team, members in self.players.items(): for member in members: self.players_combobox.addItem(member, team) def center(self): qr = self.frameGeometry() cp = QScreen().availableGeometry().center() qr.moveCenter(cp) def SeeVersion(self): git_url = "https://raw.githubusercontent.com/vg-mjg/tablecloth-" git_url += "generator/main/version.txt" with urllib.request.urlopen(git_url) as response: url_version = response.read().decode("utf-8") version = "Your version is up to date!" if url_version != VERSION: version = "Your version is outdated." version += "Please check the <a href='https://github.com/vg-mjg/" version += "tablecloth-generator/releases'>Github page</a>" version +=" for updates." version_message = QMessageBox(self) version_message.setWindowTitle("Checking version") version_message.setText("""<h1>Tablecloth generator</h1> <br> <b>Current Version:</b> %s<br> <b>Your Version:</b> %s<br> <i>%s</i> """ % (url_version, VERSION, version)) version_message.exec() def GetHelp(self): webbrowser.open("https://github.com/vg-mjg/tablecloth-generator/wiki")
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.view = None self.uid = None self.b_id = None self.chap_id = None self.page_num = None self.page_length = None self.label_choose_page = None self.widget_choose_page = None self.add_bookmark_dialog = None self.add_signal_func = { LoginView: self.add_LoginView_signal, RegisterView: self.add_RegisterView_signal, WelcomeView: self.add_WelcomeView_signal, UserBookmarkView: self.add_UserBookmarkView_signal, ChapterView: self.add_ChapterView_signal, ContentView: self.add_ContentView_signal, BookBookmarkView: self.add_BookBookmarkView_signal } self.remove_signal_func = { LoginView: self.remove_LoginView_signal, RegisterView: self.remove_RegisterView_signal, WelcomeView: self.remove_WelcomeView_signal, UserBookmarkView: self.remove_BookmarkView_signal, ChapterView: self.remove_ChapterView_signal, ContentView: self.remove_ContentView_signal, BookBookmarkView: self.remove_BookmarkView_signal } self.add_view(LoginView, None) def closeEvent(self, event: PySide6.QtGui.QCloseEvent) -> None: if self.uid is not None: get_logout_response(self.uid) event.accept() def display_status_message(self, message, timeout=0): self.MainStatusBar.showMessage(message, timeout) def toggle_view(self, subview): old_view = type(self.view) self.remove_view() self.add_view(subview, old_view) def add_view(self, subview, old_view): assert subview in { LoginView, RegisterView, WelcomeView, UserBookmarkView, ChapterView, ContentView, BookBookmarkView } if subview == UserBookmarkView: self.view = subview(self.uid) elif subview == ChapterView: self.view = subview(self.b_id) elif subview == ContentView: self.view = subview(self.b_id, self.chap_id, self.page_num) self.page_num, self.page_length = self.view.get_page_info() elif subview == BookBookmarkView: self.view = subview(self.uid, self.b_id) else: self.view = subview() self.MainGridLayout.addWidget(self.view) self.add_signal_func.get(subview, lambda x: None)(old_view) self.view.show() def remove_view(self): type_of_view = type(self.view) assert type_of_view in { LoginView, RegisterView, WelcomeView, UserBookmarkView, ChapterView, ContentView, BookBookmarkView } self.view.hide() self.remove_signal_func.get(type_of_view, lambda: None)() self.MainToolBar.clear() self.MainGridLayout.removeWidget(self.view) self.view = None def add_LoginView_signal(self, old_view): self.view.login_button_signal.connect(self.toggle_view) self.view.register_button_signal.connect(self.toggle_view) self.view.display_status_signal.connect(self.display_status_message) self.view.set_current_user_signal.connect(self.set_current_user) def remove_LoginView_signal(self): self.view.login_button_signal.disconnect(self.toggle_view) self.view.register_button_signal.disconnect(self.toggle_view) self.view.display_status_signal.disconnect(self.display_status_message) self.view.set_current_user_signal.disconnect(self.set_current_user) def add_RegisterView_signal(self, old_view): self.view.submit_button_signal.connect(self.toggle_view) self.view.display_status_signal.connect(self.display_status_message) def remove_RegisterView_signal(self): self.view.submit_button_signal.disconnect(self.toggle_view) self.view.display_status_signal.disconnect(self.display_status_message) def add_WelcomeView_signal(self, old_view): self.view.select_book_signal.connect(self.toggle_view) self.view.display_status_signal.connect(self.display_status_message) self.view.set_current_book_signal.connect(self.set_current_book) action_logout = QAction('Logout', self) action_explore_bookmark = QAction('My Bookmark', self) action_logout.triggered.connect(self.logout_action_onclick) action_explore_bookmark.triggered.connect( lambda: self.toggle_view(UserBookmarkView)) self.MainToolBar.addAction(action_logout) self.MainToolBar.addAction(action_explore_bookmark) def remove_WelcomeView_signal(self): self.view.select_book_signal.disconnect(self.toggle_view) self.view.display_status_signal.disconnect(self.display_status_message) self.view.set_current_book_signal.disconnect(self.set_current_book) def add_BookmarkView_signal(self): self.view.display_status_signal.connect(self.display_status_message) self.view.set_current_book_signal.connect(self.set_current_book) self.view.set_current_chapter_signal.connect(self.set_current_chapter) self.view.set_current_page_signal.connect(self.set_current_page) self.view.select_chapter_signal.connect(self.toggle_view) def remove_BookmarkView_signal(self): self.view.display_status_signal.disconnect(self.display_status_message) self.view.set_current_book_signal.disconnect(self.set_current_book) self.view.set_current_chapter_signal.disconnect( self.set_current_chapter) self.view.set_current_page_signal.disconnect(self.set_current_page) self.view.select_chapter_signal.disconnect(self.toggle_view) def add_UserBookmarkView_signal(self, old_view): self.add_BookmarkView_signal() action_back = QAction('Back', self) action_remove_all = QAction('Remove all', self) action_back.triggered.connect(lambda: self.toggle_view(old_view)) action_remove_all.triggered.connect( lambda: self.view.delete_bookmark_all('user')) self.MainToolBar.addAction(action_back) self.MainToolBar.addAction(action_remove_all) def add_ChapterView_signal(self, old_view): self.view.display_status_signal.connect(self.display_status_message) self.view.select_chapter_signal.connect(self.toggle_view) self.view.set_current_chapter_signal.connect(self.set_current_chapter) action_back = QAction('Back', self) action_explore_bookmark = QAction('My Bookmark', self) action_back.triggered.connect(lambda: self.toggle_view(WelcomeView)) action_explore_bookmark.triggered.connect( lambda: self.toggle_view(BookBookmarkView)) self.MainToolBar.addAction(action_back) self.MainToolBar.addAction(action_explore_bookmark) def remove_ChapterView_signal(self): self.view.display_status_signal.disconnect(self.display_status_message) self.view.select_chapter_signal.disconnect(self.toggle_view) self.view.set_current_chapter_signal.disconnect( self.set_current_chapter) def add_ContentView_signal(self, old_view): self.view.set_current_page_signal.connect(self.set_current_page) self.view.set_page_length_signal.connect(self.set_page_length) action_back = QAction('Back', self) action_chapter_minus = QAction('<<', self) action_page_minus = QAction('<', self) action_page_plus = QAction('>', self) action_chapter_plus = QAction('>>', self) action_add_bookmark = QAction('Add Bookmark', self) action_explore_bookmark = QAction('My Bookmark', self) action_download = QAction('Download', self) self.label_choose_page = QLabel( f' ( {self.page_num + 1} / {self.page_length} ) ') self.widget_choose_page = QLineEdit() self.widget_choose_page.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.widget_choose_page.setFixedWidth(60) self.widget_choose_page.setAlignment(Qt.AlignCenter) self.widget_choose_page.setValidator( QIntValidator(self.page_num + 1, self.page_length)) action_chapter_minus.setToolTip('Chapter Up') action_page_minus.setToolTip('Page Up') action_page_plus.setToolTip('Page Down') action_chapter_plus.setToolTip('Chapter Up') action_back.triggered.connect(lambda: self.toggle_view(ChapterView)) action_chapter_minus.triggered.connect(self.chapter_minus_onclick) action_page_minus.triggered.connect(self.page_minus_onclick) action_page_plus.triggered.connect(self.page_plus_onclick) action_chapter_plus.triggered.connect(self.chapter_plus_onclick) action_add_bookmark.triggered.connect(self.open_add_bookmark_dialog) action_explore_bookmark.triggered.connect( lambda: self.toggle_view(BookBookmarkView)) action_download.triggered.connect(self.download_file) self.widget_choose_page.editingFinished.connect( self.page_choose_onfinish) self.MainToolBar.addAction(action_back) self.MainToolBar.addSeparator() self.MainToolBar.addActions([action_chapter_minus, action_page_minus]) self.MainToolBar.addWidget(self.widget_choose_page) self.MainToolBar.addWidget(self.label_choose_page) self.MainToolBar.addActions([action_page_plus, action_chapter_plus]) self.MainToolBar.addSeparator() self.MainToolBar.addActions( [action_add_bookmark, action_explore_bookmark, action_download]) def remove_ContentView_signal(self): self.view.set_current_page_signal.disconnect(self.set_current_page) self.view.set_page_length_signal.disconnect(self.set_page_length) def add_BookBookmarkView_signal(self, old_view): self.add_BookmarkView_signal() action_back = QAction('Back', self) action_remove_all = QAction('Remove all', self) action_back.triggered.connect(lambda: self.toggle_view(old_view)) action_remove_all.triggered.connect( lambda: self.view.delete_bookmark_all('user_book', self.view.b_id)) self.MainToolBar.addAction(action_back) self.MainToolBar.addAction(action_remove_all) def download_file(self): file_path = QFileDialog.getSaveFileName(self, 'Save File', 'C:\\', 'Texts (*.txt)')[0] file_content = get_chapter('single', self.b_id, self.chap_id)[1] if file_content == []: self.display_status_message('Fail to download.', 2000) with open(file_path, 'w', encoding='utf-8') as fp: fp.write(file_content) self.display_status_message('Successfully downloaded.', 2000) def set_current_user(self, uid): self.uid = uid def set_current_book(self, b_id): self.b_id = b_id def set_current_chapter(self, chap_id): self.chap_id = chap_id def set_page_length(self, page_length): self.page_length = page_length if self.label_choose_page is not None: self.label_choose_page.setText( f' ( {self.page_num + 1} / {self.page_length} ) ') def set_current_page(self, page_num): self.page_num = page_num if self.label_choose_page is not None: self.label_choose_page.setText( f' ( {self.page_num + 1} / {self.page_length} ) ') def page_minus_onclick(self): if self.page_num == 0: self.display_status_message('We are at the first page.', 2000) else: self.set_current_page(self.page_num - 1) self.view.set_page(self.page_num) def page_plus_onclick(self): if self.page_num == self.page_length - 1: self.display_status_message('We are at the last page.', 2000) else: self.set_current_page(self.page_num + 1) self.view.set_page(self.page_num) def page_choose_onfinish(self): page_num = int(self.widget_choose_page.text()) - 1 self.set_current_page(page_num) self.view.set_page(page_num) def chapter_minus_onclick(self): chap_list = get_chapter('simple', self.b_id) chap_list.sort() pos = chap_list.index(self.chap_id) if pos == 0: self.display_status_message('We are at the first chapter.', 2000) else: self.chap_id = chap_list[pos - 1] self.view.refresh(self.b_id, self.chap_id) def chapter_plus_onclick(self): chap_list = get_chapter('simple', self.b_id) chap_list.sort() chap_list_length = len(chap_list) pos = chap_list.index(self.chap_id) if pos == chap_list_length - 1: self.display_status_message('We are at the last chapter.', 2000) else: self.chap_id = chap_list[pos + 1] self.view.refresh(self.b_id, self.chap_id) def open_add_bookmark_dialog(self): self.add_bookmark_dialog = AddBookmarkDialog() self.add_bookmark_dialog.display_status_signal.connect( self.display_status_message) self.add_bookmark_dialog.close_dialog_signal.connect( self.close_add_bookmark_dialog) self.add_bookmark_dialog.transmit_bookmark_name_signal.connect( self.add_bookmark) self.add_bookmark_dialog.show() def close_add_bookmark_dialog(self): self.add_bookmark_dialog.close() self.add_bookmark_dialog.display_status_signal.disconnect( self.display_status_message) self.add_bookmark_dialog.close_dialog_signal.disconnect( self.close_add_bookmark_dialog) self.add_bookmark_dialog.transmit_bookmark_name_signal.disconnect( self.add_bookmark) self.add_bookmark_dialog = None def add_bookmark(self, bm_name): request = {'type': 'get_bookmark_id', 'data': {}} resp = get_response(request) assert resp['type'] == 'get_bookmark_id' resp_data = resp['data'] if resp_data['status'] == 'error': return resp['type'] bm_id = resp_data['content'] return add_bookmark(self.uid, self.b_id, bm_id, bm_name, self.chap_id, self.page_num) def logout_action_onclick(self): resp = get_logout_response(self.uid) assert resp['type'] == 'logout' resp_data = resp['data'] self.uid = None self.toggle_view(LoginView) message = 'Successfully Logouted.' if resp_data[ 'status'] == 'ok' else resp_data['type'] self.display_status_message(message, 3000)
class AddOTPWidget(TritonWidget): def __init__(self, base, *args, **kwargs): TritonWidget.__init__(self, base, *args, **kwargs) self.key = None self.type = Globals.OTPAuth self.setWindowTitle('Add Authenticator') self.setBackgroundColor(self, Qt.white) self.boxLayout = QVBoxLayout(self) self.boxLayout.setContentsMargins(20, 20, 20, 20) self.nameWidget = TextboxWidget(base, 'Name:') self.secretLabel = QLabel() self.secretLabel.setText( 'Enter the Secret Code. If you have a QR code,\nyou can paste the URL of the image instead.' ) self.secretLabel.setFont(QFont('Helvetica', 10)) self.secretBox = QLineEdit() self.secretBox.setFixedWidth(300) self.secretBox.setFont(QFont('Helvetica', 10)) self.secretBox.textChanged.connect( lambda text: self.invalidateSecret()) self.verifyLabel = QLabel() self.verifyLabel.setText( 'Click the Verify button to check the first code.') self.verifyLabel.setFont(QFont('Helvetica', 10)) self.verifyBox = QLineEdit() self.verifyBox.setFixedWidth(150) self.verifyBox.setFont(QFont('Helvetica', 10)) self.verifyBox.setEnabled(False) palette = QPalette() palette.setColor(QPalette.Text, Qt.black) self.verifyBox.setPalette(palette) self.verifyBox.setAlignment(Qt.AlignCenter) self.verifyButton = QPushButton('Verify') self.verifyButton.clicked.connect(self.checkVerify) self.verifyButton.setFixedWidth(150) self.addButton = QPushButton('OK') self.addButton.clicked.connect(self.add) self.boxLayout.addWidget(self.nameWidget) self.boxLayout.addSpacing(10) self.boxLayout.addWidget(self.secretLabel) self.boxLayout.addWidget(self.secretBox) self.boxLayout.addSpacing(10) self.boxLayout.addWidget(self.verifyLabel) self.boxLayout.addWidget(self.verifyBox, 0, Qt.AlignCenter) self.boxLayout.addWidget(self.verifyButton, 0, Qt.AlignCenter) self.boxLayout.addSpacing(10) self.boxLayout.addWidget(self.addButton, 0, Qt.AlignRight) self.setFixedSize(self.sizeHint()) self.center() self.show() def getName(self): return self.nameWidget.box.text() def getAccount(self): return { 'name': self.getName(), 'type': self.type, 'key': self.key, 'icon': 'icons/WinAuthIcon.png' } def invalidateSecret(self, value=''): self.key = None self.verifyBox.setText(value) def checkVerify(self): self.key = self.secretBox.text() if not self.key: self.invalidateSecret('Invalid') return self.key = self.base.readQRLink(self.key) or self.key self.key = self.key.upper().replace(' ', '') try: self.verifyBox.setText(self.base.getAuthCode(self.getAccount())) except: self.invalidateSecret('Invalid') def add(self): if not self.key or not self.getName(): return self.base.addAccount(self.getAccount()) self.close()