Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Workbench from Pyface to Apptools #331

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/actions/install-qt-support/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Install Qt dependencies

This action calls `apt-get` to install packages required for running Qt on Ubuntu.

## Inputs

There are no inputs.

## Outputs

There are no outputs.

## Example usage

```yml

jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Install Qt dependencies
uses: ./.github/actions/install-qt-support
```
30 changes: 30 additions & 0 deletions .github/actions/install-qt-support/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: install-qt-support
description: 'Install supporting OS packages for Qt-using code'
runs:
using: composite
steps:
- name: Install Linux packages for Qt
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install qtbase5-dev
sudo apt-get install qtchooser
sudo apt-get install qt5-qmake
sudo apt-get install qtbase5-dev-tools
sudo apt-get install libegl1
sudo apt-get install libxkbcommon-x11-0
sudo apt-get install libxcb-icccm4
sudo apt-get install libxcb-image0
sudo apt-get install libxcb-keysyms1
sudo apt-get install libxcb-randr0
sudo apt-get install libxcb-render-util0
sudo apt-get install libxcb-xinerama0
sudo apt-get install libxcb-shape0
sudo apt-get install libxcb-cursor0
sudo apt-get install pulseaudio
sudo apt-get install libpulse-mainloop-glib0
# Needed to work around https://bugreports.qt.io/browse/PYSIDE-1547
sudo apt-get install libopengl0
# Needed for Qt6 video playback
sudo apt-get install libgstreamer-gl1.0-0
shell: bash
67 changes: 65 additions & 2 deletions .github/workflows/test-with-pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,72 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies and local packages
run: |
python -m pip install .[h5,preferences]
python -m pip install .[test,h5,preferences]
mkdir testdir
- name: Run tests
run: |
python -m unittest discover -v apptools
working-directory: testdir

tests-qt:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.8', '3.11']
qt-api: ['pyside6']
env:
ETS_TOOLKIT: qt
runs-on: ${{ matrix.os }}
timeout-minutes: 20 # should be plenty, it's usually < 5

steps:
- name: Check out the target commit
uses: actions/checkout@v3
- name: Install Qt dependencies
uses: ./.github/actions/install-qt-support
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies and local packages
run: |
python -m pip install "traitsui[${{ matrix.qt-api }}]"
python -m pip install ".[test,h5,preferences]"
mkdir testdir
cd testdir
- name: Run tests (Linux)
run: |
xvfb-run -a python -m unittest discover -v apptools
if: matrix.os == 'ubuntu-latest'
working-directory: testdir
- name: Run tests (Windows and MacOS)
run: |
python -m unittest discover -v apptools
if: matrix.os != 'ubuntu-latest'
working-directory: testdir

tests-wx:
strategy:
matrix:
os: [windows-latest]
python-version: ['3.8', '3.10']
env:
ETS_TOOLKIT: wx
runs-on: ${{ matrix.os }}
timeout-minutes: 20 # should be plenty, it's usually < 5

steps:
- name: Check out the target commit
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies and local packages
run: |
python -m pip install "traitsui[wx]"
python -m pip install ".[test,h5,preferences]"
mkdir testdir
- name: Run tests
run: |
python -m unittest discover -v apptools
working-directory: testdir
2 changes: 1 addition & 1 deletion apptools/logger/plugin/logger_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import zipfile

