Start implementing plot view

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
This commit is contained in:
TheJackiMonster 2022-10-29 18:42:55 +02:00
parent 6f031d4d37
commit cfa7452292
No known key found for this signature in database
GPG key ID: D850A5F772E880F9
7 changed files with 438 additions and 56 deletions

View file

@ -4,6 +4,8 @@
import os import os
from collections import OrderedDict from collections import OrderedDict
from collections.abc import Callable
from manuskript.data.color import Color from manuskript.data.color import Color
from manuskript.data.importance import Importance from manuskript.data.importance import Importance
from manuskript.data.unique_id import UniqueIDHost from manuskript.data.unique_id import UniqueIDHost
@ -16,6 +18,7 @@ class Character:
def __init__(self, path, characters): def __init__(self, path, characters):
self.file = MmdFile(path, 21) self.file = MmdFile(path, 21)
self.characters = characters self.characters = characters
self.links = list()
self.UID = None self.UID = None
self.name = None self.name = None
@ -32,14 +35,21 @@ class Character:
self.color = None self.color = None
self.details = dict() self.details = dict()
def link(self, callback: Callable[[int], None]):
self.links.append(callback)
def unlink(self, callback: Callable[[int], None]):
self.links.remove(callback)
def allowPOV(self) -> bool: def allowPOV(self) -> bool:
return True if self.POV is None else self.POV return True if self.POV is None else self.POV
def remove(self): def remove(self):
if self.UID is None: for link in self.links:
return link(self.UID.value)
self.characters.removeByID(self.UID.value) self.links.clear()
self.characters.remove(self)
@classmethod @classmethod
def loadAttribute(cls, metadata: dict, name: str, defaultValue=None): def loadAttribute(cls, metadata: dict, name: str, defaultValue=None):
@ -134,8 +144,9 @@ class Characters:
def getByID(self, ID: int) -> Character: def getByID(self, ID: int) -> Character:
return self.data.get(ID, None) return self.data.get(ID, None)
def removeByID(self, ID: int): def remove(self, character: Character):
self.data.pop(ID) self.host.removeID(character.UID)
self.data.pop(character.UID.value)
def load(self): def load(self):
self.data.clear() self.data.clear()

View file

@ -4,7 +4,7 @@
import os import os
from lxml import etree from lxml import etree
from enum import Enum, unique from manuskript.data.characters import Characters
from manuskript.data.importance import Importance from manuskript.data.importance import Importance
from manuskript.data.unique_id import UniqueIDHost, UniqueID from manuskript.data.unique_id import UniqueIDHost, UniqueID
from manuskript.io.xmlFile import XmlFile from manuskript.io.xmlFile import XmlFile
@ -26,10 +26,13 @@ class PlotStep:
class PlotLine: class PlotLine:
def __init__(self, plots, UID: UniqueID, name: str, importance: Importance = Importance.MINOR): def __init__(self, plots, UID: UniqueID, name: str = None, importance: Importance = Importance.MINOR):
self.plots = plots self.plots = plots
self.host = UniqueIDHost() self.host = UniqueIDHost()
if name is None:
name = "New plot"
self.UID = UID self.UID = UID
self.name = name self.name = name
self.importance = importance self.importance = importance
@ -38,6 +41,24 @@ class PlotLine:
self.result = "" self.result = ""
self.steps = list() self.steps = list()
def addCharacterByID(self, ID: int):
character = self.plots.characters.getByID(ID)
if character is None:
return
character.link(self.removeCharacterByID)
self.characters.append(character.UID.value)
def removeCharacterByID(self, ID: int):
character = self.plots.characters.getByID(ID)
if character is None:
self.characters.remove(ID)
else:
character.unlink(self.removeCharacterByID)
self.characters.remove(character.UID.value)
def addStep(self, name: str, meta: str = "", summary: str = ""): def addStep(self, name: str, meta: str = "", summary: str = ""):
step = PlotStep(self, self.host.newID(), name, meta, summary) step = PlotStep(self, self.host.newID(), name, meta, summary)
self.steps.append(step) self.steps.append(step)
@ -61,17 +82,18 @@ class PlotLine:
class Plots: class Plots:
def __init__(self, path): def __init__(self, path, characters: Characters):
self.file = XmlFile(os.path.join(path, "plots.xml")) self.file = XmlFile(os.path.join(path, "plots.xml"))
self.host = UniqueIDHost() self.host = UniqueIDHost()
self.characters = characters
self.lines = dict() self.lines = dict()
def addLine(self, name: str, importance: Importance = Importance.MINOR): def addLine(self, name: str = None, importance: Importance = Importance.MINOR):
line = PlotLine(self, self.host.newID(), name, importance) line = PlotLine(self, self.host.newID(), name, importance)
self.lines[line.UID.value] = line self.lines[line.UID.value] = line
return line return line
def loadLine(self, ID: int, name: str, importance: Importance = Importance.MINOR): def loadLine(self, ID: int, name: str = None, importance: Importance = Importance.MINOR):
line = PlotLine(self, self.host.loadID(ID), name, importance) line = PlotLine(self, self.host.loadID(ID), name, importance)
self.lines[line.UID.value] = line self.lines[line.UID.value] = line
return line return line
@ -80,6 +102,9 @@ class Plots:
self.host.removeID(line.UID) self.host.removeID(line.UID)
self.lines.pop(line.UID.value) self.lines.pop(line.UID.value)
def getLineByID(self, ID: int) -> PlotLine:
return self.lines.get(ID, None)
def __iter__(self): def __iter__(self):
return self.lines.values().__iter__() return self.lines.values().__iter__()
@ -110,10 +135,13 @@ class Plots:
line.result = element.get("result") line.result = element.get("result")
for characterID in element.get("characters", "").split(','): for characterID in element.get("characters", "").split(','):
#TODO: Character loadings/adding should link to models!
try: try:
line.characters.append(int(characterID)) character = plots.characters.getByID(int(characterID))
if character is None:
continue
line.addCharacterByID(character.UID.value)
except ValueError: except ValueError:
continue continue

