diff --git a/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py b/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py index 453e35fd5f..d4f6d84ab1 100644 --- a/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py +++ b/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py @@ -285,7 +285,7 @@ def getTabsForFit(self): """ Returns list of tab names selected for fitting """ - return [tab for tab in self.tabs_for_fitting if self.tabs_for_fitting[tab]] + return [tab for tab in self.tabs_for_fitting if ObjectLibrary.getObject(tab) is not None] def onChainFit(self, is_checked): """ @@ -332,7 +332,6 @@ def onFit(self): weights = {} for tab in tabs_to_fit: tab_object = ObjectLibrary.getObject(tab) - #weight = FittingUtilities.getWeight(tab_object.data, tab_object.is2D, flag=tab_object.weighting) weight = FittingUtilities.getRelativeError(tab_object.data, tab_object.is2D, flag=tab_object.weighting) weights[tab] = weight diff --git a/src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py b/src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py index 09fb8fcc3f..50b5392e28 100644 --- a/src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py +++ b/src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py @@ -1,5 +1,6 @@ import numpy import copy +import re from typing import Optional @@ -62,6 +63,10 @@ def __init__(self, parent=None, data=None): # The tabs need to be movabe self.setMovable(True) + # Remember the last tab closed + self.lastTabClosed = None + self.installEventFilter(self) + self.communicate = self.parent.communicator() # Initialize the first tab @@ -96,6 +101,14 @@ def __init__(self, parent=None, data=None): self.plusButton.setToolTip("Add a new Fit Page") self.plusButton.clicked.connect(lambda: self.addFit(None)) + def eventFilter(self, widget, event): + if event.type() == QtCore.QEvent.KeyPress: + key = event.key() + # check for Ctrl-T press + if key == QtCore.Qt.Key_T and event.modifiers() == QtCore.Qt.ControlModifier: + self.addClosedTab() + return True + return QtCore.QObject.eventFilter(self, widget, event) def updateWindowTitle(self): """ @@ -261,7 +274,7 @@ def addFit(self, data, is_batch=False, tab_index=None): self.tabs.append(tab) if data: self.updateFitDict(data, tab_name) - self.maxIndex = max([tab.tab_id for tab in self.tabs], default=0) + 1 + self.maxIndex = self.nextAvailableTabIndex() icon = QtGui.QIcon() if is_batch: @@ -272,6 +285,34 @@ def addFit(self, data, is_batch=False, tab_index=None): # Notify listeners self.tabsModifiedSignal.emit() + def nextAvailableTabIndex(self): + """ + Returns the index of the next available tab + """ + return max((tab.tab_id for tab in self.tabs), default=0) + 1 + + def addClosedTab(self): + """ + Recover the deleted tab. + The tab is held in self.lastTabClosed + """ + if self.lastTabClosed is None: + return + tab = self.lastTabClosed + icon = QtGui.QIcon() + # tab_name = self.getTabName() + tab_name = "FitPage" + str(tab.tab_id) + ObjectLibrary.addObject(tab_name, tab) + self.addTab(tab, icon, tab_name) + # Update the list of tabs + self.tabs.append(tab) + # Show the new tab + self.setCurrentWidget(tab) + # lastTabClosed is no longer valid + self.lastTabClosed = None + # Notify listeners + self.tabsModifiedSignal.emit() + def addConstraintTab(self): """ Add a new C&S fitting tab @@ -326,7 +367,10 @@ def closeTabByIndex(self, index): try: ObjectLibrary.deleteObjectByRef(self.tabs[index]) self.removeTab(index) - del self.tabs[index] + # can't just delete the tab, since we still hold a reference to it + # del self.tabs[index] + # Instead, we just recreate self.tabs without the deleted tab + self.tabs = [tab for tab in self.tabs if tab is not self.tabs[index]] self.tabsModifiedSignal.emit() except IndexError: # The tab might have already been deleted previously @@ -349,8 +393,15 @@ def tabCloses(self, index): """ Update local bookkeeping on tab close """ + # update the last-tab closed information + # this should be done only for regular fitting + if not isinstance(self.tabs[index], ConstraintWidget) and \ + not self.tabs[index].is_batch_fitting: + self.lastTabClosed = self.tabs[index] + # don't remove the last tab if len(self.tabs) <= 1: + # remove the tab from the tabbed group self.resetTab(index) return self.closeTabByIndex(index) @@ -574,7 +625,7 @@ def getTabByName(self, name): """ assert isinstance(name, str) for tab in self.tabs: - if tab.modelName() == name: + if hasattr(tab, 'modelName') and tab.modelName() == name: return tab return None