Skip to content

Commit

Permalink
Merge pull request #2387 from Carifio24/move-viewer
Browse files Browse the repository at this point in the history
Add functionality for moving viewers between tabs
  • Loading branch information
astrofrog authored May 15, 2023
2 parents a170e3e + fde4e3b commit c0eb36c
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 2 deletions.
29 changes: 29 additions & 0 deletions glue/app/qt/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,35 @@ def screenshot(self, filename):
image.save(filename)
painter.end()

def move_viewer_to_tab(self, viewer, tab):
"""
Move the given viewer to the given tab.
If the given tab is the same as the current tab,
do nothing.
"""
current_window = viewer.parent()
current_tab = current_window.mdiArea()
new_tab = self.tab(tab)
if new_tab is None:
raise ValueError(f"Invalid tab index: {tab}")
if current_tab is not new_tab:

# We do this rather than just use setParent on current_window
# so that the moved window is put in a reasonable place
# in the new tab (i.e. not on top of another viewer),
# because there may be another viewer in the new tab
# with the same position.
# Also, if we don't resize, moved windows will get progressively
# smaller. This is because the new MDI window will be sized
# according to the size of the old viewer, which is slightly
# smaller than the parent window.
current_tab.removeSubWindow(current_window)
viewer.resize(current_window.size())
current_window.setWidget(None)
current_window.close()

self.add_widget(viewer, tab=tab)

def add_datasets(self, *args, **kwargs):
result = super(GlueApplication, self).add_datasets(*args, **kwargs)
run_autolinker(self.data_collection)
Expand Down
27 changes: 27 additions & 0 deletions glue/app/qt/tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,33 @@ def test_subset_facet(self):
with patch('glue.dialogs.subset_facet.qt.SubsetFacetDialog.exec_'):
act._do_action()

def test_move_viewer_to_tab(self):

# Create a viewer in the first tab
viewer = self.app.new_data_viewer(ScatterViewer)
assert viewer.parent().mdiArea() is self.app.tab(0)

# Move it to a new tab
self.app.new_tab()
self.app.move_viewer_to_tab(viewer, 1)
assert viewer.parent().mdiArea() is self.app.tab(1)
assert set(self.app.tab(0).subWindowList()) == {self.app._terminal}
assert set(self.app.tab(1).subWindowList()) == {viewer.parent()}

# Move it back to the first tab
self.app.move_viewer_to_tab(viewer, 0)
assert viewer.parent().mdiArea() is self.app.tab(0)
assert set(self.app.tab(0).subWindowList()) == {self.app._terminal, viewer.parent()}
assert len(self.app.tab(1).subWindowList()) == 0

# Check that we do nothing if the given tab is the same as the
# viewer's current tab
parent = viewer.parent()
viewer_state = viewer.state
self.app.move_viewer_to_tab(viewer, 0)
assert parent is viewer.parent()
assert viewer_state is viewer.state

# FIXME: The following test fails and causes subsequent issues if run with
#
# pytest -s -v -x glue
Expand Down
Binary file added glue/icons/windows.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions glue/viewers/common/qt/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import tools # noqa
7 changes: 5 additions & 2 deletions glue/viewers/common/qt/data_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@ class DataViewer(Viewer, BaseQtViewerWidget,
_default_mouse_mode_cls = None

inherit_tools = True
tools = ['save']
subtools = {'save': []}
tools = ['save', 'window']
subtools = {
'save': [],
'window': ['window:movetab']
}

_close_on_last_layer_removed = True

Expand Down
33 changes: 33 additions & 0 deletions glue/viewers/common/qt/tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from glue.config import viewer_tool
from glue.utils.qt import pick_item
from glue.viewers.common.tool import Tool, SimpleToolMenu

__all__ = ['MoveTabTool', 'WindowTool']


@viewer_tool
class WindowTool(SimpleToolMenu):
"""
A generic "window operations" tool that the Qt app and plugins
can register tools for windowing operations with.
"""

tool_id = 'window'
icon = 'windows'
tool_tip = 'Modify the viewer window'


@viewer_tool
class MoveTabTool(Tool):

icon = 'windows'
tool_id = 'window:movetab'
action_text = 'Move to another tab'
tool_tip = 'Move viewer to another tab'

def activate(self):
app = self.viewer.session.application
default = 1 if (app.tab_count > 1 and app.current_tab == app.tab(0)) else 0
tab = pick_item(range(app.tab_count), app.tab_names, title="Move Viewer", label="Select a tab", default=default)
if tab is not None:
app.move_viewer_to_tab(self.viewer, tab)

0 comments on commit c0eb36c

Please sign in to comment.