Remember currently opened projects and restore them on startup.

startup
Ben Niemann 2019-06-10 15:55:28 +02:00
parent 8d0ef9c2f0
commit 0a4d1994aa
3 changed files with 82 additions and 55 deletions

View File

@ -253,7 +253,43 @@ class EditorApp(ui_base.AbstractEditorApp):
with progress.step("Scanning projects..."):
self.project_registry = project_registry.ProjectRegistry(context=self.context)
await self.project_registry.setup()
tab_page.showOpenDialog()
initial_projects = []
if self.paths:
for path in self.paths:
if path.startswith('+'):
initial_projects.append((True, path[1:]))
else:
initial_projects.append((False, path))
else:
for path in self.settings.value('opened_projects', []) or []:
initial_projects.append((False, path))
logger.info(
"Starting with projects:\n%s",
'\n'.join('%s%s' % ('+' if create else '', path)
for create, path in initial_projects))
idx = 0
for create, path in initial_projects:
if idx == 0:
tab = tab_page
else:
tab = win.addProjectTab(path)
if create:
self.process.event_loop.create_task(tab.createProject(path))
idx += 1
else:
try:
project = self.project_registry.getProject(path)
except KeyError:
logging.error("There is no known project at %s", path)
else:
self.process.event_loop.create_task(tab.openProject(project))
idx += 1
if idx == 0:
tab_page.showOpenDialog()
with progress.step("Scanning nodes and plugins..."):
await self.createNodeDB()
@ -311,18 +347,6 @@ class EditorApp(ui_base.AbstractEditorApp):
self.show_stat_monitor_action.setEnabled(True)
self.setup_complete.set()
# if self.paths:
# logger.info("Starting with projects from cmdline.")
# for path in self.paths:
# if path.startswith('+'):
# await self.createProject(path[1:])
# else:
# await self.openProject(path)
# else:
# reopen_projects = self.settings.value('opened_projects', [])
# for path in reopen_projects or []:
# await self.openProject(path)
async def cleanup(self) -> None:
logger.info("Cleanup app...")
@ -551,33 +575,6 @@ class EditorApp(ui_base.AbstractEditorApp):
def clipboardContent(self) -> Any:
return self.__clipboard
# async def createProject(self, path: str) -> None:
# project_connection = self.project_registry.add_project(path)
# idx = self.win.addProjectSetupView(project_connection)
# await project_connection.create()
# await self.win.activateProjectView(idx, project_connection)
# self._updateOpenedProjects()
# async def openProject(self, path: str) -> None:
# project_connection = self.project_registry.add_project(path)
# idx = self.win.addProjectSetupView(project_connection)
# await project_connection.open()
# await self.win.activateProjectView(idx, project_connection)
# self._updateOpenedProjects()
# def _updateOpenedProjects(self) -> None:
# self.settings.setValue(
# 'opened_projects',
# sorted(
# project.path
# for project in self.project_registry.projects.values()
# if project.path))
# async def removeProject(self, project_connection: project_registry.Project) -> None:
# await self.win.removeProjectView(project_connection)
# await self.project_registry.close_project(project_connection)
# self._updateOpenedProjects()
def crashWithMessage(self, title: str, msg: str) -> None:
logger.error('%s: %s', title, msg)

View File

