Implement label and status configuration

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
This commit is contained in:
TheJackiMonster 2022-11-18 23:32:08 +01:00
parent d3a2e7f907
commit d2f5290069
No known key found for this signature in database
GPG key ID: D850A5F772E880F9
14 changed files with 300 additions and 36 deletions

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
import collections
import os
from manuskript.data.color import Color
@ -29,10 +30,15 @@ class LabelHost:
def __init__(self, path):
self.file = MmdFile(os.path.join(path, "labels.txt"), 21)
self.labels = dict()
self.labels = collections.OrderedDict()
def addLabel(self, name: str, color: Color):
self.labels[name] = Label(self, name, color)
def addLabel(self, name: str = None, color: Color = None):
if name is None:
name = "New Label"
label = Label(self, name, color)
self.labels[name] = label
return label
def removeLabel(self, name: str):
self.labels.pop(name)
@ -64,7 +70,7 @@ class LabelHost:
self.addLabel(name, Color.parse(value))
def save(self):
metadata = dict()
metadata = collections.OrderedDict()
for (name, label) in self.labels.items():
metadata[name] = label.color

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
import collections
import os
from manuskript.io.textFile import TextFile
@ -27,10 +28,15 @@ class StatusHost:
def __init__(self, path):
self.file = TextFile(os.path.join(path, "status.txt"))
self.statuses = dict()
self.statuses = collections.OrderedDict()
def addStatus(self, name: str):
self.statuses[name] = Status(self, name)
def addStatus(self, name: str = None):
if name is None:
name = "New Status"
status = Status(self, name)
self.statuses[name] = status
return status
def removeStatus(self, name: str):
self.statuses.pop(name)

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
import collections
import os
import re
@ -14,7 +15,7 @@ class MmdFile(AbstractFile):
self.metaSpacing = metaSpacing
def loadMMD(self, ignoreBody: bool = True):
metadata = dict()
metadata = collections.OrderedDict()
body = None
metaPattern = re.compile(r"^([^\s].*?):\s*(.*)\n$")

View file

@ -8,15 +8,124 @@ from gi.repository import Gtk, Handy
Handy.init()
from manuskript.data import Settings
from manuskript.data import Settings, LabelHost, Label, Color
from manuskript.ui.util import rgbaFromColor, pixbufFromColor
class LabelsPage:
def __init__(self, settings: Settings):
def __init__(self, settings: Settings, labels: LabelHost):
self.settings = settings
self.labels = labels
self.label = None
builder = Gtk.Builder()
builder.add_from_file("ui/settings/labels.glade")
self.widget = builder.get_object("labels_page")
self.labelStore = builder.get_object("label_store")
self.refreshLabelStore()
self.labelSelection = builder.get_object("label_selection")
self.labelSelection.connect("changed", self.labelSelectionChanged)
self.addButton = builder.get_object("add_label")
self.removeButton = builder.get_object("remove_label")
self.addButton.connect("clicked", self.addClicked)
self.removeButton.connect("clicked", self.removeClicked)
self.colorButton = builder.get_object("color")
self.colorButton.connect("color-set", self.colorSet)
self.unloadLabelData()
def refreshLabelStore(self):
self.labelStore.clear()
for label in self.labels:
tree_iter = self.labelStore.append()
if tree_iter is None:
continue
self.labelStore.set_value(tree_iter, 0, label.name)
self.labelStore.set_value(tree_iter, 1, pixbufFromColor(label.color))
def loadLabelData(self, label: Label):
self.label = None
self.colorButton.set_rgba(rgbaFromColor(label.color))
self.label = label
self.colorButton.set_sensitive(True)
def unloadLabelData(self):
self.label = None
self.colorButton.set_sensitive(False)
self.colorButton.set_rgba(rgbaFromColor(Color(0, 0, 0)))
def labelSelectionChanged(self, selection: Gtk.TreeSelection):
model, tree_iter = selection.get_selected()
if tree_iter is None:
self.unloadLabelData()
return
label = self.labels.getLabel(model[tree_iter][0])
if label is None:
self.unloadLabelData()
else:
self.loadLabelData(label)
def addClicked(self, button: Gtk.Button):
label = self.labels.addLabel()
if label is None:
return
tree_iter = self.labelStore.append()
if tree_iter is None:
return
self.labelStore.set_value(tree_iter, 0, label.name)
self.labelStore.set_value(tree_iter, 1, pixbufFromColor(label.color))
def removeClicked(self, button: Gtk.Button):
if self.label is None:
return
model, tree_iter = self.labelSelection.get_selected()
if (model is None) or (tree_iter is None):
return
name = model.get_value(tree_iter, 0)
model.remove(tree_iter)
self.labels.removeLabel(name)
def colorSet(self, button: Gtk.ColorButton):
if self.label is None:
return
color = button.get_rgba()
red = int(color.red * 255)
green = int(color.green * 255)
blue = int(color.blue * 255)
color = Color(red, green, blue)
self.label.color = color
character_name = self.label.name
for row in self.labelStore:
if row[0] == character_name:
row[1] = pixbufFromColor(color)
break

