Tue, 10 Dec 2024 15:49:01 +0100
Updated copyright for 2025.
# -*- coding: utf-8 -*- # Copyright (c) 2010 - 2025 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the Change Signature dialog. """ import copy from PyQt6.QtCore import Qt, pyqtSlot from PyQt6.QtWidgets import QAbstractButton, QDialog, QDialogButtonBox, QListWidgetItem from .RefactoringDialogBase import RefactoringDialogBase from .Ui_ChangeSignatureDialog import Ui_ChangeSignatureDialog class ChangeSignatureDialog(RefactoringDialogBase, Ui_ChangeSignatureDialog): """ Class implementing the Change Signature dialog. """ NameRole = Qt.ItemDataRole.UserRole IsAddedRole = Qt.ItemDataRole.UserRole + 1 DefaultRole = Qt.ItemDataRole.UserRole + 2 ValueRole = Qt.ItemDataRole.UserRole + 3 def __init__(self, refactoring, title, filename, offset, parent=None): """ Constructor @param refactoring reference to the main refactoring object @type RefactoringServer @param title title of the dialog @type str @param filename file name to be worked on @type str @param offset offset within file @type int or None @param parent reference to the parent widget @type QWidget """ RefactoringDialogBase.__init__(self, refactoring, title, parent) self.setupUi(self) self._changeGroupName = "ChangeSignature" self.__filename = filename self.__offset = offset self.__definition_info = [] self.__to_be_removed = [] self.__okButton = self.buttonBox.button(QDialogButtonBox.StandardButton.Ok) self.__previewButton = self.buttonBox.addButton( self.tr("Preview"), QDialogButtonBox.ButtonRole.ActionRole ) self.__previewButton.setDefault(True) self._refactoring.sendJson( "RequestSignature", { "ChangeGroup": self._changeGroupName, "Title": self._title, "FileName": self.__filename, "Offset": self.__offset, }, ) def __processSignature(self, data): """ Private method to process the inline type data sent by the refactoring client in order to polish the dialog. @param data dictionary containing the inline type data @type dict """ self.__definition_info = data["DefinitionInfo"] # populate the parameters list for arg, default in self.__definition_info: itm = ( QListWidgetItem(arg, self.parameterList) if default is None else QListWidgetItem("{0}={1}".format(arg, default), self.parameterList) ) itm.setData(ChangeSignatureDialog.NameRole, arg) itm.setData(ChangeSignatureDialog.IsAddedRole, False) itm.setData(ChangeSignatureDialog.DefaultRole, None) itm.setData(ChangeSignatureDialog.ValueRole, None) if self.parameterList.count(): self.parameterList.setCurrentRow(0) else: self.on_parameterList_currentRowChanged(-1) @pyqtSlot(int) def on_parameterList_currentRowChanged(self, currentRow): """ Private slot called, when the current row is changed. @param currentRow index of the current row @type int """ if currentRow == -1: self.upButton.setEnabled(False) self.downButton.setEnabled(False) self.removeButton.setEnabled(False) else: maxIndex = self.parameterList.count() - 1 self.upButton.setEnabled(currentRow != 0) self.downButton.setEnabled(currentRow != maxIndex) @pyqtSlot() def on_upButton_clicked(self): """ Private slot called to move the selected item up in the list. """ row = self.parameterList.currentRow() if row == 0: # we're already at the top return itm = self.parameterList.takeItem(row) self.parameterList.insertItem(row - 1, itm) self.parameterList.setCurrentItem(itm) if row == 1: self.upButton.setEnabled(False) else: self.upButton.setEnabled(True) self.downButton.setEnabled(True) @pyqtSlot() def on_downButton_clicked(self): """ Private slot called to move the selected item down in the list. """ rows = self.parameterList.count() row = self.parameterList.currentRow() if row == rows - 1: # we're already at the end return itm = self.parameterList.takeItem(row) self.parameterList.insertItem(row + 1, itm) self.parameterList.setCurrentItem(itm) self.upButton.setEnabled(True) if row == rows - 2: self.downButton.setEnabled(False) else: self.downButton.setEnabled(True) @pyqtSlot() def on_removeButton_clicked(self): """ Private slot to remove a parameter. """ itm = self.parameterList.takeItem(self.parameterList.currentRow()) self.__to_be_removed.append(itm) @pyqtSlot() def on_addButton_clicked(self): """ Private slot to add a new parameter. """ from .AddParameterDialog import AddParameterDialog dlg = AddParameterDialog(parent=self) if dlg.exec() == QDialog.DialogCode.Accepted: name, default, value = dlg.getData() if default: s = "{0}={1}".format(name, default) else: s = name itm = QListWidgetItem(s) itm.setData(ChangeSignatureDialog.NameRole, name) itm.setData(ChangeSignatureDialog.IsAddedRole, True) if default: itm.setData(ChangeSignatureDialog.DefaultRole, default) else: itm.setData(ChangeSignatureDialog.DefaultRole, None) if value: itm.setData(ChangeSignatureDialog.ValueRole, value) else: itm.setData(ChangeSignatureDialog.ValueRole, None) if self.parameterList.count(): self.parameterList.insertItem(self.parameterList.currentRow() + 1, itm) else: self.parameterList.addItem(itm) self.parameterList.setCurrentItem(itm) @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot to act on the button pressed. @param button reference to the button pressed @type QAbstractButton """ if button == self.__previewButton: self.requestPreview() elif button == self.__okButton: self.applyChanges() def __getParameterIndex(self, definition_info, name): """ Private method to calculate the index of the given paramter. @param definition_info list of lists containing the method signature definition @type list of lists of two str @param name parameter name @type str @return index of the parameter @rtype int """ for index, pair in enumerate(definition_info): if pair[0] == name: return index return -1 def _calculateChanges(self): """ Protected method to initiate the calculation of the changes. """ removals = [] definition_info = copy.deepcopy(self.__definition_info) for itm in self.__to_be_removed: if itm.data(ChangeSignatureDialog.IsAddedRole): continue index = self.__getParameterIndex( definition_info, itm.data(ChangeSignatureDialog.NameRole) ) if index >= 0: removals.append(index) del definition_info[index] additions = [] for index in range(self.parameterList.count()): itm = self.parameterList.item(index) if itm.data(ChangeSignatureDialog.IsAddedRole): name = itm.data(ChangeSignatureDialog.NameRole) default = itm.data(ChangeSignatureDialog.DefaultRole) value = itm.data(ChangeSignatureDialog.ValueRole) additions.append([index, name, default, value]) try: definition_info.insert(index, [name, default]) except Exception as err: self._refactoring.handleRopeError(err, self._title) newOrdering = [] for row in range(self.parameterList.count()): itm = self.parameterList.item(row) name = itm.data(ChangeSignatureDialog.NameRole) index = self.__getParameterIndex(definition_info, name) if index >= 0: newOrdering.append(index) autodef = self.autodefEdit.text() if not autodef: autodef = None self._refactoring.sendJson( "CalculateSignatureChanges", { "ChangeGroup": self._changeGroupName, "Title": self._title, "FileName": self.__filename, "Offset": self.__offset, "Removals": removals, "Additions": additions, "Ordering": newOrdering, "AutoDef": autodef, "Hierarchy": self.hierarchyCheckBox.isChecked(), }, ) def processChangeData(self, data): """ Public method to process the change data sent by the refactoring client. @param data dictionary containing the change data @type dict """ subcommand = data["Subcommand"] if subcommand == "Signature": self.__processSignature(data) else: # pass on to base class RefactoringDialogBase.processChangeData(self, data)