Skip to content

Commit

Permalink
Merge pull request #748 from TheJackiMonster/optional-pov
Browse files Browse the repository at this point in the history
Enabling/Disabling POV for a specific character
  • Loading branch information
TheJackiMonster committed Feb 19, 2021
2 parents ca5a987 + e8c61e7 commit e18944e
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 96 deletions.
1 change: 1 addition & 0 deletions manuskript/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Character(IntEnum):
summaryPara = 8
summaryFull = 9
notes = 10
pov = 11

class Plot(IntEnum):
name = 0
Expand Down
3 changes: 2 additions & 1 deletion manuskript/load_save/version_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@
(Character.name, "Name"),
(Character.ID, "ID"),
(Character.importance, "Importance"),
(Character.pov, "POV"),
(Character.motivation, "Motivation"),
(Character.goal, "Goal"),
(Character.conflict, "Conflict"),
(Character.epiphany, "Epiphany"),
(Character.summarySentence, "Phrase Summary"),
(Character.summaryPara, "Paragraph Summary"),
(Character.summaryFull, "Full Summary"),
(Character.notes, "Notes"),
(Character.notes, "Notes")
])

# If true, logs infos while saving and loading.
Expand Down
22 changes: 22 additions & 0 deletions manuskript/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ def changeCurrentCharacter(self, trash=None):
# Slider importance
self.updateCharacterImportance(c.ID())

# POV state
self.updateCharacterPOVState(c.ID())

# Character Infos
self.tblPersoInfos.setRootIndex(index)

Expand All @@ -366,6 +369,18 @@ def updateCharacterImportance(self, ID):
c = self.mdlCharacter.getCharacterByID(ID)
self.sldPersoImportance.setValue(int(c.importance()))

def updateCharacterPOVState(self, ID):
c = self.mdlCharacter.getCharacterByID(ID)
self.disconnectAll(self.chkPersoPOV.stateChanged, self.lstCharacters.changeCharacterPOVState)

if c.pov():
self.chkPersoPOV.setCheckState(Qt.Checked)
else:
self.chkPersoPOV.setCheckState(Qt.Unchecked)

self.chkPersoPOV.stateChanged.connect(self.lstCharacters.changeCharacterPOVState, F.AUC)
self.chkPersoPOV.setEnabled(len(self.mdlOutline.findItemsByPOV(ID)) == 0)

###############################################################################
# PLOTS
###############################################################################
Expand Down Expand Up @@ -935,9 +950,13 @@ def makeConnections(self):
self.tblPersoInfos.setModel(self.mdlCharacter)

self.btnAddPerso.clicked.connect(self.mdlCharacter.addCharacter, F.AUC)

try:
self.btnRmPerso.clicked.connect(self.lstCharacters.removeCharacter, F.AUC)

self.btnPersoColor.clicked.connect(self.lstCharacters.choseCharacterColor, F.AUC)
self.chkPersoPOV.stateChanged.connect(self.lstCharacters.changeCharacterPOVState, F.AUC)

self.btnPersoAddInfo.clicked.connect(self.lstCharacters.addCharacterInfo, F.AUC)
self.btnPersoRmInfo.clicked.connect(self.lstCharacters.removeCharacterInfo, F.AUC)
except TypeError:
Expand Down Expand Up @@ -1091,7 +1110,10 @@ def breakConnections(self):
# Characters
self.disconnectAll(self.btnAddPerso.clicked, self.mdlCharacter.addCharacter)
self.disconnectAll(self.btnRmPerso.clicked, self.lstCharacters.removeCharacter)

self.disconnectAll(self.btnPersoColor.clicked, self.lstCharacters.choseCharacterColor)
self.disconnectAll(self.chkPersoPOV.stateChanged, self.lstCharacters.changeCharacterPOVState)

self.disconnectAll(self.btnPersoAddInfo.clicked, self.lstCharacters.addCharacterInfo)
self.disconnectAll(self.btnPersoRmInfo.clicked, self.lstCharacters.removeCharacterInfo)

Expand Down
23 changes: 23 additions & 0 deletions manuskript/models/characterModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ def ID(self, row):
def importance(self, row):
return self.character(row).importance()

def pov(self, row):
return self.character(row).pov()

###############################################################################
# MODEL QUERIES
###############################################################################
Expand All @@ -143,8 +146,10 @@ def getCharactersByImportance(self):
@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):
Expand All @@ -153,6 +158,7 @@ def getCharacterByID(self, ID):
for c in self.characters:
if c.ID() == ID:
return c