View file

@ -8,15 +8,89 @@ from gi.repository import Gtk, Handy
Handy.init()
from manuskript.data import Settings
from manuskript.data import Settings, StatusHost, Status
class StatusPage:
def __init__(self, settings: Settings):
def __init__(self, settings: Settings, statuses: StatusHost):
self.settings = settings
self.statuses = statuses
self.status = None
builder = Gtk.Builder()
builder.add_from_file("ui/settings/status.glade")
self.widget = builder.get_object("status_page")
self.statusStore = builder.get_object("status_store")
self.refreshStatusStore()
self.statusSelection = builder.get_object("status_selection")
self.statusSelection.connect("changed", self.statusSelectionChanged)
self.addButton = builder.get_object("add_status")
self.removeButton = builder.get_object("remove_status")
self.addButton.connect("clicked", self.addClicked)
self.removeButton.connect("clicked", self.removeClicked)
self.unloadStatusData()
def refreshStatusStore(self):
self.statusStore.clear()
for status in self.statuses:
tree_iter = self.statusStore.append()
if tree_iter is None:
continue
self.statusStore.set_value(tree_iter, 0, status.name)
def loadStatusData(self, status: Status):
self.status = status
def unloadStatusData(self):
self.status = None
def statusSelectionChanged(self, selection: Gtk.TreeSelection):
model, tree_iter = selection.get_selected()
if tree_iter is None:
self.unloadStatusData()
return
status = self.statuses.getStatus(model[tree_iter][0])
if status is None:
self.unloadStatusData()
else:
self.loadStatusData(status)
def addClicked(self, button: Gtk.Button):
status = self.statuses.addStatus()
if status is None:
return
tree_iter = self.statusStore.append()
if tree_iter is None:
return
self.statusStore.set_value(tree_iter, 0, status.name)
def removeClicked(self, button: Gtk.Button):
if self.status is None:
return
model, tree_iter = self.statusSelection.get_selected()
if (model is None) or (tree_iter is None):
return
name = model.get_value(tree_iter, 0)
model.remove(tree_iter)
self.statuses.removeStatus(name)

View file

@ -10,19 +10,22 @@ Handy.init()
from manuskript.ui.abstractDialog import AbstractDialog
from manuskript.data import Settings
from manuskript.data import Project, Settings
from manuskript.ui.settings import *
class SettingsWindow(AbstractDialog):
@classmethod
def packPage(cls, window, page_cls, settings: Settings):
def packPage(cls, window, page_cls, settings: Settings, data=None):
if window is None:
return None
try:
page = page_cls(settings)
if data is None:
page = page_cls(settings)
else:
page = page_cls(settings, data)
except Exception as e:
print(e)
return None
@ -44,12 +47,18 @@ class SettingsWindow(AbstractDialog):
self.fullscreenPage = None
def initWindow(self, builder, window):
self.generalPage = SettingsWindow.packPage(window, GeneralPage, self.getSettings())
self.revisionsPage = SettingsWindow.packPage(window, RevisionsPage, self.getSettings())
self.viewsPage = SettingsWindow.packPage(window, ViewsPage, self.getSettings())
self.labelsPage = SettingsWindow.packPage(window, LabelsPage, self.getSettings())
self.statusPage = SettingsWindow.packPage(window, StatusPage, self.getSettings())
self.fullscreenPage = SettingsWindow.packPage(window, FullscreenPage, self.getSettings())
project = self.getProject()
settings = self.getSettings()
self.generalPage = SettingsWindow.packPage(window, GeneralPage, settings)
self.revisionsPage = SettingsWindow.packPage(window, RevisionsPage, settings)
self.viewsPage = SettingsWindow.packPage(window, ViewsPage, settings)
self.labelsPage = SettingsWindow.packPage(window, LabelsPage, settings, project.labels)
self.statusPage = SettingsWindow.packPage(window, StatusPage, settings, project.statuses)
self.fullscreenPage = SettingsWindow.packPage(window, FullscreenPage, settings)
def getSettings(self) -> Settings:
return self.mainWindow.getSettings()
def getProject(self) -> Project:
return self.mainWindow.getProject()

View file

