mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-05-15 10:22:26 +12:00
Implement recent projects menu
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
This commit is contained in:
parent
988fa62d61
commit
9287e85b7e
|
@ -14,5 +14,6 @@ from manuskript.ui import MainWindow
|
|||
|
||||
path = os.path.join(os.getcwd(), "sample-projects/book-of-acts")
|
||||
|
||||
window = MainWindow(path + ".msk")
|
||||
window = MainWindow()
|
||||
window.openProject(path + ".msk")
|
||||
window.run()
|
||||
|
|
|
@ -17,36 +17,14 @@ from manuskript.ui.tools import *
|
|||
from manuskript.ui.aboutDialog import AboutDialog
|
||||
from manuskript.ui.settingsWindow import SettingsWindow
|
||||
from manuskript.ui.startupWindow import StartupWindow
|
||||
from manuskript.ui.util import bindMenuItem
|
||||
from manuskript.util import profileTime
|
||||
from manuskript.ui.util import bindMenuItem, packViewIntoSlot, unpackFromSlot
|
||||
from manuskript.util import parseFilenameFromURL
|
||||
|
||||
|
||||
class MainWindow:
|
||||
|
||||
@classmethod
|
||||
def packViewIntoSlot(cls, builder, id, view_cls, data=None):
|
||||
slot = builder.get_object(id)
|
||||
|
||||
if slot is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
if data is None:
|
||||
view = profileTime(view_cls)
|
||||
else:
|
||||
view = profileTime(view_cls, data)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
if view.widget is None:
|
||||
return None
|
||||
|
||||
slot.pack_start(view.widget, True, True, 0)
|
||||
return view
|
||||
|
||||
def __init__(self, path):
|
||||
self.project = Project(path)
|
||||
self.project.load()
|
||||
def __init__(self):
|
||||
self.project = None
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("ui/main.glade")
|
||||
|
@ -58,20 +36,25 @@ class MainWindow:
|
|||
self.leaflet = builder.get_object("leaflet")
|
||||
self.viewSwitcherBar = builder.get_object("view_switcher_bar")
|
||||
|
||||
self.headerBar.set_subtitle(self.project.info.title)
|
||||
|
||||
self.leaflet.bind_property("folded", self.viewSwitcherBar, "reveal", GObject.BindingFlags.SYNC_CREATE)
|
||||
self.leaflet.bind_property("folded", self.headerBar, "show-close-button", GObject.BindingFlags.SYNC_CREATE |
|
||||
GObject.BindingFlags.INVERT_BOOLEAN)
|
||||
|
||||
self.generalView = MainWindow.packViewIntoSlot(builder, "general_slot", GeneralView, self.project.info)
|
||||
self.summaryView = MainWindow.packViewIntoSlot(builder, "summary_slot", SummaryView, self.project.summary)
|
||||
self.charactersView = MainWindow.packViewIntoSlot(builder, "characters_slot", CharactersView,
|
||||
self.project.characters)
|
||||
self.plotView = MainWindow.packViewIntoSlot(builder, "plot_slot", PlotView, self.project.plots)
|
||||
self.worldView = MainWindow.packViewIntoSlot(builder, "world_slot", WorldView, self.project.world)
|
||||
self.outlineView = MainWindow.packViewIntoSlot(builder, "outline_slot", OutlineView, self.project.outline)
|
||||
self.editorView = MainWindow.packViewIntoSlot(builder, "editor_slot", EditorView, self.project)
|
||||
self.generalSlot = builder.get_object("general_slot")
|
||||
self.summarySlot = builder.get_object("summary_slot")
|
||||
self.charactersSlot = builder.get_object("characters_slot")
|
||||
self.plotSlot = builder.get_object("plot_slot")
|
||||
self.worldSlot = builder.get_object("world_slot")
|
||||
self.outlineSlot = builder.get_object("outline_slot")
|
||||
self.editorSlot = builder.get_object("editor_slot")
|
||||
|
||||
self.generalView = None
|
||||
self.summaryView = None
|
||||
self.charactersView = None
|
||||
self.plotView = None
|
||||
self.worldView = None
|
||||
self.outlineView = None
|
||||
self.editorView = None
|
||||
|
||||
self.startupWindow = StartupWindow(self)
|
||||
self.aboutDialog = AboutDialog(self)
|
||||
|
@ -85,6 +68,9 @@ class MainWindow:
|
|||
self.settingsWindow
|
||||
]
|
||||
|
||||
self.recentChooserMenu = builder.get_object("recent_chooser_menu")
|
||||
self.recentChooserMenu.connect("item-activated", self._recentAction)
|
||||
|
||||
bindMenuItem(builder, "open_menu_item", self._openAction)
|
||||
bindMenuItem(builder, "save_menu_item", self._saveAction)
|
||||
bindMenuItem(builder, "close_menu_item", self._closeAction)
|
||||
|
@ -94,18 +80,66 @@ class MainWindow:
|
|||
bindMenuItem(builder, "frequency_menu_item", self._frequencyAction)
|
||||
bindMenuItem(builder, "about_menu_item", self._aboutAction)
|
||||
|
||||
self.hide()
|
||||
|
||||
def getProject(self):
|
||||
return self.project
|
||||
|
||||
def openProject(self):
|
||||
pass
|
||||
def openProject(self, path=None, dialog=False):
|
||||
if self.project is not None:
|
||||
self.closeProject()
|
||||
|
||||
if dialog:
|
||||
return
|
||||
|
||||
if path is None:
|
||||
return
|
||||
|
||||
self.project = Project(path)
|
||||
self.project.load()
|
||||
|
||||
self.headerBar.set_subtitle(self.project.info.title)
|
||||
|
||||
self.generalView = packViewIntoSlot(self.generalSlot, GeneralView, self.project.info)
|
||||
self.summaryView = packViewIntoSlot(self.summarySlot, SummaryView, self.project.summary)
|
||||
self.charactersView = packViewIntoSlot(self.charactersSlot, CharactersView, self.project.characters)
|
||||
self.plotView = packViewIntoSlot(self.plotSlot, PlotView, self.project.plots)
|
||||
self.worldView = packViewIntoSlot(self.worldSlot, WorldView, self.project.world)
|
||||
self.outlineView = packViewIntoSlot(self.outlineSlot, OutlineView, self.project.outline)
|
||||
self.editorView = packViewIntoSlot(self.editorSlot, EditorView, self.project)
|
||||
|
||||
self.startupWindow.hide()
|
||||
self.show()
|
||||
|
||||
def closeProject(self):
|
||||
if self.project is not None:
|
||||
self.generalView = unpackFromSlot(self.generalSlot, self.generalView)
|
||||
self.summaryView = unpackFromSlot(self.summarySlot, self.summaryView)
|
||||
self.charactersView = unpackFromSlot(self.charactersSlot, self.charactersView)
|
||||
self.plotView = unpackFromSlot(self.plotSlot, self.plotView)
|
||||
self.worldView = unpackFromSlot(self.worldSlot, self.worldView)
|
||||
self.outlineView = unpackFromSlot(self.outlineSlot, self.outlineView)
|
||||
self.editorView = unpackFromSlot(self.editorSlot, self.editorView)
|
||||
|
||||
del self.project
|
||||
self.project = None
|
||||
|
||||
self.hide()
|
||||
self.startupWindow.show()
|
||||
|
||||
def _openAction(self, menuItem: Gtk.MenuItem):
|
||||
self.openProject()
|
||||
self.openProject(dialog=True)
|
||||
|
||||
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.openProject(path)
|
||||
|
||||
def _saveAction(self, menuItem: Gtk.MenuItem):
|
||||
self.getProject().save()
|
||||
|
|
|
@ -6,8 +6,8 @@ import gi
|
|||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import GObject, Gtk, Handy
|
||||
|
||||
from manuskript.data import Template, TemplateLevel, TemplateKind
|
||||
from manuskript.util import validInt, validString
|
||||
from manuskript.data import Template, TemplateKind
|
||||
from manuskript.util import validInt, validString, parseFilenameFromURL
|
||||
|
||||
from manuskript.ui.abstractDialog import AbstractDialog
|
||||
from manuskript.ui.startup import TemplateEntry
|
||||
|
@ -25,6 +25,8 @@ class StartupWindow(AbstractDialog):
|
|||
self.headerBar = None
|
||||
self.templatesLeaflet = None
|
||||
|
||||
self.recentChooserMenu = None
|
||||
|
||||
self.templatesStore = None
|
||||
self.fictionTemplatesStore = None
|
||||
self.nonfictionTemplatesStore = None
|
||||
|
@ -45,6 +47,9 @@ class StartupWindow(AbstractDialog):
|
|||
GObject.BindingFlags.SYNC_CREATE |
|
||||
GObject.BindingFlags.INVERT_BOOLEAN)
|
||||
|
||||
self.recentChooserMenu = builder.get_object("recent_chooser_menu")
|
||||
self.recentChooserMenu.connect("item-activated", self._recentAction)
|
||||
|
||||
bindMenuItem(builder, "open_menu_item", self._openAction)
|
||||
bindMenuItem(builder, "quit_menu_item", self._quitAction)
|
||||
|
||||
|
@ -154,6 +159,17 @@ class StartupWindow(AbstractDialog):
|
|||
def _openAction(self, menuItem: Gtk.MenuItem):
|
||||
self.mainWindow.openProject()
|
||||
|
||||
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)
|
||||
|
||||
def _quitAction(self, menuItem: Gtk.MenuItem):
|
||||
self.mainWindow.exit(True)
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ gi.require_version('GdkPixbuf', '2.0')
|
|||
from gi.repository import GdkPixbuf, Gdk
|
||||
|
||||
from manuskript.data import Color, OutlineItem, OutlineText, OutlineFolder
|
||||
from manuskript.util import profileTime
|
||||
|
||||
|
||||
def rgbaFromColor(color: Color) -> Gdk.RGBA:
|
||||
|
@ -34,6 +35,36 @@ def bindMenuItem(builder, id, action):
|
|||
menuItem.connect("activate", action)
|
||||
|
||||
|
||||
def packViewIntoSlot(slot, view_cls, data=None):
|
||||
if slot is None:
|
||||
return None
|
||||
|
||||
for child in slot.get_children():
|
||||
slot.remove(child)
|
||||
|
||||
try:
|
||||
if data is None:
|
||||
view = profileTime(view_cls)
|
||||
else:
|
||||
view = profileTime(view_cls, data)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
if view.widget is None:
|
||||
return None
|
||||
|
||||
slot.pack_start(view.widget, True, True, 0)
|
||||
return view
|
||||
|
||||
|
||||
def unpackFromSlot(slot, view):
|
||||
if (slot is not None) and (view.widget is not None):
|
||||
slot.remove(view.widget)
|
||||
|
||||
del view
|
||||
return None
|
||||
|
||||
|
||||
def iconByOutlineItemType(outlineItem: OutlineItem) -> str:
|
||||
if type(outlineItem) is OutlineFolder:
|
||||
return "folder-symbolic"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import re
|
||||
import time
|
||||
import traceback
|
||||
import urllib.parse
|
||||
|
||||
from manuskript.util.counter import CounterKind, CharCounter, WordCounter, PageCounter
|
||||
|
||||
|
@ -51,6 +52,18 @@ def safeFilename(filename: str, extension: str = None) -> str:
|
|||
return re.sub(r"[^a-zA-Z0-9._\-+()]", "_", name)
|
||||
|
||||
|
||||
def parseFilenameFromURL(url: str) -> str | None:
|
||||
result = urllib.parse.urlparse(url)
|
||||
|
||||
if result is None:
|
||||
return None
|
||||
|
||||
if result.scheme != "file":
|
||||
return None
|
||||
|
||||
return result.path
|
||||
|
||||
|
||||
def countText(text: str, kind: CounterKind = CounterKind.WORDS):
|
||||
if text is None:
|
||||
return 0
|
||||
|
|
|
@ -923,20 +923,6 @@ summary</property>
|
|||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Next</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
Loading…
Reference in a new issue