From c6f3a904d5ce508997b36c140f1676ff8995e5a7 Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Tue, 10 Jan 2023 07:39:27 -0500
Subject: [PATCH 01/21] Added all the files
deleted extra saved things
Deleted backups
Delete character_details_template_editor.glade~
---
test_io.py | 24 +++
ui/about.glade | 8 +-
ui/character_details_template_editor.glade | 202 +++++++++++++++++++++
ui/characters.glade | 15 +-
ui/general.glade | 17 +-
ui/main.glade | 8 +
ui/quote_of_the_day.glade | 71 ++++++++
7 files changed, 340 insertions(+), 5 deletions(-)
create mode 100644 test_io.py
create mode 100644 ui/character_details_template_editor.glade
create mode 100644 ui/quote_of_the_day.glade
diff --git a/test_io.py b/test_io.py
new file mode 100644
index 00000000..a4971543
--- /dev/null
+++ b/test_io.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# I put this here because otherwise I couldn't run it.
+# I also added some tests and had to modify this to get it to run -- ShadowOfHassen
+import os
+import sys
+
+# gi
+import gi
+gi.require_version('GdkPixbuf', '2.0')
+from gi.repository import GdkPixbuf
+
+realpath = os.path.realpath(__file__)
+LOGO_FILE = 'icons/Manuskript/manuskript.svg'
+#sys.path.insert(1, os.path.join(os.path.dirname(realpath), '..'))
+
+from manuskript.ui import MainWindow
+
+
+window = MainWindow("sample-projects/book-of-acts" + ".msk")
+# Let's make this a bit fancier
+window.window.set_icon(GdkPixbuf.Pixbuf.new_from_file(LOGO_FILE))
+
+window.run()
diff --git a/ui/about.glade b/ui/about.glade
index b96638e1..b29464fd 100644
--- a/ui/about.glade
+++ b/ui/about.glade
@@ -1,5 +1,5 @@
-
+
+
+
+
+
+
diff --git a/ui/characters.glade b/ui/characters.glade
index e17aae5b..a1559d09 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -933,10 +933,23 @@ summary
False
True
- end
3
+
+
+ Append Detail Template
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 4
+
+
False
diff --git a/ui/general.glade b/ui/general.glade
index 7f894133..44c04442 100644
--- a/ui/general.glade
+++ b/ui/general.glade
@@ -1,5 +1,5 @@
-
+
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+ -1
+
+
+
+
+
+ True
+ False
+ True
+ 20
+ True
+
+
+ True
+ False
+ label
+
+
+ 2
+ 1
+
+
+
+
+ True
+ False
+ label
+
+
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 8f899b1accb9de1246df5201aac6f6015e8c2cfb Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Tue, 10 Jan 2023 07:39:27 -0500
Subject: [PATCH 02/21] Added all the files
deleted extra saved things
Deleted backups
Delete character_details_template_editor.glade~
Fixed Some things that should have been there.
---
manuskript/data/characters_template.py | 30 +++
manuskript/data/project.py | 7 +
manuskript/ui/mainWindow.py | 8 +-
.../ui/tools/Character_Template_Editor.py | 150 +++++++++++++
manuskript/ui/tools/__init__.py | 1 +
manuskript/ui/views/charactersView.py | 35 ++-
manuskript/util/unique_name_checker.py | 16 ++
test_io.py | 24 +++
ui/about.glade | 8 +-
ui/character_details_template_editor.glade | 202 ++++++++++++++++++
ui/characters.glade | 15 +-
ui/general.glade | 17 +-
ui/main.glade | 8 +
ui/quote_of_the_day.glade | 71 ++++++
14 files changed, 579 insertions(+), 13 deletions(-)
create mode 100644 manuskript/data/characters_template.py
create mode 100644 manuskript/ui/tools/Character_Template_Editor.py
create mode 100644 manuskript/util/unique_name_checker.py
create mode 100644 test_io.py
create mode 100644 ui/character_details_template_editor.glade
create mode 100644 ui/quote_of_the_day.glade
diff --git a/manuskript/data/characters_template.py b/manuskript/data/characters_template.py
new file mode 100644
index 00000000..b613892c
--- /dev/null
+++ b/manuskript/data/characters_template.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# --!-- coding: utf8 --!--
+
+import os
+
+#from io.jsonFile import* # I need to figure out how to import this. io is also a package in python
+from collections import OrderedDict
+
+
+# So this is a template for charecter details
+# It is edited by the Charecter Template Editor
+# Most of the code is taken from charecters.py
+# I think this should have a custom save that's like a .json file in the main part of the manuskript save
+
+#Main Class
+class CharacterDetailTemplate:
+
+ details = {'Age':'','Birthdate':'',
+ 'Eye Color':'','Hair Color':'',
+ 'Handed':''} # We'll make a default template
+
+
+
+ # TODO saving
+ def save(self):
+ pass
+
+ def load(self):
+ pass
+
diff --git a/manuskript/data/project.py b/manuskript/data/project.py
index ebce4e42..488e7d9d 100644
--- a/manuskript/data/project.py
+++ b/manuskript/data/project.py
@@ -1,9 +1,12 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
+# Imports
+# Python bundled modules
import os
from zipfile import BadZipFile
+# Manuskript modules
from manuskript.data.version import Version, CURRENT_MSK_VERSION
from manuskript.data.info import Info
from manuskript.data.summary import Summary
@@ -15,6 +18,9 @@ from manuskript.data.plots import Plots
from manuskript.data.world import World
from manuskript.data.outline import Outline
from manuskript.data.revisions import Revisions
+# This is for the charecter template
+from manuskript.data.characters_template import CharacterDetailTemplate
+
from manuskript.io.mskFile import MskFile
@@ -34,6 +40,7 @@ class Project:
self.world = World(self.file.dir_path)
self.outline = Outline(self.file.dir_path, self.plots, self.labels, self.statuses)
self.revisions = Revisions(self.file.dir_path)
+ self.character_template = CharacterDetailTemplate()
def __del__(self):
del self.file
diff --git a/manuskript/ui/mainWindow.py b/manuskript/ui/mainWindow.py
index 87756323..d92ad3b3 100644
--- a/manuskript/ui/mainWindow.py
+++ b/manuskript/ui/mainWindow.py
@@ -65,7 +65,7 @@ class MainWindow:
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.charactersView = MainWindow.packViewIntoSlot(builder, "characters_slot", CharactersView, self.project) # Just project because we need it for characters and the template
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)
@@ -74,12 +74,14 @@ class MainWindow:
self.startupWindow = StartupWindow(self)
self.aboutDialog = AboutDialog(self)
self.frequencyWindow = FrequencyWindow(self)
+ self.character_template_window = CharacterTemplateEditorWindow(self)
self.settingsWindow = SettingsWindow(self)
self.windows = [
self.startupWindow,
self.aboutDialog,
self.frequencyWindow,
+ self.character_template_window,
self.settingsWindow
]
@@ -90,6 +92,7 @@ class MainWindow:
bindMenuItem(builder, "settings_menu_item", self.settingsAction)
bindMenuItem(builder, "frequency_menu_item", self.frequencyAction)
+ bindMenuItem(builder, "character_details_template_editor", self.character_details_template_editor_action)
bindMenuItem(builder, "about_menu_item", self.aboutAction)
def getProject(self):
@@ -119,6 +122,9 @@ class MainWindow:
def frequencyAction(self, menuItem: Gtk.MenuItem):
self.frequencyWindow.show()
+
+ def character_details_template_editor_action(self, menuItem: Gtk.MenuItem):
+ self.character_template_window.show()
def aboutAction(self, menuItem: Gtk.MenuItem):
self.aboutDialog.show()
diff --git a/manuskript/ui/tools/Character_Template_Editor.py b/manuskript/ui/tools/Character_Template_Editor.py
new file mode 100644
index 00000000..ecbf7dd5
--- /dev/null
+++ b/manuskript/ui/tools/Character_Template_Editor.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+
+# Imports
+# Gi
+import gi
+
+gi.require_version("Gtk", "3.0")
+from gi.repository import GObject, Gtk, Handy
+
+# Manuskript
+from manuskript.ui.abstractDialog import AbstractDialog
+from manuskript.util import unique_name_checker
+
+# I lifted a lot of this code from frequencyWindow
+# With a bit more stuff from charactersView
+
+class CharacterTemplateEditorWindow(AbstractDialog):
+
+ def __init__(self, mainWindow):
+ AbstractDialog.__init__(self, mainWindow, "ui/character_details_template_editor.glade", "character_details_template_editor")
+
+ self.headerBar = None
+ self.back = None
+ self.wordLeaflet = None
+ self.analyzeWords = None
+ self.analyzePhrases = None
+
+ def initWindow(self, builder, window):
+ self.headerBar = builder.get_object("header_bar")
+ self.back = builder.get_object("back")
+
+ self.character_leaflet = builder.get_object("character_details_leaflet")
+
+ self.character_leaflet.bind_property("folded", self.back, "visible", GObject.BindingFlags.SYNC_CREATE)
+ self.character_leaflet.bind_property("folded", self.headerBar, "show-close-button", GObject.BindingFlags.SYNC_CREATE |
+ GObject.BindingFlags.INVERT_BOOLEAN)
+
+
+ self.back.connect("clicked", self._backClicked)
+
+ #Liking Stuff stole from charactersView
+ self.detailsStore = builder.get_object("details_store")
+ self.detailsSelection = builder.get_object("details_selection")
+ self.addDetailsButton = builder.get_object("add_details")
+ self.removeDetailsButton = builder.get_object("remove_details")
+ self.append_details_template_button = builder.get_object("appened_details_template")
+ self.detailsNameRenderer = builder.get_object("details_name")
+ self.detailsValueRenderer = builder.get_object("details_value")
+
+ self.addDetailsButton.connect("clicked", self.addDetailsClicked)
+ self.removeDetailsButton.connect("clicked", self.removeDetailsClicked)
+
+ self.detailsNameRenderer.connect("edited", self.detailsNameEdited)
+ self.detailsValueRenderer.connect("edited", self.detailsValueEdited)
+
+ self.populate_tree()
+
+
+
+ def _backClicked(self, button: Gtk.Button):
+ if self.wordLeaflet.get_visible_child_name() == "wordlist_view":
+ self.wordLeaflet.set_visible_child_name("wordfilter_view")
+ else:
+ self.hide()
+
+ # So this adds any previously added parts to the template
+ def populate_tree(self):
+ for name, value in self.mainWindow.project.character_template.details.items():
+ tree_iter = self.detailsStore.append()
+
+ if tree_iter is None:
+ return
+
+
+ self.detailsStore.set_value(tree_iter, 0, name)
+ self.detailsStore.set_value(tree_iter, 1, value)
+
+# Functions stole From charactersView
+ def addDetailsClicked(self, button: Gtk.Button):
+
+ tree_iter = self.detailsStore.append()
+
+ if tree_iter is None:
+ return
+
+ name = unique_name_checker.get_unique_name_for_dictionary(self.mainWindow.project.character_template.details, "Description")
+ value = "Value"
+
+ self.detailsStore.set_value(tree_iter, 0, name)
+ self.detailsStore.set_value(tree_iter, 1, value)
+
+ self.mainWindow.project.character_template.details[name] = value
+
+ def removeDetailsClicked(self, button: Gtk.Button):
+
+ model, tree_iter = self.detailsSelection.get_selected()
+
+ if (model is None) or (tree_iter is None):
+ return
+
+ name = model.get_value(tree_iter, 0)
+ model.remove(tree_iter)
+
+ self.mainWindow.project.character_template.details.pop(name)
+
+ def detailsNameEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
+
+ model, tree_iter = self.detailsSelection.get_selected()
+
+ if (model is None) or (tree_iter is None):
+ return
+ text_to_set = unique_name_checker.get_unique_name_for_dictionary(self.mainWindow.project.character_template.details, text)
+ name = model.get_value(tree_iter, 0)
+ model.set_value(tree_iter, 0, text_to_set)
+ # There was an error with this line but it didn't seem to do anything bad.
+ self.mainWindow.project.character_template.details[text_to_set] = self.mainWindow.project.character_template.details.pop(name)
+
+ def detailsValueEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
+
+ model, tree_iter = self.detailsSelection.get_selected()
+
+ if (model is None) or (tree_iter is None):
+ return
+
+ name = model.get_value(tree_iter, 0)
+ model.set_value(tree_iter, 1, text)
+
+ self.mainWindow.project.character_template.details[name] = text
+
+ def nameChanged(self, buffer: Gtk.EntryBuffer):
+
+ text = buffer.get_text()
+ name = invalidString(text)
+
+ self.character.name = name
+
+ character_id = self.character.UID.value
+
+ for row in self.charactersStore:
+ if row[0] == character_id:
+ row[1] = validString(name)
+ break
+
+ def nameDeletedText(self, buffer: Gtk.EntryBuffer, position: int, n_chars: int):
+ self.nameChanged(buffer)
+
+ def nameInsertedText(self, buffer: Gtk.EntryBuffer, position: int, chars: str, n_chars: int):
+ self.nameChanged(buffer)
diff --git a/manuskript/ui/tools/__init__.py b/manuskript/ui/tools/__init__.py
index 7cd78588..ff95f6bf 100644
--- a/manuskript/ui/tools/__init__.py
+++ b/manuskript/ui/tools/__init__.py
@@ -2,3 +2,4 @@
# -*- coding: utf-8 -*-
from manuskript.ui.tools.frequencyWindow import FrequencyWindow
+from manuskript.ui.tools.Character_Template_Editor import CharacterTemplateEditorWindow
\ No newline at end of file
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index 1a32619c..dbcc69de 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -8,13 +8,14 @@ from gi.repository import Gtk
from manuskript.data import Characters, Character, Importance, Color
from manuskript.ui.util import rgbaFromColor, pixbufFromColor
-from manuskript.util import validString, invalidString, validInt, invalidInt
+from manuskript.util import validString, invalidString, validInt, invalidInt, unique_name_checker
class CharactersView:
- def __init__(self, characters: Characters):
- self.characters = characters
+ def __init__(self,project):
+ self.character_template = project.character_template # The template for detailed info
+ self.characters = project.characters
self.character = None
builder = Gtk.Builder()
@@ -74,13 +75,19 @@ class CharactersView:
self.detailsSelection = builder.get_object("details_selection")
self.addDetailsButton = builder.get_object("add_details")
self.removeDetailsButton = builder.get_object("remove_details")
+ self.append_details_template_button = builder.get_object("appened_details_template")
self.detailsNameRenderer = builder.get_object("details_name")
self.detailsValueRenderer = builder.get_object("details_value")
self.addDetailsButton.connect("clicked", self.addDetailsClicked)
self.removeDetailsButton.connect("clicked", self.removeDetailsClicked)
+ # This is to append the template
+ self.append_details_template_button.connect("clicked", self.append_template_clicked)
+
self.detailsNameRenderer.connect("edited", self.detailsNameEdited)
self.detailsValueRenderer.connect("edited", self.detailsValueEdited)
+
+
self.nameBuffer = builder.get_object("name")
self.motivationBuffer = builder.get_object("motivation")
@@ -105,6 +112,7 @@ class CharactersView:
self.notesBuffer.connect("changed", self.notesChanged)
self.unloadCharacterData()
+
def refreshCharacterStore(self):
self.charactersStore.clear()
@@ -297,7 +305,7 @@ class CharactersView:
if tree_iter is None:
return
- name = "Description"
+ name = unique_name_checker.get_unique_name_for_dictionary(self.character.details, "Description")
value = "Value"
self.detailsStore.set_value(tree_iter, 0, name)
@@ -318,6 +326,18 @@ class CharactersView:
model.remove(tree_iter)
self.character.details.pop(name)
+
+ # This is the the template code
+ # It appends the template onto the code
+ def append_template_clicked(self, button):
+ if self.character is None:
+ return
+ # This following bit could be turned into a def
+ for x in self.character_template.details:
+ self.character.details[x]= self.character_template.details[x]
+
+ #We have to reload the charecter
+ self.loadCharacterData(self.character)
def detailsNameEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
if self.character is None:
@@ -327,11 +347,12 @@ class CharactersView:
if (model is None) or (tree_iter is None):
return
-
+
+ text_to_set = unique_name_checker.get_unique_name_for_dictionary(self.character.details, text)
name = model.get_value(tree_iter, 0)
- model.set_value(tree_iter, 0, text)
+ model.set_value(tree_iter, 0, text_to_set)
- self.character.details[text] = self.character.details.pop(name)
+ self.character.details[text_to_set] = self.character.details.pop(name)
def detailsValueEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
if self.character is None:
diff --git a/manuskript/util/unique_name_checker.py b/manuskript/util/unique_name_checker.py
new file mode 100644
index 00000000..423ef52e
--- /dev/null
+++ b/manuskript/util/unique_name_checker.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# So this thing changes a name until it works with a dictionary
+# Ie. if you have a dictioary {'Item':1,'Item2':1,'Item3':1} and if you add an item it'll be Item4
+# It works only on strings
+
+def get_unique_name_for_dictionary(dictionary, name):
+ count = 1
+ test_name = name
+ while test_name in dictionary:
+ count += 1
+ test_name = str(name) +(str(count))
+
+ return test_name
+
diff --git a/test_io.py b/test_io.py
new file mode 100644
index 00000000..a4971543
--- /dev/null
+++ b/test_io.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# I put this here because otherwise I couldn't run it.
+# I also added some tests and had to modify this to get it to run -- ShadowOfHassen
+import os
+import sys
+
+# gi
+import gi
+gi.require_version('GdkPixbuf', '2.0')
+from gi.repository import GdkPixbuf
+
+realpath = os.path.realpath(__file__)
+LOGO_FILE = 'icons/Manuskript/manuskript.svg'
+#sys.path.insert(1, os.path.join(os.path.dirname(realpath), '..'))
+
+from manuskript.ui import MainWindow
+
+
+window = MainWindow("sample-projects/book-of-acts" + ".msk")
+# Let's make this a bit fancier
+window.window.set_icon(GdkPixbuf.Pixbuf.new_from_file(LOGO_FILE))
+
+window.run()
diff --git a/ui/about.glade b/ui/about.glade
index b96638e1..b29464fd 100644
--- a/ui/about.glade
+++ b/ui/about.glade
@@ -1,5 +1,5 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ vertical
+
+
+ 200
+ True
+ False
+ True
+ True
+ 0
+ 0
+
+
+ True
+ True
+ in
+
+
+ True
+ False
+
+
+ True
+ True
+ details_store
+ True
+ 0
+ both
+
+
+
+
+
+ Name
+
+
+ True
+
+
+ 0
+
+
+
+
+
+
+ Value
+
+
+ True
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ 4
+
+
+ True
+ True
+ True
+
+
+ True
+ False
+ list-add
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+
+
+ True
+ False
+ list-remove
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+
+
diff --git a/ui/characters.glade b/ui/characters.glade
index e17aae5b..a1559d09 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -933,10 +933,23 @@ summary
False
True
- end
3
+
+
+ Append Detail Template
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 4
+
+
False
diff --git a/ui/general.glade b/ui/general.glade
index 7f894133..44c04442 100644
--- a/ui/general.glade
+++ b/ui/general.glade
@@ -1,5 +1,5 @@
-
+
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+ -1
+
+
+
+
+
+ True
+ False
+ True
+ 20
+ True
+
+
+ True
+ False
+ label
+
+
+ 2
+ 1
+
+
+
+
+ True
+ False
+ label
+
+
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 4ccd78bc7de02a2288a730d6f977131674010cc4 Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Fri, 3 Feb 2023 16:01:17 +0100
Subject: [PATCH 03/21] Fix multiple warnings, errors and naming issues
Signed-off-by: TheJackiMonster
---
manuskript/ui/mainWindow.py | 2 +-
manuskript/ui/tools/__init__.py | 2 +-
...e_Editor.py => characterTemplateWindow.py} | 91 +++------
ui/character_details_template_editor.glade | 191 +++++++++---------
ui/characters.glade | 5 +-
ui/frequency.glade | 10 +-
6 files changed, 128 insertions(+), 173 deletions(-)
rename manuskript/ui/tools/{Character_Template_Editor.py => characterTemplateWindow.py} (55%)
diff --git a/manuskript/ui/mainWindow.py b/manuskript/ui/mainWindow.py
index 302898c2..a063d7f7 100644
--- a/manuskript/ui/mainWindow.py
+++ b/manuskript/ui/mainWindow.py
@@ -75,7 +75,7 @@ class MainWindow:
self.startupWindow = StartupWindow(self)
self.aboutDialog = AboutDialog(self)
self.frequencyWindow = FrequencyWindow(self)
- self.characterTemplateWindow = CharacterTemplateEditorWindow(self)
+ self.characterTemplateWindow = CharacterTemplateWindow(self)
self.settingsWindow = SettingsWindow(self)
self.windows = [
diff --git a/manuskript/ui/tools/__init__.py b/manuskript/ui/tools/__init__.py
index ff95f6bf..674f8ba8 100644
--- a/manuskript/ui/tools/__init__.py
+++ b/manuskript/ui/tools/__init__.py
@@ -2,4 +2,4 @@
# -*- coding: utf-8 -*-
from manuskript.ui.tools.frequencyWindow import FrequencyWindow
-from manuskript.ui.tools.Character_Template_Editor import CharacterTemplateEditorWindow
\ No newline at end of file
+from manuskript.ui.tools.characterTemplateWindow import CharacterTemplateWindow
diff --git a/manuskript/ui/tools/Character_Template_Editor.py b/manuskript/ui/tools/characterTemplateWindow.py
similarity index 55%
rename from manuskript/ui/tools/Character_Template_Editor.py
rename to manuskript/ui/tools/characterTemplateWindow.py
index ecbf7dd5..75c10148 100644
--- a/manuskript/ui/tools/Character_Template_Editor.py
+++ b/manuskript/ui/tools/characterTemplateWindow.py
@@ -11,81 +11,75 @@ from gi.repository import GObject, Gtk, Handy
# Manuskript
from manuskript.ui.abstractDialog import AbstractDialog
-from manuskript.util import unique_name_checker
+from manuskript.util import unique_name_checker, invalidString, validString
+
# I lifted a lot of this code from frequencyWindow
# With a bit more stuff from charactersView
-class CharacterTemplateEditorWindow(AbstractDialog):
+class CharacterTemplateWindow(AbstractDialog):
def __init__(self, mainWindow):
- AbstractDialog.__init__(self, mainWindow, "ui/character_details_template_editor.glade", "character_details_template_editor")
+ AbstractDialog.__init__(self, mainWindow, "ui/character_details_template_editor.glade",
+ "character_details_template_editor")
self.headerBar = None
self.back = None
- self.wordLeaflet = None
- self.analyzeWords = None
- self.analyzePhrases = None
+
+ self.detailsStore = None
+ self.detailsSelection = None
+ self.addDetailsButton = None
+ self.removeDetailsButton = None
+ self.appendDetailsTemplateButton = None
+ self.detailsNameRenderer = None
+ self.detailsValueRenderer = None
def initWindow(self, builder, window):
self.headerBar = builder.get_object("header_bar")
self.back = builder.get_object("back")
-
- self.character_leaflet = builder.get_object("character_details_leaflet")
-
- self.character_leaflet.bind_property("folded", self.back, "visible", GObject.BindingFlags.SYNC_CREATE)
- self.character_leaflet.bind_property("folded", self.headerBar, "show-close-button", GObject.BindingFlags.SYNC_CREATE |
- GObject.BindingFlags.INVERT_BOOLEAN)
-
self.back.connect("clicked", self._backClicked)
- #Liking Stuff stole from charactersView
+ # Liking Stuff stole from charactersView
self.detailsStore = builder.get_object("details_store")
self.detailsSelection = builder.get_object("details_selection")
self.addDetailsButton = builder.get_object("add_details")
self.removeDetailsButton = builder.get_object("remove_details")
- self.append_details_template_button = builder.get_object("appened_details_template")
+ self.appendDetailsTemplateButton = builder.get_object("appened_details_template")
self.detailsNameRenderer = builder.get_object("details_name")
self.detailsValueRenderer = builder.get_object("details_value")
- self.addDetailsButton.connect("clicked", self.addDetailsClicked)
- self.removeDetailsButton.connect("clicked", self.removeDetailsClicked)
+ self.addDetailsButton.connect("clicked", self._addDetailsClicked)
+ self.removeDetailsButton.connect("clicked", self._removeDetailsClicked)
- self.detailsNameRenderer.connect("edited", self.detailsNameEdited)
- self.detailsValueRenderer.connect("edited", self.detailsValueEdited)
+ self.detailsNameRenderer.connect("edited", self._detailsNameEdited)
+ self.detailsValueRenderer.connect("edited", self._detailsValueEdited)
- self.populate_tree()
-
-
+ self.loadCharacterTemplate()
def _backClicked(self, button: Gtk.Button):
- if self.wordLeaflet.get_visible_child_name() == "wordlist_view":
- self.wordLeaflet.set_visible_child_name("wordfilter_view")
- else:
- self.hide()
+ self.hide()
# So this adds any previously added parts to the template
- def populate_tree(self):
+ def loadCharacterTemplate(self):
for name, value in self.mainWindow.project.character_template.details.items():
tree_iter = self.detailsStore.append()
if tree_iter is None:
return
-
self.detailsStore.set_value(tree_iter, 0, name)
self.detailsStore.set_value(tree_iter, 1, value)
# Functions stole From charactersView
- def addDetailsClicked(self, button: Gtk.Button):
-
+ def _addDetailsClicked(self, button: Gtk.Button):
tree_iter = self.detailsStore.append()
if tree_iter is None:
return
- name = unique_name_checker.get_unique_name_for_dictionary(self.mainWindow.project.character_template.details, "Description")
+ name = unique_name_checker.get_unique_name_for_dictionary(self.mainWindow.project.character_template.details,
+ "Description")
value = "Value"
self.detailsStore.set_value(tree_iter, 0, name)
@@ -93,8 +87,7 @@ class CharacterTemplateEditorWindow(AbstractDialog):
self.mainWindow.project.character_template.details[name] = value
- def removeDetailsClicked(self, button: Gtk.Button):
-
+ def _removeDetailsClicked(self, button: Gtk.Button):
model, tree_iter = self.detailsSelection.get_selected()
if (model is None) or (tree_iter is None):
@@ -105,20 +98,20 @@ class CharacterTemplateEditorWindow(AbstractDialog):
self.mainWindow.project.character_template.details.pop(name)
- def detailsNameEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
-
+ def _detailsNameEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
model, tree_iter = self.detailsSelection.get_selected()
if (model is None) or (tree_iter is None):
return
- text_to_set = unique_name_checker.get_unique_name_for_dictionary(self.mainWindow.project.character_template.details, text)
+ text_to_set = unique_name_checker.get_unique_name_for_dictionary(
+ self.mainWindow.project.character_template.details, text)
name = model.get_value(tree_iter, 0)
model.set_value(tree_iter, 0, text_to_set)
# There was an error with this line but it didn't seem to do anything bad.
- self.mainWindow.project.character_template.details[text_to_set] = self.mainWindow.project.character_template.details.pop(name)
-
- def detailsValueEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
+ self.mainWindow.project.character_template.details[text_to_set] = \
+ self.mainWindow.project.character_template.details.pop(name)
+ def _detailsValueEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
model, tree_iter = self.detailsSelection.get_selected()
if (model is None) or (tree_iter is None):
@@ -128,23 +121,3 @@ class CharacterTemplateEditorWindow(AbstractDialog):
model.set_value(tree_iter, 1, text)
self.mainWindow.project.character_template.details[name] = text
-
- def nameChanged(self, buffer: Gtk.EntryBuffer):
-
- text = buffer.get_text()
- name = invalidString(text)
-
- self.character.name = name
-
- character_id = self.character.UID.value
-
- for row in self.charactersStore:
- if row[0] == character_id:
- row[1] = validString(name)
- break
-
- def nameDeletedText(self, buffer: Gtk.EntryBuffer, position: int, n_chars: int):
- self.nameChanged(buffer)
-
- def nameInsertedText(self, buffer: Gtk.EntryBuffer, position: int, chars: str, n_chars: int):
- self.nameChanged(buffer)
diff --git a/ui/character_details_template_editor.glade b/ui/character_details_template_editor.glade
index 4409bf47..72d0e4b2 100644
--- a/ui/character_details_template_editor.glade
+++ b/ui/character_details_template_editor.glade
@@ -3,14 +3,6 @@
-
-
-
-
-
-
-
-
False
@@ -32,8 +24,6 @@
True
True
True
- 4
- 4
4
4
@@ -55,68 +45,64 @@
-
+
True
False
+ 8
+ vertical
+ 8
-
+
+ 200
True
False
- vertical
+ True
+ True
+ 0
+ 0
-
- 200
+
True
- False
- True
- True
- 0
- 0
+ True
+ in
-
+
True
- True
- in
+ False
-
+
True
- False
+ True
+ details_store
+ True
+ 0
+ both
+
+
+
-
- True
- True
- details_store
- True
- 0
- both
-
-
-
+
+ Name
-
- Name
-
-
- True
-
-
- 0
-
-
+
+ True
+
+ 0
+
+
+
+
+
+ Value
-
- Value
-
-
- True
-
-
- 1
-
-
+
+ True
+
+ 1
+
@@ -124,74 +110,71 @@
-
-
+
+
+
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ 4
+
+
+ True
+ True
+ True
+
+
+ True
+ False
+ list-add
+
- True
+ False
True
0
-
+
True
- False
- 4
+ True
+ True
-
+
True
- True
- True
-
-
- True
- False
- list-add
-
-
+ False
+ list-remove
-
- False
- True
- 0
-
-
-
-
- True
- True
- True
-
-
- True
- False
- list-remove
-
-
-
-
- False
- True
- 1
-
-
-
-
False
- False
+ True
1
+
+ False
+ False
+ 1
+
- False
+ True
True
1
@@ -199,4 +182,12 @@
+
+
+
+
+
+
+
+
diff --git a/ui/characters.glade b/ui/characters.glade
index a1559d09..78a0ba85 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -795,10 +795,7 @@ summary
True
False
- 8
- 8
- 8
- 8
+ 8
vertical
8
diff --git a/ui/frequency.glade b/ui/frequency.glade
index 45ba2c95..7589b2da 100644
--- a/ui/frequency.glade
+++ b/ui/frequency.glade
@@ -102,10 +102,7 @@ along with Manuskript. If not, see .
300
True
False
- 8
- 8
- 8
- 8
+ 8
vertical
8
@@ -311,11 +308,8 @@ along with Manuskript. If not, see .
250
True
True
- 8
- 8
- 8
- 8
True
+ 8
in
From fbbf497449c51ccd76460d58f392043fba41158e Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Sat, 4 Feb 2023 13:11:28 -0500
Subject: [PATCH 04/21] Fixed Name of the Button
There is no icon and I can't make the text any smaller
---
ui/characters.glade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/characters.glade b/ui/characters.glade
index 78a0ba85..23e70247 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -935,7 +935,7 @@ summary
- Append Detail Template
+ Append Template
True
True
True
From 45889d6279b1077f466a99b162b1f8ded5f84a13 Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Sat, 4 Feb 2023 13:11:28 -0500
Subject: [PATCH 05/21] Changed Template Manager
I also added glade back up files to gitignore. It wasn't.
---
.gitignore | 1 +
...rs_template.py => characters_templates.py} | 19 +-
manuskript/data/project.py | 4 +-
manuskript/ui/mainWindow.py | 2 -
manuskript/ui/tools/__init__.py | 3 +-
.../ui/tools/characterTemplateWindow.py | 123 -----------
manuskript/ui/views/charactersView.py | 58 ++++-
test_io.py | 0
ui/character_details_template_editor.glade | 193 -----------------
ui/characters.glade | 203 +++++++++++++++++-
ui/main.glade | 8 -
11 files changed, 266 insertions(+), 348 deletions(-)
rename manuskript/data/{characters_template.py => characters_templates.py} (56%)
delete mode 100644 manuskript/ui/tools/characterTemplateWindow.py
mode change 100644 => 100755 test_io.py
delete mode 100644 ui/character_details_template_editor.glade
diff --git a/.gitignore b/.gitignore
index 75595ae8..d0e9cc37 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ manuskript.log
snowflake*
test-projects
main.pyproject.user
+*.glade#
diff --git a/manuskript/data/characters_template.py b/manuskript/data/characters_templates.py
similarity index 56%
rename from manuskript/data/characters_template.py
rename to manuskript/data/characters_templates.py
index b613892c..d2deadf3 100644
--- a/manuskript/data/characters_template.py
+++ b/manuskript/data/characters_templates.py
@@ -7,21 +7,22 @@ import os
from collections import OrderedDict
-# So this is a template for charecter details
-# It is edited by the Charecter Template Editor
-# Most of the code is taken from charecters.py
+# So this is a template for character details
+# It is edited by the Character Template Editor
+# Most of the code is taken from characters.py
# I think this should have a custom save that's like a .json file in the main part of the manuskript save
#Main Class
-class CharacterDetailTemplate:
-
- details = {'Age':'','Birthdate':'',
+class CharacterDetailTemplates:
+# Basic Template
+ templates = {'Basic Human':
+ {'Age':'','Birthdate':'',
'Eye Color':'','Hair Color':'',
- 'Handed':''} # We'll make a default template
-
+ 'Handed':''},
+ }
- # TODO saving
+ # TODO: saving
def save(self):
pass
diff --git a/manuskript/data/project.py b/manuskript/data/project.py
index f1f6c351..4c9884ec 100644
--- a/manuskript/data/project.py
+++ b/manuskript/data/project.py
@@ -19,7 +19,7 @@ from manuskript.data.world import World
from manuskript.data.outline import Outline
from manuskript.data.revisions import Revisions
# This is for the charecter template
-from manuskript.data.characters_template import CharacterDetailTemplate
+from manuskript.data.characters_templates import CharacterDetailTemplates
from manuskript.io.mskFile import MskFile
from manuskript.util import profileTime
@@ -41,7 +41,7 @@ class Project:
self.world = World(self.file.dir_path)
self.outline = Outline(self.file.dir_path, self.plots, self.labels, self.statuses)
self.revisions = Revisions(self.file.dir_path)
- self.character_template = CharacterDetailTemplate()
+ self.character_templates = CharacterDetailTemplates() # TODO: RENAME PROPERALLY
def __del__(self):
del self.file
diff --git a/manuskript/ui/mainWindow.py b/manuskript/ui/mainWindow.py
index a063d7f7..ed9a2d38 100644
--- a/manuskript/ui/mainWindow.py
+++ b/manuskript/ui/mainWindow.py
@@ -75,14 +75,12 @@ class MainWindow:
self.startupWindow = StartupWindow(self)
self.aboutDialog = AboutDialog(self)
self.frequencyWindow = FrequencyWindow(self)
- self.characterTemplateWindow = CharacterTemplateWindow(self)
self.settingsWindow = SettingsWindow(self)
self.windows = [
self.startupWindow,
self.aboutDialog,
self.frequencyWindow,
- self.characterTemplateWindow,
self.settingsWindow
]
diff --git a/manuskript/ui/tools/__init__.py b/manuskript/ui/tools/__init__.py
index 674f8ba8..3efbdd35 100644
--- a/manuskript/ui/tools/__init__.py
+++ b/manuskript/ui/tools/__init__.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from manuskript.ui.tools.frequencyWindow import FrequencyWindow
-from manuskript.ui.tools.characterTemplateWindow import CharacterTemplateWindow
+from manuskript.ui.tools.frequencyWindow import FrequencyWindow
\ No newline at end of file
diff --git a/manuskript/ui/tools/characterTemplateWindow.py b/manuskript/ui/tools/characterTemplateWindow.py
deleted file mode 100644
index 75c10148..00000000
--- a/manuskript/ui/tools/characterTemplateWindow.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-
-# Imports
-# Gi
-import gi
-
-gi.require_version("Gtk", "3.0")
-from gi.repository import GObject, Gtk, Handy
-
-# Manuskript
-from manuskript.ui.abstractDialog import AbstractDialog
-from manuskript.util import unique_name_checker, invalidString, validString
-
-
-# I lifted a lot of this code from frequencyWindow
-# With a bit more stuff from charactersView
-
-class CharacterTemplateWindow(AbstractDialog):
-
- def __init__(self, mainWindow):
- AbstractDialog.__init__(self, mainWindow, "ui/character_details_template_editor.glade",
- "character_details_template_editor")
-
- self.headerBar = None
- self.back = None
-
- self.detailsStore = None
- self.detailsSelection = None
- self.addDetailsButton = None
- self.removeDetailsButton = None
- self.appendDetailsTemplateButton = None
- self.detailsNameRenderer = None
- self.detailsValueRenderer = None
-
- def initWindow(self, builder, window):
- self.headerBar = builder.get_object("header_bar")
- self.back = builder.get_object("back")
-
- self.back.connect("clicked", self._backClicked)
-
- # Liking Stuff stole from charactersView
- self.detailsStore = builder.get_object("details_store")
- self.detailsSelection = builder.get_object("details_selection")
- self.addDetailsButton = builder.get_object("add_details")
- self.removeDetailsButton = builder.get_object("remove_details")
- self.appendDetailsTemplateButton = builder.get_object("appened_details_template")
- self.detailsNameRenderer = builder.get_object("details_name")
- self.detailsValueRenderer = builder.get_object("details_value")
-
- self.addDetailsButton.connect("clicked", self._addDetailsClicked)
- self.removeDetailsButton.connect("clicked", self._removeDetailsClicked)
-
- self.detailsNameRenderer.connect("edited", self._detailsNameEdited)
- self.detailsValueRenderer.connect("edited", self._detailsValueEdited)
-
- self.loadCharacterTemplate()
-
- def _backClicked(self, button: Gtk.Button):
- self.hide()
-
- # So this adds any previously added parts to the template
- def loadCharacterTemplate(self):
- for name, value in self.mainWindow.project.character_template.details.items():
- tree_iter = self.detailsStore.append()
-
- if tree_iter is None:
- return
-
- self.detailsStore.set_value(tree_iter, 0, name)
- self.detailsStore.set_value(tree_iter, 1, value)
-
-# Functions stole From charactersView
- def _addDetailsClicked(self, button: Gtk.Button):
- tree_iter = self.detailsStore.append()
-
- if tree_iter is None:
- return
-
- name = unique_name_checker.get_unique_name_for_dictionary(self.mainWindow.project.character_template.details,
- "Description")
- value = "Value"
-
- self.detailsStore.set_value(tree_iter, 0, name)
- self.detailsStore.set_value(tree_iter, 1, value)
-
- self.mainWindow.project.character_template.details[name] = value
-
- def _removeDetailsClicked(self, button: Gtk.Button):
- model, tree_iter = self.detailsSelection.get_selected()
-
- if (model is None) or (tree_iter is None):
- return
-
- name = model.get_value(tree_iter, 0)
- model.remove(tree_iter)
-
- self.mainWindow.project.character_template.details.pop(name)
-
- def _detailsNameEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
- model, tree_iter = self.detailsSelection.get_selected()
-
- if (model is None) or (tree_iter is None):
- return
- text_to_set = unique_name_checker.get_unique_name_for_dictionary(
- self.mainWindow.project.character_template.details, text)
- name = model.get_value(tree_iter, 0)
- model.set_value(tree_iter, 0, text_to_set)
- # There was an error with this line but it didn't seem to do anything bad.
- self.mainWindow.project.character_template.details[text_to_set] = \
- self.mainWindow.project.character_template.details.pop(name)
-
- def _detailsValueEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
- model, tree_iter = self.detailsSelection.get_selected()
-
- if (model is None) or (tree_iter is None):
- return
-
- name = model.get_value(tree_iter, 0)
- model.set_value(tree_iter, 1, text)
-
- self.mainWindow.project.character_template.details[name] = text
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index a6ceac1e..0e92b8bf 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -14,7 +14,7 @@ from manuskript.util import validString, invalidString, validInt, invalidInt, un
class CharactersView:
def __init__(self, project):
- self.characterTemplate = project.character_template # The template for detailed info
+ self.characterTemplates = project.character_templates # The template for detailed info
self.characters = project.characters
self.character = None
@@ -78,13 +78,19 @@ class CharactersView:
self.detailsSelection = builder.get_object("details_selection")
self.addDetailsButton = builder.get_object("add_details")
self.removeDetailsButton = builder.get_object("remove_details")
- self.appendDetailsTemplateButton = builder.get_object("appened_details_template")
+ self.charecterDetailsMenuButton = builder.get_object("characters_details_menu_button")
+ self.newTemplateButton = builder.get_object("new_template_button")
+ self.newTemplateEntry = builder.get_object("new_template_entry")
+ self.newTemplateEntryBuffer = builder.get_object("new_template_entry_buffer")
+ self.charecterDetailsMenuAppendBox = builder.get_object("template_select_box")
+ self.charecterDetailsMenuTemplateBox = builder.get_object("template_select_box2")
self.detailsNameRenderer = builder.get_object("details_name")
self.detailsValueRenderer = builder.get_object("details_value")
self.addDetailsButton.connect("clicked", self._addDetailsClicked)
self.removeDetailsButton.connect("clicked", self._removeDetailsClicked)
- self.appendDetailsTemplateButton.connect("clicked", self._appendTemplateClicked)
+ self.charecterDetailsMenuButton.connect("clicked", self._onCharecterDetailsMenuClicked)
+ self.newTemplateButton.connect("clicked", self._onNewTemplateButtonClicked)
self.detailsNameRenderer.connect("edited", self._detailsNameEdited)
self.detailsValueRenderer.connect("edited", self._detailsValueEdited)
@@ -325,17 +331,56 @@ class CharactersView:
model.remove(tree_iter)
self.character.details.pop(name)
+
+ def _updateCharecterDetailsMenu(self):
+ def clear_container(container):
+ data = container.get_children()
+ for d in data:
+ container.remove(d)
+ clear_container( self.charecterDetailsMenuAppendBox)
+ clear_container(self.charecterDetailsMenuTemplateBox)
+ for x in self.characterTemplates.templates:
+ button = Gtk.Button(label=x,) # TODO: turn into ModelButton
+ button.connect("clicked", self._appendTemplateClicked, x)
+ self.charecterDetailsMenuAppendBox.add(button)
+ # Now we do the buttons for charecterDetailsMenuTemplateBox
+ button2 = Gtk.Button(label=x,) # TODO: turn into ModelButton
+ button2.connect("clicked", self._updateTemplateClicked, x)
+ self.charecterDetailsMenuTemplateBox.add(button2)
- def _appendTemplateClicked(self, button: Gtk.Button):
+ self.charecterDetailsMenuAppendBox.show_all()
+ self.charecterDetailsMenuTemplateBox.show_all()
+
+ def _onCharecterDetailsMenuClicked(self, button: Gtk.MenuButton):
+ self._updateCharecterDetailsMenu()
+
+ def _updateTemplateClicked(self, button: Gtk.ModelButton, template):
+ if self.character is None:
+ return
+ self.characterTemplates.templates[template] = self.character.details # TODO: Add A warning? Or should there be undo/ redo when revisions are written.
+
+ def _appendTemplateClicked(self, button: Gtk.ModelButton, template):
if self.character is None:
return
# This following bit could be turned into a def
- for (key, value) in self.characterTemplate.details.items():
+ for (key, value) in self.characterTemplates.templates[template].items():
self.character.details[key]= value
- #We have to reload the charecter
+ # We have to reload the character
self.loadCharacterData(self.character)
+ def _onNewTemplateButtonClicked(self, button: Gtk.Button):
+ text = self.newTemplateEntryBuffer.get_text()
+ if text == "":
+ return
+ if text in self.characterTemplates.templates:
+ new_text = unique_name_checker.get_unique_name_for_dictionary(self.characterTemplates.templates, text)
+ self.newTemplateEntryBuffer.set_text(new_text, -1) # TODO: Add a warning
+ return
+ else:
+ self.characterTemplates.templates[text] = self.character.details
+ self._updateCharecterDetailsMenu()
+
def _detailsNameEdited(self, renderer: Gtk.CellRendererText, path: str, text: str):
if self.character is None:
return
@@ -477,3 +522,4 @@ class CharactersView:
def show(self):
self.widget.show_all()
+
diff --git a/test_io.py b/test_io.py
old mode 100644
new mode 100755
diff --git a/ui/character_details_template_editor.glade b/ui/character_details_template_editor.glade
deleted file mode 100644
index 72d0e4b2..00000000
--- a/ui/character_details_template_editor.glade
+++ /dev/null
@@ -1,193 +0,0 @@
-
-
-
-
-
-
- False
-
-
- True
- False
- vertical
-
-
- True
- False
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- 8
- vertical
- 8
-
-
- 200
- True
- False
- True
- True
- 0
- 0
-
-
- True
- True
- in
-
-
- True
- False
-
-
- True
- True
- details_store
- True
- 0
- both
-
-
-
-
-
- Name
-
-
- True
-
-
- 0
-
-
-
-
-
-
- Value
-
-
- True
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- 0
-
-
-
-
- True
- False
- 4
-
-
- True
- True
- True
-
-
- True
- False
- list-add
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- True
- True
-
-
- True
- False
- list-remove
-
-
-
-
- False
- True
- 1
-
-
-
-
- False
- False
- 1
-
-
-
-
- True
- True
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ui/characters.glade b/ui/characters.glade
index 78a0ba85..231faffd 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -85,6 +85,195 @@ along with Manuskript. If not, see .
+
+
@@ -934,12 +1123,20 @@ summary
-
- Append Detail Template
+
False
diff --git a/ui/main.glade b/ui/main.glade
index c2289edf..32d9a619 100644
--- a/ui/main.glade
+++ b/ui/main.glade
@@ -619,14 +619,6 @@ along with Manuskript. If not, see .
True
-
-
-
From 1d20efcfbc09be1434dc7a90ee6119133f0306ea Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Mon, 6 Feb 2023 17:11:32 -0500
Subject: [PATCH 06/21] Update project.py
---
manuskript/data/project.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/manuskript/data/project.py b/manuskript/data/project.py
index 2aaf034a..57c30f73 100644
--- a/manuskript/data/project.py
+++ b/manuskript/data/project.py
@@ -8,7 +8,6 @@ import os
from zipfile import BadZipFile
# Manuskript modules
-=======
from manuskript.data.abstractData import AbstractData
from manuskript.data.version import Version, CURRENT_MSK_VERSION
@@ -30,7 +29,7 @@ from manuskript.util import profileTime
class Project(AbstractData):
- def __init__(self, path):
+ def __init__(self, path):
AbstractData.__init__(self, path)
self.file = MskFile(self.dataPath)
@@ -45,6 +44,8 @@ class Project(AbstractData):
self.world = World(self.file.directoryPath)
self.outline = Outline(self.file.directoryPath, self.plots, self.labels, self.statuses)
self.revisions = Revisions(self.file.directoryPath)
+ self.character_templates = CharacterDetailTemplates() # TODO: RENAME PROPERALLY
+
def __del__(self):
del self.file
From 546a9bebf2663ee420da5d56d02266d19bac1c9b Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Fri, 17 Feb 2023 14:15:48 -0500
Subject: [PATCH 07/21] Update startupWindow.py
I did this so that the startup menu (Normal start up in Manuksript) would not cause the program to crash)
it's because some actions called the function() when it is now _functon()
---
manuskript/ui/startupWindow.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/manuskript/ui/startupWindow.py b/manuskript/ui/startupWindow.py
index 4173d573..c1c3f5fa 100644
--- a/manuskript/ui/startupWindow.py
+++ b/manuskript/ui/startupWindow.py
@@ -45,10 +45,10 @@ class StartupWindow(AbstractDialog):
GObject.BindingFlags.SYNC_CREATE |
GObject.BindingFlags.INVERT_BOOLEAN)
- bindMenuItem(builder, "open_menu_item", self.mainWindow.openAction)
- bindMenuItem(builder, "quit_menu_item", self.mainWindow.quitAction)
+ bindMenuItem(builder, "open_menu_item", self.mainWindow._openAction)
+ bindMenuItem(builder, "quit_menu_item", self.mainWindow._quitAction)
- bindMenuItem(builder, "about_menu_item", self.mainWindow.aboutAction)
+ bindMenuItem(builder, "about_menu_item", self.mainWindow._aboutAction)
self.templatesStore = builder.get_object("templates_store")
From 1852676b129006de7283101ff04a0c33e36509f8 Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Wed, 22 Feb 2023 12:35:33 -0500
Subject: [PATCH 08/21] Update charactersView.py
I found the update function and it works a lot better.
---
manuskript/ui/views/charactersView.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index 0e92b8bf..168b760d 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -362,9 +362,7 @@ class CharactersView:
def _appendTemplateClicked(self, button: Gtk.ModelButton, template):
if self.character is None:
return
- # This following bit could be turned into a def
- for (key, value) in self.characterTemplates.templates[template].items():
- self.character.details[key]= value
+ self.character.details.update(self.characterTemplates.templates[template])
# We have to reload the character
self.loadCharacterData(self.character)
From 52c63a4763e02787f105395ab4de0684b9a906aa Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Thu, 16 Mar 2023 15:04:08 -0400
Subject: [PATCH 09/21] Added Deleting templates
---
manuskript/ui/views/charactersView.py | 17 ++++++-
ui/characters.glade | 70 ++++++++++++++++++++++++++-
2 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index 168b760d..540b0fae 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -84,6 +84,7 @@ class CharactersView:
self.newTemplateEntryBuffer = builder.get_object("new_template_entry_buffer")
self.charecterDetailsMenuAppendBox = builder.get_object("template_select_box")
self.charecterDetailsMenuTemplateBox = builder.get_object("template_select_box2")
+ self.characterDetaisMenuDeleteBox = builder.get_object("delete_select_box")
self.detailsNameRenderer = builder.get_object("details_name")
self.detailsValueRenderer = builder.get_object("details_value")
@@ -339,6 +340,7 @@ class CharactersView:
container.remove(d)
clear_container( self.charecterDetailsMenuAppendBox)
clear_container(self.charecterDetailsMenuTemplateBox)
+ clear_container(self.characterDetaisMenuDeleteBox)
for x in self.characterTemplates.templates:
button = Gtk.Button(label=x,) # TODO: turn into ModelButton
button.connect("clicked", self._appendTemplateClicked, x)
@@ -347,10 +349,19 @@ class CharactersView:
button2 = Gtk.Button(label=x,) # TODO: turn into ModelButton
button2.connect("clicked", self._updateTemplateClicked, x)
self.charecterDetailsMenuTemplateBox.add(button2)
+ # now we do delete templates
+ box = Gtk.Box()
+ label = Gtk.Label(label=x)
+ box.pack_start(label, False, False, 0)
+ button3 = Gtk.Button(label='delete') # TODO: Make this red
+ button3.connect("clicked", self._deleteTemplateClicked, x)
+ box.pack_start(button3, False, False, 0)
+ self.characterDetaisMenuDeleteBox.add(box)
self.charecterDetailsMenuAppendBox.show_all()
self.charecterDetailsMenuTemplateBox.show_all()
-
+ self.characterDetaisMenuDeleteBox.show_all()
+
def _onCharecterDetailsMenuClicked(self, button: Gtk.MenuButton):
self._updateCharecterDetailsMenu()
@@ -359,6 +370,10 @@ class CharactersView:
return
self.characterTemplates.templates[template] = self.character.details # TODO: Add A warning? Or should there be undo/ redo when revisions are written.
+ def _deleteTemplateClicked(self, button: Gtk.ModelButton, template):
+ del self.characterTemplates.templates[template]
+ self._updateCharecterDetailsMenu()
+
def _appendTemplateClicked(self, button: Gtk.ModelButton, template):
if self.character is None:
return
diff --git a/ui/characters.glade b/ui/characters.glade
index 231faffd..327434c9 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -139,7 +139,6 @@ along with Manuskript. If not, see .
append_template
- 1
@@ -231,7 +230,7 @@ along with Manuskript. If not, see .
edit_template
- 2
+ 1
@@ -267,9 +266,76 @@ along with Manuskript. If not, see .
1
+
+
+ True
+ True
+ True
+ Delete Template
+ delete_template
+
+
+ False
+ True
+ 2
+
+
main
+ 2
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ True
+ True
+ Delete Template
+ main
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+ in
+
+
+ True
+ False
+
+
+ True
+ False
+ none
+ False
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ delete_template
3
From d9c09386148292ac422d186b9ba1dfc717a1ca3e Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Wed, 22 Mar 2023 08:26:09 +0100
Subject: [PATCH 10/21] Improve optimized MMD loading to skip empty files later
on
Signed-off-by: TheJackiMonster
---
manuskript/data/outline.py | 3 ++-
manuskript/io/mmdFile.py | 24 +++++++++++++++++-------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/manuskript/data/outline.py b/manuskript/data/outline.py
index fafa097e..fa5f7a9c 100644
--- a/manuskript/data/outline.py
+++ b/manuskript/data/outline.py
@@ -156,8 +156,9 @@ class OutlineText(OutlineItem):
metadata, body = self.file.loadMMD(optimized)
OutlineItem.loadMetadata(self, metadata)
- if not optimized:
+ if body is not None:
self.text = body
+ optimized = False
self.complete(optimized=optimized)
diff --git a/manuskript/io/mmdFile.py b/manuskript/io/mmdFile.py
index 40ec50dc..f89c58b7 100644
--- a/manuskript/io/mmdFile.py
+++ b/manuskript/io/mmdFile.py
@@ -24,7 +24,8 @@ class MmdFile(AbstractFile):
metaValue = None
with open(self.path, 'rt', encoding='utf-8') as file:
- for line in file:
+ line = file.readline()
+ while line:
m = metaPattern.match(line)
if not (m is None):
@@ -33,14 +34,15 @@ class MmdFile(AbstractFile):
metaKey = m.group(1)
metaValue = m.group(2)
- continue
+ else:
+ m = metaValuePattern.match(line)
- m = metaValuePattern.match(line)
+ if not (m is None):
+ metaValue += "\n" + m.group(2)
+ elif line == "\n":
+ break
- if not (m is None):
- metaValue += "\n" + m.group(2)
- elif line == "\n":
- break
+ line = file.readline()
if not (metaKey is None):
metadata[metaKey] = metaValue
@@ -50,6 +52,14 @@ class MmdFile(AbstractFile):
if (len(body) > 0) and (body[0] == "\n"):
body = body[1:]
+ elif file.seekable():
+ currentPosition = file.tell()
+
+ file.seek(0, 2)
+ endPosition = file.tell()
+
+ if endPosition - currentPosition == 1:
+ body = ""
return metadata, body
From f85e85a1592b23e4c67e5c767aad4c9b0c9bb23d Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 8 Jun 2023 15:58:19 +0200
Subject: [PATCH 11/21] Start implementing import and compile dialog
Signed-off-by: TheJackiMonster
---
manuskript/ui/__init__.py | 2 +
manuskript/ui/compileWindow.py | 53 ++
manuskript/ui/importWindow.py | 51 ++
manuskript/ui/mainWindow.py | 12 +
ui/compile.glade | 875 +++++++++++++++++++++++++++++++++
ui/import.glade | 114 +++--
6 files changed, 1053 insertions(+), 54 deletions(-)
create mode 100644 manuskript/ui/compileWindow.py
create mode 100644 manuskript/ui/importWindow.py
create mode 100644 ui/compile.glade
diff --git a/manuskript/ui/__init__.py b/manuskript/ui/__init__.py
index 9b8ce307..51d8e08e 100644
--- a/manuskript/ui/__init__.py
+++ b/manuskript/ui/__init__.py
@@ -4,6 +4,8 @@
from manuskript.ui.util import *
from manuskript.ui.aboutDialog import AboutDialog
+from manuskript.ui.compileWindow import CompileWindow
+from manuskript.ui.importWindow import ImportWindow
from manuskript.ui.mainWindow import MainWindow
from manuskript.ui.settingsWindow import SettingsWindow
from manuskript.ui.startupWindow import StartupWindow
diff --git a/manuskript/ui/compileWindow.py b/manuskript/ui/compileWindow.py
new file mode 100644
index 00000000..03e46755
--- /dev/null
+++ b/manuskript/ui/compileWindow.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import gi
+
+gi.require_version("Gtk", "3.0")
+from gi.repository import GObject, Gtk, Handy
+
+Handy.init()
+
+from manuskript.ui.abstractDialog import AbstractDialog
+
+from manuskript.data import Project
+
+
+class CompileWindow(AbstractDialog):
+
+ def __init__(self, mainWindow):
+ AbstractDialog.__init__(self, mainWindow, "ui/compile.glade", "compile_window")
+
+ self.headerBar = None
+ self.back = None
+ self.forward = None
+ self.previewLeaflet = None
+ self.manageExportersButton = None
+
+ def initWindow(self, builder, window):
+ self.headerBar = builder.get_object("header_bar")
+ self.back = builder.get_object("back")
+ self.forward = builder.get_object("forward")
+ self.previewLeaflet = builder.get_object("preview_leaflet")
+ self.manageExportersButton = builder.get_object("manage_exporters")
+
+ self.previewLeaflet.bind_property("folded", self.back, "visible",
+ GObject.BindingFlags.SYNC_CREATE)
+ self.previewLeaflet.bind_property("folded", self.forward, "visible",
+ GObject.BindingFlags.SYNC_CREATE)
+ self.previewLeaflet.bind_property("folded", self.headerBar, "show-close-button",
+ GObject.BindingFlags.SYNC_CREATE |
+ GObject.BindingFlags.INVERT_BOOLEAN)
+
+ self.back.connect("clicked", self._backClicked)
+ self.forward.connect("clicked", self._forwardClicked)
+
+ def _backClicked(self, button: Gtk.Button):
+ if self.previewLeaflet.get_visible_child_name() == "preview_box":
+ self.previewLeaflet.set_visible_child_name("settings_box")
+ else:
+ self.hide()
+
+ def _forwardClicked(self, button: Gtk.Button):
+ if self.previewLeaflet.get_visible_child_name() == "settings_box":
+ self.previewLeaflet.set_visible_child_name("preview_box")
diff --git a/manuskript/ui/importWindow.py b/manuskript/ui/importWindow.py
new file mode 100644
index 00000000..56a8a910
--- /dev/null
+++ b/manuskript/ui/importWindow.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import gi
+
+gi.require_version("Gtk", "3.0")
+from gi.repository import GObject, Gtk, Handy
+
+Handy.init()
+
+from manuskript.ui.abstractDialog import AbstractDialog
+
+from manuskript.data import Project
+
+
+class ImportWindow(AbstractDialog):
+
+ def __init__(self, mainWindow):
+ AbstractDialog.__init__(self, mainWindow, "ui/import.glade", "import_window")
+
+ self.headerBar = None
+ self.back = None
+ self.forward = None
+ self.previewLeaflet = None
+
+ def initWindow(self, builder, window):
+ self.headerBar = builder.get_object("header_bar")
+ self.back = builder.get_object("back")
+ self.forward = builder.get_object("forward")
+ self.previewLeaflet = builder.get_object("preview_leaflet")
+
+ self.previewLeaflet.bind_property("folded", self.back, "visible",
+ GObject.BindingFlags.SYNC_CREATE)
+ self.previewLeaflet.bind_property("folded", self.forward, "visible",
+ GObject.BindingFlags.SYNC_CREATE)
+ self.previewLeaflet.bind_property("folded", self.headerBar, "show-close-button",
+ GObject.BindingFlags.SYNC_CREATE |
+ GObject.BindingFlags.INVERT_BOOLEAN)
+
+ self.back.connect("clicked", self._backClicked)
+ self.forward.connect("clicked", self._forwardClicked)
+
+ def _backClicked(self, button: Gtk.Button):
+ if self.previewLeaflet.get_visible_child_name() == "preview_box":
+ self.previewLeaflet.set_visible_child_name("settings_box")
+ else:
+ self.hide()
+
+ def _forwardClicked(self, button: Gtk.Button):
+ if self.previewLeaflet.get_visible_child_name() == "settings_box":
+ self.previewLeaflet.set_visible_child_name("preview_box")
diff --git a/manuskript/ui/mainWindow.py b/manuskript/ui/mainWindow.py
index 9efbf75e..15edfc18 100644
--- a/manuskript/ui/mainWindow.py
+++ b/manuskript/ui/mainWindow.py
@@ -16,6 +16,8 @@ from manuskript.ui.views import *
from manuskript.ui.chooser import openFileDialog, saveFileDialog, FileFilter
from manuskript.ui.tools import *
from manuskript.ui.aboutDialog import AboutDialog
+from manuskript.ui.compileWindow import CompileWindow
+from manuskript.ui.importWindow import ImportWindow
from manuskript.ui.settingsWindow import SettingsWindow
from manuskript.ui.startupWindow import StartupWindow
from manuskript.ui.util import bindMenuItem, packViewIntoSlot, unpackFromSlot
@@ -61,6 +63,8 @@ class MainWindow:
self.aboutDialog = AboutDialog(self)
self.frequencyWindow = FrequencyWindow(self)
self.settingsWindow = SettingsWindow(self)
+ self.importWindow = ImportWindow(self)
+ self.compileWindow = CompileWindow(self)
self.windows = [
self.startupWindow,
@@ -76,6 +80,8 @@ class MainWindow:
bindMenuItem(builder, "save_menu_item", self._saveAction)
bindMenuItem(builder, "saveas_menu_item", self._saveAsAction)
bindMenuItem(builder, "close_menu_item", self._closeAction)
+ bindMenuItem(builder, "import_menu_item", self._importAction)
+ bindMenuItem(builder, "compile_menu_item", self._compileAction)
bindMenuItem(builder, "quit_menu_item", self._quitAction)
bindMenuItem(builder, "settings_menu_item", self._settingsAction)
@@ -157,6 +163,12 @@ class MainWindow:
def _closeAction(self, menuItem: Gtk.MenuItem):
self.closeProject()
+
+ def _importAction(self, menuItem: Gtk.MenuItem):
+ self.importWindow.show()
+
+ def _compileAction(self, menuItem: Gtk.MenuItem):
+ self.compileWindow.show()
def _quitAction(self, menuItem: Gtk.MenuItem):
self.exit(True)
diff --git a/ui/compile.glade b/ui/compile.glade
new file mode 100644
index 00000000..64d054b2
--- /dev/null
+++ b/ui/compile.glade
@@ -0,0 +1,875 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Markdown
+ text/markdown
+ text-x-generic
+
+
+ Folder
+ directory
+ folder
+
+
+ OPML
+ text/opml
+ text-x-generic-template
+
+
+ Mind Map
+ text/mind-map
+ text-x-generic-template
+
+
+
+
+ False
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ 300
+ True
+ False
+ vertical
+
+
+
+ False
+ True
+ end
+ 4
+
+
+
+
+ True
+ False
+ 8
+ 8
+ 8
+ 8
+ vertical
+ 8
+
+
+ True
+ False
+ 6
+ 6
+ Settings
+ 0
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+
+
+ True
+ False
+ 8
+ vertical
+
+
+ True
+ False
+ Decide here what will be included in the final export.
+ True
+ word-char
+ end
+ 0
+
+
+ False
+ True
+ 0
+
+
+
+
+
+ True
+ False
+ 4
+ True
+
+
+ True
+ False
+ Type
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ Title
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ Text
+
+
+ 2
+ 0
+
+
+
+
+
+ True
+ True
+ False
+ True
+
+
+ 1
+ 1
+
+
+
+
+
+ True
+ True
+ False
+ True
+
+
+ 2
+ 2
+
+
+
+
+
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+ 4
+
+
+ True
+ False
+ folder-symbolic
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ Folder
+
+
+ False
+ True
+ 1
+
+
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ 4
+
+
+ True
+ False
+ text-x-generic-symbolic
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ Folder
+
+
+ False
+ True
+ 1
+
+
+
+
+ 0
+ 2
+
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ I need more granularity
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ 4
+ vertical
+
+
+ True
+ True
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ Filters what items will be included in the final export.
+(Not fully implemented yet.)
+ True
+ word-char
+ end
+ 0
+
+
+ False
+ True
+ 0
+
+
+
+
+ Ignore compile status (include all items)
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ Subitems of:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ Labels
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 3
+
+
+
+
+ Status
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 4
+
+
+
+
+
+
+ True
+ False
+ Filters
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ False
+ True
+ 4
+
+
+
+
+
+
+ True
+ False
+ Content
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+
+
+
+
+
+ True
+ False
+ Separations
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+
+
+
+
+
+ True
+ False
+ Transformations
+
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ True
+
+
+
+
+
+ True
+ False
+ Preview
+
+
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ True
+ 5
+
+
+
+
+ settings_box
+
+
+
+
+ 250
+ True
+ False
+ True
+ vertical
+
+
+ True
+ False
+ 8
+ 8
+ 8
+ 8
+ vertical
+ 8
+
+
+ True
+ False
+ 6
+ 6
+ Preview
+ 0
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+
+ False
+ True
+ end
+ 2
+
+
+
+
+ preview_box
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui/import.glade b/ui/import.glade
index cc89e89d..2a8a9689 100644
--- a/ui/import.glade
+++ b/ui/import.glade
@@ -1,5 +1,5 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+ Markdown
+ text/markdown
+ text-x-generic
+
+
+ Folder
+ directory
+ folder
+
+
+ OPML
+ text/opml
+ text-x-generic-template
+
+
+ Mind Map
+ text/mind-map
+ text-x-generic-template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
False
@@ -39,12 +87,12 @@ along with Manuskript. If not, see .
True
False
-
@@ -620,52 +674,4 @@ along with Manuskript. If not, see .
-
-
-
-
-
-
-
-
-
-
-
- Markdown
- text/markdown
- text-x-generic
-
-
- Folder
- directory
- folder
-
-
- OPML
- text/opml
- text-x-generic-template
-
-
- Mind Map
- text/mind-map
- text-x-generic-template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
From 13b6e26b13cc2c5eb6e32ddccdbbd3430fc404c7 Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 8 Jun 2023 17:08:21 +0200
Subject: [PATCH 12/21] Adjust frequency analyzer
Signed-off-by: TheJackiMonster
---
manuskript/ui/tools/frequencyWindow.py | 49 ++++++++++
ui/frequency.glade | 123 ++++++++++++++++++++++---
2 files changed, 160 insertions(+), 12 deletions(-)
diff --git a/manuskript/ui/tools/frequencyWindow.py b/manuskript/ui/tools/frequencyWindow.py
index 26b030f4..989aea20 100644
--- a/manuskript/ui/tools/frequencyWindow.py
+++ b/manuskript/ui/tools/frequencyWindow.py
@@ -17,15 +17,35 @@ class FrequencyWindow(AbstractDialog):
self.headerBar = None
self.back = None
self.wordLeaflet = None
+ self.wordsProgress = None
self.analyzeWords = None
+ self.phrasesProgress = None
self.analyzePhrases = None
+ self.wordEntry = None
+ self.removeWord = None
+ self.addWord = None
+
+ self.excludeWordSelection = None
+ self.excludeWordsStore = None
+ self.wordsFrequencyStore = None
+ self.phrasesFrequencyStore = None
def initWindow(self, builder, window):
self.headerBar = builder.get_object("header_bar")
self.back = builder.get_object("back")
self.wordLeaflet = builder.get_object("word_leaflet")
+ self.wordsProgress = builder.get_object("words_progress")
self.analyzeWords = builder.get_object("analyze_words")
+ self.phrasesProgress = builder.get_object("phrases_progress")
self.analyzePhrases = builder.get_object("analyze_phrases")
+ self.wordEntry = builder.get_object("word_entry")
+ self.removeWord = builder.get_object("remove_word")
+ self.addWord = builder.get_object("add_word")
+
+ self.excludeWordSelection = builder.get_object("exclude_word_selection")
+ self.excludeWordsStore = builder.get_object("exclude_words_store")
+ self.wordsFrequencyStore = builder.get_object("words_frequency_store")
+ self.phrasesFrequencyStore = builder.get_object("phrases_frequency_store")
self.wordLeaflet.bind_property("folded", self.back, "visible",
GObject.BindingFlags.SYNC_CREATE)
@@ -35,6 +55,10 @@ class FrequencyWindow(AbstractDialog):
self.back.connect("clicked", self._backClicked)
self.analyzeWords.connect("clicked", self._analyzeWordsClicked)
+ self.analyzePhrases.connect("clicked", self._analyzePhrasesClicked)
+ self.excludeWordSelection.connect("changed", self._excludeWordSelectionChanged)
+ self.removeWord.connect("clicked", self._removeWordClicked)
+ self.addWord.connect("clicked", self._addWordClicked)
def _backClicked(self, button: Gtk.Button):
if self.wordLeaflet.get_visible_child_name() == "wordlist_view":
@@ -44,3 +68,28 @@ class FrequencyWindow(AbstractDialog):
def _analyzeWordsClicked(self, button: Gtk.Button):
self.wordLeaflet.set_visible_child_name("wordlist_view")
+
+ def _analyzePhrasesClicked(self, button: Gtk.Button):
+ pass
+
+ def _excludeWordSelectionChanged(self, selection: Gtk.TreeSelection):
+ model, tree_iter = selection.get_selected()
+
+ self.removeWord.set_sensitive(tree_iter is not None)
+
+ def _removeWordClicked(self, button: Gtk.Button):
+ model, tree_iter = self.excludeWordSelection.get_selected()
+
+ if tree_iter is None:
+ return
+
+ self.excludeWordsStore.remove(tree_iter)
+
+ def _addWordClicked(self, button: Gtk.Button):
+ tree_iter = self.excludeWordsStore.append()
+
+ if tree_iter is None:
+ return
+
+ word = self.wordEntry.get_buffer().get_text()
+ self.excludeWordsStore.set_value(tree_iter, 0, word)
diff --git a/ui/frequency.glade b/ui/frequency.glade
index 45ba2c95..09bb4a26 100644
--- a/ui/frequency.glade
+++ b/ui/frequency.glade
@@ -27,6 +27,12 @@ along with Manuskript. If not, see .
+
+
+
+
+
+
2
99
@@ -41,6 +47,14 @@ along with Manuskript. If not, see .
1
10
+
+
+
+
+
+
+
+
1
99
@@ -48,6 +62,14 @@ along with Manuskript. If not, see .
1
10
+
+
+
+
+
+
+
+
False
@@ -184,9 +206,26 @@ along with Manuskript. If not, see .
True
False
-
+
True
- False
+ True
+ exclude_words_store
+ False
+ False
+
+
+
+
+
+ Word
+
+
+
+ 0
+
+
+
+
@@ -204,8 +243,9 @@ along with Manuskript. If not, see .
False
8
-
+
True
+ False
True
True
@@ -223,7 +263,7 @@ along with Manuskript. If not, see .
-
+
True
True
@@ -234,7 +274,7 @@ along with Manuskript. If not, see .
-
+
True
True
True
@@ -277,10 +317,9 @@ along with Manuskript. If not, see .
-
+
True
False
- 12
False
@@ -322,9 +361,39 @@ along with Manuskript. If not, see .
True
False
-
+
True
- False
+ True
+ words_frequency_store
+
+
+
+
+
+ Word
+ True
+ True
+
+
+
+ 0
+
+
+
+
+
+
+ Frequency
+ True
+ True
+
+
+
+ 1
+
+
+
+
@@ -490,9 +559,39 @@ along with Manuskript. If not, see .
True
False
-
+
True
- False
+ True
+ phrases_frequency_store
+
+
+
+
+
+ Phrase
+ True
+ True
+
+
+
+ 0
+
+
+
+
+
+
+ Frequency
+ True
+ True
+
+
+
+ 1
+
+
+
+
@@ -506,7 +605,7 @@ along with Manuskript. If not, see .
-
+
True
False
From 07a8197bcdcbc3ef5208b27e1cb321557e05b0ab Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 8 Jun 2023 18:46:30 +0200
Subject: [PATCH 13/21] Implement async frequency analyzing
Signed-off-by: TheJackiMonster
---
manuskript/ui/tools/frequencyWindow.py | 137 ++++++++++++++++++++++++-
ui/frequency.glade | 6 ++
2 files changed, 140 insertions(+), 3 deletions(-)
diff --git a/manuskript/ui/tools/frequencyWindow.py b/manuskript/ui/tools/frequencyWindow.py
index 989aea20..a1e5fea8 100644
--- a/manuskript/ui/tools/frequencyWindow.py
+++ b/manuskript/ui/tools/frequencyWindow.py
@@ -4,9 +4,22 @@
import gi
gi.require_version("Gtk", "3.0")
-from gi.repository import GObject, Gtk, Handy
+from gi.repository import GObject, Gtk
+import re
+
+from enum import Enum, unique
+
+from manuskript.data import OutlineFolder, OutlineText, OutlineState, Project
from manuskript.ui.abstractDialog import AbstractDialog
+from manuskript.util import validString, validInt
+
+
+@unique
+class AnalyzeStatus(Enum):
+ NONE = 0
+ WORDS = 1
+ PHRASES = 2
class FrequencyWindow(AbstractDialog):
@@ -14,6 +27,11 @@ class FrequencyWindow(AbstractDialog):
def __init__(self, mainWindow):
AbstractDialog.__init__(self, mainWindow, "ui/frequency.glade", "frequency_window")
+ self.analyzeStatus = AnalyzeStatus.NONE
+ self.frequencies = dict()
+ self.outlineCompletion = list()
+ self.analyzeCompleted = 0
+
self.headerBar = None
self.back = None
self.wordLeaflet = None
@@ -30,6 +48,10 @@ class FrequencyWindow(AbstractDialog):
self.wordsFrequencyStore = None
self.phrasesFrequencyStore = None
+ self.phraseMinimum = None
+ self.phraseMaximum = None
+ self.wordSize = None
+
def initWindow(self, builder, window):
self.headerBar = builder.get_object("header_bar")
self.back = builder.get_object("back")
@@ -47,6 +69,10 @@ class FrequencyWindow(AbstractDialog):
self.wordsFrequencyStore = builder.get_object("words_frequency_store")
self.phrasesFrequencyStore = builder.get_object("phrases_frequency_store")
+ self.phraseMinimum = builder.get_object("phrase_minimum")
+ self.phraseMaximum = builder.get_object("phrase_maximum")
+ self.wordSize = builder.get_object("word_size")
+
self.wordLeaflet.bind_property("folded", self.back, "visible",
GObject.BindingFlags.SYNC_CREATE)
self.wordLeaflet.bind_property("folded", self.headerBar, "show-close-button",
@@ -59,18 +85,123 @@ class FrequencyWindow(AbstractDialog):
self.excludeWordSelection.connect("changed", self._excludeWordSelectionChanged)
self.removeWord.connect("clicked", self._removeWordClicked)
self.addWord.connect("clicked", self._addWordClicked)
+
+ def getProject(self) -> Project:
+ return self.mainWindow.getProject()
def _backClicked(self, button: Gtk.Button):
if self.wordLeaflet.get_visible_child_name() == "wordlist_view":
self.wordLeaflet.set_visible_child_name("wordfilter_view")
else:
self.hide()
+
+ def __analyzeOutlineText(self, outlineText: OutlineText):
+ if self.analyzeStatus == AnalyzeStatus.WORDS:
+ word_size = validInt(self.wordSize.get_value())
+
+ patterns = [re.compile(r"\w{" + str(word_size) + r",}")]
+ elif self.analyzeStatus == AnalyzeStatus.PHRASES:
+ patterns = []
+
+ phrase_minimum = validInt(self.phraseMinimum.get_value())
+ phrase_maximum = validInt(self.phraseMaximum.get_value())
+
+ for n in range(phrase_minimum, phrase_maximum + 1):
+ patterns.append(re.compile(r"\w+" + r"\s+\w+" * (n - 1)))
+ else:
+ return
+
+ for pattern in patterns:
+ for match in pattern.findall(outlineText.text):
+ if match in self.frequencies:
+ self.frequencies[match] = self.frequencies[match] + 1
+ else:
+ self.frequencies[match] = 1
+
+ def __completeOutlineItem(self):
+ outline_item = self.outlineCompletion.pop(0)
+
+ if outline_item.state != OutlineState.COMPLETE:
+ outline_item.load(False)
+
+ if isinstance(outline_item, OutlineFolder):
+ for item in outline_item:
+ self.outlineCompletion.append(item)
+ elif isinstance(outline_item, OutlineText):
+ self.__analyzeOutlineText(outline_item)
+
+ self.analyzeCompleted = self.analyzeCompleted + 1
+
+ incomplete = len(self.outlineCompletion)
+ complete = self.analyzeCompleted
+ fraction = 1.0 * complete / (complete + incomplete)
+
+ if self.analyzeStatus == AnalyzeStatus.WORDS:
+ self.wordsProgress.set_fraction(fraction)
+ elif self.analyzeStatus == AnalyzeStatus.PHRASES:
+ self.phrasesProgress.set_fraction(fraction)
+
+ if incomplete > 0:
+ return True
+
+ if self.analyzeStatus == AnalyzeStatus.WORDS:
+ self.wordsFrequencyStore.clear()
+
+ for word, frequency in self.frequencies.items():
+ tree_iter = self.wordsFrequencyStore.append()
+
+ if tree_iter is None:
+ continue
+
+ self.wordsFrequencyStore.set_value(tree_iter, 0, validString(word))
+ self.wordsFrequencyStore.set_value(tree_iter, 1, validInt(frequency))
+
+ self.wordLeaflet.set_visible_child_name("wordlist_view")
+ elif self.analyzeStatus == AnalyzeStatus.PHRASES:
+ self.phrasesFrequencyStore.clear()
+
+ for phrase, frequency in self.frequencies.items():
+ tree_iter = self.phrasesFrequencyStore.append()
+
+ if tree_iter is None:
+ continue
+
+ self.phrasesFrequencyStore.set_value(tree_iter, 0, validString(phrase))
+ self.phrasesFrequencyStore.set_value(tree_iter, 1, validInt(frequency))
+
+ self.analyzeStatus = AnalyzeStatus.NONE
+ self.frequencies = dict()
+ return False
+
+ def analyze(self, status: AnalyzeStatus):
+ if self.analyzeStatus != AnalyzeStatus.NONE:
+ return
+
+ project = self.getProject()
+
+ if project is None:
+ return
+
+ self.analyzeStatus = status
+
+ if len(self.outlineCompletion) == 0:
+ self.frequencies = dict()
+ self.analyzeCompleted = 0
+
+ if self.analyzeStatus == AnalyzeStatus.WORDS:
+ self.wordsProgress.set_fraction(0.0)
+ elif self.analyzeStatus == AnalyzeStatus.PHRASES:
+ self.phrasesProgress.set_fraction(0.0)
+
+ GObject.idle_add(self.__completeOutlineItem)
+ for outline_item in project.outline:
+ self.outlineCompletion.append(outline_item)
def _analyzeWordsClicked(self, button: Gtk.Button):
- self.wordLeaflet.set_visible_child_name("wordlist_view")
+ self.analyze(AnalyzeStatus.WORDS)
def _analyzePhrasesClicked(self, button: Gtk.Button):
- pass
+ self.analyze(AnalyzeStatus.PHRASES)
def _excludeWordSelectionChanged(self, selection: Gtk.TreeSelection):
model, tree_iter = selection.get_selected()
diff --git a/ui/frequency.glade b/ui/frequency.glade
index 09bb4a26..7e123c48 100644
--- a/ui/frequency.glade
+++ b/ui/frequency.glade
@@ -365,6 +365,8 @@ along with Manuskript. If not, see .
True
True
words_frequency_store
+ 0
+ False
@@ -373,6 +375,7 @@ along with Manuskript. If not, see .
Word
True
True
+ 0
@@ -386,6 +389,7 @@ along with Manuskript. If not, see .
Frequency
True
True
+ 1
@@ -571,6 +575,7 @@ along with Manuskript. If not, see .
Phrase
True
True
+ 0
@@ -584,6 +589,7 @@ along with Manuskript. If not, see .
Frequency
True
True
+ 1
From 55bd817540969bb1f1d928208f03f53b826b5cf7 Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 8 Jun 2023 18:55:58 +0200
Subject: [PATCH 14/21] Tweak async loading of outline elements
Signed-off-by: TheJackiMonster
---
manuskript/ui/tools/frequencyWindow.py | 6 +++---
ui/frequency.glade | 6 ++++--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/manuskript/ui/tools/frequencyWindow.py b/manuskript/ui/tools/frequencyWindow.py
index a1e5fea8..3afb03c5 100644
--- a/manuskript/ui/tools/frequencyWindow.py
+++ b/manuskript/ui/tools/frequencyWindow.py
@@ -121,13 +121,13 @@ class FrequencyWindow(AbstractDialog):
def __completeOutlineItem(self):
outline_item = self.outlineCompletion.pop(0)
- if outline_item.state != OutlineState.COMPLETE:
- outline_item.load(False)
-
if isinstance(outline_item, OutlineFolder):
for item in outline_item:
self.outlineCompletion.append(item)
elif isinstance(outline_item, OutlineText):
+ if outline_item.state != OutlineState.COMPLETE:
+ outline_item.load(False)
+
self.__analyzeOutlineText(outline_item)
self.analyzeCompleted = self.analyzeCompleted + 1
diff --git a/ui/frequency.glade b/ui/frequency.glade
index 7e123c48..e40236fb 100644
--- a/ui/frequency.glade
+++ b/ui/frequency.glade
@@ -367,6 +367,7 @@ along with Manuskript. If not, see .
words_frequency_store
0
False
+ 0
@@ -374,7 +375,6 @@ along with Manuskript. If not, see .
Word
True
- True
0
@@ -567,6 +567,9 @@ along with Manuskript. If not, see .
True
True
phrases_frequency_store
+ 0
+ False
+ 0
@@ -574,7 +577,6 @@ along with Manuskript. If not, see .
Phrase
True
- True
0
From 8adcd3e2695c8c185464ea60cc2639e3db6d2b6b Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 8 Jun 2023 19:27:16 +0200
Subject: [PATCH 15/21] Implement exclusion filter
Signed-off-by: TheJackiMonster
---
manuskript/ui/tools/frequencyWindow.py | 35 ++++++++++++++++++++++++++
ui/frequency.glade | 5 +++-
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/manuskript/ui/tools/frequencyWindow.py b/manuskript/ui/tools/frequencyWindow.py
index 3afb03c5..7b589cfb 100644
--- a/manuskript/ui/tools/frequencyWindow.py
+++ b/manuskript/ui/tools/frequencyWindow.py
@@ -69,6 +69,11 @@ class FrequencyWindow(AbstractDialog):
self.wordsFrequencyStore = builder.get_object("words_frequency_store")
self.phrasesFrequencyStore = builder.get_object("phrases_frequency_store")
+ self.filteredFrequencyStore = builder.get_object("filtered_frequency_store")
+
+ self.filteredFrequencyStore.set_visible_func(self._filterFrequencies)
+ self.filteredFrequencyStore.refilter()
+
self.phraseMinimum = builder.get_object("phrase_minimum")
self.phraseMaximum = builder.get_object("phrase_maximum")
self.wordSize = builder.get_object("word_size")
@@ -82,12 +87,34 @@ class FrequencyWindow(AbstractDialog):
self.back.connect("clicked", self._backClicked)
self.analyzeWords.connect("clicked", self._analyzeWordsClicked)
self.analyzePhrases.connect("clicked", self._analyzePhrasesClicked)
+ self.wordSize.connect("value-changed", self._wordSizeChanged)
self.excludeWordSelection.connect("changed", self._excludeWordSelectionChanged)
self.removeWord.connect("clicked", self._removeWordClicked)
self.addWord.connect("clicked", self._addWordClicked)
def getProject(self) -> Project:
return self.mainWindow.getProject()
+
+ def _filterFrequencies(self, model, iterator, userdata):
+ word = model[iterator][0]
+
+ if word is None:
+ return False
+
+ word_size = validInt(self.wordSize.get_value())
+
+ if len(word) < word_size:
+ return False
+
+ iter = self.excludeWordsStore.get_iter_first()
+ while iter is not None:
+ excluded = self.excludeWordsStore.get_value(iter, 0)
+ if word == excluded:
+ return False
+
+ iter = self.excludeWordsStore.iter_next(iter)
+
+ return True
def _backClicked(self, button: Gtk.Button):
if self.wordLeaflet.get_visible_child_name() == "wordlist_view":
@@ -113,6 +140,9 @@ class FrequencyWindow(AbstractDialog):
for pattern in patterns:
for match in pattern.findall(outlineText.text):
+ if match is None:
+ continue
+
if match in self.frequencies:
self.frequencies[match] = self.frequencies[match] + 1
else:
@@ -203,6 +233,9 @@ class FrequencyWindow(AbstractDialog):
def _analyzePhrasesClicked(self, button: Gtk.Button):
self.analyze(AnalyzeStatus.PHRASES)
+ def _wordSizeChanged(self, adjustment: Gtk.Adjustment):
+ self.filteredFrequencyStore.refilter()
+
def _excludeWordSelectionChanged(self, selection: Gtk.TreeSelection):
model, tree_iter = selection.get_selected()
@@ -215,6 +248,7 @@ class FrequencyWindow(AbstractDialog):
return
self.excludeWordsStore.remove(tree_iter)
+ self.filteredFrequencyStore.refilter()
def _addWordClicked(self, button: Gtk.Button):
tree_iter = self.excludeWordsStore.append()
@@ -224,3 +258,4 @@ class FrequencyWindow(AbstractDialog):
word = self.wordEntry.get_buffer().get_text()
self.excludeWordsStore.set_value(tree_iter, 0, word)
+ self.filteredFrequencyStore.refilter()
diff --git a/ui/frequency.glade b/ui/frequency.glade
index e40236fb..728e9e1d 100644
--- a/ui/frequency.glade
+++ b/ui/frequency.glade
@@ -70,6 +70,9 @@ along with Manuskript. If not, see .
+
+ words_frequency_store
+
False
@@ -364,7 +367,7 @@ along with Manuskript. If not, see .
True
True
- words_frequency_store
+ filtered_frequency_store
0
False
0
From d5a0b563870c1dd79ca4b355419152f6f7d2066b Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 8 Jun 2023 19:37:30 +0200
Subject: [PATCH 16/21] Improve speed of frequency tool
Signed-off-by: TheJackiMonster
---
manuskript/ui/tools/frequencyWindow.py | 74 ++++++++++++++------------
1 file changed, 40 insertions(+), 34 deletions(-)
diff --git a/manuskript/ui/tools/frequencyWindow.py b/manuskript/ui/tools/frequencyWindow.py
index 7b589cfb..e41e5231 100644
--- a/manuskript/ui/tools/frequencyWindow.py
+++ b/manuskript/ui/tools/frequencyWindow.py
@@ -28,7 +28,7 @@ class FrequencyWindow(AbstractDialog):
AbstractDialog.__init__(self, mainWindow, "ui/frequency.glade", "frequency_window")
self.analyzeStatus = AnalyzeStatus.NONE
- self.frequencies = dict()
+ self.analyzeTexts = list()
self.outlineCompletion = list()
self.analyzeCompleted = 0
@@ -70,7 +70,7 @@ class FrequencyWindow(AbstractDialog):
self.phrasesFrequencyStore = builder.get_object("phrases_frequency_store")
self.filteredFrequencyStore = builder.get_object("filtered_frequency_store")
-
+
self.filteredFrequencyStore.set_visible_func(self._filterFrequencies)
self.filteredFrequencyStore.refilter()
@@ -122,32 +122,6 @@ class FrequencyWindow(AbstractDialog):
else:
self.hide()
- def __analyzeOutlineText(self, outlineText: OutlineText):
- if self.analyzeStatus == AnalyzeStatus.WORDS:
- word_size = validInt(self.wordSize.get_value())
-
- patterns = [re.compile(r"\w{" + str(word_size) + r",}")]
- elif self.analyzeStatus == AnalyzeStatus.PHRASES:
- patterns = []
-
- phrase_minimum = validInt(self.phraseMinimum.get_value())
- phrase_maximum = validInt(self.phraseMaximum.get_value())
-
- for n in range(phrase_minimum, phrase_maximum + 1):
- patterns.append(re.compile(r"\w+" + r"\s+\w+" * (n - 1)))
- else:
- return
-
- for pattern in patterns:
- for match in pattern.findall(outlineText.text):
- if match is None:
- continue
-
- if match in self.frequencies:
- self.frequencies[match] = self.frequencies[match] + 1
- else:
- self.frequencies[match] = 1
-
def __completeOutlineItem(self):
outline_item = self.outlineCompletion.pop(0)
@@ -157,8 +131,8 @@ class FrequencyWindow(AbstractDialog):
elif isinstance(outline_item, OutlineText):
if outline_item.state != OutlineState.COMPLETE:
outline_item.load(False)
-
- self.__analyzeOutlineText(outline_item)
+
+ self.analyzeTexts.append(outline_item.text)
self.analyzeCompleted = self.analyzeCompleted + 1
@@ -174,10 +148,36 @@ class FrequencyWindow(AbstractDialog):
if incomplete > 0:
return True
+ patterns = list()
+
+ if self.analyzeStatus == AnalyzeStatus.WORDS:
+ word_size = validInt(self.wordSize.get_value())
+
+ patterns.append(re.compile(r"\w{" + str(word_size) + r",}"))
+ elif self.analyzeStatus == AnalyzeStatus.PHRASES:
+ phrase_minimum = validInt(self.phraseMinimum.get_value())
+ phrase_maximum = validInt(self.phraseMaximum.get_value())
+
+ for n in range(phrase_minimum, phrase_maximum + 1):
+ patterns.append(re.compile(r"\w+" + r"\s+\w+" * (n - 1)))
+
+ frequencies = dict()
+ text = "\n".join(self.analyzeTexts)
+
+ for pattern in patterns:
+ for match in pattern.findall(text):
+ if match is None:
+ continue
+
+ if match in frequencies:
+ frequencies[match] = frequencies[match] + 1
+ else:
+ frequencies[match] = 1
+
if self.analyzeStatus == AnalyzeStatus.WORDS:
self.wordsFrequencyStore.clear()
- for word, frequency in self.frequencies.items():
+ for word, frequency in frequencies.items():
tree_iter = self.wordsFrequencyStore.append()
if tree_iter is None:
@@ -190,7 +190,7 @@ class FrequencyWindow(AbstractDialog):
elif self.analyzeStatus == AnalyzeStatus.PHRASES:
self.phrasesFrequencyStore.clear()
- for phrase, frequency in self.frequencies.items():
+ for phrase, frequency in frequencies.items():
tree_iter = self.phrasesFrequencyStore.append()
if tree_iter is None:
@@ -200,7 +200,10 @@ class FrequencyWindow(AbstractDialog):
self.phrasesFrequencyStore.set_value(tree_iter, 1, validInt(frequency))
self.analyzeStatus = AnalyzeStatus.NONE
- self.frequencies = dict()
+ self.analyzeTexts = list()
+
+ self.analyzeWords.set_sensitive(True)
+ self.analyzePhrases.set_sensitive(True)
return False
def analyze(self, status: AnalyzeStatus):
@@ -212,10 +215,13 @@ class FrequencyWindow(AbstractDialog):
if project is None:
return
+ self.analyzeWords.set_sensitive(False)
+ self.analyzePhrases.set_sensitive(False)
+
self.analyzeStatus = status
if len(self.outlineCompletion) == 0:
- self.frequencies = dict()
+ self.analyzeTexts = list()
self.analyzeCompleted = 0
if self.analyzeStatus == AnalyzeStatus.WORDS:
From 3d469e671e2993393e783cc5b320a2c194e2a3b1 Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Fri, 16 Jun 2023 00:26:40 +0200
Subject: [PATCH 17/21] Fix editor view texts
Signed-off-by: TheJackiMonster
---
manuskript/ui/views/editorView.py | 2 --
ui/editor.glade | 29 +++++++++++++++++++----------
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/manuskript/ui/views/editorView.py b/manuskript/ui/views/editorView.py
index 6d32d55d..bea71764 100644
--- a/manuskript/ui/views/editorView.py
+++ b/manuskript/ui/views/editorView.py
@@ -270,8 +270,6 @@ class EditorView:
self.editorItems = self.project.outline.items
elif type(outlineItem) is OutlineFolder:
self.editorItems = outlineItem.items
- elif type(outlineItem) is OutlineText:
- self.__appendOutlineItemText(outlineItem)
if outlineItem is None:
for item in self.editorItems:
diff --git a/ui/editor.glade b/ui/editor.glade
index 3755d625..569fb31a 100644
--- a/ui/editor.glade
+++ b/ui/editor.glade
@@ -65,16 +65,6 @@ along with Manuskript. If not, see .
False
-
-
- Normal
-
-
-
-
- Normal
-
-
h2
@@ -173,7 +163,21 @@ along with Manuskript. If not, see .
p
Normal
+ 4
+ 4
+ 8
20
+ 8
+
+
+
+
+ line
+ Normal
+ False
+ 4
+ True
+ 4
@@ -397,6 +401,11 @@ along with Manuskript. If not, see .
True
True
word-char
+ 8
+ 8
+ 4
+ 4
+ 4
editor_text
GTK_INPUT_HINT_SPELLCHECK | GTK_INPUT_HINT_WORD_COMPLETION | GTK_INPUT_HINT_NONE
From c20ee8d07a8c8eba7dc78497ce23f5c1e71be690 Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Sat, 1 Apr 2023 10:36:42 -0400
Subject: [PATCH 18/21] I simplified the UI for templates
---
manuskript/ui/views/charactersView.py | 22 ++++----
ui/characters.glade | 80 ++++-----------------------
ui/quote_of_the_day.glade | 71 ------------------------
3 files changed, 21 insertions(+), 152 deletions(-)
delete mode 100644 ui/quote_of_the_day.glade
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index 540b0fae..e8f5ecc7 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -84,7 +84,6 @@ class CharactersView:
self.newTemplateEntryBuffer = builder.get_object("new_template_entry_buffer")
self.charecterDetailsMenuAppendBox = builder.get_object("template_select_box")
self.charecterDetailsMenuTemplateBox = builder.get_object("template_select_box2")
- self.characterDetaisMenuDeleteBox = builder.get_object("delete_select_box")
self.detailsNameRenderer = builder.get_object("details_name")
self.detailsValueRenderer = builder.get_object("details_value")
@@ -340,27 +339,28 @@ class CharactersView:
container.remove(d)
clear_container( self.charecterDetailsMenuAppendBox)
clear_container(self.charecterDetailsMenuTemplateBox)
- clear_container(self.characterDetaisMenuDeleteBox)
for x in self.characterTemplates.templates:
button = Gtk.Button(label=x,) # TODO: turn into ModelButton
button.connect("clicked", self._appendTemplateClicked, x)
self.charecterDetailsMenuAppendBox.add(button)
# Now we do the buttons for charecterDetailsMenuTemplateBox
- button2 = Gtk.Button(label=x,) # TODO: turn into ModelButton
- button2.connect("clicked", self._updateTemplateClicked, x)
- self.charecterDetailsMenuTemplateBox.add(button2)
- # now we do delete templates
box = Gtk.Box()
label = Gtk.Label(label=x)
box.pack_start(label, False, False, 0)
- button3 = Gtk.Button(label='delete') # TODO: Make this red
- button3.connect("clicked", self._deleteTemplateClicked, x)
- box.pack_start(button3, False, False, 0)
- self.characterDetaisMenuDeleteBox.add(box)
+ overwrite_button = Gtk.Button()
+ overwrite_button.add(Gtk.Image(icon_name='emblem-insync-syncing'))
+ overwrite_button.connect("clicked", self._updateTemplateClicked, x)
+ overwrite_button.set_tooltip_markup ('Overwrite template with text of current file') # TODO: This might be an issue when it comes to translating
+ delete_button = Gtk.Button()
+ delete_button.add(Gtk.Image(icon_name='app-remove-symbolic'))
+ delete_button.set_tooltip_markup ('Delete') # TODO: This might be an issue when it comes to translating
+ delete_button.connect("clicked", self._deleteTemplateClicked, x)
+ box.pack_start(overwrite_button, False, False, 0)
+ box.pack_start(delete_button, False, False, 0)
+ self.charecterDetailsMenuTemplateBox.add(box)
self.charecterDetailsMenuAppendBox.show_all()
self.charecterDetailsMenuTemplateBox.show_all()
- self.characterDetaisMenuDeleteBox.show_all()
def _onCharecterDetailsMenuClicked(self, button: Gtk.MenuButton):
self._updateCharecterDetailsMenu()
diff --git a/ui/characters.glade b/ui/characters.glade
index 327434c9..a6cefe00 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -89,58 +89,6 @@ along with Manuskript. If not, see .
@@ -287,7 +224,10 @@ along with Manuskript. If not, see .
-
+
+
+
+
True
False
vertical
@@ -296,7 +236,7 @@ along with Manuskript. If not, see .
True
True
True
- Delete Template
+ Append Template
main
True
@@ -317,7 +257,7 @@ along with Manuskript. If not, see .
True
False
-
+
True
False
none
@@ -335,8 +275,8 @@ along with Manuskript. If not, see .
- delete_template
- 3
+ append_template
+ 4
diff --git a/ui/quote_of_the_day.glade b/ui/quote_of_the_day.glade
deleted file mode 100644
index 2e24848d..00000000
--- a/ui/quote_of_the_day.glade
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
-
- True
- False
-
-
- True
- False
-
-
- -1
-
-
-
-
-
- True
- False
- True
- 20
- True
-
-
- True
- False
- label
-
-
- 2
- 1
-
-
-
-
- True
- False
- label
-
-
- 2
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
From 355f02afd5378ffab3cfdd6f5bc62fa2832d0226 Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Sat, 17 Jun 2023 08:44:46 -0400
Subject: [PATCH 19/21] Update
---
test_io.py | 24 ------------------------
ui/about.glade | 2 +-
2 files changed, 1 insertion(+), 25 deletions(-)
delete mode 100755 test_io.py
diff --git a/test_io.py b/test_io.py
deleted file mode 100755
index a4971543..00000000
--- a/test_io.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# I put this here because otherwise I couldn't run it.
-# I also added some tests and had to modify this to get it to run -- ShadowOfHassen
-import os
-import sys
-
-# gi
-import gi
-gi.require_version('GdkPixbuf', '2.0')
-from gi.repository import GdkPixbuf
-
-realpath = os.path.realpath(__file__)
-LOGO_FILE = 'icons/Manuskript/manuskript.svg'
-#sys.path.insert(1, os.path.join(os.path.dirname(realpath), '..'))
-
-from manuskript.ui import MainWindow
-
-
-window = MainWindow("sample-projects/book-of-acts" + ".msk")
-# Let's make this a bit fancier
-window.window.set_icon(GdkPixbuf.Pixbuf.new_from_file(LOGO_FILE))
-
-window.run()
diff --git a/ui/about.glade b/ui/about.glade
index b29464fd..4aa56b78 100644
--- a/ui/about.glade
+++ b/ui/about.glade
@@ -31,7 +31,7 @@ along with Manuskript. If not, see .
center-on-parent
dialog
Manuskript
- Gtk Working Version (Last Version 0.14.0)
+ Gtk Working Version (Last Version 0.15.0)
Copyright © 2015-2021 Olivier Keshavjee et al.
This is a Gtk Version Still In Development
https://www.theologeek.ch/manuskript/
From 828ee817839fe4c4a7d30a5e2e20eea1987078b3 Mon Sep 17 00:00:00 2001
From: TheShadowOfHassen <94244235+TheShadowOfHassen@users.noreply.github.com>
Date: Sun, 25 Jun 2023 18:10:53 -0400
Subject: [PATCH 20/21] Update charactersView.py
---
manuskript/ui/views/charactersView.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index e8f5ecc7..d1b8e3bf 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -346,9 +346,8 @@ class CharactersView:
# Now we do the buttons for charecterDetailsMenuTemplateBox
box = Gtk.Box()
label = Gtk.Label(label=x)
- box.pack_start(label, False, False, 0)
overwrite_button = Gtk.Button()
- overwrite_button.add(Gtk.Image(icon_name='emblem-insync-syncing'))
+ overwrite_button.add(Gtk.Image(icon_name='system-restart-symbolic'))
overwrite_button.connect("clicked", self._updateTemplateClicked, x)
overwrite_button.set_tooltip_markup ('Overwrite template with text of current file') # TODO: This might be an issue when it comes to translating
delete_button = Gtk.Button()
@@ -357,6 +356,7 @@ class CharactersView:
delete_button.connect("clicked", self._deleteTemplateClicked, x)
box.pack_start(overwrite_button, False, False, 0)
box.pack_start(delete_button, False, False, 0)
+ box.pack_start(label, False, False, 0)
self.charecterDetailsMenuTemplateBox.add(box)
self.charecterDetailsMenuAppendBox.show_all()
From b0d9ac29e7708a02b984a2f6918bc169371fbbde Mon Sep 17 00:00:00 2001
From: TheJackiMonster
Date: Thu, 3 Aug 2023 23:41:52 +0200
Subject: [PATCH 21/21] Adjust variable, layout, icon and alignment
Signed-off-by: TheJackiMonster
---
manuskript/ui/views/charactersView.py | 34 ++---
ui/characters.glade | 206 ++++++++++++++------------
2 files changed, 125 insertions(+), 115 deletions(-)
diff --git a/manuskript/ui/views/charactersView.py b/manuskript/ui/views/charactersView.py
index d1b8e3bf..6b93e5a0 100644
--- a/manuskript/ui/views/charactersView.py
+++ b/manuskript/ui/views/charactersView.py
@@ -339,24 +339,24 @@ class CharactersView:
container.remove(d)
clear_container( self.charecterDetailsMenuAppendBox)
clear_container(self.charecterDetailsMenuTemplateBox)
- for x in self.characterTemplates.templates:
- button = Gtk.Button(label=x,) # TODO: turn into ModelButton
- button.connect("clicked", self._appendTemplateClicked, x)
+ for template_name in self.characterTemplates.templates:
+ button = Gtk.Button(label=template_name) # TODO: turn into ModelButton
+ button.connect("clicked", self._appendTemplateClicked, template_name)
self.charecterDetailsMenuAppendBox.add(button)
# Now we do the buttons for charecterDetailsMenuTemplateBox
box = Gtk.Box()
- label = Gtk.Label(label=x)
+ label = Gtk.Label(label=template_name)
overwrite_button = Gtk.Button()
- overwrite_button.add(Gtk.Image(icon_name='system-restart-symbolic'))
- overwrite_button.connect("clicked", self._updateTemplateClicked, x)
+ overwrite_button.add(Gtk.Image(icon_name='emblem-synchronizing-symbolic'))
+ overwrite_button.connect("clicked", self._updateTemplateClicked, template_name)
overwrite_button.set_tooltip_markup ('Overwrite template with text of current file') # TODO: This might be an issue when it comes to translating
delete_button = Gtk.Button()
- delete_button.add(Gtk.Image(icon_name='app-remove-symbolic'))
+ delete_button.add(Gtk.Image(icon_name='list-remove-symbolic'))
delete_button.set_tooltip_markup ('Delete') # TODO: This might be an issue when it comes to translating
- delete_button.connect("clicked", self._deleteTemplateClicked, x)
- box.pack_start(overwrite_button, False, False, 0)
- box.pack_start(delete_button, False, False, 0)
- box.pack_start(label, False, False, 0)
+ delete_button.connect("clicked", self._deleteTemplateClicked, template_name)
+ box.pack_end(delete_button, False, False, 0)
+ box.pack_end(overwrite_button, False, False, 0)
+ box.pack_start(label, True, False, 0)
self.charecterDetailsMenuTemplateBox.add(box)
self.charecterDetailsMenuAppendBox.show_all()
@@ -365,19 +365,19 @@ class CharactersView:
def _onCharecterDetailsMenuClicked(self, button: Gtk.MenuButton):
self._updateCharecterDetailsMenu()
- def _updateTemplateClicked(self, button: Gtk.ModelButton, template):
+ def _updateTemplateClicked(self, button: Gtk.ModelButton, template_name):
if self.character is None:
return
- self.characterTemplates.templates[template] = self.character.details # TODO: Add A warning? Or should there be undo/ redo when revisions are written.
+ self.characterTemplates.templates[template_name] = self.character.details # TODO: Add A warning? Or should there be undo/ redo when revisions are written.
- def _deleteTemplateClicked(self, button: Gtk.ModelButton, template):
- del self.characterTemplates.templates[template]
+ def _deleteTemplateClicked(self, button: Gtk.ModelButton, template_name):
+ del self.characterTemplates.templates[template_name]
self._updateCharecterDetailsMenu()
- def _appendTemplateClicked(self, button: Gtk.ModelButton, template):
+ def _appendTemplateClicked(self, button: Gtk.ModelButton, template_name):
if self.character is None:
return
- self.character.details.update(self.characterTemplates.templates[template])
+ self.character.details.update(self.characterTemplates.templates[template_name])
# We have to reload the character
self.loadCharacterData(self.character)
diff --git a/ui/characters.glade b/ui/characters.glade
index a6cefe00..1b0333a6 100644
--- a/ui/characters.glade
+++ b/ui/characters.glade
@@ -87,100 +87,9 @@ along with Manuskript. If not, see .