Merge: adds new file format

This commit is contained in:
Olivier Keshavjee 2016-03-10 14:15:42 +01:00
commit 468e2e0dd7
38 changed files with 2076 additions and 710 deletions

3
.gitignore vendored
View file

@ -10,4 +10,5 @@ ExportTest
icons/Numix icons/Numix
.idea .idea
dist dist
build build
test-projects

View file

@ -1669,7 +1669,7 @@ des lignes:</translation>
</message> </message>
</context> </context>
<context> <context>
<name>outlinePersoDelegate</name> <name>outlineCharacterDelegate</name>
<message> <message>
<location filename="../manuskript/ui/views/outlineDelegates.py" line="126"/> <location filename="../manuskript/ui/views/outlineDelegates.py" line="126"/>
<source>None</source> <source>None</source>

View file

@ -10,7 +10,7 @@ run: $(UIs)
bin/manuskript bin/manuskript
debug: $(UIs) debug: $(UIs)
gdb --args python3 manuskript/main.py gdb --args python3 bin/manuskript
lineprof: lineprof:
kernprof -l -v manuskript/main.py kernprof -l -v manuskript/main.py

View file

@ -9,7 +9,7 @@ from enum import Enum
#def enum(**enums): #def enum(**enums):
#return type(str('Enum'), (), enums) #return type(str('Enum'), (), enums)
class Perso(Enum): class Character(Enum):
name = 0 name = 0
ID = 1 ID = 1
importance = 2 importance = 2
@ -21,20 +21,18 @@ class Perso(Enum):
summaryPara = 8 summaryPara = 8
summaryFull = 9 summaryFull = 9
notes = 10 notes = 10
infoName = 11
infoData = 12
class Plot(Enum): class Plot(Enum):
name = 0 name = 0
ID = 1 ID = 1
importance = 2 importance = 2
persos = 3 characters = 3
description = 4 description = 4
result = 5 result = 5
subplots = 6 steps = 6
summary = 7 summary = 7
class Subplot(Enum): class PlotStep(Enum):
name = 0 name = 0
ID = 1 ID = 1
meta = 2 meta = 2
@ -66,4 +64,3 @@ class Outline(Enum):
# (sum of all sub-items' goals) # (sum of all sub-items' goals)
textFormat = 15 textFormat = 15
revisions = 16 revisions = 16

View file

@ -121,9 +121,9 @@ def outlineItemColors(item):
# POV # POV
colors["POV"] = QColor(Qt.transparent) colors["POV"] = QColor(Qt.transparent)
POV = item.data(Outline.POV.value) POV = item.data(Outline.POV.value)
for i in range(mw.mdlPersos.rowCount()): for i in range(mw.mdlCharacter.rowCount()):
if mw.mdlPersos.ID(i) == POV: if mw.mdlCharacter.ID(i) == POV:
colors["POV"] = iconColor(mw.mdlPersos.icon(i)) colors["POV"] = iconColor(mw.mdlCharacter.icon(i))
# Label # Label
lbl = item.data(Outline.label.value) lbl = item.data(Outline.label.value)
@ -179,6 +179,10 @@ def allPaths(suffix=None):
return paths return paths
def lightBlue(): def lightBlue():
"""
A light blue used in several places in manuskript.
@return: QColor
"""
return QColor(Qt.blue).lighter(190) return QColor(Qt.blue).lighter(190)
def totalObjects(): def totalObjects():

View file

@ -1,149 +1,58 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
# The loadSave file calls the propper functions to load and save file
# trying to detect the proper file format if it comes from an older version
import os
import zipfile import zipfile
from PyQt5.QtCore import QModelIndex, Qt import manuskript.load_save.version_0 as v0
from PyQt5.QtGui import QColor, QStandardItem import manuskript.load_save.version_1 as v1
from PyQt5.QtWidgets import qApp
from lxml import etree as ET
from manuskript.functions import iconColor, iconFromColorString
try: def saveProject(version=None):
import zlib # Used with zipfile for compression
compression = zipfile.ZIP_DEFLATED
except:
compression = zipfile.ZIP_STORED
def saveFilesToZip(files, zipname): # While debugging, we don't save the project
"""Saves given files to zipname. # return
files is actually a list of (content, filename)."""
if version == 0:
zf = zipfile.ZipFile(zipname, mode="w") v0.saveProject()
for content, filename in files:
zf.writestr(filename, content, compress_type=compression)
zf.close()
def loadFilesFromZip(zipname):
"""Returns the content of zipfile as a dict of filename:content."""
print(zipname)
zf = zipfile.ZipFile(zipname)
files = {}
for f in zf.namelist():
files[f] = zf.read(f)
return files
def saveStandardItemModelXML(mdl, xml=None):
"""Saves the given QStandardItemModel to XML.
If xml (filename) is given, saves to xml. Otherwise returns as string."""
root = ET.Element("model")
root.attrib["version"] = qApp.applicationVersion()
# Header
header = ET.SubElement(root, "header")
vHeader = ET.SubElement(header, "vertical")
for x in range(mdl.rowCount()):
vH = ET.SubElement(vHeader, "label")
vH.attrib["row"] = str(x)
vH.attrib["text"] = str(mdl.headerData(x, Qt.Vertical))
hHeader = ET.SubElement(header, "horizontal")
for y in range(mdl.columnCount()):
hH = ET.SubElement(hHeader, "label")
hH.attrib["row"] = str(y)
hH.attrib["text"] = str(mdl.headerData(y, Qt.Horizontal))
# Data
data = ET.SubElement(root, "data")
saveItem(data, mdl)
#print(qApp.tr("Saving to {}.").format(xml))
if xml:
ET.ElementTree(root).write(xml, encoding="UTF-8", xml_declaration=True, pretty_print=True)
else: else:
return ET.tostring(root, encoding="UTF-8", xml_declaration=True, pretty_print=True) v1.saveProject()
def saveItem(root, mdl, parent=QModelIndex()): # FIXME: add settings to chose between saving as zip or not.
for x in range(mdl.rowCount(parent)):
row = ET.SubElement(root, "row")
row.attrib["row"] = str(x) def loadProject(project):
for y in range(mdl.columnCount(parent)): # Detect version
col = ET.SubElement(row, "col") isZip = False
col.attrib["col"] = str(y) version = 0
if mdl.data(mdl.index(x, y, parent), Qt.DecorationRole) != None:
color = iconColor(mdl.data(mdl.index(x, y, parent), Qt.DecorationRole)).name(QColor.HexArgb) # Is it a zip?
col.attrib["color"] = color if color != "#ff000000" else "#00000000" try:
if mdl.data(mdl.index(x, y, parent)) != "": zf = zipfile.ZipFile(project)
col.text = mdl.data(mdl.index(x, y, parent)) isZip = True
if mdl.hasChildren(mdl.index(x, y, parent)): except zipfile.BadZipFile:
saveItem(col, mdl, mdl.index(x, y, parent)) isZip = False
def loadStandardItemModelXML(mdl, xml, fromString=False): # Does it have a VERSION in zip root?
"""Load data to a QStandardItemModel mdl from xml. if isZip and "VERSION" in zf.namelist():
By default xml is a filename. If fromString=True, xml is a string containg the data.""" version = int(zf.read("VERSION"))
#print(qApp.tr("Loading {}... ").format(xml), end="") # Zip but no VERSION: oldest file format
elif isZip:
if not fromString: version = 0
try:
tree = ET.parse(xml) # Not a zip
except:
print("Failed.")
return
else: else:
root = ET.fromstring(xml) with open(project, "r") as f:
version = int(f.read())
#root = tree.getroot()
print("Loading:", project)
#Header print("Detected file format version: {}. Zip: {}.".format(version, isZip))
hLabels = []
vLabels = [] if version == 0:
for l in root.find("header").find("horizontal").findall("label"): v0.loadProject(project)
hLabels.append(l.attrib["text"]) else:
for l in root.find("header").find("vertical").findall("label"): v1.loadProject(project, zip=isZip)
vLabels.append(l.attrib["text"])
#print(root.find("header").find("vertical").text)
#mdl.setVerticalHeaderLabels(vLabels)
#mdl.setHorizontalHeaderLabels(hLabels)
# Populates with empty items
for i in enumerate(vLabels):
row = []
for r in enumerate(hLabels):
row.append(QStandardItem())
mdl.appendRow(row)
#Data
data = root.find("data")
loadItem(data, mdl)
return True
def loadItem(root, mdl, parent=QModelIndex()):
for row in root:
r = int(row.attrib["row"])
for col in row:
c = int(col.attrib["col"])
item = mdl.itemFromIndex(mdl.index(r, c, parent))
if not item:
item = QStandardItem()
mdl.itemFromIndex(parent).setChild(r, c, item)
if col.text:
#mdl.setData(mdl.index(r, c, parent), col.text)
item.setText(col.text)
if "color" in col.attrib:
#mdl.itemFromIndex(mdl.index(r, c, parent)).setIcon(iconFromColorString(col.attrib["color"]))
item.setIcon(iconFromColorString(col.attrib["color"]))
if len(col) != 0:
#loadItem(col, mdl, mdl.index(r, c, parent))
loadItem(col, mdl, mdl.indexFromItem(item))

View file

View file

@ -0,0 +1,289 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
# Version 0 of file saving format.
# Was used at the begining and up util version XXX when
# it was superseded by Version 1, which is more open and flexible
import zipfile
from PyQt5.QtCore import QModelIndex, Qt
from PyQt5.QtGui import QColor, QStandardItem
from PyQt5.QtWidgets import qApp
from lxml import etree as ET
from manuskript import settings
from manuskript.functions import iconColor, iconFromColorString, mainWindow
from manuskript.models.characterModel import Character, CharacterInfo
try:
import zlib # Used with zipfile for compression
compression = zipfile.ZIP_DEFLATED
except:
compression = zipfile.ZIP_STORED
###########################################################################################
# SAVE
###########################################################################################
def saveProject():
"""
Saves the whole project. Call this function to save the project in Version 0 format.
"""
files = []
mw = mainWindow()
files.append((saveStandardItemModelXML(mw.mdlFlatData),
"flatModel.xml"))
print("ERROR: file format 0 does not save characters !")
# files.append((saveStandardItemModelXML(mw.mdlCharacter),
# "perso.xml"))
files.append((saveStandardItemModelXML(mw.mdlWorld),
"world.xml"))
files.append((saveStandardItemModelXML(mw.mdlLabels),
"labels.xml"))
files.append((saveStandardItemModelXML(mw.mdlStatus),
"status.xml"))
files.append((saveStandardItemModelXML(mw.mdlPlots),
"plots.xml"))
files.append((mw.mdlOutline.saveToXML(),
"outline.xml"))
files.append((settings.save(),
"settings.pickle"))
saveFilesToZip(files, mw.currentProject)
def saveFilesToZip(files, zipname):
"""Saves given files to zipname.
files is actually a list of (content, filename)."""
zf = zipfile.ZipFile(zipname, mode="w")
for content, filename in files:
zf.writestr(filename, content, compress_type=compression)
zf.close()
def saveStandardItemModelXML(mdl, xml=None):
"""Saves the given QStandardItemModel to XML.
If xml (filename) is given, saves to xml. Otherwise returns as string."""
root = ET.Element("model")
root.attrib["version"] = qApp.applicationVersion()
# Header
header = ET.SubElement(root, "header")
vHeader = ET.SubElement(header, "vertical")
for x in range(mdl.rowCount()):
vH = ET.SubElement(vHeader, "label")
vH.attrib["row"] = str(x)
vH.attrib["text"] = str(mdl.headerData(x, Qt.Vertical))
hHeader = ET.SubElement(header, "horizontal")
for y in range(mdl.columnCount()):
hH = ET.SubElement(hHeader, "label")
hH.attrib["row"] = str(y)
hH.attrib["text"] = str(mdl.headerData(y, Qt.Horizontal))
# Data
data = ET.SubElement(root, "data")
saveItem(data, mdl)
# print(qApp.tr("Saving to {}.").format(xml))
if xml:
ET.ElementTree(root).write(xml, encoding="UTF-8", xml_declaration=True, pretty_print=True)
else:
return ET.tostring(root, encoding="UTF-8", xml_declaration=True, pretty_print=True)
def saveItem(root, mdl, parent=QModelIndex()):
for x in range(mdl.rowCount(parent)):
row = ET.SubElement(root, "row")
row.attrib["row"] = str(x)
for y in range(mdl.columnCount(parent)):
col = ET.SubElement(row, "col")
col.attrib["col"] = str(y)
if mdl.data(mdl.index(x, y, parent), Qt.DecorationRole) != None:
color = iconColor(mdl.data(mdl.index(x, y, parent), Qt.DecorationRole)).name(QColor.HexArgb)
col.attrib["color"] = color if color != "#ff000000" else "#00000000"
if mdl.data(mdl.index(x, y, parent)) != "":
col.text = mdl.data(mdl.index(x, y, parent))
if mdl.hasChildren(mdl.index(x, y, parent)):
saveItem(col, mdl, mdl.index(x, y, parent))
###########################################################################################
# LOAD
###########################################################################################
def loadProject(project):
files = loadFilesFromZip(project)
mw = mainWindow()
errors = []
if "flatModel.xml" in files:
loadStandardItemModelXML(mw.mdlFlatData,
files["flatModel.xml"], fromString=True)
else:
errors.append("flatModel.xml")
if "perso.xml" in files:
loadStandardItemModelXMLForCharacters(mw.mdlCharacter, files["perso.xml"])
else:
errors.append("perso.xml")
if "world.xml" in files:
loadStandardItemModelXML(mw.mdlWorld,
files["world.xml"], fromString=True)
else:
errors.append("world.xml")
if "labels.xml" in files:
loadStandardItemModelXML(mw.mdlLabels,
files["labels.xml"], fromString=True)
else:
errors.append("labels.xml")
if "status.xml" in files:
loadStandardItemModelXML(mw.mdlStatus,
files["status.xml"], fromString=True)
else:
errors.append("status.xml")
if "plots.xml" in files:
loadStandardItemModelXML(mw.mdlPlots,
files["plots.xml"], fromString=True)
else:
errors.append("plots.xml")
if "outline.xml" in files:
mw.mdlOutline.loadFromXML(files["outline.xml"], fromString=True)
else:
errors.append("outline.xml")
if "settings.pickle" in files:
settings.load(files["settings.pickle"], fromString=True)
else:
errors.append("settings.pickle")
return errors
def loadFilesFromZip(zipname):
"""Returns the content of zipfile as a dict of filename:content."""
zf = zipfile.ZipFile(zipname)
files = {}
for f in zf.namelist():
files[f] = zf.read(f)
return files
def loadStandardItemModelXML(mdl, xml, fromString=False):
"""Load data to a QStandardItemModel mdl from xml.
By default xml is a filename. If fromString=True, xml is a string containg the data."""
# print(qApp.tr("Loading {}... ").format(xml), end="")
if not fromString:
try:
tree = ET.parse(xml)
except:
print("Failed.")
return
else:
root = ET.fromstring(xml)
# root = tree.getroot()
# Header
hLabels = []
vLabels = []
for l in root.find("header").find("horizontal").findall("label"):
hLabels.append(l.attrib["text"])
for l in root.find("header").find("vertical").findall("label"):
vLabels.append(l.attrib["text"])
# print(root.find("header").find("vertical").text)
# mdl.setVerticalHeaderLabels(vLabels)
# mdl.setHorizontalHeaderLabels(hLabels)
# Populates with empty items
for i in enumerate(vLabels):
row = []
for r in enumerate(hLabels):
row.append(QStandardItem())
mdl.appendRow(row)
# Data
data = root.find("data")
loadItem(data, mdl)
return True
def loadItem(root, mdl, parent=QModelIndex()):
for row in root:
r = int(row.attrib["row"])
for col in row:
c = int(col.attrib["col"])
item = mdl.itemFromIndex(mdl.index(r, c, parent))
if not item:
item = QStandardItem()
mdl.itemFromIndex(parent).setChild(r, c, item)
if col.text:
# mdl.setData(mdl.index(r, c, parent), col.text)
item.setText(col.text)
if "color" in col.attrib:
# mdl.itemFromIndex(mdl.index(r, c, parent)).setIcon(iconFromColorString(col.attrib["color"]))
item.setIcon(iconFromColorString(col.attrib["color"]))
if len(col) != 0:
# loadItem(col, mdl, mdl.index(r, c, parent))
loadItem(col, mdl, mdl.indexFromItem(item))
def loadStandardItemModelXMLForCharacters(mdl, xml):
"""
Loads a standardItemModel saved to XML by version 0, but for the new characterModel.
@param mdl: characterModel
@param xml: the content of the xml
@return: nothing
"""
mdl = mainWindow().mdlCharacter
root = ET.fromstring(xml)
data = root.find("data")
for row in data:
char = Character(mdl)
for col in row:
c = int(col.attrib["col"])
# Value
if col.text:
char._data[c] = col.text
# Color
if "color" in col.attrib:
char.setColor(QColor(col.attrib["color"]))
# Infos
if len(col) != 0:
for rrow in col:
info = CharacterInfo(char)
for ccol in rrow:
cc = int(ccol.attrib["col"])
if cc == 11 and ccol.text:
info.description = ccol.text
if cc == 12 and ccol.text:
info.value = ccol.text
char.infos.append(info)
mdl.characters.append(char)