View file

@ -30,7 +30,7 @@ class Project:
self.statuses = StatusHost(self.file.dir_path) self.statuses = StatusHost(self.file.dir_path)
self.settings = Settings(self.file.dir_path) self.settings = Settings(self.file.dir_path)
self.characters = Characters(self.file.dir_path) self.characters = Characters(self.file.dir_path)
self.plots = Plots(self.file.dir_path) self.plots = Plots(self.file.dir_path, self.characters)
self.world = World(self.file.dir_path) self.world = World(self.file.dir_path)
self.outline = Outline(self.file.dir_path) self.outline = Outline(self.file.dir_path)
self.revisions = Revisions(self.file.dir_path) self.revisions = Revisions(self.file.dir_path)

View file

@ -66,7 +66,7 @@ class MainWindow:
self.generalView = MainWindow.packViewIntoSlot(builder, "general_slot", GeneralView, self.project.info) self.generalView = MainWindow.packViewIntoSlot(builder, "general_slot", GeneralView, self.project.info)
self.summaryView = MainWindow.packViewIntoSlot(builder, "summary_slot", SummaryView, self.project.summary) 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.characters)
self.plotView = MainWindow.packViewIntoSlot(builder, "plot_slot", PlotView) self.plotView = MainWindow.packViewIntoSlot(builder, "plot_slot", PlotView, self.project.plots)
self.worldView = MainWindow.packViewIntoSlot(builder, "world_slot", WorldView) self.worldView = MainWindow.packViewIntoSlot(builder, "world_slot", WorldView)
self.outlineView = MainWindow.packViewIntoSlot(builder, "outline_slot", OutlineView) self.outlineView = MainWindow.packViewIntoSlot(builder, "outline_slot", OutlineView)
self.editorView = MainWindow.packViewIntoSlot(builder, "editor_slot", EditorView) self.editorView = MainWindow.packViewIntoSlot(builder, "editor_slot", EditorView)

View file

