Browse Source

Fix lint issues and tests.

startup
Ben Niemann 3 years ago
parent
commit
10c30878d6
  1. 42
      3rdparty/typeshed/PyQt5/QtCore.pyi
  2. 2
      3rdparty/typeshed/humanize.pyi
  3. 6
      noisicaa/builtin_nodes/score_track/track_ui.py
  4. 2
      noisicaa/core/process_manager.py
  5. 7
      noisicaa/ui/editor_app.py
  6. 16
      noisicaa/ui/editor_window.py
  7. 36
      noisicaa/ui/open_project_dialog.py
  8. 8
      noisicaa/ui/open_project_dialog_test.py
  9. 32
      noisicaa/ui/project_registry.py
  10. 2
      noisicaa/ui/project_view.py
  11. 16
      noisicaa/ui/ui_base.py

42
3rdparty/typeshed/PyQt5/QtCore.pyi vendored

@ -1852,6 +1852,20 @@ class QPersistentModelIndex(sip.simplewrapper):
class QAbstractItemModel(QObject):
dataChanged = ... # type: PYQT_SIGNAL
columnsMoved = ... # type: PYQT_SIGNAL
columnsAboutToBeMoved = ... # type: PYQT_SIGNAL
rowsMoved = ... # type: PYQT_SIGNAL
rowsAboutToBeMoved = ... # type: PYQT_SIGNAL
modelReset = ... # type: PYQT_SIGNAL
modelAboutToBeReset = ... # type: PYQT_SIGNAL
columnsRemoved = ... # type: PYQT_SIGNAL
columnsAboutToBeRemoved = ... # type: PYQT_SIGNAL
columnsInserted = ... # type: PYQT_SIGNAL
columnsAboutToBeInserted = ... # type: PYQT_SIGNAL
rowsRemoved = ... # type: PYQT_SIGNAL
rowsAboutToBeRemoved = ... # type: PYQT_SIGNAL
rowsInserted = ... # type: PYQT_SIGNAL
rowsAboutToBeInserted = ... # type: PYQT_SIGNAL
class LayoutChangeHint(int): ...
NoLayoutChangeHint = ... # type: 'QAbstractItemModel.LayoutChangeHint'
@ -1872,10 +1886,10 @@ class QAbstractItemModel(QObject):
def beginMoveColumns(self, sourceParent: QModelIndex, sourceFirst: int, sourceLast: int, destinationParent: QModelIndex, destinationColumn: int) -> bool: ...
def endMoveRows(self) -> None: ...
def beginMoveRows(self, sourceParent: QModelIndex, sourceFirst: int, sourceLast: int, destinationParent: QModelIndex, destinationRow: int) -> bool: ...
def columnsMoved(self, parent: QModelIndex, start: int, end: int, destination: QModelIndex, column: int) -> None: ...
def columnsAboutToBeMoved(self, sourceParent: QModelIndex, sourceStart: int, sourceEnd: int, destinationParent: QModelIndex, destinationColumn: int) -> None: ...
def rowsMoved(self, parent: QModelIndex, start: int, end: int, destination: QModelIndex, row: int) -> None: ...
def rowsAboutToBeMoved(self, sourceParent: QModelIndex, sourceStart: int, sourceEnd: int, destinationParent: QModelIndex, destinationRow: int) -> None: ...
#def columnsMoved(self, parent: QModelIndex, start: int, end: int, destination: QModelIndex, column: int) -> None: ...
#def columnsAboutToBeMoved(self, sourceParent: QModelIndex, sourceStart: int, sourceEnd: int, destinationParent: QModelIndex, destinationColumn: int) -> None: ...
#def rowsMoved(self, parent: QModelIndex, start: int, end: int, destination: QModelIndex, row: int) -> None: ...
#def rowsAboutToBeMoved(self, sourceParent: QModelIndex, sourceStart: int, sourceEnd: int, destinationParent: QModelIndex, destinationRow: int) -> None: ...
def createIndex(self, row: int, column: int, object: typing.Any = ...) -> QModelIndex: ...
def roleNames(self) -> typing.Any: ...
def supportedDragActions(self) -> Qt.DropActions: ...
@ -1898,16 +1912,16 @@ class QAbstractItemModel(QObject):
def encodeData(self, indexes: typing.Any, stream: 'QDataStream') -> None: ...
def revert(self) -> None: ...
def submit(self) -> bool: ...
def modelReset(self) -> None: ...
def modelAboutToBeReset(self) -> None: ...
def columnsRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
def columnsAboutToBeRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
def columnsInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
def columnsAboutToBeInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
def rowsRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
def rowsAboutToBeRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
def rowsInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
def rowsAboutToBeInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def modelReset(self) -> None: ...
#def modelAboutToBeReset(self) -> None: ...
#def columnsRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def columnsAboutToBeRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def columnsInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def columnsAboutToBeInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def rowsRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def rowsAboutToBeRemoved(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def rowsInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
#def rowsAboutToBeInserted(self, parent: QModelIndex, first: int, last: int) -> None: ...
def layoutChanged(self, parents: typing.Iterable[QPersistentModelIndex] = ..., hint: 'QAbstractItemModel.LayoutChangeHint' = ...) -> None: ...
def layoutAboutToBeChanged(self, parents: typing.Any = ..., hint: 'QAbstractItemModel.LayoutChangeHint' = ...) -> None: ...
def headerDataChanged(self, orientation: Qt.Orientation, first: int, last: int) -> None: ...