File diff suppressed because it is too large Load diff

View file

@ -9,13 +9,11 @@ from PyQt5.QtWidgets import QMainWindow, QHeaderView, qApp, QMenu, QActionGroup,
QLabel QLabel
from manuskript import settings from manuskript import settings
from manuskript.enums import Perso, Subplot, Plot, World from manuskript.enums import Character, PlotStep, Plot, World
from manuskript.functions import AUC, wordCount, appPath from manuskript.functions import AUC, wordCount, appPath
from manuskript.loadSave import loadStandardItemModelXML, loadFilesFromZip from manuskript.loadSave import saveProject, loadProject
from manuskript.loadSave import saveFilesToZip from manuskript.models.characterModel import characterModel
from manuskript.loadSave import saveStandardItemModelXML
from manuskript.models.outlineModel import outlineModel from manuskript.models.outlineModel import outlineModel
from manuskript.models.persosModel import persosModel
from manuskript.models.plotModel import plotModel from manuskript.models.plotModel import plotModel
from manuskript.models.worldModel import worldModel from manuskript.models.worldModel import worldModel
from manuskript.settingsWindow import settingsWindow from manuskript.settingsWindow import settingsWindow
@ -24,7 +22,7 @@ from manuskript.ui.compileDialog import compileDialog
from manuskript.ui.helpLabel import helpLabel from manuskript.ui.helpLabel import helpLabel
from manuskript.ui.mainWindow import Ui_MainWindow from manuskript.ui.mainWindow import Ui_MainWindow
from manuskript.ui.tools.frequencyAnalyzer import frequencyAnalyzer from manuskript.ui.tools.frequencyAnalyzer import frequencyAnalyzer
from manuskript.ui.views.outlineDelegates import outlinePersoDelegate from manuskript.ui.views.outlineDelegates import outlineCharacterDelegate
from manuskript.ui.views.plotDelegate import plotDelegate from manuskript.ui.views.plotDelegate import plotDelegate
# Spellcheck support # Spellcheck support
@ -144,15 +142,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# PERSOS # PERSOS
############################################################################### ###############################################################################
def changeCurrentPerso(self, trash=None): def changeCurrentCharacter(self, trash=None):
"""
index = self.lstPersos.currentPersoIndex() @return:
"""
if not index.isValid(): c = self.lstCharacters.currentCharacter()
if not c:
self.tabPlot.setEnabled(False) self.tabPlot.setEnabled(False)
return return
self.tabPersos.setEnabled(True) self.tabPersos.setEnabled(True)
index = c.index()
for w in [ for w in [
self.txtPersoName, self.txtPersoName,
@ -169,27 +170,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
w.setCurrentModelIndex(index) w.setCurrentModelIndex(index)
# Button color # Button color
self.mdlPersos.updatePersoColor(index) self.updateCharacterColor(c.ID())
# Perso Infos # Character Infos
self.tblPersoInfos.setRootIndex(index) self.tblPersoInfos.setRootIndex(index)
if self.mdlPersos.rowCount(index): if self.mdlCharacter.rowCount(index):
self.updatePersoInfoView() self.updatePersoInfoView()
def updatePersoInfoView(self): def updatePersoInfoView(self):
# Hide columns self.tblPersoInfos.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
for i in range(self.mdlPersos.columnCount()): self.tblPersoInfos.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.tblPersoInfos.hideColumn(i)
self.tblPersoInfos.showColumn(Perso.infoName.value)
self.tblPersoInfos.showColumn(Perso.infoData.value)
self.tblPersoInfos.horizontalHeader().setSectionResizeMode(
Perso.infoName.value, QHeaderView.ResizeToContents)
self.tblPersoInfos.horizontalHeader().setSectionResizeMode(
Perso.infoData.value, QHeaderView.Stretch)
self.tblPersoInfos.verticalHeader().hide() self.tblPersoInfos.verticalHeader().hide()
def updateCharacterColor(self, ID):
c = self.mdlCharacter.getCharacterByID(ID)
color = c.color().name()
self.btnPersoColor.setStyleSheet("background:{};".format(color))
############################################################################### ###############################################################################
# PLOTS # PLOTS
############################################################################### ###############################################################################
@ -207,8 +205,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.txtPlotResult.setCurrentModelIndex(index) self.txtPlotResult.setCurrentModelIndex(index)
self.sldPlotImportance.setCurrentModelIndex(index) self.sldPlotImportance.setCurrentModelIndex(index)
self.lstPlotPerso.setRootIndex(index.sibling(index.row(), self.lstPlotPerso.setRootIndex(index.sibling(index.row(),
Plot.persos.value)) Plot.characters.value))
subplotindex = index.sibling(index.row(), Plot.subplots.value) subplotindex = index.sibling(index.row(), Plot.steps.value)
self.lstSubPlots.setRootIndex(subplotindex) self.lstSubPlots.setRootIndex(subplotindex)
if self.mdlPlots.rowCount(subplotindex): if self.mdlPlots.rowCount(subplotindex):
self.updateSubPlotView() self.updateSubPlotView()
@ -224,18 +222,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Hide columns # Hide columns
for i in range(self.mdlPlots.columnCount()): for i in range(self.mdlPlots.columnCount()):
self.lstSubPlots.hideColumn(i) self.lstSubPlots.hideColumn(i)
self.lstSubPlots.showColumn(Subplot.name.value) self.lstSubPlots.showColumn(PlotStep.name.value)
self.lstSubPlots.showColumn(Subplot.meta.value) self.lstSubPlots.showColumn(PlotStep.meta.value)
self.lstSubPlots.horizontalHeader().setSectionResizeMode( self.lstSubPlots.horizontalHeader().setSectionResizeMode(
Subplot.name.value, QHeaderView.Stretch) PlotStep.name.value, QHeaderView.Stretch)
self.lstSubPlots.horizontalHeader().setSectionResizeMode( self.lstSubPlots.horizontalHeader().setSectionResizeMode(
Subplot.meta.value, QHeaderView.ResizeToContents) PlotStep.meta.value, QHeaderView.ResizeToContents)
self.lstSubPlots.verticalHeader().hide() self.lstSubPlots.verticalHeader().hide()
def changeCurrentSubPlot(self, index): def changeCurrentSubPlot(self, index):
# Got segfaults when using textEditView model system, so ad hoc stuff. # Got segfaults when using textEditView model system, so ad hoc stuff.
index = index.sibling(index.row(), Subplot.summary.value) index = index.sibling(index.row(), PlotStep.summary.value)
item = self.mdlPlots.itemFromIndex(index) item = self.mdlPlots.itemFromIndex(index)
if not item: if not item:
self.txtSubPlotSummary.setEnabled(False) self.txtSubPlotSummary.setEnabled(False)
@ -253,7 +251,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
index = self.lstSubPlots.currentIndex() index = self.lstSubPlots.currentIndex()
if not index.isValid(): if not index.isValid():
return return
index = index.sibling(index.row(), Subplot.summary.value) index = index.sibling(index.row(), PlotStep.summary.value)
item = self.mdlPlots.itemFromIndex(index) item = self.mdlPlots.itemFromIndex(index)
self._updatingSubPlot = True self._updatingSubPlot = True
@ -310,7 +308,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Load settings # Load settings
for i in settings.openIndexes: for i in settings.openIndexes:
idx = self.mdlOutline.indexFromPath(i) idx = self.mdlOutline.getIndexByID(i)
self.mainEditor.setCurrentModelIndex(idx, newTab=True) self.mainEditor.setCurrentModelIndex(idx, newTab=True)
self.generateViewMenu() self.generateViewMenu()
self.mainEditor.sldCorkSizeFactor.setValue(settings.corkSizeFactor) self.mainEditor.sldCorkSizeFactor.setValue(settings.corkSizeFactor)
@ -340,7 +338,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.saveTimerNoChanges.setSingleShot(True) self.saveTimerNoChanges.setSingleShot(True)
self.mdlFlatData.dataChanged.connect(self.startTimerNoChanges) self.mdlFlatData.dataChanged.connect(self.startTimerNoChanges)
self.mdlOutline.dataChanged.connect(self.startTimerNoChanges) self.mdlOutline.dataChanged.connect(self.startTimerNoChanges)
self.mdlPersos.dataChanged.connect(self.startTimerNoChanges) self.mdlCharacter.dataChanged.connect(self.startTimerNoChanges)
self.mdlPlots.dataChanged.connect(self.startTimerNoChanges) self.mdlPlots.dataChanged.connect(self.startTimerNoChanges)
self.mdlWorld.dataChanged.connect(self.startTimerNoChanges) self.mdlWorld.dataChanged.connect(self.startTimerNoChanges)
# self.mdlPersosInfos.dataChanged.connect(self.startTimerNoChanges) # self.mdlPersosInfos.dataChanged.connect(self.startTimerNoChanges)
@ -434,10 +432,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
settings.lastTab = self.tabMain.currentIndex() settings.lastTab = self.tabMain.currentIndex()
if self.currentProject: if self.currentProject:
# Remembering the current items # Remembering the current items (stores outlineItem's ID)
sel = [] sel = []
for i in range(self.mainEditor.tab.count()): for i in range(self.mainEditor.tab.count()):
sel.append(self.mdlOutline.pathToIndex(self.mainEditor.tab.widget(i).currentIndex)) sel.append(self.mdlOutline.ID(self.mainEditor.tab.widget(i).currentIndex))
settings.openIndexes = sel settings.openIndexes = sel
# Save data from models # Save data from models
@ -462,27 +460,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.currentProject = projectName self.currentProject = projectName
QSettings().setValue("lastProject", projectName) QSettings().setValue("lastProject", projectName)
# Saving saveProject() # version=0
files = [] self.saveTimerNoChanges.stop()
files.append((saveStandardItemModelXML(self.mdlFlatData),
"flatModel.xml"))
files.append((saveStandardItemModelXML(self.mdlPersos),
"perso.xml"))
files.append((saveStandardItemModelXML(self.mdlWorld),
"world.xml"))
files.append((saveStandardItemModelXML(self.mdlLabels),
"labels.xml"))
files.append((saveStandardItemModelXML(self.mdlStatus),
"status.xml"))
files.append((saveStandardItemModelXML(self.mdlPlots),
"plots.xml"))
files.append((self.mdlOutline.saveToXML(),
"outline.xml"))
files.append((settings.save(),
"settings.pickle"))
saveFilesToZip(files, self.currentProject)
# Giving some feedback # Giving some feedback
print(self.tr("Project {} saved.").format(self.currentProject)) print(self.tr("Project {} saved.").format(self.currentProject))
@ -491,7 +470,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def loadEmptyDatas(self): def loadEmptyDatas(self):
self.mdlFlatData = QStandardItemModel(self) self.mdlFlatData = QStandardItemModel(self)
self.mdlPersos = persosModel(self) self.mdlCharacter = characterModel(self)
# self.mdlPersosProxy = persosProxyModel(self) # self.mdlPersosProxy = persosProxyModel(self)
# self.mdlPersosInfos = QStandardItemModel(self) # self.mdlPersosInfos = QStandardItemModel(self)
self.mdlLabels = QStandardItemModel(self) self.mdlLabels = QStandardItemModel(self)
@ -501,56 +480,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.mdlWorld = worldModel(self) self.mdlWorld = worldModel(self)
def loadDatas(self, project): def loadDatas(self, project):
# Loading
files = loadFilesFromZip(project)
errors = [] errors = loadProject(project)
if "flatModel.xml" in files:
loadStandardItemModelXML(self.mdlFlatData,
files["flatModel.xml"], fromString=True)
else:
errors.append("flatModel.xml")
if "perso.xml" in files:
loadStandardItemModelXML(self.mdlPersos,
files["perso.xml"], fromString=True)
else:
errors.append("perso.xml")
if "world.xml" in files:
loadStandardItemModelXML(self.mdlWorld,
files["world.xml"], fromString=True)
else:
errors.append("world.xml")
if "labels.xml" in files:
loadStandardItemModelXML(self.mdlLabels,
files["labels.xml"], fromString=True)
else:
errors.append("perso.xml")
if "status.xml" in files:
loadStandardItemModelXML(self.mdlStatus,
files["status.xml"], fromString=True)
else:
errors.append("perso.xml")
if "plots.xml" in files:
loadStandardItemModelXML(self.mdlPlots,
files["plots.xml"], fromString=True)
else:
errors.append("perso.xml")
if "outline.xml" in files:
self.mdlOutline.loadFromXML(files["outline.xml"], fromString=True)
else:
errors.append("perso.xml")
if "settings.pickle" in files:
settings.load(files["settings.pickle"], fromString=True)
else:
errors.append("perso.xml")
# Giving some feedback # Giving some feedback
if not errors: if not errors:
@ -570,7 +501,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def makeUIConnections(self): def makeUIConnections(self):
"Connections that have to be made once only, event when new project is loaded." "Connections that have to be made once only, event when new project is loaded."
self.lstPersos.currentItemChanged.connect(self.changeCurrentPerso, AUC) self.lstCharacters.currentItemChanged.connect(self.changeCurrentCharacter, AUC)
self.txtPlotFilter.textChanged.connect(self.lstPlots.setFilter, AUC) self.txtPlotFilter.textChanged.connect(self.lstPlots.setFilter, AUC)
self.lstPlots.currentItemChanged.connect(self.changeCurrentPlot, AUC) self.lstPlots.currentItemChanged.connect(self.changeCurrentPlot, AUC)
@ -622,29 +553,32 @@ class MainWindow(QMainWindow, Ui_MainWindow):
widget.setCurrentModelIndex(self.mdlFlatData.index(0, col)) widget.setCurrentModelIndex(self.mdlFlatData.index(0, col))
# Persos # Persos
self.lstPersos.setPersosModel(self.mdlPersos) self.lstCharacters.setCharactersModel(self.mdlCharacter)
self.tblPersoInfos.setModel(self.mdlPersos) self.tblPersoInfos.setModel(self.mdlCharacter)
self.btnAddPerso.clicked.connect(self.mdlPersos.addPerso, AUC) self.btnAddPerso.clicked.connect(self.mdlCharacter.addCharacter, AUC)
self.btnRmPerso.clicked.connect(self.mdlPersos.removePerso, AUC) try:
self.btnPersoColor.clicked.connect(self.mdlPersos.chosePersoColor, AUC) self.btnRmPerso.clicked.connect(self.lstCharacters.removeCharacter, AUC)
self.btnPersoColor.clicked.connect(self.lstCharacters.choseCharacterColor, AUC)
self.btnPersoAddInfo.clicked.connect(self.mdlPersos.addPersoInfo, AUC) self.btnPersoAddInfo.clicked.connect(self.lstCharacters.addCharacterInfo, AUC)
self.btnPersoRmInfo.clicked.connect(self.mdlPersos.removePersoInfo, AUC) self.btnPersoRmInfo.clicked.connect(self.lstCharacters.removeCharacterInfo, AUC)
except TypeError:
# Connection has already been made
pass
for w, c in [ for w, c in [
(self.txtPersoName, Perso.name.value), (self.txtPersoName, Character.name.value),
(self.sldPersoImportance, Perso.importance.value), (self.sldPersoImportance, Character.importance.value),
(self.txtPersoMotivation, Perso.motivation.value), (self.txtPersoMotivation, Character.motivation.value),
(self.txtPersoGoal, Perso.goal.value), (self.txtPersoGoal, Character.goal.value),
(self.txtPersoConflict, Perso.conflict.value), (self.txtPersoConflict, Character.conflict.value),
(self.txtPersoEpiphany, Perso.epiphany.value), (self.txtPersoEpiphany, Character.epiphany.value),
(self.txtPersoSummarySentence, Perso.summarySentence.value), (self.txtPersoSummarySentence, Character.summarySentence.value),
(self.txtPersoSummaryPara, Perso.summaryPara.value), (self.txtPersoSummaryPara, Character.summaryPara.value),
(self.txtPersoSummaryFull, Perso.summaryFull.value), (self.txtPersoSummaryFull, Character.summaryFull.value),
(self.txtPersoNotes, Perso.notes.value) (self.txtPersoNotes, Character.notes.value)
]: ]:
w.setModel(self.mdlPersos) w.setModel(self.mdlCharacter)
w.setColumn(c) w.setColumn(c)
self.tabPersos.setEnabled(False) self.tabPersos.setEnabled(False)
@ -672,13 +606,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.tabPlot.setEnabled(False) self.tabPlot.setEnabled(False)
self.mdlPlots.updatePlotPersoButton() self.mdlPlots.updatePlotPersoButton()
self.mdlPersos.dataChanged.connect(self.mdlPlots.updatePlotPersoButton) self.mdlCharacter.dataChanged.connect(self.mdlPlots.updatePlotPersoButton)
self.lstOutlinePlots.setPlotModel(self.mdlPlots) self.lstOutlinePlots.setPlotModel(self.mdlPlots)
self.lstOutlinePlots.setShowSubPlot(True) self.lstOutlinePlots.setShowSubPlot(True)
self.plotPersoDelegate = outlinePersoDelegate(self.mdlPersos, self) self.plotCharacterDelegate = outlineCharacterDelegate(self.mdlCharacter, self)
self.lstPlotPerso.setItemDelegate(self.plotPersoDelegate) self.lstPlotPerso.setItemDelegate(self.plotCharacterDelegate)
self.plotDelegate = plotDelegate(self) self.plotDelegate = plotDelegate(self)
self.lstSubPlots.setItemDelegateForColumn(Subplot.meta.value, self.plotDelegate) self.lstSubPlots.setItemDelegateForColumn(PlotStep.meta.value, self.plotDelegate)
# World # World
self.treeWorld.setModel(self.mdlWorld) self.treeWorld.setModel(self.mdlWorld)
@ -702,18 +636,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Outline # Outline
self.treeRedacOutline.setModel(self.mdlOutline) self.treeRedacOutline.setModel(self.mdlOutline)
self.treeOutlineOutline.setModelPersos(self.mdlPersos) self.treeOutlineOutline.setModelCharacters(self.mdlCharacter)
self.treeOutlineOutline.setModelLabels(self.mdlLabels) self.treeOutlineOutline.setModelLabels(self.mdlLabels)
self.treeOutlineOutline.setModelStatus(self.mdlStatus) self.treeOutlineOutline.setModelStatus(self.mdlStatus)
self.redacMetadata.setModels(self.mdlOutline, self.mdlPersos, self.redacMetadata.setModels(self.mdlOutline, self.mdlCharacter,
self.mdlLabels, self.mdlStatus) self.mdlLabels, self.mdlStatus)
self.outlineItemEditor.setModels(self.mdlOutline, self.mdlPersos, self.outlineItemEditor.setModels(self.mdlOutline, self.mdlCharacter,
self.mdlLabels, self.mdlStatus) self.mdlLabels, self.mdlStatus)
self.treeOutlineOutline.setModel(self.mdlOutline) self.treeOutlineOutline.setModel(self.mdlOutline)
# self.redacEditor.setModel(self.mdlOutline) # self.redacEditor.setModel(self.mdlOutline)
self.storylineView.setModels(self.mdlOutline, self.mdlPersos, self.mdlPlots) self.storylineView.setModels(self.mdlOutline, self.mdlCharacter, self.mdlPlots)
self.treeOutlineOutline.selectionModel().selectionChanged.connect(lambda: self.treeOutlineOutline.selectionModel().selectionChanged.connect(lambda:
self.outlineItemEditor.selectionChanged( self.outlineItemEditor.selectionChanged(
@ -735,12 +669,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Debug # Debug
self.mdlFlatData.setVerticalHeaderLabels(["Infos générales", "Summary"]) self.mdlFlatData.setVerticalHeaderLabels(["Infos générales", "Summary"])
self.tblDebugFlatData.setModel(self.mdlFlatData) self.tblDebugFlatData.setModel(self.mdlFlatData)
self.tblDebugPersos.setModel(self.mdlPersos) self.tblDebugPersos.setModel(self.mdlCharacter)
self.tblDebugPersosInfos.setModel(self.mdlPersos) self.tblDebugPersosInfos.setModel(self.mdlCharacter)
self.tblDebugPersos.selectionModel().currentChanged.connect( self.tblDebugPersos.selectionModel().currentChanged.connect(
lambda: self.tblDebugPersosInfos.setRootIndex(self.mdlPersos.index( lambda: self.tblDebugPersosInfos.setRootIndex(self.mdlCharacter.index(
self.tblDebugPersos.selectionModel().currentIndex().row(), self.tblDebugPersos.selectionModel().currentIndex().row(),
Perso.name.value)), AUC) Character.name.value)), AUC)
self.tblDebugPlots.setModel(self.mdlPlots) self.tblDebugPlots.setModel(self.mdlPlots)
self.tblDebugPlotsPersos.setModel(self.mdlPlots) self.tblDebugPlotsPersos.setModel(self.mdlPlots)
@ -748,11 +682,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.tblDebugPlots.selectionModel().currentChanged.connect( self.tblDebugPlots.selectionModel().currentChanged.connect(
lambda: self.tblDebugPlotsPersos.setRootIndex(self.mdlPlots.index( lambda: self.tblDebugPlotsPersos.setRootIndex(self.mdlPlots.index(
self.tblDebugPlots.selectionModel().currentIndex().row(), self.tblDebugPlots.selectionModel().currentIndex().row(),
Plot.persos.value)), AUC) Plot.characters.value)), AUC)
self.tblDebugPlots.selectionModel().currentChanged.connect( self.tblDebugPlots.selectionModel().currentChanged.connect(
lambda: self.tblDebugSubPlots.setRootIndex(self.mdlPlots.index( lambda: self.tblDebugSubPlots.setRootIndex(self.mdlPlots.index(
self.tblDebugPlots.selectionModel().currentIndex().row(), self.tblDebugPlots.selectionModel().currentIndex().row(),
Plot.subplots.value)), AUC) Plot.steps.value)), AUC)
self.treeDebugWorld.setModel(self.mdlWorld) self.treeDebugWorld.setModel(self.mdlWorld)
self.treeDebugOutline.setModel(self.mdlOutline) self.treeDebugOutline.setModel(self.mdlOutline)
self.lstDebugLabels.setModel(self.mdlLabels) self.lstDebugLabels.setModel(self.mdlLabels)

View file

@ -0,0 +1,293 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex, Qt, QAbstractItemModel, QVariant
from PyQt5.QtGui import QIcon, QPixmap, QColor
from manuskript.functions import randomColor, iconColor, mainWindow
from manuskript.enums import Character as C
class characterModel(QAbstractItemModel):
def __init__(self, parent):
QAbstractItemModel.__init__(self, parent)
# CharacterItems are stored in this list
self.characters = []
###############################################################################
# QAbstractItemModel subclassed
###############################################################################
def rowCount(self, parent=QModelIndex()):
if parent.isValid():
c = parent.internalPointer()
return len(c.infos)
else:
return len(self.characters)
def columnCount(self, parent=QModelIndex()):
if parent.isValid():
# Returns characters infos
return 2
else:
return len(C)
def data(self, index, role=Qt.DisplayRole):
c = index.internalPointer()
if type(c) == Character:
if role == Qt.DisplayRole:
if index.column() in c._data:
return c._data[index.column()]
else:
return ""
elif type(c) == CharacterInfo:
if role == Qt.DisplayRole or role == Qt.EditRole:
if index.column() == 0:
return c.description
elif index.column() == 1:
return c.value
def setData(self, index, value, role=Qt.EditRole):
c = index.internalPointer()
if type(c) == Character:
if role == Qt.EditRole:
# We update only if data is different
if index.column() not in c._data or c._data[index.column()] != value:
c._data[index.column()] = value
self.dataChanged.emit(index, index)
return True
elif type(c) == CharacterInfo:
if role == Qt.EditRole:
if index.column() == 0:
c.description = value
elif index.column() == 1:
c.value = value
self.dataChanged.emit(index, index)
return True
return False
def index(self, row, column, parent=QModelIndex()):
if not parent.isValid():
return self.createIndex(row, column, self.characters[row])
else:
c = parent.internalPointer()
if row < len(c.infos):
return self.createIndex(row, column, c.infos[row])
else:
return QModelIndex()
def indexFromItem(self, item, column=0):
if not item:
return QModelIndex()
row = self.characters.index(item)
col = column
return self.createIndex(row, col, item)
def parent(self, index):
if not index.isValid():
return QModelIndex()
child = index.internalPointer()
if type(child) == Character:
return QModelIndex()
elif type(child) == CharacterInfo:
return child.character.index()
def flags(self, index):
if index.parent().isValid():
return QAbstractItemModel.flags(self, index) | Qt.ItemIsEditable
else:
return QAbstractItemModel.flags(self, index)
###############################################################################
# CHARACTER QUERRIES
###############################################################################
def character(self, row):
return self.characters[row]
def name(self, row):
return self.character(row).name()
def icon(self, row):
return self.character(row).icon
def ID(self, row):
return self.character(row).ID()
def importance(self, row):
return self.character(row).importance()
###############################################################################
# MODEL QUERRIES
###############################################################################
def getCharactersByImportance(self):
"""
Lists characters by importance.
@return: array of array of ´character´, by importance.
"""
r = [[], [], []]
for c in self.characters:
r[2-int(c.importance())].append(c)
return r
def getCharacterByID(self, ID):
if ID is not None:
ID = str(ID)
for c in self.characters:
if c.ID() == ID:
return c
return None
###############################################################################
# ADDING / REMOVING
###############################################################################
def addCharacter(self):
"""
Creates a new character
@return: the character
"""
c = Character(model=self, name=self.tr("New character"))
self.beginInsertRows(QModelIndex(), len(self.characters), len(self.characters))
self.characters.append(c)
self.endInsertRows()
return c
def removeCharacter(self, ID):
"""
Removes character whose ID is ID...
@param ID: the ID of the character to remove
@return: nothing
"""
c = self.getCharacterByID(ID)
self.beginRemoveRows(QModelIndex(), self.characters.index(c), self.characters.index(c))
self.characters.remove(c)
self.endRemoveRows()
###############################################################################
# CHARACTER INFOS
###############################################################################
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
if section == 0:
return self.tr("Name")
elif section == 1:
return self.tr("Value")
else:
return C(section).name
def addCharacterInfo(self, ID):
c = self.getCharacterByID(ID)
self.beginInsertRows(c.index(), len(c.infos), len(c.infos))
c.infos.append(CharacterInfo(c, description="Description", value="Value"))
self.endInsertRows()
mainWindow().updatePersoInfoView()
def removeCharacterInfo(self, ID):
c = self.getCharacterByID(ID)
rm = []
for idx in mainWindow().tblPersoInfos.selectedIndexes():
if not idx.row() in rm:
rm.append(idx.row())
rm.sort()
rm.reverse()
for r in rm:
self.beginRemoveRows(c.index(), r, r)
c.infos.pop(r)
self.endRemoveRows()
###############################################################################
# CHARACTER
###############################################################################
class Character():
def __init__(self, model, name="No name"):
self._model = model
self.lastPath = ""
self._data = {}
self._data[C.name.value] = name
self.assignUniqueID()
self.assignRandomColor()
self._data[C.importance.value] = "0"
self.infos = []
def name(self):
return self._data[C.name.value]
def importance(self):
return self._data[C.importance.value]
def ID(self):
return self._data[C.ID.value]
def index(self, column=0):
return self._model.indexFromItem(self, column)
def assignRandomColor(self):
"""
Assigns a random color the the character.
"""
color = randomColor(QColor(Qt.white))
self.setColor(color)
def setColor(self, color):
"""
Sets the character's color
@param color: QColor.
"""
px = QPixmap(32, 32)
px.fill(color)
self.icon = QIcon(px)
try:
self._model.dataChanged.emit(self.index(), self.index())
except:
# If it is the initialisation, won't be able to emit
pass
def color(self):
"""
Returns character's color in QColor
@return: QColor
"""
return iconColor(self.icon)
def assignUniqueID(self, parent=QModelIndex()):
"""Assigns an unused character ID."""
vals = []
for c in self._model.characters:
vals.append(int(c.ID()))
k = 0
while k in vals:
k += 1
self._data[C.ID.value] = str(k)
def listInfos(self):
r = []
for i in self.infos:
r.append((i.description, i.value))
return r
class CharacterInfo():
def __init__(self, character, description="", value=""):
self.description = description
self.value = value
self.character = character

View file

@ -18,7 +18,7 @@ from manuskript.enums import Outline
from manuskript.functions import mainWindow, toInt, wordCount from manuskript.functions import mainWindow, toInt, wordCount
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
import time import time, os
class outlineModel(QAbstractItemModel): class outlineModel(QAbstractItemModel):
@ -27,6 +27,9 @@ class outlineModel(QAbstractItemModel):
self.rootItem = outlineItem(self, title="root", ID="0") self.rootItem = outlineItem(self, title="root", ID="0")
# Stores removed item, in order to remove them on disk when saving, depending on the file format.
self.removed = []
def index(self, row, column, parent): def index(self, row, column, parent):
if not self.hasIndex(row, column, parent): if not self.hasIndex(row, column, parent):
@ -74,9 +77,7 @@ class outlineModel(QAbstractItemModel):
in columns ``columns`` (being a list of int).""" in columns ``columns`` (being a list of int)."""
return self.rootItem.findItemsContaining(text, columns, mainWindow(), caseSensitive) return self.rootItem.findItemsContaining(text, columns, mainWindow(), caseSensitive)
def getIndexByID(self, ID): def getItemByID(self, ID):
"Returns the index of item whose ID is ``ID``. If none, returns QModelIndex()."
def search(item): def search(item):
if item.ID() == ID: if item.ID() == ID:
return item return item
@ -86,6 +87,11 @@ class outlineModel(QAbstractItemModel):
return r return r
item = search(self.rootItem) item = search(self.rootItem)
return item
def getIndexByID(self, ID):
"Returns the index of item whose ID is ``ID``. If none, returns QModelIndex()."
item = self.getItemByID(ID)
if not item: if not item:
return QModelIndex() return QModelIndex()
else: else:
@ -363,7 +369,8 @@ class outlineModel(QAbstractItemModel):
self.beginRemoveRows(parent, row, row + count - 1) self.beginRemoveRows(parent, row, row + count - 1)
for i in range(count): for i in range(count):
parentItem.removeChild(row) item = parentItem.removeChild(row)
self.removed.append(item)
self.endRemoveRows() self.endRemoveRows()
return True return True
@ -400,19 +407,6 @@ class outlineModel(QAbstractItemModel):
self.rootItem = outlineItem(model=self, xml=ET.tostring(root), ID="0") self.rootItem = outlineItem(model=self, xml=ET.tostring(root), ID="0")
self.rootItem.checkIDs() self.rootItem.checkIDs()
def pathToIndex(self, index, path=""):
# FIXME: Use item's ID instead of rows
if not index.isValid():
return ""
if index.parent().isValid():
path = self.pathToIndex(index.parent())
if path:
path = "{},{}".format(path, str(index.row()))
else:
path = str(index.row())
return path
def indexFromPath(self, path): def indexFromPath(self, path):
path = path.split(",") path = path.split(",")
item = self.rootItem item = self.rootItem
@ -431,6 +425,8 @@ class outlineItem():
self._model = model self._model = model
self.defaultTextType = None self.defaultTextType = None
self.IDs = [] # used by root item to store unique IDs self.IDs = [] # used by root item to store unique IDs
self._lastPath = "" # used by loadSave version_1 to remember which files the items comes from,
# in case it is renamed / removed
if title: if title:
self._data[Outline.title] = title self._data[Outline.title] = title
@ -603,7 +599,7 @@ class outlineItem():
self.parent().updateWordCount(emit) self.parent().updateWordCount(emit)
def row(self): def row(self):
if self.parent: if self.parent():
return self.parent().childItems.index(self) return self.parent().childItems.index(self)
def appendChild(self, child): def appendChild(self, child):
@ -645,9 +641,15 @@ class outlineItem():
c.emitDataChanged(cols, recursive=True) c.emitDataChanged(cols, recursive=True)
def removeChild(self, row): def removeChild(self, row):
self.childItems.pop(row) """
Removes child at position `row` and returns it.
@param row: index (int) of the child to remove.
@return: the removed outlineItem
"""
r = self.childItems.pop(row)
# Might be causing segfault when updateWordCount emits dataChanged # Might be causing segfault when updateWordCount emits dataChanged
self.updateWordCount(emit=False) self.updateWordCount(emit=False)
return r
def parent(self): def parent(self):
return self._parent return self._parent
@ -758,6 +760,9 @@ class outlineItem():
revItem.set("text", r[1]) revItem.set("text", r[1])
item.append(revItem) item.append(revItem)
# Saving lastPath
item.set("lastPath", self._lastPath)
for i in self.childItems: for i in self.childItems:
item.append(ET.XML(i.toXML())) item.append(ET.XML(i.toXML()))
@ -773,6 +778,9 @@ class outlineItem():
# else: # else:
self.setData(Outline.__members__[k].value, str(root.attrib[k])) self.setData(Outline.__members__[k].value, str(root.attrib[k]))
if "lastPath" in root.attrib:
self._lastPath = root.attrib["lastPath"]
for child in root: for child in root:
if child.tag == "outlineItem": if child.tag == "outlineItem":
item = outlineItem(self._model, xml=ET.tostring(child), parent=self) item = outlineItem(self._model, xml=ET.tostring(child), parent=self)
@ -854,8 +862,13 @@ class outlineItem():
text = text.lower() if not caseSensitive else text text = text.lower() if not caseSensitive else text
for c in columns: for c in columns:
if c == Outline.POV.value: if c == Outline.POV.value and self.POV():
searchIn = mainWindow.mdlPersos.getPersoNameByID(self.POV()) c = mainWindow.mdlCharacter.getCharacterByID(self.POV())
if c:
searchIn = c.name()
else:
searchIn = ""
print("Character POV not found:", self.POV())
elif c == Outline.status.value: elif c == Outline.status.value:
searchIn = mainWindow.mdlStatus.item(toInt(self.status()), 0).text() searchIn = mainWindow.mdlStatus.item(toInt(self.status()), 0).text()

View file

@ -1,183 +0,0 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex, Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QColor, QPixmap, QIcon
from PyQt5.QtWidgets import QColorDialog
from manuskript.enums import Perso
from manuskript.enums import Plot
from manuskript.functions import iconColor
from manuskript.functions import mainWindow
from manuskript.functions import randomColor
from manuskript.functions import toInt
class persosModel(QStandardItemModel):
def __init__(self, parent):
QStandardItemModel.__init__(self, 0, 3, parent)
self.setHorizontalHeaderLabels([i.name for i in Perso])
self.mw = mainWindow()
# self._proxy = plotsProxyModel()
# self._proxy.setSourceModel(self)
###############################################################################
# PERSOS QUERRIES
###############################################################################
def name(self, row):
return self.item(row, Perso.name.value).text()
def icon(self, row):
return self.item(row, Perso.name.value).icon()
def ID(self, row):
return self.item(row, Perso.ID.value).text()
def importance(self, row):
return self.item(row, Perso.importance.value).text()
###############################################################################
# MODEL QUERRIES
###############################################################################
def getPersosByImportance(self):
persos = [[], [], []]
for i in range(self.rowCount()):
importance = self.item(i, Perso.importance.value).text()
ID = self.item(i, Perso.ID.value).text()
persos[2-toInt(importance)].append(ID)
return persos
def getPersoNameByID(self, ID):
index = self.getIndexFromID(ID)
if index.isValid():
return self.name(index.row())
return ""
def getIndexFromID(self, ID):
for i in range(self.rowCount()):
_ID = self.item(i, Perso.ID.value).text()
if _ID == ID or toInt(_ID) == ID:
return self.index(i, 0)
return QModelIndex()
def getPersoColorByID(self, ID):
idx = self.getIndexFromID(ID)
return self.getPersoColorName(idx)
def getPersoColorName(self, index):
icon = self.item(index.row()).icon()
return iconColor(icon).name() if icon else ""
def currentListIndex(self):
i = self.mw.lstPersos.currentIndex()
if i .isValid():
return i
else:
return None
def currentPersoIndex(self):
return self.mw.lstPersos.currentPersoIndex()
###############################################################################
# ADDING / REMOVING
###############################################################################
def addPerso(self):
"""Creates a perso by adding a row in mdlPersos
and a column in mdlPersosInfos with same ID"""
p = QStandardItem(self.tr("New character"))
self.setPersoColor(p, randomColor(QColor(Qt.white)))
pid = self.getUniqueID()
self.appendRow([p, QStandardItem(pid), QStandardItem("0")])
def getUniqueID(self, parent=QModelIndex()):
"""Returns an unused perso ID (row 1)."""
vals = []
for i in range(self.rowCount(parent)):
index = self.index(i, Perso.ID.value, parent)
if index.isValid() and index.data():
vals.append(int(index.data()))
k = 0
while k in vals:
k += 1
return str(k)
def removePerso(self):
index = self.currentPersoIndex()
self.takeRow(index.row())
def setPersoColor(self, item, color):
px = QPixmap(32, 32)
px.fill(color)
item.setIcon(QIcon(px))
def chosePersoColor(self):
idx = self.currentPersoIndex()
item = self.item(idx.row(), Perso.name.value)
if item:
color = iconColor(item.icon())
else:
color = Qt.white
self.colorDialog = QColorDialog(color, self.mw)
color = self.colorDialog.getColor(color)
if color.isValid():
self.setPersoColor(item, color)
self.updatePersoColor(idx)
###############################################################################
# UI
###############################################################################
def updatePersoColor(self, idx):
# idx = self.currentPersoIndex()
color = self.getPersoColorName(idx)
self.mw.btnPersoColor.setStyleSheet("background:{};".format(color))
###############################################################################
# PERSO INFOS
###############################################################################
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
if section == Perso.infoName.value:
return self.tr("Name")
elif section == Perso.infoData.value:
return self.tr("Value")
else:
return Perso(section).name
else:
return QStandardItemModel.headerData(self, section, orientation, role)
def addPersoInfo(self):
perso = self.itemFromIndex(self.currentPersoIndex())
row = perso.rowCount()
perso.setChild(row, Perso.infoName.value, QStandardItem(""))
perso.setChild(row, Perso.infoData.value, QStandardItem(""))
self.mw.updatePersoInfoView()
def removePersoInfo(self):
perso = self.itemFromIndex(self.currentPersoIndex())
rm = []
for idx in self.mw.tblPersoInfos.selectedIndexes():
if not idx.row() in rm:
rm.append(idx.row())
rm.sort()
rm.reverse()
for r in rm:
perso.takeRow(r)
def listPersoInfos(self, index):
infos = []
for i in range(self.rowCount(index)):
name = self.data(index.child(i, Perso.infoName.value))
val = self.data(index.child(i, Perso.infoData.value))
infos.append((name, val))
return infos

View file

@ -9,7 +9,7 @@ from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QAction, QMenu from PyQt5.QtWidgets import QAction, QMenu
from manuskript.enums import Plot from manuskript.enums import Plot
from manuskript.enums import Subplot from manuskript.enums import PlotStep
from manuskript.functions import toInt, mainWindow from manuskript.functions import toInt, mainWindow
@ -37,7 +37,7 @@ class plotModel(QStandardItemModel):
index = self.getIndexFromID(ID) index = self.getIndexFromID(ID)
if not index.isValid(): if not index.isValid():
return return
index = index.sibling(index.row(), Plot.subplots.value) index = index.sibling(index.row(), Plot.steps.value)
item = self.itemFromIndex(index) item = self.itemFromIndex(index)
lst = [] lst = []
for i in range(item.rowCount()): for i in range(item.rowCount()):
@ -86,8 +86,8 @@ class plotModel(QStandardItemModel):
p = QStandardItem(self.tr("New plot")) p = QStandardItem(self.tr("New plot"))
_id = QStandardItem(self.getUniqueID()) _id = QStandardItem(self.getUniqueID())
importance = QStandardItem(str(0)) importance = QStandardItem(str(0))
self.appendRow([p, _id, importance, QStandardItem("Persos"), self.appendRow([p, _id, importance, QStandardItem("Characters"),
QStandardItem(), QStandardItem(), QStandardItem("Subplots")]) QStandardItem(), QStandardItem(), QStandardItem("Resolution steps")])
def getUniqueID(self, parent=QModelIndex()): def getUniqueID(self, parent=QModelIndex()):
"""Returns an unused ID""" """Returns an unused ID"""
@ -114,9 +114,9 @@ class plotModel(QStandardItemModel):
def headerData(self, section, orientation, role=Qt.DisplayRole): def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
if orientation == Qt.Horizontal: if orientation == Qt.Horizontal:
if section == Subplot.name.value: if section == PlotStep.name.value:
return self.tr("Name") return self.tr("Name")
elif section == Subplot.meta.value: elif section == PlotStep.meta.value:
return self.tr("Meta") return self.tr("Meta")
else: else:
return "" return ""
@ -127,8 +127,8 @@ class plotModel(QStandardItemModel):
def data(self, index, role=Qt.DisplayRole): def data(self, index, role=Qt.DisplayRole):
if index.parent().isValid() and \ if index.parent().isValid() and \
index.parent().column() == Plot.subplots.value and \ index.parent().column() == Plot.steps.value and \
index.column() == Subplot.meta.value: index.column() == PlotStep.meta.value:
if role == Qt.TextAlignmentRole: if role == Qt.TextAlignmentRole:
return Qt.AlignRight | Qt.AlignVCenter return Qt.AlignRight | Qt.AlignVCenter
elif role == Qt.ForegroundRole: elif role == Qt.ForegroundRole:
@ -144,13 +144,13 @@ class plotModel(QStandardItemModel):
if not index.isValid(): if not index.isValid():
return return
parent = index.sibling(index.row(), Plot.subplots.value) parent = index.sibling(index.row(), Plot.steps.value)
parentItem = self.item(index.row(), Plot.subplots.value) parentItem = self.item(index.row(), Plot.steps.value)
if not parentItem: if not parentItem:
return return
p = QStandardItem(self.tr("New subplot")) p = QStandardItem(self.tr("New step"))
_id = QStandardItem(self.getUniqueID(parent)) _id = QStandardItem(self.getUniqueID(parent))
summary = QStandardItem() summary = QStandardItem()
@ -182,10 +182,10 @@ class plotModel(QStandardItemModel):
def addPlotPerso(self, v): def addPlotPerso(self, v):
index = self.mw.lstPlots.currentPlotIndex() index = self.mw.lstPlots.currentPlotIndex()
if index.isValid(): if index.isValid():
if not self.item(index.row(), Plot.persos.value): if not self.item(index.row(), Plot.characters.value):
self.setItem(index.row(), Plot.persos.value, QStandardItem()) self.setItem(index.row(), Plot.characters.value, QStandardItem())
item = self.item(index.row(), Plot.persos.value) item = self.item(index.row(), Plot.characters.value)
# We check that the PersoID is not in the list yet # We check that the PersoID is not in the list yet
for i in range(item.rowCount()): for i in range(item.rowCount()):
@ -212,13 +212,13 @@ class plotModel(QStandardItemModel):
menu.addMenu(m) menu.addMenu(m)
mpr = QSignalMapper(menu) mpr = QSignalMapper(menu)
for i in range(self.mw.mdlPersos.rowCount()): for i in range(self.mw.mdlCharacter.rowCount()):
a = QAction(self.mw.mdlPersos.name(i), menu) a = QAction(self.mw.mdlCharacter.name(i), menu)
a.setIcon(self.mw.mdlPersos.icon(i)) a.setIcon(self.mw.mdlCharacter.icon(i))
a.triggered.connect(mpr.map) a.triggered.connect(mpr.map)
mpr.setMapping(a, int(self.mw.mdlPersos.ID(i))) mpr.setMapping(a, int(self.mw.mdlCharacter.ID(i)))
imp = toInt(self.mw.mdlPersos.importance(i)) imp = toInt(self.mw.mdlCharacter.importance(i))
menus[2 - imp].addAction(a) menus[2 - imp].addAction(a)

View file

@ -11,9 +11,9 @@ import re
from PyQt5.QtWidgets import qApp from PyQt5.QtWidgets import qApp
from manuskript.enums import Outline from manuskript.enums import Outline
from manuskript.enums import Perso from manuskript.enums import Character
from manuskript.enums import Plot from manuskript.enums import Plot
from manuskript.enums import Subplot from manuskript.enums import PlotStep
from manuskript.functions import mainWindow from manuskript.functions import mainWindow
RegEx = r"{(\w):(\d+):?.*?}" RegEx = r"{(\w):(\d+):?.*?}"
@ -22,7 +22,7 @@ RegExNonCapturing = r"{\w:\d+:?.*?}"
# The basic format of the references # The basic format of the references
EmptyRef = "{{{}:{}:{}}}" EmptyRef = "{{{}:{}:{}}}"
EmptyRefSearchable = "{{{}:{}:" EmptyRefSearchable = "{{{}:{}:"
PersoLetter = "C" CharacterLetter = "C"
TextLetter = "T" TextLetter = "T"
PlotLetter = "P" PlotLetter = "P"
WorldLetter = "W" WorldLetter = "W"
@ -37,13 +37,13 @@ def plotReference(ID, searchable=False):
return EmptyRefSearchable.format(PlotLetter, ID, "") return EmptyRefSearchable.format(PlotLetter, ID, "")
def persoReference(ID, searchable=False): def characterReference(ID, searchable=False):
"""Takes the ID of a character and returns a reference for that character. """Takes the ID of a character and returns a reference for that character.
@searchable: returns a stripped version that allows simple text search.""" @searchable: returns a stripped version that allows simple text search."""
if not searchable: if not searchable:
return EmptyRef.format(PersoLetter, ID, "") return EmptyRef.format(CharacterLetter, ID, "")
else: else:
return EmptyRefSearchable.format(PersoLetter, ID, "") return EmptyRefSearchable.format(CharacterLetter, ID, "")
def textReference(ID, searchable=False): def textReference(ID, searchable=False):
@ -103,8 +103,8 @@ def infos(ref):
POV = "" POV = ""
if item.POV(): if item.POV():
POV = "<a href='{ref}'>{text}</a>".format( POV = "<a href='{ref}'>{text}</a>".format(
ref=persoReference(item.POV()), ref=characterReference(item.POV()),
text=mainWindow().mdlPersos.getPersoNameByID(item.POV())) text=mainWindow().mdlCharacter.getCharacterByID(item.POV()).name())
# The status of the scene # The status of the scene
status = item.status() status = item.status()
@ -174,10 +174,12 @@ def infos(ref):
return text return text
# A character # A character
elif _type == PersoLetter: elif _type == CharacterLetter:
m = mainWindow().mdlPersos m = mainWindow().mdlCharacter
index = m.getIndexFromID(_ref) c = m.getCharacterByID(int(_ref))
name = m.name(index.row()) index = c.index()
name = c.name()
# Titles # Titles
basicTitle = qApp.translate("references", "Basic infos") basicTitle = qApp.translate("references", "Basic infos")
@ -191,14 +193,16 @@ def infos(ref):
# basic infos # basic infos
basic = [] basic = []
for i in [ for i in [
(Perso.motivation, qApp.translate("references", "Motivation"), False), (Character.motivation, qApp.translate("references", "Motivation"), False),
(Perso.goal, qApp.translate("references", "Goal"), False), (Character.goal, qApp.translate("references", "Goal"), False),
(Perso.conflict, qApp.translate("references", "Conflict"), False), (Character.conflict, qApp.translate("references", "Conflict"), False),
(Perso.epiphany, qApp.translate("references", "Epiphany"), False), (Character.epiphany, qApp.translate("references", "Epiphany"), False),
(Perso.summarySentence, qApp.translate("references", "Short summary"), True), (Character.summarySentence, qApp.translate("references", "Short summary"), True),
(Perso.summaryPara, qApp.translate("references", "Longer summary"), True), (Character.summaryPara, qApp.translate("references", "Longer summary"), True),
]: ]:
val = m.data(index.sibling(index.row(), i[0].value)) val = m.data(index.sibling(index.row(), i[0].value))
if val: if val:
basic.append("<b>{title}:</b>{n}{val}".format( basic.append("<b>{title}:</b>{n}{val}".format(
title=i[1], title=i[1],
@ -208,7 +212,7 @@ def infos(ref):
# detailed infos # detailed infos
detailed = [] detailed = []
for _name, _val in m.listPersoInfos(index): for _name, _val in c.listInfos():
detailed.append("<b>{}:</b> {}".format( detailed.append("<b>{}:</b> {}".format(
_name, _name,
_val)) _val))
@ -272,24 +276,24 @@ def infos(ref):
Plot.result.value)) Plot.result.value))
# Characters # Characters
pM = mainWindow().mdlPersos pM = mainWindow().mdlCharacter
item = m.item(index.row(), Plot.persos.value) item = m.item(index.row(), Plot.characters.value)
characters = "" characters = ""
if item: if item:
for r in range(item.rowCount()): for r in range(item.rowCount()):
ID = item.child(r, 0).text() ID = item.child(r, 0).text()
characters += "<li><a href='{link}'>{text}</a>".format( characters += "<li><a href='{link}'>{text}</a>".format(
link=persoReference(ID), link=characterReference(ID),
text=pM.getPersoNameByID(ID)) text=pM.getPersoNameByID(ID))
# Resolution steps # Resolution steps
steps = "" steps = ""
item = m.item(index.row(), Plot.subplots.value) item = m.item(index.row(), Plot.steps.value)
if item: if item:
for r in range(item.rowCount()): for r in range(item.rowCount()):
title = item.child(r, Subplot.name.value).text() title = item.child(r, PlotStep.name.value).text()
summary = item.child(r, Subplot.summary.value).text() summary = item.child(r, PlotStep.summary.value).text()
meta = item.child(r, Subplot.meta.value).text() meta = item.child(r, PlotStep.meta.value).text()
if meta: if meta:
meta = " <span style='color:gray;'>({})</span>".format(meta) meta = " <span style='color:gray;'>({})</span>".format(meta)
steps += "<li><b>{title}</b>{summary}{meta}</li>".format( steps += "<li><b>{title}</b>{summary}{meta}</li>".format(
@ -408,15 +412,16 @@ def shortInfos(ref):
infos["path"] = item.path() infos["path"] = item.path()
return infos return infos
elif _type == PersoLetter: elif _type == CharacterLetter:
infos["type"] = PersoLetter infos["type"] = CharacterLetter
m = mainWindow().mdlPersos m = mainWindow().mdlCharacter
item = m.item(int(_ref), Perso.name.value) c = m.getCharacterByID(_ref)
if item:
infos["title"] = item.text() if c:
infos["name"] = item.text() infos["title"] = c.name()
infos["name"] = c.name()
return infos return infos
elif _type == PlotLetter: elif _type == PlotLetter:
@ -482,7 +487,7 @@ def tooltip(ref):
tt += "<br><i>{}</i>".format(infos["path"]) tt += "<br><i>{}</i>".format(infos["path"])
return tt return tt
elif infos["type"] == PersoLetter: elif infos["type"] == CharacterLetter:
return qApp.translate("references", "Character: <b>{}</b>").format(infos["title"]) return qApp.translate("references", "Character: <b>{}</b>").format(infos["title"])
elif infos["type"] == PlotLetter: elif infos["type"] == PlotLetter:
@ -515,9 +520,9 @@ def refToLink(ref):
item = idx.internalPointer() item = idx.internalPointer()
text = item.title() text = item.title()
elif _type == PersoLetter: elif _type == CharacterLetter:
m = mainWindow().mdlPersos m = mainWindow().mdlCharacter
text = m.item(int(_ref), Perso.name.value).text() text = m.getCharacterByID(int(_ref)).name()
elif _type == PlotLetter: elif _type == PlotLetter:
m = mainWindow().mdlPlots m = mainWindow().mdlPlots
@ -618,16 +623,16 @@ def open(ref):
_type = match.group(1) _type = match.group(1)
_ref = match.group(2) _ref = match.group(2)
if _type == PersoLetter: if _type == CharacterLetter:
mw = mainWindow() mw = mainWindow()
item = mw.lstPersos.getItemByID(_ref) item = mw.lstCharacters.getItemByID(int(_ref))
if item: if item:
mw.tabMain.setCurrentIndex(mw.TabPersos) mw.tabMain.setCurrentIndex(mw.TabPersos)
mw.lstPersos.setCurrentItem(item) mw.lstCharacters.setCurrentItem(item)
return True return True
print("Ref not found") print("Error: Ref {} not found".format(ref))
return False return False
elif _type == TextLetter: elif _type == TextLetter:

View file

@ -1,12 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import collections import collections
import json
import pickle import pickle
from PyQt5.QtWidgets import qApp from PyQt5.QtWidgets import qApp
from manuskript.enums import Outline from manuskript.enums import Outline
# TODO: move some/all of those settings to application settings and not project settings
# in order to allow a shared project between several writers
viewSettings = { viewSettings = {
"Tree": { "Tree": {
"Icon": "Nothing", "Icon": "Nothing",
@ -28,7 +32,8 @@ viewSettings = {
"Background": "Nothing", "Background": "Nothing",
}, },
} }
# Application
spellcheck = False spellcheck = False
dict = None dict = None
corkSizeFactor = 100 corkSizeFactor = 100
@ -81,7 +86,7 @@ frequencyAnalyzer = {
"phraseMax": 5 "phraseMax": 5
} }
def save(filename=None): def save(filename=None, protocol=None):
global spellcheck, dict, corkSliderFactor, viewSettings, corkSizeFactor, folderView, lastTab, openIndexes, \ global spellcheck, dict, corkSliderFactor, viewSettings, corkSizeFactor, folderView, lastTab, openIndexes, \
autoSave, autoSaveDelay, saveOnQuit, autoSaveNoChanges, autoSaveNoChangesDelay, outlineViewColumns, \ autoSave, autoSaveDelay, saveOnQuit, autoSaveNoChanges, autoSaveNoChangesDelay, outlineViewColumns, \
@ -107,7 +112,7 @@ def save(filename=None):
"textEditor":textEditor, "textEditor":textEditor,
"revisions":revisions, "revisions":revisions,
"frequencyAnalyzer": frequencyAnalyzer "frequencyAnalyzer": frequencyAnalyzer
} }
#pp=pprint.PrettyPrinter(indent=4, compact=False) #pp=pprint.PrettyPrinter(indent=4, compact=False)
#print("Saving:") #print("Saving:")
@ -117,9 +122,16 @@ def save(filename=None):
f = open(filename, "wb") f = open(filename, "wb")
pickle.dump(allSettings, f) pickle.dump(allSettings, f)
else: else:
return pickle.dumps(allSettings) if protocol == 0:
# This looks stupid
def load(string, fromString=False): # But a simple json.dumps with sort_keys will throw a TypeError
# because of unorderable types.
return json.dumps(json.loads(json.dumps(allSettings)), indent=4, sort_keys=True)
else:
return pickle.dumps(allSettings)
def load(string, fromString=False, protocol=None):
"""Load settings from 'string'. 'string' is the filename of the pickle dump. """Load settings from 'string'. 'string' is the filename of the pickle dump.
If fromString=True, string is the data of the pickle dumps.""" If fromString=True, string is the data of the pickle dumps."""
global allSettings global allSettings
@ -133,8 +145,11 @@ def load(string, fromString=False):
print("{} doesn't exist, cannot load settings.".format(string)) print("{} doesn't exist, cannot load settings.".format(string))
return return
else: else:
allSettings = pickle.loads(string) if protocol == 0:
allSettings = json.loads(string)
else:
allSettings = pickle.loads(string)
#pp=pprint.PrettyPrinter(indent=4, compact=False) #pp=pprint.PrettyPrinter(indent=4, compact=False)
#print("Loading:") #print("Loading:")
#pp.pprint(allSettings) #pp.pprint(allSettings)
@ -211,6 +226,17 @@ def load(string, fromString=False):
global revisions global revisions
revisions = allSettings["revisions"] revisions = allSettings["revisions"]
# With JSON we had to convert int keys to str, and None to "null", so we roll back.
r = {}
for i in revisions["rules"]:
if i == "null":
r[None] = revisions["rules"]["null"]
continue
elif i == None:
continue
r[int(i)] = revisions["rules"][i]
revisions["rules"] = r
if "frequencyAnalyzer" in allSettings: if "frequencyAnalyzer" in allSettings:
global frequencyAnalyzer global frequencyAnalyzer
frequencyAnalyzer = allSettings["frequencyAnalyzer"] frequencyAnalyzer = allSettings["frequencyAnalyzer"]

View file

@ -4,7 +4,7 @@ from PyQt5.QtCore import pyqtSignal, Qt, QTimer, QRect
from PyQt5.QtGui import QBrush, QCursor, QPalette, QFontMetrics from PyQt5.QtGui import QBrush, QCursor, QPalette, QFontMetrics
from PyQt5.QtWidgets import QWidget, QListWidgetItem, QToolTip, QStyledItemDelegate, QStyle from PyQt5.QtWidgets import QWidget, QListWidgetItem, QToolTip, QStyledItemDelegate, QStyle
from manuskript.enums import Perso from manuskript.enums import Character
from manuskript.enums import Plot from manuskript.enums import Plot
from manuskript.functions import lightBlue from manuskript.functions import lightBlue
from manuskript.functions import mainWindow from manuskript.functions import mainWindow
@ -36,7 +36,7 @@ class cheatSheet(QWidget, Ui_cheatSheet):
self.line.hide() self.line.hide()
self.outlineModel = None self.outlineModel = None
self.persoModel = None self.characterModel = None
self.plotModel = None self.plotModel = None
self.worldModel = None self.worldModel = None
@ -53,12 +53,14 @@ class cheatSheet(QWidget, Ui_cheatSheet):
def setModels(self): def setModels(self):
mw = mainWindow() mw = mainWindow()
self.outlineModel = mw.mdlOutline self.outlineModel = mw.mdlOutline
self.persoModel = mw.mdlPersos self.characterModel = mw.mdlCharacter
self.plotModel = mw.mdlPlots self.plotModel = mw.mdlPlots
self.worldModel = mw.mdlWorld self.worldModel = mw.mdlWorld
self.outlineModel.dataChanged.connect(self.populateTimer.start) self.outlineModel.dataChanged.connect(self.populateTimer.start)
self.persoModel.dataChanged.connect(self.populateTimer.start) self.characterModel.dataChanged.connect(self.populateTimer.start)
self.characterModel.rowsInserted.connect(self.populateTimer.start)
self.characterModel.rowsRemoved.connect(self.populateTimer.start)
self.plotModel.dataChanged.connect(self.populateTimer.start) self.plotModel.dataChanged.connect(self.populateTimer.start)
self.worldModel.dataChanged.connect(self.populateTimer.start) self.worldModel.dataChanged.connect(self.populateTimer.start)
@ -75,17 +77,14 @@ class cheatSheet(QWidget, Ui_cheatSheet):
self.list.hide() self.list.hide()
def populate(self): def populate(self):
if self.persoModel: if self.characterModel:
d = [] d = []
for r in range(self.persoModel.rowCount()): for c in self.characterModel.characters:
name = self.persoModel.item(r, Perso.name.value).text() imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(c.importance())]
ID = self.persoModel.item(r, Perso.ID.value).text() d.append((c.name(), c.ID(), imp))
imp = self.persoModel.item(r, Perso.importance.value).text()
imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)]
d.append((name, ID, imp))
self.data[(self.tr("Characters"), Ref.PersoLetter)] = d self.data[(self.tr("Characters"), Ref.CharacterLetter)] = d
if self.outlineModel: if self.outlineModel:
d = [] d = []

View file

@ -61,7 +61,7 @@ class basicHighlighter(QSyntaxHighlighter):
fmt.setFontWeight(QFont.DemiBold) fmt.setFontWeight(QFont.DemiBold)
if txt.group(1) == Ref.TextLetter: if txt.group(1) == Ref.TextLetter:
fmt.setBackground(QBrush(QColor(Qt.blue).lighter(190))) fmt.setBackground(QBrush(QColor(Qt.blue).lighter(190)))
elif txt.group(1) == Ref.PersoLetter: elif txt.group(1) == Ref.CharacterLetter:
fmt.setBackground(QBrush(QColor(Qt.yellow).lighter(170))) fmt.setBackground(QBrush(QColor(Qt.yellow).lighter(170)))
elif txt.group(1) == Ref.PlotLetter: elif txt.group(1) == Ref.PlotLetter:
fmt.setBackground(QBrush(QColor(Qt.red).lighter(170))) fmt.setBackground(QBrush(QColor(Qt.red).lighter(170)))

View file

@ -173,7 +173,7 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
elif item and item.isFolder() and self.folderView == "outline": elif item and item.isFolder() and self.folderView == "outline":
self.stack.setCurrentIndex(3) self.stack.setCurrentIndex(3)
self.outlineView.setModelPersos(mainWindow().mdlPersos) self.outlineView.setModelCharacters(mainWindow().mdlCharacter)
self.outlineView.setModelLabels(mainWindow().mdlLabels) self.outlineView.setModelLabels(mainWindow().mdlLabels)
self.outlineView.setModelStatus(mainWindow().mdlStatus) self.outlineView.setModelStatus(mainWindow().mdlStatus)
self.outlineView.setModel(self.mw.mdlOutline) self.outlineView.setModel(self.mw.mdlOutline)

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/mainWindow.ui' # Form implementation generated from reading ui file 'manuskript/ui/mainWindow.ui'
# #
# Created: Wed Mar 2 00:30:17 2016 # Created: Thu Mar 3 18:52:22 2016
# by: PyQt5 UI code generator 5.2.1 # by: PyQt5 UI code generator 5.2.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -337,12 +337,12 @@ class Ui_MainWindow(object):
self.groupBox.setObjectName("groupBox") self.groupBox.setObjectName("groupBox")
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.groupBox) self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.groupBox)
self.verticalLayout_8.setObjectName("verticalLayout_8") self.verticalLayout_8.setObjectName("verticalLayout_8")
self.lstPersos = persoTreeView(self.groupBox) self.lstCharacters = characterTreeView(self.groupBox)
self.lstPersos.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.lstCharacters.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.lstPersos.setDragEnabled(True) self.lstCharacters.setDragEnabled(True)
self.lstPersos.setObjectName("lstPersos") self.lstCharacters.setObjectName("lstCharacters")
self.lstPersos.headerItem().setText(0, "1") self.lstCharacters.headerItem().setText(0, "1")
self.verticalLayout_8.addWidget(self.lstPersos) self.verticalLayout_8.addWidget(self.lstCharacters)
self.horizontalLayout_14 = QtWidgets.QHBoxLayout() self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
self.horizontalLayout_14.setObjectName("horizontalLayout_14") self.horizontalLayout_14.setObjectName("horizontalLayout_14")
self.btnAddPerso = QtWidgets.QPushButton(self.groupBox) self.btnAddPerso = QtWidgets.QPushButton(self.groupBox)
@ -1166,7 +1166,7 @@ class Ui_MainWindow(object):
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
self.stack.setCurrentIndex(1) self.stack.setCurrentIndex(1)
self.tabMain.setCurrentIndex(6) self.tabMain.setCurrentIndex(2)
self.tabSummary.setCurrentIndex(0) self.tabSummary.setCurrentIndex(0)
self.tabPersos.setCurrentIndex(0) self.tabPersos.setCurrentIndex(0)
self.tabPlot.setCurrentIndex(0) self.tabPlot.setCurrentIndex(0)
@ -1303,18 +1303,18 @@ class Ui_MainWindow(object):
self.actCompile.setShortcut(_translate("MainWindow", "F6")) self.actCompile.setShortcut(_translate("MainWindow", "F6"))
self.actToolFrequency.setText(_translate("MainWindow", "&Frequency Analyzer")) self.actToolFrequency.setText(_translate("MainWindow", "&Frequency Analyzer"))
from manuskript.ui.views.storylineView import storylineView
from manuskript.ui.views.textEditView import textEditView
from manuskript.ui.views.lineEditView import lineEditView
from manuskript.ui.views.treeView import treeView
from manuskript.ui.editors.mainEditor import mainEditor
from manuskript.ui.views.basicItemView import basicItemView
from manuskript.ui.views.persoTreeView import persoTreeView
from manuskript.ui.views.plotTreeView import plotTreeView
from manuskript.ui.views.outlineView import outlineView from manuskript.ui.views.outlineView import outlineView
from manuskript.ui.views.metadataView import metadataView from manuskript.ui.views.textEditView import textEditView
from manuskript.ui.views.basicItemView import basicItemView
from manuskript.ui.views.plotTreeView import plotTreeView
from manuskript.ui.cheatSheet import cheatSheet from manuskript.ui.cheatSheet import cheatSheet
from manuskript.ui.views.textEditCompleter import textEditCompleter from manuskript.ui.views.sldImportance import sldImportance
from manuskript.ui.sldImportance import sldImportance from manuskript.ui.views.metadataView import metadataView
from manuskript.ui.welcome import welcome from manuskript.ui.views.characterTreeView import characterTreeView
from manuskript.ui.editors.mainEditor import mainEditor
from manuskript.ui.search import search from manuskript.ui.search import search
from manuskript.ui.views.lineEditView import lineEditView
from manuskript.ui.welcome import welcome
from manuskript.ui.views.treeView import treeView
from manuskript.ui.views.textEditCompleter import textEditCompleter
from manuskript.ui.views.storylineView import storylineView

View file

@ -124,7 +124,7 @@
<enum>QTabWidget::Rounded</enum> <enum>QTabWidget::Rounded</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>6</number> <number>2</number>
</property> </property>
<property name="documentMode"> <property name="documentMode">
<bool>true</bool> <bool>true</bool>
@ -714,7 +714,7 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_8">
<item> <item>
<widget class="persoTreeView" name="lstPersos"> <widget class="characterTreeView" name="lstCharacters">
<property name="horizontalScrollBarPolicy"> <property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum> <enum>Qt::ScrollBarAlwaysOff</enum>
</property> </property>
@ -2358,7 +2358,7 @@ QListView::item:hover {
<customwidget> <customwidget>
<class>sldImportance</class> <class>sldImportance</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>manuskript.ui.sldImportance.h</header> <header>manuskript.ui.views.sldImportance.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
@ -2396,9 +2396,9 @@ QListView::item:hover {
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>persoTreeView</class> <class>characterTreeView</class>
<extends>QTreeWidget</extends> <extends>QTreeWidget</extends>
<header>manuskript.ui.views.persoTreeView.h</header> <header>manuskript.ui.views.characterTreeView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cheatSheet</class> <class>cheatSheet</class>

View file

@ -14,8 +14,8 @@ class basicItemView(QWidget, Ui_basicItemView):
self.txtSummaryFull.setColumn(Outline.summaryFull.value) self.txtSummaryFull.setColumn(Outline.summaryFull.value)
self.txtGoal.setColumn(Outline.setGoal.value) self.txtGoal.setColumn(Outline.setGoal.value)
def setModels(self, mdlOutline, mdlPersos, mdlLabels, mdlStatus): def setModels(self, mdlOutline, mdlCharacter, mdlLabels, mdlStatus):
self.cmbPOV.setModels(mdlPersos, mdlOutline) self.cmbPOV.setModels(mdlCharacter, mdlOutline)
self.txtSummarySentence.setModel(mdlOutline) self.txtSummarySentence.setModel(mdlOutline)
self.txtSummaryFull.setModel(mdlOutline) self.txtSummaryFull.setModel(mdlOutline)
self.txtGoal.setModel(mdlOutline) self.txtGoal.setModel(mdlOutline)

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/views/basicItemView_ui.ui' # Form implementation generated from reading ui file 'manuskript/ui/views/basicItemView_ui.ui'
# #
# Created: Wed Mar 2 00:33:34 2016 # Created: Thu Mar 3 17:26:11 2016
# by: PyQt5 UI code generator 5.2.1 # by: PyQt5 UI code generator 5.2.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -24,7 +24,7 @@ class Ui_basicItemView(object):
self.lblPlanPOV.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.lblPlanPOV.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.lblPlanPOV.setObjectName("lblPlanPOV") self.lblPlanPOV.setObjectName("lblPlanPOV")
self.horizontalLayout_11.addWidget(self.lblPlanPOV) self.horizontalLayout_11.addWidget(self.lblPlanPOV)
self.cmbPOV = cmbOutlinePersoChoser(basicItemView) self.cmbPOV = cmbOutlineCharacterChoser(basicItemView)
self.cmbPOV.setFrame(False) self.cmbPOV.setFrame(False)
self.cmbPOV.setObjectName("cmbPOV") self.cmbPOV.setObjectName("cmbPOV")
self.horizontalLayout_11.addWidget(self.cmbPOV) self.horizontalLayout_11.addWidget(self.cmbPOV)
@ -67,6 +67,6 @@ class Ui_basicItemView(object):
self.txtSummarySentence.setPlaceholderText(_translate("basicItemView", "One line summary")) self.txtSummarySentence.setPlaceholderText(_translate("basicItemView", "One line summary"))
self.label_9.setText(_translate("basicItemView", "Few sentences summary:")) self.label_9.setText(_translate("basicItemView", "Few sentences summary:"))
from manuskript.ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser from manuskript.ui.views.cmbOutlineCharacterChoser import cmbOutlineCharacterChoser
from manuskript.ui.views.textEditView import textEditView
from manuskript.ui.views.lineEditView import lineEditView from manuskript.ui.views.lineEditView import lineEditView
from manuskript.ui.views.textEditView import textEditView

View file

@ -43,7 +43,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="cmbOutlinePersoChoser" name="cmbPOV"> <widget class="cmbOutlineCharacterChoser" name="cmbPOV">
<property name="frame"> <property name="frame">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -112,9 +112,9 @@
<header>manuskript.ui.views.textEditView.h</header> <header>manuskript.ui.views.textEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlinePersoChoser</class> <class>cmbOutlineCharacterChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>manuskript.ui.views.cmbOutlinePersoChoser.h</header> <header>manuskript.ui.views.cmbOutlineCharacterChoser.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>lineEditView</class> <class>lineEditView</class>

View file

@ -2,12 +2,16 @@
# --!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QSize, QModelIndex, Qt from PyQt5.QtCore import QSize, QModelIndex, Qt
from PyQt5.QtGui import QPixmap, QColor, QIcon, QBrush from PyQt5.QtGui import QPixmap, QColor, QIcon, QBrush
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QColorDialog
from manuskript.enums import Perso from manuskript.enums import Character
from manuskript.functions import iconColor, mainWindow
class persoTreeView(QTreeWidget): class characterTreeView(QTreeWidget):
"""
A QTreeWidget that displays characters from a characterModel in respect of their importance.
"""
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeWidget.__init__(self, parent) QTreeWidget.__init__(self, parent)
self._model = None self._model = None
@ -24,7 +28,7 @@ class persoTreeView(QTreeWidget):
self._rootItem = QTreeWidgetItem() self._rootItem = QTreeWidgetItem()
self.insertTopLevelItem(0, self._rootItem) self.insertTopLevelItem(0, self._rootItem)
def setPersosModel(self, model): def setCharactersModel(self, model):
self._model = model self._model = model
self._model.dataChanged.connect(self.updateMaybe) self._model.dataChanged.connect(self.updateMaybe)
self._model.rowsInserted.connect(self.updateMaybe2) self._model.rowsInserted.connect(self.updateMaybe2)
@ -39,11 +43,11 @@ class persoTreeView(QTreeWidget):
if topLeft.parent() != QModelIndex(): if topLeft.parent() != QModelIndex():
return return
if topLeft.column() <= Perso.name.value <= bottomRight.column(): if topLeft.column() <= Character.name.value <= bottomRight.column():
# Update name # Update name
self.updateNames() self.updateNames()
elif topLeft.column() <= Perso.importance.value <= bottomRight.column(): elif topLeft.column() <= Character.importance.value <= bottomRight.column():
# Importance changed # Importance changed
self.updateItems() self.updateItems()
@ -56,16 +60,17 @@ class persoTreeView(QTreeWidget):
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
item = self.topLevelItem(i) item = self.topLevelItem(i)
for c in range(item.childCount()): for child in range(item.childCount()):
sub = item.child(c) sub = item.child(child)
ID = sub.data(0, Qt.UserRole) ID = sub.data(0, Qt.UserRole)
if ID: if ID is not None:
# Update name # Update name
name = self._model.getPersoNameByID(ID) c = self._model.getCharacterByID(ID)
name = c.name()
sub.setText(0, name) sub.setText(0, name)
# Update icon # Update icon
px = QPixmap(32, 32) px = QPixmap(32, 32)
color = QColor(self._model.getPersoColorByID(ID)) color = c.color()
px.fill(color) px.fill(color)
sub.setIcon(0, QIcon(px)) sub.setIcon(0, QIcon(px))
@ -78,10 +83,12 @@ class persoTreeView(QTreeWidget):
self._updating = True self._updating = True
self.clear() self.clear()
persos = self._model.getPersosByImportance() characters = self._model.getCharactersByImportance()
h = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] h = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]
for i in range(3): for i in range(3):
# Create category item
cat = QTreeWidgetItem(self, [h[i]]) cat = QTreeWidgetItem(self, [h[i]])
cat.setBackground(0, QBrush(QColor(Qt.blue).lighter(190))) cat.setBackground(0, QBrush(QColor(Qt.blue).lighter(190)))
cat.setForeground(0, QBrush(Qt.darkBlue)) cat.setForeground(0, QBrush(Qt.darkBlue))
@ -92,23 +99,68 @@ class persoTreeView(QTreeWidget):
self.addTopLevelItem(cat) self.addTopLevelItem(cat)
# cat.setChildIndicatorPolicy(cat.DontShowIndicator) # cat.setChildIndicatorPolicy(cat.DontShowIndicator)
for ID in persos[i]: for c in characters[i]:
name = self._model.getPersoNameByID(ID) name = c.name()
# Check if name passes filter
if not self._filter.lower() in name.lower(): if not self._filter.lower() in name.lower():
continue continue
item = QTreeWidgetItem(cat, [name]) item = QTreeWidgetItem(cat, [name])
item.setData(0, Qt.UserRole, ID) item.setData(0, Qt.UserRole, c.ID())
px = QPixmap(32, 32) px = QPixmap(32, 32)
color = QColor(self._model.getPersoColorByID(ID)) color = QColor(c.color())
px.fill(color) px.fill(color)
item.setIcon(0, QIcon(px)) item.setIcon(0, QIcon(px))
if ID == self._lastID: if c.ID() == self._lastID:
self.setCurrentItem(item) self.setCurrentItem(item)
self.expandAll() self.expandAll()
self._updating = False self._updating = False
def removeCharacter(self):
"""
Removes selected character.
"""
ID = self.currentCharacterID()
if ID:
self._model.removeCharacter(ID)
def choseCharacterColor(self):
ID = self.currentCharacterID()
c = self._model.getCharacterByID(ID)
if c:
color = iconColor(c.icon)
else:
color = Qt.white
self.colorDialog = QColorDialog(color, mainWindow())
color = self.colorDialog.getColor(color)
if color.isValid():
c.setColor(color)
mainWindow().updateCharacterColor(ID)
def addCharacterInfo(self):
self._model.addCharacterInfo(self.currentCharacterID())
def removeCharacterInfo(self):
self._model.removeCharacterInfo(self.currentCharacterID(),
)
def currentCharacterID(self):
ID = None
if self.currentItem():
ID = self.currentItem().data(0, Qt.UserRole)
return ID
def currentCharacter(self):
"""
Returns the selected character
@return: Character
"""
ID = self.currentCharacterID()
return self._model.getCharacterByID(ID)
def getItemByID(self, ID): def getItemByID(self, ID):
for t in range(self.topLevelItemCount()): for t in range(self.topLevelItemCount()):
for i in range(self.topLevelItem(t).childCount()): for i in range(self.topLevelItem(t).childCount()):
@ -116,13 +168,6 @@ class persoTreeView(QTreeWidget):
if item.data(0, Qt.UserRole) == ID: if item.data(0, Qt.UserRole) == ID:
return item return item
def currentPersoIndex(self):
ID = None
if self.currentItem():
ID = self.currentItem().data(0, Qt.UserRole)
return self._model.getIndexFromID(ID)
def mouseDoubleClickEvent(self, event): def mouseDoubleClickEvent(self, event):
item = self.currentItem() item = self.currentItem()
# Catching double clicks to forbid collapsing of toplevel items # Catching double clicks to forbid collapsing of toplevel items

View file

@ -8,7 +8,7 @@ from manuskript.enums import Outline
from manuskript.functions import toInt from manuskript.functions import toInt
class cmbOutlinePersoChoser(QComboBox): class cmbOutlineCharacterChoser(QComboBox):
def __init__(self, parent=None): def __init__(self, parent=None):
QComboBox.__init__(self, parent) QComboBox.__init__(self, parent)
self.activated[int].connect(self.submit) self.activated[int].connect(self.submit)
@ -18,9 +18,12 @@ class cmbOutlinePersoChoser(QComboBox):
self._updating = False self._updating = False
self._various = False self._various = False
def setModels(self, mdlPersos, mdlOutline): def setModels(self, mdlCharacter, mdlOutline):
self.mdlPersos = mdlPersos self.mdlCharacters = mdlCharacter
self.mdlPersos.dataChanged.connect(self.updateItems) self.mdlCharacters.dataChanged.connect(self.updateItems)
self.mdlCharacters.rowsInserted.connect(self.updateItems)
self.mdlCharacters.rowsRemoved.connect(self.updateItems)
self.mdlOutline = mdlOutline self.mdlOutline = mdlOutline
self.mdlOutline.dataChanged.connect(self.update) self.mdlOutline.dataChanged.connect(self.update)
self.updateItems() self.updateItems()
@ -37,14 +40,14 @@ class cmbOutlinePersoChoser(QComboBox):
self.setItemData(self.count() - 1, QBrush(QColor(Qt.blue).lighter(190)), Qt.BackgroundRole) self.setItemData(self.count() - 1, QBrush(QColor(Qt.blue).lighter(190)), Qt.BackgroundRole)
item = self.model().item(self.count() - 1) item = self.model().item(self.count() - 1)
item.setFlags(Qt.ItemIsEnabled) item.setFlags(Qt.ItemIsEnabled)
for i in range(self.mdlPersos.rowCount()): for i in range(self.mdlCharacters.rowCount()):
imp = toInt(self.mdlPersos.importance(i)) imp = toInt(self.mdlCharacters.importance(i))
if not 2 - imp == importance: if not 2 - imp == importance:
continue continue
self.addItem(self.mdlPersos.icon(i), self.mdlPersos.name(i), self.mdlPersos.ID(i)) self.addItem(self.mdlCharacters.icon(i), self.mdlCharacters.name(i), self.mdlCharacters.ID(i))
self.setItemData(self.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole) self.setItemData(self.count() - 1, self.mdlCharacters.name(i), Qt.ToolTipRole)
self._various = False self._various = False

View file

@ -16,8 +16,8 @@ class metadataView(QWidget, Ui_metadataView):
self.txtNotes.setColumn(Outline.notes.value) self.txtNotes.setColumn(Outline.notes.value)
self.revisions.setEnabled(False) self.revisions.setEnabled(False)
def setModels(self, mdlOutline, mdlPersos, mdlLabels, mdlStatus): def setModels(self, mdlOutline, mdlCharacter, mdlLabels, mdlStatus):
self.properties.setModels(mdlOutline, mdlPersos, mdlLabels, mdlStatus) self.properties.setModels(mdlOutline, mdlCharacter, mdlLabels, mdlStatus)
self.txtSummarySentence.setModel(mdlOutline) self.txtSummarySentence.setModel(mdlOutline)
self.txtSummaryFull.setModel(mdlOutline) self.txtSummaryFull.setModel(mdlOutline)
self.txtNotes.setModel(mdlOutline) self.txtNotes.setModel(mdlOutline)

View file

@ -83,12 +83,12 @@ class outlineBasics(QAbstractItemView):
self.menuPOV.addMenu(m) self.menuPOV.addMenu(m)
mpr = QSignalMapper(self.menuPOV) mpr = QSignalMapper(self.menuPOV)
for i in range(mw.mdlPersos.rowCount()): for i in range(mw.mdlCharacter.rowCount()):
a = QAction(mw.mdlPersos.icon(i), mw.mdlPersos.name(i), self.menuPOV) a = QAction(mw.mdlCharacter.icon(i), mw.mdlCharacter.name(i), self.menuPOV)
a.triggered.connect(mpr.map) a.triggered.connect(mpr.map)
mpr.setMapping(a, int(mw.mdlPersos.ID(i))) mpr.setMapping(a, int(mw.mdlCharacter.ID(i)))
imp = toInt(mw.mdlPersos.importance(i)) imp = toInt(mw.mdlCharacter.importance(i))
menus[2 - imp].addAction(a) menus[2 - imp].addAction(a)

View file

@ -6,7 +6,7 @@ from PyQt5.QtWidgets import QStyledItemDelegate, QStyleOptionViewItem, QStyle, Q
from PyQt5.QtWidgets import qApp from PyQt5.QtWidgets import qApp
from manuskript import settings from manuskript import settings
from manuskript.enums import Perso, Outline from manuskript.enums import Character, Outline
from manuskript.functions import outlineItemColors, mixColors, colorifyPixmap, toInt, toFloat, drawProgress from manuskript.functions import outlineItemColors, mixColors, colorifyPixmap, toInt, toFloat, drawProgress
@ -92,18 +92,18 @@ class outlineTitleDelegate(QStyledItemDelegate):
# QStyledItemDelegate.paint(self, painter, option, index) # QStyledItemDelegate.paint(self, painter, option, index)
class outlinePersoDelegate(QStyledItemDelegate): class outlineCharacterDelegate(QStyledItemDelegate):
def __init__(self, mdlPersos, parent=None): def __init__(self, mdlCharacter, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self.mdlPersos = mdlPersos self.mdlCharacter = mdlCharacter
def sizeHint(self, option, index): def sizeHint(self, option, index):
# s = QStyledItemDelegate.sizeHint(self, option, index) # s = QStyledItemDelegate.sizeHint(self, option, index)
item = QModelIndex() item = QModelIndex()
for i in range(self.mdlPersos.rowCount()): character = self.mdlCharacter.getCharacterByID(index.data())
if self.mdlPersos.ID(i) == index.data(): if character:
item = self.mdlPersos.index(i, Perso.name.value) item = character.index(Character.name.value)
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, item) self.initStyleOption(opt, item)
@ -136,13 +136,13 @@ class outlinePersoDelegate(QStyledItemDelegate):
editor.setItemData(editor.count() - 1, QBrush(QColor(Qt.blue).lighter(190)), Qt.BackgroundRole) editor.setItemData(editor.count() - 1, QBrush(QColor(Qt.blue).lighter(190)), Qt.BackgroundRole)
item = editor.model().item(editor.count() - 1) item = editor.model().item(editor.count() - 1)
item.setFlags(Qt.ItemIsEnabled) item.setFlags(Qt.ItemIsEnabled)
for i in range(self.mdlPersos.rowCount()): for i in range(self.mdlCharacter.rowCount()):
imp = toInt(self.mdlPersos.importance(i)) imp = toInt(self.mdlCharacter.importance(i))
if not 2 - imp == importance: continue if not 2 - imp == importance: continue
# try: # try:
editor.addItem(self.mdlPersos.icon(i), self.mdlPersos.name(i), self.mdlPersos.ID(i)) editor.addItem(self.mdlCharacter.icon(i), self.mdlCharacter.name(i), self.mdlCharacter.ID(i))
editor.setItemData(editor.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole) editor.setItemData(editor.count() - 1, self.mdlCharacter.name(i), Qt.ToolTipRole)
# except: # except:
# pass # pass
@ -158,18 +158,21 @@ class outlinePersoDelegate(QStyledItemDelegate):
# QStyledItemDelegate.paint(self, painter, option, index) # QStyledItemDelegate.paint(self, painter, option, index)
##option.rect.setWidth(option.rect.width() + 18) ##option.rect.setWidth(option.rect.width() + 18)
item = QModelIndex() itemIndex = QModelIndex()
for i in range(self.mdlPersos.rowCount()): character = self.mdlCharacter.getCharacterByID(index.data())
if self.mdlPersos.ID(i) == index.data(): if character:
item = self.mdlPersos.index(i, Perso.name.value) itemIndex = character.index(Character.name.value)
else:
# Character ID not found in character model.
return
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, item) self.initStyleOption(opt, itemIndex)
qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter) qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
# if index.isValid() and index.internalPointer().data(Outline.POV.value) not in ["", None]: # if index.isValid() and index.internalPointer().data(Outline.POV.value) not in ["", None]:
if index.isValid() and self.mdlPersos.data(index) not in ["", None]: if itemIndex.isValid() and self.mdlCharacter.data(itemIndex) not in ["", None]:
opt = QStyleOptionComboBox() opt = QStyleOptionComboBox()
opt.rect = option.rect opt.rect = option.rect
r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow) r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow)

