mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-05-02 03:52:22 +12:00
Checkpoint: refactoring
This commit is contained in:
parent
ad01de4cd4
commit
04fc6a5ae4
|
@ -353,3 +353,17 @@ def customIcons():
|
|||
|
||||
def statusMessage(message, duration=5000):
|
||||
mainWindow().statusBar().showMessage(message, duration)
|
||||
|
||||
def inspect():
|
||||
"""
|
||||
Debugging tool. Call it to see a stack of calls up to that point.
|
||||
"""
|
||||
import inspect, os
|
||||
print("-----------------------")
|
||||
for s in inspect.stack()[1:]:
|
||||
print(" * {}:{} // {}".format(
|
||||
os.path.basename(s.filename),
|
||||
s.lineno,
|
||||
s.function))
|
||||
print(" " + "".join(s.code_context))
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
import locale
|
||||
|
||||
from PyQt5.QtCore import QAbstractItemModel, QMimeData
|
||||
from PyQt5.QtCore import QModelIndex
|
||||
from PyQt5.QtCore import QSize
|
||||
|
@ -10,22 +8,9 @@ from PyQt5.QtCore import QVariant
|
|||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QIcon, QFont
|
||||
from PyQt5.QtWidgets import QTextEdit, qApp
|
||||
|
||||
from manuskript import settings
|
||||
from lxml import etree as ET
|
||||
|
||||
from manuskript.enums import Outline
|
||||
from manuskript import enums
|
||||
from manuskript.functions import mainWindow, toInt, wordCount
|
||||
from manuskript.converters import HTML2PlainText
|
||||
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except:
|
||||
# Invalid locale, but not really a big deal because it's used only for
|
||||
# number formating
|
||||
pass
|
||||
import os
|
||||
|
||||
|
||||
class abstractItem():
|
||||
|
@ -53,12 +38,12 @@ class abstractItem():
|
|||
if xml is not None:
|
||||
self.setFromXML(xml)
|
||||
|
||||
if parent:
|
||||
parent.appendChild(self)
|
||||
|
||||
if ID:
|
||||
self._data[self.enum.ID] = ID
|
||||
|
||||
if parent:
|
||||
parent.appendChild(self)
|
||||
|
||||
#######################################################################
|
||||
# Model
|
||||
#######################################################################
|
||||
|
@ -107,7 +92,7 @@ class abstractItem():
|
|||
return self._data.get(self.enum.title, "")
|
||||
|
||||
def ID(self):
|
||||
return self._data.get(self.enum.ID, 0)
|
||||
return self._data.get(self.enum.ID)
|
||||
|
||||
def columnCount(self):
|
||||
return len(self.enum)
|
||||
|
@ -197,7 +182,7 @@ class abstractItem():
|
|||
###############################################################################
|
||||
|
||||
def getUniqueID(self, recursive=False):
|
||||
self.setData(Outline.ID, self._model.rootItem.findUniqueID())
|
||||
self.setData(self.enum.ID, self._model.rootItem.findUniqueID())
|
||||
|
||||
if recursive:
|
||||
for c in self.children():
|
||||
|
@ -241,109 +226,38 @@ class abstractItem():
|
|||
#######################################################################
|
||||
|
||||
def data(self, column, role=Qt.DisplayRole):
|
||||
|
||||
# print("Data: ", column, role)
|
||||
|
||||
# Return value in self._data
|
||||
if role == Qt.DisplayRole or role == Qt.EditRole:
|
||||
# if column == Outline.compile:
|
||||
# return self.data(column, Qt.CheckStateRole)
|
||||
return self._data.get(column, "")
|
||||
|
||||
if Outline(column) in self._data:
|
||||
return self._data[Outline(column)]
|
||||
|
||||
elif column == Outline.revisions:
|
||||
return []
|
||||
|
||||
else:
|
||||
return ""
|
||||
|
||||
elif role == Qt.DecorationRole and column == Outline.title:
|
||||
if self.customIcon():
|
||||
return QIcon.fromTheme(self.data(Outline.customIcon))
|
||||
if self.isFolder():
|
||||
return QIcon.fromTheme("folder")
|
||||
elif self.isMD():
|
||||
return QIcon.fromTheme("text-x-generic")
|
||||
|
||||
# elif role == Qt.ForegroundRole:
|
||||
# if self.isCompile() in [0, "0"]:
|
||||
# return QBrush(Qt.gray)
|
||||
|
||||
elif role == Qt.CheckStateRole and column == Outline.compile:
|
||||
# print(self.title(), self.compile())
|
||||
# if self._data[Outline(column)] and not self.compile():
|
||||
# return Qt.PartiallyChecked
|
||||
# else:
|
||||
return self._data[Outline(column)]
|
||||
|
||||
elif role == Qt.FontRole:
|
||||
f = QFont()
|
||||
if column == Outline.wordCount and self.isFolder():
|
||||
f.setItalic(True)
|
||||
elif column == Outline.goal and self.isFolder() and self.data(Outline.setGoal) == None:
|
||||
f.setItalic(True)
|
||||
if self.isFolder():
|
||||
f.setBold(True)
|
||||
return f
|
||||
# Or return QVariant
|
||||
return QVariant()
|
||||
|
||||
def setData(self, column, data, role=Qt.DisplayRole):
|
||||
if role not in [Qt.DisplayRole, Qt.EditRole, Qt.CheckStateRole]:
|
||||
print(column, column == Outline.text, data, role)
|
||||
return
|
||||
|
||||
if column == Outline.text and self.isFolder():
|
||||
# Folder have no text
|
||||
return
|
||||
|
||||
if column == Outline.goal:
|
||||
self._data[Outline.setGoal] = toInt(data) if toInt(data) > 0 else ""
|
||||
|
||||
# Checking if we will have to recount words
|
||||
updateWordCount = False
|
||||
if column in [Outline.wordCount, Outline.goal, Outline.setGoal]:
|
||||
updateWordCount = not Outline(column) in self._data or self._data[Outline(column)] != data
|
||||
|
||||
# Stuff to do before
|
||||
if column == Outline.text:
|
||||
self.addRevision()
|
||||
|
||||
# Setting data
|
||||
self._data[Outline(column)] = data
|
||||
self._data[column] = data
|
||||
|
||||
# Stuff to do afterwards
|
||||
if column == Outline.text:
|
||||
wc = wordCount(data)
|
||||
self.setData(Outline.wordCount, wc)
|
||||
self.emitDataChanged(cols=[Outline.text]) # new in 0.5.0
|
||||
|
||||
if column == Outline.compile:
|
||||
self.emitDataChanged(cols=[Outline.title, Outline.compile], recursive=True)
|
||||
|
||||
if column == Outline.customIcon:
|
||||
# If custom icon changed, we tell views to update title (so that icons
|
||||
# will be updated as well)
|
||||
self.emitDataChanged(cols=[Outline.title])
|
||||
|
||||
if updateWordCount:
|
||||
self.updateWordCount()
|
||||
# Emit signal
|
||||
self.emitDataChanged(cols=[column]) # new in 0.5.0
|
||||
|
||||
###############################################################################
|
||||
# XML
|
||||
###############################################################################
|
||||
|
||||
# We don't want to write some datas (computed)
|
||||
XMLExclude = [Outline.wordCount, Outline.goal, Outline.goalPercentage, Outline.revisions]
|
||||
XMLExclude = []
|
||||
# We want to force some data even if they're empty
|
||||
XMLForce = [Outline.compile]
|
||||
XMLForce = []
|
||||
|
||||
def toXML(self):
|
||||
"""
|
||||
Returns a string containing the item (and children) in XML.
|
||||
By default, saves all attributes from self.enum and lastPath.
|
||||
You can define in XMLExclude and XMLForce what you want to be
|
||||
excluded or forcibly included.
|
||||
"""
|
||||
item = ET.Element(self.name)
|
||||
|
||||
## We don't want to write some datas (computed)
|
||||
#exclude = [Outline.wordCount, Outline.goal, Outline.goalPercentage, Outline.revisions]
|
||||
## We want to force some data even if they're empty
|
||||
#force = [Outline.compile]
|
||||
|
||||
for attrib in self.enum:
|
||||
if attrib in self.XMLExclude:
|
||||
continue
|
||||
|
@ -351,72 +265,42 @@ class abstractItem():
|
|||
if val or attrib in self.XMLForce:
|
||||
item.set(attrib.name, str(val))
|
||||
|
||||
# Saving revisions
|
||||
rev = self.revisions()
|
||||
for r in rev:
|
||||
revItem = ET.Element("revision")
|
||||
revItem.set("timestamp", str(r[0]))
|
||||
revItem.set("text", r[1])
|
||||
item.append(revItem)
|
||||
|
||||
# Saving lastPath
|
||||
item.set("lastPath", self._lastPath)
|
||||
|
||||
# Additional stuff for subclasses
|
||||
item = self.toXMLProcessItem(item)
|
||||
|
||||
for i in self.childItems:
|
||||
item.append(ET.XML(i.toXML()))
|
||||
|
||||
return ET.tostring(item)
|
||||
|
||||
def toXML_(self):
|
||||
item = ET.Element("outlineItem")
|
||||
|
||||
for attrib in Outline:
|
||||
if attrib in exclude: continue
|
||||
val = self.data(attrib.value)
|
||||
if val or attrib in force:
|
||||
item.set(attrib.name, str(val))
|
||||
|
||||
# Saving revisions
|
||||
rev = self.revisions()
|
||||
for r in rev:
|
||||
revItem = ET.Element("revision")
|
||||
revItem.set("timestamp", str(r[0]))
|
||||
revItem.set("text", r[1])
|
||||
item.append(revItem)
|
||||
|
||||
# Saving lastPath
|
||||
item.set("lastPath", self._lastPath)
|
||||
|
||||
for i in self.childItems:
|
||||
item.append(ET.XML(i.toXML()))
|
||||
|
||||
return ET.tostring(item)
|
||||
def toXMLProcessItem(self, item):
|
||||
"""
|
||||
Subclass this to change the behavior of `toXML`.
|
||||
"""
|
||||
return item
|
||||
|
||||
def setFromXML(self, xml):
|
||||
root = ET.XML(xml)
|
||||
|
||||
for k in root.attrib:
|
||||
if k in Outline.__members__:
|
||||
# if k == Outline.compile:
|
||||
# self.setData(Outline.__members__[k], unicode(root.attrib[k]), Qt.CheckStateRole)
|
||||
# else:
|
||||
self.setData(Outline.__members__[k], str(root.attrib[k]))
|
||||
for k in self.enum:
|
||||
if k.name in root.attrib:
|
||||
self.setData(k, str(root.attrib[k.name]))
|
||||
|
||||
if "lastPath" in root.attrib:
|
||||
self._lastPath = root.attrib["lastPath"]
|
||||
|
||||
# If loading from an old file format, convert to md and remove html markup
|
||||
if self.type() in ["txt", "t2t"]:
|
||||
self.setData(Outline.type, "md")
|
||||
|
||||
elif self.type() == "html":
|
||||
self.setData(Outline.type, "md")
|
||||
self.setData(Outline.text, HTML2PlainText(self.data(Outline.text)))
|
||||
self.setData(Outline.notes, HTML2PlainText(self.data(Outline.notes)))
|
||||
self.setFromXMLProcessMore(root)
|
||||
|
||||
for child in root:
|
||||
if child.tag == "outlineItem":
|
||||
item = outlineItem(self._model, xml=ET.tostring(child), parent=self)
|
||||
elif child.tag == "revision":
|
||||
self.appendRevision(child.attrib["timestamp"], child.attrib["text"])
|
||||
if child.tag == self.name:
|
||||
item = self.__class__(self._model, xml=ET.tostring(child), parent=self)
|
||||
|
||||
def setFromXMLProcessMore(self, root):
|
||||
"""
|
||||
Additional stuff that subclasses must do with the XML to restore
|
||||
item.
|
||||
"""
|
||||
return
|
||||
|
|
|
@ -16,7 +16,6 @@ from lxml import etree as ET
|
|||
|
||||
from manuskript.enums import Outline
|
||||
from manuskript.functions import mainWindow, toInt, wordCount
|
||||
from manuskript.converters import HTML2PlainText
|
||||
from manuskript.models import outlineItem
|
||||
|
||||
try:
|
||||
|
@ -105,13 +104,13 @@ class abstractModel(QAbstractItemModel):
|
|||
item = search(self.rootItem)
|
||||
return item
|
||||
|
||||
def getIndexByID(self, ID):
|
||||
def getIndexByID(self, ID, column=0):
|
||||
"Returns the index of item whose ID is `ID`. If none, returns QModelIndex()."
|
||||
item = self.getItemByID(ID)
|
||||
if not item:
|
||||
return QModelIndex()
|
||||
else:
|
||||
return self.indexFromItem(item)
|
||||
return self.indexFromItem(item, column)
|
||||
|
||||
def parent(self, index=QModelIndex()):
|
||||
if not index.isValid():
|
||||
|
@ -369,6 +368,7 @@ class abstractModel(QAbstractItemModel):
|
|||
return False
|
||||
|
||||
items = self.decodeMimeData(data)
|
||||
|
||||
if items is None:
|
||||
return False
|
||||
|
||||
|
|
|
@ -1,12 +1,24 @@
|
|||
#!/usr/bin/env python
|
||||
# --!-- coding: utf8 --!--
|
||||
|
||||
import time
|
||||
import locale
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QFont, QIcon
|
||||
from PyQt5.QtWidgets import qApp
|
||||
from lxml import etree as ET
|
||||
from manuskript.models.abstractItem import abstractItem
|
||||
from manuskript import enums
|
||||
from manuskript.functions import mainWindow, toInt
|
||||
from manuskript import functions as F
|
||||
from manuskript import settings
|
||||
import time
|
||||
from manuskript.converters import HTML2PlainText
|
||||
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except:
|
||||
# Invalid locale, but not really a big deal because it's used only for
|
||||
# number formating
|
||||
pass
|
||||
|
||||
|
||||
class outlineItem(abstractItem):
|
||||
|
@ -20,7 +32,8 @@ class outlineItem(abstractItem):
|
|||
abstractItem.__init__(self, model, title, _type, xml, parent, ID)
|
||||
|
||||
self.defaultTextType = None
|
||||
self._data[self.enum.compile] = Qt.Checked
|
||||
if not self._data.get(self.enum.compile):
|
||||
self._data[self.enum.compile] = 2
|
||||
|
||||
#######################################################################
|
||||
# Properties
|
||||
|
@ -42,7 +55,7 @@ class outlineItem(abstractItem):
|
|||
return self.data(self.enum.text)
|
||||
|
||||
def compile(self):
|
||||
if self._data[self.enum.compile] in ["0", 0]:
|
||||
if self._data.get(self.enum.compile, 1) in ["0", 0]:
|
||||
return False
|
||||
elif self.parent():
|
||||
return self.parent().compile()
|
||||
|
@ -64,6 +77,87 @@ class outlineItem(abstractItem):
|
|||
def setCustomIcon(self, customIcon):
|
||||
self.setData(self.enum.customIcon, customIcon)
|
||||
|
||||
def wordCount(self):
|
||||
return self._data.get(self.enum.wordCount, 0)
|
||||
|
||||
#######################################################################
|
||||
# Data
|
||||
#######################################################################
|
||||
|
||||
def data(self, column, role=Qt.DisplayRole):
|
||||
|
||||
data = abstractItem.data(self, column, role)
|
||||
E = self.enum
|
||||
|
||||
if role == Qt.DisplayRole or role == Qt.EditRole:
|
||||
if column == E.revisions:
|
||||
return []
|
||||
|
||||
else:
|
||||
return data
|
||||
|
||||
elif role == Qt.DecorationRole and column == E.title:
|
||||
if self.customIcon():
|
||||
return QIcon.fromTheme(self.data(E.customIcon))
|
||||
if self.isFolder():
|
||||
return QIcon.fromTheme("folder")
|
||||
elif self.isText():
|
||||
return QIcon.fromTheme("text-x-generic")
|
||||
|
||||
elif role == Qt.CheckStateRole and column == E.compile:
|
||||
return Qt.Checked if self.compile() else Qt.Unchecked
|
||||
|
||||
elif role == Qt.FontRole:
|
||||
f = QFont()
|
||||
if column == E.wordCount and self.isFolder():
|
||||
f.setItalic(True)
|
||||
elif column == E.goal and self.isFolder() and not self.data(E.setGoal):
|
||||
f.setItalic(True)
|
||||
if self.isFolder():
|
||||
f.setBold(True)
|
||||
return f
|
||||
|
||||
def setData(self, column, data, role=Qt.DisplayRole):
|
||||
|
||||
E = self.enum
|
||||
|
||||
if column == E.text and self.isFolder():
|
||||
# Folder have no text
|
||||
return
|
||||
|
||||
if column == E.goal:
|
||||
self._data[E.setGoal] = F.toInt(data) if F.toInt(data) > 0 else ""
|
||||
|
||||
# Checking if we will have to recount words
|
||||
updateWordCount = False
|
||||
if column in [E.wordCount, E.goal, E.setGoal]:
|
||||
updateWordCount = not column in self._data or self._data[column] != data
|
||||
|
||||
# Stuff to do before
|
||||
if column == E.text:
|
||||
self.addRevision()
|
||||
|
||||
# Calling base class implementation
|
||||
abstractItem.setData(self, column, data, role)
|
||||
|
||||
# Stuff to do afterwards
|
||||
if column == E.text:
|
||||
wc = F.wordCount(data)
|
||||
self.setData(E.wordCount, wc)
|
||||
|
||||
if column == E.compile:
|
||||
# Title changes when compile changes
|
||||
self.emitDataChanged(cols=[E.title, E.compile],
|
||||
recursive=True)
|
||||
|
||||
if column == E.customIcon:
|
||||
# If custom icon changed, we tell views to update title (so that
|
||||
# icons will be updated as well)
|
||||
self.emitDataChanged(cols=[E.title])
|
||||
|
||||
if updateWordCount:
|
||||
self.updateWordCount()
|
||||
|
||||
#######################################################################
|
||||
# Wordcount
|
||||
#######################################################################
|
||||
|
@ -82,23 +176,23 @@ class outlineItem(abstractItem):
|
|||
"""Update word count for item and parents.
|
||||
If emit is False, no signal is emitted (sometimes cause segfault)"""
|
||||
if not self.isFolder():
|
||||
setGoal = toInt(self.data(self.enum.setGoal))
|
||||
goal = toInt(self.data(self.enum.goal))
|
||||
setGoal = F.toInt(self.data(self.enum.setGoal))
|
||||
goal = F.toInt(self.data(self.enum.goal))
|
||||
|
||||
if goal != setGoal:
|
||||
self._data[self.enum.goal] = setGoal
|
||||
if setGoal:
|
||||
wc = toInt(self.data(self.enum.wordCount))
|
||||
wc = F.toInt(self.data(self.enum.wordCount))
|
||||
self.setData(self.enum.goalPercentage, wc / float(setGoal))
|
||||
|
||||
else:
|
||||
wc = 0
|
||||
for c in self.children():
|
||||
wc += toInt(c.data(self.enum.wordCount))
|
||||
wc += F.toInt(c.data(self.enum.wordCount))
|
||||
self._data[self.enum.wordCount] = wc
|
||||
|
||||
setGoal = toInt(self.data(self.enum.setGoal))
|
||||
goal = toInt(self.data(self.enum.goal))
|
||||
setGoal = F.toInt(self.data(self.enum.setGoal))
|
||||
goal = F.toInt(self.data(self.enum.goal))
|
||||
|
||||
if setGoal:
|
||||
if goal != setGoal:
|
||||
|
@ -107,7 +201,7 @@ class outlineItem(abstractItem):
|
|||
else:
|
||||
goal = 0
|
||||
for c in self.children():
|
||||
goal += toInt(c.data(self.enum.goal))
|
||||
goal += F.toInt(c.data(self.enum.goal))
|
||||
self._data[self.enum.goal] = goal
|
||||
|
||||
if goal:
|
||||
|
@ -123,9 +217,9 @@ class outlineItem(abstractItem):
|
|||
self.parent().updateWordCount(emit)
|
||||
|
||||
def stats(self):
|
||||
wc = self.data(Outline.wordCount)
|
||||
goal = self.data(Outline.goal)
|
||||
progress = self.data(Outline.goalPercentage)
|
||||
wc = self.data(enums.Outline.wordCount)
|
||||
goal = self.data(enums.Outline.goal)
|
||||
progress = self.data(enums.Outline.goalPercentage)
|
||||
if not wc:
|
||||
wc = 0
|
||||
if goal:
|
||||
|
@ -242,7 +336,8 @@ class outlineItem(abstractItem):
|
|||
|
||||
return lst
|
||||
|
||||
def findItemsContaining(self, text, columns, mainWindow=mainWindow(), caseSensitive=False, recursive=True):
|
||||
def findItemsContaining(self, text, columns, mainWindow=F.mainWindow(),
|
||||
caseSensitive=False, recursive=True):
|
||||
"""Returns a list if IDs of all subitems
|
||||
containing ``text`` in columns ``columns``
|
||||
(being a list of int).
|
||||
|
@ -255,7 +350,8 @@ class outlineItem(abstractItem):
|
|||
|
||||
return lst
|
||||
|
||||
def itemContains(self, text, columns, mainWindow=mainWindow(), caseSensitive=False):
|
||||
def itemContains(self, text, columns, mainWindow=F.mainWindow(),
|
||||
caseSensitive=False):
|
||||
lst = []
|
||||
text = text.lower() if not caseSensitive else text
|
||||
for c in columns:
|
||||
|
@ -269,10 +365,10 @@ class outlineItem(abstractItem):
|
|||
print("Character POV not found:", self.POV())
|
||||
|
||||
elif c == self.enum.status:
|
||||
searchIn = mainWindow.mdlStatus.item(toInt(self.status()), 0).text()
|
||||
searchIn = mainWindow.mdlStatus.item(F.toInt(self.status()), 0).text()
|
||||
|
||||
elif c == self.enum.label:
|
||||
searchIn = mainWindow.mdlLabels.item(toInt(self.label()), 0).text()
|
||||
searchIn = mainWindow.mdlLabels.item(F.toInt(self.label()), 0).text()
|
||||
|
||||
else:
|
||||
searchIn = self.data(c)
|
||||
|
@ -309,7 +405,7 @@ class outlineItem(abstractItem):
|
|||
|
||||
self.appendRevision(
|
||||
time.time(),
|
||||
self._data[self.enum.text])
|
||||
self.text())
|
||||
|
||||
if settings.revisions["smartremove"]:
|
||||
self.cleanRevisions()
|
||||
|
@ -358,7 +454,44 @@ class outlineItem(abstractItem):
|
|||
self._data[self.enum.revisions] = rev2
|
||||
self.emitDataChanged([self.enum.revisions])
|
||||
|
||||
#######################################################################
|
||||
# XML
|
||||
#######################################################################
|
||||
|
||||
# We don't want to write some datas (computed)
|
||||
XMLExclude = [enums.Outline.wordCount,
|
||||
enums.Outline.goal,
|
||||
enums.Outline.goalPercentage,
|
||||
enums.Outline.revisions]
|
||||
# We want to force some data even if they're empty
|
||||
XMLForce = [enums.Outline.compile]
|
||||
|
||||
def toXMLProcessItem(self, item):
|
||||
|
||||
# Saving revisions
|
||||
rev = self.revisions()
|
||||
for r in rev:
|
||||
revItem = ET.Element("revision")
|
||||
revItem.set("timestamp", str(r[0]))
|
||||
revItem.set("text", r[1])
|
||||
item.append(revItem)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
def setFromXMLProcessMore(self, root):
|
||||
|
||||
# If loading from an old file format, convert to md and
|
||||
# remove html markup
|
||||
if self.type() in ["txt", "t2t"]:
|
||||
self.setData(Outline.type, "md")
|
||||
|
||||
elif self.type() == "html":
|
||||
self.setData(Outline.type, "md")
|
||||
self.setData(Outline.text, HTML2PlainText(self.data(Outline.text)))
|
||||
self.setData(Outline.notes, HTML2PlainText(self.data(Outline.notes)))
|
||||
|
||||
# Revisions
|
||||
for child in root:
|
||||
if child.tag == "revision":
|
||||
self.appendRevision(child.attrib["timestamp"], child.attrib["text"])
|
||||
|
|
|
@ -43,13 +43,7 @@ class chkOutlineCompile(QCheckBox):
|
|||
|
||||
def getCheckedValue(self, index):
|
||||
item = index.internalPointer()
|
||||
c = item.data(Outline.compile)
|
||||
if c:
|
||||
c = int(c)
|
||||
else:
|
||||
c = Qt.Unchecked
|
||||
|
||||
return c
|
||||
return Qt.Checked if item.compile() else Qt.Unchecked
|
||||
|
||||
def update(self, topLeft, bottomRight):
|
||||
|
||||
|
|
|
@ -31,8 +31,10 @@ class outlineBasics(QAbstractItemView):
|
|||
if event.button() == Qt.RightButton:
|
||||
self.menu = self.makePopupMenu()
|
||||
self.menu.popup(event.globalPos())
|
||||
else:
|
||||
QAbstractItemView.mouseReleaseEvent(self, event)
|
||||
# We don't call QAbstractItemView.mouseReleaseEvent because
|
||||
# outlineBasics is never subclassed alone. So the others views
|
||||
# (outlineView, corkView, treeView) that subclass outlineBasics
|
||||
# call their respective mother class.
|
||||
|
||||
def makePopupMenu(self):
|
||||
index = self.currentIndex()
|
||||
|
|
|
@ -195,6 +195,9 @@ class outlineCompileDelegate(QStyledItemDelegate):
|
|||
def displayText(self, value, locale):
|
||||
return ""
|
||||
|
||||
#def createEditor(self, parent, option, index):
|
||||
#return None
|
||||
|
||||
|
||||
class outlineGoalPercentageDelegate(QStyledItemDelegate):
|
||||
def __init__(self, rootIndex=None, parent=None):
|
||||
|
|
|
@ -39,6 +39,10 @@ class textEditView(QTextEdit):
|
|||
self.setAcceptRichText(False)
|
||||
# When setting up a theme, this becomes true.
|
||||
self._fromTheme = False
|
||||
# Sometimes we need to update index because item has changed its
|
||||
# position, so we only have it's ID as reference. We store it to
|
||||
# update at the propper time.
|
||||
self._updateIndexFromID = None
|
||||
|
||||
self.spellcheck = spellcheck
|
||||
self.currentDict = dict if dict else settings.dict
|
||||
|
@ -271,7 +275,15 @@ class textEditView(QTextEdit):
|
|||
if self._updating:
|
||||
return
|
||||
|
||||
elif self._index and self._index.isValid():
|
||||
if self._updateIndexFromID:
|
||||
# We have to update to a new index
|
||||
self._index = self._index.model().getIndexByID(
|
||||
self._updateIndexFromID,
|
||||
self._column)
|
||||
self._updateIndexFromID = None
|
||||
|
||||
if self._index and self._index.isValid():
|
||||
|
||||
if topLeft.parent() != self._index.parent():
|
||||
return
|
||||
|
||||
|
@ -294,13 +306,34 @@ class textEditView(QTextEdit):
|
|||
self.updateText()
|
||||
|
||||
def rowsAboutToBeRemoved(self, parent, first, last):
|
||||
if self._index:
|
||||
if self._index and self._index.isValid():
|
||||
|
||||
# Has my _index just been removed?
|
||||
if self._index.parent() == parent and \
|
||||
first <= self._index.row() <= last:
|
||||
self._index = None
|
||||
self.setEnabled(False)
|
||||
return
|
||||
# FIXME: self._indexes
|
||||
|
||||
# We check if item is a child of the row about to be removed
|
||||
child = False
|
||||
p = self._index.parent()
|
||||
while p:
|
||||
if p == parent:
|
||||
child = True
|
||||
p = None
|
||||
elif p.isValid():
|
||||
p = p.parent()
|
||||
else:
|
||||
p = None
|
||||
if child:
|
||||
# Item might have moved (so will not be valid any more)
|
||||
ID = self._index.internalPointer().ID()
|
||||
# We store ID, and we update it in self.update (after the
|
||||
# rows have been removed).
|
||||
self._updateIndexFromID = ID
|
||||
|
||||
def disconnectDocument(self):
|
||||
try:
|
||||
self.document().contentsChanged.disconnect(self.updateTimer.start)
|
||||
|
|
|
@ -94,7 +94,7 @@ class treeTitleDelegate(QStyledItemDelegate):
|
|||
# If text color is Compile and item is selected, we have
|
||||
# to change the color
|
||||
if settings.viewSettings["Outline"]["Text"] == "Compile" and \
|
||||
item.compile() in [0, "0"]:
|
||||
not item.compile():
|
||||
col = mixColors(textColor, QColor(S.window))
|
||||
painter.setPen(col)
|
||||
f = QFont(opt.font)
|
||||
|
@ -109,7 +109,7 @@ class treeTitleDelegate(QStyledItemDelegate):
|
|||
extraText = item.childCount()
|
||||
extraText = " [{}]".format(extraText)
|
||||
elif settings.viewSettings["Tree"]["InfoFolder"] == "WC":
|
||||
extraText = item.data(Outline.wordCount)
|
||||
extraText = item.wordCount()
|
||||
extraText = " ({})".format(extraText)
|
||||
elif settings.viewSettings["Tree"]["InfoFolder"] == "Progress":
|
||||
extraText = int(toFloat(item.data(Outline.goalPercentage)) * 100)
|
||||
|
@ -122,7 +122,7 @@ class treeTitleDelegate(QStyledItemDelegate):
|
|||
|
||||
if item.isText() and settings.viewSettings["Tree"]["InfoText"] != "Nothing":
|
||||
if settings.viewSettings["Tree"]["InfoText"] == "WC":
|
||||
extraText = item.data(Outline.wordCount)
|
||||
extraText = item.wordCount()
|
||||
extraText = " ({})".format(extraText)
|
||||
elif settings.viewSettings["Tree"]["InfoText"] == "Progress":
|
||||
extraText = int(toFloat(item.data(Outline.goalPercentage)) * 100)
|
||||
|
|
Loading…
Reference in a new issue