2022-09-16 06:38:43 +12:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import gi
|
|
|
|
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
|
|
from gi.repository import GObject, Gtk, Handy
|
|
|
|
|
2023-03-22 10:36:36 +13:00
|
|
|
from manuskript.data import Project, Template, TemplateKind
|
2023-03-22 08:51:05 +13:00
|
|
|
from manuskript.util import validInt, validString, parseFilenameFromURL
|
2022-09-16 08:15:33 +12:00
|
|
|
|
2022-09-16 06:38:43 +12:00
|
|
|
from manuskript.ui.abstractDialog import AbstractDialog
|
2023-03-22 10:36:36 +13:00
|
|
|
from manuskript.ui.chooser import openFileDialog, saveFileDialog, FileFilter
|
2022-09-16 09:35:45 +12:00
|
|
|
from manuskript.ui.startup import TemplateEntry
|
2022-09-16 08:15:33 +12:00
|
|
|
from manuskript.ui.util import bindMenuItem
|
2022-09-16 06:38:43 +12:00
|
|
|
|
|
|
|
|
|
|
|
class StartupWindow(AbstractDialog):
|
|
|
|
|
|
|
|
def __init__(self, mainWindow):
|
|
|
|
AbstractDialog.__init__(self, mainWindow, "ui/startup.glade", "startup_window")
|
|
|
|
|
2022-09-16 08:15:33 +12:00
|
|
|
self.templates = Template.getDefaultTemplates()
|
2022-09-16 09:35:45 +12:00
|
|
|
self.template = None
|
2022-09-16 08:15:33 +12:00
|
|
|
|
2022-09-16 06:38:43 +12:00
|
|
|
self.headerBar = None
|
2022-09-16 08:15:33 +12:00
|
|
|
self.templatesLeaflet = None
|
|
|
|
|
2023-03-22 08:51:05 +13:00
|
|
|
self.recentChooserMenu = None
|
2023-03-22 09:52:07 +13:00
|
|
|
self.recentChooserMenuBtn = None
|
2023-03-22 08:51:05 +13:00
|
|
|
|
2022-09-16 08:15:33 +12:00
|
|
|
self.templatesStore = None
|
|
|
|
self.fictionTemplatesStore = None
|
|
|
|
self.nonfictionTemplatesStore = None
|
|
|
|
self.demoTemplatesStore = None
|
|
|
|
|
|
|
|
self.templateSelections = list()
|
2022-09-16 09:35:45 +12:00
|
|
|
self.templateLevelsListbox = None
|
|
|
|
|
2022-09-16 09:53:15 +12:00
|
|
|
self.goalLabel = None
|
2022-09-16 09:35:45 +12:00
|
|
|
self.addLevelButton = None
|
|
|
|
self.addGoalButton = None
|
2022-09-16 06:38:43 +12:00
|
|
|
|
2023-03-22 09:52:07 +13:00
|
|
|
self.openButton = None
|
|
|
|
self.recentButton = None
|
|
|
|
self.createButton = None
|
|
|
|
|
2022-09-16 06:38:43 +12:00
|
|
|
def initWindow(self, builder, window):
|
|
|
|
self.headerBar = builder.get_object("header_bar")
|
2022-09-16 08:15:33 +12:00
|
|
|
self.templatesLeaflet = builder.get_object("templates_leaflet")
|
|
|
|
|
|
|
|
self.templatesLeaflet.bind_property("folded", self.headerBar, "show-close-button",
|
|
|
|
GObject.BindingFlags.SYNC_CREATE |
|
|
|
|
GObject.BindingFlags.INVERT_BOOLEAN)
|
|
|
|
|
2023-03-22 08:51:05 +13:00
|
|
|
self.recentChooserMenu = builder.get_object("recent_chooser_menu")
|
2023-03-22 09:52:07 +13:00
|
|
|
self.recentChooserMenuBtn = builder.get_object("recent_chooser_menu_btn")
|
|
|
|
|
2023-03-22 08:51:05 +13:00
|
|
|
self.recentChooserMenu.connect("item-activated", self._recentAction)
|
2023-03-22 09:52:07 +13:00
|
|
|
self.recentChooserMenuBtn.connect("item-activated", self._recentAction)
|
2023-03-22 08:51:05 +13:00
|
|
|
|
2023-03-02 11:32:03 +13:00
|
|
|
bindMenuItem(builder, "open_menu_item", self._openAction)
|
|
|
|
bindMenuItem(builder, "quit_menu_item", self._quitAction)
|
2022-09-16 08:15:33 +12:00
|
|
|
|
2023-03-02 11:32:03 +13:00
|
|
|
bindMenuItem(builder, "about_menu_item", self._aboutAction)
|
2022-09-16 09:35:45 +12:00
|
|
|
|
2022-09-16 08:15:33 +12:00
|
|
|
self.templatesStore = builder.get_object("templates_store")
|
|
|
|
|
|
|
|
for index in range(len(self.templates)):
|
|
|
|
tree_iter = self.templatesStore.append()
|
|
|
|
|
|
|
|
if tree_iter is None:
|
|
|
|
continue
|
|
|
|
|
|
|
|
template = self.templates[index]
|
|
|
|
|
|
|
|
self.templatesStore.set_value(tree_iter, 0, validInt(index))
|
|
|
|
self.templatesStore.set_value(tree_iter, 1, validString(template.name))
|
|
|
|
self.templatesStore.set_value(tree_iter, 2, TemplateKind.asValue(template.kind))
|
|
|
|
|
|
|
|
self.fictionTemplatesStore = builder.get_object("fiction_templates_store")
|
|
|
|
self.nonfictionTemplatesStore = builder.get_object("nonfiction_templates_store")
|
|
|
|
self.demoTemplatesStore = builder.get_object("demo_templates_store")
|
|
|
|
|
|
|
|
self.fictionTemplatesStore.set_visible_func(
|
2023-02-03 14:00:18 +13:00
|
|
|
lambda model, iterator, userdata: model[iterator][2] == TemplateKind.FICTION.value)
|
2022-09-16 08:15:33 +12:00
|
|
|
self.nonfictionTemplatesStore.set_visible_func(
|
2023-02-03 14:00:18 +13:00
|
|
|
lambda model, iterator, userdata: model[iterator][2] == TemplateKind.NONFICTION.value)
|
2022-09-16 08:15:33 +12:00
|
|
|
self.demoTemplatesStore.set_visible_func(
|
2023-02-03 14:00:18 +13:00
|
|
|
lambda model, iterator, userdata: model[iterator][2] == TemplateKind.DEMO.value)
|
2022-09-16 08:15:33 +12:00
|
|
|
|
|
|
|
self.fictionTemplatesStore.refilter()
|
|
|
|
self.nonfictionTemplatesStore.refilter()
|
|
|
|
self.demoTemplatesStore.refilter()
|
|
|
|
|
|
|
|
self.templateSelections = [
|
|
|
|
builder.get_object("fiction_template_selection"),
|
|
|
|
builder.get_object("nonfiction_template_selection"),
|
|
|
|
builder.get_object("demo_template_selection")
|
|
|
|
]
|
|
|
|
|
|
|
|
for selection in self.templateSelections:
|
2023-02-03 14:00:18 +13:00
|
|
|
selection.connect("changed", self._templateSelectionChanged)
|
2022-09-16 08:15:33 +12:00
|
|
|
|
2022-09-16 09:35:45 +12:00
|
|
|
self.templateLevelsListbox = builder.get_object("template_levels_listbox")
|
|
|
|
|
2022-09-16 09:53:15 +12:00
|
|
|
self.goalLabel = builder.get_object("goal_label")
|
2022-09-16 09:35:45 +12:00
|
|
|
self.addLevelButton = builder.get_object("add_level_button")
|
|
|
|
self.addGoalButton = builder.get_object("add_goal_button")
|
|
|
|
|
2023-02-03 14:00:18 +13:00
|
|
|
self.addLevelButton.connect("clicked", self._addLevelClicked)
|
|
|
|
self.addGoalButton.connect("clicked", self._addGoalClicked)
|
2022-09-16 09:35:45 +12:00
|
|
|
|
2023-03-22 09:52:07 +13:00
|
|
|
self.openButton = builder.get_object("open_button")
|
|
|
|
self.recentButton = builder.get_object("recent_button")
|
|
|
|
self.createButton = builder.get_object("create_button")
|
|
|
|
|
|
|
|
self.openButton.connect("clicked", self._openClicked)
|
2023-03-22 10:36:36 +13:00
|
|
|
self.createButton.connect("clicked", self._createClicked)
|
2023-03-22 09:52:07 +13:00
|
|
|
|
2022-09-16 09:35:45 +12:00
|
|
|
def loadTemplate(self, template: Template):
|
|
|
|
self.template = template
|
|
|
|
self.templateLevelsListbox.foreach(lambda child: self.templateLevelsListbox.remove(child))
|
|
|
|
|
|
|
|
self.addLevelButton.set_sensitive(self.template is not None)
|
|
|
|
self.addGoalButton.set_sensitive((self.template is not None) and (self.template.goal is None))
|
|
|
|
|
|
|
|
if self.template is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
for level in self.template.levels:
|
|
|
|
entry = TemplateEntry(self)
|
2022-09-16 09:53:15 +12:00
|
|
|
entry.bindTemplate(self.template, level)
|
2022-09-16 09:35:45 +12:00
|
|
|
|
|
|
|
self.templateLevelsListbox.add(entry.widget)
|
|
|
|
entry.show()
|
|
|
|
|
2022-09-16 09:53:15 +12:00
|
|
|
if self.template.goal is not None:
|
2022-09-16 09:35:45 +12:00
|
|
|
entry = TemplateEntry(self)
|
2022-09-16 09:53:15 +12:00
|
|
|
entry.bindTemplate(self.template)
|
2022-09-16 09:35:45 +12:00
|
|
|
|
|
|
|
self.templateLevelsListbox.add(entry.widget)
|
|
|
|
entry.show()
|
|
|
|
|
2022-09-16 09:53:15 +12:00
|
|
|
self.goalLabel.set_text(self.template.getGoalString())
|
|
|
|
|
2023-02-03 14:00:18 +13:00
|
|
|
def _templateSelectionChanged(self, selection: Gtk.TreeSelection):
|
2022-09-16 08:15:33 +12:00
|
|
|
model, tree_iter = selection.get_selected()
|
|
|
|
|
|
|
|
if tree_iter is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
for other in self.templateSelections:
|
|
|
|
if other != selection:
|
|
|
|
other.unselect_all()
|
|
|
|
|
|
|
|
index = model[tree_iter][0]
|
2022-09-16 06:38:43 +12:00
|
|
|
|
2022-09-16 09:35:45 +12:00
|
|
|
self.loadTemplate(self.templates[index] if (index >= 0) and (index < len(self.templates)) else None)
|
|
|
|
|
2023-02-03 14:00:18 +13:00
|
|
|
def _addLevelClicked(self, button: Gtk.Button):
|
2022-09-16 09:35:45 +12:00
|
|
|
if self.template is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.template.addLevel()
|
|
|
|
self.loadTemplate(self.template)
|
|
|
|
|
2023-02-03 14:00:18 +13:00
|
|
|
def _addGoalClicked(self, button: Gtk.Button):
|
2022-09-16 09:35:45 +12:00
|
|
|
if self.template is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.template.addGoal()
|
|
|
|
self.loadTemplate(self.template)
|
2023-03-02 11:32:03 +13:00
|
|
|
|
2023-03-22 09:52:07 +13:00
|
|
|
def openProject(self):
|
2023-03-22 10:36:36 +13:00
|
|
|
path = openFileDialog(self.window, FileFilter("Manuskript project", "msk"))
|
2023-03-22 09:52:07 +13:00
|
|
|
if path is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.mainWindow.openProject(path)
|
|
|
|
|
|
|
|
def _openClicked(self, button: Gtk.Button):
|
|
|
|
self.openProject()
|
|
|
|
|
2023-03-22 10:36:36 +13:00
|
|
|
def _createClicked(self, button: Gtk.Button):
|
|
|
|
path = saveFileDialog(self.window, FileFilter("Manuskript project", "msk"), appendAllFilter=False)
|
|
|
|
if path is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
project = Project(path)
|
2023-03-22 10:40:01 +13:00
|
|
|
# TODO: apply project template!
|
2023-03-22 10:36:36 +13:00
|
|
|
project.save()
|
|
|
|
|
|
|
|
self.mainWindow.openProject(path)
|
|
|
|
|
2023-03-02 11:32:03 +13:00
|
|
|
def _openAction(self, menuItem: Gtk.MenuItem):
|
2023-03-22 09:52:07 +13:00
|
|
|
self.openProject()
|
2023-03-02 11:32:03 +13:00
|
|
|
|
2023-03-22 08:51:05 +13:00
|
|
|
def _recentAction(self, recentChooser: Gtk.RecentChooser):
|
|
|
|
uri = recentChooser.get_current_uri()
|
|
|
|
if uri is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
path = parseFilenameFromURL(uri)
|
|
|
|
if path is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.mainWindow.openProject(path)
|
|
|
|
|
2023-03-02 11:32:03 +13:00
|
|
|
def _quitAction(self, menuItem: Gtk.MenuItem):
|
|
|
|
self.mainWindow.exit(True)
|
|
|
|
|
|
|
|
def _aboutAction(self, menuItem: Gtk.MenuItem):
|
|
|
|
self.mainWindow.aboutDialog.show()
|