View file

@ -6,25 +6,25 @@ from manuskript import settings
from manuskript.enums import Outline from manuskript.enums import Outline
from manuskript.ui.views.dndView import dndView from manuskript.ui.views.dndView import dndView
from manuskript.ui.views.outlineBasics import outlineBasics from manuskript.ui.views.outlineBasics import outlineBasics
from manuskript.ui.views.outlineDelegates import outlineTitleDelegate, outlinePersoDelegate, outlineCompileDelegate, \ from manuskript.ui.views.outlineDelegates import outlineTitleDelegate, outlineCharacterDelegate, outlineCompileDelegate, \
outlineStatusDelegate, outlineGoalPercentageDelegate, outlineLabelDelegate outlineStatusDelegate, outlineGoalPercentageDelegate, outlineLabelDelegate
class outlineView(QTreeView, dndView, outlineBasics): class outlineView(QTreeView, dndView, outlineBasics):
def __init__(self, parent=None, modelPersos=None, modelLabels=None, modelStatus=None): def __init__(self, parent=None, modelCharacters=None, modelLabels=None, modelStatus=None):
QTreeView.__init__(self, parent) QTreeView.__init__(self, parent)
dndView.__init__(self) dndView.__init__(self)
outlineBasics.__init__(self, parent) outlineBasics.__init__(self, parent)
self.modelPersos = modelPersos self.modelCharacters = modelCharacters
self.modelLabels = modelLabels self.modelLabels = modelLabels
self.modelStatus = modelStatus self.modelStatus = modelStatus
self.header().setStretchLastSection(False) self.header().setStretchLastSection(False)
def setModelPersos(self, model): def setModelCharacters(self, model):
# This is used by outlinePersoDelegate to select character # This is used by outlineCharacterDelegate to select character
self.modelPersos = model self.modelCharacters = model
def setModelLabels(self, model): def setModelLabels(self, model):
# This is used by outlineLabelDelegate to display labels # This is used by outlineLabelDelegate to display labels
@ -41,8 +41,8 @@ class outlineView(QTreeView, dndView, outlineBasics):
self.outlineTitleDelegate = outlineTitleDelegate(self) self.outlineTitleDelegate = outlineTitleDelegate(self)
# self.outlineTitleDelegate.setView(self) # self.outlineTitleDelegate.setView(self)
self.setItemDelegateForColumn(Outline.title.value, self.outlineTitleDelegate) self.setItemDelegateForColumn(Outline.title.value, self.outlineTitleDelegate)
self.outlinePersoDelegate = outlinePersoDelegate(self.modelPersos) self.outlineCharacterDelegate = outlineCharacterDelegate(self.modelCharacters)
self.setItemDelegateForColumn(Outline.POV.value, self.outlinePersoDelegate) self.setItemDelegateForColumn(Outline.POV.value, self.outlineCharacterDelegate)
self.outlineCompileDelegate = outlineCompileDelegate() self.outlineCompileDelegate = outlineCompileDelegate()
self.setItemDelegateForColumn(Outline.compile.value, self.outlineCompileDelegate) self.setItemDelegateForColumn(Outline.compile.value, self.outlineCompileDelegate)
self.outlineStatusDelegate = outlineStatusDelegate(self.modelStatus) self.outlineStatusDelegate = outlineStatusDelegate(self.modelStatus)