@ -122,9 +122,9 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
project_registry=self.app.project_registry,
context=self.context)
dialog.projectSelected.connect(
lambda project: self.call_async(self.__projectSelected(project)))
lambda project: self.call_async(self.openProject(project)))
dialog.createProject.connect(
lambda path: self.call_async(self.__createProject(path)))
lambda path: self.call_async(self.createProject(path)))
dialog.debugProject.connect(
lambda path: self.call_async(self.__debugProject(path)))
@ -162,7 +162,7 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
dialog.finished.connect(lambda result: self.showOpenDialog())
dialog.show()
async def __projectSelected(self, project: project_registry_lib.Project) -> None:
async def openProject(self, project: project_registry_lib.Project) -> None:
self.showLoadSpinner("Loading project \"%s\"..." % project.name)
await self.app.setup_complete.wait()
try:
@ -177,7 +177,7 @@ class ProjectTabPage(ui_base.CommonMixin, QtWidgets.QWidget):
self.__project_view = view
self.__setPage(view)
async def __createProject(self, path: str) -> None:
async def createProject(self, path: str) -> None:
project = project_registry_lib.Project(
path=path, context=self.context)
self.showLoadSpinner("Creating project \"%s\"..." % project.name)

View File

@ -95,6 +95,9 @@ class Project(ui_base.CommonMixin, Item):
return super().data(role)
def isOpened(self) -> bool:
return self.client is not None
@property
def name(self) -> str:
return urllib.parse.unquote(os.path.splitext(os.path.basename(self.path))[0])
@ -116,6 +119,7 @@ class Project(ui_base.CommonMixin, Item):
return client
async def open(self) -> None:
assert not self.isOpened()
client = await self.__create_process()
try:
await client.open(self.path)
@ -123,8 +127,10 @@ class Project(ui_base.CommonMixin, Item):
await client.cleanup()
raise
self.client = client
self.app.project_registry.updateOpenedProjects()
async def create(self) -> None:
assert not self.isOpened()
client = await self.__create_process()
try:
await client.create(self.path)
@ -132,14 +138,18 @@ class Project(ui_base.CommonMixin, Item):
await client.cleanup()
raise
self.client = client
self.app.project_registry.addProject(self)
self.app.project_registry.updateOpenedProjects()
async def close(self) -> None:
if self.client is not None:
await self.client.close()
await self.client.cleanup()
self.client = None
self.app.project_registry.updateOpenedProjects()
async def delete(self) -> None:
assert not self.isOpened()
shutil.rmtree(self.path)
@ -148,11 +158,13 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
super().__init__(**kwargs)
self.__root = Root()
self.__in_cleanup = False
async def setup(self) -> None:
await self.refresh()
async def cleanup(self) -> None:
self.__in_cleanup = True
for project in self.__root.projects():
await project.close()
self.__root = None
@ -198,19 +210,37 @@ class ProjectRegistry(ui_base.CommonMixin, QtCore.QAbstractItemModel):
for path in new_paths - old_paths:
logger.info("Adding project at %s...", path)
idx = 0
while idx < len(self.__root.children) and path > self.__root.children[idx].path:
idx += 1
project = Project(path=path, context=self.context)
project.parent = self.__root
self.addProject(project)
self.beginInsertRows(QtCore.QModelIndex(), idx, idx)
self.__root.children.insert(idx, project)
for idx, item in enumerate(self.__root.children[idx:], idx):
item.index = idx
self.endInsertRows()
def getProject(self, path: str) -> Project:
path = os.path.expanduser(path)
path = os.path.abspath(path)
for project in self.projects():
if project.path == path:
return project
raise KeyError("No known project at '%s'" % path)
def addProject(self, project: Project) -> None:
idx = 0
while idx < len(self.__root.children) and project.path > self.__root.children[idx].path:
idx += 1
project.parent = self.__root
self.beginInsertRows(QtCore.QModelIndex(), idx, idx)
self.__root.children.insert(idx, project)
for idx, item in enumerate(self.__root.children[idx:], idx):
item.index = idx
self.endInsertRows()
def updateOpenedProjects(self) -> None:
if self.__in_cleanup:
return
opened_project_paths = sorted(
project.path for project in self.projects() if project.isOpened())
logger.info("Currently opened projects:\n%s", '\n'.join(opened_project_paths))
self.app.settings.setValue('opened_projects', opened_project_paths)
def item(self, index: QtCore.QModelIndex = QtCore.QModelIndex()) -> Item:
if not index.isValid():