@ -30,7 +30,13 @@ class CharactersView:
self.secondaryCharactersStore = builder.get_object("secondary_characters_store") self.secondaryCharactersStore = builder.get_object("secondary_characters_store")
self.minorCharactersStore = builder.get_object("minor_characters_store") self.minorCharactersStore = builder.get_object("minor_characters_store")
self.filterCharactersBuffer = builder.get_object("filter_characters")
self.filterCharactersBuffer.connect("deleted-text", self.filterCharactersDeletedText)
self.filterCharactersBuffer.connect("inserted-text", self.filterCharactersInsertedText)
self.filteredCharactersStore.set_visible_func(self.filterCharacters) self.filteredCharactersStore.set_visible_func(self.filterCharacters)
self.filteredCharactersStore.refilter()
self.mainCharactersStore.set_visible_func(lambda model, iter, userdata: model[iter][3] == Importance.MAIN.value) self.mainCharactersStore.set_visible_func(lambda model, iter, userdata: model[iter][3] == Importance.MAIN.value)
self.secondaryCharactersStore.set_visible_func(lambda model, iter, userdata: model[iter][3] == Importance.SECONDARY.value) self.secondaryCharactersStore.set_visible_func(lambda model, iter, userdata: model[iter][3] == Importance.SECONDARY.value)
@ -51,14 +57,10 @@ class CharactersView:
self.addCharacterButton = builder.get_object("add_character") self.addCharacterButton = builder.get_object("add_character")
self.removeCharacterButton = builder.get_object("remove_character") self.removeCharacterButton = builder.get_object("remove_character")
self.filterCharactersBuffer = builder.get_object("filter_characters")
self.addCharacterButton.connect("clicked", self.addCharacterClicked) self.addCharacterButton.connect("clicked", self.addCharacterClicked)
self.removeCharacterButton.connect("clicked", self.removeCharacterClicked) self.removeCharacterButton.connect("clicked", self.removeCharacterClicked)
self.filterCharactersBuffer.connect("deleted-text", self.filterCharactersDeletedText)
self.filterCharactersBuffer.connect("inserted-text", self.filterCharactersInsertedText)
self.colorButton = builder.get_object("color") self.colorButton = builder.get_object("color")
self.importanceCombo = builder.get_object("importance") self.importanceCombo = builder.get_object("importance")
self.allowPOVCheck = builder.get_object("allow_POV") self.allowPOVCheck = builder.get_object("allow_POV")
@ -184,11 +186,15 @@ class CharactersView:
self.loadCharacterData(character) self.loadCharacterData(character)
def addCharacterClicked(self, button: Gtk.Button): def addCharacterClicked(self, button: Gtk.Button):
character = self.characters.add() name = invalidString(self.filterCharactersBuffer.get_text())
character = self.characters.add(name)
if character is None: if character is None:
return return
if self.character is not None:
character.importance = self.character.importance
self.refreshCharacterStore() self.refreshCharacterStore()
def removeCharacterClicked(self, button: Gtk.Button): def removeCharacterClicked(self, button: Gtk.Button):
@ -200,9 +206,9 @@ class CharactersView:
def filterCharacters(self, model, iter, userdata): def filterCharacters(self, model, iter, userdata):
name = validString(model[iter][1]) name = validString(model[iter][1])
text = self.filterCharactersBuffer.get_text() text = validString(self.filterCharactersBuffer.get_text())
return text in name return text.lower() in name.lower()
def filterCharactersChanged(self, buffer: Gtk.EntryBuffer): def filterCharactersChanged(self, buffer: Gtk.EntryBuffer):
self.filteredCharactersStore.refilter() self.filteredCharactersStore.refilter()

View file