View file

@ -12,8 +12,8 @@ class propertiesView(QWidget, Ui_propertiesView):
self.setupUi(self) self.setupUi(self)
self.txtGoal.setColumn(Outline.setGoal.value) self.txtGoal.setColumn(Outline.setGoal.value)
def setModels(self, mdlOutline, mdlPersos, mdlLabels, mdlStatus): def setModels(self, mdlOutline, mdlCharacter, mdlLabels, mdlStatus):
self.cmbPOV.setModels(mdlPersos, mdlOutline) self.cmbPOV.setModels(mdlCharacter, mdlOutline)
self.cmbLabel.setModels(mdlLabels, mdlOutline) self.cmbLabel.setModels(mdlLabels, mdlOutline)
self.cmbStatus.setModels(mdlStatus, mdlOutline) self.cmbStatus.setModels(mdlStatus, mdlOutline)
self.cmbType.setModel(mdlOutline) self.cmbType.setModel(mdlOutline)

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/views/propertiesView_ui.ui' # Form implementation generated from reading ui file 'manuskript/ui/views/propertiesView_ui.ui'
# #
# Created: Wed Mar 2 00:30:18 2016 # Created: Thu Mar 3 17:26:11 2016
# by: PyQt5 UI code generator 5.2.1 # by: PyQt5 UI code generator 5.2.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -37,7 +37,7 @@ class Ui_propertiesView(object):
self.lblPOV = QtWidgets.QLabel(self.page) self.lblPOV = QtWidgets.QLabel(self.page)
self.lblPOV.setObjectName("lblPOV") self.lblPOV.setObjectName("lblPOV")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lblPOV) self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lblPOV)
self.cmbPOV = cmbOutlinePersoChoser(self.page) self.cmbPOV = cmbOutlineCharacterChoser(self.page)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -116,7 +116,7 @@ class Ui_propertiesView(object):
self.lblPOV_2 = QtWidgets.QLabel(self.page_2) self.lblPOV_2 = QtWidgets.QLabel(self.page_2)
self.lblPOV_2.setObjectName("lblPOV_2") self.lblPOV_2.setObjectName("lblPOV_2")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lblPOV_2) self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lblPOV_2)
self.cmbPOVMulti = cmbOutlinePersoChoser(self.page_2) self.cmbPOVMulti = cmbOutlineCharacterChoser(self.page_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -195,9 +195,9 @@ class Ui_propertiesView(object):
self.label_36.setText(_translate("propertiesView", "Goal")) self.label_36.setText(_translate("propertiesView", "Goal"))
self.txtGoalMulti.setPlaceholderText(_translate("propertiesView", "Word count")) self.txtGoalMulti.setPlaceholderText(_translate("propertiesView", "Word count"))
from manuskript.ui.views.cmbOutlineStatusChoser import cmbOutlineStatusChoser
from manuskript.ui.views.lineEditView import lineEditView from manuskript.ui.views.lineEditView import lineEditView
from manuskript.ui.views.chkOutlineCompile import chkOutlineCompile from manuskript.ui.views.cmbOutlineCharacterChoser import cmbOutlineCharacterChoser
from manuskript.ui.views.cmbOutlineLabelChoser import cmbOutlineLabelChoser
from manuskript.ui.views.cmbOutlineTypeChoser import cmbOutlineTypeChoser from manuskript.ui.views.cmbOutlineTypeChoser import cmbOutlineTypeChoser
from manuskript.ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser from manuskript.ui.views.chkOutlineCompile import chkOutlineCompile
from manuskript.ui.views.cmbOutlineStatusChoser import cmbOutlineStatusChoser
from manuskript.ui.views.cmbOutlineLabelChoser import cmbOutlineLabelChoser

View file

@ -53,7 +53,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="cmbOutlinePersoChoser" name="cmbPOV"> <widget class="cmbOutlineCharacterChoser" name="cmbPOV">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -190,7 +190,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="cmbOutlinePersoChoser" name="cmbPOVMulti"> <widget class="cmbOutlineCharacterChoser" name="cmbPOVMulti">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -300,9 +300,9 @@
<header>manuskript.ui.views.lineEditView.h</header> <header>manuskript.ui.views.lineEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlinePersoChoser</class> <class>cmbOutlineCharacterChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>manuskript.ui.views.cmbOutlinePersoChoser.h</header> <header>manuskript.ui.views.cmbOutlineCharacterChoser.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlineStatusChoser</class> <class>cmbOutlineStatusChoser</class>

View file

@ -2,9 +2,9 @@
# --!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import pyqtSignal, pyqtProperty from PyQt5.QtCore import pyqtSignal, pyqtProperty
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from manuskript.ui.views.sldImportance_ui import Ui_sldImportance
from manuskript.functions import toInt from manuskript.functions import toInt
from manuskript.ui.sldImportance_ui import Ui_sldImportance
class sldImportance(QWidget, Ui_sldImportance): class sldImportance(QWidget, Ui_sldImportance):

View file

@ -1,12 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'manuskript/ui/sldImportance_ui.ui' # Form implementation generated from reading ui file 'manuskript/ui/views/sldImportance_ui.ui'
# #
# Created by: PyQt5 UI code generator 5.4.1 # Created: Thu Mar 3 18:52:22 2016
# by: PyQt5 UI code generator 5.2.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_sldImportance(object): class Ui_sldImportance(object):
def setupUi(self, sldImportance): def setupUi(self, sldImportance):

View file

@ -46,7 +46,7 @@ class storylineView(QWidget, Ui_storylineView):
self.btnSettings.setMenu(m) self.btnSettings.setMenu(m)
def setModels(self, mdlOutline, mdlPersos, mdlPlots): def setModels(self, mdlOutline, mdlCharacter, mdlPlots):
self._mdlPlots = mdlPlots self._mdlPlots = mdlPlots
# self._mdlPlots.dataChanged.connect(self.refresh) # self._mdlPlots.dataChanged.connect(self.refresh)
# self._mdlPlots.rowsInserted.connect(self.refresh) # self._mdlPlots.rowsInserted.connect(self.refresh)
@ -54,8 +54,8 @@ class storylineView(QWidget, Ui_storylineView):
self._mdlOutline = mdlOutline self._mdlOutline = mdlOutline
self._mdlOutline.dataChanged.connect(self.reloadTimer.start) self._mdlOutline.dataChanged.connect(self.reloadTimer.start)
self._mdlPersos = mdlPersos self._mdlCharacter = mdlCharacter
self._mdlPersos.dataChanged.connect(self.reloadTimer.start) self._mdlCharacter.dataChanged.connect(self.reloadTimer.start)
def plotReferences(self): def plotReferences(self):
"Returns a list of plot references" "Returns a list of plot references"
@ -71,22 +71,22 @@ class storylineView(QWidget, Ui_storylineView):
return r return r
def persosReferences(self): def charactersReferences(self):
"Returns a list of character references" "Returns a list of character references"
if not self._mdlPersos: if not self._mdlCharacter:
pass pass
IDs = self._mdlPersos.getPersosByImportance() chars = self._mdlCharacter.getCharactersByImportance()
r = [] r = []
for importance in IDs: for importance in chars:
for ID in importance: for c in importance:
ref = references.persoReference(ID) ref = references.characterReference(c.ID())
r.append(ref) r.append(ref)
return r return r
def refresh(self): def refresh(self):
if not self._mdlPlots or not self._mdlOutline or not self._mdlPersos: if not self._mdlPlots or not self._mdlOutline or not self._mdlCharacter:
pass pass
LINE_HEIGHT = 18 LINE_HEIGHT = 18
@ -118,7 +118,7 @@ class storylineView(QWidget, Ui_storylineView):
trackedItems += self.plotReferences() trackedItems += self.plotReferences()
if self.actCharacters.isChecked(): if self.actCharacters.isChecked():
trackedItems += self.persosReferences() trackedItems += self.charactersReferences()
ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING ) ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING )
@ -185,7 +185,7 @@ class storylineView(QWidget, Ui_storylineView):
# Tests if POV # Tests if POV
scenePOV = False # Will hold true of character is POV of the current text, not containing folder scenePOV = False # Will hold true of character is POV of the current text, not containing folder
if references.type(ref) == references.PersoLetter: if references.type(ref) == references.CharacterLetter:
ID = references.ID(ref) ID = references.ID(ref)
c = child c = child
while c: while c:
@ -221,8 +221,8 @@ class storylineView(QWidget, Ui_storylineView):
itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING) itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING)
for ref in trackedItems: for ref in trackedItems:
if references.type(ref) == references.PersoLetter: if references.type(ref) == references.CharacterLetter:
color = QColor(self._mdlPersos.getPersoColorByID(references.ID(ref))) color = self._mdlCharacter.getCharacterByID(references.ID(ref)).color()
else: else:
color = randomColor() color = randomColor()