return None

###############################################################################
Expand Down Expand Up @@ -231,6 +237,7 @@ def __init__(self, model, name="No name"):
self.assignUniqueID()
self.assignRandomColor()
self._data[C.importance.value] = "0"
self._data[C.pov.value] = "True"

self.infos = []

Expand Down Expand Up @@ -274,6 +281,22 @@ def color(self):
"""
return iconColor(self.icon)

def setPOVEnabled(self, enabled):
if enabled != self.pov():
if enabled:
self._data[C.pov.value] = 'True'
else:
self._data[C.pov.value] = 'False'

try:
self._model.dataChanged.emit(self.index(), self.index())
except:
# If it is the initialisation, won't be able to emit
pass

def pov(self):
return self._data[C.pov.value] == 'True'

def assignUniqueID(self, parent=QModelIndex()):
"""Assigns an unused character ID."""
vals = []
Expand Down
47 changes: 47 additions & 0 deletions manuskript/models/characterPOVModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex, QSortFilterProxyModel


class characterPOVModel(QSortFilterProxyModel):

def __init__(self, sourceModel, parent=None):
QSortFilterProxyModel.__init__(self, parent)

self.setSourceModel(sourceModel)

if sourceModel:
sourceModel.dataChanged.connect(self.sourceDataChanged)

def filterAcceptsRow(self, sourceRow, sourceParent):
return self.sourceModel().pov(sourceRow)

def rowToSource(self, row):
index = self.index(row, 0)
sourceIndex = self.mapToSource(index)
return sourceIndex.row()

def sourceDataChanged(self, topLeft, bottomRight):
self.invalidateFilter()

###############################################################################
# CHARACTER QUERIES
###############################################################################

def character(self, row):
return self.sourceModel().character(self.rowToSource(row))

def name(self, row):
return self.sourceModel().name(self.rowToSource(row))

def icon(self, row):
return self.sourceModel().icon(self.rowToSource(row))

def ID(self, row):
return self.sourceModel().ID(self.rowToSource(row))

def importance(self, row):
return self.sourceModel().importance(self.rowToSource(row))

def pov(self, row):
return self.sourceModel().pov(self.rowToSource(row))
96 changes: 54 additions & 42 deletions manuskript/ui/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

# Form implementation generated from reading ui file 'manuskript/ui/mainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.14.1
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
Expand Down Expand Up @@ -378,47 +380,77 @@ def setupUi(self, MainWindow):
self.scrollAreaPersoInfos.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.scrollAreaPersoInfos.setObjectName("scrollAreaPersoInfos")
self.scrollAreaPersoInfosWidget = QtWidgets.QWidget()
self.scrollAreaPersoInfosWidget.setGeometry(QtCore.QRect(0, 0, 204, 606))
self.scrollAreaPersoInfosWidget.setGeometry(QtCore.QRect(0, 0, 453, 695))
self.scrollAreaPersoInfosWidget.setObjectName("scrollAreaPersoInfosWidget")
self.formLayout_8 = QtWidgets.QFormLayout(self.scrollAreaPersoInfosWidget)
self.formLayout_8.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout_8.setObjectName("formLayout_8")
self.label_3 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_3.setObjectName("label_3")
self.formLayout_8.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_3)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.txtPersoName = lineEditView(self.scrollAreaPersoInfosWidget)
self.txtPersoName.setObjectName("txtPersoName")
self.horizontalLayout_3.addWidget(self.txtPersoName)
self.btnPersoColor = QtWidgets.QPushButton(self.scrollAreaPersoInfosWidget)
self.btnPersoColor.setText("")
self.btnPersoColor.setObjectName("btnPersoColor")
self.horizontalLayout_3.addWidget(self.btnPersoColor)
self.formLayout_8.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_3)
self.horizontalLayout_20 = QtWidgets.QHBoxLayout()
self.horizontalLayout_20.setObjectName("horizontalLayout_20")
self.sldPersoImportance = sldImportance(self.scrollAreaPersoInfosWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sldPersoImportance.sizePolicy().hasHeightForWidth())
self.sldPersoImportance.setSizePolicy(sizePolicy)
self.sldPersoImportance.setObjectName("sldPersoImportance")
self.horizontalLayout_20.addWidget(self.sldPersoImportance)
self.chkPersoPOV = QtWidgets.QCheckBox(self.scrollAreaPersoInfosWidget)
self.chkPersoPOV.setChecked(False)
self.chkPersoPOV.setAutoRepeat(False)
self.chkPersoPOV.setTristate(False)
self.chkPersoPOV.setObjectName("chkPersoPOV")
self.horizontalLayout_20.addWidget(self.chkPersoPOV)
self.formLayout_8.setLayout(4, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_20)
self.label_4 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_4.setObjectName("label_4")
self.formLayout_8.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
self.formLayout_8.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_4)
self.txtPersoMotivation = MDEditCompleter(self.scrollAreaPersoInfosWidget)
self.txtPersoMotivation.setObjectName("txtPersoMotivation")
self.formLayout_8.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.txtPersoMotivation)
self.formLayout_8.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.txtPersoMotivation)
self.label_5 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_5.setObjectName("label_5")
self.formLayout_8.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
self.formLayout_8.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_5)
self.txtPersoGoal = MDEditCompleter(self.scrollAreaPersoInfosWidget)
self.txtPersoGoal.setObjectName("txtPersoGoal")
self.formLayout_8.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.txtPersoGoal)
self.formLayout_8.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.txtPersoGoal)
self.label_6 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_6.setObjectName("label_6")
self.formLayout_8.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
self.formLayout_8.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_6)
self.txtPersoConflict = MDEditCompleter(self.scrollAreaPersoInfosWidget)
self.txtPersoConflict.setObjectName("txtPersoConflict")
self.formLayout_8.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.txtPersoConflict)
self.formLayout_8.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.txtPersoConflict)
self.label_7 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_7.setObjectName("label_7")
self.formLayout_8.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
self.formLayout_8.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_7)
self.txtPersoEpiphany = MDEditCompleter(self.scrollAreaPersoInfosWidget)
self.txtPersoEpiphany.setObjectName("txtPersoEpiphany")
self.formLayout_8.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.txtPersoEpiphany)
self.formLayout_8.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.txtPersoEpiphany)
self.label_24 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_24.setObjectName("label_24")
self.formLayout_8.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_24)
self.formLayout_8.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.label_24)
self.txtPersoSummarySentence = MDEditCompleter(self.scrollAreaPersoInfosWidget)
self.txtPersoSummarySentence.setObjectName("txtPersoSummarySentence")
self.formLayout_8.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.txtPersoSummarySentence)
self.formLayout_8.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.txtPersoSummarySentence)
self.label_8 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_8.setObjectName("label_8")
self.formLayout_8.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_8)
self.formLayout_8.setWidget(11, QtWidgets.QFormLayout.LabelRole, self.label_8)
self.txtPersoSummaryPara = MDEditCompleter(self.scrollAreaPersoInfosWidget)
self.txtPersoSummaryPara.setObjectName("txtPersoSummaryPara")
self.formLayout_8.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.txtPersoSummaryPara)
self.formLayout_8.setWidget(11, QtWidgets.QFormLayout.FieldRole, self.txtPersoSummaryPara)
self.horizontalLayout_21 = QtWidgets.QHBoxLayout()
self.horizontalLayout_21.setObjectName("horizontalLayout_21")
spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
Expand All @@ -429,31 +461,10 @@ def setupUi(self, MainWindow):
self.btnStepFour.setFlat(True)
self.btnStepFour.setObjectName("btnStepFour")
self.horizontalLayout_21.addWidget(self.btnStepFour)
self.formLayout_8.setLayout(10, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_21)
self.formLayout_8.setLayout(12, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_21)
self.label_18 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_18.setObjectName("label_18")
self.formLayout_8.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_18)
self.sldPersoImportance = sldImportance(self.scrollAreaPersoInfosWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sldPersoImportance.sizePolicy().hasHeightForWidth())
self.sldPersoImportance.setSizePolicy(sizePolicy)
self.sldPersoImportance.setObjectName("sldPersoImportance")
self.formLayout_8.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.sldPersoImportance)
self.label_3 = QtWidgets.QLabel(self.scrollAreaPersoInfosWidget)
self.label_3.setObjectName("label_3")
self.formLayout_8.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_3)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.txtPersoName = lineEditView(self.scrollAreaPersoInfosWidget)
self.txtPersoName.setObjectName("txtPersoName")
self.horizontalLayout_3.addWidget(self.txtPersoName)
self.btnPersoColor = QtWidgets.QPushButton(self.scrollAreaPersoInfosWidget)
self.btnPersoColor.setText("")
self.btnPersoColor.setObjectName("btnPersoColor")
self.horizontalLayout_3.addWidget(self.btnPersoColor)
self.formLayout_8.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_3)
self.formLayout_8.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_18)
self.scrollAreaPersoInfos.setWidget(self.scrollAreaPersoInfosWidget)
self.verticalLayout_20.addWidget(self.scrollAreaPersoInfos)
self.tabPersos.addTab(self.info, "")
Expand Down Expand Up @@ -745,7 +756,7 @@ def setupUi(self, MainWindow):
self.treeWorld.setRootIsDecorated(False)
self.treeWorld.setObjectName("treeWorld")
self.treeWorld.header().setVisible(False)
self.treeWorld.header().setDefaultSectionSize(0)
self.treeWorld.header().setDefaultSectionSize(25)
self.verticalLayout_32.addWidget(self.treeWorld)
self.horizontalLayout_19 = QtWidgets.QHBoxLayout()
self.horizontalLayout_19.setObjectName("horizontalLayout_19")
Expand Down Expand Up @@ -833,6 +844,7 @@ def setupUi(self, MainWindow):
self.layoutWidget = QtWidgets.QWidget(self.splitterOutlineH)
self.layoutWidget.setObjectName("layoutWidget")
self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget)
self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_14.setObjectName("verticalLayout_14")
self.splitterOutlineV = QtWidgets.QSplitter(self.layoutWidget)
self.splitterOutlineV.setOrientation(QtCore.Qt.Vertical)
Expand Down Expand Up @@ -1029,7 +1041,7 @@ def setupUi(self, MainWindow):
self.horizontalLayout_2.addWidget(self.stack)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1112, 30))
self.menubar.setGeometry(QtCore.QRect(0, 0, 1112, 24))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
Expand Down Expand Up @@ -1339,7 +1351,7 @@ def setupUi(self, MainWindow):

self.retranslateUi(MainWindow)
self.stack.setCurrentIndex(1)
self.tabMain.setCurrentIndex(0)
self.tabMain.setCurrentIndex(2)
self.tabSummary.setCurrentIndex(0)
self.tabPersos.setCurrentIndex(0)
self.tabPlot.setCurrentIndex(0)
Expand Down Expand Up @@ -1484,6 +1496,8 @@ def retranslateUi(self, MainWindow):
self.tabMain.setTabText(self.tabMain.indexOf(self.lytTabSummary), _translate("MainWindow", "Summary"))
self.groupBox.setTitle(_translate("MainWindow", "Names"))
self.txtPersosFilter.setPlaceholderText(_translate("MainWindow", "Filter"))
self.label_3.setText(_translate("MainWindow", "Name"))
self.chkPersoPOV.setText(_translate("MainWindow", "Allow POV"))
self.label_4.setText(_translate("MainWindow", "Motivation"))
self.label_5.setText(_translate("MainWindow", "Goal"))
self.label_6.setText(_translate("MainWindow", "Conflict"))
Expand All @@ -1492,7 +1506,6 @@ def retranslateUi(self, MainWindow):
self.label_8.setText(_translate("MainWindow", "<html><head/><body><p align=\"right\">One paragraph<br/>summary</p></body></html>"))
self.btnStepFour.setText(_translate("MainWindow", "Next"))
self.label_18.setText(_translate("MainWindow", "Importance"))
self.label_3.setText(_translate("MainWindow", "Name"))
self.tabPersos.setTabText(self.tabPersos.indexOf(self.info), _translate("MainWindow", "Basic info"))
self.btnStepSix.setText(_translate("MainWindow", "Next"))
self.tabPersos.setTabText(self.tabPersos.indexOf(self.tab_11), _translate("MainWindow", "Summary"))
Expand Down Expand Up @@ -1635,7 +1648,6 @@ def retranslateUi(self, MainWindow):
self.actFormatOrderedList.setText(_translate("MainWindow", "&Ordered list"))
self.actFormatList.setText(_translate("MainWindow", "&Unordered list"))
self.actFormatBlockquote.setText(_translate("MainWindow", "B&lockquote"))

from manuskript.ui.cheatSheet import cheatSheet
from manuskript.ui.editors.mainEditor import mainEditor
from manuskript.ui.search import search
Expand Down

0 comments on commit e18944e

Please sign in to comment.