# Enthought library imports
from pyface.workbench.api import View as WorkbenchView
from apptools.workbench.api import View as WorkbenchView
from traits.api import (
Any,
Callable,
Expand Down
2 changes: 1 addition & 1 deletion apptools/logger/plugin/view/logger_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# Enthought library imports.
from pyface.api import ImageResource, clipboard
from pyface.workbench.api import TraitsUIView
from apptools.workbench.api import TraitsUIView
from traits.api import (
Button,
Instance,
Expand Down
9 changes: 9 additions & 0 deletions apptools/workbench/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
Empty file.
44 changes: 44 additions & 0 deletions apptools/workbench/action/action_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" The action controller for workbench menu and tool bars. """


from pyface.action.api import ActionController
from traits.api import Instance

from apptools.workbench.workbench_window import WorkbenchWindow


class ActionController(ActionController):
"""The action controller for workbench menu and tool bars.

The controller is used to 'hook' the invocation of every action on the menu
and tool bars. This is done so that additional (and workbench specific)
information can be added to action events. Currently, we attach a reference
to the workbench window.

"""

# 'ActionController' interface -----------------------------------------

# The workbench window that this is the controller for.
window = Instance(WorkbenchWindow)

# ------------------------------------------------------------------------
# 'ActionController' interface.
# ------------------------------------------------------------------------

def perform(self, action, event):
"""Control an action invocation."""

# Add a reference to the window and the application to the event.
event.window = self.window

return action.perform(event)
14 changes: 14 additions & 0 deletions apptools/workbench/action/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!


from .menu_bar_manager import MenuBarManager
from .tool_bar_manager import ToolBarManager
from .view_menu_manager import ViewMenuManager
78 changes: 78 additions & 0 deletions apptools/workbench/action/delete_user_perspective_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" An action that deletes a user perspective. """


from pyface.api import YES

from .user_perspective_action import UserPerspectiveAction


class DeleteUserPerspectiveAction(UserPerspectiveAction):
"""An action that deletes a user perspective."""

# 'Action' interface ---------------------------------------------------

# The action's unique identifier (may be None).
id = "apptools.workbench.action.delete_user_perspective_action"

# The action's name (displayed on menus/tool bar tools etc).
name = "Delete Perspective"

# ------------------------------------------------------------------------
# 'Action' interface.
# ------------------------------------------------------------------------

def perform(self, event):
"""Perform the action."""

window = event.window
manager = window.workbench.user_perspective_manager

# The perspective to delete.
perspective = window.active_perspective

# Make sure that the user isn't having second thoughts!
message = (
'Are you sure you want to delete the "%s" perspective?'
% perspective.name
)

answer = window.confirm(message, title="Confirm Delete")
if answer == YES:
# Set the active perspective to be the first remaining perspective.
#
# There is always a default NON-user perspective (even if no
# perspectives are explicitly defined) so we should never(!) not
# be able to find one!
window.active_perspective = self._get_next_perspective(window)

# Remove the perspective from the window.
window.perspectives.remove(perspective)

# Remove it from the user perspective manager.
manager.remove(perspective.id)

return

# ------------------------------------------------------------------------
# Private interface.
# ------------------------------------------------------------------------

def _get_next_perspective(self, window):
"""Return the first perspective that is not the active one!"""

if window.active_perspective is window.perspectives[0]:
index = 1

else:
index = 0

return window.perspectives[index]
39 changes: 39 additions & 0 deletions apptools/workbench/action/menu_bar_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" The menu bar manager for Envisage workbench windows. """


from pyface.action.api import MenuBarManager as BaseMenuBarManager
from traits.api import Instance

from .action_controller import ActionController


class MenuBarManager(BaseMenuBarManager):
"""The menu bar manager for Envisage workbench windows."""

# 'MenuBarManager' interface -------------------------------------------

# The workbench window that we are the menu bar manager for.
window = Instance("apptools.workbench.workbench_window.WorkbenchWindow")

# ------------------------------------------------------------------------
# 'MenuBarManager' interface.
# ------------------------------------------------------------------------

def create_menu_bar(self, parent):
"""Creates a menu bar representation of the manager."""

# The controller handles the invocation of every action.
controller = ActionController(window=self.window)

menu_bar = super().create_menu_bar(parent, controller=controller)

return menu_bar
52 changes: 52 additions & 0 deletions apptools/workbench/action/new_user_perspective_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" An action that creates a new (and empty) user perspective. """


from .user_perspective_name import UserPerspectiveName
from .workbench_action import WorkbenchAction


class NewUserPerspectiveAction(WorkbenchAction):
"""An action that creates a new (and empty) user perspective."""

# 'Action' interface ---------------------------------------------------

# The action's unique identifier.
id = "apptools.workbench.action.new_user_perspective_action"

# The action's name.
name = "New Perspective..."

# ------------------------------------------------------------------------
# 'Action' interface.
# ------------------------------------------------------------------------

def perform(self, event):
"""Peform the action."""

window = event.window
manager = window.workbench.user_perspective_manager

# Get the details of the new perspective.
upn = UserPerspectiveName(name="User Perspective %d" % manager.next_id)
if upn.edit_traits(view="new_view").result:
# Create a new (and empty) user perspective.
perspective = manager.create_perspective(
upn.name.strip(), upn.show_editor_area
)

# Add it to the window...
window.perspectives.append(perspective)

# ... and make it the active perspective.
window.active_perspective = perspective

return
Loading