@ -21,6 +21,7 @@ class CharactersView:
builder.add_from_file("ui/characters.glade")
self.widget = builder.get_object("characters_view")
self.notebook = builder.get_object("character_notebook")
self.charactersStore = builder.get_object("characters_store")
self.refreshCharacterStore()
@ -65,7 +66,7 @@ class CharactersView:
self.importanceCombo = builder.get_object("importance")
self.allowPOVCheck = builder.get_object("allow_POV")
self.colorSetSignal = self.colorButton.connect("color-set", self.colorSet)
self.colorButton.connect("color-set", self.colorSet)
self.importanceCombo.connect("changed", self.importanceChanged)
self.allowPOVCheck.connect("toggled", self.allowPOVToggled)
@ -148,9 +149,11 @@ class CharactersView:
self.detailsStore.set_value(tree_iter, 1, validString(value))
self.character = character
self.notebook.set_sensitive(True)
def unloadCharacterData(self):
self.character = None
self.notebook.set_sensitive(False)
self.colorButton.set_rgba(rgbaFromColor(Color(0, 0, 0)))
self.allowPOVCheck.set_active(False)

View file

@ -22,6 +22,7 @@ class PlotView:
builder.add_from_file("ui/plot.glade")
self.widget = builder.get_object("plot_view")
self.notebook = builder.get_object("plot_notebook")
self.plotsStore = builder.get_object("plots_store")
self.refreshPlotsStore()
@ -161,6 +162,7 @@ class PlotView:
self.resolutionStepsStore.set_value(tree_iter, 2, validString(step.meta))
self.plotLine = plotLine
self.notebook.set_sensitive(True)
if self.plotLine is not None:
self.plotLine.links.add(self.__linkActionPlotLine)
@ -173,6 +175,7 @@ class PlotView:
self.plotLine.links.remove(self.__linkActionPlotLine)
self.plotLine = None
self.notebook.set_sensitive(False)
self.nameBuffer.set_text("", -1)
self.descriptionBuffer.set_text("", -1)

View file

@ -20,6 +20,7 @@ class WorldView:
builder.add_from_file("ui/world.glade")
self.widget = builder.get_object("world_view")
self.notebook = builder.get_object("world_notebook")
self.worldTreeView = builder.get_object("world_tree_view")
@ -88,9 +89,11 @@ class WorldView:
self.sourceOfConflictBuffer.set_text(validString(worldItem.conflict), -1)
self.worldItem = worldItem
self.notebook.set_sensitive(True)
def unloadWorldData(self):
self.worldItem = None
self.notebook.set_sensitive(False)
self.nameBuffer.set_text("", -1)
self.descriptionBuffer.set_text("", -1)

View file

@ -344,7 +344,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkNotebook">
<object class="GtkNotebook" id="character_notebook">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>

View file

@ -334,7 +334,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkNotebook">
<object class="GtkNotebook" id="plot_notebook">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>

View file

@ -1,5 +1,5 @@
<?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.
@ -27,6 +27,14 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<!-- interface-name Manuskript -->
<!-- interface-description Manuskript is an open-source tool for writers. -->
<!-- interface-copyright 2015-2021 Olivier Keshavjee et al. -->
<object class="GtkListStore" id="label_store">
<columns>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name color -->
<column type="GdkPixbuf"/>
</columns>
</object>
<object class="HdyPreferencesPage" id="labels_page">
<property name="visible">True</property>
<property name="can-focus">False</property>
@ -68,9 +76,30 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkListBox">
<object class="GtkTreeView">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="can-focus">True</property>
<property name="model">label_store</property>
<property name="headers-visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="label_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererPixbuf"/>
<attributes>
<attribute name="pixbuf">1</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
@ -83,7 +112,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkColorButton">
<object class="GtkColorButton" id="color">
<property name="width-request">48</property>
<property name="height-request">48</property>
<property name="visible">True</property>
@ -113,7 +142,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="valign">start</property>
<property name="spacing">8</property>
<child>
<object class="GtkButton">
<object class="GtkButton" id="add_label">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
@ -132,7 +161,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkButton">
<object class="GtkButton" id="remove_label">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>

View file

@ -1,5 +1,5 @@
<?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.
@ -27,6 +27,12 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<!-- interface-name Manuskript -->
<!-- interface-description Manuskript is an open-source tool for writers. -->
<!-- interface-copyright 2015-2021 Olivier Keshavjee et al. -->
<object class="GtkListStore" id="status_store">
<columns>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
</object>
<object class="HdyPreferencesPage" id="status_page">
<property name="visible">True</property>
<property name="can-focus">False</property>
@ -63,9 +69,24 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkListBox">
<object class="GtkTreeView">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="can-focus">True</property>
<property name="model">status_store</property>
<property name="headers-visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="status_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
@ -85,7 +106,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="valign">start</property>
<property name="spacing">8</property>
<child>
<object class="GtkButton">
<object class="GtkButton" id="add_status">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
@ -104,7 +125,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkButton">
<object class="GtkButton" id="remove_status">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>

View file

@ -179,7 +179,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkNotebook">
<object class="GtkNotebook" id="world_notebook">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>