Skip to content

Commit

Permalink
Fix tab indices not aligned with stackwidget's
Browse files Browse the repository at this point in the history
* The custom QStackWidget+QTabBar class did not manage the tabs properly because the indices in the stackwidget were not aligned with the ones in the tab bar.
* Properly disable exclude list action when it is the currently displayed widget.
* Merge action callbacks for triggering ignore list or exclude list to avoid repeating code and remove unused checks for tab visibility.
* Remove unused SetTabVisible() function.
  • Loading branch information
glubsy committed Aug 23, 2020
1 parent 3382bd5 commit 26d1894
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 56 deletions.
39 changes: 14 additions & 25 deletions qt/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,35 +279,24 @@ def clearPictureCacheTriggered(self):

def ignoreListTriggered(self):
if self.use_tabs:
# Fetch the index in the TabWidget or the StackWidget (depends on class):
index = self.main_window.indexOfWidget(self.ignoreListDialog)
if index < 0:
# we have not instantiated and populated it in their internal list yet
index = self.main_window.addTab(
self.ignoreListDialog, "Ignore List", switch=True)
elif not self.ignoreListDialog.isVisible() and not self.main_window.isTabVisible(index):
index = self.main_window.addTab(
self.ignoreListDialog, "Ignore List", switch=True)
# self.main_window.showTab(self.ignoreListDialog)
self.main_window.setTabVisible(index, True)
self.main_window.setCurrentIndex(index)
else:
self.showTriggeredTabbedDialog(self.ignoreListDialog, "Ignore List")
else: # floating windows
self.model.ignore_list_dialog.show()

def excludeListTriggered(self):
if self.use_tabs:
index = self.main_window.indexOfWidget(self.excludeListDialog)
if index < 0:
index = self.main_window.addTab(
self.excludeListDialog, "Exclude List", switch=True)
elif not self.excludeListDialog.isVisible() and not self.main_window.isTabVisible(index):
index = self.main_window.addTab(
self.excludeListDialog, "Exclude List", switch=True)
# self.main_window.showTab(self.excludeListDialog)
self.main_window.setTabVisible(index, True)
self.main_window.setCurrentIndex(index)
else:
self.excludeListDialog.show()
self.showTriggeredTabbedDialog(self.excludeListDialog, "Exclude List")
else: # floating windows
self.model.exclude_list_dialog.show()

def showTriggeredTabbedDialog(self, dialog, desc_string):
"""Add tab for dialog, name the tab with desc_string, then show it."""
index = self.main_window.indexOfWidget(dialog)
# Create the tab if it doesn't exist already
if index < 0: # or (not dialog.isVisible() and not self.main_window.isTabVisible(index)):
index = self.main_window.addTab(dialog, desc_string, switch=True)
# Show the tab for that widget
self.main_window.setCurrentIndex(index)

def openDebugLogTriggered(self):
debugLogPath = op.join(self.model.appdata, "debug.log")
Expand Down
62 changes: 31 additions & 31 deletions qt/tabbed_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def _setupMenu(self):
self.menuList.add(self.menuHelp)

@pyqtSlot(int)
def updateMenuBar(self, page_index=None):
def updateMenuBar(self, page_index=-1):
if page_index < 0:
return
current_index = self.getCurrentIndex()
Expand Down Expand Up @@ -142,7 +142,9 @@ def updateMenuBar(self, page_index=None):
and not page_type == "IgnoreListDialog" else False)
self.app.actionDirectoriesWindow.setEnabled(
False if page_type == "DirectoriesDialog" else True)
# FIXME add ExcludeListDialog here too
self.app.actionExcludeList.setEnabled(
True if self.app.excludeListDialog is not None
and not page_type == "ExcludeListDialog" else False)

self.previous_widget_actions = active_widget.specific_actions
self.last_index = current_index
Expand Down Expand Up @@ -182,7 +184,6 @@ def addTab(self, page, title, switch=False):

def showTab(self, page):
index = self.indexOfWidget(page)
self.setTabVisible(index, True)
self.setCurrentIndex(index)

def indexOfWidget(self, widget):
Expand All @@ -191,9 +192,6 @@ def indexOfWidget(self, widget):
def setCurrentIndex(self, index):
return self.tabWidget.setCurrentIndex(index)

def setTabVisible(self, index, value):
return self.tabWidget.setTabVisible(index, value)

def removeTab(self, index):
return self.tabWidget.removeTab(index)