@ -6,14 +6,248 @@ import gi
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
from gi.repository import Gtk from gi.repository import Gtk
from manuskript.data import Plots, PlotLine, PlotStep, Importance
from manuskript.ui.util import rgbaFromColor, pixbufFromColor
from manuskript.util import validString, invalidString, validInt, invalidInt
class PlotView: class PlotView:
def __init__(self): def __init__(self, plots: Plots):
self.plots = plots
self.plotLine = None
self.plotStep = None
builder = Gtk.Builder() builder = Gtk.Builder()
builder.add_from_file("ui/plot.glade") builder.add_from_file("ui/plot.glade")
self.widget = builder.get_object("plot_view") self.widget = builder.get_object("plot_view")
self.plotsStore = builder.get_object("plots_store")
self.refreshPlotsStore()
self.charactersStore = builder.get_object("characters_store")
self.refreshCharacterStore()
self.filteredPlotsStore = builder.get_object("filtered_plots_store")
self.mainPlotsStore = builder.get_object("main_plots_store")
self.secondaryPlotsStore = builder.get_object("secondary_plots_store")
self.minorPlotsStore = builder.get_object("minor_plots_store")
self.filterPlotsBuffer = builder.get_object("filter_plots")
self.filterPlotsBuffer.connect("deleted-text", self.filterPlotsDeletedText)
self.filterPlotsBuffer.connect("inserted-text", self.filterPlotsInsertedText)
self.filteredPlotsStore.set_visible_func(self.filterPlots)
self.filteredPlotsStore.refilter()
self.mainPlotsStore.set_visible_func(
lambda model, iter, userdata: model[iter][2] == Importance.MAIN.value)
self.secondaryPlotsStore.set_visible_func(
lambda model, iter, userdata: model[iter][2] == Importance.SECONDARY.value)
self.minorPlotsStore.set_visible_func(
lambda model, iter, userdata: model[iter][2] == Importance.MINOR.value)
self.mainPlotsStore.refilter()
self.secondaryPlotsStore.refilter()
self.minorPlotsStore.refilter()
self.plotSelections = [
builder.get_object("minor_plot_selection"),
builder.get_object("secondary_plot_selection"),
builder.get_object("main_plot_selection")
]
for selection in self.plotSelections:
selection.connect("changed", self.plotSelectionChanged)
self.addPlotButton = builder.get_object("add_plot")
self.removePlotButton = builder.get_object("remove_plot")
self.addPlotButton.connect("clicked", self.addPlotClicked)
self.removePlotButton.connect("clicked", self.removePlotClicked)
self.importanceCombo = builder.get_object("importance")
self.nameBuffer = builder.get_object("name")
self.descriptionBuffer = builder.get_object("description")
self.resultBuffer = builder.get_object("result")
self.stepSummaryBuffer = builder.get_object("step_summary")
self.nameBuffer.connect("deleted-text", self.nameDeletedText)
self.nameBuffer.connect("inserted-text", self.nameInsertedText)
self.plotCharactersStore = builder.get_object("plot_characters_store")
self.plotCharactersStore.set_visible_func(self.filterPlotCharacters)
self.plotCharactersStore.refilter()
self.descriptionBuffer.connect("changed", self.descriptionChanged)
self.resultBuffer.connect("changed", self.resultChanged)
self.stepSummaryBuffer.connect("changed", self.stepSummaryChanged)
def refreshPlotsStore(self):
self.plotsStore.clear()
for plotLine in self.plots:
tree_iter = self.plotsStore.append()
if tree_iter is None:
continue
self.plotsStore.set_value(tree_iter, 0, plotLine.UID.value)
self.plotsStore.set_value(tree_iter, 1, validString(plotLine.name))
self.plotsStore.set_value(tree_iter, 2, Importance.asValue(plotLine.importance))
def refreshCharacterStore(self):
self.charactersStore.clear()
for character in self.plots.characters:
tree_iter = self.charactersStore.append()
if tree_iter is None:
continue
self.charactersStore.set_value(tree_iter, 0, character.UID.value)
self.charactersStore.set_value(tree_iter, 1, validString(character.name))
self.charactersStore.set_value(tree_iter, 2, pixbufFromColor(character.color))
def loadPlotData(self, plotLine: PlotLine):
self.plotLine = None
self.importanceCombo.set_active(Importance.asValue(plotLine.importance))
self.nameBuffer.set_text(validString(plotLine.name), -1)
self.descriptionBuffer.set_text(validString(plotLine.description), -1)
self.resultBuffer.set_text(validString(plotLine.result), -1)
self.plotLine = plotLine
self.plotCharactersStore.refilter()
def unloadPlotData(self):
self.plotLine = None
self.nameBuffer.set_text("", -1)
self.descriptionBuffer.set_text("", -1)
self.resultBuffer.set_text("", -1)
self.stepSummaryBuffer.set_text("", -1)
def plotSelectionChanged(self, selection: Gtk.TreeSelection):
model, tree_iter = selection.get_selected()
if tree_iter is None:
self.unloadPlotData()
return
for other in self.plotSelections:
if other != selection:
other.unselect_all()
plotLine = self.plots.getLineByID(model[tree_iter][0])
if plotLine is None:
self.unloadPlotData()
else:
self.loadPlotData(plotLine)
def addPlotClicked(self, button: Gtk.Button):
name = invalidString(self.filterPlotsBuffer.get_text())
plotLine = self.plots.addLine(name)
if plotLine is None:
return
if self.plotLine is not None:
plotLine.importance = self.plotLine.importance
self.refreshPlotsStore()
def removePlotClicked(self, button: Gtk.Button):
if self.plotLine is None:
return
self.plots.removeLine(self.plotLine)
self.refreshPlotsStore()
def filterPlots(self, model, iter, userdata):
name = validString(model[iter][1])
text = validString(self.filterPlotsBuffer.get_text())
return text.lower() in name.lower()
def filterPlotsChanged(self, buffer: Gtk.EntryBuffer):
self.filteredPlotsStore.refilter()
def filterPlotsDeletedText(self, buffer: Gtk.EntryBuffer, position: int, n_chars: int):
self.filterPlotsChanged(buffer)
def filterPlotsInsertedText(self, buffer: Gtk.EntryBuffer, position: int, chars: str, n_chars: int):
self.filterPlotsChanged(buffer)
def nameChanged(self, buffer: Gtk.EntryBuffer):
if self.plotLine is None:
return
text = buffer.get_text()
name = invalidString(text)
self.plotLine.name = name
plot_id = self.plotLine.UID.value
for row in self.plotsStore:
if row[0] == plot_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)
def filterPlotCharacters(self, model, iter, userdata):
ID = validInt(model[iter][0])
if self.plotLine is None:
return False
return ID in self.plotLine.characters
def descriptionChanged(self, buffer: Gtk.TextBuffer):
if self.plotLine is None:
return
start_iter = buffer.get_start_iter()
end_iter = buffer.get_end_iter()
text = buffer.get_text(start_iter, end_iter, False)
self.plotLine.description = invalidString(text)
def resultChanged(self, buffer: Gtk.TextBuffer):
if self.plotLine is None:
return
start_iter = buffer.get_start_iter()
end_iter = buffer.get_end_iter()
text = buffer.get_text(start_iter, end_iter, False)
self.plotLine.result = invalidString(text)
def stepSummaryChanged(self, buffer: Gtk.TextBuffer):
if self.plotStep is None:
return
start_iter = buffer.get_start_iter()
end_iter = buffer.get_end_iter()
text = buffer.get_text(start_iter, end_iter, False)
self.plotStep.summary = invalidString(text)
def show(self): def show(self):
self.widget.show_all() self.widget.show_all()

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 <!-- Generated with glade 3.40.0
Copyright (C) 2015-2021 Olivier Keshavjee et al. Copyright (C) 2015-2021 Olivier Keshavjee et al.
@ -25,23 +25,66 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<!-- interface-name Manuskript --> <!-- interface-name Manuskript -->
<!-- interface-description Manuskript is an open-source tool for writers. --> <!-- interface-description Manuskript is an open-source tool for writers. -->
<!-- interface-copyright 2015-2021 Olivier Keshavjee et al. --> <!-- interface-copyright 2015-2021 Olivier Keshavjee et al. -->
<object class="GtkListStore" id="characters_store">
<columns>
<!-- column-name ID -->
<column type="gint"/>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name color -->
<column type="GdkPixbuf"/>
</columns>
</object>
<object class="GtkTreeModelFilter" id="plot_characters_store">
<property name="child-model">characters_store</property>
</object>
<object class="GtkTextBuffer" id="description"/>
<object class="GtkEntryBuffer" id="filter_plots"/>
<object class="GtkListStore" id="importance_store"> <object class="GtkListStore" id="importance_store">
<columns> <columns>
<!-- column-name name --> <!-- column-name name -->
<column type="gchararray"/> <column type="gchararray"/>
<!-- column-name value -->
<column type="gint"/>
</columns> </columns>
<data> <data>
<row> <row>
<col id="0" translatable="yes">Main</col> <col id="0" translatable="yes">Main</col>
<col id="1">2</col>
</row> </row>
<row> <row>
<col id="0" translatable="yes">Secondary</col> <col id="0" translatable="yes">Secondary</col>
<col id="1">1</col>
</row> </row>
<row> <row>
<col id="0" translatable="yes">Minor</col> <col id="0" translatable="yes">Minor</col>
<col id="1">0</col>
</row> </row>
</data> </data>
</object> </object>
<object class="GtkEntryBuffer" id="name"/>
<object class="GtkListStore" id="plots_store">
<columns>
<!-- column-name ID -->
<column type="gint"/>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name importance -->
<column type="gint"/>
</columns>
</object>
<object class="GtkTreeModelFilter" id="filtered_plots_store">
<property name="child-model">plots_store</property>
</object>
<object class="GtkTreeModelFilter" id="main_plots_store">
<property name="child-model">filtered_plots_store</property>
</object>
<object class="GtkTreeModelFilter" id="minor_plots_store">
<property name="child-model">filtered_plots_store</property>
</object>
<object class="GtkTreeModelFilter" id="secondary_plots_store">
<property name="child-model">filtered_plots_store</property>
</object>
<object class="GtkListStore" id="resolution_steps_store"> <object class="GtkListStore" id="resolution_steps_store">
<columns> <columns>
<!-- column-name name --> <!-- column-name name -->
@ -59,6 +102,8 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</row> </row>
</data> </data>
</object> </object>
<object class="GtkTextBuffer" id="result"/>
<object class="GtkTextBuffer" id="step_summary"/>
<object class="GtkScrolledWindow" id="plot_view"> <object class="GtkScrolledWindow" id="plot_view">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
@ -109,9 +154,24 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkListBox"> <object class="GtkTreeView">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">True</property>
<property name="model">main_plots_store</property>
<property name="headers-visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="main_plot_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -132,9 +192,24 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkListBox"> <object class="GtkTreeView">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">True</property>
<property name="model">secondary_plots_store</property>
<property name="headers-visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="secondary_plot_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -155,12 +230,27 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkListBox"> <object class="GtkTreeView">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">True</property>
<property name="model">minor_plots_store</property>
<property name="headers-visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="minor_plot_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">5</property> <property name="position">5</property>
</packing> </packing>
@ -185,7 +275,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="margin-bottom">8</property> <property name="margin-bottom">8</property>
<property name="spacing">4</property> <property name="spacing">4</property>
<child> <child>
<object class="GtkButton"> <object class="GtkButton" id="add_plot">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
@ -204,7 +294,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButton"> <object class="GtkButton" id="remove_plot">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
@ -226,6 +316,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<object class="GtkEntry"> <object class="GtkEntry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="buffer">filter_plots</property>
<property name="placeholder-text" translatable="yes">Filter</property> <property name="placeholder-text" translatable="yes">Filter</property>
</object> </object>
<packing> <packing>
@ -265,7 +356,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="row-spacing">8</property> <property name="row-spacing">8</property>
<property name="column-spacing">8</property> <property name="column-spacing">8</property>
<child> <child>
<object class="GtkLabel" id="label20"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="valign">start</property> <property name="valign">start</property>
@ -279,7 +370,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label21"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="valign">start</property> <property name="valign">start</property>
@ -306,6 +397,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="wrap-mode">word-char</property> <property name="wrap-mode">word-char</property>
<property name="buffer">result</property>
</object> </object>
</child> </child>
<child type="label_item"> <child type="label_item">
@ -331,6 +423,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="wrap-mode">word-char</property> <property name="wrap-mode">word-char</property>
<property name="buffer">description</property>
</object> </object>
</child> </child>
<child type="label_item"> <child type="label_item">
@ -343,7 +436,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label22"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="valign">start</property> <property name="valign">start</property>
@ -357,7 +450,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label23"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Importance</property> <property name="label" translatable="yes">Importance</property>
@ -369,7 +462,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label24"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Plot</property> <property name="label" translatable="yes">Plot</property>
@ -389,6 +482,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<object class="GtkEntry"> <object class="GtkEntry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="buffer">name</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -396,19 +490,6 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkColorButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">2</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left-attach">1</property>
@ -430,10 +511,31 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="label-xalign">0</property> <property name="label-xalign">0</property>
<property name="label-yalign">0</property> <property name="label-yalign">0</property>
<child> <child>
<object class="GtkListBox"> <object class="GtkTreeView">
<property name="height-request">200</property> <property name="height-request">200</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">True</property>
<property name="model">plot_characters_store</property>
<property name="headers-visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererPixbuf"/>
<attributes>
<attribute name="pixbuf">2</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object> </object>
</child> </child>
<child type="label_item"> <child type="label_item">
@ -508,7 +610,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBox"> <object class="GtkComboBox" id="importance">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="model">importance_store</property> <property name="model">importance_store</property>
@ -616,7 +718,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="spacing">4</property> <property name="spacing">4</property>
<child> <child>
<object class="GtkButton"> <object class="GtkButton" id="add_resolution_step">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
@ -635,7 +737,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButton"> <object class="GtkButton" id="remove_resolution_step">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
@ -709,6 +811,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="wrap-mode">word-char</property> <property name="wrap-mode">word-char</property>
<property name="buffer">step_summary</property>
</object> </object>
</child> </child>
<child type="label_item"> <child type="label_item">