2
3rdparty/typeshed/humanize.pyi vendored

@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...

6
noisicaa/builtin_nodes/score_track/track_ui.py

@ -69,9 +69,9 @@ class ScoreToolBase(measured_track_editor.MeasuredToolBase):
self._updateGhost(target, evt.pos())
ymid = target.height() // 2
stave_line = (
int(ymid + 5 - evt.pos().y()) // 10 + target.measure.clef.center_pitch.stave_line)
# ymid = target.height() // 2
# stave_line = (
# int(ymid + 5 - evt.pos().y()) // 10 + target.measure.clef.center_pitch.stave_line)
# idx, _, _ = target.getEditArea(evt.pos().x())
# if idx < 0:

2
noisicaa/core/process_manager.py

@ -809,7 +809,7 @@ class SubprocessMixin(ProcessBase):
self.manager_address = manager_address
self.pid = os.getpid()
self.executor = None
self.executor = None # type: concurrent.futures.ThreadPoolExecutor
@staticmethod
def entry(argv: List[str]) -> None:

7
noisicaa/ui/editor_app.py

@ -505,7 +505,12 @@ class EditorApp(ui_base.AbstractEditorApp):
dialog.finished.connect(functools.partial(self.__newProjectDialogDone, dialog, win))
dialog.show()
def __newProjectDialogDone(self, dialog: open_project_dialog.NewProjectDialog, win: editor_window.EditorWindow, result: int) -> None:
def __newProjectDialogDone(
self,
dialog: open_project_dialog.NewProjectDialog,
win: editor_window.EditorWindow,
result: int
) -> None:
if result != QtWidgets.QDialog.Accepted:
return

16
noisicaa/ui/editor_window.py

@ -26,7 +26,7 @@ import logging
import time
import traceback
import typing
from typing import cast, Any, Optional, Callable
from typing import cast, Any, Optional, Callable, Generator
from PyQt5.QtCore import Qt
from PyQt5 import QtCore
@ -74,7 +74,7 @@ class SetupProgressWidget(QtWidgets.QWidget):
self.__bar.setRange(0, num_steps)
@contextlib.contextmanager
def step(self, message: str) -> None:
def step(self, message: str) -> Generator:
self.__step += 1
self.__bar.setValue(self.__step)
self.__message.setText("Initializing noisicaä: %s" % message)
@ -105,7 +105,12 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
def projectDebugger(self) -> Optional[project_debugger.ProjectDebugger]:
return self.__project_debugger
def __setPage(self, name: str, page: QtWidgets.QWidget, cleanup_func: Callable[[], None] = None) -> None:
def __setPage(
self,
name: str,
page: QtWidgets.QWidget,
cleanup_func: Callable[[], None] = None
) -> None:
if self.__page is not None:
self.__layout.removeWidget(self.__page)
self.__page.setParent(None)
@ -122,7 +127,6 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
def showOpenDialog(self) -> None:
dialog = open_project_dialog.OpenProjectDialog(
parent=self,
project_registry=self.app.project_registry,
context=self.context)
dialog.projectSelected.connect(
lambda project: self.call_async(self.openProject(project)))
@ -170,7 +174,7 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
await self.app.setup_complete.wait()
try:
await project.open()
except Exception as exc: # pylint: disable=bare-except
except Exception as exc: # pylint: disable=broad-except
self.__projectErrorDialog(
exc, "Failed to open project \"%s\"." % project.name)
@ -188,7 +192,7 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
try:
await project.create()
except: # pylint: disable=bare-except
except Exception as exc: # pylint: disable=broad-except
self.__projectErrorDialog(
exc, "Failed to create project \"%s\"." % project.name)

36
noisicaa/ui/open_project_dialog.py

@ -25,7 +25,6 @@ import functools
import logging
import os.path
import random
import time
from typing import Any, Dict, List
from PyQt5.QtCore import Qt
@ -95,20 +94,27 @@ class ItemDelegate(QtWidgets.QAbstractItemDelegate):
def __init__(self) -> None:
super().__init__()
self.__widgets = {} # type: Dict[QtCore.QModelIndex, QtWidgets.QWidget]
self.__widgets = {} # type: Dict[str, QtWidgets.QWidget]
def __getWidget(self, index: QtCore.QModelIndex) -> QtWidgets.QWidget:
item = index.model().item(index)
if item.path not in self.__widgets:
if item is None:
logger.error("Index without item: %d,%d", index.row(), index.column())
path = '<invalid>'
else:
path = item.path
if path not in self.__widgets:
widget = None # type: QtWidgets.QWidget
if isinstance(item, project_registry_lib.Project):
widget = ProjectItem(item)
elif isinstance(item, project_registry_lib.Root):
elif isinstance(item, project_registry_lib.Root) or item is None:
widget = QtWidgets.QWidget()
else:
raise TypeError("%s: %s" % (item.path, type(item)))
self.__widgets[item.path] = widget
raise TypeError("%s: %s" % (path, type(item)))
self.__widgets[path] = widget
return self.__widgets[item.path]
return self.__widgets[path]
def paint(
self,
@ -116,8 +122,6 @@ class ItemDelegate(QtWidgets.QAbstractItemDelegate):
option: QtWidgets.QStyleOptionViewItem,
index: QtCore.QModelIndex
) -> None:
item = index.model().item(index)
widget = self.__getWidget(index)
widget.resize(option.rect.size())
widget.updateContents()
@ -351,18 +355,11 @@ class OpenProjectDialog(ui_base.CommonMixin, QtWidgets.QWidget):
createProject = QtCore.pyqtSignal(str)
debugProject = QtCore.pyqtSignal(project_registry_lib.Project)
def __init__(
self, *,
project_registry: project_registry_lib.ProjectRegistry,
**kwargs: Any,
) -> None:
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.__project_registry = project_registry
self.__project_registry.contentsChanged.connect(self.__updateButtons)
self.__filter_model = FilterModel()
self.__filter_model.setSourceModel(FlatProjectListModel(self.__project_registry))
self.__filter_model.setSourceModel(FlatProjectListModel(self.app.project_registry))
self.__filter_model.setSortRole(project_registry_lib.Project.NameRole)
self.__filter_model.setSortCaseSensitivity(Qt.CaseInsensitive)
self.__filter_model.sort(0, Qt.AscendingOrder)
@ -435,6 +432,7 @@ class OpenProjectDialog(ui_base.CommonMixin, QtWidgets.QWidget):
self.__list.itemDoubleClicked.connect(self.__itemDoubleClicked)
self.__updateButtons()
self.app.project_registry.contentsChanged.connect(self.__updateButtons)
l4 = QtWidgets.QHBoxLayout()
l4.setContentsMargins(0, 0, 0, 0)
@ -543,7 +541,7 @@ class OpenProjectDialog(ui_base.CommonMixin, QtWidgets.QWidget):
self.setDisabled(True)
await project.delete()
await self.__project_registry.refresh()
await self.app.project_registry.refresh()
self.setDisabled(False)
def __debuggerClicked(self) -> None:

8
noisicaa/ui/open_project_dialog_test.py

@ -27,13 +27,13 @@ from . import project_registry
class OpenProjectDialogTest(uitest.UITestCase):
async def test_show(self):
registry = project_registry.ProjectRegistry(context=self.context)
await registry.setup()
self.app.project_registry = project_registry.ProjectRegistry(context=self.context)
await self.app.project_registry.setup()
try:
dialog = open_project_dialog.OpenProjectDialog(
project_registry=registry,
context=self.context)
dialog.show()
dialog.hide()
finally:
await registry.cleanup()
await self.app.project_registry.cleanup()

32
noisicaa/ui/project_registry.py

@ -30,7 +30,6 @@ from typing import cast, Any, List, Iterable, Iterator
from PyQt5.QtCore import Qt
from PyQt5 import QtCore
from PyQt5 import QtGui
from noisicaa.core.typing_extra import down_cast
from noisicaa import music
@ -48,15 +47,14 @@ class Item(QtCore.QObject):
super().__init__()
self.path = path
self.parent = None # type: Item
self.index = 0
self.children = [] # type: List[Item]
self.childItems = [] # type: List[Item]
def isOpened(self) -> bool:
return False
def projects(self) -> Iterator['Project']:
for child in self.children:
for child in self.childItems:
yield from child.projects()
def data(self, role: int) -> Any:
@ -201,7 +199,7 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
directory = os.path.expanduser(directory)
directory = os.path.abspath(directory)
logger.info("Scanning project directory %s...", directory)
for dirpath, dirnames, filenames in os.walk(directory):
for dirpath, dirnames, _ in os.walk(directory):
for dirname in list(dirnames):
if os.path.isfile(os.path.join(dirpath, dirname, 'project.noise')):
dirnames.remove(dirname)
@ -224,12 +222,12 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
for path in old_paths - new_paths:
logger.info("Removing project at %s...", path)
for idx, project in enumerate(self.__root.children):
for idx, project in enumerate(self.__root.childItems):
if project.path == path:
self.beginRemoveRows(QtCore.QModelIndex(), idx, idx)
del self.__root.children[idx]
for idx, item in enumerate(self.__root.children[idx:], idx):
item.index = idx
del self.__root.childItems[idx]
for i, item in enumerate(self.__root.childItems[idx:], idx):
item.index = i
self.endRemoveRows()
await project.close()
self.contentsChanged.emit()
@ -250,14 +248,14 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
def addProject(self, project: Project) -> None:
idx = 0
while idx < len(self.__root.children) and project.path > self.__root.children[idx].path:
while idx < len(self.__root.childItems) and project.path > self.__root.childItems[idx].path:
idx += 1
project.parent = self.__root
project.setParent(self.__root)
self.beginInsertRows(QtCore.QModelIndex(), idx, idx)
self.__root.children.insert(idx, project)
for idx, item in enumerate(self.__root.children[idx:], idx):
self.__root.childItems.insert(idx, project)
for idx, item in enumerate(self.__root.childItems[idx:], idx):
item.index = idx
self.endInsertRows()
@ -273,7 +271,7 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
logger.info("Currently opened projects:\n%s", '\n'.join(opened_project_paths))
self.app.settings.setValue('opened_projects', opened_project_paths)
def __projectChanged(self, project: Project):
def __projectChanged(self, project: Project) -> None:
index = self.index(project.index)
self.dataChanged.emit(index, index)
@ -290,7 +288,7 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
return QtCore.QModelIndex()
parent_item = self.item(parent)
return self.createIndex(row, column, parent_item.children[row])
return self.createIndex(row, column, parent_item.childItems[row])
def parent(self, index: QtCore.QModelIndex) -> QtCore.QModelIndex: # type: ignore
if not index.isValid():
@ -300,7 +298,7 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
if item is self.__root:
return QtCore.QModelIndex()
return self.createIndex(item.parent.index, 0, item.parent)
return self.createIndex(item.parent().index, 0, item.parent())
def columnCount(self, parent: QtCore.QModelIndex = QtCore.QModelIndex()) -> int:
return 1
@ -309,7 +307,7 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
parent_item = self.item(parent)
if parent_item is None:
return 0
return len(parent_item.children)
return len(parent_item.childItems)
def flags(self, index: QtCore.QModelIndex) -> Qt.ItemFlags:
return self.item(index).flags()

2
noisicaa/ui/project_view.py

@ -45,7 +45,7 @@ from .track_list import measured_track_editor
logger = logging.getLogger(__name__)
class ProjectView(ui_base.AbstractProjectView, QtWidgets.QWidget):
class ProjectView(ui_base.AbstractProjectView):
playingChanged = QtCore.pyqtSignal(bool)
loopEnabledChanged = QtCore.pyqtSignal(bool)

16
noisicaa/ui/ui_base.py

@ -42,7 +42,8 @@ if typing.TYPE_CHECKING:
from noisicaa import runtime_settings as runtime_settings_lib
from noisicaa import lv2
from . import instrument_list as instrument_list_lib
from . import project_registry
from . import project_registry as project_registry_lib
from . import editor_window
class CommonContext(object):
@ -124,7 +125,7 @@ class CommonMixin(object):
class ProjectContext(CommonContext):
def __init__(
self, *,
project_connection: 'project_registry.Project',
project_connection: 'project_registry_lib.Project',
selection_set: selection_set_lib.SelectionSet,
project_view: 'AbstractProjectView',
**kwargs: Any) -> None:
@ -142,7 +143,7 @@ class ProjectContext(CommonContext):
return self.__project_view
@property
def project_connection(self) -> 'project_registry.Project':
def project_connection(self) -> 'project_registry_lib.Project':
return self.__project_connection
@property
@ -174,7 +175,7 @@ class ProjectMixin(CommonMixin):
return self._context.selection_set
@property
def project_connection(self) -> 'project_registry.Project':
def project_connection(self) -> 'project_registry_lib.Project':
return self._context.project_connection
@property
@ -206,7 +207,7 @@ class ProjectMixin(CommonMixin):
return self._context.add_session_listener(key, listener)
class AbstractProjectView(ProjectMixin):
class AbstractProjectView(ProjectMixin, QtWidgets.QWidget):
async def createPluginUI(self, node_id: str) -> Tuple[int, Tuple[int, int]]:
raise NotImplementedError
@ -252,6 +253,8 @@ class AbstractEditorApp(object):
qt_app = None # type: QtWidgets.QApplication
devices = None # type: device_list.DeviceList
instrument_list = None # type: instrument_list_lib.InstrumentList
project_registry = None # type: project_registry_lib.ProjectRegistry
setup_complete = None # type: asyncio.Event
def quit(self, exit_code: int = 0) -> None:
raise NotImplementedError
@ -264,3 +267,6 @@ class AbstractEditorApp(object):
def clipboardContent(self) -> Any:
raise NotImplementedError
async def deleteWindow(self, win: 'editor_window.EditorWindow') -> None:
raise NotImplementedError

Loading…
Cancel
Save