Expand Down Expand Up @@ -232,14 +230,13 @@ def onTabCloseRequested(self, index):
# menu or shortcut. But this is useless if we don't have a button
# set up to make a close request anyway. This check could be removed.
return
current_widget.close()
self.setTabVisible(index, False)
# current_widget.close() # seems unnecessary
# self.tabWidget.widget(index).hide()
self.removeTab(index)

@pyqtSlot()
def onDialogAccepted(self):
"""Remove tabbed dialog when Accepted/Done."""
"""Remove tabbed dialog when Accepted/Done (close button clicked)."""
widget = self.sender()
index = self.indexOfWidget(widget)
if index > -1:
Expand Down Expand Up @@ -277,7 +274,7 @@ def _setupUi(self):
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalLayout.addWidget(self.stackedWidget)

self.tabBar.currentChanged.connect(self.showWidget)
self.tabBar.currentChanged.connect(self.showTabIndex)
self.tabBar.tabCloseRequested.connect(self.onTabCloseRequested)

self.stackedWidget.currentChanged.connect(self.updateMenuBar)
Expand All @@ -287,50 +284,48 @@ def _setupUi(self):
self.restoreGeometry()

def addTab(self, page, title, switch=True):
stack_index = self.stackedWidget.insertWidget(-1, page)
tab_index = self.tabBar.addTab(title)
stack_index = self.stackedWidget.addWidget(page)
self.tabBar.insertTab(stack_index, title)

if isinstance(page, DirectoriesDialog):
self.tabBar.setTabButton(
tab_index, QTabBar.RightSide, None)
stack_index, QTabBar.RightSide, None)
if switch: # switch to the added tab immediately upon creation
self.setTabIndex(tab_index)
self.stackedWidget.setCurrentWidget(page)
self.setTabIndex(stack_index)
return stack_index

@pyqtSlot(int)
def showWidget(self, index):
if index >= 0 and index <= self.stackedWidget.count() - 1:
def showTabIndex(self, index):
# The tab bar's indices should be aligned with the stackwidget's
if index >= 0 and index <= self.stackedWidget.count():
self.stackedWidget.setCurrentIndex(index)
# if not self.tabBar.isTabVisible(index):
self.setTabVisible(index, True)

def indexOfWidget(self, widget):
# Warning: this may return -1 if widget is not a child of stackedwidget
return self.stackedWidget.indexOf(widget)

def setCurrentIndex(self, tab_index):
# The signal will handle switching the stackwidget's widget
self.setTabIndex(tab_index)
# The signal will handle switching the stackwidget's widget
# self.stackedWidget.setCurrentWidget(self.stackedWidget.widget(tab_index))

def setCurrentWidget(self, widget):
"""Sets the current Tab on TabBar for this widget."""
self.tabBar.setCurrentIndex(self.indexOfWidget(widget))

@pyqtSlot(int)
def setTabIndex(self, index):
if index is None:
return
self.tabBar.setCurrentIndex(index)

def setTabVisible(self, index, value):
return self.tabBar.setTabVisible(index, value)

@pyqtSlot(int)
def onRemovedWidget(self, index):
self.removeTab(index)

@pyqtSlot(int)
def removeTab(self, index):
# No need to remove the widget here:
# self.stackedWidget.removeWidget(self.stackedWidget.widget(index))
"""Remove the tab, but not the widget (it should already be removed)"""
return self.tabBar.removeTab(index)

@pyqtSlot(int)
Expand All @@ -357,13 +352,18 @@ def toggleTabBar(self):

@pyqtSlot(int)
def onTabCloseRequested(self, index):
current_widget = self.getWidgetAtIndex(index)
if isinstance(current_widget, DirectoriesDialog):
target_widget = self.getWidgetAtIndex(index)
if isinstance(target_widget, DirectoriesDialog):
# On MacOS, the tab has a close button even though we explicitely
# set it to None in order to hide it. This should prevent
# the "Directories" tab from closing by mistake.
return
current_widget.close()
self.stackedWidget.removeWidget(current_widget)
# In this case the signal will take care of the tab itself after removing the widget
# self.removeTab(index)
# target_widget.close() # seems unnecessary
# Removing the widget should trigger tab removal via the signal
self.removeWidget(self.getWidgetAtIndex(index))

@pyqtSlot()
def onDialogAccepted(self):
"""Remove tabbed dialog when Accepted/Done (close button clicked)."""
widget = self.sender()
self.removeWidget(widget)

0 comments on commit 26d1894

Please sign in to comment.