View file

@ -12,9 +12,9 @@ from PyQt5.QtWidgets import QWidget, QAction, QFileDialog, QSpinBox, QLineEdit,
from manuskript import settings from manuskript import settings
from manuskript.enums import Outline from manuskript.enums import Outline
from manuskript.functions import mainWindow, iconFromColor, appPath from manuskript.functions import mainWindow, iconFromColor, appPath
from manuskript.models.characterModel import characterModel
from manuskript.models.outlineModel import outlineItem from manuskript.models.outlineModel import outlineItem
from manuskript.models.outlineModel import outlineModel from manuskript.models.outlineModel import outlineModel
from manuskript.models.persosModel import persosModel
from manuskript.models.plotModel import plotModel from manuskript.models.plotModel import plotModel
from manuskript.models.worldModel import worldModel from manuskript.models.worldModel import worldModel
from manuskript.ui.welcome_ui import Ui_welcome from manuskript.ui.welcome_ui import Ui_welcome
@ -345,7 +345,7 @@ class welcome(QWidget, Ui_welcome):
# Persos # Persos
# self.mw.mdlPersos = QStandardItemModel(0, 0, self.mw) # self.mw.mdlPersos = QStandardItemModel(0, 0, self.mw)
self.mw.mdlPersos = persosModel(self.mw) self.mw.mdlCharacter = characterModel(self.mw)
# self.mdlPersosProxy = None # persosProxyModel() # None # self.mdlPersosProxy = None # persosProxyModel() # None
# self.mw.mdlPersosProxy = persosProxyModel(self.mw) # self.mw.mdlPersosProxy = persosProxyModel(self.mw)