Cleaning up imports, at last

This commit is contained in:
Olivier Keshavjee 2016-02-06 12:34:22 +01:00
parent 9f0f60067a
commit 69e0ca93be
83 changed files with 3189 additions and 3032 deletions

View file

@ -1,4 +1,4 @@
UI := $(wildcard src/ui/*.ui) $(wildcard src/ui/*/*.ui) $(wildcard src/ui/*.qrc) UI := $(wildcard manuskript/ui/*.ui) $(wildcard manuskript/ui/*/*.ui) $(wildcard manuskript/ui/*.qrc)
UIs= $(UI:.ui=.py) $(UI:.qrc=_rc.py) UIs= $(UI:.ui=.py) $(UI:.qrc=_rc.py)
TS := $(wildcard i18n/*.ts) TS := $(wildcard i18n/*.ts)
QMs= $(TS:.ts=.qm) QMs= $(TS:.ts=.qm)
@ -6,22 +6,23 @@ QMs= $(TS:.ts=.qm)
ui: $(UIs) ui: $(UIs)
run: $(UIs) run: $(UIs)
python3 src/main.py # python3 manuskript/main.py
bin/manuskript
debug: $(UIs) debug: $(UIs)
gdb --args python3 src/main.py gdb --args python3 manuskript/main.py
lineprof: lineprof:
kernprof -l -v src/main.py kernprof -l -v manuskript/main.py
profile: profile:
python3 -m cProfile -s 'cumtime' src/main.py | more python3 -m cProfile -s 'cumtime' manuskript/main.py | more
compile: compile:
cd src && python3 setup.py build_ext --inplace cd manuskript && python3 setup.py build_ext --inplace
callgraph: callgraph:
cd src; pycallgraph myoutput -- main.py cd manuskript; pycallgraph myoutput -- main.py
translation: translation:
pylupdate5 -noobsolete i18n/manuskript.pro pylupdate5 -noobsolete i18n/manuskript.pro

View file

@ -1,31 +1,32 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
import collections import collections
from qt import *
from .html import htmlExporter from PyQt5.QtWidgets import qApp
from .arbo import arboExporter
from .odt import odtExporter from manuskript.exporter.arbo import arboExporter
from manuskript.exporter.html import htmlExporter
from manuskript.exporter.odt import odtExporter
formats = collections.OrderedDict([ formats = collections.OrderedDict([
#Format # Format
# Readable name # Readable name
# Class # Class
# QFileDialog filter # QFileDialog filter
('html', ( ('html', (
qApp.translate("exporter", "HTML"), qApp.translate("exporter", "HTML"),
htmlExporter, htmlExporter,
qApp.translate("exporter", "HTML Document (*.html)"))), qApp.translate("exporter", "HTML Document (*.html)"))),
('arbo', ( ('arbo', (
qApp.translate("exporter", "Arborescence"), qApp.translate("exporter", "Arborescence"),
arboExporter, arboExporter,
None)), None)),
('odt', ( ('odt', (
qApp.translate("exporter", "OpenDocument (LibreOffice)"), qApp.translate("exporter", "OpenDocument (LibreOffice)"),
odtExporter, odtExporter,
qApp.translate("exporter", "OpenDocument (*.odt)"))), qApp.translate("exporter", "OpenDocument (*.odt)"))),
('epub', ( ('epub', (
"ePub (not yet)", "ePub (not yet)",
None, None,
None)), None)),
]) ])

View file

@ -1,53 +1,48 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
import os
from qt import *
from enums import * from manuskript.functions import mainWindow
from functions import *
class arboExporter(): class arboExporter():
requires = ["path"] requires = ["path"]
def __init__(self): def __init__(self):
pass pass
def doCompile(self, path): def doCompile(self, path):
#FIXME: overwrites when items have identical names # FIXME: overwrites when items have identical names
mw = mainWindow() mw = mainWindow()
root = mw.mdlOutline.rootItem root = mw.mdlOutline.rootItem
def writeItem(item, path): def writeItem(item, path):
if item.isFolder(): if item.isFolder():
path2 = os.path.join(path, item.title()) path2 = os.path.join(path, item.title())
try: try:
os.mkdir(path2) os.mkdir(path2)
except FileExistsError: except FileExistsError:
pass pass
for c in item.children(): for c in item.children():
writeItem(c, path2) writeItem(c, path2)
else: else:
ext = ".t2t" if item.isT2T() else \ ext = ".t2t" if item.isT2T() else \
".html" if item.isHTML() else \ ".html" if item.isHTML() else \
".txt" ".txt"
path2 = os.path.join(path, item.title() + ext) path2 = os.path.join(path, item.title() + ext)
f = open(path2, "w") f = open(path2, "w")
text = self.formatText(item.text(), item.type()) text = self.formatText(item.text(), item.type())
f.write(text) f.write(text)
for c in root.children(): for c in root.children():
writeItem(c, path) writeItem(c, path)
def formatText(self, text, _type): def formatText(self, text, _type):
if _type == "t2t": if _type == "t2t":
# Empty lines for headers # Empty lines for headers
text = "\n\n\n" + text text = "\n\n\n" + text
return text return text

View file

@ -1,31 +1,28 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from functions import *
import subprocess
import re import re
import subprocess
class basicExporter(): class basicExporter():
def __init__(self): def __init__(self):
pass pass
def runT2T(self, text, target="html"): def runT2T(self, text, target="html"):
cmdl = ['txt2tags', '-t', target, '--enc=utf-8', '--no-headers', '-o', '-', '-'] cmdl = ['txt2tags', '-t', target, '--enc=utf-8', '--no-headers', '-o', '-', '-']
cmd = subprocess.Popen(('echo', text), stdout=subprocess.PIPE) cmd = subprocess.Popen(('echo', text), stdout=subprocess.PIPE)
try: try:
output = subprocess.check_output(cmdl, stdin=cmd.stdout, stderr=subprocess.STDOUT) # , cwd="/tmp" output = subprocess.check_output(cmdl, stdin=cmd.stdout, stderr=subprocess.STDOUT) # , cwd="/tmp"
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print("Error!") print("Error!")
return text return text
cmd.wait() cmd.wait()
return output.decode("utf-8") return output.decode("utf-8")
def htmlBody(self, text): def htmlBody(self, text):
text = text.replace("\n", "") text = text.replace("\n", "")
text = re.sub(r".*<body[^>]*?>(.*)</body>.*", "\\1", text) text = re.sub(r".*<body[^>]*?>(.*)</body>.*", "\\1", text)

View file

@ -1,45 +1,41 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from manuskript.exporter.basic import basicExporter
from qt import * from manuskript.functions import mainWindow
from enums import *
from functions import *
from exporter.basic import basicExporter
class htmlExporter(basicExporter): class htmlExporter(basicExporter):
requires = ["filename"] requires = ["filename"]
def __init__(self): def __init__(self):
pass pass
def doCompile(self, filename): def doCompile(self, filename):
mw = mainWindow() mw = mainWindow()
root = mw.mdlOutline.rootItem root = mw.mdlOutline.rootItem
html = "" html = ""
def appendItem(item): def appendItem(item):
if item.isFolder(): if item.isFolder():
html = "" html = ""
title = "<h{l}>{t}</h{l}>\n".format( title = "<h{l}>{t}</h{l}>\n".format(
l = str(item.level() + 1), l=str(item.level() + 1),
t = item.title()) t=item.title())
html += title html += title
for c in item.children(): for c in item.children():
html += appendItem(c) html += appendItem(c)
return html return html
else: else:
text = self.formatText(item.text(), item.type()) text = self.formatText(item.text(), item.type())
return text return text
for c in root.children(): for c in root.children():
html += appendItem(c) html += appendItem(c)
template = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" template = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
@ -51,25 +47,25 @@ class htmlExporter(basicExporter):
{BODY} {BODY}
</body> </body>
</html>""" </html>"""
f = open(filename, "w") f = open(filename, "w")
f.write(template.format( f.write(template.format(
TITLE="FIXME", TITLE="FIXME",
BODY=html)) BODY=html))
def formatText(self, text, _type): def formatText(self, text, _type):
if not text: if not text:
return text return text
if _type == "t2t": if _type == "t2t":
text = self.runT2T(text) text = self.runT2T(text)
elif _type == "txt": elif _type == "txt":
text = text.replace("\n", "<br>") text = text.replace("\n", "<br>")
elif _type == "html": elif _type == "html":
# keep only body # keep only body
text = self.htmlBody(text) text = self.htmlBody(text)
return text + "<br>" return text + "<br>"

View file

@ -1,75 +1,74 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
import os
from qt import * import sys
from enums import *
from functions import * from PyQt5.QtGui import QTextDocument
from exporter.basic import basicExporter
from libs.odf.opendocument import OpenDocumentText
from libs.odf.text import H, P
from manuskript.exporter.basic import basicExporter
from manuskript.functions import appPath
from manuskript.functions import mainWindow
import sys, os
sys.path.append(os.path.join(appPath(), "libs")) sys.path.append(os.path.join(appPath(), "libs"))
from odf.opendocument import OpenDocumentText
from odf.style import Style, TextProperties
from odf.text import H, P, Span
class odtExporter(basicExporter): class odtExporter(basicExporter):
requires = ["filename"] requires = ["filename"]
def __init__(self): def __init__(self):
pass pass
def doCompile(self, filename): def doCompile(self, filename):
mw = mainWindow() mw = mainWindow()
root = mw.mdlOutline.rootItem root = mw.mdlOutline.rootItem
doc = OpenDocumentText() doc = OpenDocumentText()
def appendItem(item): def appendItem(item):
if item.isFolder(): if item.isFolder():
self.addHeading(item.title(), item.level() + 1, doc) self.addHeading(item.title(), item.level() + 1, doc)
for c in item.children(): for c in item.children():
appendItem(c) appendItem(c)
else: else:
text = self.formatText(item.text(), item.type()) text = self.formatText(item.text(), item.type())
if text: if text:
for l in text.split("\n"): for l in text.split("\n"):
self.addParagraph(l, doc) self.addParagraph(l, doc)
for c in root.children(): for c in root.children():
appendItem(c) appendItem(c)
doc.save(filename) doc.save(filename)
def formatText(self, text, _type): def formatText(self, text, _type):
if not text: if not text:
return text return text
#if _type == "t2t": # if _type == "t2t":
#text = self.runT2T(text) # text = self.runT2T(text)
#elif _type == "txt": # elif _type == "txt":
#text = text.replace("\n", "<br>") # text = text.replace("\n", "<br>")
elif _type == "html": elif _type == "html":
doc = QTextDocument() doc = QTextDocument()
doc.setHtml(text) doc.setHtml(text)
text = doc.toPlainText() text = doc.toPlainText()
#text = self.htmlBody(text) # text = self.htmlBody(text)
return text return text
def addHeading(self, text, level, doc): def addHeading(self, text, level, doc):
doc.text.addElement(H(outlinelevel=int(level), text=text)) doc.text.addElement(H(outlinelevel=int(level), text=text))
return doc return doc
def addParagraph(self, text, doc): def addParagraph(self, text, doc):
p = P(stylename="Text Body", text=text) p = P(stylename="Text Body", text=text)
doc.text.addElement(p) doc.text.addElement(p)
return doc return doc

View file

@ -1,61 +1,59 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtGui import QTextDocument, QTextCursor, QTextDocumentWriter
from qt import *
from enums import * from manuskript.exporter.basic import basicExporter
from functions import * from manuskript.functions import mainWindow
from exporter.basic import basicExporter
class odtExporter(basicExporter): class odtExporter(basicExporter):
requires = ["filename"] requires = ["filename"]
def __init__(self): def __init__(self):
pass pass
def doCompile(self, filename): def doCompile(self, filename):
mw = mainWindow() mw = mainWindow()
root = mw.mdlOutline.rootItem root = mw.mdlOutline.rootItem
doc = QTextDocument() doc = QTextDocument()
cursor = QTextCursor(doc) cursor = QTextCursor(doc)
def appendItem(item): def appendItem(item):
if item.isFolder(): if item.isFolder():
cursor.setPosition(doc.characterCount() - 1) cursor.setPosition(doc.characterCount() - 1)
title = "<h{l}>{t}</h{l}><br>\n".format( title = "<h{l}>{t}</h{l}><br>\n".format(
l = str(item.level() + 1), l=str(item.level() + 1),
t = item.title()) t=item.title())
cursor.insertHtml(title) cursor.insertHtml(title)
for c in item.children(): for c in item.children():
appendItem(c) appendItem(c)
else: else:
text = self.formatText(item.text(), item.type()) text = self.formatText(item.text(), item.type())
cursor.setPosition(doc.characterCount() - 1) cursor.setPosition(doc.characterCount() - 1)
cursor.insertHtml(text) cursor.insertHtml(text)
for c in root.children(): for c in root.children():
appendItem(c) appendItem(c)
dw = QTextDocumentWriter(filename, "odt") dw = QTextDocumentWriter(filename, "odt")
dw.write(doc) dw.write(doc)
def formatText(self, text, _type): def formatText(self, text, _type):
if not text: if not text:
return text return text
if _type == "t2t": if _type == "t2t":
text = self.runT2T(text) text = self.runT2T(text)
elif _type == "txt": elif _type == "txt":
text = text.replace("\n", "<br>") text = text.replace("\n", "<br>")
elif _type == "html": elif _type == "html":
text = self.htmlBody(text) text = self.htmlBody(text)
return text + "<br>" return text + "<br>"

View file

@ -1,12 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- #--!-- coding: utf8 --!--
from qt import *
from random import *
from enums import *
import os import os
from random import *
from PyQt5.QtCore import Qt, QRect, QStandardPaths, QObject
# Used to detect multiple connections # Used to detect multiple connections
from PyQt5.QtGui import QBrush, QIcon, QPainter
from PyQt5.QtGui import QColor
from PyQt5.QtGui import QImage
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import qApp
from manuskript.enums import Outline
AUC = Qt.AutoConnection | Qt.UniqueConnection AUC = Qt.AutoConnection | Qt.UniqueConnection
MW = None MW = None
@ -70,7 +78,7 @@ def mainWindow():
return MW return MW
def iconColor(icon): def iconColor(icon):
"Returns a QRgb from a QIcon, assuming its all the same color" """Returns a QRgb from a QIcon, assuming its all the same color"""
px = icon.pixmap(5, 5) px = icon.pixmap(5, 5)
if px.width() != 0: if px.width() != 0:
return QColor(QImage(px).pixel(2, 2)) return QColor(QImage(px).pixel(2, 2))
@ -86,7 +94,7 @@ def iconFromColorString(string):
return iconFromColor(QColor(string)) return iconFromColor(QColor(string))
def randomColor(mix=None): def randomColor(mix=None):
"Generates a random color. If mix (QColor) is given, mixes the random color and mix." """Generates a random color. If mix (QColor) is given, mixes the random color and mix."""
r = randint(0, 255) r = randint(0, 255)
g = randint(0, 255) g = randint(0, 255)
b = randint(0, 255) b = randint(0, 255)
@ -106,36 +114,36 @@ def mixColors(col1, col2, f=.5):
return QColor(r, g, b) return QColor(r, g, b)
def outlineItemColors(item): def outlineItemColors(item):
"Takes an OutlineItem and returns a dict of colors." """Takes an OutlineItem and returns a dict of colors."""
colors = {} colors = {}
mw = mainWindow() mw = mainWindow()
# 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.mdlPersos.rowCount()):
if mw.mdlPersos.ID(i) == POV: if mw.mdlPersos.ID(i) == POV:
colors["POV"] = iconColor(mw.mdlPersos.icon(i)) colors["POV"] = iconColor(mw.mdlPersos.icon(i))
# Label # Label
lbl = item.data(Outline.label.value) lbl = item.data(Outline.label.value)
col = iconColor(mw.mdlLabels.item(toInt(lbl)).icon()) col = iconColor(mw.mdlLabels.item(toInt(lbl)).icon())
if col == Qt.black: if col == Qt.black:
# Don't know why, but transparent is rendered as black # Don't know why, but transparent is rendered as black
col = QColor(Qt.transparent) col = QColor(Qt.transparent)
colors["Label"] = col colors["Label"] = col
# Progress # Progress
pg = item.data(Outline.goalPercentage.value) pg = item.data(Outline.goalPercentage.value)
colors["Progress"] = colorFromProgress(pg) colors["Progress"] = colorFromProgress(pg)
# Compile # Compile
if item.compile() in [0, "0"]: if item.compile() in [0, "0"]:
colors["Compile"] = QColor(Qt.gray) colors["Compile"] = QColor(Qt.gray)
else: else:
colors["Compile"] = QColor(Qt.black) colors["Compile"] = QColor(Qt.black)
return colors return colors
def colorifyPixmap(pixmap, color): def colorifyPixmap(pixmap, color):
# FIXME: ugly # FIXME: ugly

View file

@ -1,10 +1,15 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- #--!-- coding: utf8 --!--
from qt import *
from functions import *
from lxml import etree as ET
import zipfile 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.functions import iconColor, iconFromColorString
try: try:
import zlib # Used with zipfile for compression import zlib # Used with zipfile for compression
compression = zipfile.ZIP_DEFLATED compression = zipfile.ZIP_DEFLATED

View file

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys
from qt import *
from functions import *
import faulthandler import faulthandler
import sys
from PyQt5.QtCore import QLocale, QTranslator, QSettings
from PyQt5.QtWidgets import QApplication
from .functions import *
_version = "0.1" _version = "0.1"
@ -49,7 +50,7 @@ def run():
def launch(): def launch():
from mainWindow import MainWindow from .mainWindow import MainWindow
main = MainWindow() main = MainWindow()
main.show() main.show()

View file

@ -1,27 +1,33 @@
#!/usr/bin/env python #!/usr/bin/env python
# --!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from ui.mainWindow import *
from ui.helpLabel import helpLabel
from ui.compileDialog import compileDialog
from loadSave import *
from enums import *
from models.outlineModel import *
from models.persosModel import *
from models.plotModel import *
from models.worldModel import worldModel
from ui.views.outlineDelegates import outlinePersoDelegate
from ui.views.plotDelegate import plotDelegate
from ui.collapsibleDockWidgets import collapsibleDockWidgets
# from models.persosProxyModel import *
from functions import *
from settingsWindow import *
import settings
import imp import imp
import os
from PyQt5.QtCore import pyqtSignal, QSignalMapper, QTimer, QSettings, Qt, QRegExp, QUrl
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QMainWindow, QHeaderView, qApp, QMenu, QActionGroup, QAction, QStyle
from manuskript import settings
from manuskript.enums import Perso, Subplot, Plot, World
from manuskript.functions import AUC, wordCount
from manuskript.loadSave import loadStandardItemModelXML, loadFilesFromZip
from manuskript.loadSave import saveFilesToZip
from manuskript.loadSave import saveStandardItemModelXML
from manuskript.models.outlineModel import outlineModel
from manuskript.models.persosModel import persosModel
from manuskript.models.plotModel import plotModel
from manuskript.models.worldModel import worldModel
from manuskript.settingsWindow import settingsWindow
from manuskript.ui.collapsibleDockWidgets import collapsibleDockWidgets
from manuskript.ui.compileDialog import compileDialog
from manuskript.ui.helpLabel import helpLabel
from manuskript.ui.mainWindow import Ui_MainWindow
from manuskript.ui.views.outlineDelegates import outlinePersoDelegate
from manuskript.ui.views.plotDelegate import plotDelegate
# Spellcheck support # Spellcheck support
from manuskript.ui.views.textEditView import textEditView
try: try:
import enchant import enchant
except ImportError: except ImportError:
@ -907,6 +913,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
w.setDict(settings.dict) w.setDict(settings.dict)
def openPyEnchantWebPage(self): def openPyEnchantWebPage(self):
from PyQt5.QtGui import QDesktopServices
QDesktopServices.openUrl(QUrl("http://pythonhosted.org/pyenchant/")) QDesktopServices.openUrl(QUrl("http://pythonhosted.org/pyenchant/"))
def toggleSpellcheck(self, val): def toggleSpellcheck(self, val):

View file

@ -1,14 +1,22 @@
#!/usr/bin/env python #!/usr/bin/env python
# --!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from enum import Enum
from lxml import etree as ET
from functions import *
import settings
import locale import locale
from PyQt5.QtCore import QAbstractItemModel, QMimeData
from PyQt5.QtCore import QModelIndex
from PyQt5.QtCore import QSize
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.functions import mainWindow, toInt, wordCount
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
import time import time

View file

@ -1,9 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex, Qt
from qt import * from PyQt5.QtGui import QStandardItemModel, QStandardItem, QColor, QPixmap, QIcon
from enums import * from PyQt5.QtWidgets import QColorDialog
from functions import *
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): class persosModel(QStandardItemModel):
@ -11,8 +18,8 @@ class persosModel(QStandardItemModel):
QStandardItemModel.__init__(self, 0, 3, parent) QStandardItemModel.__init__(self, 0, 3, parent)
self.setHorizontalHeaderLabels([i.name for i in Plot]) self.setHorizontalHeaderLabels([i.name for i in Plot])
self.mw = mainWindow() self.mw = mainWindow()
#self._proxy = plotsProxyModel() # self._proxy = plotsProxyModel()
#self._proxy.setSourceModel(self) # self._proxy.setSourceModel(self)
############################################################################### ###############################################################################
# PERSOS QUERRIES # PERSOS QUERRIES
@ -126,7 +133,7 @@ class persosModel(QStandardItemModel):
############################################################################### ###############################################################################
def updatePersoColor(self, idx): def updatePersoColor(self, idx):
#idx = self.currentPersoIndex() # idx = self.currentPersoIndex()
color = self.getPersoColorName(idx) color = self.getPersoColorName(idx)
self.mw.btnPersoColor.setStyleSheet("background:{};".format(color)) self.mw.btnPersoColor.setStyleSheet("background:{};".format(color))
@ -174,4 +181,3 @@ class persosModel(QStandardItemModel):
infos.append((name, val)) infos.append((name, val))
return infos return infos

View file

@ -1,11 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- #--!-- coding: utf8 --!--
from qt import * from manuskript import enums
from enums import *
from enum import Enum
from lxml import etree as ET
class persosProxyModel(QSortFilterProxyModel): class persosProxyModel(QSortFilterProxyModel):

View file

@ -1,31 +1,38 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex
from qt import * from PyQt5.QtCore import QSignalMapper
from enums import * from PyQt5.QtCore import Qt
from functions import * from PyQt5.QtGui import QBrush
from PyQt5.QtGui import QStandardItem
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QAction, QMenu
from manuskript.enums import Plot
from manuskript.enums import Subplot
from manuskript.functions import toInt, mainWindow
class plotModel(QStandardItemModel): class plotModel(QStandardItemModel):
def __init__(self, parent): def __init__(self, parent):
QStandardItemModel.__init__(self, 0, 3, parent) QStandardItemModel.__init__(self, 0, 3, parent)
self.setHorizontalHeaderLabels([i.name for i in Plot]) self.setHorizontalHeaderLabels([i.name for i in Plot])
self.mw = mainWindow() self.mw = mainWindow()
self.updatePlotPersoButton() self.updatePlotPersoButton()
############################################################################### ###############################################################################
# QUERIES # QUERIES
############################################################################### ###############################################################################
def getPlotsByImportance(self): def getPlotsByImportance(self):
plots = [[], [], []] plots = [[], [], []]
for i in range(self.rowCount()): for i in range(self.rowCount()):
importance = self.item(i, Plot.importance.value).text() importance = self.item(i, Plot.importance.value).text()
ID = self.item(i, Plot.ID.value).text() ID = self.item(i, Plot.ID.value).text()
plots[2-toInt(importance)].append(ID) plots[2 - toInt(importance)].append(ID)
return plots return plots
def getSubPlotsByID(self, ID): def getSubPlotsByID(self, ID):
index = self.getIndexFromID(ID) index = self.getIndexFromID(ID)
if not index.isValid(): if not index.isValid():
@ -39,7 +46,7 @@ class plotModel(QStandardItemModel):
summary = item.child(i, 3).text() summary = item.child(i, 3).text()
lst.append((_ID, name, summary)) lst.append((_ID, name, summary))
return lst return lst
def getPlotNameByID(self, ID): def getPlotNameByID(self, ID):
for i in range(self.rowCount()): for i in range(self.rowCount()):
_ID = self.item(i, Plot.ID.value).text() _ID = self.item(i, Plot.ID.value).text()
@ -47,7 +54,7 @@ class plotModel(QStandardItemModel):
name = self.item(i, Plot.name.value).text() name = self.item(i, Plot.name.value).text()
return name return name
return None return None
def getSubPlotTextsByID(self, plotID, subplotRaw): def getSubPlotTextsByID(self, plotID, subplotRaw):
"""Returns a tuple (name, summary) for the suplot whose raw in the model """Returns a tuple (name, summary) for the suplot whose raw in the model
is ``subplotRaw``, of plot whose ID is ``plotID``. is ``subplotRaw``, of plot whose ID is ``plotID``.
@ -55,53 +62,54 @@ class plotModel(QStandardItemModel):
plotIndex = self.getIndexFromID(plotID) plotIndex = self.getIndexFromID(plotID)
name = plotIndex.child(subplotRaw, Plot.name.value).data() name = plotIndex.child(subplotRaw, Plot.name.value).data()
summary = plotIndex.child(subplotRaw, 3).data() # 3 is for summary summary = plotIndex.child(subplotRaw, 3).data() # 3 is for summary
return (name, summary) return name, summary
def getIndexFromID(self, ID): def getIndexFromID(self, ID):
for i in range(self.rowCount()): for i in range(self.rowCount()):
_ID = self.item(i, Plot.ID.value).text() _ID = self.item(i, Plot.ID.value).text()
if _ID == ID or toInt(_ID) == ID: if _ID == ID or toInt(_ID) == ID:
return self.index(i, 0) return self.index(i, 0)
return QModelIndex() return QModelIndex()
def currentIndex(self): def currentIndex(self):
i = self.mw.lstPlots.currentIndex() i = self.mw.lstPlots.currentIndex()
if i .isValid(): if i.isValid():
return i return i
else: else:
return None return None
############################################################################### ###############################################################################
# ADDING / REMOVING # ADDING / REMOVING
############################################################################### ###############################################################################
def addPlot(self): def addPlot(self):
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("Persos"),
QStandardItem(), QStandardItem(), QStandardItem("Subplots")]) QStandardItem(), QStandardItem(), QStandardItem("Subplots")])
def getUniqueID(self, parent=QModelIndex()): def getUniqueID(self, parent=QModelIndex()):
"Returns an unused ID" """Returns an unused ID"""
parentItem = self.itemFromIndex(parent) parentItem = self.itemFromIndex(parent)
vals = [] vals = []
for i in range(self.rowCount(parent)): for i in range(self.rowCount(parent)):
index = self.index(i, Plot.ID.value, parent) index = self.index(i, Plot.ID.value, parent)
#item = self.item(i, Plot.ID.value) # item = self.item(i, Plot.ID.value)
if index.isValid() and index.data(): if index.isValid() and index.data():
vals.append(int(index.data())) vals.append(int(index.data()))
k = 0 k = 0
while k in vals: k += 1 while k in vals:
k += 1
return str(k) return str(k)
def removePlot(self, index): def removePlot(self, index):
self.takeRow(index.row()) self.takeRow(index.row())
############################################################################### ###############################################################################
# SUBPLOTS # SUBPLOTS
############################################################################### ###############################################################################
def headerData(self, section, orientation, role=Qt.DisplayRole): def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
@ -116,42 +124,42 @@ class plotModel(QStandardItemModel):
return "" return ""
else: else:
return QStandardItemModel.headerData(self, section, orientation, role) return QStandardItemModel.headerData(self, section, orientation, role)
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.subplots.value and \
index.column() == Subplot.meta.value: index.column() == Subplot.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:
return QBrush(Qt.gray) return QBrush(Qt.gray)
else: else:
return QStandardItemModel.data(self, index, role) return QStandardItemModel.data(self, index, role)
else: else:
return QStandardItemModel.data(self, index, role) return QStandardItemModel.data(self, index, role)
def addSubPlot(self): def addSubPlot(self):
index = self.mw.lstPlots.currentPlotIndex() index = self.mw.lstPlots.currentPlotIndex()
if not index.isValid(): if not index.isValid():
return return
parent = index.sibling(index.row(), Plot.subplots.value) parent = index.sibling(index.row(), Plot.subplots.value)
parentItem = self.item(index.row(), Plot.subplots.value) parentItem = self.item(index.row(), Plot.subplots.value)
if not parentItem: if not parentItem:
return return
p = QStandardItem(self.tr("New subplot")) p = QStandardItem(self.tr("New subplot"))
_id = QStandardItem(self.getUniqueID(parent)) _id = QStandardItem(self.getUniqueID(parent))
summary = QStandardItem() summary = QStandardItem()
# Don't know why, if summary is in third position, then drag/drop deletes it... # Don't know why, if summary is in third position, then drag/drop deletes it...
parentItem.appendRow([p, _id, QStandardItem(), summary]) parentItem.appendRow([p, _id, QStandardItem(), summary])
# Select last index # Select last index
self.mw.lstSubPlots.setCurrentIndex(parent.child(self.rowCount(parent)-1, 0)) self.mw.lstSubPlots.setCurrentIndex(parent.child(self.rowCount(parent) - 1, 0))
def removeSubPlot(self): def removeSubPlot(self):
index = self.mw.lstSubPlots.currentIndex() index = self.mw.lstSubPlots.currentIndex()
if not index.isValid(): if not index.isValid():
@ -159,33 +167,33 @@ class plotModel(QStandardItemModel):
parent = index.parent() parent = index.parent()
parentItem = self.itemFromIndex(parent) parentItem = self.itemFromIndex(parent)
parentItem.takeRow(index.row()) parentItem.takeRow(index.row())
def flags(self, index): def flags(self, index):
parent = index.parent() parent = index.parent()
if parent.isValid(): # this is a subitem if parent.isValid(): # this is a subitem
return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
else: else:
return QStandardItemModel.flags(self, index) return QStandardItemModel.flags(self, index)
############################################################################### ###############################################################################
# PLOT PERSOS # PLOT PERSOS
############################################################################### ###############################################################################
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.persos.value):
self.setItem(index.row(), Plot.persos.value, QStandardItem()) self.setItem(index.row(), Plot.persos.value, QStandardItem())
item = self.item(index.row(), Plot.persos.value) item = self.item(index.row(), Plot.persos.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()):
if item.child(i).text() == str(v): if item.child(i).text() == str(v):
return return
item.appendRow(QStandardItem(str(v))) item.appendRow(QStandardItem(str(v)))
def removePlotPerso(self): def removePlotPerso(self):
index = self.mw.lstPlotPerso.currentIndex() index = self.mw.lstPlotPerso.currentIndex()
if not index.isValid(): if not index.isValid():
@ -193,26 +201,26 @@ class plotModel(QStandardItemModel):
parent = index.parent() parent = index.parent()
parentItem = self.itemFromIndex(parent) parentItem = self.itemFromIndex(parent)
parentItem.takeRow(index.row()) parentItem.takeRow(index.row())
def updatePlotPersoButton(self): def updatePlotPersoButton(self):
menu = QMenu(self.mw) menu = QMenu(self.mw)
menus = [] menus = []
for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]: for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]:
m = QMenu(i, menu) m = QMenu(i, menu)
menus.append(m) menus.append(m)
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.mdlPersos.rowCount()):
a = QAction(self.mw.mdlPersos.name(i), menu) a = QAction(self.mw.mdlPersos.name(i), menu)
a.setIcon(self.mw.mdlPersos.icon(i)) a.setIcon(self.mw.mdlPersos.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.mdlPersos.ID(i)))
imp = toInt(self.mw.mdlPersos.importance(i)) imp = toInt(self.mw.mdlPersos.importance(i))
menus[2-imp].addAction(a) menus[2 - imp].addAction(a)
mpr.mapped.connect(self.addPlotPerso) mpr.mapped.connect(self.addPlotPerso)
self.mw.btnAddPlotPerso.setMenu(menu) self.mw.btnAddPlotPerso.setMenu(menu)

View file

@ -1,107 +1,109 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex
from qt import * from PyQt5.QtCore import QSortFilterProxyModel
from enums import * from PyQt5.QtCore import Qt
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QBrush, QFont
from PyQt5.QtGui import QColor
from PyQt5.QtGui import QStandardItem
from manuskript.enums import Plot
from enum import Enum
from lxml import etree as ET
class plotsProxyModel(QSortFilterProxyModel): class plotsProxyModel(QSortFilterProxyModel):
newStatuses = pyqtSignal() newStatuses = pyqtSignal()
def __init__(self, parent=None): def __init__(self, parent=None):
QSortFilterProxyModel.__init__(self, parent) QSortFilterProxyModel.__init__(self, parent)
#self.rootItem = QStandardItem() # self.rootItem = QStandardItem()
self.p1 = QStandardItem(self.tr("Main")) self.p1 = QStandardItem(self.tr("Main"))
self.p2 = QStandardItem(self.tr("Secundary")) self.p2 = QStandardItem(self.tr("Secundary"))
self.p3 = QStandardItem(self.tr("Minors")) self.p3 = QStandardItem(self.tr("Minors"))
self._cats = [ self._cats = [
self.p1, self.p1,
self.p2, self.p2,
self.p3 self.p3
] ]
def mapFromSource(self, sourceIndex): def mapFromSource(self, sourceIndex):
if not sourceIndex.isValid(): if not sourceIndex.isValid():
return QModelIndex() return QModelIndex()
row = self._map.index(sourceIndex.row()) row = self._map.index(sourceIndex.row())
#item = sourceIndex.internalPointer() # item = sourceIndex.internalPointer()
item = self.sourceModel().itemFromIndex(sourceIndex) item = self.sourceModel().itemFromIndex(sourceIndex)
return self.createIndex(row, sourceIndex.column(), item) return self.createIndex(row, sourceIndex.column(), item)
def flags(self, index): def flags(self, index):
if not index.isValid(): if not index.isValid():
return Qt.NoItemFlags return Qt.NoItemFlags
if index.isValid() and not self.mapToSource(index).isValid(): if index.isValid() and not self.mapToSource(index).isValid():
return Qt.NoItemFlags#Qt.ItemIsEnabled return Qt.NoItemFlags # Qt.ItemIsEnabled
else: else:
return Qt.ItemIsEnabled | Qt.ItemIsSelectable return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def mapToSource(self, proxyIndex): def mapToSource(self, proxyIndex):
if not proxyIndex.isValid(): if not proxyIndex.isValid():
return QModelIndex() return QModelIndex()
row = self._map[proxyIndex.row()] row = self._map[proxyIndex.row()]
if type(row) != int: if type(row) != int:
return QModelIndex() return QModelIndex()
#item = proxyIndex.internalPointer() # item = proxyIndex.internalPointer()
item = self.sourceModel().item(row, proxyIndex.column()) item = self.sourceModel().item(row, proxyIndex.column())
return self.sourceModel().indexFromItem(item) return self.sourceModel().indexFromItem(item)
def setSourceModel(self, model): def setSourceModel(self, model):
QSortFilterProxyModel.setSourceModel(self, model) QSortFilterProxyModel.setSourceModel(self, model)
self.sourceModel().dataChanged.connect(self.mapModelMaybe) self.sourceModel().dataChanged.connect(self.mapModelMaybe)
self.sourceModel().rowsInserted.connect(self.mapModel) self.sourceModel().rowsInserted.connect(self.mapModel)
self.sourceModel().rowsRemoved.connect(self.mapModel) self.sourceModel().rowsRemoved.connect(self.mapModel)
self.sourceModel().rowsMoved.connect(self.mapModel) self.sourceModel().rowsMoved.connect(self.mapModel)
self.mapModel() self.mapModel()
def mapModelMaybe(self, topLeft, bottomRight): def mapModelMaybe(self, topLeft, bottomRight):
if topLeft.column() <= Plot.importance.value <= bottomRight.column(): if topLeft.column() <= Plot.importance.value <= bottomRight.column():
self.mapModel() self.mapModel()
def mapModel(self): def mapModel(self):
self.beginResetModel() self.beginResetModel()
src = self.sourceModel() src = self.sourceModel()
self._map = [] self._map = []
for i in range(len(self._cats)): for i in range(len(self._cats)):
self._map.append(self._cats[i]) self._map.append(self._cats[i])
for p in range(src.rowCount()): for p in range(src.rowCount()):
item = src.item(p, Plot.importance.value) item = src.item(p, Plot.importance.value)
if item: if item:
imp = int(item.text()) imp = int(item.text())
else: else:
imp = 0 imp = 0
if 2-imp == i: if 2 - imp == i:
self._map.append(p) self._map.append(p)
self.endResetModel() self.endResetModel()
def data(self, index, role=Qt.DisplayRole): def data(self, index, role=Qt.DisplayRole):
if index.isValid() and not self.mapToSource(index).isValid(): if index.isValid() and not self.mapToSource(index).isValid():
row = index.row() row = index.row()
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
return self._map[row].text() return self._map[row].text()
elif role == Qt.ForegroundRole: elif role == Qt.ForegroundRole:
return QBrush(Qt.darkBlue) return QBrush(Qt.darkBlue)
elif role == Qt.BackgroundRole: elif role == Qt.BackgroundRole:
@ -110,32 +112,32 @@ class plotsProxyModel(QSortFilterProxyModel):
return Qt.AlignCenter return Qt.AlignCenter
elif role == Qt.FontRole: elif role == Qt.FontRole:
f = QFont() f = QFont()
#f.setPointSize(f.pointSize() + 1) # f.setPointSize(f.pointSize() + 1)
f.setWeight(QFont.Bold) f.setWeight(QFont.Bold)
return f return f
else: else:
#FIXME: sometimes, the name of the character is not displayed # FIXME: sometimes, the name of the character is not displayed
return self.sourceModel().data(self.mapToSource(index), role) return self.sourceModel().data(self.mapToSource(index), role)
def index(self, row, column, parent): def index(self, row, column, parent):
i = self._map[row] i = self._map[row]
if type(i) != int: if type(i) != int:
return self.createIndex(row, column, i) return self.createIndex(row, column, i)
else: else:
return self.mapFromSource(self.sourceModel().index(i, column, QModelIndex())) return self.mapFromSource(self.sourceModel().index(i, column, QModelIndex()))
def parent(self, index=QModelIndex()): def parent(self, index=QModelIndex()):
return QModelIndex() return QModelIndex()
def rowCount(self, parent=QModelIndex()): def rowCount(self, parent=QModelIndex()):
return len(self._map) return len(self._map)
def columnCount(self, parent=QModelIndex()): def columnCount(self, parent=QModelIndex()):
return self.sourceModel().columnCount(QModelIndex()) return self.sourceModel().columnCount(QModelIndex())
def item(self, row, col, parent=QModelIndex()): def item(self, row, col, parent=QModelIndex()):
idx = self.mapToSource(self.index(row, col, parent)) idx = self.mapToSource(self.index(row, col, parent))
return self.sourceModel().item(idx.row(), idx.column()) return self.sourceModel().item(idx.row(), idx.column())

View file

@ -1,9 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from functions import *
import re import re
############################################################################### ###############################################################################
@ -11,6 +8,14 @@ import re
############################################################################### ###############################################################################
# A regex used to match references # A regex used to match references
from PyQt5.QtWidgets import qApp
from manuskript.enums import Outline
from manuskript.enums import Perso
from manuskript.enums import Plot
from manuskript.enums import Subplot
from manuskript.functions import mainWindow
RegEx = r"{(\w):(\d+):?.*?}" RegEx = r"{(\w):(\d+):?.*?}"
# A non-capturing regex used to identify references # A non-capturing regex used to identify references
RegExNonCapturing = r"{\w:\d+:?.*?}" RegExNonCapturing = r"{\w:\d+:?.*?}"
@ -21,21 +26,26 @@ TextLetter = "T"
PlotLetter = "P" PlotLetter = "P"
WorldLetter = "W" WorldLetter = "W"
def plotReference(ID): def plotReference(ID):
"Takes the ID of a plot and returns a reference for that plot." """Takes the ID of a plot and returns a reference for that plot."""
return EmptyRef.format(PlotLetter, ID, "") return EmptyRef.format(PlotLetter, ID, "")
def persoReference(ID): def persoReference(ID):
"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."""
return EmptyRef.format(PersoLetter, ID, "") return EmptyRef.format(PersoLetter, ID, "")
def textReference(ID): def textReference(ID):
"Takes the ID of an outline item and returns a reference for that item." """Takes the ID of an outline item and returns a reference for that item."""
return EmptyRef.format(TextLetter, ID, "") return EmptyRef.format(TextLetter, ID, "")
def worldReference(ID): def worldReference(ID):
"Takes the ID of a world item and returns a reference for that item." """Takes the ID of a world item and returns a reference for that item."""
return EmptyRef.format(WordLetter, ID, "") return EmptyRef.format(WorldLetter, ID, "")
############################################################################### ###############################################################################
# READABLE INFOS # READABLE INFOS
@ -48,21 +58,21 @@ def infos(ref):
match = re.fullmatch(RegEx, ref) match = re.fullmatch(RegEx, ref)
if not match: if not match:
return qApp.translate("references", "Not a reference: {}.").format(ref) return qApp.translate("references", "Not a reference: {}.").format(ref)
_type = match.group(1) _type = match.group(1)
_ref = match.group(2) _ref = match.group(2)
# A text or outine item # A text or outine item
if _type == TextLetter: if _type == TextLetter:
m = mainWindow().mdlOutline m = mainWindow().mdlOutline
idx = m.getIndexByID(_ref) idx = m.getIndexByID(_ref)
if not idx.isValid(): if not idx.isValid():
return qApp.translate("references", "Unknown reference: {}.").format(ref) return qApp.translate("references", "Unknown reference: {}.").format(ref)
item = idx.internalPointer() item = idx.internalPointer()
#Titles # Titles
pathTitle = qApp.translate("references", "Path:") pathTitle = qApp.translate("references", "Path:")
statsTitle = qApp.translate("references", "Stats:") statsTitle = qApp.translate("references", "Stats:")
POVTitle = qApp.translate("references", "POV:") POVTitle = qApp.translate("references", "POV:")
@ -71,42 +81,42 @@ def infos(ref):
ssTitle = qApp.translate("references", "Short summary:") ssTitle = qApp.translate("references", "Short summary:")
lsTitle = qApp.translate("references", "Long summary:") lsTitle = qApp.translate("references", "Long summary:")
notesTitle = qApp.translate("references", "Notes:") notesTitle = qApp.translate("references", "Notes:")
# The POV of the scene # The POV of the scene
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=persoReference(item.POV()),
text=mainWindow().mdlPersos.getPersoNameByID(item.POV())) text=mainWindow().mdlPersos.getPersoNameByID(item.POV()))
# The status of the scene # The status of the scene
status = item.status() status = item.status()
if status: if status:
status = mainWindow().mdlStatus.item(int(status), 0).text() status = mainWindow().mdlStatus.item(int(status), 0).text()
else: else:
status = "" status = ""
# The label of the scene # The label of the scene
label = item.label() label = item.label()
if label: if label:
label = mainWindow().mdlLabels.item(int(label), 0).text() label = mainWindow().mdlLabels.item(int(label), 0).text()
else: else:
label = "" label = ""
# The path of the scene # The path of the scene
path = item.pathID() path = item.pathID()
pathStr = [] pathStr = []
for _id, title in path: for _id, title in path:
pathStr.append("<a href='{ref}'>{text}</a>".format( pathStr.append("<a href='{ref}'>{text}</a>".format(
ref=textReference(_id), ref=textReference(_id),
text=title)) text=title))
path = " > ".join(pathStr) path = " > ".join(pathStr)
# Summaries and notes # Summaries and notes
ss = item.data(Outline.summarySentance.value) ss = item.data(Outline.summarySentance.value)
ls = item.data(Outline.summaryFull.value) ls = item.data(Outline.summaryFull.value)
notes = item.data(Outline.notes.value) notes = item.data(Outline.notes.value)
text = """<h1>{title}</h1> text = """<h1>{title}</h1>
<p><b>{pathTitle}</b> {path}</p> <p><b>{pathTitle}</b> {path}</p>
<p><b>{statsTitle}</b> {stats}<br> <p><b>{statsTitle}</b> {stats}<br>
@ -118,86 +128,86 @@ def infos(ref):
{notes} {notes}
{references} {references}
""".format( """.format(
title=item.title(), title=item.title(),
pathTitle=pathTitle, pathTitle=pathTitle,
path=path, path=path,
statsTitle=statsTitle, statsTitle=statsTitle,
stats=item.stats(), stats=item.stats(),
POV="<b>{POVTitle}</b> {POV}<br>".format( POV="<b>{POVTitle}</b> {POV}<br>".format(
POVTitle=POVTitle, POVTitle=POVTitle,
POV=POV) if POV else "", POV=POV) if POV else "",
status="<b>{statusTitle}</b> {status}<br>".format( status="<b>{statusTitle}</b> {status}<br>".format(
statusTitle=statusTitle, statusTitle=statusTitle,
status=status) if status else "", status=status) if status else "",
label="<b>{labelTitle}</b> {label}</p>".format( label="<b>{labelTitle}</b> {label}</p>".format(
labelTitle=labelTitle, labelTitle=labelTitle,
label=label) if label else "", label=label) if label else "",
ss="<p><b>{ssTitle}</b> {ss}</p>".format( ss="<p><b>{ssTitle}</b> {ss}</p>".format(
ssTitle=ssTitle, ssTitle=ssTitle,
ss=ss.replace("\n", "<br>")) if ss.strip() else "", ss=ss.replace("\n", "<br>")) if ss.strip() else "",
ls="<p><b>{lsTitle}</b><br>{ls}</p>".format( ls="<p><b>{lsTitle}</b><br>{ls}</p>".format(
lsTitle=lsTitle, lsTitle=lsTitle,
ls=ls.replace("\n", "<br>")) if ls.strip() else "", ls=ls.replace("\n", "<br>")) if ls.strip() else "",
notes="<p><b>{notesTitle}</b><br>{notes}</p>".format( notes="<p><b>{notesTitle}</b><br>{notes}</p>".format(
notesTitle=notesTitle, notesTitle=notesTitle,
notes=linkifyAllRefs(basicT2TFormat(notes))) if notes.strip() else "", notes=linkifyAllRefs(basicT2TFormat(notes))) if notes.strip() else "",
references=listReferences(ref) references=listReferences(ref)
) )
return text return text
# A character # A character
elif _type == PersoLetter: elif _type == PersoLetter:
m = mainWindow().mdlPersos m = mainWindow().mdlPersos
index = m.getIndexFromID(_ref) index = m.getIndexFromID(_ref)
name = m.name(index.row()) name = m.name(index.row())
# Titles # Titles
basicTitle = qApp.translate("references", "Basic infos") basicTitle = qApp.translate("references", "Basic infos")
detailedTitle = qApp.translate("references", "Detailed infos") detailedTitle = qApp.translate("references", "Detailed infos")
POVof = qApp.translate("references", "POV of:") POVof = qApp.translate("references", "POV of:")
# Goto (link) # Goto (link)
goto = qApp.translate("references", "Go to {}.") goto = qApp.translate("references", "Go to {}.")
goto = goto.format(refToLink(ref)) goto = goto.format(refToLink(ref))
# basic infos # basic infos
basic = [] basic = []
for i in [ for i in [
(Perso.motivation, qApp.translate("references", "Motivation"), False), (Perso.motivation, qApp.translate("references", "Motivation"), False),
(Perso.goal, qApp.translate("references", "Goal"), False), (Perso.goal, qApp.translate("references", "Goal"), False),
(Perso.conflict, qApp.translate("references", "Conflict"), False), (Perso.conflict, qApp.translate("references", "Conflict"), False),
(Perso.epiphany, qApp.translate("references", "Epiphany"), False), (Perso.epiphany, qApp.translate("references", "Epiphany"), False),
(Perso.summarySentance, qApp.translate("references", "Short summary"), True), (Perso.summarySentance, qApp.translate("references", "Short summary"), True),
(Perso.summaryPara, qApp.translate("references", "Longer summary"), True), (Perso.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],
n = "\n" if i[2] else " ", n="\n" if i[2] else " ",
val=val)) val=val))
basic = "<br>".join(basic) basic = "<br>".join(basic)
# detailed infos # detailed infos
detailed = [] detailed = []
for _name, _val in m.listPersoInfos(index): for _name, _val in m.listPersoInfos(index):
detailed.append("<b>{}:</b> {}".format( detailed.append("<b>{}:</b> {}".format(
_name, _name,
_val)) _val))
detailed = "<br>".join(detailed) detailed = "<br>".join(detailed)
# list scenes of which it is POV # list scenes of which it is POV
oM = mainWindow().mdlOutline oM = mainWindow().mdlOutline
lst = oM.findItemsByPOV(_ref) lst = oM.findItemsByPOV(_ref)
listPOV = "" listPOV = ""
for t in lst: for t in lst:
idx = oM.getIndexByID(t) idx = oM.getIndexByID(t)
listPOV += "<li><a href='{link}'>{text}</a></li>".format( listPOV += "<li><a href='{link}'>{text}</a></li>".format(
link=textReference(t), link=textReference(t),
text=oM.data(idx, Outline.title.value)) text=oM.data(idx, Outline.title.value))
text = """<h1>{name}</h1> text = """<h1>{name}</h1>
{goto} {goto}
{basicInfos} {basicInfos}
@ -205,45 +215,45 @@ def infos(ref):
{POV} {POV}
{references} {references}
""".format( """.format(
name=name, name=name,
goto=goto, goto=goto,
basicInfos="<h2>{basicTitle}</h2>{basic}".format( basicInfos="<h2>{basicTitle}</h2>{basic}".format(
basicTitle=basicTitle, basicTitle=basicTitle,
basic=basic) if basic else "", basic=basic) if basic else "",
detailedInfos="<h2>{detailedTitle}</h2>{detailed}".format( detailedInfos="<h2>{detailedTitle}</h2>{detailed}".format(
detailedTitle=detailedTitle, detailedTitle=detailedTitle,
detailed=detailed) if detailed else "", detailed=detailed) if detailed else "",
POV="<h2>{POVof}</h2><ul>{listPOV}</ul>".format( POV="<h2>{POVof}</h2><ul>{listPOV}</ul>".format(
POVof=POVof, POVof=POVof,
listPOV=listPOV) if listPOV else "", listPOV=listPOV) if listPOV else "",
references=listReferences(ref) references=listReferences(ref)
) )
return text return text
# A plot # A plot
elif _type == PlotLetter: elif _type == PlotLetter:
m = mainWindow().mdlPlots m = mainWindow().mdlPlots
index = m.getIndexFromID(_ref) index = m.getIndexFromID(_ref)
name = m.getPlotNameByID(_ref) name = m.getPlotNameByID(_ref)
# Titles # Titles
descriptionTitle = qApp.translate("references", "Description") descriptionTitle = qApp.translate("references", "Description")
resultTitle = qApp.translate("references", "Result") resultTitle = qApp.translate("references", "Result")
charactersTitle = qApp.translate("references", "Characters") charactersTitle = qApp.translate("references", "Characters")
stepsTitle = qApp.translate("references", "Resolution steps") stepsTitle = qApp.translate("references", "Resolution steps")
# Goto (link) # Goto (link)
goto = qApp.translate("references", "Go to {}.") goto = qApp.translate("references", "Go to {}.")
goto = goto.format(refToLink(ref)) goto = goto.format(refToLink(ref))
# Description # Description
description = m.data(index.sibling(index.row(), description = m.data(index.sibling(index.row(),
Plot.description.value)) Plot.description.value))
# Result # Result
result = m.data(index.sibling(index.row(), result = m.data(index.sibling(index.row(),
Plot.result.value)) Plot.result.value))
# Characters # Characters
pM = mainWindow().mdlPersos pM = mainWindow().mdlPersos
item = m.item(index.row(), Plot.persos.value) item = m.item(index.row(), Plot.persos.value)
@ -252,9 +262,9 @@ def infos(ref):
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=persoReference(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.subplots.value)
@ -266,10 +276,10 @@ def infos(ref):
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(
title=title, title=title,
summary=": {}".format(summary) if summary else "", summary=": {}".format(summary) if summary else "",
meta = meta if meta else "") meta=meta if meta else "")
text = """<h1>{name}</h1> text = """<h1>{name}</h1>
{goto} {goto}
{characters} {characters}
@ -278,48 +288,48 @@ def infos(ref):
{steps} {steps}
{references} {references}
""".format( """.format(
name=name, name=name,
goto=goto, goto=goto,
description="<h2>{title}</h2>{text}".format( description="<h2>{title}</h2>{text}".format(
title=descriptionTitle, title=descriptionTitle,
text=description) if description else "", text=description) if description else "",
result="<h2>{title}</h2>{text}".format( result="<h2>{title}</h2>{text}".format(
title=resultTitle, title=resultTitle,
text=result) if result else "", text=result) if result else "",
characters="<h2>{title}</h2><ul>{lst}</ul>".format( characters="<h2>{title}</h2><ul>{lst}</ul>".format(
title=charactersTitle, title=charactersTitle,
lst=characters) if characters else "", lst=characters) if characters else "",
steps="<h2>{title}</h2><ul>{steps}</ul>".format( steps="<h2>{title}</h2><ul>{steps}</ul>".format(
title=stepsTitle, title=stepsTitle,
steps=steps) if steps else "", steps=steps) if steps else "",
references=listReferences(ref, referenceTitle) references=listReferences(ref)
) )
return text return text
# A World item # A World item
elif _type == WorldLetter: elif _type == WorldLetter:
m = mainWindow().mdlWorld m = mainWindow().mdlWorld
index = m.indexByID(_ref) index = m.indexByID(_ref)
name = m.name(index) name = m.name(index)
# Titles # Titles
descriptionTitle = qApp.translate("references", "Description") descriptionTitle = qApp.translate("references", "Description")
passionTitle = qApp.translate("references", "Passion") passionTitle = qApp.translate("references", "Passion")
conflictTitle = qApp.translate("references", "Conflict") conflictTitle = qApp.translate("references", "Conflict")
# Goto (link) # Goto (link)
goto = qApp.translate("references", "Go to {}.") goto = qApp.translate("references", "Go to {}.")
goto = goto.format(refToLink(ref)) goto = goto.format(refToLink(ref))
# Description # Description
description = basicFormat(m.description(index)) description = basicFormat(m.description(index))
# Passion # Passion
passion = basicFormat(m.passion(index)) passion = basicFormat(m.passion(index))
# Conflict # Conflict
conflict = basicFormat(m.conflict(index)) conflict = basicFormat(m.conflict(index))
text = """<h1>{name}</h1> text = """<h1>{name}</h1>
{goto} {goto}
{description} {description}
@ -327,60 +337,61 @@ def infos(ref):
{conflict} {conflict}
{references} {references}
""".format( """.format(
name=name, name=name,
goto=goto, goto=goto,
description="<h2>{title}</h2>{text}".format( description="<h2>{title}</h2>{text}".format(
title=descriptionTitle, title=descriptionTitle,
text=description) if description else "", text=description) if description else "",
passion="<h2>{title}</h2>{text}".format( passion="<h2>{title}</h2>{text}".format(
title=passionTitle, title=passionTitle,
text=passion) if passion else "", text=passion) if passion else "",
conflict="<h2>{title}</h2><ul>{lst}</ul>".format( conflict="<h2>{title}</h2><ul>{lst}</ul>".format(
title=conflictTitle, title=conflictTitle,
lst=conflict) if conflict else "", lst=conflict) if conflict else "",
references=listReferences(ref) references=listReferences(ref)
) )
return text return text
else: else:
return qApp.translate("references", "Unknown reference: {}.").format(ref) return qApp.translate("references", "Unknown reference: {}.").format(ref)
def tooltip(ref): def tooltip(ref):
"Returns a tooltip in HTML for the reference ``ref``." """Returns a tooltip in HTML for the reference ``ref``."""
match = re.fullmatch(RegEx, ref) match = re.fullmatch(RegEx, ref)
if not match: if not match:
return qApp.translate("references", "Not a reference: {}.").format(ref) return qApp.translate("references", "Not a reference: {}.").format(ref)
_type = match.group(1) _type = match.group(1)
_ref = match.group(2) _ref = match.group(2)
if _type == TextLetter: if _type == TextLetter:
m = mainWindow().mdlOutline m = mainWindow().mdlOutline
idx = m.getIndexByID(_ref) idx = m.getIndexByID(_ref)
if not idx.isValid(): if not idx.isValid():
return qApp.translate("references", "Unknown reference: {}.").format(ref) return qApp.translate("references", "Unknown reference: {}.").format(ref)
item = idx.internalPointer() item = idx.internalPointer()
tooltip = qApp.translate("references", "Text: <b>{}</b>").format(item.title()) tt = qApp.translate("references", "Text: <b>{}</b>").format(item.title())
tooltip += "<br><i>{}</i>".format(item.path()) tt += "<br><i>{}</i>".format(item.path())
return tooltip return tt
elif _type == PersoLetter: elif _type == PersoLetter:
m = mainWindow().mdlPersos m = mainWindow().mdlPersos
item = m.item(int(_ref), Perso.name.value) item = m.item(int(_ref), Perso.name.value)
if item: if item:
return qApp.translate("references", "Character: <b>{}</b>").format(item.text()) return qApp.translate("references", "Character: <b>{}</b>").format(item.text())
elif _type == PlotLetter: elif _type == PlotLetter:
m = mainWindow().mdlPlots m = mainWindow().mdlPlots
name = m.getPlotNameByID(_ref) name = m.getPlotNameByID(_ref)
if name: if name:
return qApp.translate("references", "Plot: <b>{}</b>").format(name) return qApp.translate("references", "Plot: <b>{}</b>").format(name)
elif _type == WorldLetter: elif _type == WorldLetter:
m = mainWindow().mdlWorld m = mainWindow().mdlWorld
item = m.itemByID(_ref) item = m.itemByID(_ref)
@ -388,15 +399,16 @@ def tooltip(ref):
name = item.text() name = item.text()
path = m.path(item) path = m.path(item)
return qApp.translate("references", "World: <b>{name}</b>{path}").format( return qApp.translate("references", "World: <b>{name}</b>{path}").format(
name=name, name=name,
path=" <span style='color:gray;'>({})</span>".format(path) if path else "") path=" <span style='color:gray;'>({})</span>".format(path) if path else "")
return qApp.translate("references", "<b>Unknown reference:</b> {}.").format(ref) return qApp.translate("references", "<b>Unknown reference:</b> {}.").format(ref)
############################################################################### ###############################################################################
# FUNCTIONS # FUNCTIONS
############################################################################### ###############################################################################
def refToLink(ref): def refToLink(ref):
"""Transforms the reference ``ref`` in a link displaying useful infos """Transforms the reference ``ref`` in a link displaying useful infos
about that reference. For character, character's name. For text item, about that reference. For character, character's name. For text item,
@ -413,30 +425,32 @@ def refToLink(ref):
if idx.isValid(): if idx.isValid():
item = idx.internalPointer() item = idx.internalPointer()
text = item.title() text = item.title()
elif _type == PersoLetter: elif _type == PersoLetter:
m = mainWindow().mdlPersos m = mainWindow().mdlPersos
text = m.item(int(_ref), Perso.name.value).text() text = m.item(int(_ref), Perso.name.value).text()
elif _type == PlotLetter: elif _type == PlotLetter:
m = mainWindow().mdlPlots m = mainWindow().mdlPlots
text = m.getPlotNameByID(_ref) text = m.getPlotNameByID(_ref)
elif _type == WorldLetter: elif _type == WorldLetter:
m = mainWindow().mdlWorld m = mainWindow().mdlWorld
text = m.itemByID(_ref).text() text = m.itemByID(_ref).text()
if text: if text:
return "<a href='{ref}'>{text}</a>".format( return "<a href='{ref}'>{text}</a>".format(
ref=ref, ref=ref,
text=text) text=text)
else: else:
return ref return ref
def linkifyAllRefs(text): def linkifyAllRefs(text):
"Takes all the references in ``text`` and transform them into HMTL links." """Takes all the references in ``text`` and transform them into HMTL links."""
return re.sub(RegEx, lambda m: refToLink(m.group(0)), text) return re.sub(RegEx, lambda m: refToLink(m.group(0)), text)
def listReferences(ref, title=qApp.translate("references", "Referenced in:")): def listReferences(ref, title=qApp.translate("references", "Referenced in:")):
oM = mainWindow().mdlOutline oM = mainWindow().mdlOutline
listRefs = "" listRefs = ""
@ -445,22 +459,23 @@ def listReferences(ref, title=qApp.translate("references", "Referenced in:")):
for t in lst: for t in lst:
idx = oM.getIndexByID(t) idx = oM.getIndexByID(t)
listRefs += "<li><a href='{link}'>{text}</a></li>".format( listRefs += "<li><a href='{link}'>{text}</a></li>".format(
link=textReference(t), link=textReference(t),
text=oM.data(idx, Outline.title.value)) text=oM.data(idx, Outline.title.value))
return "<h2>{title}</h2><ul>{ref}</ul>".format( return "<h2>{title}</h2><ul>{ref}</ul>".format(
title=title, title=title,
ref=listRefs) if listRefs else "" ref=listRefs) if listRefs else ""
def basicT2TFormat(text, formatting=True, EOL=True, titles=True): def basicT2TFormat(text, formatting=True, EOL=True, titles=True):
"A very basic t2t formatter to display notes and texts." """A very basic t2t formatter to display notes and texts."""
text = text.splitlines() text = text.splitlines()
for n, line in enumerate(text): for n, line in enumerate(text):
if formatting: if formatting:
line = re.sub("\*\*(.*?)\*\*", "<b>\\1</b>", line) line = re.sub("\*\*(.*?)\*\*", "<b>\\1</b>", line)
line = re.sub("//(.*?)//", "<i>\\1</i>", line) line = re.sub("//(.*?)//", "<i>\\1</i>", line)
line = re.sub("__(.*?)__", "<u>\\1</u>", line) line = re.sub("__(.*?)__", "<u>\\1</u>", line)
if titles: if titles:
for i in range(1, 6): for i in range(1, 6):
r1 = '^\s*{s}([^=].*[^=]){s}\s*$'.format(s="=" * i) r1 = '^\s*{s}([^=].*[^=]){s}\s*$'.format(s="=" * i)
@ -472,9 +487,10 @@ def basicT2TFormat(text, formatting=True, EOL=True, titles=True):
text = "\n".join(text) text = "\n".join(text)
if EOL: if EOL:
text = text.replace("\n", "<br>") text = text.replace("\n", "<br>")
return text return text
def basicFormat(text): def basicFormat(text):
if not text: if not text:
return "" return ""
@ -482,31 +498,32 @@ def basicFormat(text):
text = linkifyAllRefs(text) text = linkifyAllRefs(text)
return text return text
def open(ref): def open(ref):
"Identify ``ref`` and open it." """Identify ``ref`` and open it."""
match = re.fullmatch(RegEx, ref) match = re.fullmatch(RegEx, ref)
if not match: if not match:
return return
_type = match.group(1) _type = match.group(1)
_ref = match.group(2) _ref = match.group(2)
if _type == PersoLetter: if _type == PersoLetter:
mw = mainWindow() mw = mainWindow()
item = mw.lstPersos.getItemByID(_ref) item = mw.lstPersos.getItemByID(_ref)
if item: if item:
mw.tabMain.setCurrentIndex(mw.TabPersos) mw.tabMain.setCurrentIndex(mw.TabPersos)
mw.lstPersos.setCurrentItem(item) mw.lstPersos.setCurrentItem(item)
return True return True
print("Ref not found") print("Ref not found")
return False return False
elif _type == TextLetter: elif _type == TextLetter:
mw = mainWindow() mw = mainWindow()
index = mw.mdlOutline.getIndexByID(_ref) index = mw.mdlOutline.getIndexByID(_ref)
if index.isValid(): if index.isValid():
mw.tabMain.setCurrentIndex(mw.TabRedac) mw.tabMain.setCurrentIndex(mw.TabRedac)
mw.mainEditor.setCurrentModelIndex(index, newTab=True) mw.mainEditor.setCurrentModelIndex(index, newTab=True)
@ -514,31 +531,31 @@ def open(ref):
else: else:
print("Ref not found") print("Ref not found")
return False return False
elif _type == PlotLetter: elif _type == PlotLetter:
mw = mainWindow() mw = mainWindow()
item = mw.lstPlots.getItemByID(_ref) item = mw.lstPlots.getItemByID(_ref)
if item: if item:
mw.tabMain.setCurrentIndex(mw.TabPlots) mw.tabMain.setCurrentIndex(mw.TabPlots)
mw.lstPlots.setCurrentItem(item) mw.lstPlots.setCurrentItem(item)
return True return True
print("Ref not found") print("Ref not found")
return False return False
elif _type == WorldLetter: elif _type == WorldLetter:
mw = mainWindow() mw = mainWindow()
item = mw.mdlWorld.itemByID(_ref) item = mw.mdlWorld.itemByID(_ref)
if item: if item:
mw.tabMain.setCurrentIndex(mw.TabWorld) mw.tabMain.setCurrentIndex(mw.TabWorld)
mw.treeWorld.setCurrentIndex( mw.treeWorld.setCurrentIndex(
mw.mdlWorld.indexFromItem(item)) mw.mdlWorld.indexFromItem(item))
return True return True
print("Ref not found") print("Ref not found")
return False return False
print("Ref not implemented") print("Ref not implemented")
return False return False

View file

@ -1,23 +1,27 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex
from qt import * from PyQt5.QtCore import QSize
from enums import * from PyQt5.QtCore import Qt
from functions import * from PyQt5.QtGui import QStandardItem, QBrush, QFontMetrics
import collections from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QMenu, QAction, qApp
from manuskript.enums import World
from manuskript.functions import mainWindow, lightBlue
class worldModel(QStandardItemModel): class worldModel(QStandardItemModel):
def __init__(self, parent): def __init__(self, parent):
QStandardItemModel.__init__(self, 0, 3, parent) QStandardItemModel.__init__(self, 0, 3, parent)
self.mw = mainWindow() self.mw = mainWindow()
############################################################################### ###############################################################################
# SELECTION # SELECTION
############################################################################### ###############################################################################
def selectedItem(self): def selectedItem(self):
"Returns the item selected in mw.treeWorld. invisibleRootItem if None." """Returns the item selected in mw.treeWorld. invisibleRootItem if None."""
index = self.selectedIndex() index = self.selectedIndex()
item = self.itemFromIndex(index) item = self.itemFromIndex(index)
if item: if item:
@ -26,57 +30,57 @@ class worldModel(QStandardItemModel):
return self.invisibleRootItem() return self.invisibleRootItem()
def selectedIndex(self): def selectedIndex(self):
"Returns the selected index in the treeView." """Returns the selected index in the treeView."""
if self.mw.treeWorld.selectedIndexes(): if self.mw.treeWorld.selectedIndexes():
return self.mw.treeWorld.currentIndex() return self.mw.treeWorld.currentIndex()
else: else:
return QModelIndex() return QModelIndex()
def selectedIndexes(self): def selectedIndexes(self):
return self.mw.treeWorld.selectedIndexes() return self.mw.treeWorld.selectedIndexes()
############################################################################### ###############################################################################
# GETTERS # GETTERS
############################################################################### ###############################################################################
def ID(self, index): def ID(self, index):
"Returns the ID of the given index." """Returns the ID of the given index."""
index = index.sibling(index.row(), World.ID.value) index = index.sibling(index.row(), World.ID.value)
return self.data(index) return self.data(index)
def name(self, index): def name(self, index):
"Returns the name of the given index." """Returns the name of the given index."""
index = index.sibling(index.row(), World.name.value) index = index.sibling(index.row(), World.name.value)
return self.data(index) return self.data(index)
def description(self, index): def description(self, index):
index = index.sibling(index.row(), World.description.value) index = index.sibling(index.row(), World.description.value)
return self.data(index) return self.data(index)
def conflict(self, index): def conflict(self, index):
index = index.sibling(index.row(), World.conflict.value) index = index.sibling(index.row(), World.conflict.value)
return self.data(index) return self.data(index)
def passion(self, index): def passion(self, index):
index = index.sibling(index.row(), World.passion.value) index = index.sibling(index.row(), World.passion.value)
return self.data(index) return self.data(index)
def itemID(self, item): def itemID(self, item):
"Returns the ID of the given item." """Returns the ID of the given item."""
index = self.indexFromItem(item) index = self.indexFromItem(item)
return self.ID(index) return self.ID(index)
def children(self, item): def children(self, item):
"Returns a list of all item's children." """Returns a list of all item's children."""
c = [] c = []
for i in range(item.rowCount()): for i in range(item.rowCount()):
c.append(item.child(i)) c.append(item.child(i))
return c return c
def listAll(self): def listAll(self):
"Returns a list of tupple ``(name, ID, path)`` for all items." """Returns a list of tupple ``(name, ID, path)`` for all items."""
lst = [] lst = []
def readAll(item): def readAll(item):
name = item.text() name = item.text()
ID = self.itemID(item) ID = self.itemID(item)
@ -85,17 +89,18 @@ class worldModel(QStandardItemModel):
lst.append((name, ID, path)) lst.append((name, ID, path))
for c in self.children(item): for c in self.children(item):
readAll(c) readAll(c)
readAll(self.invisibleRootItem()) readAll(self.invisibleRootItem())
return lst return lst
def indexByID(self, ID): def indexByID(self, ID):
"Returns the index of item whose ID is ID." """Returns the index of item whose ID is ID."""
return self.indexFromItem(self.itemByID(ID)) return self.indexFromItem(self.itemByID(ID))
def itemByID(self, ID): def itemByID(self, ID):
"Returns the item whose ID is ID." """Returns the item whose ID is ID."""
def browse(item): def browse(item):
if self.itemID(item) == ID: if self.itemID(item) == ID:
return item return item
@ -103,25 +108,25 @@ class worldModel(QStandardItemModel):
r = browse(c) r = browse(c)
if r: if r:
return r return r
r = browse(self.invisibleRootItem()) r = browse(self.invisibleRootItem())
return r if r else None return r if r else None
def path(self, item): def path(self, item):
"Returns the path to the item in the form of 'ancestor > ... > grand-parent > parent'." """Returns the path to the item in the form of 'ancestor > ... > grand-parent > parent'."""
path = [] path = []
while item.parent(): while item.parent():
item = item.parent() item = item.parent()
path.append(item.text()) path.append(item.text())
path = " > ".join(path) path = " > ".join(path)
return path return path
############################################################################### ###############################################################################
# ADDING AND REMOVE # ADDING AND REMOVE
############################################################################### ###############################################################################
def addItem(self, title=None, parent=None): def addItem(self, title=None, parent=None):
"Adds an item, and returns it." """Adds an item, and returns it."""
if not parent: if not parent:
parent = self.selectedItem() parent = self.selectedItem()
if not title: if not title:
@ -133,21 +138,22 @@ class worldModel(QStandardItemModel):
return name return name
def getUniqueID(self): def getUniqueID(self):
"Returns an unused ID" """Returns an unused ID"""
parentItem = self.invisibleRootItem() parentItem = self.invisibleRootItem()
vals = [] vals = []
def collectIDs(item): def collectIDs(item):
vals.append(int(self.itemID(item))) vals.append(int(self.itemID(item)))
for c in self.children(item): for c in self.children(item):
collectIDs(c) collectIDs(c)
for c in self.children(parentItem): for c in self.children(parentItem):
collectIDs(c) collectIDs(c)
k = 0 k = 0
while k in vals: k += 1 while k in vals:
k += 1
return str(k) return str(k)
def removeItem(self): def removeItem(self):
@ -155,12 +161,12 @@ class worldModel(QStandardItemModel):
index = self.selectedIndexes()[0] index = self.selectedIndexes()[0]
self.removeRows(index.row(), 1, index.parent()) self.removeRows(index.row(), 1, index.parent())
############################################################################### ###############################################################################
# TEMPLATES # TEMPLATES
############################################################################### ###############################################################################
def dataSets(self): def dataSets(self):
"Returns sets of empty data that can guide the writer for world building." """Returns sets of empty data that can guide the writer for world building."""
dataset = { dataset = {
self.tr("Fantasy world building"): [ self.tr("Fantasy world building"): [
(self.tr("Physical"), [ (self.tr("Physical"), [
@ -173,7 +179,7 @@ class worldModel(QStandardItemModel):
self.tr("History"), self.tr("History"),
self.tr("Races"), self.tr("Races"),
self.tr("Diseases"), self.tr("Diseases"),
]), ]),
(self.tr("Cultural"), [ (self.tr("Cultural"), [
self.tr("Customs"), self.tr("Customs"),
self.tr("Food"), self.tr("Food"),
@ -196,34 +202,34 @@ class worldModel(QStandardItemModel):
self.tr("Demography"), self.tr("Demography"),
self.tr("Transportation"), self.tr("Transportation"),
self.tr("Medicine"), self.tr("Medicine"),
]), ]),
(self.tr("Magic system"), [ (self.tr("Magic system"), [
self.tr("Rules"), self.tr("Rules"),
self.tr("Organization"), self.tr("Organization"),
self.tr("Magical objects"), self.tr("Magical objects"),
self.tr("Magical places"), self.tr("Magical places"),
self.tr("Magical races"), self.tr("Magical races"),
]), ]),
self.tr("Important places"), self.tr("Important places"),
self.tr("Important objects"), self.tr("Important objects"),
] ]
} }
return dataset return dataset
def emptyDataMenu(self): def emptyDataMenu(self):
"Returns a menu with the empty data sets." """Returns a menu with the empty data sets."""
self.menu = QMenu("menu") self.menu = QMenu("menu")
for name in self.dataSets(): for name in self.dataSets():
a = QAction(name, self.menu) a = QAction(name, self.menu)
a.triggered.connect(self.setEmptyData) a.triggered.connect(self.setEmptyData)
self.menu.addAction(a) self.menu.addAction(a)
return self.menu return self.menu
def setEmptyData(self): def setEmptyData(self):
"Called from the menu generated with ``emptyDataMenu``." """Called from the menu generated with ``emptyDataMenu``."""
act = self.sender() act = self.sender()
data = self.dataSets()[act.text()] data = self.dataSets()[act.text()]
def addItems(data, parent): def addItems(data, parent):
for d in data: for d in data:
if len(d) == 1 or type(d) == str: if len(d) == 1 or type(d) == str:
@ -231,39 +237,39 @@ class worldModel(QStandardItemModel):
else: else:
i = self.addItem(d[0], parent) i = self.addItem(d[0], parent)
addItems(d[1], i) addItems(d[1], i)
addItems(data, None) addItems(data, None)
self.mw.treeWorld.expandAll() self.mw.treeWorld.expandAll()
############################################################################### ###############################################################################
# APPEARANCE # APPEARANCE
############################################################################### ###############################################################################
def data(self, index, role=Qt.EditRole): def data(self, index, role=Qt.EditRole):
level = 0 level = 0
i = index i = index
while i.parent() != QModelIndex(): while i.parent() != QModelIndex():
i = i.parent() i = i.parent()
level += 1 level += 1
if role == Qt.BackgroundRole: if role == Qt.BackgroundRole:
if level == 0: if level == 0:
return QBrush(lightBlue()) return QBrush(lightBlue())
if role == Qt.TextAlignmentRole: if role == Qt.TextAlignmentRole:
if level == 0: if level == 0:
return Qt.AlignCenter return Qt.AlignCenter
if role == Qt.FontRole: if role == Qt.FontRole:
if level in [0, 1]: if level in [0, 1]:
f = qApp.font() f = qApp.font()
f.setBold(True) f.setBold(True)
return f return f
if role == Qt.ForegroundRole: if role == Qt.ForegroundRole:
if level == 0: if level == 0:
return QBrush(Qt.darkBlue) return QBrush(Qt.darkBlue)
if role == Qt.SizeHintRole: if role == Qt.SizeHintRole:
fm = QFontMetrics(qApp.font()) fm = QFontMetrics(qApp.font())
h = fm.height() h = fm.height()
@ -271,6 +277,5 @@ class worldModel(QStandardItemModel):
return QSize(0, h + 12) return QSize(0, h + 12)
elif level == 1: elif level == 1:
return QSize(0, h + 6) return QSize(0, h + 6)
return QStandardItemModel.data(self, index, role) return QStandardItemModel.data(self, index, role)

View file

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
#from PyQt4.QtCore import *
#from PyQt4.QtGui import *

View file

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pickle
import pprint
from enums import *
from qt import *
import collections import collections
import pickle
from PyQt5.QtWidgets import qApp
from manuskript.enums import Outline
viewSettings = { viewSettings = {
"Tree": { "Tree": {

View file

@ -1,41 +1,48 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from ui.settings import *
from enums import *
from functions import *
from ui.editors.themes import *
from ui.views.textEditView import *
import settings
import os import os
from PyQt5.QtCore import QSize, QSettings, QRegExp
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIntValidator, QIcon, QFont, QColor, QPixmap, QStandardItem, QPainter
from PyQt5.QtWidgets import QStyleFactory, QWidget, QStyle, QColorDialog, QListWidgetItem
from PyQt5.QtWidgets import qApp
# Spell checker support # Spell checker support
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import allPaths, iconColor, writablePath, appPath
from manuskript.functions import mainWindow
from manuskript.ui.editors.themes import createThemePreview
from manuskript.ui.editors.themes import getThemeName
from manuskript.ui.editors.themes import loadThemeDatas
from manuskript.ui.settings_ui import Ui_Settings
from manuskript.ui.views.textEditView import textEditView
try: try:
import enchant import enchant
except ImportError: except ImportError:
enchant = None enchant = None
class settingsWindow(QWidget, Ui_Settings): class settingsWindow(QWidget, Ui_Settings):
def __init__(self, mainWindow): def __init__(self, mainWindow):
QWidget.__init__(self) QWidget.__init__(self)
self.setupUi(self) self.setupUi(self)
self.mw = mainWindow self.mw = mainWindow
# UI # UI
for i in range(self.lstMenu.count()): for i in range(self.lstMenu.count()):
item = self.lstMenu.item(i) item = self.lstMenu.item(i)
item.setSizeHint(QSize(item.sizeHint().width(), 42)) item.setSizeHint(QSize(item.sizeHint().width(), 42))
item.setTextAlignment(Qt.AlignCenter) item.setTextAlignment(Qt.AlignCenter)
self.lstMenu.setMaximumWidth(150) self.lstMenu.setMaximumWidth(150)
# General # General
self.cmbStyle.addItems(list(QStyleFactory.keys())) self.cmbStyle.addItems(list(QStyleFactory.keys()))
self.cmbStyle.setCurrentIndex([i.lower() for i in list(QStyleFactory.keys())].index(qApp.style().objectName())) self.cmbStyle.setCurrentIndex([i.lower() for i in list(QStyleFactory.keys())].index(qApp.style().objectName()))
self.cmbStyle.currentIndexChanged[str].connect(self.setStyle) self.cmbStyle.currentIndexChanged[str].connect(self.setStyle)
self.txtAutoSave.setValidator(QIntValidator(0, 999, self)) self.txtAutoSave.setValidator(QIntValidator(0, 999, self))
self.txtAutoSaveNoChanges.setValidator(QIntValidator(0, 999, self)) self.txtAutoSaveNoChanges.setValidator(QIntValidator(0, 999, self))
self.chkAutoSave.setChecked(settings.autoSave) self.chkAutoSave.setChecked(settings.autoSave)
@ -51,12 +58,12 @@ class settingsWindow(QWidget, Ui_Settings):
autoLoad, last = self.mw.welcome.getAutoLoadValues() autoLoad, last = self.mw.welcome.getAutoLoadValues()
self.chkAutoLoad.setChecked(autoLoad) self.chkAutoLoad.setChecked(autoLoad)
self.chkAutoLoad.stateChanged.connect(self.saveSettingsChanged) self.chkAutoLoad.stateChanged.connect(self.saveSettingsChanged)
dtt = [ dtt = [
("t2t", self.tr("Txt2Tags"), "text-x-script"), ("t2t", self.tr("Txt2Tags"), "text-x-script"),
("html", self.tr("Rich Text (html)"), "text-html"), ("html", self.tr("Rich Text (html)"), "text-html"),
("txt", self.tr("Plain Text"), "text-x-generic"), ("txt", self.tr("Plain Text"), "text-x-generic"),
] ]
self.cmbDefaultTextType.clear() self.cmbDefaultTextType.clear()
for t in dtt: for t in dtt:
self.cmbDefaultTextType.addItem(QIcon.fromTheme(t[2]), t[1], t[0]) self.cmbDefaultTextType.addItem(QIcon.fromTheme(t[2]), t[1], t[0])
@ -64,7 +71,7 @@ class settingsWindow(QWidget, Ui_Settings):
if i != -1: if i != -1:
self.cmbDefaultTextType.setCurrentIndex(i) self.cmbDefaultTextType.setCurrentIndex(i)
self.cmbDefaultTextType.currentIndexChanged.connect(self.saveSettingsChanged) self.cmbDefaultTextType.currentIndexChanged.connect(self.saveSettingsChanged)
# Revisions # Revisions
opt = settings.revisions opt = settings.revisions
self.chkRevisionsKeep.setChecked(opt["keep"]) self.chkRevisionsKeep.setChecked(opt["keep"])
@ -81,7 +88,7 @@ class settingsWindow(QWidget, Ui_Settings):
self.spnRevisionsMonth.valueChanged.connect(self.revisionsSettingsChanged) self.spnRevisionsMonth.valueChanged.connect(self.revisionsSettingsChanged)
self.spnRevisionsEternity.setValue(60 * 60 * 24 * 7 / opt["rules"][None]) self.spnRevisionsEternity.setValue(60 * 60 * 24 * 7 / opt["rules"][None])
self.spnRevisionsEternity.valueChanged.connect(self.revisionsSettingsChanged) self.spnRevisionsEternity.valueChanged.connect(self.revisionsSettingsChanged)
# Views # Views
self.tabViews.setCurrentIndex(0) self.tabViews.setCurrentIndex(0)
lst = ["Nothing", "POV", "Label", "Progress", "Compile"] lst = ["Nothing", "POV", "Label", "Progress", "Compile"]
@ -89,12 +96,12 @@ class settingsWindow(QWidget, Ui_Settings):
item, part = self.viewSettingsDatas()[cmb] item, part = self.viewSettingsDatas()[cmb]
cmb.setCurrentIndex(lst.index(settings.viewSettings[item][part])) cmb.setCurrentIndex(lst.index(settings.viewSettings[item][part]))
cmb.currentIndexChanged.connect(self.viewSettingsChanged) cmb.currentIndexChanged.connect(self.viewSettingsChanged)
for chk in self.outlineColumnsData(): for chk in self.outlineColumnsData():
col = self.outlineColumnsData()[chk] col = self.outlineColumnsData()[chk]
chk.setChecked(col in settings.outlineViewColumns) chk.setChecked(col in settings.outlineViewColumns)
chk.stateChanged.connect(self.outlineColumnsChanged) chk.stateChanged.connect(self.outlineColumnsChanged)
for item, what, value in [ for item, what, value in [
(self.rdoTreeItemCount, "InfoFolder", "Count"), (self.rdoTreeItemCount, "InfoFolder", "Count"),
(self.rdoTreeWC, "InfoFolder", "WC"), (self.rdoTreeWC, "InfoFolder", "WC"),
@ -103,16 +110,16 @@ class settingsWindow(QWidget, Ui_Settings):
(self.rdoTreeTextWC, "InfoText", "WC"), (self.rdoTreeTextWC, "InfoText", "WC"),
(self.rdoTreeTextProgress, "InfoText", "Progress"), (self.rdoTreeTextProgress, "InfoText", "Progress"),
(self.rdoTreeTextNothing, "InfoText", "Nothing"), (self.rdoTreeTextNothing, "InfoText", "Nothing"),
]: ]:
item.setChecked(settings.viewSettings["Tree"][what] == value) item.setChecked(settings.viewSettings["Tree"][what] == value)
item.toggled.connect(self.treeViewSettignsChanged) item.toggled.connect(self.treeViewSettignsChanged)
self.populatesCmbBackgrounds(self.cmbCorkImage) self.populatesCmbBackgrounds(self.cmbCorkImage)
self.setCorkImageDefault() self.setCorkImageDefault()
self.updateCorkColor() self.updateCorkColor()
self.cmbCorkImage.currentIndexChanged.connect(self.setCorkBackground) self.cmbCorkImage.currentIndexChanged.connect(self.setCorkBackground)
self.btnCorkColor.clicked.connect(self.setCorkColor) self.btnCorkColor.clicked.connect(self.setCorkColor)
# Text editor # Text editor
opt = settings.textEditor opt = settings.textEditor
self.setButtonColor(self.btnEditorFontColor, opt["fontColor"]) self.setButtonColor(self.btnEditorFontColor, opt["fontColor"])
@ -128,10 +135,10 @@ class settingsWindow(QWidget, Ui_Settings):
self.spnEditorFontSize.setValue(f.pointSize()) self.spnEditorFontSize.setValue(f.pointSize())
self.spnEditorFontSize.valueChanged.connect(self.updateEditorSettings) self.spnEditorFontSize.valueChanged.connect(self.updateEditorSettings)
self.cmbEditorLineSpacing.setCurrentIndex( self.cmbEditorLineSpacing.setCurrentIndex(
0 if opt["lineSpacing"] == 100 else 0 if opt["lineSpacing"] == 100 else
1 if opt["lineSpacing"] == 150 else 1 if opt["lineSpacing"] == 150 else
2 if opt["lineSpacing"] == 200 else 2 if opt["lineSpacing"] == 200 else
3) 3)
self.cmbEditorLineSpacing.currentIndexChanged.connect(self.updateEditorSettings) self.cmbEditorLineSpacing.currentIndexChanged.connect(self.updateEditorSettings)
self.spnEditorLineSpacing.setValue(opt["lineSpacing"]) self.spnEditorLineSpacing.setValue(opt["lineSpacing"])
self.spnEditorLineSpacing.valueChanged.connect(self.updateEditorSettings) self.spnEditorLineSpacing.valueChanged.connect(self.updateEditorSettings)
@ -145,7 +152,7 @@ class settingsWindow(QWidget, Ui_Settings):
self.spnEditorParaAbove.valueChanged.connect(self.updateEditorSettings) self.spnEditorParaAbove.valueChanged.connect(self.updateEditorSettings)
self.spnEditorParaBelow.setValue(opt["spacingBelow"]) self.spnEditorParaBelow.setValue(opt["spacingBelow"])
self.spnEditorParaAbove.valueChanged.connect(self.updateEditorSettings) self.spnEditorParaAbove.valueChanged.connect(self.updateEditorSettings)
# Labels # Labels
self.lstLabels.setModel(self.mw.mdlLabels) self.lstLabels.setModel(self.mw.mdlLabels)
self.lstLabels.setRowHidden(0, True) self.lstLabels.setRowHidden(0, True)
@ -153,13 +160,13 @@ class settingsWindow(QWidget, Ui_Settings):
self.btnLabelAdd.clicked.connect(self.addLabel) self.btnLabelAdd.clicked.connect(self.addLabel)
self.btnLabelRemove.clicked.connect(self.removeLabel) self.btnLabelRemove.clicked.connect(self.removeLabel)
self.btnLabelColor.clicked.connect(self.setLabelColor) self.btnLabelColor.clicked.connect(self.setLabelColor)
# Statuses # Statuses
self.lstStatus.setModel(self.mw.mdlStatus) self.lstStatus.setModel(self.mw.mdlStatus)
self.lstStatus.setRowHidden(0, True) self.lstStatus.setRowHidden(0, True)
self.btnStatusAdd.clicked.connect(self.addStatus) self.btnStatusAdd.clicked.connect(self.addStatus)
self.btnStatusRemove.clicked.connect(self.removeStatus) self.btnStatusRemove.clicked.connect(self.removeStatus)
# Fullscreen # Fullscreen
self._editingTheme = None self._editingTheme = None
self.btnThemeEditOK.setIcon(qApp.style().standardIcon(QStyle.SP_DialogApplyButton)) self.btnThemeEditOK.setIcon(qApp.style().standardIcon(QStyle.SP_DialogApplyButton))
@ -175,42 +182,41 @@ class settingsWindow(QWidget, Ui_Settings):
self.btnThemeAdd.clicked.connect(self.newTheme) self.btnThemeAdd.clicked.connect(self.newTheme)
self.btnThemeEdit.clicked.connect(self.editTheme) self.btnThemeEdit.clicked.connect(self.editTheme)
self.btnThemeRemove.clicked.connect(self.removeTheme) self.btnThemeRemove.clicked.connect(self.removeTheme)
def setTab(self, tab): def setTab(self, tab):
tabs = { tabs = {
"General":0, "General": 0,
"Views":1, "Views": 1,
"Labels":2, "Labels": 2,
"Status":3, "Status": 3,
"Fullscreen":4, "Fullscreen": 4,
} }
if tab in tabs: if tab in tabs:
self.lstMenu.setCurrentRow(tabs[tab]) self.lstMenu.setCurrentRow(tabs[tab])
else: else:
self.lstMenu.setCurrentRow(tab) self.lstMenu.setCurrentRow(tab)
#################################################################################################### ####################################################################################################
# GENERAL # # GENERAL #
#################################################################################################### ####################################################################################################
def setStyle(self, style): def setStyle(self, style):
#Save style to Qt Settings # Save style to Qt Settings
sttgs = QSettings(qApp.organizationName(), qApp.applicationName()) sttgs = QSettings(qApp.organizationName(), qApp.applicationName())
sttgs.setValue("applicationStyle", style) sttgs.setValue("applicationStyle", style)
qApp.setStyle(style) qApp.setStyle(style)
def saveSettingsChanged(self): def saveSettingsChanged(self):
if self.txtAutoSave.text() in ["", "0"]: if self.txtAutoSave.text() in ["", "0"]:
self.txtAutoSave.setText("1") self.txtAutoSave.setText("1")
if self.txtAutoSaveNoChanges.text() in ["", "0"]: if self.txtAutoSaveNoChanges.text() in ["", "0"]:
self.txtAutoSaveNoChanges.setText("1") self.txtAutoSaveNoChanges.setText("1")
sttgs = QSettings() sttgs = QSettings()
sttgs.setValue("autoLoad", True if self.chkAutoLoad.checkState() else False) sttgs.setValue("autoLoad", True if self.chkAutoLoad.checkState() else False)
sttgs.sync() sttgs.sync()
settings.autoSave = True if self.chkAutoSave.checkState() else False settings.autoSave = True if self.chkAutoSave.checkState() else False
settings.autoSaveNoChanges = True if self.chkAutoSaveNoChanges.checkState() else False settings.autoSaveNoChanges = True if self.chkAutoSaveNoChanges.checkState() else False
settings.saveOnQuit = True if self.chkSaveOnQuit.checkState() else False settings.saveOnQuit = True if self.chkSaveOnQuit.checkState() else False
@ -220,10 +226,9 @@ class settingsWindow(QWidget, Ui_Settings):
self.mw.saveTimerNoChanges.setInterval(settings.autoSaveNoChangesDelay * 1000) self.mw.saveTimerNoChanges.setInterval(settings.autoSaveNoChangesDelay * 1000)
settings.defaultTextType = self.cmbDefaultTextType.currentData() settings.defaultTextType = self.cmbDefaultTextType.currentData()
####################################################################################################
#################################################################################################### # REVISION #
# REVISION # ####################################################################################################
####################################################################################################
def revisionsSettingsChanged(self): def revisionsSettingsChanged(self):
opt = settings.revisions opt = settings.revisions
@ -234,10 +239,10 @@ class settingsWindow(QWidget, Ui_Settings):
opt["rules"][60 * 60 * 24] = 60 * 60 / self.spnRevisionsDay.value() opt["rules"][60 * 60 * 24] = 60 * 60 / self.spnRevisionsDay.value()
opt["rules"][60 * 60 * 24 * 30] = 60 * 60 * 24 / self.spnRevisionsMonth.value() opt["rules"][60 * 60 * 24 * 30] = 60 * 60 * 24 / self.spnRevisionsMonth.value()
opt["rules"][None] = 60 * 60 * 24 * 7 / self.spnRevisionsEternity.value() opt["rules"][None] = 60 * 60 * 24 * 7 / self.spnRevisionsEternity.value()
#################################################################################################### ####################################################################################################
# VIEWS # # VIEWS #
#################################################################################################### ####################################################################################################
def viewSettingsDatas(self): def viewSettingsDatas(self):
return { return {
@ -252,15 +257,15 @@ class settingsWindow(QWidget, Ui_Settings):
self.cmbCorkBackground: ("Cork", "Background"), self.cmbCorkBackground: ("Cork", "Background"),
self.cmbCorkBorder: ("Cork", "Border"), self.cmbCorkBorder: ("Cork", "Border"),
self.cmbCorkCorner: ("Cork", "Corner") self.cmbCorkCorner: ("Cork", "Corner")
} }
def viewSettingsChanged(self): def viewSettingsChanged(self):
cmb = self.sender() cmb = self.sender()
lst = ["Nothing", "POV", "Label", "Progress", "Compile"] lst = ["Nothing", "POV", "Label", "Progress", "Compile"]
item, part = self.viewSettingsDatas()[cmb] item, part = self.viewSettingsDatas()[cmb]
element = lst[cmb.currentIndex()] element = lst[cmb.currentIndex()]
self.mw.setViewSettings(item, part, element) self.mw.setViewSettings(item, part, element)
def outlineColumnsData(self): def outlineColumnsData(self):
return { return {
self.chkOutlineTitle: Outline.title.value, self.chkOutlineTitle: Outline.title.value,
@ -271,8 +276,8 @@ class settingsWindow(QWidget, Ui_Settings):
self.chkOutlineWordCount: Outline.wordCount.value, self.chkOutlineWordCount: Outline.wordCount.value,
self.chkOutlineGoal: Outline.goal.value, self.chkOutlineGoal: Outline.goal.value,
self.chkOutlinePercentage: Outline.goalPercentage.value, self.chkOutlinePercentage: Outline.goalPercentage.value,
} }
def outlineColumnsChanged(self): def outlineColumnsChanged(self):
chk = self.sender() chk = self.sender()
val = True if chk.checkState() else False val = True if chk.checkState() else False
@ -281,11 +286,11 @@ class settingsWindow(QWidget, Ui_Settings):
settings.outlineViewColumns.append(col) settings.outlineViewColumns.append(col)
elif not val and col in settings.outlineViewColumns: elif not val and col in settings.outlineViewColumns:
settings.outlineViewColumns.remove(col) settings.outlineViewColumns.remove(col)
# Update views # Update views
self.mw.redacEditor.outlineView.hideColumns() self.mw.redacEditor.outlineView.hideColumns()
self.mw.treePlanOutline.hideColumns() self.mw.treePlanOutline.hideColumns()
def treeViewSettignsChanged(self): def treeViewSettignsChanged(self):
for item, what, value in [ for item, what, value in [
(self.rdoTreeItemCount, "InfoFolder", "Count"), (self.rdoTreeItemCount, "InfoFolder", "Count"),
@ -295,12 +300,12 @@ class settingsWindow(QWidget, Ui_Settings):
(self.rdoTreeTextWC, "InfoText", "WC"), (self.rdoTreeTextWC, "InfoText", "WC"),
(self.rdoTreeTextProgress, "InfoText", "Progress"), (self.rdoTreeTextProgress, "InfoText", "Progress"),
(self.rdoTreeTextNothing, "InfoText", "Nothing"), (self.rdoTreeTextNothing, "InfoText", "Nothing"),
]: ]:
if item.isChecked(): if item.isChecked():
settings.viewSettings["Tree"][what] = value settings.viewSettings["Tree"][what] = value
self.mw.treeRedacOutline.viewport().update() self.mw.treeRedacOutline.viewport().update()
def setCorkColor(self): def setCorkColor(self):
color = QColor(settings.corkBackground["color"]) color = QColor(settings.corkBackground["color"])
self.colorDialog = QColorDialog(color, self) self.colorDialog = QColorDialog(color, self)
@ -310,10 +315,10 @@ class settingsWindow(QWidget, Ui_Settings):
self.updateCorkColor() self.updateCorkColor()
# Update Cork view # Update Cork view
self.mw.mainEditor.updateCorkBackground() self.mw.mainEditor.updateCorkBackground()
def updateCorkColor(self): def updateCorkColor(self):
self.btnCorkColor.setStyleSheet("background:{};".format(settings.corkBackground["color"])) self.btnCorkColor.setStyleSheet("background:{};".format(settings.corkBackground["color"]))
def setCorkBackground(self, i): def setCorkBackground(self, i):
img = self.cmbCorkImage.itemData(i) img = self.cmbCorkImage.itemData(i)
if img: if img:
@ -322,11 +327,11 @@ class settingsWindow(QWidget, Ui_Settings):
settings.corkBackground["image"] = "" settings.corkBackground["image"] = ""
# Update Cork view # Update Cork view
self.mw.mainEditor.updateCorkBackground() self.mw.mainEditor.updateCorkBackground()
def populatesCmbBackgrounds(self, cmb): def populatesCmbBackgrounds(self, cmb):
#self.cmbDelegate = cmbPixmapDelegate() # self.cmbDelegate = cmbPixmapDelegate()
#self.cmbCorkImage.setItemDelegate(self.cmbDelegate) # self.cmbCorkImage.setItemDelegate(self.cmbDelegate)
paths = allPaths("resources/backgrounds") paths = allPaths("resources/backgrounds")
cmb.clear() cmb.clear()
cmb.addItem(QIcon.fromTheme("list-remove"), "", "") cmb.addItem(QIcon.fromTheme("list-remove"), "", "")
@ -334,21 +339,21 @@ class settingsWindow(QWidget, Ui_Settings):
lst = os.listdir(p) lst = os.listdir(p)
for l in lst: for l in lst:
if l.lower()[-4:] in [".jpg", ".png"] or \ if l.lower()[-4:] in [".jpg", ".png"] or \
l.lower()[-5:] in [".jpeg"]: l.lower()[-5:] in [".jpeg"]:
px = QPixmap(os.path.join(p, l)).scaled(128, 64, Qt.KeepAspectRatio) px = QPixmap(os.path.join(p, l)).scaled(128, 64, Qt.KeepAspectRatio)
cmb.addItem(QIcon(px), "", os.path.join(p, l)) cmb.addItem(QIcon(px), "", os.path.join(p, l))
cmb.setIconSize(QSize(128, 64)) cmb.setIconSize(QSize(128, 64))
def setCorkImageDefault(self): def setCorkImageDefault(self):
if settings.corkBackground["image"] != "": if settings.corkBackground["image"] != "":
i = self.cmbCorkImage.findData(settings.corkBackground["image"]) i = self.cmbCorkImage.findData(settings.corkBackground["image"])
if i != -1: if i != -1:
self.cmbCorkImage.setCurrentIndex(i) self.cmbCorkImage.setCurrentIndex(i)
#################################################################################################### ####################################################################################################
# VIEWS / EDITOR # VIEWS / EDITOR
#################################################################################################### ####################################################################################################
def updateEditorSettings(self): def updateEditorSettings(self):
# Store settings # Store settings
@ -356,20 +361,20 @@ class settingsWindow(QWidget, Ui_Settings):
f.setPointSize(self.spnEditorFontSize.value()) f.setPointSize(self.spnEditorFontSize.value())
settings.textEditor["font"] = f.toString() settings.textEditor["font"] = f.toString()
settings.textEditor["lineSpacing"] = \ settings.textEditor["lineSpacing"] = \
100 if self.cmbEditorLineSpacing.currentIndex() == 0 else\ 100 if self.cmbEditorLineSpacing.currentIndex() == 0 else \
150 if self.cmbEditorLineSpacing.currentIndex() == 1 else\ 150 if self.cmbEditorLineSpacing.currentIndex() == 1 else \
200 if self.cmbEditorLineSpacing.currentIndex() == 2 else\ 200 if self.cmbEditorLineSpacing.currentIndex() == 2 else \
self.spnEditorLineSpacing.value() self.spnEditorLineSpacing.value()
self.spnEditorLineSpacing.setEnabled(self.cmbEditorLineSpacing.currentIndex() == 3) self.spnEditorLineSpacing.setEnabled(self.cmbEditorLineSpacing.currentIndex() == 3)
settings.textEditor["tabWidth"] = self.spnEditorTabWidth.value() settings.textEditor["tabWidth"] = self.spnEditorTabWidth.value()
settings.textEditor["indent"] = True if self.chkEditorIndent.checkState() else False settings.textEditor["indent"] = True if self.chkEditorIndent.checkState() else False
settings.textEditor["spacingAbove"] = self.spnEditorParaAbove.value() settings.textEditor["spacingAbove"] = self.spnEditorParaAbove.value()
settings.textEditor["spacingBelow"] = self.spnEditorParaBelow.value() settings.textEditor["spacingBelow"] = self.spnEditorParaBelow.value()
# Update font and defaultBlockFormat to all textEditView. Drastically. # Update font and defaultBlockFormat to all textEditView. Drastically.
for w in mainWindow().findChildren(textEditView, QRegExp(".*")): for w in mainWindow().findChildren(textEditView, QRegExp(".*")):
w.loadFontSettings() w.loadFontSettings()
def choseEditorFontColor(self): def choseEditorFontColor(self):
color = settings.textEditor["fontColor"] color = settings.textEditor["fontColor"]
self.colorDialog = QColorDialog(QColor(color), self) self.colorDialog = QColorDialog(QColor(color), self)
@ -387,7 +392,7 @@ class settingsWindow(QWidget, Ui_Settings):
settings.textEditor["misspelled"] = color.name() settings.textEditor["misspelled"] = color.name()
self.setButtonColor(self.btnEditorMisspelledColor, color.name()) self.setButtonColor(self.btnEditorMisspelledColor, color.name())
self.updateEditorSettings() self.updateEditorSettings()
def choseEditorBackgroundColor(self): def choseEditorBackgroundColor(self):
color = settings.textEditor["background"] color = settings.textEditor["background"]
self.colorDialog = QColorDialog(QColor(color), self) self.colorDialog = QColorDialog(QColor(color), self)
@ -396,40 +401,39 @@ class settingsWindow(QWidget, Ui_Settings):
settings.textEditor["background"] = color.name() settings.textEditor["background"] = color.name()
self.setButtonColor(self.btnEditorBackgroundColor, color.name()) self.setButtonColor(self.btnEditorBackgroundColor, color.name())
self.updateEditorSettings() self.updateEditorSettings()
#################################################################################################### ####################################################################################################
# STATUS # # STATUS #
#################################################################################################### ####################################################################################################
def addStatus(self): def addStatus(self):
self.mw.mdlStatus.appendRow(QStandardItem(self.tr("New status"))) self.mw.mdlStatus.appendRow(QStandardItem(self.tr("New status")))
def removeStatus(self): def removeStatus(self):
for i in self.lstStatus.selectedIndexes(): for i in self.lstStatus.selectedIndexes():
self.mw.mdlStatus.removeRows(i.row(), 1) self.mw.mdlStatus.removeRows(i.row(), 1)
#################################################################################################### ####################################################################################################
# LABELS # # LABELS #
#################################################################################################### ####################################################################################################
def updateLabelColor(self, index): def updateLabelColor(self, index):
#px = QPixmap(64, 64) # px = QPixmap(64, 64)
#px.fill(iconColor(self.mw.mdlLabels.item(index.row()).icon())) # px.fill(iconColor(self.mw.mdlLabels.item(index.row()).icon()))
#self.btnLabelColor.setIcon(QIcon(px)) # self.btnLabelColor.setIcon(QIcon(px))
self.btnLabelColor.setStyleSheet("background:{};".format(iconColor(self.mw.mdlLabels.item(index.row()).icon()).name())) self.btnLabelColor.setStyleSheet(
"background:{};".format(iconColor(self.mw.mdlLabels.item(index.row()).icon()).name()))
self.btnLabelColor.setEnabled(True) self.btnLabelColor.setEnabled(True)
def addLabel(self): def addLabel(self):
px = QPixmap(32, 32) px = QPixmap(32, 32)
px.fill(Qt.transparent) px.fill(Qt.transparent)
self.mw.mdlLabels.appendRow(QStandardItem(QIcon(px), self.tr("New label"))) self.mw.mdlLabels.appendRow(QStandardItem(QIcon(px), self.tr("New label")))
def removeLabel(self): def removeLabel(self):
for i in self.lstLabels.selectedIndexes(): for i in self.lstLabels.selectedIndexes():
self.mw.mdlLabels.removeRows(i.row(), 1) self.mw.mdlLabels.removeRows(i.row(), 1)
def setLabelColor(self): def setLabelColor(self):
index = self.lstLabels.currentIndex() index = self.lstLabels.currentIndex()
color = iconColor(self.mw.mdlLabels.item(index.row()).icon()) color = iconColor(self.mw.mdlLabels.item(index.row()).icon())
@ -440,16 +444,16 @@ class settingsWindow(QWidget, Ui_Settings):
px.fill(color) px.fill(color)
self.mw.mdlLabels.item(index.row()).setIcon(QIcon(px)) self.mw.mdlLabels.item(index.row()).setIcon(QIcon(px))
self.updateLabelColor(index) self.updateLabelColor(index)
#################################################################################################### ####################################################################################################
# FULLSCREEN # # FULLSCREEN #
#################################################################################################### ####################################################################################################
def themeSelected(self, current, previous): def themeSelected(self, current, previous):
if current: if current:
# UI updates # UI updates
self.btnThemeEdit.setEnabled(current.data(Qt.UserRole+1)) self.btnThemeEdit.setEnabled(current.data(Qt.UserRole + 1))
self.btnThemeRemove.setEnabled(current.data(Qt.UserRole+1)) self.btnThemeRemove.setEnabled(current.data(Qt.UserRole + 1))
# Save settings # Save settings
theme = current.data(Qt.UserRole) theme = current.data(Qt.UserRole)
settings.fullScreenTheme = os.path.splitext(os.path.split(theme)[1])[0] settings.fullScreenTheme = os.path.splitext(os.path.split(theme)[1])[0]
@ -457,7 +461,7 @@ class settingsWindow(QWidget, Ui_Settings):
# UI updates # UI updates
self.btnThemeEdit.setEnabled(False) self.btnThemeEdit.setEnabled(False)
self.btnThemeRemove.setEnabled(False) self.btnThemeRemove.setEnabled(False)
def newTheme(self): def newTheme(self):
path = writablePath("resources/themes") path = writablePath("resources/themes")
name = self.tr("newtheme") name = self.tr("newtheme")
@ -468,41 +472,41 @@ class settingsWindow(QWidget, Ui_Settings):
name = os.path.join(path, "{}_{}.theme".format(name, i)) name = os.path.join(path, "{}_{}.theme".format(name, i))
else: else:
name = os.path.join(path, "{}.theme".format(name)) name = os.path.join(path, "{}.theme".format(name))
settings = QSettings(name, QSettings.IniFormat) settings = QSettings(name, QSettings.IniFormat)
settings.setValue("Name", self.tr("New theme")) settings.setValue("Name", self.tr("New theme"))
settings.sync() settings.sync()
self.populatesThemesList() self.populatesThemesList()
def editTheme(self): def editTheme(self):
item = self.lstThemes.currentItem() item = self.lstThemes.currentItem()
theme = item.data(Qt.UserRole) theme = item.data(Qt.UserRole)
self.loadTheme(theme) self.loadTheme(theme)
self.themeStack.setCurrentIndex(1) self.themeStack.setCurrentIndex(1)
def removeTheme(self): def removeTheme(self):
item = self.lstThemes.currentItem() item = self.lstThemes.currentItem()
theme = item.data(Qt.UserRole) theme = item.data(Qt.UserRole)
os.remove(theme) os.remove(theme)
self.populatesThemesList() self.populatesThemesList()
def populatesThemesList(self): def populatesThemesList(self):
paths = allPaths("resources/themes") paths = allPaths("resources/themes")
current = settings.fullScreenTheme current = settings.fullScreenTheme
self.lstThemes.clear() self.lstThemes.clear()
for p in paths: for p in paths:
lst = [i for i in os.listdir(p) if os.path.splitext(i)[1] == ".theme"] lst = [i for i in os.listdir(p) if os.path.splitext(i)[1] == ".theme"]
for t in lst: for t in lst:
theme = os.path.join(p, t) theme = os.path.join(p, t)
editable = not appPath() in theme editable = not appPath() in theme
n = getThemeName(theme) n = getThemeName(theme)
item = QListWidgetItem(n) item = QListWidgetItem(n)
item.setData(Qt.UserRole, theme) item.setData(Qt.UserRole, theme)
item.setData(Qt.UserRole+1, editable) item.setData(Qt.UserRole + 1, editable)
thumb = os.path.join(p, t.replace(".theme", ".jpg")) thumb = os.path.join(p, t.replace(".theme", ".jpg"))
px = QPixmap(200, 120) px = QPixmap(200, 120)
px.fill(Qt.white) px.fill(Qt.white)
@ -510,32 +514,32 @@ class settingsWindow(QWidget, Ui_Settings):
currentScreen = qApp.desktop().screenNumber(self) currentScreen = qApp.desktop().screenNumber(self)
screenRect = qApp.desktop().screenGeometry(currentScreen) screenRect = qApp.desktop().screenGeometry(currentScreen)
thumb = createThemePreview(theme, screenRect) thumb = createThemePreview(theme, screenRect)
icon = QPixmap(thumb).scaled(200, 120, Qt.KeepAspectRatio) icon = QPixmap(thumb).scaled(200, 120, Qt.KeepAspectRatio)
painter = QPainter(px) painter = QPainter(px)
painter.drawPixmap(px.rect().center()-icon.rect().center(), icon) painter.drawPixmap(px.rect().center() - icon.rect().center(), icon)
painter.end() painter.end()
item.setIcon(QIcon(px)) item.setIcon(QIcon(px))
self.lstThemes.addItem(item) self.lstThemes.addItem(item)
if current and current in t: if current and current in t:
self.lstThemes.setCurrentItem(item) self.lstThemes.setCurrentItem(item)
current = None current = None
self.lstThemes.setIconSize(QSize(200, 120)) self.lstThemes.setIconSize(QSize(200, 120))
if current: # the theme from settings wasn't found if current: # the theme from settings wasn't found
# select the last from the list # select the last from the list
self.lstThemes.setCurrentRow(self.lstThemes.count() - 1) self.lstThemes.setCurrentRow(self.lstThemes.count() - 1)
def loadTheme(self, theme): def loadTheme(self, theme):
self._editingTheme = theme self._editingTheme = theme
self._loadingTheme = True # So we don't generate preview while loading self._loadingTheme = True # So we don't generate preview while loading
# Load datas # Load datas
self._themeData = loadThemeDatas(theme) self._themeData = loadThemeDatas(theme)
# Window Background # Window Background
self.btnThemWindowBackgroundColor.clicked.connect(lambda: self.getThemeColor("Background/Color")) self.btnThemWindowBackgroundColor.clicked.connect(lambda: self.getThemeColor("Background/Color"))
try: try:
@ -545,7 +549,7 @@ class settingsWindow(QWidget, Ui_Settings):
self.populatesCmbBackgrounds(self.cmbThemeBackgroundImage) self.populatesCmbBackgrounds(self.cmbThemeBackgroundImage)
self.cmbThemeBackgroundImage.currentIndexChanged.connect(self.updateThemeBackground) self.cmbThemeBackgroundImage.currentIndexChanged.connect(self.updateThemeBackground)
self.cmbThemBackgroundType.currentIndexChanged.connect(lambda i: self.setSetting("Background/Type", i)) self.cmbThemBackgroundType.currentIndexChanged.connect(lambda i: self.setSetting("Background/Type", i))
# Text Background # Text Background
self.btnThemeTextBackgroundColor.clicked.connect(lambda: self.getThemeColor("Foreground/Color")) self.btnThemeTextBackgroundColor.clicked.connect(lambda: self.getThemeColor("Foreground/Color"))
self.spnThemeTextBackgroundOpacity.valueChanged.connect(lambda v: self.setSetting("Foreground/Opacity", v)) self.spnThemeTextBackgroundOpacity.valueChanged.connect(lambda v: self.setSetting("Foreground/Opacity", v))
@ -554,7 +558,7 @@ class settingsWindow(QWidget, Ui_Settings):
self.cmbThemeTextPosition.currentIndexChanged.connect(lambda i: self.setSetting("Foreground/Position", i)) self.cmbThemeTextPosition.currentIndexChanged.connect(lambda i: self.setSetting("Foreground/Position", i))
self.spnThemeTextRadius.valueChanged.connect(lambda v: self.setSetting("Foreground/Rounding", v)) self.spnThemeTextRadius.valueChanged.connect(lambda v: self.setSetting("Foreground/Rounding", v))
self.spnThemeTextWidth.valueChanged.connect(lambda v: self.setSetting("Foreground/Width", v)) self.spnThemeTextWidth.valueChanged.connect(lambda v: self.setSetting("Foreground/Width", v))
# Text Options # Text Options
self.btnThemeTextColor.clicked.connect(lambda: self.getThemeColor("Text/Color")) self.btnThemeTextColor.clicked.connect(lambda: self.getThemeColor("Text/Color"))
self.cmbThemeFont.currentFontChanged.connect(self.updateThemeFont) self.cmbThemeFont.currentFontChanged.connect(self.updateThemeFont)
@ -565,37 +569,37 @@ class settingsWindow(QWidget, Ui_Settings):
self.populatesFontSize() self.populatesFontSize()
self.cmbThemeFontSize.currentIndexChanged.connect(self.updateThemeFont) self.cmbThemeFontSize.currentIndexChanged.connect(self.updateThemeFont)
self.btnThemeMisspelledColor.clicked.connect(lambda: self.getThemeColor("Text/Misspelled")) self.btnThemeMisspelledColor.clicked.connect(lambda: self.getThemeColor("Text/Misspelled"))
# Paragraph Options # Paragraph Options
self.chkThemeIndent.stateChanged.connect(lambda v: self.setSetting("Spacings/IndendFirstLine", v!=0)) self.chkThemeIndent.stateChanged.connect(lambda v: self.setSetting("Spacings/IndendFirstLine", v != 0))
self.cmbThemeLineSpacing.currentIndexChanged.connect(self.updateLineSpacing) self.cmbThemeLineSpacing.currentIndexChanged.connect(self.updateLineSpacing)
self.cmbThemeLineSpacing.currentIndexChanged.connect(self.updateLineSpacing) self.cmbThemeLineSpacing.currentIndexChanged.connect(self.updateLineSpacing)
self.spnThemeLineSpacing.valueChanged.connect(lambda v: self.setSetting("Spacings/LineSpacing", v)) self.spnThemeLineSpacing.valueChanged.connect(lambda v: self.setSetting("Spacings/LineSpacing", v))
self.spnThemeParaAbove.valueChanged.connect(lambda v: self.setSetting("Spacings/ParagraphAbove", v)) self.spnThemeParaAbove.valueChanged.connect(lambda v: self.setSetting("Spacings/ParagraphAbove", v))
self.spnThemeParaBelow.valueChanged.connect(lambda v: self.setSetting("Spacings/ParagraphBelow", v)) self.spnThemeParaBelow.valueChanged.connect(lambda v: self.setSetting("Spacings/ParagraphBelow", v))
self.spnThemeTabWidth.valueChanged.connect(lambda v: self.setSetting("Spacings/TabWidth", v)) self.spnThemeTabWidth.valueChanged.connect(lambda v: self.setSetting("Spacings/TabWidth", v))
# Update UI # Update UI
self.updateUIFromTheme() self.updateUIFromTheme()
# Generate preview # Generate preview
self._loadingTheme = False self._loadingTheme = False
self.updatePreview() self.updatePreview()
def setSetting(self, key, val): def setSetting(self, key, val):
self._themeData[key] = val self._themeData[key] = val
self.updatePreview() self.updatePreview()
def updateUIFromTheme(self): def updateUIFromTheme(self):
self.txtThemeName.setText(self._themeData["Name"]) self.txtThemeName.setText(self._themeData["Name"])
# Window Background # Window Background
self.setButtonColor(self.btnThemWindowBackgroundColor, self._themeData["Background/Color"]) self.setButtonColor(self.btnThemWindowBackgroundColor, self._themeData["Background/Color"])
i = self.cmbThemeBackgroundImage.findData(self._themeData["Background/ImageFile"], flags=Qt.MatchContains) i = self.cmbThemeBackgroundImage.findData(self._themeData["Background/ImageFile"], flags=Qt.MatchContains)
if i != -1: if i != -1:
self.cmbThemeBackgroundImage.setCurrentIndex(i) self.cmbThemeBackgroundImage.setCurrentIndex(i)
self.cmbThemBackgroundType.setCurrentIndex(self._themeData["Background/Type"]) self.cmbThemBackgroundType.setCurrentIndex(self._themeData["Background/Type"])
# Text background # Text background
self.setButtonColor(self.btnThemeTextBackgroundColor, self._themeData["Foreground/Color"]) self.setButtonColor(self.btnThemeTextBackgroundColor, self._themeData["Foreground/Color"])
self.spnThemeTextBackgroundOpacity.setValue(self._themeData["Foreground/Opacity"]) self.spnThemeTextBackgroundOpacity.setValue(self._themeData["Foreground/Opacity"])
@ -604,7 +608,7 @@ class settingsWindow(QWidget, Ui_Settings):
self.cmbThemeTextPosition.setCurrentIndex(self._themeData["Foreground/Position"]) self.cmbThemeTextPosition.setCurrentIndex(self._themeData["Foreground/Position"])
self.spnThemeTextRadius.setValue(self._themeData["Foreground/Rounding"]) self.spnThemeTextRadius.setValue(self._themeData["Foreground/Rounding"])
self.spnThemeTextWidth.setValue(self._themeData["Foreground/Width"]) self.spnThemeTextWidth.setValue(self._themeData["Foreground/Width"])
# Text Options # Text Options
self.setButtonColor(self.btnThemeTextColor, self._themeData["Text/Color"]) self.setButtonColor(self.btnThemeTextColor, self._themeData["Text/Color"])
f = QFont() f = QFont()
@ -615,9 +619,9 @@ class settingsWindow(QWidget, Ui_Settings):
self.cmbThemeFontSize.setCurrentIndex(i) self.cmbThemeFontSize.setCurrentIndex(i)
else: else:
self.cmbThemeFontSize.addItem(str(f.pointSize())) self.cmbThemeFontSize.addItem(str(f.pointSize()))
self.cmbThemeFontSize.setCurrentIndex(self.cmbThemeFontSize.count()-1) self.cmbThemeFontSize.setCurrentIndex(self.cmbThemeFontSize.count() - 1)
self.setButtonColor(self.btnThemeMisspelledColor, self._themeData["Text/Misspelled"]) self.setButtonColor(self.btnThemeMisspelledColor, self._themeData["Text/Misspelled"])
# Paragraph Options # Paragraph Options
self.chkThemeIndent.setCheckState(Qt.Checked if self._themeData["Spacings/IndendFirstLine"] else Qt.Unchecked) self.chkThemeIndent.setCheckState(Qt.Checked if self._themeData["Spacings/IndendFirstLine"] else Qt.Unchecked)
self.spnThemeLineSpacing.setEnabled(False) self.spnThemeLineSpacing.setEnabled(False)
@ -634,22 +638,22 @@ class settingsWindow(QWidget, Ui_Settings):
self.spnThemeParaAbove.setValue(self._themeData["Spacings/ParagraphAbove"]) self.spnThemeParaAbove.setValue(self._themeData["Spacings/ParagraphAbove"])
self.spnThemeParaBelow.setValue(self._themeData["Spacings/ParagraphBelow"]) self.spnThemeParaBelow.setValue(self._themeData["Spacings/ParagraphBelow"])
self.spnThemeTabWidth.setValue(self._themeData["Spacings/TabWidth"]) self.spnThemeTabWidth.setValue(self._themeData["Spacings/TabWidth"])
def populatesFontSize(self): def populatesFontSize(self):
self.cmbThemeFontSize.clear() self.cmbThemeFontSize.clear()
s = list(range(6, 13)) + list(range(14,29, 2)) + [36, 48, 72] s = list(range(6, 13)) + list(range(14, 29, 2)) + [36, 48, 72]
for i in s: for i in s:
self.cmbThemeFontSize.addItem(str(i)) self.cmbThemeFontSize.addItem(str(i))
def updateThemeFont(self, v): def updateThemeFont(self, v):
f = self.cmbThemeFont.currentFont() f = self.cmbThemeFont.currentFont()
s = self.cmbThemeFontSize.itemText(self.cmbThemeFontSize.currentIndex()) s = self.cmbThemeFontSize.itemText(self.cmbThemeFontSize.currentIndex())
if s: if s:
f.setPointSize(int(s)) f.setPointSize(int(s))
self._themeData["Text/Font"] = f.toString() self._themeData["Text/Font"] = f.toString()
self.updatePreview() self.updatePreview()
def updateLineSpacing(self, i): def updateLineSpacing(self, i):
if i == 0: if i == 0:
self._themeData["Spacings/LineSpacing"] = 100 self._themeData["Spacings/LineSpacing"] = 100
@ -661,16 +665,16 @@ class settingsWindow(QWidget, Ui_Settings):
self._themeData["Spacings/LineSpacing"] = self.spnThemeLineSpacing.value() self._themeData["Spacings/LineSpacing"] = self.spnThemeLineSpacing.value()
self.spnThemeLineSpacing.setEnabled(i == 3) self.spnThemeLineSpacing.setEnabled(i == 3)
self.updatePreview() self.updatePreview()
def updateThemeBackground(self, i): def updateThemeBackground(self, i):
img = self.cmbCorkImage.itemData(i) img = self.cmbCorkImage.itemData(i)
if img: if img:
self._themeData["Background/ImageFile"] = os.path.split(img)[1] self._themeData["Background/ImageFile"] = os.path.split(img)[1]
else: else:
self._themeData["Background/ImageFile"] = "" self._themeData["Background/ImageFile"] = ""
self.updatePreview() self.updatePreview()
def getThemeColor(self, key): def getThemeColor(self, key):
color = self._themeData[key] color = self._themeData[key]
self.colorDialog = QColorDialog(QColor(color), self) self.colorDialog = QColorDialog(QColor(color), self)
@ -679,37 +683,37 @@ class settingsWindow(QWidget, Ui_Settings):
self._themeData[key] = color.name() self._themeData[key] = color.name()
self.updateUIFromTheme() self.updateUIFromTheme()
self.updatePreview() self.updatePreview()
def updatePreview(self): def updatePreview(self):
if self._loadingTheme: if self._loadingTheme:
return return
currentScreen = qApp.desktop().screenNumber(self) currentScreen = qApp.desktop().screenNumber(self)
screen = qApp.desktop().screenGeometry(currentScreen) screen = qApp.desktop().screenGeometry(currentScreen)
px = createThemePreview(self._themeData, screen, self.lblPreview.size()) px = createThemePreview(self._themeData, screen, self.lblPreview.size())
self.lblPreview.setPixmap(px) self.lblPreview.setPixmap(px)
def setButtonColor(self, btn, color): def setButtonColor(self, btn, color):
btn.setStyleSheet("background:{};".format(color)) btn.setStyleSheet("background:{};".format(color))
def saveTheme(self): def saveTheme(self):
settings = QSettings(self._editingTheme, QSettings.IniFormat) settings = QSettings(self._editingTheme, QSettings.IniFormat)
self._themeData["Name"] = self.txtThemeName.text() self._themeData["Name"] = self.txtThemeName.text()
for key in self._themeData: for key in self._themeData:
settings.setValue(key, self._themeData[key]) settings.setValue(key, self._themeData[key])
settings.sync() settings.sync()
self.populatesThemesList() self.populatesThemesList()
self.themeStack.setCurrentIndex(0) self.themeStack.setCurrentIndex(0)
self._editingTheme = None self._editingTheme = None
def cancelEdit(self): def cancelEdit(self):
self.themeStack.setCurrentIndex(0) self.themeStack.setCurrentIndex(0)
self._editingTheme = None self._editingTheme = None
def resizeEvent(self, event): def resizeEvent(self, event):
QWidget.resizeEvent(self, event) QWidget.resizeEvent(self, event)
if self._editingTheme: if self._editingTheme:
self.updatePreview() self.updatePreview()

View file

@ -1,23 +1,26 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import pyqtSignal, Qt, QTimer, QRect
from qt import * from PyQt5.QtGui import QBrush, QCursor, QPalette, QFontMetrics
from enums import * from PyQt5.QtWidgets import QWidget, QListWidgetItem, QToolTip, QStyledItemDelegate, QStyle
from models.outlineModel import *
from ui.cheatSheet_ui import * from manuskript.enums import Perso
from functions import * from manuskript.enums import Plot
import models.references as Ref from manuskript.functions import lightBlue
from manuskript.functions import mainWindow
from manuskript.ui.cheatSheet_ui import Ui_cheatSheet
from manuskript.models import references as Ref
class cheatSheet(QWidget, Ui_cheatSheet): class cheatSheet(QWidget, Ui_cheatSheet):
activated = pyqtSignal(str) activated = pyqtSignal(str)
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.splitter.setStretchFactor(0, 5) self.splitter.setStretchFactor(0, 5)
self.splitter.setStretchFactor(1, 70) self.splitter.setStretchFactor(1, 70)
self.txtFilter.textChanged.connect(self.updateListFromData) self.txtFilter.textChanged.connect(self.updateListFromData)
self.txtFilter.returnPressed.connect(self.showInfos) self.txtFilter.returnPressed.connect(self.showInfos)
self.listDelegate = listCompleterDelegate(self) self.listDelegate = listCompleterDelegate(self)
@ -26,80 +29,80 @@ class cheatSheet(QWidget, Ui_cheatSheet):
self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.linkActivated.connect(self.openLink) self.view.linkActivated.connect(self.openLink)
self.view.linkHovered.connect(self.linkHovered) self.view.linkHovered.connect(self.linkHovered)
self.outlineModel = None self.outlineModel = None
self.persoModel = None self.persoModel = None
self.plotModel = None self.plotModel = None
self.worldModel = None self.worldModel = None
self.populateTimer = QTimer(self) self.populateTimer = QTimer(self)
self.populateTimer.setSingleShot(True) self.populateTimer.setSingleShot(True)
self.populateTimer.setInterval(500) self.populateTimer.setInterval(500)
self.populateTimer.timeout.connect(self.populate) self.populateTimer.timeout.connect(self.populate)
self.populateTimer.stop() self.populateTimer.stop()
self.data = {} self.data = {}
self.populate() self.populate()
def setModels(self): def setModels(self):
mw = mainWindow() mw = mainWindow()
self.outlineModel = mw.mdlOutline self.outlineModel = mw.mdlOutline
self.persoModel = mw.mdlPersos self.persoModel = mw.mdlPersos
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.persoModel.dataChanged.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)
self.populate() self.populate()
def populate(self): def populate(self):
if self.persoModel: if self.persoModel:
d = [] d = []
for r in range(self.persoModel.rowCount()): for r in range(self.persoModel.rowCount()):
name = self.persoModel.item(r, Perso.name.value).text() name = self.persoModel.item(r, Perso.name.value).text()
ID = self.persoModel.item(r, Perso.ID.value).text() ID = self.persoModel.item(r, Perso.ID.value).text()
imp = self.persoModel.item(r, Perso.importance.value).text() imp = self.persoModel.item(r, Perso.importance.value).text()
imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)] imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)]
d.append((name, ID, imp)) d.append((name, ID, imp))
self.data[(self.tr("Characters"), Ref.PersoLetter)] = d self.data[(self.tr("Characters"), Ref.PersoLetter)] = d
if self.outlineModel: if self.outlineModel:
d = [] d = []
def addChildren(item): def addChildren(item):
for c in item.children(): for c in item.children():
d.append((c.title(), c.ID(), c.path())) d.append((c.title(), c.ID(), c.path()))
addChildren(c) addChildren(c)
r = self.outlineModel.rootItem r = self.outlineModel.rootItem
addChildren(r) addChildren(r)
self.data[(self.tr("Texts"), Ref.TextLetter)] = d self.data[(self.tr("Texts"), Ref.TextLetter)] = d
if self.plotModel: if self.plotModel:
d = [] d = []
for r in range(self.plotModel.rowCount()): for r in range(self.plotModel.rowCount()):
name = self.plotModel.item(r, Plot.name.value).text() name = self.plotModel.item(r, Plot.name.value).text()
ID = self.plotModel.item(r, Plot.ID.value).text() ID = self.plotModel.item(r, Plot.ID.value).text()
imp = self.plotModel.item(r, Plot.importance.value).text() imp = self.plotModel.item(r, Plot.importance.value).text()
imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)] imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)]
d.append((name, ID, imp)) d.append((name, ID, imp))
self.data[(self.tr("Plots"), Ref.PlotLetter)] = d self.data[(self.tr("Plots"), Ref.PlotLetter)] = d
if self.worldModel: if self.worldModel:
d = self.worldModel.listAll() d = self.worldModel.listAll()
self.data[(self.tr("World"), Ref.WorldLetter)] = d self.data[(self.tr("World"), Ref.WorldLetter)] = d
self.updateListFromData() self.updateListFromData()
def addCategory(self, title): def addCategory(self, title):
item = QListWidgetItem(title) item = QListWidgetItem(title)
item.setBackground(QBrush(lightBlue())) item.setBackground(QBrush(lightBlue()))
@ -109,7 +112,7 @@ class cheatSheet(QWidget, Ui_cheatSheet):
f.setBold(True) f.setBold(True)
item.setFont(f) item.setFont(f)
self.list.addItem(item) self.list.addItem(item)
def updateListFromData(self): def updateListFromData(self):
self.list.clear() self.list.clear()
for cat in self.data: for cat in self.data:
@ -119,48 +122,48 @@ class cheatSheet(QWidget, Ui_cheatSheet):
for item in filtered: for item in filtered:
i = QListWidgetItem(item[0]) i = QListWidgetItem(item[0])
i.setData(Qt.UserRole, Ref.EmptyRef.format(cat[1], item[1], item[0])) i.setData(Qt.UserRole, Ref.EmptyRef.format(cat[1], item[1], item[0]))
i.setData(Qt.UserRole+1, item[2]) i.setData(Qt.UserRole + 1, item[2])
self.list.addItem(i) self.list.addItem(i)
self.list.setCurrentRow(1) self.list.setCurrentRow(1)
def showInfos(self): def showInfos(self):
i = self.list.currentItem() i = self.list.currentItem()
ref = i.data(Qt.UserRole) ref = i.data(Qt.UserRole)
if ref: if ref:
self.view.setText(Ref.infos(ref)) self.view.setText(Ref.infos(ref))
def openLink(self, link): def openLink(self, link):
Ref.open(link) Ref.open(link)
def linkHovered(self, link): def linkHovered(self, link):
if link: if link:
QToolTip.showText(QCursor.pos(), Ref.tooltip(link)) QToolTip.showText(QCursor.pos(), Ref.tooltip(link))
def keyPressEvent(self, event): def keyPressEvent(self, event):
if event.key() in [Qt.Key_Up, Qt.Key_Down]: if event.key() in [Qt.Key_Up, Qt.Key_Down]:
self.list.keyPressEvent(event) self.list.keyPressEvent(event)
else: else:
QWidget.keyPressEvent(self, event) QWidget.keyPressEvent(self, event)
class listCompleterDelegate(QStyledItemDelegate): class listCompleterDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index): def paint(self, painter, option, index):
extra = index.data(Qt.UserRole+1) extra = index.data(Qt.UserRole + 1)
if not extra: if not extra:
return QStyledItemDelegate.paint(self, painter, option, index) return QStyledItemDelegate.paint(self, painter, option, index)
else: else:
if option.state & QStyle.State_Selected: if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight))
title = index.data() title = index.data()
extra = " - {}".format(extra) extra = " - {}".format(extra)
painter.drawText(option.rect, Qt.AlignLeft, title) painter.drawText(option.rect, Qt.AlignLeft, title)
fm = QFontMetrics(option.font) fm = QFontMetrics(option.font)
w = fm.width(title) w = fm.width(title)
r = QRect(option.rect) r = QRect(option.rect)
@ -168,4 +171,4 @@ class listCompleterDelegate(QStyledItemDelegate):
painter.save() painter.save()
painter.setPen(Qt.gray) painter.setPen(Qt.gray)
painter.drawText(r, Qt.AlignLeft, extra) painter.drawText(r, Qt.AlignLeft, extra)
painter.restore() painter.restore()

View file

@ -6,7 +6,7 @@
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtWidgets
class Ui_cheatSheet(object): class Ui_cheatSheet(object):
def setupUi(self, cheatSheet): def setupUi(self, cheatSheet):

View file

@ -1,7 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from qt import * from PyQt5.QtWidgets import QToolBar, QDockWidget, QAction, QToolButton, QSizePolicy, QStylePainter, \
QStyleOptionButton, QStyle
class collapsibleDockWidgets(QToolBar): class collapsibleDockWidgets(QToolBar):
@ -14,7 +15,7 @@ class collapsibleDockWidgets(QToolBar):
Qt.RightDockWidgetArea: Qt.RightToolBarArea, Qt.RightDockWidgetArea: Qt.RightToolBarArea,
Qt.TopDockWidgetArea: Qt.TopToolBarArea, Qt.TopDockWidgetArea: Qt.TopToolBarArea,
Qt.BottomDockWidgetArea: Qt.BottomToolBarArea, Qt.BottomDockWidgetArea: Qt.BottomToolBarArea,
} }
def __init__(self, area, parent, name=""): def __init__(self, area, parent, name=""):
QToolBar.__init__(self, parent) QToolBar.__init__(self, parent)
@ -26,18 +27,18 @@ class collapsibleDockWidgets(QToolBar):
self.setFloatable(False) self.setFloatable(False)
self.setMovable(False) self.setMovable(False)
#self.setAllowedAreas(self.TRANSPOSED_AREA[self._area]) # self.setAllowedAreas(self.TRANSPOSED_AREA[self._area])
self.parent().addToolBar(self.TRANSPOSED_AREA[self._area], self) self.parent().addToolBar(self.TRANSPOSED_AREA[self._area], self)
# Dock widgets # Dock widgets
for d in self._dockWidgets(): for d in self._dockWidgets():
b = verticalButton(self) b = verticalButton(self)
b.setDefaultAction(d.toggleViewAction()) b.setDefaultAction(d.toggleViewAction())
self.addWidget(b) self.addWidget(b)
self.addSeparator() self.addSeparator()
# Other widgets # Other widgets
self.otherWidgets = [] self.otherWidgets = []
self.currentGroup = None self.currentGroup = None
@ -47,41 +48,41 @@ class collapsibleDockWidgets(QToolBar):
for w in mw.findChildren(QDockWidget, None): for w in mw.findChildren(QDockWidget, None):
yield w yield w
def addCustomWidget(self, text, widget, group=None): def addCustomWidget(self, text, widget, group=None):
a = QAction(text, self) a = QAction(text, self)
a.setCheckable(True) a.setCheckable(True)
a.setChecked(widget.isVisible()) a.setChecked(widget.isVisible())
a.toggled.connect(widget.setVisible) a.toggled.connect(widget.setVisible)
#widget.installEventFilter(self) # widget.installEventFilter(self)
b = verticalButton(self) b = verticalButton(self)
b.setDefaultAction(a) b.setDefaultAction(a)
a2 = self.addWidget(b) a2 = self.addWidget(b)
self.otherWidgets.append((b, a2, widget, group)) self.otherWidgets.append((b, a2, widget, group))
#def eventFilter(self, widget, event): # def eventFilter(self, widget, event):
#if event.type() in [QEvent.Show, QEvent.Hide]: # if event.type() in [QEvent.Show, QEvent.Hide]:
#for btn, action, w, grp in self.otherWidgets: # for btn, action, w, grp in self.otherWidgets:
#if w == widget: # if w == widget:
#btn.defaultAction().setChecked(event.type() == QEvent.Show) # btn.defaultAction().setChecked(event.type() == QEvent.Show)
#return False # return False
def setCurrentGroup(self, group): def setCurrentGroup(self, group):
self.currentGroup = group self.currentGroup = group
for btn, action, widget, grp in self.otherWidgets: for btn, action, widget, grp in self.otherWidgets:
if not grp == group or grp == None: if not grp == group or grp is None:
action.setVisible(False) action.setVisible(False)
else: else:
action.setVisible(True) action.setVisible(True)
class verticalButton(QToolButton): class verticalButton(QToolButton):
def __init__(self, parent): def __init__(self, parent):
QToolButton.__init__(self, parent) QToolButton.__init__(self, parent)
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
def sizeHint(self): def sizeHint(self):
return QToolButton.sizeHint(self).transposed() return QToolButton.sizeHint(self).transposed()
def paintEvent(self, event): def paintEvent(self, event):
p = QStylePainter(self) p = QStylePainter(self)
p.rotate(90) p.rotate(90)
@ -93,4 +94,4 @@ class verticalButton(QToolButton):
opt.state |= QStyle.State_On opt.state |= QStyle.State_On
s = opt.rect.size().transposed() s = opt.rect.size().transposed()
opt.rect.setSize(s) opt.rect.setSize(s)
p.drawControl(QStyle.CE_PushButton, opt) p.drawControl(QStyle.CE_PushButton, opt)

View file

@ -1,31 +1,30 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QRect, QRectF
from PyQt5.QtGui import QColor, QBrush, QRegion, QTextOption, QFont
from PyQt5.QtWidgets import QSizePolicy, QGroupBox, QWidget, QStylePainter, QStyleOptionGroupBox, qApp, QVBoxLayout, \
QStyle, QStyleOptionFrame, QStyleOptionFocusRect
from qt import *
class collapsibleGroupBox(QGroupBox): class collapsibleGroupBox(QGroupBox):
def __init__(self, parent=None): def __init__(self, parent=None):
QGroupBox.__init__(self) QGroupBox.__init__(self)
self.toggled.connect(self.setExpanded) self.toggled.connect(self.setExpanded)
self.tempWidget = QWidget() self.tempWidget = QWidget()
self.customStyle = False self.customStyle = False
def setExpanded(self, val): def setExpanded(self, val):
self.setCollapsed(not val) self.setCollapsed(not val)
def setCollapsed(self, val): def setCollapsed(self, val):
if val: if val:
# Save layout # Save layout
self.tempWidget.setLayout(self.layout()) self.tempWidget.setLayout(self.layout())
# Set empty layout # Set empty layout
l = QVBoxLayout() l = QVBoxLayout()
#print(l.contentsMargins().left(), l.contentsMargins().bottom(), l.contentsMargins().top(), ) # print(l.contentsMargins().left(), l.contentsMargins().bottom(), l.contentsMargins().top(), )
l.setContentsMargins(0, 0, 0, 0) l.setContentsMargins(0, 0, 0, 0)
self.setLayout(l) self.setLayout(l)
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
@ -35,37 +34,37 @@ class collapsibleGroupBox(QGroupBox):
# Set saved layout # Set saved layout
self.setLayout(self.tempWidget.layout()) self.setLayout(self.tempWidget.layout())
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
def paintEvent(self, event): def paintEvent(self, event):
if not self.customStyle: if not self.customStyle:
return QGroupBox.paintEvent(self, event) return QGroupBox.paintEvent(self, event)
p = QStylePainter(self) p = QStylePainter(self)
opt = QStyleOptionGroupBox() opt = QStyleOptionGroupBox()
self.initStyleOption(opt) self.initStyleOption(opt)
style = qApp.style() style = qApp.style()
groupBox = opt groupBox = opt
#// Draw frame # // Draw frame
textRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxLabel) textRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxLabel)
checkBoxRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxCheckBox) checkBoxRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxCheckBox)
p.save() p.save()
titleRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxFrame) titleRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxFrame)
#r.setBottom(style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxContents).top()) # r.setBottom(style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxContents).top())
titleRect.setHeight(textRect.height()) titleRect.setHeight(textRect.height())
titleRect.moveTop(textRect.top()) titleRect.moveTop(textRect.top())
p.setBrush(QBrush(QColor(Qt.blue).lighter(190))) p.setBrush(QBrush(QColor(Qt.blue).lighter(190)))
p.setPen(Qt.NoPen) p.setPen(Qt.NoPen)
p.drawRoundedRect(titleRect, 10, 10) p.drawRoundedRect(titleRect, 10, 10)
p.restore() p.restore()
if groupBox.subControls & QStyle.SC_GroupBoxFrame: if groupBox.subControls & QStyle.SC_GroupBoxFrame:
frame = QStyleOptionFrame() frame = QStyleOptionFrame()
#frame.operator=(groupBox) # frame.operator=(groupBox)
frame.state = groupBox.state frame.state = groupBox.state
frame.features = groupBox.features frame.features = groupBox.features
frame.lineWidth = groupBox.lineWidth frame.lineWidth = groupBox.lineWidth
@ -81,26 +80,26 @@ class collapsibleGroupBox(QGroupBox):
finalRect.adjust(-4 if ltr else 0, 0, 0 if ltr else 4, 0) finalRect.adjust(-4 if ltr else 0, 0, 0 if ltr else 4, 0)
else: else:
finalRect = textRect finalRect = textRect
region -= QRegion(finalRect) region -= QRegion(finalRect)
p.setClipRegion(region) p.setClipRegion(region)
style.drawPrimitive(style.PE_FrameGroupBox, frame, p) style.drawPrimitive(style.PE_FrameGroupBox, frame, p)
p.restore() p.restore()
##// Draw title # // Draw title
if groupBox.subControls & QStyle.SC_GroupBoxLabel and groupBox.text: if groupBox.subControls & QStyle.SC_GroupBoxLabel and groupBox.text:
#textColor = QColor(groupBox.textColor) # textColor = QColor(groupBox.textColor)
#if textColor.isValid(): # if textColor.isValid():
#p.setPen(textColor) # p.setPen(textColor)
#alignment = int(groupBox.textAlignment) # alignment = int(groupBox.textAlignment)
#if not style.styleHint(QStyle.SH_UnderlineShortcut, opt): # if not style.styleHint(QStyle.SH_UnderlineShortcut, opt):
#alignment |= Qt.TextHideMnemonic # alignment |= Qt.TextHideMnemonic
# style.drawItemText(p, textRect, Qt.TextShowMnemonic | Qt.AlignHCenter | alignment,
# groupBox.palette, groupBox.state & style.State_Enabled, groupBox.text,
# QPalette.NoRole if textColor.isValid() else QPalette.WindowText)
#style.drawItemText(p, textRect, Qt.TextShowMnemonic | Qt.AlignHCenter | alignment,
#groupBox.palette, groupBox.state & style.State_Enabled, groupBox.text,
#QPalette.NoRole if textColor.isValid() else QPalette.WindowText)
p.save() p.save()
topt = QTextOption(Qt.AlignHCenter | Qt.AlignVCenter) topt = QTextOption(Qt.AlignHCenter | Qt.AlignVCenter)
f = QFont() f = QFont()
@ -112,15 +111,15 @@ class collapsibleGroupBox(QGroupBox):
if groupBox.state & style.State_HasFocus: if groupBox.state & style.State_HasFocus:
fropt = QStyleOptionFocusRect() fropt = QStyleOptionFocusRect()
#fropt.operator=(groupBox) # fropt.operator=(groupBox)
fropt.state = groupBox.state fropt.state = groupBox.state
fropt.rect = textRect fropt.rect = textRect
style.drawPrimitive(style.PE_FrameFocusRect, fropt, p) style.drawPrimitive(style.PE_FrameFocusRect, fropt, p)
#// Draw checkbox # // Draw checkbox
#if groupBox.subControls & style.SC_GroupBoxCheckBox: # if groupBox.subControls & style.SC_GroupBoxCheckBox:
#box = QStyleOptionButton() # box = QStyleOptionButton()
##box.operator=(groupBox) # box.operator=(groupBox)
#box.state = groupBox.state # box.state = groupBox.state
#box.rect = checkBoxRect # box.rect = checkBoxRect
#style.drawPrimitive(style.PE_IndicatorCheckBox, box, p) # style.drawPrimitive(style.PE_IndicatorCheckBox, box, p)

View file

@ -1,10 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QFrame, QPushButton, QVBoxLayout, QSizePolicy
from qt import *
class collapsibleGroupBox2(QWidget): class collapsibleGroupBox2(QWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.frame = QFrame(self) self.frame = QFrame(self)
@ -14,12 +14,12 @@ class collapsibleGroupBox2(QWidget):
self.switched = False self.switched = False
self.vPolicy = None self.vPolicy = None
self.button.setStyleSheet("background: lightBlue;") self.button.setStyleSheet("background: lightBlue;")
def resizeEvent(self, event): def resizeEvent(self, event):
if not self.switched: if not self.switched:
self.switchLayout() self.switchLayout()
return QWidget.resizeEvent(self, event) return QWidget.resizeEvent(self, event)
def switchLayout(self): def switchLayout(self):
self.frame.setLayout(self.layout()) self.frame.setLayout(self.layout())
self.wLayout = QVBoxLayout(self) self.wLayout = QVBoxLayout(self)
@ -29,31 +29,31 @@ class collapsibleGroupBox2(QWidget):
self.button.toggled.connect(self.setExpanded) self.button.toggled.connect(self.setExpanded)
self.frame.layout().setContentsMargins(5, 0, 5, 0) self.frame.layout().setContentsMargins(5, 0, 5, 0)
self.switched = True self.switched = True
self.vPolicy = self.sizePolicy().verticalPolicy() self.vPolicy = self.sizePolicy().verticalPolicy()
self.parent().layout().setAlignment(Qt.AlignTop) self.parent().layout().setAlignment(Qt.AlignTop)
self.setExpanded(self.button.isChecked()) self.setExpanded(self.button.isChecked())
def setFlat(self, val): def setFlat(self, val):
if val: if val:
self.frame.setFrameShape(QFrame.NoFrame) self.frame.setFrameShape(QFrame.NoFrame)
def setCheckable(self, val): def setCheckable(self, val):
pass pass
def setTitle(self, title): def setTitle(self, title):
self.button.setText(title) self.button.setText(title)
def setExpanded(self, val): def setExpanded(self, val):
self.frame.setVisible(val) self.frame.setVisible(val)
if val: if val:
self.setSizePolicy(QSizePolicy.Preferred, self.vPolicy) self.setSizePolicy(QSizePolicy.Preferred, self.vPolicy)
else: else:
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
def saveState(self): def saveState(self):
return self.button.isChecked() return self.button.isChecked()
def restoreState(self, val): def restoreState(self, val):
self.button.setChecked(val) self.button.setChecked(val)

View file

@ -1,107 +1,102 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from qt import * from PyQt5.QtWidgets import QDialog, qApp, QFileDialog
from enums import *
from models.outlineModel import * from manuskript import exporter
from ui.compileDialog_ui import * from manuskript.ui.compileDialog_ui import Ui_compileDialog
from functions import *
import os
import exporter
class compileDialog(QDialog, Ui_compileDialog): class compileDialog(QDialog, Ui_compileDialog):
def __init__(self, parent=None): def __init__(self, parent=None):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.btnPath.clicked.connect(self.getPath) self.btnPath.clicked.connect(self.getPath)
self.btnFilename.clicked.connect(self.getFilename) self.btnFilename.clicked.connect(self.getFilename)
self.btnCompile.clicked.connect(self.doCompile) self.btnCompile.clicked.connect(self.doCompile)
self.cmbTargets.activated.connect(self.updateUI) self.cmbTargets.activated.connect(self.updateUI)
self.txtPath.setText("/home/olivier/Documents/Travail/Geekeries/Python/manuskript/ExportTest") self.txtPath.setText("/home/olivier/Documents/Travail/Geekeries/Python/manuskript/ExportTest")
self.txtFilename.setText("/home/olivier/Documents/Travail/Geekeries/Python/manuskript/ExportTest/test.html") self.txtFilename.setText("/home/olivier/Documents/Travail/Geekeries/Python/manuskript/ExportTest/test.html")
self.populatesTarget() self.populatesTarget()
self.updateUI() self.updateUI()
############################################################################### ###############################################################################
# UI # UI
############################################################################### ###############################################################################
def populatesTarget(self): def populatesTarget(self):
for code in exporter.formats: for code in exporter.formats:
self.cmbTargets.addItem(exporter.formats[code][0], code) self.cmbTargets.addItem(exporter.formats[code][0], code)
def updateUI(self): def updateUI(self):
target = self.cmbTargets.currentData() target = self.cmbTargets.currentData()
if not exporter.formats[target][1]: if not exporter.formats[target][1]:
self.btnCompile.setEnabled(False) self.btnCompile.setEnabled(False)
requires = [] requires = []
else: else:
self.btnCompile.setEnabled(True) self.btnCompile.setEnabled(True)
requires = exporter.formats[target][1].requires requires = exporter.formats[target][1].requires
self.wPath.setVisible("path" in requires) self.wPath.setVisible("path" in requires)
self.wFilename.setVisible("filename" in requires) self.wFilename.setVisible("filename" in requires)
def startWorking(self): def startWorking(self):
# Setting override cursor # Setting override cursor
qApp.setOverrideCursor(Qt.WaitCursor) qApp.setOverrideCursor(Qt.WaitCursor)
# Button # Button
self.btnCompile.setEnabled(False) self.btnCompile.setEnabled(False)
self.txtBtn = self.btnCompile.text() self.txtBtn = self.btnCompile.text()
self.btnCompile.setText(self.tr("Working...")) self.btnCompile.setText(self.tr("Working..."))
def stopWorking(self): def stopWorking(self):
# Removing override cursor # Removing override cursor
qApp.restoreOverrideCursor() qApp.restoreOverrideCursor()
# Button # Button
self.btnCompile.setEnabled(True) self.btnCompile.setEnabled(True)
self.btnCompile.setText(self.txtBtn) self.btnCompile.setText(self.txtBtn)
############################################################################### ###############################################################################
# USER INPUTS # USER INPUTS
############################################################################### ###############################################################################
def getPath(self): def getPath(self):
path = self.txtPath.text() path = self.txtPath.text()
path = QFileDialog.getExistingDirectory(self, self.tr("Chose export folder"), path) path = QFileDialog.getExistingDirectory(self, self.tr("Chose export folder"), path)
if path: if path:
self.txtPath.setText(path) self.txtPath.setText(path)
def getFilename(self): def getFilename(self):
fn = self.txtFilename.text() fn = self.txtFilename.text()
target = self.cmbTargets.currentData() target = self.cmbTargets.currentData()
fltr = exporter.formats[target][2] fltr = exporter.formats[target][2]
fn = QFileDialog.getSaveFileName(self, self.tr("Chose export target"), fn, fltr) fn = QFileDialog.getSaveFileName(self, self.tr("Chose export target"), fn, fltr)
if fn[0]: if fn[0]:
self.txtFilename.setText(fn[0]) self.txtFilename.setText(fn[0])
###############################################################################
# COMPILE ###############################################################################
############################################################################### # COMPILE
###############################################################################
def doCompile(self): def doCompile(self):
target = self.cmbTargets.currentData() target = self.cmbTargets.currentData()
self.startWorking() self.startWorking()
if target == "arbo": if target == "arbo":
compiler = exporter.formats[target][1]() compiler = exporter.formats[target][1]()
compiler.doCompile(self.txtPath.text()) compiler.doCompile(self.txtPath.text())
elif target in ["html", "odt"]: elif target in ["html", "odt"]:
compiler = exporter.formats[target][1]() compiler = exporter.formats[target][1]()
compiler.doCompile(self.txtFilename.text()) compiler.doCompile(self.txtFilename.text())
self.stopWorking() self.stopWorking()

View file

@ -6,7 +6,7 @@
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtWidgets
class Ui_compileDialog(object): class Ui_compileDialog(object):
def setupUi(self, compileDialog): def setupUi(self, compileDialog):

View file

@ -1,13 +1,15 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
from qt import *
import re import re
from functions import *
import models.references as Ref from PyQt5.QtCore import Qt
from PyQt5.QtGui import QBrush, QTextCursor, QColor, QFont, QSyntaxHighlighter, QTextBlockFormat, QTextCharFormat
import manuskript.models.references as Ref
class basicHighlighter(QSyntaxHighlighter): class basicHighlighter(QSyntaxHighlighter):
def __init__(self, editor): def __init__(self, editor):
QSyntaxHighlighter.__init__(self, editor.document()) QSyntaxHighlighter.__init__(self, editor.document())
@ -19,21 +21,20 @@ class basicHighlighter(QSyntaxHighlighter):
def setDefaultBlockFormat(self, bf): def setDefaultBlockFormat(self, bf):
self._defaultBlockFormat = bf self._defaultBlockFormat = bf
self.rehighlight() self.rehighlight()
def setDefaultCharFormat(self, cf): def setDefaultCharFormat(self, cf):
self._defaultCharFormat = cf self._defaultCharFormat = cf
self.rehighlight() self.rehighlight()
def setMisspelledColor(self, color): def setMisspelledColor(self, color):
self._misspelledColor = color self._misspelledColor = color
def highlightBlock(self, text): def highlightBlock(self, text):
"""Apply syntax highlighting to the given block of text. """Apply syntax highlighting to the given block of text.
""" """
self.highlightBlockBefore(text) self.highlightBlockBefore(text)
self.highlightBlockAfter(text) self.highlightBlockAfter(text)
def highlightBlockBefore(self, text): def highlightBlockBefore(self, text):
"""Highlighting to do before anything else. """Highlighting to do before anything else.
@ -43,16 +44,16 @@ class basicHighlighter(QSyntaxHighlighter):
bf = QTextBlockFormat(self._defaultBlockFormat) bf = QTextBlockFormat(self._defaultBlockFormat)
bf.setAlignment(QTextCursor(self.currentBlock()).blockFormat().alignment()) bf.setAlignment(QTextCursor(self.currentBlock()).blockFormat().alignment())
QTextCursor(self.currentBlock()).setBlockFormat(bf) QTextCursor(self.currentBlock()).setBlockFormat(bf)
#self.setFormat(0, len(text), self._defaultCharFormat) # self.setFormat(0, len(text), self._defaultCharFormat)
def highlightBlockAfter(self, text): def highlightBlockAfter(self, text):
"""Highlighting to do after everything else. """Highlighting to do after everything else.
When subclassing basicHighlighter, you must call highlightBlockAfter When subclassing basicHighlighter, you must call highlightBlockAfter
after your custom highlighting. after your custom highlighting.
""" """
# References # References
for txt in re.finditer(Ref.RegEx, text): for txt in re.finditer(Ref.RegEx, text):
fmt = self.format(txt.start()) fmt = self.format(txt.start())
@ -66,11 +67,11 @@ class basicHighlighter(QSyntaxHighlighter):
fmt.setBackground(QBrush(QColor(Qt.red).lighter(170))) fmt.setBackground(QBrush(QColor(Qt.red).lighter(170)))
elif txt.group(1) == Ref.WorldLetter: elif txt.group(1) == Ref.WorldLetter:
fmt.setBackground(QBrush(QColor(Qt.green).lighter(170))) fmt.setBackground(QBrush(QColor(Qt.green).lighter(170)))
self.setFormat(txt.start(), self.setFormat(txt.start(),
txt.end() - txt.start(), txt.end() - txt.start(),
fmt) fmt)
# Spell checking # Spell checking
# Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ # Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/
WORDS = '(?iu)[\w\']+' WORDS = '(?iu)[\w\']+'
@ -81,7 +82,4 @@ class basicHighlighter(QSyntaxHighlighter):
format.setUnderlineColor(self._misspelledColor) format.setUnderlineColor(self._misspelledColor)
format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline) format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
self.setFormat(word_object.start(), self.setFormat(word_object.start(),
word_object.end() - word_object.start(), format) word_object.end() - word_object.start(), format)

View file

@ -1,14 +1,12 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
from PyQt5.QtGui import QTextBlockUserData
from qt import *
class blockUserData (QTextBlockUserData): class blockUserData(QTextBlockUserData):
@staticmethod @staticmethod
def getUserData(block): def getUserData(block):
"Returns userData if it exists, or a blank one." """Returns userData if it exists, or a blank one."""
data = block.userData() data = block.userData()
if data is None: if data is None:
data = blockUserData() data = blockUserData()
@ -16,7 +14,7 @@ class blockUserData (QTextBlockUserData):
@staticmethod @staticmethod
def getUserState(block): def getUserState(block):
"Returns the block state." """Returns the block state."""
state = block.userState() state = block.userState()
while state >= 100: while state >= 100:
state -= 100 # +100 means in a list state -= 100 # +100 means in a list

View file

@ -1,17 +1,18 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import pyqtSignal, Qt, QRect
from qt import * from PyQt5.QtGui import QBrush, QFontMetrics, QPalette
from enums import * from PyQt5.QtWidgets import QWidget, QListWidgetItem, QStyledItemDelegate, QStyle
from models.outlineModel import *
from ui.editors.completer_ui import * from manuskript.functions import lightBlue
from functions import * from manuskript.functions import mainWindow
import models.references as Ref from manuskript.ui.editors.completer_ui import Ui_completer
from manuskript.models import references as Ref
class completer(QWidget, Ui_completer): class completer(QWidget, Ui_completer):
activated = pyqtSignal(str) activated = pyqtSignal(str)
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
@ -23,20 +24,20 @@ class completer(QWidget, Ui_completer):
self.list.itemActivated.connect(self.submit) self.list.itemActivated.connect(self.submit)
self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.hide() self.hide()
def popup(self, completion=""): def popup(self, completion=""):
self.updateListFromData() self.updateListFromData()
self.text.setText(completion) self.text.setText(completion)
self.text.setFocus(Qt.PopupFocusReason) self.text.setFocus(Qt.PopupFocusReason)
self.show() self.show()
def addCategory(self, title): def addCategory(self, title):
item = QListWidgetItem(title) item = QListWidgetItem(title)
item.setBackground(QBrush(lightBlue())) item.setBackground(QBrush(lightBlue()))
item.setForeground(QBrush(Qt.darkBlue)) item.setForeground(QBrush(Qt.darkBlue))
item.setFlags(Qt.ItemIsEnabled) item.setFlags(Qt.ItemIsEnabled)
self.list.addItem(item) self.list.addItem(item)
def updateListFromData(self): def updateListFromData(self):
data = mainWindow().cheatSheet.data data = mainWindow().cheatSheet.data
self.list.clear() self.list.clear()
@ -47,41 +48,41 @@ class completer(QWidget, Ui_completer):
for item in filtered: for item in filtered:
i = QListWidgetItem(item[0]) i = QListWidgetItem(item[0])
i.setData(Qt.UserRole, Ref.EmptyRef.format(cat[1], item[1], item[0])) i.setData(Qt.UserRole, Ref.EmptyRef.format(cat[1], item[1], item[0]))
i.setData(Qt.UserRole+1, item[2]) i.setData(Qt.UserRole + 1, item[2])
self.list.addItem(i) self.list.addItem(i)
self.list.setCurrentRow(1) self.list.setCurrentRow(1)
self.text.setFocus(Qt.PopupFocusReason) self.text.setFocus(Qt.PopupFocusReason)
def submit(self): def submit(self):
i = self.list.currentItem() i = self.list.currentItem()
self.activated.emit(i.data(Qt.UserRole)) self.activated.emit(i.data(Qt.UserRole))
self.hide() self.hide()
def keyPressEvent(self, event): def keyPressEvent(self, event):
if event.key() in [Qt.Key_Up, Qt.Key_Down]: if event.key() in [Qt.Key_Up, Qt.Key_Down]:
self.list.keyPressEvent(event) self.list.keyPressEvent(event)
else: else:
QWidget.keyPressEvent(self, event) QWidget.keyPressEvent(self, event)
class listCompleterDelegate(QStyledItemDelegate): class listCompleterDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index): def paint(self, painter, option, index):
extra = index.data(Qt.UserRole+1) extra = index.data(Qt.UserRole + 1)
if not extra: if not extra:
return QStyledItemDelegate.paint(self, painter, option, index) return QStyledItemDelegate.paint(self, painter, option, index)
else: else:
if option.state & QStyle.State_Selected: if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight))
title = index.data() title = index.data()
extra = " - {}".format(extra) extra = " - {}".format(extra)
painter.drawText(option.rect, Qt.AlignLeft, title) painter.drawText(option.rect, Qt.AlignLeft, title)
fm = QFontMetrics(option.font) fm = QFontMetrics(option.font)
w = fm.width(title) w = fm.width(title)
r = QRect(option.rect) r = QRect(option.rect)
@ -89,4 +90,4 @@ class listCompleterDelegate(QStyledItemDelegate):
painter.save() painter.save()
painter.setPen(Qt.gray) painter.setPen(Qt.gray)
painter.drawText(r, Qt.AlignLeft, extra) painter.drawText(r, Qt.AlignLeft, extra)
painter.restore() painter.restore()

View file

@ -6,7 +6,7 @@
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtWidgets
class Ui_completer(object): class Ui_completer(object):
def setupUi(self, completer): def setupUi(self, completer):

View file

@ -1,20 +1,19 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import pyqtSignal, QModelIndex
from qt import * from PyQt5.QtGui import QPalette
from enums import * from PyQt5.QtWidgets import QWidget, QFrame, QSpacerItem, QSizePolicy, QVBoxLayout
from ui.editors.editorWidget_ui import *
from ui.editors.fullScreenEditor import * from manuskript import settings
from ui.editors.textFormat import * from manuskript.functions import AUC, mainWindow
from ui.views.textEditView import * from manuskript.ui.editors.editorWidget_ui import Ui_editorWidget_ui
from functions import * from manuskript.ui.views.textEditView import textEditView
import settings
class editorWidget(QWidget, Ui_editorWidget_ui): class editorWidget(QWidget, Ui_editorWidget_ui):
toggledSpellcheck = pyqtSignal(bool) toggledSpellcheck = pyqtSignal(bool)
dictChanged = pyqtSignal(str) dictChanged = pyqtSignal(str)
def __init__(self, parent): def __init__(self, parent):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
@ -29,11 +28,11 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
self.spellcheck = True self.spellcheck = True
self.folderView = "cork" self.folderView = "cork"
self.mw = mainWindow() self.mw = mainWindow()
#def setModel(self, model): # def setModel(self, model):
#self._model = model # self._model = model
#self.setView() # self.setView()
def setFolderView(self, v): def setFolderView(self, v):
oldV = self.folderView oldV = self.folderView
if v == "cork": if v == "cork":
@ -42,66 +41,67 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
self.folderView = "outline" self.folderView = "outline"
else: else:
self.folderView = "text" self.folderView = "text"
# Saving value # Saving value
settings.folderView = self.folderView settings.folderView = self.folderView
if oldV != self.folderView and self.currentIndex: if oldV != self.folderView and self.currentIndex:
self.setCurrentModelIndex(self.currentIndex) self.setCurrentModelIndex(self.currentIndex)
def setCorkSizeFactor(self, v): def setCorkSizeFactor(self, v):
self.corkView.itemDelegate().setCorkSizeFactor(v) self.corkView.itemDelegate().setCorkSizeFactor(v)
self.redrawCorkItems() self.redrawCorkItems()
def redrawCorkItems(self): def redrawCorkItems(self):
r = self.corkView.rootIndex() r = self.corkView.rootIndex()
if r.isValid(): if r.isValid():
count = r.internalPointer().childCount() count = r.internalPointer().childCount()
else: else:
count = self.mw.mdlOutline.rootItem.childCount() count = self.mw.mdlOutline.rootItem.childCount()
for c in range(count): for c in range(count):
self.corkView.itemDelegate().sizeHintChanged.emit(r.child(c, 0)) self.corkView.itemDelegate().sizeHintChanged.emit(r.child(c, 0))
def setView(self): def setView(self):
#index = mainWindow().treeRedacOutline.currentIndex() # index = mainWindow().treeRedacOutline.currentIndex()
## Couting the number of other selected items # Couting the number of other selected items
#sel = [] # sel = []
#for i in mainWindow().treeRedacOutline.selectionModel().selection().indexes(): # for i in mainWindow().treeRedacOutline.selectionModel().selection().indexes():
#if i.column() != 0: continue # if i.column() != 0: continue
#if i not in sel: sel.append(i) # if i not in sel: sel.append(i)
#if len(sel) != 0: # if len(sel) != 0:
#item = index.internalPointer() # item = index.internalPointer()
#else: # else:
#index = QModelIndex() # index = QModelIndex()
#item = self.mw.mdlOutline.rootItem # item = self.mw.mdlOutline.rootItem
#self.currentIndex = index # self.currentIndex = index
if self.currentIndex.isValid(): if self.currentIndex.isValid():
item = self.currentIndex.internalPointer() item = self.currentIndex.internalPointer()
else: else:
item = self.mw.mdlOutline.rootItem item = self.mw.mdlOutline.rootItem
def addTitle(itm): def addTitle(itm):
edt = textEditView(self, html="<h{l}>{t}</h{l}>".format(l=min(itm.level()+1, 5), t=itm.title()), autoResize=True) edt = textEditView(self, html="<h{l}>{t}</h{l}>".format(l=min(itm.level() + 1, 5), t=itm.title()),
autoResize=True)
edt.setFrameShape(QFrame.NoFrame) edt.setFrameShape(QFrame.NoFrame)
self.txtEdits.append(edt) self.txtEdits.append(edt)
l.addWidget(edt) l.addWidget(edt)
def addLine(): def addLine():
line = QFrame(self.text) line = QFrame(self.text)
line.setFrameShape(QFrame.HLine) line.setFrameShape(QFrame.HLine)
line.setFrameShadow(QFrame.Sunken) line.setFrameShadow(QFrame.Sunken)
l.addWidget(line) l.addWidget(line)
def addText(itm): def addText(itm):
edt = textEditView(self, edt = textEditView(self,
index=itm.index(), index=itm.index(),
spellcheck=self.spellcheck, spellcheck=self.spellcheck,
dict=settings.dict, dict=settings.dict,
highlighting=True, highlighting=True,
autoResize=True) autoResize=True)
@ -110,67 +110,67 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
edt.setStatusTip("{} ({})".format(itm.path(), itm.type())) edt.setStatusTip("{} ({})".format(itm.path(), itm.type()))
self.toggledSpellcheck.connect(edt.toggleSpellcheck, AUC) self.toggledSpellcheck.connect(edt.toggleSpellcheck, AUC)
self.dictChanged.connect(edt.setDict, AUC) self.dictChanged.connect(edt.setDict, AUC)
#edt.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) # edt.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
self.txtEdits.append(edt) self.txtEdits.append(edt)
l.addWidget(edt) l.addWidget(edt)
def addChildren(itm): def addChildren(itm):
for c in range(itm.childCount()): for c in range(itm.childCount()):
child = itm.child(c) child = itm.child(c)
if child.isFolder(): if child.isFolder():
addTitle(child) addTitle(child)
addChildren(child) addChildren(child)
else: else:
addText(child) addText(child)
addLine() addLine()
def addSpacer(): def addSpacer():
l.addItem(QSpacerItem(10, 1000, QSizePolicy.Minimum, QSizePolicy.Expanding)) l.addItem(QSpacerItem(10, 1000, QSizePolicy.Minimum, QSizePolicy.Expanding))
# Display multiple selected items # Display multiple selected items
#if len(sel) > 1 and False: # Buggy and not very useful, skip # if len(sel) > 1 and False: # Buggy and not very useful, skip
#self.stack.setCurrentIndex(1) # self.stack.setCurrentIndex(1)
#w = QWidget() # w = QWidget()
#l = QVBoxLayout(w) # l = QVBoxLayout(w)
#self.txtEdits = [] # self.txtEdits = []
#for idx in sel: # for idx in sel:
#sItem = idx.internalPointer() # sItem = idx.internalPointer()
#addTitle(sItem) # addTitle(sItem)
#if sItem.isFolder(): # if sItem.isFolder():
#addChildren(sItem) # addChildren(sItem)
#else: # else:
#addText(sItem) # addText(sItem)
#addLine() # addLine()
#addSpacer() # addSpacer()
#self.scroll.setWidget(w) # self.scroll.setWidget(w)
if item and item.isFolder() and self.folderView == "text": if item and item.isFolder() and self.folderView == "text":
self.stack.setCurrentIndex(1) self.stack.setCurrentIndex(1)
w = QWidget() w = QWidget()
l = QVBoxLayout(w) l = QVBoxLayout(w)
w.setStyleSheet("background: {};".format(settings.textEditor["background"])) w.setStyleSheet("background: {};".format(settings.textEditor["background"]))
#self.scroll.setWidgetResizable(False) # self.scroll.setWidgetResizable(False)
self.txtEdits = [] self.txtEdits = []
if item != self.mw.mdlOutline.rootItem: if item != self.mw.mdlOutline.rootItem:
addTitle(item) addTitle(item)
addChildren(item) addChildren(item)
addSpacer() addSpacer()
self.scroll.setWidget(w) self.scroll.setWidget(w)
elif item and item.isFolder() and self.folderView == "cork": elif item and item.isFolder() and self.folderView == "cork":
self.stack.setCurrentIndex(2) self.stack.setCurrentIndex(2)
self.corkView.setModel(self.mw.mdlOutline) self.corkView.setModel(self.mw.mdlOutline)
self.corkView.setRootIndex(self.currentIndex) self.corkView.setRootIndex(self.currentIndex)
self.corkView.selectionModel().selectionChanged.connect( self.corkView.selectionModel().selectionChanged.connect(
lambda: mainWindow().redacMetadata.selectionChanged(self.corkView), AUC) lambda: mainWindow().redacMetadata.selectionChanged(self.corkView), AUC)
self.corkView.clicked.connect( self.corkView.clicked.connect(
lambda: mainWindow().redacMetadata.selectionChanged(self.corkView), AUC) lambda: mainWindow().redacMetadata.selectionChanged(self.corkView), AUC)
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.setModelPersos(mainWindow().mdlPersos)
@ -179,14 +179,14 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
self.outlineView.setModel(self.mw.mdlOutline) self.outlineView.setModel(self.mw.mdlOutline)
self.outlineView.setRootIndex(self.currentIndex) self.outlineView.setRootIndex(self.currentIndex)
self.outlineView.selectionModel().selectionChanged.connect( self.outlineView.selectionModel().selectionChanged.connect(
lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC) lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC)
self.outlineView.clicked.connect( self.outlineView.clicked.connect(
lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC) lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC)
else: else:
self.txtRedacText.setCurrentModelIndex(self.currentIndex) self.txtRedacText.setCurrentModelIndex(self.currentIndex)
self.stack.setCurrentIndex(0) # Single text item self.stack.setCurrentIndex(0) # Single text item
try: try:
self.mw.mdlOutline.dataChanged.connect(self.modelDataChanged, AUC) self.mw.mdlOutline.dataChanged.connect(self.modelDataChanged, AUC)
self.mw.mdlOutline.rowsInserted.connect(self.updateIndexFromID, AUC) self.mw.mdlOutline.rowsInserted.connect(self.updateIndexFromID, AUC)
@ -194,54 +194,54 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
self.mw.mdlOutline.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC) self.mw.mdlOutline.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC)
except TypeError: except TypeError:
pass pass
self.updateStatusBar() self.updateStatusBar()
def setCurrentModelIndex(self, index=None): def setCurrentModelIndex(self, index=None):
if index.isValid(): if index.isValid():
self.currentIndex = index self.currentIndex = index
self.currentID = self.mw.mdlOutline.ID(index) self.currentID = self.mw.mdlOutline.ID(index)
#self._model = index.model() # self._model = index.model()
else: else:
self.currentIndex = QModelIndex() self.currentIndex = QModelIndex()
self.setView() self.setView()
def updateIndexFromID(self): def updateIndexFromID(self):
idx = self.mw.mdlOutline.getIndexByID(self.currentID) idx = self.mw.mdlOutline.getIndexByID(self.currentID)
if idx != self.currentIndex: if idx != self.currentIndex:
self.currentIndex = idx self.currentIndex = idx
self.setView() self.setView()
def modelDataChanged(self, topLeft, bottomRight): def modelDataChanged(self, topLeft, bottomRight):
#if self.currentID: # if self.currentID:
#self.updateIndexFromID() # self.updateIndexFromID()
if not self.currentIndex: if not self.currentIndex:
return return
if topLeft.row() <= self.currentIndex.row() <= bottomRight.row(): if topLeft.row() <= self.currentIndex.row() <= bottomRight.row():
self.updateStatusBar() self.updateStatusBar()
def rowsAboutToBeRemoved(self, parent, first, last): def rowsAboutToBeRemoved(self, parent, first, last):
if self.currentIndex: if self.currentIndex:
if self.currentIndex.parent() == parent and \ if self.currentIndex.parent() == parent and \
first <= self.currentIndex.row() <= last: first <= self.currentIndex.row() <= last:
# Item deleted, close tab # Item deleted, close tab
self.mw.mainEditor.tab.removeTab(self.mw.mainEditor.tab.indexOf(self)) self.mw.mainEditor.tab.removeTab(self.mw.mainEditor.tab.indexOf(self))
def updateStatusBar(self): def updateStatusBar(self):
# Update progress # Update progress
#if self.currentIndex and self.currentIndex.isValid(): # if self.currentIndex and self.currentIndex.isValid():
#if self._model: # if self._model:
mw = mainWindow() mw = mainWindow()
if not mw: return if not mw:
return
mw.mainEditor.updateStats() mw.mainEditor.updateStats()
def toggleSpellcheck(self, v): def toggleSpellcheck(self, v):
self.spellcheck = v self.spellcheck = v
self.toggledSpellcheck.emit(v) self.toggledSpellcheck.emit(v)
def setDict(self, dct): def setDict(self, dct):
self.currentDict = dct self.currentDict = dct
self.dictChanged.emit(dct) self.dictChanged.emit(dct)

View file

@ -37,7 +37,7 @@ class Ui_editorWidget_ui(object):
self.scroll.setWidgetResizable(True) self.scroll.setWidgetResizable(True)
self.scroll.setObjectName("scroll") self.scroll.setObjectName("scroll")
self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 396, 296)) self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 96, 26))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scroll.setWidget(self.scrollAreaWidgetContents) self.scroll.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout.addWidget(self.scroll) self.verticalLayout.addWidget(self.scroll)
@ -70,6 +70,6 @@ class Ui_editorWidget_ui(object):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
editorWidget_ui.setWindowTitle(_translate("editorWidget_ui", "Form")) editorWidget_ui.setWindowTitle(_translate("editorWidget_ui", "Form"))
from ui.views.corkView import corkView from manuskript.ui.views.corkView import corkView
from ui.views.outlineView import outlineView from manuskript.ui.views.outlineView import outlineView
from ui.views.textEditView import textEditView from manuskript.ui.views.textEditView import textEditView

View file

@ -14,7 +14,16 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -24,7 +33,16 @@
</property> </property>
<widget class="QWidget" name="text"> <widget class="QWidget" name="text">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -37,7 +55,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -53,8 +80,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>396</width> <width>96</width>
<height>296</height> <height>26</height>
</rect> </rect>
</property> </property>
</widget> </widget>
@ -64,7 +91,16 @@
</widget> </widget>
<widget class="QWidget" name="cork"> <widget class="QWidget" name="cork">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -74,7 +110,16 @@
</widget> </widget>
<widget class="QWidget" name="outline"> <widget class="QWidget" name="outline">
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -90,17 +135,17 @@
<customwidget> <customwidget>
<class>textEditView</class> <class>textEditView</class>
<extends>QTextEdit</extends> <extends>QTextEdit</extends>
<header>ui.views.textEditView.h</header> <header>manuskript.ui.views.textEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>outlineView</class> <class>outlineView</class>
<extends>QTreeView</extends> <extends>QTreeView</extends>
<header>ui.views.outlineView.h</header> <header>manuskript.ui.views.outlineView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>corkView</class> <class>corkView</class>
<extends>QListView</extends> <extends>QListView</extends>
<header>ui.views.corkView.h</header> <header>manuskript.ui.views.corkView.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -1,24 +1,30 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
import os
from qt import *
from enums import *
from ui.views.textEditView import *
from ui.editors.themes import *
from ui.editors.textFormat import *
from ui.editors.locker import locker
from functions import * from PyQt5.QtCore import Qt, QSize, QPoint, QRect, QEvent, QTimer
import settings from PyQt5.QtGui import QFontMetrics, QColor, QBrush, QPalette, QPainter, QPixmap
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QFrame, QWidget, QPushButton, qApp, QStyle, QComboBox, QLabel, QScrollBar, \
QStyleOptionSlider, QHBoxLayout, QVBoxLayout
# Spell checker support # Spell checker support
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import allPaths, drawProgress
from manuskript.ui.editors.locker import locker
from manuskript.ui.editors.textFormat import textFormat
from manuskript.ui.editors.themes import findThemePath, generateTheme, setThemeEditorDatas
from manuskript.ui.editors.themes import loadThemeDatas
from manuskript.ui.views.textEditView import textEditView
try: try:
import enchant import enchant
except ImportError: except ImportError:
enchant = None enchant = None
class fullScreenEditor(QWidget): class fullScreenEditor(QWidget):
def __init__(self, index, parent=None): def __init__(self, index, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self._background = None self._background = None
@ -27,9 +33,9 @@ class fullScreenEditor(QWidget):
self._themeDatas = loadThemeDatas(self._theme) self._themeDatas = loadThemeDatas(self._theme)
self.setMouseTracking(True) self.setMouseTracking(True)
self._geometries = {} self._geometries = {}
# Text editor # Text editor
self.editor = textEditView(self, self.editor = textEditView(self,
index=index, index=index,
spellcheck=settings.spellcheck, spellcheck=settings.spellcheck,
highlighting=True, highlighting=True,
@ -42,11 +48,11 @@ class fullScreenEditor(QWidget):
self.editor.setVerticalScrollBar(myScrollBar()) self.editor.setVerticalScrollBar(myScrollBar())
self.scrollBar = self.editor.verticalScrollBar() self.scrollBar = self.editor.verticalScrollBar()
self.scrollBar.setParent(self) self.scrollBar.setParent(self)
# Top Panel # Top Panel
self.topPanel = myPanel(parent=self) self.topPanel = myPanel(parent=self)
#self.topPanel.layout().addStretch(1) # self.topPanel.layout().addStretch(1)
# Spell checking # Spell checking
if enchant: if enchant:
self.btnSpellCheck = QPushButton(self) self.btnSpellCheck = QPushButton(self)
@ -56,30 +62,30 @@ class fullScreenEditor(QWidget):
self.btnSpellCheck.setChecked(self.editor.spellcheck) self.btnSpellCheck.setChecked(self.editor.spellcheck)
self.btnSpellCheck.toggled.connect(self.editor.toggleSpellcheck) self.btnSpellCheck.toggled.connect(self.editor.toggleSpellcheck)
self.topPanel.layout().addWidget(self.btnSpellCheck) self.topPanel.layout().addWidget(self.btnSpellCheck)
self.topPanel.layout().addStretch(1) self.topPanel.layout().addStretch(1)
# Formatting # Formatting
self.textFormat = textFormat(self) self.textFormat = textFormat(self)
self.topPanel.layout().addWidget(self.textFormat) self.topPanel.layout().addWidget(self.textFormat)
self.topPanel.layout().addStretch(1) self.topPanel.layout().addStretch(1)
self.btnClose = QPushButton(self) self.btnClose = QPushButton(self)
self.btnClose.setIcon(qApp.style().standardIcon(QStyle.SP_DialogCloseButton)) self.btnClose.setIcon(qApp.style().standardIcon(QStyle.SP_DialogCloseButton))
self.btnClose.clicked.connect(self.close) self.btnClose.clicked.connect(self.close)
self.btnClose.setFlat(True) self.btnClose.setFlat(True)
self.topPanel.layout().addWidget(self.btnClose) self.topPanel.layout().addWidget(self.btnClose)
# Left Panel # Left Panel
self._locked = False self._locked = False
self.leftPanel = myPanel(vertical=True, parent=self) self.leftPanel = myPanel(vertical=True, parent=self)
self.locker = locker(self) self.locker = locker(self)
self.locker.lockChanged.connect(self.setLocked) self.locker.lockChanged.connect(self.setLocked)
self.leftPanel.layout().addWidget(self.locker) self.leftPanel.layout().addWidget(self.locker)
# Bottom Panel # Bottom Panel
self.bottomPanel = myPanel(parent=self) self.bottomPanel = myPanel(parent=self)
self.bottomPanel.layout().addSpacing(24) self.bottomPanel.layout().addSpacing(24)
self.lstThemes = QComboBox(self) self.lstThemes = QComboBox(self)
self.lstThemes.setAttribute(Qt.WA_TranslucentBackground) self.lstThemes.setAttribute(Qt.WA_TranslucentBackground)
@ -95,7 +101,7 @@ class fullScreenEditor(QWidget):
self.bottomPanel.layout().addWidget(QLabel(self.tr("Theme:"), self)) self.bottomPanel.layout().addWidget(QLabel(self.tr("Theme:"), self))
self.bottomPanel.layout().addWidget(self.lstThemes) self.bottomPanel.layout().addWidget(self.lstThemes)
self.bottomPanel.layout().addStretch(1) self.bottomPanel.layout().addStretch(1)
self.lblProgress = QLabel(self) self.lblProgress = QLabel(self)
self.lblProgress.setMaximumSize(QSize(200, 14)) self.lblProgress.setMaximumSize(QSize(200, 14))
self.lblProgress.setMinimumSize(QSize(100, 14)) self.lblProgress.setMinimumSize(QSize(100, 14))
@ -103,162 +109,162 @@ class fullScreenEditor(QWidget):
self.bottomPanel.layout().addWidget(self.lblWC) self.bottomPanel.layout().addWidget(self.lblWC)
self.bottomPanel.layout().addWidget(self.lblProgress) self.bottomPanel.layout().addWidget(self.lblProgress)
self.updateStatusBar() self.updateStatusBar()
self.bottomPanel.layout().addSpacing(24) self.bottomPanel.layout().addSpacing(24)
# Connection # Connection
self._index.model().dataChanged.connect(self.dataChanged) self._index.model().dataChanged.connect(self.dataChanged)
#self.updateTheme() # self.updateTheme()
self.showFullScreen() self.showFullScreen()
#self.showMaximized() # self.showMaximized()
#self.show() # self.show()
def setLocked(self, val): def setLocked(self, val):
self._locked = val self._locked = val
self.btnClose.setVisible(not val) self.btnClose.setVisible(not val)
def setTheme(self, themeName): def setTheme(self, themeName):
settings.fullScreenTheme = themeName settings.fullScreenTheme = themeName
self._theme = findThemePath(themeName) self._theme = findThemePath(themeName)
self._themeDatas = loadThemeDatas(self._theme) self._themeDatas = loadThemeDatas(self._theme)
self.updateTheme() self.updateTheme()
def updateTheme(self): def updateTheme(self):
# Reinit stored geometries for hiding widgets # Reinit stored geometries for hiding widgets
self._geometries = {} self._geometries = {}
rect = self.geometry() rect = self.geometry()
self._background = generateTheme(self._themeDatas, rect) self._background = generateTheme(self._themeDatas, rect)
setThemeEditorDatas(self.editor, self._themeDatas, self._background, rect) setThemeEditorDatas(self.editor, self._themeDatas, self._background, rect)
# Colors # Colors
if self._themeDatas["Foreground/Color"] == self._themeDatas["Background/Color"] or \ if self._themeDatas["Foreground/Color"] == self._themeDatas["Background/Color"] or \
self._themeDatas["Foreground/Opacity"] < 5: self._themeDatas["Foreground/Opacity"] < 5:
self._bgcolor = QColor(self._themeDatas["Text/Color"]) self._bgcolor = QColor(self._themeDatas["Text/Color"])
self._fgcolor = QColor(self._themeDatas["Background/Color"]) self._fgcolor = QColor(self._themeDatas["Background/Color"])
else: else:
self._bgcolor = QColor(self._themeDatas["Foreground/Color"]) self._bgcolor = QColor(self._themeDatas["Foreground/Color"])
self._bgcolor.setAlpha(self._themeDatas["Foreground/Opacity"] * 255 / 100) self._bgcolor.setAlpha(self._themeDatas["Foreground/Opacity"] * 255 / 100)
self._fgcolor = QColor(self._themeDatas["Text/Color"]) self._fgcolor = QColor(self._themeDatas["Text/Color"])
if self._themeDatas["Text/Color"] == self._themeDatas["Foreground/Color"]: if self._themeDatas["Text/Color"] == self._themeDatas["Foreground/Color"]:
self._fgcolor = QColor(self._themeDatas["Background/Color"]) self._fgcolor = QColor(self._themeDatas["Background/Color"])
# ScrollBar # ScrollBar
r = self.editor.geometry() r = self.editor.geometry()
w = qApp.style().pixelMetric(QStyle.PM_ScrollBarExtent) w = qApp.style().pixelMetric(QStyle.PM_ScrollBarExtent)
r.setWidth(w) r.setWidth(w)
r.moveRight(rect.right() - rect.left()) r.moveRight(rect.right() - rect.left())
self.scrollBar.setGeometry(r) self.scrollBar.setGeometry(r)
#self.scrollBar.setVisible(False) # self.scrollBar.setVisible(False)
self.hideWidget(self.scrollBar) self.hideWidget(self.scrollBar)
p = self.scrollBar.palette() p = self.scrollBar.palette()
b = QBrush(self._background.copy(self.scrollBar.geometry())) b = QBrush(self._background.copy(self.scrollBar.geometry()))
p.setBrush(QPalette.Base, b) p.setBrush(QPalette.Base, b)
self.scrollBar.setPalette(p) self.scrollBar.setPalette(p)
self.scrollBar.setColor(self._bgcolor) self.scrollBar.setColor(self._bgcolor)
# Left Panel # Left Panel
r = self.locker.geometry() r = self.locker.geometry()
r.moveTopLeft(QPoint( r.moveTopLeft(QPoint(
0, 0,
self.geometry().height() / 2 - r.height() / 2 self.geometry().height() / 2 - r.height() / 2
)) ))
self.leftPanel.setGeometry(r) self.leftPanel.setGeometry(r)
self.hideWidget(self.leftPanel) self.hideWidget(self.leftPanel)
self.leftPanel.setColor(self._bgcolor) self.leftPanel.setColor(self._bgcolor)
# Top / Bottom Panels # Top / Bottom Panels
r = QRect(0, 0, 0, 24) r = QRect(0, 0, 0, 24)
r.setWidth(rect.width()) r.setWidth(rect.width())
#r.moveLeft(rect.center().x() - r.width() / 2) # r.moveLeft(rect.center().x() - r.width() / 2)
self.topPanel.setGeometry(r) self.topPanel.setGeometry(r)
#self.topPanel.setVisible(False) # self.topPanel.setVisible(False)
self.hideWidget(self.topPanel) self.hideWidget(self.topPanel)
r.moveBottom(rect.bottom() - rect.top()) r.moveBottom(rect.bottom() - rect.top())
self.bottomPanel.setGeometry(r) self.bottomPanel.setGeometry(r)
#self.bottomPanel.setVisible(False) # self.bottomPanel.setVisible(False)
self.hideWidget(self.bottomPanel) self.hideWidget(self.bottomPanel)
self.topPanel.setColor(self._bgcolor) self.topPanel.setColor(self._bgcolor)
self.bottomPanel.setColor(self._bgcolor) self.bottomPanel.setColor(self._bgcolor)
# Lst theme # Lst theme
#p = self.lstThemes.palette() # p = self.lstThemes.palette()
p = self.palette() p = self.palette()
p.setBrush(QPalette.Button, self._bgcolor) p.setBrush(QPalette.Button, self._bgcolor)
p.setBrush(QPalette.ButtonText, self._fgcolor) p.setBrush(QPalette.ButtonText, self._fgcolor)
p.setBrush(QPalette.WindowText, self._fgcolor) p.setBrush(QPalette.WindowText, self._fgcolor)
for panel in (self.bottomPanel, self.topPanel): for panel in (self.bottomPanel, self.topPanel):
for i in range(panel.layout().count()): for i in range(panel.layout().count()):
item = panel.layout().itemAt(i) item = panel.layout().itemAt(i)
if item.widget(): if item.widget():
item.widget().setPalette(p) item.widget().setPalette(p)
#self.lstThemes.setPalette(p) # self.lstThemes.setPalette(p)
#self.lblWC.setPalette(p) # self.lblWC.setPalette(p)
self.update() self.update()
def paintEvent(self, event): def paintEvent(self, event):
if self._background: if self._background:
painter = QPainter(self) painter = QPainter(self)
painter.setClipRegion(event.region()) painter.setClipRegion(event.region())
painter.drawPixmap(event.rect(), self._background, event.rect()) painter.drawPixmap(event.rect(), self._background, event.rect())
painter.end() painter.end()
def resizeEvent(self, event): def resizeEvent(self, event):
self.updateTheme() self.updateTheme()
def keyPressEvent(self, event): def keyPressEvent(self, event):
if event.key() in [Qt.Key_Escape, Qt.Key_F11] and \ if event.key() in [Qt.Key_Escape, Qt.Key_F11] and \
not self._locked: not self._locked:
self.close() self.close()
else: else:
QWidget.keyPressEvent(self, event) QWidget.keyPressEvent(self, event)
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
r = self.geometry() r = self.geometry()
for w in [self.scrollBar, self.topPanel, for w in [self.scrollBar, self.topPanel,
self.bottomPanel, self.leftPanel]: self.bottomPanel, self.leftPanel]:
#w.setVisible(w.geometry().contains(event.pos())) # w.setVisible(w.geometry().contains(event.pos()))
if self._geometries[w].contains(event.pos()): if self._geometries[w].contains(event.pos()):
self.showWidget(w) self.showWidget(w)
else: else:
self.hideWidget(w) self.hideWidget(w)
def hideWidget(self, widget): def hideWidget(self, widget):
if widget not in self._geometries: if widget not in self._geometries:
self._geometries[widget] = widget.geometry() self._geometries[widget] = widget.geometry()
widget.move(self.geometry().bottomRight()) widget.move(self.geometry().bottomRight())
def showWidget(self, widget): def showWidget(self, widget):
if widget in self._geometries: if widget in self._geometries:
widget.move(self._geometries[widget].topLeft()) widget.move(self._geometries[widget].topLeft())
def eventFilter(self, obj, event): def eventFilter(self, obj, event):
if obj == self.editor and event.type() == QEvent.Enter: if obj == self.editor and event.type() == QEvent.Enter:
for w in [self.scrollBar, self.topPanel, for w in [self.scrollBar, self.topPanel,
self.bottomPanel, self.leftPanel]: self.bottomPanel, self.leftPanel]:
#w.setVisible(False) # w.setVisible(False)
self.hideWidget(w) self.hideWidget(w)
return QWidget.eventFilter(self, obj, event) return QWidget.eventFilter(self, obj, event)
def dataChanged(self, topLeft, bottomRight): def dataChanged(self, topLeft, bottomRight):
if not self._index: if not self._index:
return return
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateStatusBar() self.updateStatusBar()
def updateStatusBar(self): def updateStatusBar(self):
if self._index: if self._index:
item = self._index.internalPointer() item = self._index.internalPointer()
wc = item.data(Outline.wordCount.value) wc = item.data(Outline.wordCount.value)
goal = item.data(Outline.goal.value) goal = item.data(Outline.goal.value)
pg = item.data(Outline.goalPercentage.value) pg = item.data(Outline.goalPercentage.value)
if goal: if goal:
rect = self.lblProgress.geometry() rect = self.lblProgress.geometry()
rect = QRect(QPoint(0, 0), rect.size()) rect = QRect(QPoint(0, 0), rect.size())
@ -272,45 +278,47 @@ class fullScreenEditor(QWidget):
else: else:
self.lblProgress.hide() self.lblProgress.hide()
self.lblWC.setText(self.tr("{} words").format(wc)) self.lblWC.setText(self.tr("{} words").format(wc))
self.locker.setWordCount(wc) self.locker.setWordCount(wc)
if not self.locker.isLocked(): if not self.locker.isLocked():
if goal - wc > 0: if goal - wc > 0:
self.locker.spnWordTarget.setValue(goal - wc) self.locker.spnWordTarget.setValue(goal - wc)
class myScrollBar(QScrollBar): class myScrollBar(QScrollBar):
def __init__(self, color=Qt.white, parent=None): def __init__(self, color=Qt.white, parent=None):
QScrollBar.__init__(self, parent) QScrollBar.__init__(self, parent)
self._color = color self._color = color
#self.setAttribute(Qt.WA_TranslucentBackground) # self.setAttribute(Qt.WA_TranslucentBackground)
self.timer = QTimer() self.timer = QTimer()
self.timer.setInterval(500) self.timer.setInterval(500)
self.timer.setSingleShot(True) self.timer.setSingleShot(True)
self.timer.timeout.connect(lambda: self.parent().hideWidget(self)) self.timer.timeout.connect(lambda: self.parent().hideWidget(self))
self.valueChanged.connect(lambda v: self.timer.start()) self.valueChanged.connect(lambda v: self.timer.start())
self.valueChanged.connect(lambda: self.parent().showWidget(self)) self.valueChanged.connect(lambda: self.parent().showWidget(self))
def setColor(self, color): def setColor(self, color):
self._color = color self._color = color
def paintEvent(self, event): def paintEvent(self, event):
opt = QStyleOptionSlider() opt = QStyleOptionSlider()
self.initStyleOption(opt) self.initStyleOption(opt)
style = qApp.style() style = qApp.style()
painter = QPainter(self) painter = QPainter(self)
# Background (Necessary with Qt 5.2 it seems, not with 5.4) # Background (Necessary with Qt 5.2 it seems, not with 5.4)
#painter.save() # painter.save()
#painter.setPen(Qt.NoPen) # painter.setPen(Qt.NoPen)
#painter.setBrush(self.palette().brush(QPalette.Base)) # painter.setBrush(self.palette().brush(QPalette.Base))
#painter.drawRect(event.rect()) # painter.drawRect(event.rect())
#painter.restore() # painter.restore()
#slider # slider
r = style.subControlRect(style.CC_ScrollBar, opt, style.SC_ScrollBarSlider) r = style.subControlRect(style.CC_ScrollBar, opt, style.SC_ScrollBarSlider)
painter.fillRect(r, self._color) painter.fillRect(r, self._color)
painter.end() painter.end()
class myPanel(QWidget): class myPanel(QWidget):
def __init__(self, color=Qt.white, vertical=False, parent=None): def __init__(self, color=Qt.white, vertical=False, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
@ -322,11 +330,11 @@ class myPanel(QWidget):
else: else:
self.setLayout(QVBoxLayout()) self.setLayout(QVBoxLayout())
self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setContentsMargins(0, 0, 0, 0)
def setColor(self, color): def setColor(self, color):
self._color = color self._color = color
def paintEvent(self, event): def paintEvent(self, event):
r = event.rect() r = event.rect()
painter = QPainter(self) painter = QPainter(self)
painter.fillRect(r, self._color) painter.fillRect(r, self._color)

View file

@ -1,19 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import pyqtSignal, QTimer
from qt import * from PyQt5.QtWidgets import QWidget, qApp
from enums import *
from ui.editors.locker_ui import Ui_locker from manuskript.ui.editors.locker_ui import Ui_locker
from functions import *
import models.references as Ref
class locker(QWidget, Ui_locker): class locker(QWidget, Ui_locker):
locked = pyqtSignal() locked = pyqtSignal()
unlocked = pyqtSignal() unlocked = pyqtSignal()
lockChanged = pyqtSignal(bool) lockChanged = pyqtSignal(bool)
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
@ -21,7 +18,7 @@ class locker(QWidget, Ui_locker):
self._words = None self._words = None
self._target = None self._target = None
self._blackout = [] self._blackout = []
self.timer = QTimer(self) self.timer = QTimer(self)
self.timer.setSingleShot(True) self.timer.setSingleShot(True)
self.timer.timeout.connect(self.unlock) self.timer.timeout.connect(self.unlock)
@ -34,9 +31,9 @@ class locker(QWidget, Ui_locker):
self.rbtnTimeTarget.toggled.connect(self.spnTimeTarget.setVisible) self.rbtnTimeTarget.toggled.connect(self.spnTimeTarget.setVisible)
self.rbtnWordTarget.setChecked(True) self.rbtnWordTarget.setChecked(True)
self.spnTimeTarget.setVisible(False) self.spnTimeTarget.setVisible(False)
self.btnLock.clicked.connect(self.lock) self.btnLock.clicked.connect(self.lock)
def lock(self): def lock(self):
# Block others screens # Block others screens
desktop = qApp.desktop() desktop = qApp.desktop()
@ -49,24 +46,24 @@ class locker(QWidget, Ui_locker):
w.move(desktop.screenGeometry(d).topLeft()) w.move(desktop.screenGeometry(d).topLeft())
w.showFullScreen() w.showFullScreen()
self._blackout.append(w) self._blackout.append(w)
if self.rbtnWordTarget.isChecked(): if self.rbtnWordTarget.isChecked():
self._target = self._words + self.spnWordTarget.value() self._target = self._words + self.spnWordTarget.value()
elif self.rbtnTimeTarget.isChecked(): elif self.rbtnTimeTarget.isChecked():
self.timer.setInterval(self.spnTimeTarget.value() * 1000 * 60) self.timer.setInterval(self.spnTimeTarget.value() * 1000 * 60)
self.timer.start() self.timer.start()
self.timerSec.start() self.timerSec.start()
self.updateBtnText() self.updateBtnText()
self.setEnabled(False) self.setEnabled(False)
self.locked.emit() self.locked.emit()
self.lockChanged.emit(True) self.lockChanged.emit(True)
def unlock(self): def unlock(self):
# Remove black screens # Remove black screens
self._blackout.clear() self._blackout.clear()
self.setEnabled(True) self.setEnabled(True)
self.btnLock.setText(self._btnText) self.btnLock.setText(self._btnText)
self.timer.stop() self.timer.stop()
@ -74,21 +71,21 @@ class locker(QWidget, Ui_locker):
self._target = None self._target = None
self.unlocked.emit() self.unlocked.emit()
self.lockChanged.emit(False) self.lockChanged.emit(False)
def isLocked(self): def isLocked(self):
return not self.isEnabled() return not self.isEnabled()
def setWordCount(self, wc): def setWordCount(self, wc):
self._words = wc self._words = wc
if self.isLocked(): if self.isLocked():
self.updateBtnText() self.updateBtnText()
if self._words >= self._target: if self._words >= self._target:
self.unlock() self.unlock()
def updateBtnText(self): def updateBtnText(self):
if not self._btnText: if not self._btnText:
self._btnText = self.btnLock.text() self._btnText = self.btnLock.text()
# Time locked # Time locked
if self.timer.remainingTime() != -1: if self.timer.remainingTime() != -1:
t = self.timer.remainingTime() t = self.timer.remainingTime()
@ -103,12 +100,11 @@ class locker(QWidget, Ui_locker):
text = self.tr("{}:{}").format(str(mn), str(sec)) text = self.tr("{}:{}").format(str(mn), str(sec))
else: else:
text = self.tr("{} s.").format(str(t)) text = self.tr("{} s.").format(str(t))
self.btnLock.setText(self.tr("{} remaining").format( self.btnLock.setText(self.tr("{} remaining").format(
text)) text))
# Word locked # Word locked
elif self._target != None: elif self._target is not None:
self.btnLock.setText(self.tr("{} words remaining").format( self.btnLock.setText(self.tr("{} words remaining").format(
self._target - self._words)) self._target - self._words))

View file

@ -1,49 +1,56 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from ui.editors.mainEditor_ui import *
from ui.editors.editorWidget import *
from functions import *
import locale import locale
from PyQt5.QtCore import QModelIndex, QRect, QPoint
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import qApp
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import AUC, mainWindow, drawProgress
from manuskript.ui.editors.editorWidget import editorWidget
from manuskript.ui.editors.fullScreenEditor import fullScreenEditor
from manuskript.ui.editors.mainEditor_ui import Ui_mainEditor
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
class mainEditor(QWidget, Ui_mainEditor): class mainEditor(QWidget, Ui_mainEditor):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self._updating = False self._updating = False
self.mw = mainWindow() self.mw = mainWindow()
self.tab.tabCloseRequested.connect(self.closeTab) self.tab.tabCloseRequested.connect(self.closeTab)
self.tab.currentChanged.connect(self.tabChanged) self.tab.currentChanged.connect(self.tabChanged)
# Connections -------------------------------------------------------- # Connections --------------------------------------------------------
self.sldCorkSizeFactor.valueChanged.connect( self.sldCorkSizeFactor.valueChanged.connect(
self.setCorkSizeFactor, AUC) self.setCorkSizeFactor, AUC)
self.btnRedacFolderCork.toggled.connect( self.btnRedacFolderCork.toggled.connect(
self.sldCorkSizeFactor.setVisible, AUC) self.sldCorkSizeFactor.setVisible, AUC)
self.btnRedacFolderText.clicked.connect( self.btnRedacFolderText.clicked.connect(
lambda v: self.setFolderView("text"), AUC) lambda v: self.setFolderView("text"), AUC)
self.btnRedacFolderCork.clicked.connect( self.btnRedacFolderCork.clicked.connect(
lambda v: self.setFolderView("cork"), AUC) lambda v: self.setFolderView("cork"), AUC)
self.btnRedacFolderOutline.clicked.connect( self.btnRedacFolderOutline.clicked.connect(
lambda v: self.setFolderView("outline"), AUC) lambda v: self.setFolderView("outline"), AUC)
self.btnRedacFullscreen.clicked.connect( self.btnRedacFullscreen.clicked.connect(
self.showFullScreen, AUC) self.showFullScreen, AUC)
############################################################################### ###############################################################################
# TABS # TABS
############################################################################### ###############################################################################
def currentEditor(self): def currentEditor(self):
return self.tab.currentWidget() return self.tab.currentWidget()
def tabChanged(self, index): def tabChanged(self, index):
if self.currentEditor(): if self.currentEditor():
index = self.currentEditor().currentIndex index = self.currentEditor().currentIndex
@ -56,61 +63,61 @@ class mainEditor(QWidget, Ui_mainEditor):
else: else:
index = QModelIndex() index = QModelIndex()
hidden = False hidden = False
self._updating = True self._updating = True
self.mw.treeRedacOutline.setCurrentIndex(index) self.mw.treeRedacOutline.setCurrentIndex(index)
self._updating = False self._updating = False
self.updateStats() self.updateStats()
self.updateThingsVisible(index) self.updateThingsVisible(index)
def closeTab(self, index): def closeTab(self, index):
#FIXME: submit data if textedit? # FIXME: submit data if textedit?
w = self.tab.widget(index) w = self.tab.widget(index)
self.tab.removeTab(index) self.tab.removeTab(index)
w.deleteLater() w.deleteLater()
def allTabs(self): def allTabs(self):
return [self.tab.widget(i) for i in range(self.tab.count())] return [self.tab.widget(i) for i in range(self.tab.count())]
############################################################################### ###############################################################################
# SELECTION AND UPDATES # SELECTION AND UPDATES
############################################################################### ###############################################################################
def selectionChanged(self): def selectionChanged(self):
if self._updating: if self._updating:
return return
if len(self.mw.treeRedacOutline.selectionModel(). if len(self.mw.treeRedacOutline.selectionModel().
selection().indexes()) == 0: selection().indexes()) == 0:
idx = QModelIndex() idx = QModelIndex()
else: else:
idx = self.mw.treeRedacOutline.currentIndex() idx = self.mw.treeRedacOutline.currentIndex()
self.setCurrentModelIndex(idx) self.setCurrentModelIndex(idx)
self.updateThingsVisible(idx) self.updateThingsVisible(idx)
def openIndexes(self, indexes, newTab=False): def openIndexes(self, indexes, newTab=False):
for i in indexes: for i in indexes:
self.setCurrentModelIndex(i, newTab) self.setCurrentModelIndex(i, newTab)
def setCurrentModelIndex(self, index, newTab=False): def setCurrentModelIndex(self, index, newTab=False):
if not index.isValid(): if not index.isValid():
title = self.tr("Root") title = self.tr("Root")
else: else:
title = index.internalPointer().title() title = index.internalPointer().title()
# Checking if tab is already openned # Checking if tab is already openned
for w in self.allTabs(): for w in self.allTabs():
if w.currentIndex == index: if w.currentIndex == index:
self.tab.setCurrentWidget(w) self.tab.setCurrentWidget(w)
return return
if qApp.keyboardModifiers() & Qt.ControlModifier: if qApp.keyboardModifiers() & Qt.ControlModifier:
newTab = True newTab = True
if newTab or not self.tab.count(): if newTab or not self.tab.count():
editor = editorWidget(self) editor = editorWidget(self)
editor.setCurrentModelIndex(index) editor.setCurrentModelIndex(index)
@ -119,28 +126,26 @@ class mainEditor(QWidget, Ui_mainEditor):
else: else:
self.currentEditor().setCurrentModelIndex(index) self.currentEditor().setCurrentModelIndex(index)
self.tab.setTabText(self.tab.currentIndex(), title) self.tab.setTabText(self.tab.currentIndex(), title)
###############################################################################
############################################################################### # UI
# UI ###############################################################################
###############################################################################
def updateThingsVisible(self, index): def updateThingsVisible(self, index):
if index.isValid(): if index.isValid():
visible = index.internalPointer().isFolder() visible = index.internalPointer().isFolder()
else: else:
visible = True visible = True
# Hides / show textFormat # Hides / show textFormat
self.textFormat.updateFromIndex(index) self.textFormat.updateFromIndex(index)
self.btnRedacFolderText.setVisible(visible) self.btnRedacFolderText.setVisible(visible)
self.btnRedacFolderCork.setVisible(visible) self.btnRedacFolderCork.setVisible(visible)
self.btnRedacFolderOutline.setVisible(visible) self.btnRedacFolderOutline.setVisible(visible)
self.sldCorkSizeFactor.setVisible(visible) self.sldCorkSizeFactor.setVisible(visible)
self.btnRedacFullscreen.setVisible(not visible) self.btnRedacFullscreen.setVisible(not visible)
def updateFolderViewButtons(self, view): def updateFolderViewButtons(self, view):
if view == "text": if view == "text":
self.btnRedacFolderText.setChecked(True) self.btnRedacFolderText.setChecked(True)
@ -148,26 +153,26 @@ class mainEditor(QWidget, Ui_mainEditor):
self.btnRedacFolderCork.setChecked(True) self.btnRedacFolderCork.setChecked(True)
elif view == "outline": elif view == "outline":
self.btnRedacFolderOutline.setChecked(True) self.btnRedacFolderOutline.setChecked(True)
def updateStats(self): def updateStats(self):
if not self.currentEditor(): if not self.currentEditor():
return return
index = self.currentEditor().currentIndex index = self.currentEditor().currentIndex
if index.isValid(): if index.isValid():
item = index.internalPointer() item = index.internalPointer()
else: else:
item = self.mw.mdlOutline.rootItem item = self.mw.mdlOutline.rootItem
if not item: if not item:
item = self.mw.mdlOutline.rootItem item = self.mw.mdlOutline.rootItem
wc = item.data(Outline.wordCount.value) wc = item.data(Outline.wordCount.value)
goal = item.data(Outline.goal.value) goal = item.data(Outline.goal.value)
progress = item.data(Outline.goalPercentage.value) progress = item.data(Outline.goalPercentage.value)
#mw = qApp.activeWindow() # mw = qApp.activeWindow()
if not wc: if not wc:
wc = 0 wc = 0
if goal: if goal:
@ -181,53 +186,51 @@ class mainEditor(QWidget, Ui_mainEditor):
del p del p
self.lblRedacProgress.setPixmap(self.px) self.lblRedacProgress.setPixmap(self.px)
self.lblRedacWC.setText(self.tr("{} words / {}").format( self.lblRedacWC.setText(self.tr("{} words / {}").format(
locale.format("%d", wc, grouping=True), locale.format("%d", wc, grouping=True),
locale.format("%d", goal, grouping=True))) locale.format("%d", goal, grouping=True)))
else: else:
self.lblRedacProgress.hide() self.lblRedacProgress.hide()
self.lblRedacWC.setText(self.tr("{} words").format( self.lblRedacWC.setText(self.tr("{} words").format(
locale.format("%d", wc, grouping=True))) locale.format("%d", wc, grouping=True)))
############################################################################### ###############################################################################
# VIEWS # VIEWS
############################################################################### ###############################################################################
def setFolderView(self, view): def setFolderView(self, view):
if self.currentEditor(): if self.currentEditor():
self.currentEditor().setFolderView(view) self.currentEditor().setFolderView(view)
def setCorkSizeFactor(self, val): def setCorkSizeFactor(self, val):
for w in self.allTabs(): for w in self.allTabs():
w.setCorkSizeFactor(val) w.setCorkSizeFactor(val)
settings.corkSizeFactor = val settings.corkSizeFactor = val
def updateCorkView(self): def updateCorkView(self):
for w in self.allTabs(): for w in self.allTabs():
w.corkView.viewport().update() w.corkView.viewport().update()
def updateCorkBackground(self): def updateCorkBackground(self):
for w in self.allTabs(): for w in self.allTabs():
w.corkView.updateBackground() w.corkView.updateBackground()
def updateTreeView(self): def updateTreeView(self):
for w in self.allTabs(): for w in self.allTabs():
w.outlineView.viewport().update() w.outlineView.viewport().update()
def showFullScreen(self): def showFullScreen(self):
if self.currentEditor(): if self.currentEditor():
self._fullScreen = fullScreenEditor(self.currentEditor().currentIndex) self._fullScreen = fullScreenEditor(self.currentEditor().currentIndex)
############################################################################### ###############################################################################
# DICT AND STUFF LIKE THAT # DICT AND STUFF LIKE THAT
############################################################################### ###############################################################################
def setDict(self, dict): def setDict(self, dict):
print(dict) print(dict)
for w in self.allTabs(): for w in self.allTabs():
w.setDict(dict) w.setDict(dict)
def toggleSpellcheck(self, val): def toggleSpellcheck(self, val):
for w in self.allTabs(): for w in self.allTabs():
w.toggleSpellcheck(val) w.toggleSpellcheck(val)

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/editors/mainEditor_ui.ui' # Form implementation generated from reading ui file 'manuskript/ui/editors/mainEditor_ui.ui'
# #
# Created by: PyQt5 UI code generator 5.4.1 # Created by: PyQt5 UI code generator 5.4.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -94,4 +94,4 @@ class Ui_mainEditor(object):
self.btnRedacFolderOutline.setText(_translate("mainEditor", "Outline")) self.btnRedacFolderOutline.setText(_translate("mainEditor", "Outline"))
self.btnRedacFullscreen.setShortcut(_translate("mainEditor", "F11")) self.btnRedacFullscreen.setShortcut(_translate("mainEditor", "F11"))
from ui.editors.textFormat import textFormat from manuskript.ui.editors.textFormat import textFormat

View file

@ -201,7 +201,7 @@
<customwidget> <customwidget>
<class>textFormat</class> <class>textFormat</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.editors.textFormat.h</header> <header>manuskript.ui.editors.textFormat.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>

View file

@ -1,9 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from qt import *
import re import re
from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QTextCursor
def t2tFormatSelection(editor, style): def t2tFormatSelection(editor, style):
""" """
Formats the current selection of ``editor`` in the format given by ``style``, Formats the current selection of ``editor`` in the format given by ``style``,
@ -54,7 +57,7 @@ def t2tFormatSelection(editor, style):
# Adjusts selection to exclude the markup # Adjusts selection to exclude the markup
while text[start:start + 1] == formatChar: while text[start:start + 1] == formatChar:
start += 1 start += 1
while text[end - 1:end] ==formatChar: while text[end - 1:end] == formatChar:
end -= 1 end -= 1
# Get the text without formatting, and the array of format # Get the text without formatting, and the array of format
@ -69,12 +72,12 @@ def t2tFormatSelection(editor, style):
# have some unformated text in the selection, so we format the # have some unformated text in the selection, so we format the
# whole selection # whole selection
propperArray = propperArray[:tStart] + [1] * \ propperArray = propperArray[:tStart] + [1] * \
(tEnd - tStart) + propperArray[tEnd:] (tEnd - tStart) + propperArray[tEnd:]
else: else:
# The whole selection is already formatted, so we remove the # The whole selection is already formatted, so we remove the
# formatting # formatting
propperArray = propperArray[:tStart] + [0] * \ propperArray = propperArray[:tStart] + [0] * \
(tEnd - tStart) + propperArray[tEnd:] (tEnd - tStart) + propperArray[tEnd:]
fArray = fArray[0:style] + [propperArray] + fArray[style + 1:] fArray = fArray[0:style] + [propperArray] + fArray[style + 1:]
@ -92,8 +95,9 @@ def t2tFormatSelection(editor, style):
editor.setTextCursor(cursor) editor.setTextCursor(cursor)
def t2tClearFormat(editor): def t2tClearFormat(editor):
"Clears format on ``editor``'s current selection." """Clears format on ``editor``'s current selection."""
cursor = editor.textCursor() cursor = editor.textCursor()
cursor.beginEditBlock() cursor.beginEditBlock()
@ -105,6 +109,7 @@ def t2tClearFormat(editor):
cursor.endEditBlock() cursor.endEditBlock()
editor.setTextCursor(cursor) editor.setTextCursor(cursor)
def textToFormatArray(text): def textToFormatArray(text):
""" """
Take some text and returns an array of array containing informations Take some text and returns an array of array containing informations
@ -140,7 +145,7 @@ def textToFormatArray(text):
pos = r.indexIn(text, 0) pos = r.indexIn(text, 0)
lastPos = 0 lastPos = 0
while pos >= 0: while pos >= 0:
#We have a winner # We have a winner
rList += [0] * (pos - lastPos) rList += [0] * (pos - lastPos)
rList += [2] * 2 rList += [2] * 2
rList += [1] * len(r.cap(2)) rList += [1] * len(r.cap(2))
@ -231,7 +236,7 @@ def reformatText(text, markupArray):
markup = ["**", "//", "__", "--", "``", "''"] markup = ["**", "//", "__", "--", "``", "''"]
for k, m in enumerate(markupArray): for k, m in enumerate(markupArray):
#m = markupArray[k] # m = markupArray[k]
_open = False # Are we in an _openned markup _open = False # Are we in an _openned markup
d = 0 d = 0
alreadySeen = [] alreadySeen = []
@ -256,7 +261,7 @@ def reformatText(text, markupArray):
for j, m2 in enumerate(markupArray): for j, m2 in enumerate(markupArray):
# The other array still have the same length # The other array still have the same length
if j > k: if j > k:
#Insert 2 for bold, 3 for italic, etc. # Insert 2 for bold, 3 for italic, etc.
m2.insert(i + d, k + 2) m2.insert(i + d, k + 2)
m2.insert(i + d, k + 2) m2.insert(i + d, k + 2)
alreadySeen = [] alreadySeen = []
@ -267,24 +272,24 @@ def reformatText(text, markupArray):
for j, m2 in enumerate(markupArray): for j, m2 in enumerate(markupArray):
# The other array still have the same length # The other array still have the same length
if j > k: if j > k:
#Insert 2 for bold, 3 for italic, etc. # Insert 2 for bold, 3 for italic, etc.
m2.insert(i + d, k + 2) m2.insert(i + d, k + 2)
m2.insert(i + d, k + 2) m2.insert(i + d, k + 2)
text = rText text = rText
rText = "" rText = ""
## Clean up # Clean up
# Exclude first and last space of the markup # Exclude first and last space of the markup
for markup in ["\*", "/", "_", "-", "`", "\'"]: for markup in ["\*", "/", "_", "-", "`", "\'"]:
#r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')') # r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')')
#r.setMinimal(True) # r.setMinimal(True)
#text.replace(r, "\\2\\1\\3\\4") # text.replace(r, "\\2\\1\\3\\4")
text = re.sub(r'(' + markup * 2 + ')(\s+?)(.+?)(' + markup * 2 + ')', text = re.sub(r'(' + markup * 2 + ')(\s+?)(.+?)(' + markup * 2 + ')',
"\\2\\1\\3\\4", "\\2\\1\\3\\4",
text) text)
#r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')') # r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')')
#r.setMinimal(True) # r.setMinimal(True)
#text.replace(r, "\\1\\2\\4\\3") # text.replace(r, "\\1\\2\\4\\3")
text = re.sub(r'(' + markup * 2 + ')(.+?)(\s+?)(' + markup * 2 + ')', text = re.sub(r'(' + markup * 2 + ')(.+?)(\s+?)(' + markup * 2 + ')',
"\\1\\2\\4\\3", "\\1\\2\\4\\3",
text) text)
@ -293,7 +298,7 @@ def reformatText(text, markupArray):
def cleanFormat(text): def cleanFormat(text):
"Makes markup clean (removes doubles, etc.)" """Makes markup clean (removes doubles, etc.)"""
t, a = textToFormatArrayNoMarkup(text) t, a = textToFormatArrayNoMarkup(text)
return reformatText(t, a) return reformatText(t, a)
@ -327,7 +332,7 @@ class State:
RAW_AREA_ENDS = 20 RAW_AREA_ENDS = 20
TAGGED_AREA_BEGINS = 21 TAGGED_AREA_BEGINS = 21
TAGGED_AREA_ENDS = 22 TAGGED_AREA_ENDS = 22
#LINE # LINE
COMMENT_LINE = 30 COMMENT_LINE = 30
CODE_LINE = 31 CODE_LINE = 31
RAW_LINE = 32 RAW_LINE = 32
@ -346,7 +351,7 @@ class State:
# TABLE # TABLE
TABLE_LINE = 50 TABLE_LINE = 50
TABLE_HEADER = 51 TABLE_HEADER = 51
#OTHER # OTHER
MARKUP = 60 MARKUP = 60
LINKS = 61 LINKS = 61
MACRO = 62 MACRO = 62
@ -368,4 +373,4 @@ class State:
State.NUMBERED_TITLE_3: 3, State.NUMBERED_TITLE_3: 3,
State.NUMBERED_TITLE_4: 4, State.NUMBERED_TITLE_4: 4,
State.NUMBERED_TITLE_5: 5, State.NUMBERED_TITLE_5: 5,
}.get(state, -1) }.get(state, -1)

View file

@ -1,22 +1,26 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
from qt import *
from ui.editors.t2tFunctions import *
from ui.editors.blockUserData import blockUserData
from ui.editors.t2tHighlighterStyle import t2tHighlighterStyle
from ui.editors.basicHighlighter import *
import re
# This is aiming at implementing every rule from www.txt2tags.org/rules.html # This is aiming at implementing every rule from www.txt2tags.org/rules.html
# But we're not there yet. # But we're not there yet.
#FIXME: macro words not hilighted properly if at the begining of a line. # FIXME: macro words not hilighted properly if at the begining of a line.
#TODO: parse %!postproc et !%preproc, et si la ligne se termine par une couleur en commentaire (%#FF00FF), utiliser cette couleur pour highlighter. Permet des règles customisées par document, facilement. # TODO: parse %!postproc et !%preproc, et si la ligne se termine par une couleur en commentaire (%#FF00FF),
# utiliser cette couleur pour highlighter. Permet des règles customisées par document, facilement.
import re
from PyQt5.QtCore import QRegExp, QDir, QFileInfo
from PyQt5.QtGui import QTextBlockFormat, QTextCursor, QTextCharFormat, QBrush
from manuskript.ui.editors.basicHighlighter import basicHighlighter
from manuskript.ui.editors.blockUserData import blockUserData
from manuskript.ui.editors.t2tFunctions import State, textToFormatArray
from manuskript.ui.editors.t2tHighlighterStyle import t2tHighlighterStyle
class t2tHighlighter (basicHighlighter): class t2tHighlighter(basicHighlighter):
"""Syntax highlighter for the Txt2Tags language. """Syntax highlighter for the Txt2Tags language.
""" """
@ -25,9 +29,9 @@ class t2tHighlighter (basicHighlighter):
# Stupid variable that fixes the loss of QTextBlockUserData. # Stupid variable that fixes the loss of QTextBlockUserData.
self.thisDocument = editor.document() self.thisDocument = editor.document()
self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style) self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style)
self.inDocRules = [] self.inDocRules = []
rules = [ rules = [
@ -63,25 +67,25 @@ class t2tHighlighter (basicHighlighter):
self._defaultCharFormat = cf self._defaultCharFormat = cf
self.setStyle() self.setStyle()
self.rehighlight() self.rehighlight()
def highlightBlock(self, text): def highlightBlock(self, text):
"""Apply syntax highlighting to the given block of text. """Apply syntax highlighting to the given block of text.
""" """
basicHighlighter.highlightBlockBefore(self, text) basicHighlighter.highlightBlockBefore(self, text)
# Check if syntax highlighting is enabled # Check if syntax highlighting is enabled
if self.style is None: if self.style is None:
default = QTextBlockFormat() default = QTextBlockFormat()
QTextCursor(self.currentBlock()).setBlockFormat(default) QTextCursor(self.currentBlock()).setBlockFormat(default)
print("t2tHighlighter.py: is style supposed to be None?") print("t2tHighlighter.py: is style supposed to be None?")
return return
block = self.currentBlock() block = self.currentBlock()
oldState = blockUserData.getUserState(block) oldState = blockUserData.getUserState(block)
self.identifyBlock(block) self.identifyBlock(block)
# formatBlock prevent undo/redo from working # formatBlock prevent undo/redo from working
# TODO: find a todo/undo compatible way of formatting block # TODO: find a todo/undo compatible way of formatting block
#self.formatBlock(block) # self.formatBlock(block)
state = blockUserData.getUserState(block) state = blockUserData.getUserState(block)
data = blockUserData.getUserData(block) data = blockUserData.getUserData(block)
@ -89,14 +93,15 @@ class t2tHighlighter (basicHighlighter):
op = self.style.format(State.MARKUP) op = self.style.format(State.MARKUP)
#self.setFormat(0, len(text), self.style.format(State.DEFAULT)) # self.setFormat(0, len(text), self.style.format(State.DEFAULT))
# InDocRules: is it a settings which might have a specific rule, # InDocRules: is it a settings which might have a specific rule,
# a comment which contains color infos, or a include conf? # a comment which contains color infos, or a include conf?
# r'^%!p[or][se]t?proc[^\s]*\s*:\s*\'(.*)\'\s*\'.*\'' # r'^%!p[or][se]t?proc[^\s]*\s*:\s*\'(.*)\'\s*\'.*\''
rlist = [QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))'), # pre/postproc rlist = [QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))'),
QRegExp(r'^%.*\s\((.*)\)'), # comment # pre/postproc
QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')] # includeconf QRegExp(r'^%.*\s\((.*)\)'), # comment
QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')] # includeconf
for r in rlist: for r in rlist:
if r.indexIn(text) != -1: if r.indexIn(text) != -1:
self.parseInDocRules() self.parseInDocRules()
@ -106,7 +111,7 @@ class t2tHighlighter (basicHighlighter):
State.BLOCKQUOTE_LINE, State.BLOCKQUOTE_LINE,
State.HORIZONTAL_LINE, State.HORIZONTAL_LINE,
State.HEADER_LINE, State.HEADER_LINE,
]: ]:
if not inList and state == lineState: if not inList and state == lineState:
self.setFormat(0, len(text), self.style.format(lineState)) self.setFormat(0, len(text), self.style.format(lineState))
@ -116,9 +121,9 @@ class t2tHighlighter (basicHighlighter):
(State.RAW_LINE, "\"\"\""), (State.RAW_LINE, "\"\"\""),
(State.TAGGED_LINE, "'''"), (State.TAGGED_LINE, "'''"),
(State.SETTINGS_LINE, "%!") (State.SETTINGS_LINE, "%!")
]: ]:
if state == lineState and \ if state == lineState and \
not (inList and state == State.SETTINGS_LINE): not (inList and state == State.SETTINGS_LINE):
n = 0 n = 0
# If it's a comment, we want to highlight all '%'. # If it's a comment, we want to highlight all '%'.
if state == State.COMMENT_LINE: if state == State.COMMENT_LINE:
@ -140,9 +145,9 @@ class t2tHighlighter (basicHighlighter):
setting = r.cap(1) setting = r.cap(1)
val = r.cap(2) val = r.cap(2)
if setting == "target" and \ if setting == "target" and \
val in self.editor.main.targetsNames: val in self.editor.main.targetsNames:
self.editor.fileWidget.preview.setPreferredTarget(val) self.editor.fileWidget.preview.setPreferredTarget(val)
# Pre/postproc # Pre/postproc
r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))') r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))')
if r.indexIn(text) != -1: if r.indexIn(text) != -1:
@ -161,15 +166,15 @@ class t2tHighlighter (basicHighlighter):
self.setFormat(i, 1, self.style.format(lineState)) self.setFormat(i, 1, self.style.format(lineState))
# Lists # Lists
#if text == " p": print(data.isList()) # if text == " p": print(data.isList())
if data.isList(): if data.isList():
r = QRegExp(r'^\s*[\+\-\:]? ?') r = QRegExp(r'^\s*[\+\-\:]? ?')
r.indexIn(text) r.indexIn(text)
self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET)) self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET))
#if state == State.LIST_BEGINS: # if state == State.LIST_BEGINS:
#r = QRegExp(r'^\s*[+-:] ') # r = QRegExp(r'^\s*[+-:] ')
#r.indexIn(text) # r.indexIn(text)
#self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET)) # self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET))
if state == State.LIST_ENDS: if state == State.LIST_ENDS:
self.setFormat(0, len(text), self.style.format(State.LIST_BULLET_ENDS)) self.setFormat(0, len(text), self.style.format(State.LIST_BULLET_ENDS))
@ -181,8 +186,8 @@ class t2tHighlighter (basicHighlighter):
if pos >= 0: if pos >= 0:
f = self.style.format(state) f = self.style.format(state)
# Uncomment for markup to be same size as title # Uncomment for markup to be same size as title
#op = self.formats(preset="markup", # op = self.formats(preset="markup",
#base=self.formats(preset=state)) # base=self.formats(preset=state))
self.setFormat(r.pos(2), len(r.cap(2)), f) self.setFormat(r.pos(2), len(r.cap(2)), f)
self.setFormat(r.pos(1), len(r.cap(1)), op) self.setFormat(r.pos(1), len(r.cap(1)), op)
self.setFormat(r.pos(3), len(r.cap(3)), op) self.setFormat(r.pos(3), len(r.cap(3)), op)
@ -193,7 +198,7 @@ class t2tHighlighter (basicHighlighter):
(State.CODE_AREA_BEGINS, State.CODE_AREA, State.CODE_AREA_ENDS), (State.CODE_AREA_BEGINS, State.CODE_AREA, State.CODE_AREA_ENDS),
(State.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS), (State.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS),
(State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS), (State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS),
]: ]:
if state == middle: if state == middle:
self.setFormat(0, len(text), self.style.format(middle)) self.setFormat(0, len(text), self.style.format(middle))
@ -202,8 +207,8 @@ class t2tHighlighter (basicHighlighter):
# Inline formatting # Inline formatting
if state not in [ if state not in [
#State.COMMENT_AREA, # State.COMMENT_AREA,
#State.COMMENT_LINE, # State.COMMENT_LINE,
State.RAW_AREA, State.RAW_AREA,
State.RAW_LINE, State.RAW_LINE,
State.CODE_AREA, State.CODE_AREA,
@ -212,7 +217,7 @@ class t2tHighlighter (basicHighlighter):
State.TAGGED_LINE, State.TAGGED_LINE,
State.SETTINGS_LINE, State.SETTINGS_LINE,
State.HORIZONTAL_LINE, State.HORIZONTAL_LINE,
] and state not in State.TITLES: ] and state not in State.TITLES:
formatArray = textToFormatArray(text) formatArray = textToFormatArray(text)
# InDocRules # InDocRules
@ -224,10 +229,10 @@ class t2tHighlighter (basicHighlighter):
if "," in c: if "," in c:
c1, c2 = c.split(",") c1, c2 = c.split(",")
self.setFormat(m.start(), l, self.setFormat(m.start(), l,
self.style.makeFormat(color=c1, bgcolor=c2, base=f)) self.style.makeFormat(color=c1, bgcolor=c2, base=f))
else: else:
self.setFormat(m.start(), l, self.setFormat(m.start(), l,
self.style.makeFormat(color=c, base=f)) self.style.makeFormat(color=c, base=f))
# Links # Links
if state not in [State.COMMENT_LINE, State.COMMENT_AREA]: if state not in [State.COMMENT_LINE, State.COMMENT_AREA]:
@ -236,8 +241,8 @@ class t2tHighlighter (basicHighlighter):
pos = r.indexIn(text) pos = r.indexIn(text)
links = [] links = []
while pos >= 0: while pos >= 0:
#TODO: The text should not be formatted if [**not bold**] # TODO: The text should not be formatted if [**not bold**]
#if max([k[pos] for k in formatArray]) == 0 or 1 == 1: # if max([k[pos] for k in formatArray]) == 0 or 1 == 1:
self.setFormat(pos, 1, self.setFormat(pos, 1,
self.style.format(State.MARKUP)) self.style.format(State.MARKUP))
self.setFormat(pos + 1, len(r.cap(0)) - 1, self.setFormat(pos + 1, len(r.cap(0)) - 1,
@ -247,29 +252,29 @@ class t2tHighlighter (basicHighlighter):
if r.pos(2) > 0: if r.pos(2) > 0:
_f = QTextCharFormat(self.style.format(State.LINKS)) _f = QTextCharFormat(self.style.format(State.LINKS))
_f.setForeground(QBrush(_f.foreground() _f.setForeground(QBrush(_f.foreground()
.color().lighter())) .color().lighter()))
_f.setFontUnderline(True) _f.setFontUnderline(True)
self.setFormat(r.pos(2), len(r.cap(2)), _f) self.setFormat(r.pos(2), len(r.cap(2)), _f)
links.append([pos, len(r.cap(0))]) # To remember for the next highlighter (single links) links.append([pos, len(r.cap(0))]) # To remember for the next highlighter (single links)
pos = r.indexIn(text, pos + 1) pos = r.indexIn(text, pos + 1)
# Links like www.theologeek.ch, http://www.fsf.org, ... # Links like www.theologeek.ch, http://www.fsf.org, ...
# FIXME: - "http://adresse et http://adresse" is detected also as italic # FIXME: - "http://adresse et http://adresse" is detected also as italic
# - some error, like "http://adress.htm." also color the final "." # - some error, like "http://adress.htm." also color the final "."
# - also: adresse@email.com, ftp://, www2, www3, etc. # - also: adresse@email.com, ftp://, www2, www3, etc.
# - But for now, does the job # - But for now, does the job
r = QRegExp(r'http://[^\s]*|www\.[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+[^\s]*') r = QRegExp(r'http://[^\s]*|www\.[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+[^\s]*')
#r.setMinimal(True) # r.setMinimal(True)
pos = r.indexIn(text) pos = r.indexIn(text)
while pos >= 0: while pos >= 0:
for k in links: for k in links:
#print pos, k[0], k[1] # print pos, k[0], k[1]
if pos > k[0] and pos < k[0] + k[1]: # already highlighted if k[0] < pos < k[0] + k[1]: # already highlighted
break break
else: else:
self.setFormat(pos, len(r.cap(0)), self.style.format(State.LINKS)) self.setFormat(pos, len(r.cap(0)), self.style.format(State.LINKS))
pos = r.indexIn(text, pos + 1) pos = r.indexIn(text, pos + 1)
# Bold, Italic, Underline, Code, Tagged, Strikeout # Bold, Italic, Underline, Code, Tagged, Strikeout
@ -288,40 +293,39 @@ class t2tHighlighter (basicHighlighter):
self.setFormat(pos, len(r.cap(0)), self.setFormat(pos, len(r.cap(0)),
self.style.format(State.MACRO)) self.style.format(State.MACRO))
pos = r.indexIn(text, pos + 1) pos = r.indexIn(text, pos + 1)
# Highlighted word (for search) # Highlighted word (for search)
if self.editor.highlightWord: if self.editor.highlightWord:
if self.editor.highligtCS and self.editor.highlightWord in text or \ if self.editor.highligtCS and self.editor.highlightWord in text or \
not self.editor.highlightCs and self.editor.highlightWord.lower() in text.lower(): not self.editor.highlightCs and self.editor.highlightWord.lower() in text.lower():
#if self.editor.highlightCS: # if self.editor.highlightCS:
#s = self.editor.highlightWord # s = self.editor.highlightWord
#else: # else:
#s = self.editor.highlightWord.toLower() # s = self.editor.highlightWord.toLower()
#print(s) # print(s)
p = text.indexOf(self.editor.highlightWord, cs=self.editor.highlightCS) p = text.indexOf(self.editor.highlightWord, cs=self.editor.highlightCS)
while p >= 0: while p >= 0:
self.setFormat(p, len(self.editor.highlightWord), self.setFormat(p, len(self.editor.highlightWord),
self.style.makeFormat(preset="higlighted", base=self.format(p))) self.style.makeFormat(preset="higlighted", base=self.format(p)))
p = text.indexOf(self.editor.highlightWord, p + 1, cs=self.editor.highlightCS) p = text.indexOf(self.editor.highlightWord, p + 1, cs=self.editor.highlightCS)
### Highlight Selection
### TODO: way to slow, find another way.
##sel = self.editor.textCursor().selectedText()
##if len(sel) > 5: self.keywordRules.append((QRegExp(sel), "selected"))
## Do keyword formatting ### Highlight Selection
#for expression, style in self.keywordRules: ### TODO: way to slow, find another way.
#expression.setMinimal( True ) ##sel = self.editor.textCursor().selectedText()
#index = expression.indexIn(text, 0) ##if len(sel) > 5: self.keywordRules.append((QRegExp(sel), "selected"))
## Do keyword formatting
# for expression, style in self.keywordRules:
# expression.setMinimal( True )
# index = expression.indexIn(text, 0)
## There might be more than one on the same line
# while index >= 0:
# length = expression.cap(0).length()
# f = self.formats(preset=style, base=self.formats(index))
# self.setFormat(index, length, f)
# index = expression.indexIn(text, index + length)
## There might be more than one on the same line
#while index >= 0:
#length = expression.cap(0).length()
#f = self.formats(preset=style, base=self.formats(index))
#self.setFormat(index, length, f)
#index = expression.indexIn(text, index + length)
basicHighlighter.highlightBlockAfter(self, text) basicHighlighter.highlightBlockAfter(self, text)
def identifyBlock(self, block): def identifyBlock(self, block):
@ -333,20 +337,20 @@ class t2tHighlighter (basicHighlighter):
# Header Lines # Header Lines
# No header line here # No header line here
#if block.blockNumber() == 0: # if block.blockNumber() == 0:
#block.setUserState(State.HEADER_LINE) # block.setUserState(State.HEADER_LINE)
#return # return
#elif block.blockNumber() in [1, 2] and \ # elif block.blockNumber() in [1, 2] and \
#self.document().findBlockByNumber(0).text(): # self.document().findBlockByNumber(0).text():
#block.setUserState(State.HEADER_LINE) # block.setUserState(State.HEADER_LINE)
#return # return
state = 0 state = 0
inList = False inList = False
blankLinesBefore = 0 blankLinesBefore = 0
#if text.contains(QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$')): # if text.contains(QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$')):
if QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$').indexIn(text) != -1: if QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$').indexIn(text) != -1:
state = State.LIST_BEGINS state = State.LIST_BEGINS
# List stuff # List stuff
@ -354,12 +358,12 @@ class t2tHighlighter (basicHighlighter):
inList = True inList = True
# listLevel and leadingSpaces # listLevel and leadingSpaces
#FIXME: not behaving exactly correctly... # FIXME: not behaving exactly correctly...
lastData = blockUserData.getUserData(block.previous()) lastData = blockUserData.getUserData(block.previous())
if state == State.LIST_BEGINS: if state == State.LIST_BEGINS:
leadingSpaces = QRegExp(r'[-+:]').indexIn(text, 0) leadingSpaces = QRegExp(r'[-+:]').indexIn(text, 0)
data.setLeadingSpaces(leadingSpaces) data.setLeadingSpaces(leadingSpaces)
data.setListSymbol(text[leadingSpaces]) data.setListSymbol(text[leadingSpaces])
if self.isList(block.previous()): if self.isList(block.previous()):
# The last block was also a list. # The last block was also a list.
@ -380,13 +384,13 @@ class t2tHighlighter (basicHighlighter):
# Blank lines before (two = end of list) # Blank lines before (two = end of list)
blankLinesBefore = self.getBlankLines(block.previous()) blankLinesBefore = self.getBlankLines(block.previous())
if not QRegExp(r'^\s*$').indexIn(block.previous().text()) != -1 and \ if not QRegExp(r'^\s*$').indexIn(block.previous().text()) != -1 and \
not blockUserData.getUserState(block.previous()) in [State.COMMENT_LINE, not blockUserData.getUserState(block.previous()) in [State.COMMENT_LINE,
State.COMMENT_AREA, State.COMMENT_AREA_BEGINS, State.COMMENT_AREA, State.COMMENT_AREA_BEGINS,
State.COMMENT_AREA_ENDS]: State.COMMENT_AREA_ENDS]:
blankLinesBefore = 0 blankLinesBefore = 0
elif not blockUserData.getUserState(block.previous()) in \ elif not blockUserData.getUserState(block.previous()) in \
[State.COMMENT_LINE, State.COMMENT_AREA, [State.COMMENT_LINE, State.COMMENT_AREA,
State.COMMENT_AREA_BEGINS, State.COMMENT_AREA_ENDS]: State.COMMENT_AREA_BEGINS, State.COMMENT_AREA_ENDS]:
blankLinesBefore += 1 blankLinesBefore += 1
if blankLinesBefore == 2: if blankLinesBefore == 2:
# End of list. # End of list.
@ -401,7 +405,7 @@ class t2tHighlighter (basicHighlighter):
(State.CODE_AREA_BEGINS, State.CODE_AREA, State.CODE_AREA_ENDS, "^```\s*$"), (State.CODE_AREA_BEGINS, State.CODE_AREA, State.CODE_AREA_ENDS, "^```\s*$"),
(State.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS, "^\"\"\"\s*$"), (State.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS, "^\"\"\"\s*$"),
(State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS, '^\'\'\'\s*$'), (State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS, '^\'\'\'\s*$'),
]: ]:
if QRegExp(marker).indexIn(text) != -1: if QRegExp(marker).indexIn(text) != -1:
if blockUserData.getUserState(block.previous()) in [begins, middle]: if blockUserData.getUserState(block.previous()) in [begins, middle]:
@ -423,8 +427,8 @@ class t2tHighlighter (basicHighlighter):
break break
if state in [State.BLOCKQUOTE_LINE, State.LIST_ENDS]: if state in [State.BLOCKQUOTE_LINE, State.LIST_ENDS]:
#FIXME: doesn't work exactly. Closes only the current level, not # FIXME: doesn't work exactly. Closes only the current level, not
#FIXME: the whole list. # FIXME: the whole list.
inList = False inList = False
if inList and not state == State.LIST_BEGINS: if inList and not state == State.LIST_BEGINS:
@ -439,8 +443,8 @@ class t2tHighlighter (basicHighlighter):
""" """
Formats the block according to its state. Formats the block according to its state.
""" """
#TODO: Use QTextDocument format presets, and QTextBlock's # TODO: Use QTextDocument format presets, and QTextBlock's
#TODO: blockFormatIndex. And move that in t2tHighlighterStyle. # TODO: blockFormatIndex. And move that in t2tHighlighterStyle.
state = block.userState() state = block.userState()
blockFormat = QTextBlockFormat() blockFormat = QTextBlockFormat()
@ -451,7 +455,7 @@ class t2tHighlighter (basicHighlighter):
QTextCursor(block).setBlockFormat(blockFormat) QTextCursor(block).setBlockFormat(blockFormat)
def getBlankLines(self, block): def getBlankLines(self, block):
"Returns if there is a blank line before in the list." """Returns if there is a blank line before in the list."""
state = block.userState() state = block.userState()
if state >= 200: if state >= 200:
return 1 return 1
@ -459,9 +463,9 @@ class t2tHighlighter (basicHighlighter):
return 0 return 0
def isList(self, block): def isList(self, block):
"Returns TRUE if the block is in a list." """Returns TRUE if the block is in a list."""
if block.userState() == State.LIST_BEGINS or\ if block.userState() == State.LIST_BEGINS or \
block.userState() >= 100: block.userState() >= 100:
return True return True
def setStyle(self, style="Default"): def setStyle(self, style="Default"):
@ -481,7 +485,7 @@ class t2tHighlighter (basicHighlighter):
self.inDocRules = [] self.inDocRules = []
t = self.thisDocument.toPlainText() t = self.thisDocument.toPlainText()
# Get all conf files # Get all conf files
confs = [] confs = []
lines = t.split("\n") lines = t.split("\n")
@ -489,26 +493,26 @@ class t2tHighlighter (basicHighlighter):
r = QRegExp(r'^%!includeconf:\s*([^\s]*)\s*') r = QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')
if r.indexIn(l) != -1: if r.indexIn(l) != -1:
confs.append(r.cap(1)) confs.append(r.cap(1))
# Try to load conf files # Try to load conf files
for c in confs: for c in confs:
try: try:
import codecs import codecs
f = self.editor.fileWidget.file f = self.editor.fileWidget.file
d = QDir.cleanPath(QFileInfo(f).absoluteDir().absolutePath()+"/"+c) d = QDir.cleanPath(QFileInfo(f).absoluteDir().absolutePath() + "/" + c)
file = codecs.open(d, 'r', "utf-8") file = codecs.open(d, 'r', "utf-8")
except: except:
print(("Error: cannot open {}.".format(c))) print(("Error: cannot open {}.".format(c)))
continue continue
# We add the content to the current lines of the current document # We add the content to the current lines of the current document
lines += file.readlines() #lines.extend(file.readlines()) lines += file.readlines() # lines.extend(file.readlines())
#b = self.thisDocument.firstBlock() # b = self.thisDocument.firstBlock()
lastColor = "" lastColor = ""
#while b.isValid(): # while b.isValid():
for l in lines: for l in lines:
text = l #b.text() text = l # b.text()
r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*(\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\")') r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*(\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\")')
if r.indexIn(text) != -1: if r.indexIn(text) != -1:
rule = r.cap(1)[1:-1] rule = r.cap(1)[1:-1]
@ -517,27 +521,27 @@ class t2tHighlighter (basicHighlighter):
self.inDocRules.append((str(rule), lastColor)) self.inDocRules.append((str(rule), lastColor))
# Check if previous block is a comment like it should # Check if previous block is a comment like it should
else: else:
previousText = lines[lines.indexOf(l)-1] #b.previous().text() previousText = lines[lines.indexOf(l) - 1] # b.previous().text()
r = QRegExp(r'^%.*\s\((.*)\)') r = QRegExp(r'^%.*\s\((.*)\)')
if r.indexIn(previousText) != -1: if r.indexIn(previousText) != -1:
lastColor = r.cap(1) lastColor = r.cap(1)
self.inDocRules.append((str(rule), lastColor)) self.inDocRules.append((str(rule), lastColor))
else: else:
lastColor = "" lastColor = ""
#b = b.next() # b = b.next()
if oldRules != self.inDocRules: if oldRules != self.inDocRules:
#Rules have changed, we need to rehighlight # Rules have changed, we need to rehighlight
#print("Rules have changed.", len(self.inDocRules)) # print("Rules have changed.", len(self.inDocRules))
#self.rehighlight() # Doesn't work (seg fault), why? # self.rehighlight() # Doesn't work (seg fault), why?
pass pass
#b = self.thisDocument.firstBlock() # b = self.thisDocument.firstBlock()
#while b.isValid(): # while b.isValid():
#for (r, c) in self.inDocRules: # for (r, c) in self.inDocRules:
#r = QRegExp(r) # r = QRegExp(r)
#pos = r.indexIn(b.text()) # pos = r.indexIn(b.text())
#if pos >= 0: # if pos >= 0:
#print("rehighlighting:", b.text()) # print("rehighlighting:", b.text())
#self.rehighlightBlock(b) # self.rehighlightBlock(b)
#break # break
#b = b.next() # b = b.next()

View file

@ -1,14 +1,17 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
from qt import *
from ui.editors.t2tFunctions import *
from ui.editors.blockUserData import blockUserData
#TODO: creates a general way to generate styles (and edit/import/export) # TODO: creates a general way to generate styles (and edit/import/export)
from PyQt5.QtCore import QRegExp, Qt
from PyQt5.QtGui import QFont, QTextBlockFormat, QColor, QFontMetrics, QTextCharFormat
from PyQt5.QtWidgets import qApp
from manuskript.ui.editors.blockUserData import blockUserData
from manuskript.ui.editors.t2tFunctions import State
class t2tHighlighterStyle (): class t2tHighlighterStyle():
"""Style for the Syntax highlighter for the Txt2Tags language. """Style for the Syntax highlighter for the Txt2Tags language.
""" """
@ -21,15 +24,15 @@ class t2tHighlighterStyle ():
self._defaultCharFormat = charFormat self._defaultCharFormat = charFormat
# Defaults # Defaults
#self.defaultFontPointSize = self.editor.defaultFontPointSize # self.defaultFontPointSize = self.editor.defaultFontPointSize
self.defaultFontFamily = qApp.font().family() self.defaultFontFamily = qApp.font().family()
self.tabStopWidth = 40 self.tabStopWidth = 40
self.setupEditor() self.setupEditor()
if self.name == "Default": if self.name == "Default":
self.initDefaults() self.initDefaults()
#Temporary other theme # Temporary other theme
elif self.name == "Monospace": elif self.name == "Monospace":
self.defaultFontFamily = "Monospace" self.defaultFontFamily = "Monospace"
self.initDefaults() self.initDefaults()
@ -46,42 +49,42 @@ class t2tHighlighterStyle ():
def initDefaults(self): def initDefaults(self):
self.styles = {} self.styles = {}
for i in [State.CODE_AREA, for i in [State.CODE_AREA,
State.CODE_LINE, State.CODE_LINE,
State.COMMENT_AREA, State.COMMENT_AREA,
State.COMMENT_LINE, State.COMMENT_LINE,
State.SETTINGS_LINE, State.SETTINGS_LINE,
State.BLOCKQUOTE_LINE, State.BLOCKQUOTE_LINE,
State.RAW_AREA, State.RAW_AREA,
State.RAW_LINE, State.RAW_LINE,
State.TAGGED_AREA, State.TAGGED_AREA,
State.TAGGED_LINE, State.TAGGED_LINE,
State.TITLE_1, State.TITLE_1,
State.TITLE_2, State.TITLE_2,
State.TITLE_3, State.TITLE_3,
State.TITLE_4, State.TITLE_4,
State.TITLE_5, State.TITLE_5,
State.NUMBERED_TITLE_1, State.NUMBERED_TITLE_1,
State.NUMBERED_TITLE_2, State.NUMBERED_TITLE_2,
State.NUMBERED_TITLE_3, State.NUMBERED_TITLE_3,
State.NUMBERED_TITLE_4, State.NUMBERED_TITLE_4,
State.NUMBERED_TITLE_5, State.NUMBERED_TITLE_5,
State.TABLE_HEADER, State.TABLE_HEADER,
State.TABLE_LINE, State.TABLE_LINE,
State.HORIZONTAL_LINE, State.HORIZONTAL_LINE,
State.MARKUP, State.MARKUP,
State.LIST_BULLET, State.LIST_BULLET,
State.LIST_BULLET_ENDS, State.LIST_BULLET_ENDS,
State.LINKS, State.LINKS,
State.MACRO, State.MACRO,
State.DEFAULT, State.DEFAULT,
State.HEADER_LINE]: State.HEADER_LINE]:
self.styles[i] = self.makeFormat(preset=i) self.styles[i] = self.makeFormat(preset=i)
def format(self, state): def format(self, state):
return self.styles[state] return self.styles[state]
def beautifyFormat(self, base, beautifiers): def beautifyFormat(self, base, beautifiers):
"Apply beautifiers given in beautifiers array to format" """Apply beautifiers given in beautifiers array to format"""
if max(beautifiers) == 2: if max(beautifiers) == 2:
return self.makeFormat(preset=State.MARKUP, base=base) return self.makeFormat(preset=State.MARKUP, base=base)
else: else:
@ -100,21 +103,21 @@ class t2tHighlighterStyle ():
return base return base
def formatBlock(self, block, state): def formatBlock(self, block, state):
"Apply transformation to given block." """Apply transformation to given block."""
blockFormat = QTextBlockFormat() blockFormat = QTextBlockFormat()
if state == State.BLOCKQUOTE_LINE: if state == State.BLOCKQUOTE_LINE:
# Number of tabs # Number of tabs
n = block.text().indexOf(QRegExp(r'[^\t]'), 0) n = block.text().indexOf(QRegExp(r'[^\t]'), 0)
blockFormat.setIndent(0) blockFormat.setIndent(0)
blockFormat.setTextIndent(-self.tabStopWidth * n) blockFormat.setTextIndent(-self.tabStopWidth * n)
blockFormat.setLeftMargin(self.tabStopWidth * n) blockFormat.setLeftMargin(self.tabStopWidth * n)
#blockFormat.setRightMargin(self.editor.contentsRect().width() # blockFormat.setRightMargin(self.editor.contentsRect().width()
# - self.editor.lineNumberAreaWidth() # - self.editor.lineNumberAreaWidth()
# - fm.width("X") * self.editor.LimitLine # - fm.width("X") * self.editor.LimitLine
#+ self.editor.tabStopWidth()) # + self.editor.tabStopWidth())
blockFormat.setAlignment(Qt.AlignJustify) blockFormat.setAlignment(Qt.AlignJustify)
if self.name == "Default" : if self.name == "Default":
blockFormat.setTopMargin(5) blockFormat.setTopMargin(5)
blockFormat.setBottomMargin(5) blockFormat.setBottomMargin(5)
elif state == State.HEADER_LINE: elif state == State.HEADER_LINE:
@ -126,32 +129,33 @@ class t2tHighlighterStyle ():
else: else:
blockFormat.setBackground(QColor("#EEEEFA")) blockFormat.setBackground(QColor("#EEEEFA"))
n = blockUserData.getUserData(block).leadingSpaces() + 1 n = blockUserData.getUserData(block).leadingSpaces() + 1
f = QFontMetrics(QFont(self.defaultFontFamily, f = QFontMetrics(QFont(self.defaultFontFamily,
self._defaultCharFormat.font().pointSize())) self._defaultCharFormat.font().pointSize()))
fm = f.width(" " * n + fm = f.width(" " * n +
blockUserData.getUserData(block).listSymbol()) blockUserData.getUserData(block).listSymbol())
blockFormat.setTextIndent(-fm) blockFormat.setTextIndent(-fm)
blockFormat.setLeftMargin(fm) blockFormat.setLeftMargin(fm)
if blockUserData.getUserState(block) == State.LIST_BEGINS and\ if blockUserData.getUserState(block) == State.LIST_BEGINS and \
self.name == "Default": self.name == "Default":
blockFormat.setTopMargin(5) blockFormat.setTopMargin(5)
return blockFormat return blockFormat
def makeFormat(self, color='', style='', size='', base='', fixedPitch='', def makeFormat(self, color='', style='', size='', base='', fixedPitch='',
preset='', title_level='', bgcolor=''): preset='', title_level='', bgcolor=''):
""" """
Returns a QTextCharFormat with the given attributes, using presets. Returns a QTextCharFormat with the given attributes, using presets.
""" """
_color = QColor() _color = QColor()
#_format = QTextCharFormat() # _format = QTextCharFormat()
#_format.setFont(self.editor.font()) # _format.setFont(self.editor.font())
#size = _format.fontPointSize() # size = _format.fontPointSize()
_format = QTextCharFormat(self._defaultCharFormat) _format = QTextCharFormat(self._defaultCharFormat)
# Base # Base
if base: _format = base if base:
_format = base
# Presets # Presets
if preset in [State.CODE_AREA, State.CODE_LINE, "code"]: if preset in [State.CODE_AREA, State.CODE_LINE, "code"]:
@ -165,15 +169,15 @@ class t2tHighlighterStyle ():
color = "darkGreen" color = "darkGreen"
if preset in [State.SETTINGS_LINE, "setting", State.MACRO]: if preset in [State.SETTINGS_LINE, "setting", State.MACRO]:
#style = "italic" # style = "italic"
color = "magenta" color = "magenta"
if preset in [State.BLOCKQUOTE_LINE]: if preset in [State.BLOCKQUOTE_LINE]:
color = "red" color = "red"
if preset in [State.HEADER_LINE]: if preset in [State.HEADER_LINE]:
size = size * 2 size *= 2
#print size # print size
if preset in [State.RAW_AREA, State.RAW_LINE, "raw"]: if preset in [State.RAW_AREA, State.RAW_LINE, "raw"]:
color = "blue" color = "blue"
@ -198,7 +202,7 @@ class t2tHighlighterStyle ():
color = "red" color = "red"
style = "bold" style = "bold"
fixedPitch = True fixedPitch = True
if preset == State.LIST_BULLET_ENDS: if preset == State.LIST_BULLET_ENDS:
color = "darkGray" color = "darkGray"
fixedPitch = True fixedPitch = True
@ -211,18 +215,18 @@ class t2tHighlighterStyle ():
fixedPitch = True fixedPitch = True
if preset == State.LINKS: if preset == State.LINKS:
color="blue" color = "blue"
#style="underline" # style="underline"
if preset == "selected": if preset == "selected":
_format.setBackground(QColor("yellow")) _format.setBackground(QColor("yellow"))
if preset == "higlighted": if preset == "higlighted":
bgcolor = "yellow" bgcolor = "yellow"
#if preset == State.DEFAULT: # if preset == State.DEFAULT:
#size = self.defaultFontPointSize # size = self.defaultFontPointSize
#_format.setFontFamily(self.defaultFontFamily) # _format.setFontFamily(self.defaultFontFamily)
# Manual formatting # Manual formatting
if color: if color:
@ -244,5 +248,5 @@ class t2tHighlighterStyle ():
_format.setFontPointSize(size) _format.setFontPointSize(size)
if fixedPitch: if fixedPitch:
_format.setFontFixedPitch(True) _format.setFontFixedPitch(True)
return _format return _format

View file

@ -1,30 +1,30 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtGui import QIcon
from qt import * from PyQt5.QtWidgets import QWidget, QAction
from enums import *
from models.outlineModel import * from manuskript.enums import Outline
from ui.editors.textFormat_ui import * from manuskript.models.outlineModel import outlineModel
from functions import * from manuskript.ui.editors.textFormat_ui import Ui_textFormat
class textFormat(QWidget, Ui_textFormat): class textFormat(QWidget, Ui_textFormat):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self._textEdit = None self._textEdit = None
formats = { formats = {
"Bold": [self.btnBold, "format-text-bold", self.tr("CTRL+B")], "Bold": [self.btnBold, "format-text-bold", self.tr("CTRL+B")],
"Italic": [self.btnItalic, "format-text-italic", self.tr("CTRL+I")], "Italic": [self.btnItalic, "format-text-italic", self.tr("CTRL+I")],
"Underline": [self.btnUnderlined, "format-text-underline", self.tr("CTRL+U")], "Underline": [self.btnUnderlined, "format-text-underline", self.tr("CTRL+U")],
"Clear": [self.btnClear, "edit-clear", self.tr("CTRL+P")], "Clear": [self.btnClear, "edit-clear", self.tr("CTRL+P")],
"Left": [self.btnLeft, "format-justify-left", self.tr("CTRL+L")], "Left": [self.btnLeft, "format-justify-left", self.tr("CTRL+L")],
"Center": [self.btnCenter, "format-justify-center", self.tr("CTRL+E")], "Center": [self.btnCenter, "format-justify-center", self.tr("CTRL+E")],
"Right": [self.btnRight, "format-justify-right", self.tr("CTRL+R")], "Right": [self.btnRight, "format-justify-right", self.tr("CTRL+R")],
"Justify": [self.btnJustify, "format-justify-fill", self.tr("CTRL+J")], "Justify": [self.btnJustify, "format-justify-fill", self.tr("CTRL+J")],
} }
for f in formats: for f in formats:
val = formats[f] val = formats[f]
a = QAction(QIcon.fromTheme(val[1]), f, self) a = QAction(QIcon.fromTheme(val[1]), f, self)
@ -32,41 +32,40 @@ class textFormat(QWidget, Ui_textFormat):
a.setToolTip("Format {} ({})".format(f, val[2])) a.setToolTip("Format {} ({})".format(f, val[2]))
a.triggered.connect(self.setFormat) a.triggered.connect(self.setFormat)
val[0].setDefaultAction(a) val[0].setDefaultAction(a)
def setTextEdit(self, textEdit): def setTextEdit(self, textEdit):
self._textEdit = textEdit self._textEdit = textEdit
def updateFromIndex(self, index): def updateFromIndex(self, index):
if not index.isValid(): if not index.isValid():
self.setVisible(False) self.setVisible(False)
return return
if type(index.model()) != outlineModel: if type(index.model()) != outlineModel:
self.setVisible(False) self.setVisible(False)
return return
if index.column() not in [Outline.text.value, Outline.notes.value]: if index.column() not in [Outline.text.value, Outline.notes.value]:
self.setVisible(False) self.setVisible(False)
return return
self.setVisible(True) self.setVisible(True)
item = index.internalPointer() item = index.internalPointer()
self.align.setVisible(True) self.align.setVisible(True)
self.format.setVisible(True) self.format.setVisible(True)
if item.isFolder(): if item.isFolder():
self.setVisible(False) self.setVisible(False)
return return
elif item.isText(): elif item.isText():
self.align.setVisible(False) self.align.setVisible(False)
self.format.setVisible(False) self.format.setVisible(False)
elif item.isT2T(): elif item.isT2T():
self.align.setVisible(False) self.align.setVisible(False)
def setFormat(self): def setFormat(self):
act = self.sender() act = self.sender()
if self._textEdit: if self._textEdit:
self._textEdit.applyFormat(act.text()) self._textEdit.applyFormat(act.text())

View file

@ -1,27 +1,30 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
# Lots of stuff from here comes from the excellet focuswriter. # Lots of stuff from here comes from the excellet focuswriter.
import os
from qt import *
from enums import *
from functions import *
from ui.views.textEditView import *
import settings
import re import re
from PyQt5.QtCore import QSettings, QRect, QSize, Qt, QPoint, QFile, QIODevice, QTextStream
from PyQt5.QtGui import QPixmap, QPainter, QColor, QBrush, QImage, QTextBlockFormat, QTextCharFormat, QFont, qGray
from PyQt5.QtWidgets import qApp, QFrame
from manuskript.functions import allPaths, appPath
from manuskript.ui.views.textEditView import textEditView
def loadThemeDatas(themeFile): def loadThemeDatas(themeFile):
settings = QSettings(themeFile, QSettings.IniFormat) settings = QSettings(themeFile, QSettings.IniFormat)
_themeData = {} _themeData = {}
# Theme name # Theme name
_themeData["Name"] = getThemeName(themeFile) _themeData["Name"] = getThemeName(themeFile)
# Window Background # Window Background
loadThemeSetting(_themeData, settings, "Background/Color", "#000000") loadThemeSetting(_themeData, settings, "Background/Color", "#000000")
loadThemeSetting(_themeData, settings, "Background/ImageFile", "") loadThemeSetting(_themeData, settings, "Background/ImageFile", "")
loadThemeSetting(_themeData, settings, "Background/Type", 0) loadThemeSetting(_themeData, settings, "Background/Type", 0)
# Text Background # Text Background
loadThemeSetting(_themeData, settings, "Foreground/Color", "#ffffff") loadThemeSetting(_themeData, settings, "Foreground/Color", "#ffffff")
loadThemeSetting(_themeData, settings, "Foreground/Opacity", 50) loadThemeSetting(_themeData, settings, "Foreground/Opacity", 50)
@ -30,43 +33,45 @@ def loadThemeDatas(themeFile):
loadThemeSetting(_themeData, settings, "Foreground/Position", 1) loadThemeSetting(_themeData, settings, "Foreground/Position", 1)
loadThemeSetting(_themeData, settings, "Foreground/Rounding", 5) loadThemeSetting(_themeData, settings, "Foreground/Rounding", 5)
loadThemeSetting(_themeData, settings, "Foreground/Width", 700) loadThemeSetting(_themeData, settings, "Foreground/Width", 700)
# Text Options # Text Options
loadThemeSetting(_themeData, settings, "Text/Color", "#ffffff") loadThemeSetting(_themeData, settings, "Text/Color", "#ffffff")
loadThemeSetting(_themeData, settings, "Text/Font", qApp.font().toString()) loadThemeSetting(_themeData, settings, "Text/Font", qApp.font().toString())
loadThemeSetting(_themeData, settings, "Text/Misspelled", "#ff0000") loadThemeSetting(_themeData, settings, "Text/Misspelled", "#ff0000")
# Paragraph Options # Paragraph Options
loadThemeSetting(_themeData, settings, "Spacings/IndendFirstLine", False) loadThemeSetting(_themeData, settings, "Spacings/IndendFirstLine", False)
loadThemeSetting(_themeData, settings, "Spacings/LineSpacing", 100) loadThemeSetting(_themeData, settings, "Spacings/LineSpacing", 100)
loadThemeSetting(_themeData, settings, "Spacings/ParagraphAbove", 0) loadThemeSetting(_themeData, settings, "Spacings/ParagraphAbove", 0)
loadThemeSetting(_themeData, settings, "Spacings/ParagraphBelow", 0) loadThemeSetting(_themeData, settings, "Spacings/ParagraphBelow", 0)
loadThemeSetting(_themeData, settings, "Spacings/TabWidth", 48) loadThemeSetting(_themeData, settings, "Spacings/TabWidth", 48)
return _themeData return _themeData
def loadThemeSetting(datas, settings, key, default): def loadThemeSetting(datas, settings, key, default):
if settings.contains(key): if settings.contains(key):
datas[key] = type(default)(settings.value(key)) datas[key] = type(default)(settings.value(key))
else: else:
datas[key] = default datas[key] = default
def getThemeName(theme): def getThemeName(theme):
settings = QSettings(theme, QSettings.IniFormat) settings = QSettings(theme, QSettings.IniFormat)
if settings.contains("Name"): if settings.contains("Name"):
return settings.value("Name") return settings.value("Name")
else: else:
return os.path.splitext(os.path.split(theme)[1])[0] return os.path.splitext(os.path.split(theme)[1])[0]
def themeTextRect(themeDatas, screenRect): def themeTextRect(themeDatas, screenRect):
margin = themeDatas["Foreground/Margin"] margin = themeDatas["Foreground/Margin"]
x = 0 x = 0
y = margin y = margin
width = min(themeDatas["Foreground/Width"], screenRect.width() - 2 * margin) width = min(themeDatas["Foreground/Width"], screenRect.width() - 2 * margin)
height = screenRect.height() - 2 * margin height = screenRect.height() - 2 * margin
if themeDatas["Foreground/Position"] == 0: # Left if themeDatas["Foreground/Position"] == 0: # Left
x = margin x = margin
elif themeDatas["Foreground/Position"] == 1: # Center elif themeDatas["Foreground/Position"] == 1: # Center
@ -77,33 +82,35 @@ def themeTextRect(themeDatas, screenRect):
x = margin x = margin
width = screenRect.width() - 2 * margin width = screenRect.width() - 2 * margin
return QRect(x, y, width, height) return QRect(x, y, width, height)
def createThemePreview(theme, screenRect, size=QSize(200, 120)): def createThemePreview(theme, screenRect, size=QSize(200, 120)):
if type(theme) == str and os.path.exists(theme): if type(theme) == str and os.path.exists(theme):
# Theme is the path to an ini file # Theme is the path to an ini file
themeDatas = loadThemeDatas(theme) themeDatas = loadThemeDatas(theme)
else: else:
themeDatas = theme themeDatas = theme
pixmap = generateTheme(themeDatas, screenRect) pixmap = generateTheme(themeDatas, screenRect)
addThemePreviewText(pixmap, themeDatas, screenRect) addThemePreviewText(pixmap, themeDatas, screenRect)
px = QPixmap(pixmap).scaled(size, Qt.KeepAspectRatio) px = QPixmap(pixmap).scaled(size, Qt.KeepAspectRatio)
w = px.width() / 10 w = px.width() / 10
h = px.height() / 10 h = px.height() / 10
r = themeTextRect(themeDatas, screenRect) r = themeTextRect(themeDatas, screenRect)
painter = QPainter(px) painter = QPainter(px)
painter.drawPixmap(QRect(w, h, w*4, h*5), pixmap, QRect(r.topLeft() - QPoint(w/3, h/3), QSize(w*4, h*5))) painter.drawPixmap(QRect(w, h, w * 4, h * 5), pixmap,
QRect(r.topLeft() - QPoint(w / 3, h / 3), QSize(w * 4, h * 5)))
painter.setPen(Qt.white) painter.setPen(Qt.white)
painter.drawRect(QRect(w, h, w*4, h*5)) painter.drawRect(QRect(w, h, w * 4, h * 5))
painter.end() painter.end()
return px return px
def findThemePath(themeName): def findThemePath(themeName):
p = findFirstFile(re.escape("{}.theme".format(themeName)), "resources/themes") p = findFirstFile(re.escape("{}.theme".format(themeName)), "resources/themes")
if not p: if not p:
@ -111,9 +118,11 @@ def findThemePath(themeName):
else: else:
return p return p
def findBackground(filename): def findBackground(filename):
return findFirstFile(re.escape(filename), "resources/backgrounds") return findFirstFile(re.escape(filename), "resources/backgrounds")
def findFirstFile(regex, path="resources"): def findFirstFile(regex, path="resources"):
paths = allPaths(path) paths = allPaths(path)
for p in paths: for p in paths:
@ -121,35 +130,36 @@ def findFirstFile(regex, path="resources"):
for l in lst: for l in lst:
if re.match(regex, l): if re.match(regex, l):
return os.path.join(p, l) return os.path.join(p, l)
def generateTheme(themeDatas, screenRect): def generateTheme(themeDatas, screenRect):
# Window Background # Window Background
px = QPixmap(screenRect.size()) px = QPixmap(screenRect.size())
px.fill(QColor(themeDatas["Background/Color"])) px.fill(QColor(themeDatas["Background/Color"]))
painter = QPainter(px) painter = QPainter(px)
if themeDatas["Background/ImageFile"]: if themeDatas["Background/ImageFile"]:
path = findBackground(themeDatas["Background/ImageFile"]) path = findBackground(themeDatas["Background/ImageFile"])
_type = themeDatas["Background/Type"] _type = themeDatas["Background/Type"]
if path and _type > 0: if path and _type > 0:
if _type == 1: # Tiled if _type == 1: # Tiled
painter.fillRect(screenRect, QBrush(QImage(path))) painter.fillRect(screenRect, QBrush(QImage(path)))
else: else:
img = QImage(path) img = QImage(path)
scaled = img.size() scaled = img.size()
if _type == 3: # Stretched if _type == 3: # Stretched
scaled.scale(screenRect.size(), Qt.IgnoreAspectRatio) scaled.scale(screenRect.size(), Qt.IgnoreAspectRatio)
elif _type == 4: # Scaled elif _type == 4: # Scaled
scaled.scale(screenRect.size(), Qt.KeepAspectRatio) scaled.scale(screenRect.size(), Qt.KeepAspectRatio)
elif _type == 5: # Zoomed elif _type == 5: # Zoomed
scaled.scale(screenRect.size(), Qt.KeepAspectRatioByExpanding) scaled.scale(screenRect.size(), Qt.KeepAspectRatioByExpanding)
painter.drawImage((screenRect.width() - scaled.width()) / 2, (screenRect.height() - scaled.height()) / 2, img.scaled(scaled)) painter.drawImage((screenRect.width() - scaled.width()) / 2,
(screenRect.height() - scaled.height()) / 2, img.scaled(scaled))
# Text Background # Text Background
textRect = themeTextRect(themeDatas, screenRect) textRect = themeTextRect(themeDatas, screenRect)
painter.save() painter.save()
color = QColor(themeDatas["Foreground/Color"]) color = QColor(themeDatas["Foreground/Color"])
color.setAlpha(themeDatas["Foreground/Opacity"] * 255 / 100) color.setAlpha(themeDatas["Foreground/Opacity"] * 255 / 100)
@ -158,19 +168,20 @@ def generateTheme(themeDatas, screenRect):
r = themeDatas["Foreground/Rounding"] r = themeDatas["Foreground/Rounding"]
painter.drawRoundedRect(textRect, r, r) painter.drawRoundedRect(textRect, r, r)
painter.restore() painter.restore()
painter.end() painter.end()
return px return px
def themeEditorGeometry(themeDatas, textRect): def themeEditorGeometry(themeDatas, textRect):
padding = themeDatas["Foreground/Padding"] padding = themeDatas["Foreground/Padding"]
x = textRect.x() + padding x = textRect.x() + padding
y = textRect.y() + padding + themeDatas["Spacings/ParagraphAbove"] y = textRect.y() + padding + themeDatas["Spacings/ParagraphAbove"]
width = textRect.width() - 2 * padding width = textRect.width() - 2 * padding
height = textRect.height() - 2 * padding - themeDatas["Spacings/ParagraphAbove"] height = textRect.height() - 2 * padding - themeDatas["Spacings/ParagraphAbove"]
return x, y, width, height return x, y, width, height
def getThemeBlockFormat(themeDatas): def getThemeBlockFormat(themeDatas):
bf = QTextBlockFormat() bf = QTextBlockFormat()
bf.setLineHeight(themeDatas["Spacings/LineSpacing"], QTextBlockFormat.ProportionalHeight) bf.setLineHeight(themeDatas["Spacings/LineSpacing"], QTextBlockFormat.ProportionalHeight)
@ -178,51 +189,51 @@ def getThemeBlockFormat(themeDatas):
bf.setTopMargin(themeDatas["Spacings/ParagraphAbove"]) bf.setTopMargin(themeDatas["Spacings/ParagraphAbove"])
bf.setBottomMargin(themeDatas["Spacings/ParagraphBelow"]) bf.setBottomMargin(themeDatas["Spacings/ParagraphBelow"])
return bf return bf
def setThemeEditorDatas(editor, themeDatas, pixmap, screenRect): def setThemeEditorDatas(editor, themeDatas, pixmap, screenRect):
textRect = themeTextRect(themeDatas, screenRect) textRect = themeTextRect(themeDatas, screenRect)
x, y, width, height = themeEditorGeometry(themeDatas, textRect) x, y, width, height = themeEditorGeometry(themeDatas, textRect)
editor.setGeometry(x, y, width, height) editor.setGeometry(x, y, width, height)
#p = editor.palette() # p = editor.palette()
##p.setBrush(QPalette.Base, QBrush(pixmap.copy(x, y, width, height))) ##p.setBrush(QPalette.Base, QBrush(pixmap.copy(x, y, width, height)))
#p.setBrush(QPalette.Base, QColor(Qt.transparent)) # p.setBrush(QPalette.Base, QColor(Qt.transparent))
#p.setColor(QPalette.Text, QColor(themeDatas["Text/Color"])) # p.setColor(QPalette.Text, QColor(themeDatas["Text/Color"]))
#p.setColor(QPalette.Highlight, QColor(themeDatas["Text/Color"])) # p.setColor(QPalette.Highlight, QColor(themeDatas["Text/Color"]))
#p.setColor(QPalette.HighlightedText, Qt.black if qGray(QColor(themeDatas["Text/Color"]).rgb()) > 127 else Qt.white) # p.setColor(QPalette.HighlightedText, Qt.black if qGray(QColor(themeDatas["Text/Color"]).rgb()) > 127 else Qt.white)
#editor.setPalette(p) # editor.setPalette(p)
editor.setAttribute(Qt.WA_NoSystemBackground, True) editor.setAttribute(Qt.WA_NoSystemBackground, True)
bf = getThemeBlockFormat(themeDatas) bf = getThemeBlockFormat(themeDatas)
editor.setDefaultBlockFormat(bf) editor.setDefaultBlockFormat(bf)
#b = editor.document().firstBlock() # b = editor.document().firstBlock()
#cursor = editor.textCursor() # cursor = editor.textCursor()
#cursor.setBlockFormat(bf) # cursor.setBlockFormat(bf)
#while b.isValid(): # while b.isValid():
#bf2 = b.blockFormat() # bf2 = b.blockFormat()
#bf2.merge(bf) # bf2.merge(bf)
#cursor.setPosition(b.position()) # cursor.setPosition(b.position())
##cursor.setPosition(b.position(), QTextCursor.KeepAnchor) ##cursor.setPosition(b.position(), QTextCursor.KeepAnchor)
#cursor.setBlockFormat(bf2) # cursor.setBlockFormat(bf2)
#b = b.next() # b = b.next()
editor.setTabStopWidth(themeDatas["Spacings/TabWidth"]) editor.setTabStopWidth(themeDatas["Spacings/TabWidth"])
editor.document().setIndentWidth(themeDatas["Spacings/TabWidth"]) editor.document().setIndentWidth(themeDatas["Spacings/TabWidth"])
editor.highlighter.setMisspelledColor(QColor(themeDatas["Text/Misspelled"])) editor.highlighter.setMisspelledColor(QColor(themeDatas["Text/Misspelled"]))
cf = QTextCharFormat() cf = QTextCharFormat()
#f = QFont() # f = QFont()
#f.fromString(themeDatas["Text/Font"]) # f.fromString(themeDatas["Text/Font"])
#cf.setFont(f) # cf.setFont(f)
editor.highlighter.setDefaultCharFormat(cf) editor.highlighter.setDefaultCharFormat(cf)
f = QFont() f = QFont()
f.fromString(themeDatas["Text/Font"]) f.fromString(themeDatas["Text/Font"])
#editor.setFont(f) # editor.setFont(f)
editor.setStyleSheet(""" editor.setStyleSheet("""
background: transparent; background: transparent;
color: {foreground}; color: {foreground};
@ -236,15 +247,13 @@ def setThemeEditorDatas(editor, themeDatas, pixmap, screenRect):
fs="{}pt".format(str(f.pointSize())), fs="{}pt".format(str(f.pointSize())),
sc="black" if qGray(QColor(themeDatas["Text/Color"]).rgb()) > 127 else "white", sc="black" if qGray(QColor(themeDatas["Text/Color"]).rgb()) > 127 else "white",
sbc=themeDatas["Text/Color"], sbc=themeDatas["Text/Color"],
) )
) )
editor._fromTheme = True editor._fromTheme = True
def addThemePreviewText(pixmap, themeDatas, screenRect): def addThemePreviewText(pixmap, themeDatas, screenRect):
# Text # Text
previewText = textEditView(highlighting=True) previewText = textEditView(highlighting=True)
previewText.setFrameStyle(QFrame.NoFrame) previewText.setFrameStyle(QFrame.NoFrame)
@ -253,11 +262,11 @@ def addThemePreviewText(pixmap, themeDatas, screenRect):
f = QFile(appPath("resources/themes/preview.txt")) f = QFile(appPath("resources/themes/preview.txt"))
f.open(QIODevice.ReadOnly) f.open(QIODevice.ReadOnly)
previewText.setPlainText(QTextStream(f).readAll()) previewText.setPlainText(QTextStream(f).readAll())
setThemeEditorDatas(previewText, themeDatas, pixmap, screenRect) setThemeEditorDatas(previewText, themeDatas, pixmap, screenRect)
previewText.render(pixmap, previewText.pos()) previewText.render(pixmap, previewText.pos())
## Text Background ## Text Background
##themeDatas["Foreground/Color"] ##themeDatas["Foreground/Color"]
##themeDatas["Foreground/Opacity"] ##themeDatas["Foreground/Opacity"]
@ -266,15 +275,15 @@ def addThemePreviewText(pixmap, themeDatas, screenRect):
##themeDatas["Foreground/Position"] ##themeDatas["Foreground/Position"]
##themeDatas["Foreground/Rounding"] ##themeDatas["Foreground/Rounding"]
##themeDatas["Foreground/Width"] ##themeDatas["Foreground/Width"]
## Text Options ## Text Options
##themeDatas["Text/Color"] ##themeDatas["Text/Color"]
##themeDatas["Text/Font"] ##themeDatas["Text/Font"]
#themeDatas["Text/Misspelled"] # themeDatas["Text/Misspelled"]
## Paragraph Options ## Paragraph Options
##themeDatas["Spacings/IndendFirstLine"] ##themeDatas["Spacings/IndendFirstLine"]
##themeDatas["Spacings/LineSpacing"] ##themeDatas["Spacings/LineSpacing"]
##themeDatas["Spacings/ParagraphAbove"] ##themeDatas["Spacings/ParagraphAbove"]
##themeDatas["Spacings/ParagraphBelow"] ##themeDatas["Spacings/ParagraphBelow"]
##themeDatas["Spacings/TabWidth"] ##themeDatas["Spacings/TabWidth"]

View file

@ -1,20 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QLabel, QSizePolicy
from qt import *
class helpLabel(QLabel): class helpLabel(QLabel):
def __init__(self, text=None, parent=None): def __init__(self, text=None, parent=None):
QLabel.__init__(self, text, parent) QLabel.__init__(self, text, parent)
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
self.setStatusTip(self.tr("If you don't wanna see me, you can hide me in Help menu.")) self.setStatusTip(self.tr("If you don't wanna see me, you can hide me in Help menu."))
self.setStyleSheet(""" self.setStyleSheet("""
QLabel { QLabel {
background-color:lightYellow; background-color:lightYellow;
@ -23,4 +19,4 @@ class helpLabel(QLabel):
margin: 3px; margin: 3px;
padding:10px; padding:10px;
color:gray; color:gray;
}""") }""")

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 by: PyQt5 UI code generator 5.4.1 # Created by: PyQt5 UI code generator 5.4.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -40,8 +40,8 @@ class Ui_MainWindow(object):
self.page_4 = QtWidgets.QWidget() self.page_4 = QtWidgets.QWidget()
self.page_4.setObjectName("page_4") self.page_4.setObjectName("page_4")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.page_4) self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.page_4)
self.horizontalLayout_2.setSpacing(0)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setSpacing(0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.tabMain = QtWidgets.QTabWidget(self.page_4) self.tabMain = QtWidgets.QTabWidget(self.page_4)
self.tabMain.setDocumentMode(True) self.tabMain.setDocumentMode(True)
@ -352,7 +352,7 @@ class Ui_MainWindow(object):
self.btnRmPerso.setObjectName("btnRmPerso") self.btnRmPerso.setObjectName("btnRmPerso")
self.horizontalLayout_14.addWidget(self.btnRmPerso) self.horizontalLayout_14.addWidget(self.btnRmPerso)
self.txtPersosFilter = QtWidgets.QLineEdit(self.groupBox) self.txtPersosFilter = QtWidgets.QLineEdit(self.groupBox)
self.txtPersosFilter.setProperty("clearButtonEnabled", True) self.txtPersosFilter.setClearButtonEnabled(True)
self.txtPersosFilter.setObjectName("txtPersosFilter") self.txtPersosFilter.setObjectName("txtPersosFilter")
self.horizontalLayout_14.addWidget(self.txtPersosFilter) self.horizontalLayout_14.addWidget(self.txtPersosFilter)
self.verticalLayout_8.addLayout(self.horizontalLayout_14) self.verticalLayout_8.addLayout(self.horizontalLayout_14)
@ -536,7 +536,7 @@ class Ui_MainWindow(object):
self.btnRmPlot.setObjectName("btnRmPlot") self.btnRmPlot.setObjectName("btnRmPlot")
self.horizontalLayout_15.addWidget(self.btnRmPlot) self.horizontalLayout_15.addWidget(self.btnRmPlot)
self.txtPlotFilter = QtWidgets.QLineEdit(self.groupBox_2) self.txtPlotFilter = QtWidgets.QLineEdit(self.groupBox_2)
self.txtPlotFilter.setProperty("clearButtonEnabled", True) self.txtPlotFilter.setClearButtonEnabled(True)
self.txtPlotFilter.setObjectName("txtPlotFilter") self.txtPlotFilter.setObjectName("txtPlotFilter")
self.horizontalLayout_15.addWidget(self.txtPlotFilter) self.horizontalLayout_15.addWidget(self.txtPlotFilter)
self.verticalLayout_10.addLayout(self.horizontalLayout_15) self.verticalLayout_10.addLayout(self.horizontalLayout_15)
@ -732,7 +732,7 @@ class Ui_MainWindow(object):
self.btnRmWorld.setObjectName("btnRmWorld") self.btnRmWorld.setObjectName("btnRmWorld")
self.horizontalLayout_19.addWidget(self.btnRmWorld) self.horizontalLayout_19.addWidget(self.btnRmWorld)
self.txtWorldFilter = QtWidgets.QLineEdit(self.frame_3) self.txtWorldFilter = QtWidgets.QLineEdit(self.frame_3)
self.txtWorldFilter.setProperty("clearButtonEnabled", True) self.txtWorldFilter.setClearButtonEnabled(True)
self.txtWorldFilter.setObjectName("txtWorldFilter") self.txtWorldFilter.setObjectName("txtWorldFilter")
self.horizontalLayout_19.addWidget(self.txtWorldFilter) self.horizontalLayout_19.addWidget(self.txtWorldFilter)
self.btnWorldEmptyData = QtWidgets.QPushButton(self.frame_3) self.btnWorldEmptyData = QtWidgets.QPushButton(self.frame_3)
@ -799,7 +799,6 @@ class Ui_MainWindow(object):
self.layoutWidget = QtWidgets.QWidget(self.splitterOutlineH) self.layoutWidget = QtWidgets.QWidget(self.splitterOutlineH)
self.layoutWidget.setObjectName("layoutWidget") self.layoutWidget.setObjectName("layoutWidget")
self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget) self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget)
self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_14.setObjectName("verticalLayout_14") self.verticalLayout_14.setObjectName("verticalLayout_14")
self.splitterOutlineV = QtWidgets.QSplitter(self.layoutWidget) self.splitterOutlineV = QtWidgets.QSplitter(self.layoutWidget)
self.splitterOutlineV.setOrientation(QtCore.Qt.Vertical) self.splitterOutlineV.setOrientation(QtCore.Qt.Vertical)
@ -979,7 +978,7 @@ class Ui_MainWindow(object):
self.horizontalLayout_12.addWidget(self.stack) self.horizontalLayout_12.addWidget(self.stack)
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1145, 21)) self.menubar.setGeometry(QtCore.QRect(0, 0, 1145, 30))
self.menubar.setObjectName("menubar") self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile") self.menuFile.setObjectName("menuFile")
@ -1215,52 +1214,52 @@ class Ui_MainWindow(object):
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_20), _translate("MainWindow", "Outline")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_20), _translate("MainWindow", "Outline"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Labels")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Labels"))
self.tabMain.setTabText(self.tabMain.indexOf(self.lytTabDebug), _translate("MainWindow", "Debug")) self.tabMain.setTabText(self.tabMain.indexOf(self.lytTabDebug), _translate("MainWindow", "Debug"))
self.menuFile.setTitle(_translate("MainWindow", "File")) self.menuFile.setTitle(_translate("MainWindow", "Fi&le"))
self.menuRecents.setTitle(_translate("MainWindow", "Recents")) self.menuRecents.setTitle(_translate("MainWindow", "&Recents"))
self.menuMode.setTitle(_translate("MainWindow", "Mode")) self.menuMode.setTitle(_translate("MainWindow", "&Mode"))
self.menuHelp.setTitle(_translate("MainWindow", "Help")) self.menuHelp.setTitle(_translate("MainWindow", "Help"))
self.menuTools.setTitle(_translate("MainWindow", "Tools")) self.menuTools.setTitle(_translate("MainWindow", "Tools"))
self.menuEdit.setTitle(_translate("MainWindow", "Edit")) self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
self.menuView.setTitle(_translate("MainWindow", "View")) self.menuView.setTitle(_translate("MainWindow", "&View"))
self.dckCheatSheet.setWindowTitle(_translate("MainWindow", "Cheat sheet")) self.dckCheatSheet.setWindowTitle(_translate("MainWindow", "&Cheat sheet"))
self.dckSearch.setWindowTitle(_translate("MainWindow", "Search")) self.dckSearch.setWindowTitle(_translate("MainWindow", "Sea&rch"))
self.actOpen.setText(_translate("MainWindow", "Open")) self.actOpen.setText(_translate("MainWindow", "&Open"))
self.actOpen.setShortcut(_translate("MainWindow", "Ctrl+O")) self.actOpen.setShortcut(_translate("MainWindow", "Ctrl+O"))
self.actSave.setText(_translate("MainWindow", "Save")) self.actSave.setText(_translate("MainWindow", "&Save"))
self.actSave.setShortcut(_translate("MainWindow", "Ctrl+S")) self.actSave.setShortcut(_translate("MainWindow", "Ctrl+S"))
self.actSaveAs.setText(_translate("MainWindow", "Save as...")) self.actSaveAs.setText(_translate("MainWindow", "Sa&ve as..."))
self.actSaveAs.setShortcut(_translate("MainWindow", "Ctrl+Shift+S")) self.actSaveAs.setShortcut(_translate("MainWindow", "Ctrl+Shift+S"))
self.actQuit.setText(_translate("MainWindow", "Quit")) self.actQuit.setText(_translate("MainWindow", "&Quit"))
self.actQuit.setShortcut(_translate("MainWindow", "Ctrl+Q")) self.actQuit.setShortcut(_translate("MainWindow", "Ctrl+Q"))
self.actShowHelp.setText(_translate("MainWindow", "Show help texts")) self.actShowHelp.setText(_translate("MainWindow", "&Show help texts"))
self.actShowHelp.setShortcut(_translate("MainWindow", "Ctrl+Shift+B")) self.actShowHelp.setShortcut(_translate("MainWindow", "Ctrl+Shift+B"))
self.actSpellcheck.setText(_translate("MainWindow", "Spellcheck")) self.actSpellcheck.setText(_translate("MainWindow", "&Spellcheck"))
self.actSpellcheck.setShortcut(_translate("MainWindow", "F9")) self.actSpellcheck.setShortcut(_translate("MainWindow", "F9"))
self.actLabels.setText(_translate("MainWindow", "Labels...")) self.actLabels.setText(_translate("MainWindow", "&Labels..."))
self.actStatus.setText(_translate("MainWindow", "Status...")) self.actStatus.setText(_translate("MainWindow", "&Status..."))
self.actViewTree.setText(_translate("MainWindow", "Tree")) self.actViewTree.setText(_translate("MainWindow", "Tree"))
self.actModeNorma.setText(_translate("MainWindow", "Normal")) self.actModeNorma.setText(_translate("MainWindow", "&Normal"))
self.actModeSimple.setText(_translate("MainWindow", "Simple")) self.actModeSimple.setText(_translate("MainWindow", "&Simple"))
self.actModeFractal.setText(_translate("MainWindow", "Fractal")) self.actModeFractal.setText(_translate("MainWindow", "&Fractal"))
self.actViewCork.setText(_translate("MainWindow", "Index cards")) self.actViewCork.setText(_translate("MainWindow", "Index cards"))
self.actViewOutline.setText(_translate("MainWindow", "Outline")) self.actViewOutline.setText(_translate("MainWindow", "Outline"))
self.actSettings.setText(_translate("MainWindow", "Settings")) self.actSettings.setText(_translate("MainWindow", "S&ettings"))
self.actSettings.setShortcut(_translate("MainWindow", "F8")) self.actSettings.setShortcut(_translate("MainWindow", "F8"))
self.actCloseProject.setText(_translate("MainWindow", "Close project")) self.actCloseProject.setText(_translate("MainWindow", "&Close project"))
self.actCompile.setText(_translate("MainWindow", "Compile")) self.actCompile.setText(_translate("MainWindow", "Co&mpile"))
self.actCompile.setShortcut(_translate("MainWindow", "F6")) self.actCompile.setShortcut(_translate("MainWindow", "F6"))
from ui.views.basicItemView import basicItemView from manuskript.ui.cheatSheet import cheatSheet
from ui.views.plotTreeView import plotTreeView from manuskript.ui.editors.mainEditor import mainEditor
from ui.search import search from manuskript.ui.search import search
from ui.views.textEditCompleter import textEditCompleter from manuskript.ui.sldImportance import sldImportance
from ui.views.treeView import treeView from manuskript.ui.views.basicItemView import basicItemView
from ui.editors.mainEditor import mainEditor from manuskript.ui.views.lineEditView import lineEditView
from ui.views.outlineView import outlineView from manuskript.ui.views.metadataView import metadataView
from ui.views.lineEditView import lineEditView from manuskript.ui.views.outlineView import outlineView
from ui.views.textEditView import textEditView from manuskript.ui.views.persoTreeView import persoTreeView
from ui.welcome import welcome from manuskript.ui.views.plotTreeView import plotTreeView
from ui.sldImportance import sldImportance from manuskript.ui.views.textEditCompleter import textEditCompleter
from ui.cheatSheet import cheatSheet from manuskript.ui.views.textEditView import textEditView
from ui.views.metadataView import metadataView from manuskript.ui.views.treeView import treeView
from ui.views.persoTreeView import persoTreeView from manuskript.ui.welcome import welcome

View file

@ -103,7 +103,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -706,7 +715,7 @@
<property name="placeholderText"> <property name="placeholderText">
<string>Filter</string> <string>Filter</string>
</property> </property>
<property name="clearButtonEnabled" stdset="0"> <property name="clearButtonEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
@ -1055,7 +1064,7 @@
<property name="placeholderText"> <property name="placeholderText">
<string>Filter</string> <string>Filter</string>
</property> </property>
<property name="clearButtonEnabled" stdset="0"> <property name="clearButtonEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
@ -1416,7 +1425,7 @@
<property name="placeholderText"> <property name="placeholderText">
<string>Filter</string> <string>Filter</string>
</property> </property>
<property name="clearButtonEnabled" stdset="0"> <property name="clearButtonEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
@ -1658,7 +1667,16 @@
<string>Redaction</string> <string>Redaction</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_15"> <layout class="QVBoxLayout" name="verticalLayout_15">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -1668,7 +1686,16 @@
</property> </property>
<widget class="QWidget" name="treeRedacWidget" native="true"> <widget class="QWidget" name="treeRedacWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_30"> <layout class="QVBoxLayout" name="verticalLayout_30">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -1850,19 +1877,21 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1145</width> <width>1145</width>
<height>21</height> <height>30</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
<property name="title"> <property name="title">
<string>File</string> <string>Fi&amp;le</string>
</property> </property>
<widget class="QMenu" name="menuRecents"> <widget class="QMenu" name="menuRecents">
<property name="title"> <property name="title">
<string>Recents</string> <string>&amp;Recents</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="folder-recent"/> <iconset theme="folder-recent">
<normaloff/>
</iconset>
</property> </property>
</widget> </widget>
<addaction name="actOpen"/> <addaction name="actOpen"/>
@ -1877,7 +1906,7 @@
</widget> </widget>
<widget class="QMenu" name="menuMode"> <widget class="QMenu" name="menuMode">
<property name="title"> <property name="title">
<string>Mode</string> <string>&amp;Mode</string>
</property> </property>
<addaction name="actModeNorma"/> <addaction name="actModeNorma"/>
<addaction name="actModeSimple"/> <addaction name="actModeSimple"/>
@ -1905,7 +1934,7 @@
</widget> </widget>
<widget class="QMenu" name="menuView"> <widget class="QMenu" name="menuView">
<property name="title"> <property name="title">
<string>View</string> <string>&amp;View</string>
</property> </property>
</widget> </widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
@ -1918,7 +1947,7 @@
<widget class="QStatusBar" name="statusbar"/> <widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dckCheatSheet"> <widget class="QDockWidget" name="dckCheatSheet">
<property name="windowTitle"> <property name="windowTitle">
<string>Cheat sheet</string> <string>&amp;Cheat sheet</string>
</property> </property>
<attribute name="dockWidgetArea"> <attribute name="dockWidgetArea">
<number>2</number> <number>2</number>
@ -1940,7 +1969,7 @@
</widget> </widget>
<widget class="QDockWidget" name="dckSearch"> <widget class="QDockWidget" name="dckSearch">
<property name="windowTitle"> <property name="windowTitle">
<string>Search</string> <string>Sea&amp;rch</string>
</property> </property>
<attribute name="dockWidgetArea"> <attribute name="dockWidgetArea">
<number>2</number> <number>2</number>
@ -1966,7 +1995,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Open</string> <string>&amp;Open</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+O</string> <string>Ctrl+O</string>
@ -1978,7 +2007,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Save</string> <string>&amp;Save</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+S</string> <string>Ctrl+S</string>
@ -1990,7 +2019,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Save as...</string> <string>Sa&amp;ve as...</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+Shift+S</string> <string>Ctrl+Shift+S</string>
@ -2002,7 +2031,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Quit</string> <string>&amp;Quit</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+Q</string> <string>Ctrl+Q</string>
@ -2020,7 +2049,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Show help texts</string> <string>&amp;Show help texts</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+Shift+B</string> <string>Ctrl+Shift+B</string>
@ -2038,7 +2067,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Spellcheck</string> <string>&amp;Spellcheck</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>F9</string> <string>F9</string>
@ -2046,12 +2075,12 @@
</action> </action>
<action name="actLabels"> <action name="actLabels">
<property name="text"> <property name="text">
<string>Labels...</string> <string>&amp;Labels...</string>
</property> </property>
</action> </action>
<action name="actStatus"> <action name="actStatus">
<property name="text"> <property name="text">
<string>Status...</string> <string>&amp;Status...</string>
</property> </property>
</action> </action>
<action name="actViewTree"> <action name="actViewTree">
@ -2067,7 +2096,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Normal</string> <string>&amp;Normal</string>
</property> </property>
</action> </action>
<action name="actModeSimple"> <action name="actModeSimple">
@ -2075,7 +2104,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Simple</string> <string>&amp;Simple</string>
</property> </property>
</action> </action>
<action name="actModeFractal"> <action name="actModeFractal">
@ -2083,7 +2112,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Fractal</string> <string>&amp;Fractal</string>
</property> </property>
</action> </action>
<action name="actViewCork"> <action name="actViewCork">
@ -2102,7 +2131,7 @@
<normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset> <normaloff>../../../../../../../.designer/backup</normaloff>../../../../../../../.designer/backup</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Settings</string> <string>S&amp;ettings</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>F8</string> <string>F8</string>
@ -2115,12 +2144,12 @@
</iconset> </iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Close project</string> <string>&amp;Close project</string>
</property> </property>
</action> </action>
<action name="actCompile"> <action name="actCompile">
<property name="text"> <property name="text">
<string>Compile</string> <string>Co&amp;mpile</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>F6</string> <string>F6</string>
@ -2131,79 +2160,79 @@
<customwidget> <customwidget>
<class>textEditView</class> <class>textEditView</class>
<extends>QTextEdit</extends> <extends>QTextEdit</extends>
<header>ui.views.textEditView.h</header> <header>manuskript.ui.views.textEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>lineEditView</class> <class>lineEditView</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
<header>ui.views.lineEditView.h</header> <header>manuskript.ui.views.lineEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>outlineView</class> <class>outlineView</class>
<extends>QTreeView</extends> <extends>QTreeView</extends>
<header>ui.views.outlineView.h</header> <header>manuskript.ui.views.outlineView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>sldImportance</class> <class>sldImportance</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.sldImportance.h</header> <header>manuskript.ui.sldImportance.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>treeView</class> <class>treeView</class>
<extends>QTreeView</extends> <extends>QTreeView</extends>
<header>ui.views.treeView.h</header> <header>manuskript.ui.views.treeView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>metadataView</class> <class>metadataView</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.views.metadataView.h</header> <header>manuskript.ui.views.metadataView.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>basicItemView</class> <class>basicItemView</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.views.basicItemView.h</header> <header>manuskript.ui.views.basicItemView.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>plotTreeView</class> <class>plotTreeView</class>
<extends>QTreeWidget</extends> <extends>QTreeWidget</extends>
<header>ui.views.plotTreeView.h</header> <header>manuskript.ui.views.plotTreeView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>welcome</class> <class>welcome</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.welcome.h</header> <header>manuskript.ui.welcome.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>mainEditor</class> <class>mainEditor</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.editors.mainEditor.h</header> <header>manuskript.ui.editors.mainEditor.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>persoTreeView</class> <class>persoTreeView</class>
<extends>QTreeWidget</extends> <extends>QTreeWidget</extends>
<header>ui.views.persoTreeView.h</header> <header>manuskript.ui.views.persoTreeView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cheatSheet</class> <class>cheatSheet</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.cheatSheet.h</header> <header>manuskript.ui.cheatSheet.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>search</class> <class>search</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.search.h</header> <header>manuskript.ui.search.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>textEditCompleter</class> <class>textEditCompleter</class>
<extends>QTextEdit</extends> <extends>QTextEdit</extends>
<header>ui.views.textEditCompleter.h</header> <header>manuskript.ui.views.textEditCompleter.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -1,24 +1,26 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from models.outlineModel import *
from ui.revisions_ui import *
from functions import *
import models.references as Ref
import datetime import datetime
import difflib import difflib
import re import re
from PyQt5.QtCore import Qt, QTimer, QRect
from PyQt5.QtGui import QPalette, QFontMetrics
from PyQt5.QtWidgets import QWidget, QMenu, QActionGroup, QAction, QListWidgetItem, QStyledItemDelegate, QStyle
from manuskript.enums import Outline
from manuskript.ui.revisions_ui import Ui_revisions
from manuskript.models import references as Ref
class revisions(QWidget, Ui_revisions): class revisions(QWidget, Ui_revisions):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.splitter.setStretchFactor(0, 5) self.splitter.setStretchFactor(0, 5)
self.splitter.setStretchFactor(1, 70) self.splitter.setStretchFactor(1, 70)
self.listDelegate = listCompleterDelegate(self) self.listDelegate = listCompleterDelegate(self)
self.list.setItemDelegate(self.listDelegate) self.list.setItemDelegate(self.listDelegate)
self.list.itemActivated.connect(self.showDiff) self.list.itemActivated.connect(self.showDiff)
@ -28,79 +30,79 @@ class revisions(QWidget, Ui_revisions):
self.btnDelete.clicked.connect(self.delete) self.btnDelete.clicked.connect(self.delete)
self.btnRestore.clicked.connect(self.restore) self.btnRestore.clicked.connect(self.restore)
self.btnRestore.setEnabled(False) self.btnRestore.setEnabled(False)
#self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.updateTimer = QTimer() self.updateTimer = QTimer()
self.updateTimer.setSingleShot(True) self.updateTimer.setSingleShot(True)
self.updateTimer.setInterval(500) self.updateTimer.setInterval(500)
self.updateTimer.timeout.connect(self.update) self.updateTimer.timeout.connect(self.update)
self.updateTimer.stop() self.updateTimer.stop()
self.menu = QMenu(self) self.menu = QMenu(self)
self.actGroup = QActionGroup(self) self.actGroup = QActionGroup(self)
self.actShowDiff = QAction(self.tr("Show modifications"), self.menu) self.actShowDiff = QAction(self.tr("Show modifications"), self.menu)
self.actShowDiff.setCheckable(True) self.actShowDiff.setCheckable(True)
self.actShowDiff.setChecked(True) self.actShowDiff.setChecked(True)
self.actShowDiff.triggered.connect(self.showDiff) self.actShowDiff.triggered.connect(self.showDiff)
self.menu.addAction(self.actShowDiff) self.menu.addAction(self.actShowDiff)
self.actGroup.addAction(self.actShowDiff) self.actGroup.addAction(self.actShowDiff)
self.actShowVersion = QAction(self.tr("Show ancient version"), self.menu) self.actShowVersion = QAction(self.tr("Show ancient version"), self.menu)
self.actShowVersion.setCheckable(True) self.actShowVersion.setCheckable(True)
self.actShowVersion.setChecked(False) self.actShowVersion.setChecked(False)
self.actShowVersion.triggered.connect(self.showDiff) self.actShowVersion.triggered.connect(self.showDiff)
self.menu.addAction(self.actShowVersion) self.menu.addAction(self.actShowVersion)
self.actGroup.addAction(self.actShowVersion) self.actGroup.addAction(self.actShowVersion)
self.menu.addSeparator() self.menu.addSeparator()
self.actShowSpaces = QAction(self.tr("Show spaces"), self.menu) self.actShowSpaces = QAction(self.tr("Show spaces"), self.menu)
self.actShowSpaces.setCheckable(True) self.actShowSpaces.setCheckable(True)
self.actShowSpaces.setChecked(False) self.actShowSpaces.setChecked(False)
self.actShowSpaces.triggered.connect(self.showDiff) self.actShowSpaces.triggered.connect(self.showDiff)
self.menu.addAction(self.actShowSpaces) self.menu.addAction(self.actShowSpaces)
self.actDiffOnly = QAction(self.tr("Show modifications only"), self.menu) self.actDiffOnly = QAction(self.tr("Show modifications only"), self.menu)
self.actDiffOnly.setCheckable(True) self.actDiffOnly.setCheckable(True)
self.actDiffOnly.setChecked(True) self.actDiffOnly.setChecked(True)
self.actDiffOnly.triggered.connect(self.showDiff) self.actDiffOnly.triggered.connect(self.showDiff)
self.menu.addAction(self.actDiffOnly) self.menu.addAction(self.actDiffOnly)
self.btnOptions.setMenu(self.menu) self.btnOptions.setMenu(self.menu)
self._model = None self._model = None
self._index = None self._index = None
def setModel(self, model): def setModel(self, model):
self._model = model self._model = model
self._model.dataChanged.connect(self.updateMaybe) self._model.dataChanged.connect(self.updateMaybe)
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._index = index self._index = index
self.view.setText("") self.view.setText("")
self.update() self.update()
def updateMaybe(self, topLeft, bottomRight): def updateMaybe(self, topLeft, bottomRight):
if self._index and \ if self._index and \
topLeft.column() <= Outline.revisions.value <= bottomRight.column() and \ topLeft.column() <= Outline.revisions.value <= bottomRight.column() and \
topLeft.row() <= self._index.row() <= bottomRight.row(): topLeft.row() <= self._index.row() <= bottomRight.row():
#self.update() # self.update()
self.updateTimer.start() self.updateTimer.start()
def update(self): def update(self):
self.list.clear() self.list.clear()
item = self._index.internalPointer() item = self._index.internalPointer()
rev = item.revisions() rev = item.revisions()
# Sort revisions # Sort revisions
rev = sorted(rev, key=lambda x:x[0], reverse=True) rev = sorted(rev, key=lambda x: x[0], reverse=True)
for r in rev: for r in rev:
timestamp = datetime.datetime.fromtimestamp(r[0]).strftime('%Y-%m-%d %H:%M:%S') timestamp = datetime.datetime.fromtimestamp(r[0]).strftime('%Y-%m-%d %H:%M:%S')
readable = self.readableDelta(r[0]) readable = self.readableDelta(r[0])
i = QListWidgetItem(readable) i = QListWidgetItem(readable)
i.setData(Qt.UserRole, r[0]) i.setData(Qt.UserRole, r[0])
i.setData(Qt.UserRole+1, timestamp) i.setData(Qt.UserRole + 1, timestamp)
self.list.addItem(i) self.list.addItem(i)
def readableDelta(self, timestamp): def readableDelta(self, timestamp):
now = datetime.datetime.now() now = datetime.datetime.now()
delta = now - datetime.datetime.fromtimestamp(timestamp) delta = now - datetime.datetime.fromtimestamp(timestamp)
@ -118,47 +120,47 @@ class revisions(QWidget, Ui_revisions):
return self.tr("{} minutes ago").format(str(int(delta.seconds / 60))) return self.tr("{} minutes ago").format(str(int(delta.seconds / 60)))
else: else:
return self.tr("{} seconds ago").format(str(delta.seconds)) return self.tr("{} seconds ago").format(str(delta.seconds))
def showDiff(self): def showDiff(self):
# UI stuff # UI stuff
self.actShowSpaces.setEnabled(self.actShowDiff.isChecked()) self.actShowSpaces.setEnabled(self.actShowDiff.isChecked())
self.actDiffOnly.setEnabled(self.actShowDiff.isChecked()) self.actDiffOnly.setEnabled(self.actShowDiff.isChecked())
#FIXME: Errors in line number # FIXME: Errors in line number
i = self.list.currentItem() i = self.list.currentItem()
if not i: if not i:
self.btnDelete.setEnabled(False) self.btnDelete.setEnabled(False)
self.btnRestore.setEnabled(False) self.btnRestore.setEnabled(False)
return return
self.btnDelete.setEnabled(True) self.btnDelete.setEnabled(True)
self.btnRestore.setEnabled(True) self.btnRestore.setEnabled(True)
ts = i.data(Qt.UserRole) ts = i.data(Qt.UserRole)
item = self._index.internalPointer() item = self._index.internalPointer()
textNow = item.text() textNow = item.text()
textBefore = [r[1] for r in item.revisions() if r[0] == ts][0] textBefore = [r[1] for r in item.revisions() if r[0] == ts][0]
if self.actShowVersion.isChecked(): if self.actShowVersion.isChecked():
if item.type() == "t2t": if item.type() == "t2t":
textBefore = Ref.basicT2TFormat(textBefore) textBefore = Ref.basicT2TFormat(textBefore)
self.view.setText(textBefore) self.view.setText(textBefore)
return return
textNow = textNow.splitlines() textNow = textNow.splitlines()
textBefore = textBefore.splitlines() textBefore = textBefore.splitlines()
d = difflib.Differ() d = difflib.Differ()
diff = list(d.compare(textBefore, textNow)) diff = list(d.compare(textBefore, textNow))
if self.actShowSpaces.isChecked(): if self.actShowSpaces.isChecked():
_format = lambda x: x.replace(" ", "␣ ") _format = lambda x: x.replace(" ", "␣ ")
else: else:
_format = lambda x:x _format = lambda x: x
extra = "" if item.type() == "html" else "<br>" extra = "" if item.type() == "html" else "<br>"
diff = [d for d in diff if d and not d[:2] == "? "] diff = [d for d in diff if d and not d[:2] == "? "]
mydiff = "" mydiff = ""
skip = False skip = False
@ -166,23 +168,23 @@ class revisions(QWidget, Ui_revisions):
l = diff[n] l = diff[n]
op = l[:2] op = l[:2]
txt = l[2:] txt = l[2:]
op2 = diff[n+1][:2] if n+1 < len(diff) else None op2 = diff[n + 1][:2] if n + 1 < len(diff) else None
txt2 = diff[n+1][2:] if n+1 < len(diff) else None txt2 = diff[n + 1][2:] if n + 1 < len(diff) else None
if skip: if skip:
skip = False skip = False
continue continue
# Same line # Same line
if op == " " and not self.actDiffOnly.isChecked(): if op == " " and not self.actDiffOnly.isChecked():
if item.type() == "t2t": if item.type() == "t2t":
txt = Ref.basicT2TFormat(txt) txt = Ref.basicT2TFormat(txt)
mydiff += "{}{}".format(txt, extra) mydiff += "{}{}".format(txt, extra)
elif op == "- " and op2 == "+ ": elif op == "- " and op2 == "+ ":
if self.actDiffOnly.isChecked(): if self.actDiffOnly.isChecked():
mydiff += "<br><span style='color: blue;'>{}</span><br>".format( mydiff += "<br><span style='color: blue;'>{}</span><br>".format(
self.tr("Line {}:").format(str(n))) self.tr("Line {}:").format(str(n)))
s = difflib.SequenceMatcher(None, txt, txt2, autojunk=True) s = difflib.SequenceMatcher(None, txt, txt2, autojunk=True)
newline = "" newline = ""
for tag, i1, i2, j1, j2 in s.get_opcodes(): for tag, i1, i2, j1, j2 in s.get_opcodes():
@ -191,21 +193,25 @@ class revisions(QWidget, Ui_revisions):
elif tag == "delete": elif tag == "delete":
newline += "<span style='color:red; background:yellow;'>{}</span>".format(_format(txt[i1:i2])) newline += "<span style='color:red; background:yellow;'>{}</span>".format(_format(txt[i1:i2]))
elif tag == "insert": elif tag == "insert":
newline += "<span style='color:green; background:yellow;'>{}</span>".format(_format(txt2[j1:j2])) newline += "<span style='color:green; background:yellow;'>{}</span>".format(
_format(txt2[j1:j2]))
elif tag == "replace": elif tag == "replace":
newline += "<span style='color:red; background:yellow;'>{}</span>".format(_format(txt[i1:i2])) newline += "<span style='color:red; background:yellow;'>{}</span>".format(_format(txt[i1:i2]))
newline += "<span style='color:green; background:yellow;'>{}</span>".format(_format(txt2[j1:j2])) newline += "<span style='color:green; background:yellow;'>{}</span>".format(
_format(txt2[j1:j2]))
# Few ugly tweaks for html diffs # Few ugly tweaks for html diffs
newline = re.sub(r"(<span style='color.*?><span.*?>)</span>(.*)<span style='color:.*?>(</span></span>)", newline = re.sub(r"(<span style='color.*?><span.*?>)</span>(.*)<span style='color:.*?>(</span></span>)",
"\\1\\2\\3", newline) "\\1\\2\\3", newline)
newline = re.sub(r"<p align=\"<span style='color:red; background:yellow;'>cen</span><span style='color:green; background:yellow;'>righ</span>t<span style='color:red; background:yellow;'>er</span>\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*?)</p>", newline = re.sub(
"<p align=\"right\"><span style='color:green; background:yellow;'>\\1</span></p>", newline) r"<p align=\"<span style='color:red; background:yellow;'>cen</span><span style='color:green; background:yellow;'>righ</span>t<span style='color:red; background:yellow;'>er</span>\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*?)</p>",
newline = re.sub(r"<p align=\"<span style='color:green; background:yellow;'>cente</span>r<span style='color:red; background:yellow;'>ight</span>\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*)</p>", "<p align=\"right\"><span style='color:green; background:yellow;'>\\1</span></p>", newline)
"<p align=\"center\"><span style='color:green; background:yellow;'>\\1</span></p>", newline) newline = re.sub(
r"<p align=\"<span style='color:green; background:yellow;'>cente</span>r<span style='color:red; background:yellow;'>ight</span>\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*)</p>",
"<p align=\"center\"><span style='color:green; background:yellow;'>\\1</span></p>", newline)
newline = re.sub(r"<p(<span.*?>)(.*?)(</span>)(.*?)>(.*?)</p>", newline = re.sub(r"<p(<span.*?>)(.*?)(</span>)(.*?)>(.*?)</p>",
"<p\\2\\4>\\1\\5\\3</p>", newline) "<p\\2\\4>\\1\\5\\3</p>", newline)
mydiff += newline + extra mydiff += newline + extra
skip = True skip = True
elif op == "- ": elif op == "- ":
@ -216,9 +222,9 @@ class revisions(QWidget, Ui_revisions):
if self.actDiffOnly.isChecked(): if self.actDiffOnly.isChecked():
mydiff += "<br>{}:<br>".format(str(n)) mydiff += "<br>{}:<br>".format(str(n))
mydiff += "<span style='color:green;'>{}</span>{}".format(txt, extra) mydiff += "<span style='color:green;'>{}</span>{}".format(txt, extra)
self.view.setText(mydiff) self.view.setText(mydiff)
def restore(self): def restore(self):
i = self.list.currentItem() i = self.list.currentItem()
if not i: if not i:
@ -228,26 +234,26 @@ class revisions(QWidget, Ui_revisions):
textBefore = [r[1] for r in item.revisions() if r[0] == ts][0] textBefore = [r[1] for r in item.revisions() if r[0] == ts][0]
index = self._index.sibling(self._index.row(), Outline.text.value) index = self._index.sibling(self._index.row(), Outline.text.value)
self._index.model().setData(index, textBefore) self._index.model().setData(index, textBefore)
#item.setData(Outline.text.value, textBefore) # item.setData(Outline.text.value, textBefore)
def delete(self): def delete(self):
i = self.list.currentItem() i = self.list.currentItem()
if not i: if not i:
return return
ts = i.data(Qt.UserRole) ts = i.data(Qt.UserRole)
self._index.internalPointer().deleteRevision(ts) self._index.internalPointer().deleteRevision(ts)
def clearAll(self): def clearAll(self):
self._index.internalPointer().clearAllRevisions() self._index.internalPointer().clearAllRevisions()
def saveState(self): def saveState(self):
return [ return [
self.actShowDiff.isChecked(), self.actShowDiff.isChecked(),
self.actShowVersion.isChecked(), self.actShowVersion.isChecked(),
self.actShowSpaces.isChecked(), self.actShowSpaces.isChecked(),
self.actDiffOnly.isChecked(), self.actDiffOnly.isChecked(),
] ]
def popupMenu(self, pos): def popupMenu(self, pos):
i = self.list.itemAt(pos) i = self.list.itemAt(pos)
m = QMenu(self) m = QMenu(self)
@ -257,9 +263,9 @@ class revisions(QWidget, Ui_revisions):
m.addSeparator() m.addSeparator()
if self.list.count(): if self.list.count():
m.addAction(self.tr("Clear all")).triggered.connect(self.clearAll) m.addAction(self.tr("Clear all")).triggered.connect(self.clearAll)
m.popup(self.list.mapToGlobal(pos)) m.popup(self.list.mapToGlobal(pos))
def restoreState(self, state): def restoreState(self, state):
self.actShowDiff.setChecked(state[0]) self.actShowDiff.setChecked(state[0])
self.actShowVersion.setChecked(state[1]) self.actShowVersion.setChecked(state[1])
@ -267,25 +273,25 @@ class revisions(QWidget, Ui_revisions):
self.actDiffOnly.setChecked(state[3]) self.actDiffOnly.setChecked(state[3])
self.actShowSpaces.setEnabled(self.actShowDiff.isChecked()) self.actShowSpaces.setEnabled(self.actShowDiff.isChecked())
self.actDiffOnly.setEnabled(self.actShowDiff.isChecked()) self.actDiffOnly.setEnabled(self.actShowDiff.isChecked())
class listCompleterDelegate(QStyledItemDelegate): class listCompleterDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index): def paint(self, painter, option, index):
extra = index.data(Qt.UserRole+1) extra = index.data(Qt.UserRole + 1)
if not extra: if not extra:
return QStyledItemDelegate.paint(self, painter, option, index) return QStyledItemDelegate.paint(self, painter, option, index)
else: else:
if option.state & QStyle.State_Selected: if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight))
title = index.data() title = index.data()
extra = " - {}".format(extra) extra = " - {}".format(extra)
painter.drawText(option.rect, Qt.AlignLeft, title) painter.drawText(option.rect, Qt.AlignLeft, title)
fm = QFontMetrics(option.font) fm = QFontMetrics(option.font)
w = fm.width(title) w = fm.width(title)
r = QRect(option.rect) r = QRect(option.rect)
@ -293,4 +299,4 @@ class listCompleterDelegate(QStyledItemDelegate):
painter.save() painter.save()
painter.setPen(Qt.gray) painter.setPen(Qt.gray)
painter.drawText(r, Qt.AlignLeft, extra) painter.drawText(r, Qt.AlignLeft, extra)
painter.restore() painter.restore()

View file

@ -1,19 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QRect
from qt import * from PyQt5.QtGui import QPalette, QFontMetrics
from enums import * from PyQt5.QtWidgets import QWidget, QMenu, QAction, qApp, QListWidgetItem, QStyledItemDelegate, QStyle
from models.outlineModel import *
import models.references as Ref from manuskript.enums import Outline
from ui.search_ui import * from manuskript.functions import mainWindow
from functions import * from manuskript.ui.search_ui import Ui_search
from manuskript.models import references as Ref
class search(QWidget, Ui_search): class search(QWidget, Ui_search):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.options = { self.options = {
"All": True, "All": True,
"Title": True, "Title": True,
@ -24,30 +25,30 @@ class search(QWidget, Ui_search):
"Status": False, "Status": False,
"Label": False, "Label": False,
"CS": True "CS": True
} }
self.text.returnPressed.connect(self.search) self.text.returnPressed.connect(self.search)
self.generateOptionMenu() self.generateOptionMenu()
self.delegate = listResultDelegate(self) self.delegate = listResultDelegate(self)
self.result.setItemDelegate(self.delegate) self.result.setItemDelegate(self.delegate)
self.result.itemActivated.connect(self.openItem) self.result.itemActivated.connect(self.openItem)
def generateOptionMenu(self): def generateOptionMenu(self):
self.menu = QMenu(self) self.menu = QMenu(self)
a = QAction(self.tr("Search in:"), self.menu) a = QAction(self.tr("Search in:"), self.menu)
a.setEnabled(False) a.setEnabled(False)
self.menu.addAction(a) self.menu.addAction(a)
for i, d in [ for i, d in [
(self.tr("All"), "All"), (self.tr("All"), "All"),
(self.tr("Title"), "Title"), (self.tr("Title"), "Title"),
(self.tr("Text"), "Text"), (self.tr("Text"), "Text"),
(self.tr("Summary"), "Summary"), (self.tr("Summary"), "Summary"),
(self.tr("Notes"), "Notes"), (self.tr("Notes"), "Notes"),
(self.tr("POV"), "POV"), (self.tr("POV"), "POV"),
(self.tr("Status"), "Status"), (self.tr("Status"), "Status"),
(self.tr("Label"), "Label"), (self.tr("Label"), "Label"),
]: ]:
a = QAction(i, self.menu) a = QAction(i, self.menu)
a.setCheckable(True) a.setCheckable(True)
a.setChecked(self.options[d]) a.setChecked(self.options[d])
@ -55,13 +56,13 @@ class search(QWidget, Ui_search):
a.triggered.connect(self.updateOptions) a.triggered.connect(self.updateOptions)
self.menu.addAction(a) self.menu.addAction(a)
self.menu.addSeparator() self.menu.addSeparator()
a = QAction(self.tr("Options:"), self.menu) a = QAction(self.tr("Options:"), self.menu)
a.setEnabled(False) a.setEnabled(False)
self.menu.addAction(a) self.menu.addAction(a)
for i, d in [ for i, d in [
(self.tr("Case sensitive"), "CS"), (self.tr("Case sensitive"), "CS"),
]: ]:
a = QAction(i, self.menu) a = QAction(i, self.menu)
a.setCheckable(True) a.setCheckable(True)
a.setChecked(self.options[d]) a.setChecked(self.options[d])
@ -69,36 +70,36 @@ class search(QWidget, Ui_search):
a.triggered.connect(self.updateOptions) a.triggered.connect(self.updateOptions)
self.menu.addAction(a) self.menu.addAction(a)
self.menu.addSeparator() self.menu.addSeparator()
self.btnOptions.setMenu(self.menu) self.btnOptions.setMenu(self.menu)
def updateOptions(self): def updateOptions(self):
a = self.sender() a = self.sender()
self.options[a.data()] = a.isChecked() self.options[a.data()] = a.isChecked()
def search(self): def search(self):
text = self.text.text() text = self.text.text()
# Chosing the right columns # Chosing the right columns
lstColumns = [ lstColumns = [
("Title", Outline.title.value), ("Title", Outline.title.value),
("Text", Outline.text.value), ("Text", Outline.text.value),
("Summary", Outline.summarySentance.value), ("Summary", Outline.summarySentance.value),
("Summary", Outline.summaryFull.value), ("Summary", Outline.summaryFull.value),
("Notes", Outline.notes.value), ("Notes", Outline.notes.value),
("POV", Outline.POV.value), ("POV", Outline.POV.value),
("Status", Outline.status.value), ("Status", Outline.status.value),
("Label", Outline.label.value), ("Label", Outline.label.value),
] ]
columns = [c[1] for c in lstColumns if self.options[c[0]] or self.options["All"]] columns = [c[1] for c in lstColumns if self.options[c[0]] or self.options["All"]]
# Setting override cursor # Setting override cursor
qApp.setOverrideCursor(Qt.WaitCursor) qApp.setOverrideCursor(Qt.WaitCursor)
# Searching # Searching
model = mainWindow().mdlOutline model = mainWindow().mdlOutline
results = model.findItemsContaining(text, columns, self.options["CS"]) results = model.findItemsContaining(text, columns, self.options["CS"])
# Showing results # Showing results
self.result.clear() self.result.clear()
for r in results: for r in results:
@ -110,35 +111,35 @@ class search(QWidget, Ui_search):
i.setData(Qt.UserRole, r) i.setData(Qt.UserRole, r)
i.setData(Qt.UserRole + 1, item.path()) i.setData(Qt.UserRole + 1, item.path())
self.result.addItem(i) self.result.addItem(i)
# Removing override cursor # Removing override cursor
qApp.restoreOverrideCursor() qApp.restoreOverrideCursor()
def openItem(self, item): def openItem(self, item):
r = Ref.textReference(item.data(Qt.UserRole)) r = Ref.textReference(item.data(Qt.UserRole))
Ref.open(r) Ref.open(r)
#mw = mainWindow() # mw = mainWindow()
#index = mw.mdlOutline.getIndexByID(item.data(Qt.UserRole)) # index = mw.mdlOutline.getIndexByID(item.data(Qt.UserRole))
#mw.mainEditor.setCurrentModelIndex(index, newTab=True) # mw.mainEditor.setCurrentModelIndex(index, newTab=True)
class listResultDelegate(QStyledItemDelegate): class listResultDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index): def paint(self, painter, option, index):
extra = index.data(Qt.UserRole+1) extra = index.data(Qt.UserRole + 1)
if not extra: if not extra:
return QStyledItemDelegate.paint(self, painter, option, index) return QStyledItemDelegate.paint(self, painter, option, index)
else: else:
if option.state & QStyle.State_Selected: if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.color(QPalette.Highlight)) painter.fillRect(option.rect, option.palette.color(QPalette.Highlight))
title = index.data() title = index.data()
extra = " - {}".format(extra) extra = " - {}".format(extra)
painter.drawText(option.rect.adjusted(2, 1, 0, 0), Qt.AlignLeft, title) painter.drawText(option.rect.adjusted(2, 1, 0, 0), Qt.AlignLeft, title)
fm = QFontMetrics(option.font) fm = QFontMetrics(option.font)
w = fm.width(title) w = fm.width(title)
r = QRect(option.rect) r = QRect(option.rect)
@ -149,4 +150,4 @@ class listResultDelegate(QStyledItemDelegate):
else: else:
painter.setPen(Qt.gray) painter.setPen(Qt.gray)
painter.drawText(r.adjusted(2, 1, 0, 0), Qt.AlignLeft, extra) painter.drawText(r.adjusted(2, 1, 0, 0), Qt.AlignLeft, extra)
painter.restore() painter.restore()

View file

@ -1,79 +1,80 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import pyqtSignal, pyqtProperty
from qt import * from PyQt5.QtWidgets import QWidget
from functions import *
from ui.sldImportance_ui import * from manuskript.functions import toInt
from manuskript.ui.sldImportance_ui import Ui_sldImportance
class sldImportance(QWidget, Ui_sldImportance): class sldImportance(QWidget, Ui_sldImportance):
importanceChanged = pyqtSignal(str) importanceChanged = pyqtSignal(str)
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self._column = 0 self._column = 0
self._updating = False self._updating = False
self._index = None self._index = None
self.lastValue = -1 self.lastValue = -1
self.sld.valueChanged.connect(self.changed) self.sld.valueChanged.connect(self.changed)
self.setValue(0) self.setValue(0)
def getImportance(self): def getImportance(self):
return str(self.sld.value()) return str(self.sld.value())
def changed(self, v): def changed(self, v):
val = [ val = [
self.tr("Minor"), self.tr("Minor"),
self.tr("Secondary"), self.tr("Secondary"),
self.tr("Main"), self.tr("Main"),
] ]
self.lbl.setText(val[v]) self.lbl.setText(val[v])
self.importanceChanged.emit(str(v)) self.importanceChanged.emit(str(v))
if self._index and not self._updating: if self._index and not self._updating:
if str(v) != self._model.data(self._index): if str(v) != self._model.data(self._index):
self._updating = True self._updating = True
self._model.setData(self._index, str(v)) self._model.setData(self._index, str(v))
self._updating = False self._updating = False
def setValue(self, v): def setValue(self, v):
if v != self.lastValue: if v != self.lastValue:
self.sld.setValue(int(v) if v else 0) self.sld.setValue(int(v) if v else 0)
self.changed(int(v) if v else 0) self.changed(int(v) if v else 0)
self.lastValue = v self.lastValue = v
def setProperty(): def setProperty():
pass pass
# MODEL / VIEW # MODEL / VIEW
def setColumn(self, column): def setColumn(self, column):
self._column = column self._column = column
def setModel(self, model): def setModel(self, model):
self._model = model self._model = model
self._model.dataChanged.connect(self.update) self._model.dataChanged.connect(self.update)
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateValue() self.updateValue()
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
if index.isValid(): if index.isValid():
if index.column() != self._column: if index.column() != self._column:
index = index.sibling(index.row(), self._column) index = index.sibling(index.row(), self._column)
self._index = index self._index = index
self.updateValue() self.updateValue()
def updateValue(self): def updateValue(self):
if self._index: if self._index:
val = toInt(self._model.data(self._index)) val = toInt(self._model.data(self._index))
@ -81,6 +82,5 @@ class sldImportance(QWidget, Ui_sldImportance):
self._updating = True self._updating = True
self.setValue(val) self.setValue(val)
self._updating = False self._updating = False
importance = pyqtProperty(str, fget=getImportance, fset=setValue, notify=importanceChanged)
importance = pyqtProperty(str, fget=getImportance, fset=setValue, notify=importanceChanged)

View file

@ -6,7 +6,7 @@
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtWidgets
class Ui_sldImportance(object): class Ui_sldImportance(object):
def setupUi(self, sldImportance): def setupUi(self, sldImportance):

View file

@ -1,45 +1,45 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QWidget
from qt import *
from enums import * from manuskript.enums import Outline
from ui.views.basicItemView_ui import * from manuskript.ui.views.basicItemView_ui import Ui_basicItemView
class basicItemView(QWidget, Ui_basicItemView): class basicItemView(QWidget, Ui_basicItemView):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self) QWidget.__init__(self)
self.setupUi(self) self.setupUi(self)
self.txtSummarySentance.setColumn(Outline.summarySentance.value) self.txtSummarySentance.setColumn(Outline.summarySentance.value)
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, mdlPersos, mdlLabels, mdlStatus):
self.cmbPOV.setModels(mdlPersos, mdlOutline) self.cmbPOV.setModels(mdlPersos, mdlOutline)
self.txtSummarySentance.setModel(mdlOutline) self.txtSummarySentance.setModel(mdlOutline)
self.txtSummaryFull.setModel(mdlOutline) self.txtSummaryFull.setModel(mdlOutline)
self.txtGoal.setModel(mdlOutline) self.txtGoal.setModel(mdlOutline)
def getIndexes(self, sourceView): def getIndexes(self, sourceView):
"Returns a list of indexes from list of QItemSelectionRange" """Returns a list of indexes from list of QItemSelectionRange"""
indexes = [] indexes = []
for i in sourceView.selectionModel().selection().indexes(): for i in sourceView.selectionModel().selection().indexes():
if i.column() != 0: if i.column() != 0:
continue continue
if i not in indexes: if i not in indexes:
indexes.append(i) indexes.append(i)
return indexes return indexes
def selectionChanged(self, sourceView): def selectionChanged(self, sourceView):
indexes = self.getIndexes(sourceView) indexes = self.getIndexes(sourceView)
if len(indexes) == 0: if len(indexes) == 0:
self.setEnabled(False) self.setEnabled(False)
elif len(indexes) == 1: elif len(indexes) == 1:
self.setEnabled(True) self.setEnabled(True)
idx = indexes[0] idx = indexes[0]
@ -47,18 +47,16 @@ class basicItemView(QWidget, Ui_basicItemView):
self.txtSummaryFull.setCurrentModelIndex(idx) self.txtSummaryFull.setCurrentModelIndex(idx)
self.cmbPOV.setCurrentModelIndex(idx) self.cmbPOV.setCurrentModelIndex(idx)
self.txtGoal.setCurrentModelIndex(idx) self.txtGoal.setCurrentModelIndex(idx)
else: else:
self.setEnabled(True) self.setEnabled(True)
self.txtSummarySentance.setCurrentModelIndexes(indexes) self.txtSummarySentance.setCurrentModelIndexes(indexes)
self.txtSummaryFull.setCurrentModelIndexes(indexes) self.txtSummaryFull.setCurrentModelIndexes(indexes)
self.cmbPOV.setCurrentModelIndexes(indexes) self.cmbPOV.setCurrentModelIndexes(indexes)
self.txtGoal.setCurrentModelIndexes(indexes) self.txtGoal.setCurrentModelIndexes(indexes)
def setDict(self, d): def setDict(self, d):
self.txtSummaryFull.setDict(d) self.txtSummaryFull.setDict(d)
def toggleSpellcheck(self, v): def toggleSpellcheck(self, v):
self.txtSummaryFull.toggleSpellcheck(v) self.txtSummaryFull.toggleSpellcheck(v)

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 by: PyQt5 UI code generator 5.4.1 # Created by: PyQt5 UI code generator 5.4.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -66,6 +66,6 @@ class Ui_basicItemView(object):
self.txtSummarySentance.setPlaceholderText(_translate("basicItemView", "One line summary")) self.txtSummarySentance.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 ui.views.textEditView import textEditView from manuskript.ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser
from ui.views.lineEditView import lineEditView from manuskript.ui.views.lineEditView import lineEditView
from ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser from manuskript.ui.views.textEditView import textEditView

View file

@ -109,17 +109,17 @@
<customwidget> <customwidget>
<class>textEditView</class> <class>textEditView</class>
<extends>QTextEdit</extends> <extends>QTextEdit</extends>
<header>ui.views.textEditView.h</header> <header>manuskript.ui.views.textEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlinePersoChoser</class> <class>cmbOutlinePersoChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>ui.views.cmbOutlinePersoChoser.h</header> <header>manuskript.ui.views.cmbOutlinePersoChoser.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>lineEditView</class> <class>lineEditView</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
<header>ui.views.lineEditView.h</header> <header>manuskript.ui.views.lineEditView.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -1,16 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
# Because I have trouble with QDataWidgetMapper and the checkbox, I don't know why. # Because I have trouble with QDataWidgetMapper and the checkbox, I don't know why.
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QCheckBox
from manuskript.enums import Outline
class chkOutlineCompile(QCheckBox): class chkOutlineCompile(QCheckBox):
def __init__(self, parent=None): def __init__(self, parent=None):
QCheckBox.__init__(self, parent) QCheckBox.__init__(self, parent)
self.stateChanged.connect(self.submit) self.stateChanged.connect(self.submit)
@ -19,11 +19,11 @@ class chkOutlineCompile(QCheckBox):
self._indexes = None self._indexes = None
self._model = None self._model = None
self._updating = False self._updating = False
def setModel(self, model): def setModel(self, model):
self._model = model self._model = model
self._model.dataChanged.connect(self.update) self._model.dataChanged.connect(self.update)
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.column() != self._column: if index.column() != self._column:
@ -31,7 +31,7 @@ class chkOutlineCompile(QCheckBox):
self._index = index self._index = index
self.setTristate(False) self.setTristate(False)
self.updateCheckState() self.updateCheckState()
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._index = None self._index = None
self._indexes = [] self._indexes = []
@ -40,7 +40,7 @@ class chkOutlineCompile(QCheckBox):
i = i.sibling(i.row(), self._column) i = i.sibling(i.row(), self._column)
self._indexes.append(i) self._indexes.append(i)
self.updateCheckState() self.updateCheckState()
def getCheckedValue(self, index): def getCheckedValue(self, index):
item = index.internalPointer() item = index.internalPointer()
c = item.data(Outline.compile) c = item.data(Outline.compile)
@ -48,72 +48,71 @@ class chkOutlineCompile(QCheckBox):
c = int(c) c = int(c)
else: else:
c = Qt.Unchecked c = Qt.Unchecked
return c return c
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
# We are currently putting data in the model, so no updates # We are currently putting data in the model, so no updates
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateCheckState() self.updateCheckState()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
if topLeft.row() <= i.row() <= bottomRight.row(): if topLeft.row() <= i.row() <= bottomRight.row():
update = True update = True
if update: if update:
self.updateCheckState() self.updateCheckState()
def updateCheckState(self): def updateCheckState(self):
if self._index: if self._index:
self.setEnabled(True) self.setEnabled(True)
c = self.getCheckedValue(self._index) c = self.getCheckedValue(self._index)
self.setCheckState(c) self.setCheckState(c)
elif self._indexes: elif self._indexes:
self.setEnabled(True) self.setEnabled(True)
values = [] values = []
for i in self._indexes: for i in self._indexes:
values.append(self.getCheckedValue(i)) values.append(self.getCheckedValue(i))
same = True same = True
for v in values[1:]: for v in values[1:]:
if v != values[0]: if v != values[0]:
same = False same = False
break break
if same: if same:
self.setCheckState(values[0]) self.setCheckState(values[0])
else: else:
self._updating = True self._updating = True
self.setCheckState(Qt.PartiallyChecked) self.setCheckState(Qt.PartiallyChecked)
self._updating = False self._updating = False
else: else:
self.setChecked(False) self.setChecked(False)
self.setEnabled(False) self.setEnabled(False)
def submit(self, state): def submit(self, state):
if self._updating: if self._updating:
return return
if self._index: if self._index:
if self._model.data(self._index) != state: if self._model.data(self._index) != state:
self._model.setData(self._index, state) self._model.setData(self._index, state)
elif self._indexes: elif self._indexes:
for i in self._indexes: for i in self._indexes:
if self._model.data(i) != state: if self._model.data(i) != state:
self._model.setData(i, state) self._model.setData(i, state)
self.setTristate(False) self.setTristate(False)

View file

@ -1,11 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from qt import * from PyQt5.QtGui import QBrush
from enums import * from PyQt5.QtWidgets import QComboBox
from manuskript.enums import Outline
class cmbOutlineLabelChoser(QComboBox): class cmbOutlineLabelChoser(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)
@ -14,27 +16,27 @@ class cmbOutlineLabelChoser(QComboBox):
self._indexes = None self._indexes = None
self._updating = False self._updating = False
self._various = False self._various = False
def setModels(self, mdlLabels, mdlOutline): def setModels(self, mdlLabels, mdlOutline):
self.mdlLabels = mdlLabels self.mdlLabels = mdlLabels
self.mdlLabels.dataChanged.connect(self.updateItems) self.mdlLabels.dataChanged.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()
def updateItems(self): def updateItems(self):
self.clear() self.clear()
for i in range(self.mdlLabels.rowCount()): for i in range(self.mdlLabels.rowCount()):
item = self.mdlLabels.item(i, 0) item = self.mdlLabels.item(i, 0)
if item: if item:
self.addItem(item.icon(), self.addItem(item.icon(),
item.text()) item.text())
self._various = False self._various = False
if self._index or self._indexes: if self._index or self._indexes:
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.column() != self._column: if index.column() != self._column:
@ -42,30 +44,30 @@ class cmbOutlineLabelChoser(QComboBox):
self._index = index self._index = index
self.updateItems() self.updateItems()
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._indexes = [] self._indexes = []
self._index = None self._index = None
for i in indexes: for i in indexes:
if i.isValid(): if i.isValid():
if i.column() != self._column: if i.column() != self._column:
i = i.sibling(i.row(), self._column) i = i.sibling(i.row(), self._column)
self._indexes.append(i) self._indexes.append(i)
self.updateItems() self.updateItems()
self.updateSelectedItem() self.updateSelectedItem()
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
# We are currently putting data in the model, so no updates # We are currently putting data in the model, so no updates
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateSelectedItem() self.updateSelectedItem()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
@ -73,39 +75,39 @@ class cmbOutlineLabelChoser(QComboBox):
update = True update = True
if update: if update:
self.updateSelectedItem() self.updateSelectedItem()
def getLabel(self, index): def getLabel(self, index):
item = index.internalPointer() item = index.internalPointer()
label = item.data(self._column) label = item.data(self._column)
if not label: if not label:
label = 0 label = 0
return int(label) return int(label)
def updateSelectedItem(self): def updateSelectedItem(self):
if self._updating: if self._updating:
return return
if self._index: if self._index:
label = self.getLabel(self._index) label = self.getLabel(self._index)
self.setCurrentIndex(label) self.setCurrentIndex(label)
elif self._indexes: elif self._indexes:
labels = [] labels = []
same = True same = True
for i in self._indexes: for i in self._indexes:
labels.append(self.getLabel(i)) labels.append(self.getLabel(i))
for lbl in labels[1:]: for lbl in labels[1:]:
if lbl != labels[0]: if lbl != labels[0]:
same = False same = False
break break
if same: if same:
self._various = False self._various = False
self.setCurrentIndex(labels[0]) self.setCurrentIndex(labels[0])
else: else:
if not self._various: if not self._various:
self.insertItem(0, self.tr("Various")) self.insertItem(0, self.tr("Various"))
@ -115,25 +117,24 @@ class cmbOutlineLabelChoser(QComboBox):
self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole)
self._various = True self._various = True
self.setCurrentIndex(0) self.setCurrentIndex(0)
else: else:
self.setCurrentIndex(0) self.setCurrentIndex(0)
def submit(self, idx): def submit(self, idx):
if self._index: if self._index:
self.mdlOutline.setData(self._index, self.currentIndex()) self.mdlOutline.setData(self._index, self.currentIndex())
elif self._indexes: elif self._indexes:
value = self.currentIndex() value = self.currentIndex()
if self._various: if self._various:
if value == 0: if value == 0:
return return
value -= 1 value -= 1
self._updating = True self._updating = True
for i in self._indexes: for i in self._indexes:
self.mdlOutline.setData(i, value) self.mdlOutline.setData(i, value)
self._updating = False self._updating = False

View file

@ -1,12 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from qt import * from PyQt5.QtGui import QIcon, QBrush, QColor
from enums import * from PyQt5.QtWidgets import QComboBox
from functions import *
from manuskript.enums import Outline
from manuskript.functions import toInt
class cmbOutlinePersoChoser(QComboBox): class cmbOutlinePersoChoser(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)
@ -15,71 +17,71 @@ class cmbOutlinePersoChoser(QComboBox):
self._indexes = None self._indexes = None
self._updating = False self._updating = False
self._various = False self._various = False
def setModels(self, mdlPersos, mdlOutline): def setModels(self, mdlPersos, mdlOutline):
self.mdlPersos = mdlPersos self.mdlPersos = mdlPersos
self.mdlPersos.dataChanged.connect(self.updateItems) self.mdlPersos.dataChanged.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()
def updateItems(self): def updateItems(self):
self.clear() self.clear()
self.addItem(QIcon.fromTheme("dialog-no"), self.tr("None")) self.addItem(QIcon.fromTheme("dialog-no"), self.tr("None"))
l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]
for importance in range(3): for importance in range(3):
self.addItem(l[importance]) self.addItem(l[importance])
self.setItemData(self.count()-1, QBrush(QColor(Qt.darkBlue)), Qt.ForegroundRole) self.setItemData(self.count() - 1, QBrush(QColor(Qt.darkBlue)), Qt.ForegroundRole)
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.mdlPersos.rowCount()):
imp = toInt(self.mdlPersos.importance(i)) imp = toInt(self.mdlPersos.importance(i))
if not 2-imp == importance: continue if not 2 - imp == importance:
continue
self.addItem(self.mdlPersos.icon(i), self.mdlPersos.name(i), self.mdlPersos.ID(i)) self.addItem(self.mdlPersos.icon(i), self.mdlPersos.name(i), self.mdlPersos.ID(i))
self.setItemData(self.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole) self.setItemData(self.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole)
self._various = False self._various = False
if self._index or self._indexes: if self._index or self._indexes:
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.column() != self._column: if index.column() != self._column:
index = index.sibling(index.row(), self._column) index = index.sibling(index.row(), self._column)
self._index = index self._index = index
self.updateItems() self.updateItems()
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._index = None self._index = None
idxes = [] idxes = []
for i in indexes: for i in indexes:
if i.isValid(): if i.isValid():
if i.column() != self._column: if i.column() != self._column:
i = i.sibling(i.row(), self._column) i = i.sibling(i.row(), self._column)
idxes.append(i) idxes.append(i)
if idxes != self._indexes: if idxes != self._indexes:
self._indexes = idxes self._indexes = idxes
self.updateItems() self.updateItems()
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
# We are currently putting data in the model, so no updates # We are currently putting data in the model, so no updates
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateSelectedItem() self.updateSelectedItem()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
@ -87,44 +89,44 @@ class cmbOutlinePersoChoser(QComboBox):
update = True update = True
if update: if update:
self.updateSelectedItem() self.updateSelectedItem()
def getPOV(self, index): def getPOV(self, index):
item = index.internalPointer() item = index.internalPointer()
POV = item.data(self._column) POV = item.data(self._column)
return POV return POV
def selectPOV(self, POV): def selectPOV(self, POV):
idx = self.findData(POV) idx = self.findData(POV)
if idx != -1: if idx != -1:
self.setCurrentIndex(idx) self.setCurrentIndex(idx)
else: else:
self.setCurrentIndex(0) self.setCurrentIndex(0)
def updateSelectedItem(self, idx1=None, idx2=None): def updateSelectedItem(self, idx1=None, idx2=None):
if self._updating: if self._updating:
return return
if self._index: if self._index:
POV = self.getPOV(self._index) POV = self.getPOV(self._index)
self.selectPOV(POV) self.selectPOV(POV)
elif self._indexes: elif self._indexes:
POVs = [] POVs = []
same = True same = True
for i in self._indexes: for i in self._indexes:
POVs.append(self.getPOV(i)) POVs.append(self.getPOV(i))
for POV in POVs[1:]: for POV in POVs[1:]:
if POV != POVs[0]: if POV != POVs[0]:
same = False same = False
break break
if same: if same:
self._various = False self._various = False
self.selectPOV(POVs[0]) self.selectPOV(POVs[0])
else: else:
if not self._various: if not self._various:
self.insertItem(0, self.tr("Various")) self.insertItem(0, self.tr("Various"))
@ -134,19 +136,19 @@ class cmbOutlinePersoChoser(QComboBox):
self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole)
self._various = True self._various = True
self.setCurrentIndex(0) self.setCurrentIndex(0)
else: else:
self.setCurrentIndex(0) self.setCurrentIndex(0)
def submit(self, idx): def submit(self, idx):
if self._index: if self._index:
self.mdlOutline.setData(self._index, self.currentData()) self.mdlOutline.setData(self._index, self.currentData())
elif self._indexes: elif self._indexes:
if self._various and self.currentIndex() == 0: if self._various and self.currentIndex() == 0:
return return
self._updating = True self._updating = True
for i in self._indexes: for i in self._indexes:
self.mdlOutline.setData(i, self.currentData()) self.mdlOutline.setData(i, self.currentData())
self._updating = False self._updating = False

View file

@ -1,12 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from qt import * from PyQt5.QtGui import QBrush
from enums import * from PyQt5.QtWidgets import QComboBox
from manuskript.enums import Outline
class cmbOutlineStatusChoser(QComboBox): class cmbOutlineStatusChoser(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)
@ -15,26 +16,26 @@ class cmbOutlineStatusChoser(QComboBox):
self._indexes = None self._indexes = None
self._updating = False self._updating = False
self._various = False self._various = False
def setModels(self, mdlStatus, mdlOutline): def setModels(self, mdlStatus, mdlOutline):
self.mdlStatus = mdlStatus self.mdlStatus = mdlStatus
self.mdlStatus.dataChanged.connect(self.updateItems) self.mdlStatus.dataChanged.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()
def updateItems(self): def updateItems(self):
self.clear() self.clear()
for i in range(self.mdlStatus.rowCount()): for i in range(self.mdlStatus.rowCount()):
item = self.mdlStatus.item(i, 0) item = self.mdlStatus.item(i, 0)
if item: if item:
self.addItem(item.text()) self.addItem(item.text())
self._various = False self._various = False
if self._index or self._indexes: if self._index or self._indexes:
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.column() != self._column: if index.column() != self._column:
@ -42,30 +43,30 @@ class cmbOutlineStatusChoser(QComboBox):
self._index = index self._index = index
self.updateItems() self.updateItems()
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._indexes = [] self._indexes = []
self._index = None self._index = None
for i in indexes: for i in indexes:
if i.isValid(): if i.isValid():
if i.column() != self._column: if i.column() != self._column:
i = i.sibling(i.row(), self._column) i = i.sibling(i.row(), self._column)
self._indexes.append(i) self._indexes.append(i)
self.updateItems() self.updateItems()
self.updateSelectedItem() self.updateSelectedItem()
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
# We are currently putting data in the model, so no updates # We are currently putting data in the model, so no updates
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateSelectedItem() self.updateSelectedItem()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
@ -73,39 +74,39 @@ class cmbOutlineStatusChoser(QComboBox):
update = True update = True
if update: if update:
self.updateSelectedItem() self.updateSelectedItem()
def getStatus(self, index): def getStatus(self, index):
item = index.internalPointer() item = index.internalPointer()
status = item.data(self._column) status = item.data(self._column)
if not status: if not status:
status = 0 status = 0
return int(status) return int(status)
def updateSelectedItem(self): def updateSelectedItem(self):
if self._updating: if self._updating:
return return
if self._index: if self._index:
status = self.getStatus(self._index) status = self.getStatus(self._index)
self.setCurrentIndex(status) self.setCurrentIndex(status)
elif self._indexes: elif self._indexes:
statuses = [] statuses = []
same = True same = True
for i in self._indexes: for i in self._indexes:
statuses.append(self.getStatus(i)) statuses.append(self.getStatus(i))
for s in statuses[1:]: for s in statuses[1:]:
if s != statuses[0]: if s != statuses[0]:
same = False same = False
break break
if same: if same:
self._various = False self._various = False
self.setCurrentIndex(statuses[0]) self.setCurrentIndex(statuses[0])
else: else:
if not self._various: if not self._various:
self.insertItem(0, self.tr("Various")) self.insertItem(0, self.tr("Various"))
@ -115,24 +116,24 @@ class cmbOutlineStatusChoser(QComboBox):
self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole)
self._various = True self._various = True
self.setCurrentIndex(0) self.setCurrentIndex(0)
else: else:
self.setCurrentIndex(0) self.setCurrentIndex(0)
def submit(self, idx): def submit(self, idx):
if self._index: if self._index:
self.mdlOutline.setData(self._index, self.currentIndex()) self.mdlOutline.setData(self._index, self.currentIndex())
elif self._indexes: elif self._indexes:
value = self.currentIndex() value = self.currentIndex()
if self._various: if self._various:
if value == 0: if value == 0:
return return
value -= 1 value -= 1
self._updating = True self._updating = True
for i in self._indexes: for i in self._indexes:
self.mdlOutline.setData(i, value) self.mdlOutline.setData(i, value)
self._updating = False self._updating = False

View file

@ -1,12 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from qt import * from PyQt5.QtGui import QIcon, QBrush
from enums import * from PyQt5.QtWidgets import QComboBox
from manuskript.enums import Outline
class cmbOutlineTypeChoser(QComboBox): class cmbOutlineTypeChoser(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)
@ -15,27 +16,27 @@ class cmbOutlineTypeChoser(QComboBox):
self._indexes = None self._indexes = None
self._updating = False self._updating = False
self._various = False self._various = False
def setModel(self, mdlOutline): def setModel(self, mdlOutline):
self.mdlOutline = mdlOutline self.mdlOutline = mdlOutline
self.mdlOutline.dataChanged.connect(self.update) self.mdlOutline.dataChanged.connect(self.update)
self.updateItems() self.updateItems()
def updateItems(self): def updateItems(self):
self.clear() self.clear()
types = [ types = [
("t2t", self.tr("Txt2Tags"), "text-x-generic"), ("t2t", self.tr("Txt2Tags"), "text-x-generic"),
("html", self.tr("Rich Text (html)"), "text-html"), ("html", self.tr("Rich Text (html)"), "text-html"),
("txt", self.tr("Plain Text"), "text-x-generic"), ("txt", self.tr("Plain Text"), "text-x-generic"),
] ]
for t in types: for t in types:
self.addItem(QIcon.fromTheme(t[2]), t[1], t[0]) self.addItem(QIcon.fromTheme(t[2]), t[1], t[0])
self._various = False self._various = False
if self._index or self._indexes: if self._index or self._indexes:
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.column() != self._column: if index.column() != self._column:
@ -45,11 +46,11 @@ class cmbOutlineTypeChoser(QComboBox):
self.setEnabled(index.internalPointer().type() in ["t2t", "html", "txt"]) self.setEnabled(index.internalPointer().type() in ["t2t", "html", "txt"])
self.updateItems() self.updateItems()
self.updateSelectedItem() self.updateSelectedItem()
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._indexes = [] self._indexes = []
self._index = None self._index = None
hasText = False hasText = False
for i in indexes: for i in indexes:
if i.isValid(): if i.isValid():
@ -58,22 +59,22 @@ class cmbOutlineTypeChoser(QComboBox):
self._indexes.append(i) self._indexes.append(i)
if i.internalPointer().type() in ["t2t", "html", "txt"]: if i.internalPointer().type() in ["t2t", "html", "txt"]:
hasText = True hasText = True
self.setEnabled(hasText) self.setEnabled(hasText)
self.updateItems() self.updateItems()
self.updateSelectedItem() self.updateSelectedItem()
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
# We are currently putting data in the model, so no updates # We are currently putting data in the model, so no updates
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateSelectedItem() self.updateSelectedItem()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
@ -81,40 +82,40 @@ class cmbOutlineTypeChoser(QComboBox):
update = True update = True
if update: if update:
self.updateSelectedItem() self.updateSelectedItem()
def getType(self, index): def getType(self, index):
item = index.internalPointer() item = index.internalPointer()
return item.type() return item.type()
def updateSelectedItem(self): def updateSelectedItem(self):
if self._updating: if self._updating:
return return
if self._index: if self._index:
_type = self.getType(self._index) _type = self.getType(self._index)
i = self.findData(_type) i = self.findData(_type)
if i != -1: if i != -1:
self.setCurrentIndex(i) self.setCurrentIndex(i)
elif self._indexes: elif self._indexes:
types = [] types = []
same = True same = True
for i in self._indexes: for i in self._indexes:
types.append(self.getType(i)) types.append(self.getType(i))
for t in types[1:]: for t in types[1:]:
if t != types[0]: if t != types[0]:
same = False same = False
break break
if same: if same:
self._various = False self._various = False
i = self.findData(types[0]) i = self.findData(types[0])
if i != -1: if i != -1:
self.setCurrentIndex(i) self.setCurrentIndex(i)
else: else:
if not self._various: if not self._various:
self.insertItem(0, self.tr("Various")) self.insertItem(0, self.tr("Various"))
@ -124,21 +125,21 @@ class cmbOutlineTypeChoser(QComboBox):
self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole)
self._various = True self._various = True
self.setCurrentIndex(0) self.setCurrentIndex(0)
else: else:
self.setCurrentIndex(0) self.setCurrentIndex(0)
def submit(self, idx): def submit(self, idx):
if self._index: if self._index:
self.mdlOutline.setData(self._index, self.currentData()) self.mdlOutline.setData(self._index, self.currentData())
elif self._indexes: elif self._indexes:
value = self.currentData() value = self.currentData()
if self._various and self.currentIndex() == 0: if self._various and self.currentIndex() == 0:
return return
self._updating = True self._updating = True
for i in self._indexes: for i in self._indexes:
self.mdlOutline.setData(i, value) self.mdlOutline.setData(i, value)
self._updating = False self._updating = False

View file

@ -1,14 +1,18 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QSize, Qt, QRect, QPoint
from qt import * from PyQt5.QtGui import QMouseEvent, QFont, QPalette, QRegion, QFontMetrics, QColor, QIcon
from enums import * from PyQt5.QtWidgets import QStyledItemDelegate, QLineEdit, QPlainTextEdit, QFrame, qApp, QStyle
from functions import *
from random import randint from manuskript import settings
import settings from manuskript.enums import Outline
from manuskript.functions import colorifyPixmap
from manuskript.functions import mainWindow
from manuskript.functions import mixColors
from manuskript.functions import outlineItemColors
class corkDelegate(QStyledItemDelegate): class corkDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self.factor = settings.corkSizeFactor / 100. self.factor = settings.corkSizeFactor / 100.
@ -16,22 +20,22 @@ class corkDelegate(QStyledItemDelegate):
self.lastPos = None self.lastPos = None
self.editing = None self.editing = None
self.margin = 5 self.margin = 5
def setCorkSizeFactor(self, v): def setCorkSizeFactor(self, v):
self.factor = v / 100. self.factor = v / 100.
def sizeHint(self, option, index): def sizeHint(self, option, index):
return self.defaultSize * self.factor return self.defaultSize * self.factor
def editorEvent(self, event, model, option, index): def editorEvent(self, event, model, option, index):
# We catch the mouse position in the widget to know which part to edit # We catch the mouse position in the widget to know which part to edit
if type(event) == QMouseEvent: if type(event) == QMouseEvent:
self.lastPos = event.pos() # - option.rect.topLeft() self.lastPos = event.pos() # - option.rect.topLeft()
return QStyledItemDelegate.editorEvent(self, event, model, option, index) return QStyledItemDelegate.editorEvent(self, event, model, option, index)
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
self.updateRects(option, index) self.updateRects(option, index)
if self.mainLineRect.contains(self.lastPos): if self.mainLineRect.contains(self.lastPos):
# One line summary # One line summary
self.editing = Outline.summarySentance self.editing = Outline.summarySentance
@ -44,7 +48,7 @@ class corkDelegate(QStyledItemDelegate):
f.setItalic(True) f.setItalic(True)
edt.setFont(f) edt.setFont(f)
return edt return edt
elif self.titleRect.contains(self.lastPos): elif self.titleRect.contains(self.lastPos):
# Title # Title
self.editing = Outline.title self.editing = Outline.title
@ -52,13 +56,13 @@ class corkDelegate(QStyledItemDelegate):
edt.setFocusPolicy(Qt.StrongFocus) edt.setFocusPolicy(Qt.StrongFocus)
edt.setFrame(False) edt.setFrame(False)
f = QFont(option.font) f = QFont(option.font)
#f.setPointSize(f.pointSize() + 1) # f.setPointSize(f.pointSize() + 1)
f.setBold(True) f.setBold(True)
edt.setFont(f) edt.setFont(f)
edt.setAlignment(Qt.AlignCenter) edt.setAlignment(Qt.AlignCenter)
#edt.setGeometry(self.titleRect) # edt.setGeometry(self.titleRect)
return edt return edt
else: # self.mainTextRect.contains(self.lastPos): else: # self.mainTextRect.contains(self.lastPos):
# Summary # Summary
self.editing = Outline.summaryFull self.editing = Outline.summaryFull
@ -67,54 +71,53 @@ class corkDelegate(QStyledItemDelegate):
edt.setFrameShape(QFrame.NoFrame) edt.setFrameShape(QFrame.NoFrame)
edt.setPlaceholderText(self.tr("Full summary")) edt.setPlaceholderText(self.tr("Full summary"))
return edt return edt
def updateEditorGeometry(self, editor, option, index): def updateEditorGeometry(self, editor, option, index):
if self.editing == Outline.summarySentance: if self.editing == Outline.summarySentance:
# One line summary # One line summary
editor.setGeometry(self.mainLineRect) editor.setGeometry(self.mainLineRect)
elif self.editing == Outline.title: elif self.editing == Outline.title:
# Title # Title
editor.setGeometry(self.titleRect) editor.setGeometry(self.titleRect)
elif self.editing == Outline.summaryFull: elif self.editing == Outline.summaryFull:
# Summary # Summary
editor.setGeometry(self.mainTextRect) editor.setGeometry(self.mainTextRect)
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
item = index.internalPointer() item = index.internalPointer()
if self.editing == Outline.summarySentance: if self.editing == Outline.summarySentance:
# One line summary # One line summary
editor.setText(item.data(Outline.summarySentance.value)) editor.setText(item.data(Outline.summarySentance.value))
elif self.editing == Outline.title: elif self.editing == Outline.title:
# Title # Title
editor.setText(index.data()) editor.setText(index.data())
elif self.editing == Outline.summaryFull: elif self.editing == Outline.summaryFull:
# Summary # Summary
editor.setPlainText(item.data(Outline.summaryFull.value)) editor.setPlainText(item.data(Outline.summaryFull.value))
def setModelData(self, editor, model, index): def setModelData(self, editor, model, index):
if self.editing == Outline.summarySentance: if self.editing == Outline.summarySentance:
# One line summary # One line summary
model.setData(index.sibling(index.row(), Outline.summarySentance.value), editor.text()) model.setData(index.sibling(index.row(), Outline.summarySentance.value), editor.text())
elif self.editing == Outline.title: elif self.editing == Outline.title:
# Title # Title
model.setData(index, editor.text(), Outline.title.value) model.setData(index, editor.text(), Outline.title.value)
elif self.editing == Outline.summaryFull: elif self.editing == Outline.summaryFull:
# Summary # Summary
model.setData(index.sibling(index.row(), Outline.summaryFull.value), editor.toPlainText()) model.setData(index.sibling(index.row(), Outline.summaryFull.value), editor.toPlainText())
def updateRects(self, option, index): def updateRects(self, option, index):
margin = self.margin margin = self.margin
iconSize = max(16*self.factor, 12) iconSize = max(16 * self.factor, 12)
item = index.internalPointer() item = index.internalPointer()
self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin) self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin)
self.iconRect = QRect(self.itemRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize)) self.iconRect = QRect(self.itemRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize))
@ -122,7 +125,7 @@ class corkDelegate(QStyledItemDelegate):
self.itemRect.topRight() + QPoint(0, iconSize + 2 * margin)) self.itemRect.topRight() + QPoint(0, iconSize + 2 * margin))
self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0), self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0),
self.labelRect.bottomLeft() - QPoint(margin, margin)) self.labelRect.bottomLeft() - QPoint(margin, margin))
self.bottomRect = QRect(QPoint(self.itemRect.x(), self.iconRect.bottom() + margin), self.bottomRect = QRect(QPoint(self.itemRect.x(), self.iconRect.bottom() + margin),
QPoint(self.itemRect.right(), self.itemRect.bottom())) QPoint(self.itemRect.right(), self.itemRect.bottom()))
self.topRect = QRect(self.itemRect.topLeft(), self.bottomRect.topRight()) self.topRect = QRect(self.itemRect.topLeft(), self.bottomRect.topRight())
self.mainRect = self.bottomRect.adjusted(margin, margin, -margin, -margin) self.mainRect = self.bottomRect.adjusted(margin, margin, -margin, -margin)
@ -130,50 +133,50 @@ class corkDelegate(QStyledItemDelegate):
self.mainRect.topRight() + QPoint(0, iconSize)) self.mainRect.topRight() + QPoint(0, iconSize))
self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin), self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin),
self.mainRect.bottomRight()) self.mainRect.bottomRight())
if not item.data(Outline.summarySentance.value) : if not item.data(Outline.summarySentance.value):
self.mainTextRect.setTopLeft(self.mainLineRect.topLeft()) self.mainTextRect.setTopLeft(self.mainLineRect.topLeft())
if item.data(Outline.label.value) in ["", "0"]: if item.data(Outline.label.value) in ["", "0"]:
self.titleRect.setBottomRight(self.labelRect.bottomRight() - QPoint(self.margin, self.margin)) self.titleRect.setBottomRight(self.labelRect.bottomRight() - QPoint(self.margin, self.margin))
def paint(self, p, option, index): def paint(self, p, option, index):
#QStyledItemDelegate.paint(self, p, option, index) # QStyledItemDelegate.paint(self, p, option, index)
if not index.isValid(): if not index.isValid():
return return
item = index.internalPointer() item = index.internalPointer()
self.updateRects(option, index) self.updateRects(option, index)
colors = outlineItemColors(item) colors = outlineItemColors(item)
style = qApp.style() style = qApp.style()
def _rotate(angle): def _rotate(angle):
p.translate(self.mainRect.center()) p.translate(self.mainRect.center())
p.rotate(angle) p.rotate(angle)
p.translate(-self.mainRect.center()) p.translate(-self.mainRect.center())
# Draw background # Draw background
cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled)
if cg == QPalette.Normal and not option.state & QStyle.State_Active: if cg == QPalette.Normal and not option.state & QStyle.State_Active:
cg = QPalette.Inactive cg = QPalette.Inactive
# Selection # Selection
if option.state & QStyle.State_Selected: if option.state & QStyle.State_Selected:
p.save() p.save()
p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setBrush(option.palette.brush(cg, QPalette.Highlight))
p.setPen(Qt.NoPen) p.setPen(Qt.NoPen)
p.drawRoundedRect(option.rect, 12, 12) p.drawRoundedRect(option.rect, 12, 12)
p.restore() p.restore()
# Stack # Stack
if item.isFolder() and item.childCount() > 0: if item.isFolder() and item.childCount() > 0:
p.save() p.save()
p.setBrush(Qt.white) p.setBrush(Qt.white)
for i in reversed(range(3)): for i in reversed(range(3)):
p.drawRoundedRect(self.itemRect.adjusted(2*i, 2*i, -2*i, 2*i), 10, 10) p.drawRoundedRect(self.itemRect.adjusted(2 * i, 2 * i, -2 * i, 2 * i), 10, 10)
p.restore() p.restore()
# Background # Background
itemRect = self.itemRect itemRect = self.itemRect
p.save() p.save()
if settings.viewSettings["Cork"]["Background"] != "Nothing": if settings.viewSettings["Cork"]["Background"] != "Nothing":
@ -187,8 +190,8 @@ class corkDelegate(QStyledItemDelegate):
p.setPen(pen) p.setPen(pen)
p.drawRoundedRect(itemRect, 10, 10) p.drawRoundedRect(itemRect, 10, 10)
p.restore() p.restore()
# Title bar # Title bar
topRect = self.topRect topRect = self.topRect
p.save() p.save()
if item.isFolder(): if item.isFolder():
@ -199,10 +202,10 @@ class corkDelegate(QStyledItemDelegate):
p.setBrush(color) p.setBrush(color)
p.setClipRegion(QRegion(topRect)) p.setClipRegion(QRegion(topRect))
p.drawRoundedRect(itemRect, 10, 10) p.drawRoundedRect(itemRect, 10, 10)
#p.drawRect(topRect) # p.drawRect(topRect)
p.restore() p.restore()
# Label color # Label color
if settings.viewSettings["Cork"]["Corner"] != "Nothing": if settings.viewSettings["Cork"]["Corner"] != "Nothing":
p.save() p.save()
color = colors[settings.viewSettings["Cork"]["Corner"]] color = colors[settings.viewSettings["Cork"]["Corner"]]
@ -210,23 +213,23 @@ class corkDelegate(QStyledItemDelegate):
p.setBrush(color) p.setBrush(color)
p.setClipRegion(QRegion(self.labelRect)) p.setClipRegion(QRegion(self.labelRect))
p.drawRoundedRect(itemRect, 10, 10) p.drawRoundedRect(itemRect, 10, 10)
#p.drawRect(topRect) # p.drawRect(topRect)
p.restore() p.restore()
p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft()) p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft())
# One line summary background # One line summary background
lineSummary = item.data(Outline.summarySentance.value) lineSummary = item.data(Outline.summarySentance.value)
fullSummary = item.data(Outline.summaryFull.value) fullSummary = item.data(Outline.summaryFull.value)
if lineSummary or not fullSummary: if lineSummary or not fullSummary:
m = self.margin m = self.margin
r = self.mainLineRect.adjusted(-m, -m, m, m/2) r = self.mainLineRect.adjusted(-m, -m, m, m / 2)
p.save() p.save()
p.setPen(Qt.NoPen) p.setPen(Qt.NoPen)
p.setBrush(QColor("#EEE")) p.setBrush(QColor("#EEE"))
p.drawRect(r) p.drawRect(r)
p.restore() p.restore()
# Border # Border
p.save() p.save()
p.setBrush(Qt.NoBrush) p.setBrush(Qt.NoBrush)
pen = p.pen() pen = p.pen()
@ -239,8 +242,7 @@ class corkDelegate(QStyledItemDelegate):
p.setPen(pen) p.setPen(pen)
p.drawRoundedRect(itemRect, 10, 10) p.drawRoundedRect(itemRect, 10, 10)
p.restore() p.restore()
# Draw the icon # Draw the icon
iconRect = self.iconRect iconRect = self.iconRect
mode = QIcon.Normal mode = QIcon.Normal
@ -248,13 +250,13 @@ class corkDelegate(QStyledItemDelegate):
mode = QIcon.Disabled mode = QIcon.Disabled
elif option.state & style.State_Selected: elif option.state & style.State_Selected:
mode = QIcon.Selected mode = QIcon.Selected
#index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode)
icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size())
if settings.viewSettings["Cork"]["Icon"] != "Nothing": if settings.viewSettings["Cork"]["Icon"] != "Nothing":
color = colors[settings.viewSettings["Cork"]["Icon"]] color = colors[settings.viewSettings["Cork"]["Icon"]]
colorifyPixmap(icon, color) colorifyPixmap(icon, color)
QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode)
# Draw title # Draw title
p.save() p.save()
text = index.data() text = index.data()
@ -266,23 +268,23 @@ class corkDelegate(QStyledItemDelegate):
col = Qt.black col = Qt.black
p.setPen(col) p.setPen(col)
f = QFont(option.font) f = QFont(option.font)
#f.setPointSize(f.pointSize() + 1) # f.setPointSize(f.pointSize() + 1)
f.setBold(True) f.setBold(True)
p.setFont(f) p.setFont(f)
fm = QFontMetrics(f) fm = QFontMetrics(f)
elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width()) elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width())
p.drawText(titleRect, Qt.AlignCenter, elidedText) p.drawText(titleRect, Qt.AlignCenter, elidedText)
p.restore() p.restore()
# Draw the line # Draw the line
bottomRect = self.bottomRect bottomRect = self.bottomRect
p.save() p.save()
#p.drawLine(itemRect.x(), iconRect.bottom() + margin, # p.drawLine(itemRect.x(), iconRect.bottom() + margin,
#itemRect.right(), iconRect.bottom() + margin) # itemRect.right(), iconRect.bottom() + margin)
p.drawLine(bottomRect.topLeft(), bottomRect.topRight()) p.drawLine(bottomRect.topLeft(), bottomRect.topRight())
p.restore() p.restore()
# Lines # Lines
if True: if True:
p.save() p.save()
p.setPen(QColor("#EEE")) p.setPen(QColor("#EEE"))
@ -293,7 +295,7 @@ class corkDelegate(QStyledItemDelegate):
p.drawLine(l, QPoint(self.mainTextRect.right(), l.y())) p.drawLine(l, QPoint(self.mainTextRect.right(), l.y()))
l.setY(l.y() + h) l.setY(l.y() + h)
p.restore() p.restore()
# Draw status # Draw status
mainRect = self.mainRect mainRect = self.mainRect
status = item.data(Outline.status.value) status = item.data(Outline.status.value)
@ -310,9 +312,9 @@ class corkDelegate(QStyledItemDelegate):
_rotate(-35) _rotate(-35)
p.drawText(mainRect, Qt.AlignCenter, it.text()) p.drawText(mainRect, Qt.AlignCenter, it.text())
p.restore() p.restore()
# Draw Summary # Draw Summary
# One line # One line
if lineSummary: if lineSummary:
p.save() p.save()
f = QFont(option.font) f = QFont(option.font)
@ -322,12 +324,12 @@ class corkDelegate(QStyledItemDelegate):
elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width())
p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText) p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText)
p.restore() p.restore()
# Full summary # Full summary
if fullSummary: if fullSummary:
p.setFont(option.font) p.setFont(option.font)
p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)
#Debug # Debug
#for r in [self.itemRect, self.iconRect, self.titleRect, self.bottomRect, self.mainLineRect, self.mainTextRect]: # for r in [self.itemRect, self.iconRect, self.titleRect, self.bottomRect, self.mainLineRect, self.mainTextRect]:
#p.drawRect(r) # p.drawRect(r)

View file

@ -1,21 +1,19 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QListView
from qt import *
from enums import * from manuskript import settings
from functions import * from manuskript.ui.views.corkDelegate import corkDelegate
from ui.views.corkDelegate import * from manuskript.ui.views.dndView import dndView
from ui.views.dndView import * from manuskript.ui.views.outlineBasics import outlineBasics
from ui.views.outlineBasics import *
import settings
class corkView(QListView, dndView, outlineBasics): class corkView(QListView, dndView, outlineBasics):
def __init__(self, parent=None): def __init__(self, parent=None):
QListView.__init__(self, parent) QListView.__init__(self, parent)
dndView.__init__(self, parent) dndView.__init__(self, parent)
outlineBasics.__init__(self, parent) outlineBasics.__init__(self, parent)
self.setResizeMode(QListView.Adjust) self.setResizeMode(QListView.Adjust)
self.setWrapping(True) self.setWrapping(True)
self.setItemDelegate(corkDelegate()) self.setItemDelegate(corkDelegate())
@ -24,7 +22,7 @@ class corkView(QListView, dndView, outlineBasics):
self.setFlow(self.LeftToRight) self.setFlow(self.LeftToRight)
self.setSelectionBehavior(self.SelectRows) self.setSelectionBehavior(self.SelectRows)
self.updateBackground() self.updateBackground()
def updateBackground(self): def updateBackground(self):
self.setStyleSheet("""QListView {{ self.setStyleSheet("""QListView {{
background:{color}; background:{color};
@ -32,12 +30,12 @@ class corkView(QListView, dndView, outlineBasics):
}}""".format( }}""".format(
color=settings.corkBackground["color"], color=settings.corkBackground["color"],
url=settings.corkBackground["image"] url=settings.corkBackground["image"]
)) ))
def dragMoveEvent(self, event): def dragMoveEvent(self, event):
dndView.dragMoveEvent(self, event) dndView.dragMoveEvent(self, event)
QListView.dragMoveEvent(self, event) QListView.dragMoveEvent(self, event)
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
QListView.mouseReleaseEvent(self, event) QListView.mouseReleaseEvent(self, event)
outlineBasics.mouseReleaseEvent(self, event) outlineBasics.mouseReleaseEvent(self, event)

View file

@ -1,25 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAbstractItemView
from qt import *
from enums import *
from functions import *
class dndView(QAbstractItemView): class dndView(QAbstractItemView):
def __init__(self, parent=None): def __init__(self, parent=None):
#QAbstractItemView.__init__(self, parent) # QAbstractItemView.__init__(self, parent)
self.setDragDropMode(self.DragDrop) self.setDragDropMode(self.DragDrop)
self.setDefaultDropAction(Qt.MoveAction) self.setDefaultDropAction(Qt.MoveAction)
self.setSelectionMode(self.ExtendedSelection) self.setSelectionMode(self.ExtendedSelection)
def dragMoveEvent(self, event): def dragMoveEvent(self, event):
#return QAbstractItemView.dragMoveEvent(self, event) # return QAbstractItemView.dragMoveEvent(self, event)
#print(a) # print(a)
if event.keyboardModifiers() & Qt.ControlModifier: if event.keyboardModifiers() & Qt.ControlModifier:
event.setDropAction(Qt.CopyAction) event.setDropAction(Qt.CopyAction)
else: else:
event.setDropAction(Qt.MoveAction) event.setDropAction(Qt.MoveAction)

View file

@ -1,12 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QLineEdit
from qt import *
from enums import * from manuskript.enums import Outline
from functions import * from manuskript.functions import toString
class lineEditView(QLineEdit): class lineEditView(QLineEdit):
def __init__(self, parent=None): def __init__(self, parent=None):
QLineEdit.__init__(self, parent) QLineEdit.__init__(self, parent)
self._column = Outline.title.value self._column = Outline.title.value
@ -14,14 +14,14 @@ class lineEditView(QLineEdit):
self._index = None self._index = None
self._placeholderText = None self._placeholderText = None
self._updating = False self._updating = False
def setModel(self, model): def setModel(self, model):
self._model = model self._model = model
self._model.dataChanged.connect(self.update) self._model.dataChanged.connect(self.update)
def setColumn(self, col): def setColumn(self, col):
self._column = col self._column = col
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.isValid(): if index.isValid():
@ -29,49 +29,49 @@ class lineEditView(QLineEdit):
index = index.sibling(index.row(), self._column) index = index.sibling(index.row(), self._column)
self._index = index self._index = index
self._model = index.model() self._model = index.model()
#self.item = index.internalPointer() # self.item = index.internalPointer()
if self._placeholderText != None: if self._placeholderText is not None:
self.setPlaceholderText(self._placeholderText) self.setPlaceholderText(self._placeholderText)
self.textEdited.connect(self.submit) self.textEdited.connect(self.submit)
self.updateText() self.updateText()
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._indexes = [] self._indexes = []
self._index = None self._index = None
for i in indexes: for i in indexes:
if i.isValid(): if i.isValid():
if i.column() != self._column: if i.column() != self._column:
i = i.sibling(i.row(), self._column) i = i.sibling(i.row(), self._column)
self._indexes.append(i) self._indexes.append(i)
self.textEdited.connect(self.submit) self.textEdited.connect(self.submit)
self.updateText() self.updateText()
def submit(self): def submit(self):
if self._index: if self._index:
#item = self._index.internalPointer() # item = self._index.internalPointer()
if self.text() != self._model.data(self._index): if self.text() != self._model.data(self._index):
self._model.setData(self._index, self.text()) self._model.setData(self._index, self.text())
elif self._indexes: elif self._indexes:
self._updating = True self._updating = True
for i in self._indexes: for i in self._indexes:
#item = i.internalPointer() # item = i.internalPointer()
if self.text() != self._model.data(i): if self.text() != self._model.data(i):
self._model.setData(i, self.text()) self._model.setData(i, self.text())
self._updating = False self._updating = False
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
# We are currently putting data in the model, so no updates # We are currently putting data in the model, so no updates
return return
if self._index: if self._index:
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
self.updateText() self.updateText()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
@ -79,35 +79,34 @@ class lineEditView(QLineEdit):
update = True update = True
if update: if update:
self.updateText() self.updateText()
def updateText(self): def updateText(self):
if self._index: if self._index:
#item = self._index.internalPointer() # item = self._index.internalPointer()
#txt = toString(item.data(self._column)) # txt = toString(item.data(self._column))
txt = toString(self._model.data(self._index)) txt = toString(self._model.data(self._index))
if self.text() != txt: if self.text() != txt:
self.setText(txt) self.setText(txt)
elif self._indexes: elif self._indexes:
t = [] t = []
same = True same = True
for i in self._indexes: for i in self._indexes:
#item = i.internalPointer() # item = i.internalPointer()
#t.append(toString(item.data(self._column))) # t.append(toString(item.data(self._column)))
t.append(toString(self._model.data(i))) t.append(toString(self._model.data(i)))
for t2 in t[1:]: for t2 in t[1:]:
if t2 != t[0]: if t2 != t[0]:
same = False same = False
break break
if same: if same:
self.setText(t[0]) self.setText(t[0])
else: else:
self.setText("") self.setText("")
if not self._placeholderText: if not self._placeholderText:
self._placeholderText = self.placeholderText() self._placeholderText = self.placeholderText()
self.setPlaceholderText(self.tr("Various")) self.setPlaceholderText(self.tr("Various"))

View file

@ -1,12 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QWidget
from qt import *
from enums import * from manuskript.enums import Outline
from ui.views.metadataView_ui import * from manuskript.ui.views.metadataView_ui import Ui_metadataView
class metadataView(QWidget, Ui_metadataView): class metadataView(QWidget, Ui_metadataView):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
@ -15,37 +15,37 @@ class metadataView(QWidget, Ui_metadataView):
self.txtSummaryFull.setColumn(Outline.summaryFull.value) self.txtSummaryFull.setColumn(Outline.summaryFull.value)
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, mdlPersos, mdlLabels, mdlStatus):
self.properties.setModels(mdlOutline, mdlPersos, mdlLabels, mdlStatus) self.properties.setModels(mdlOutline, mdlPersos, mdlLabels, mdlStatus)
self.txtSummarySentance.setModel(mdlOutline) self.txtSummarySentance.setModel(mdlOutline)
self.txtSummaryFull.setModel(mdlOutline) self.txtSummaryFull.setModel(mdlOutline)
self.txtNotes.setModel(mdlOutline) self.txtNotes.setModel(mdlOutline)
self.revisions.setModel(mdlOutline) self.revisions.setModel(mdlOutline)
def getIndexes(self, sourceView): def getIndexes(self, sourceView):
"Returns a list of indexes from list of QItemSelectionRange" """Returns a list of indexes from list of QItemSelectionRange"""
indexes = [] indexes = []
for i in sourceView.selectionModel().selection().indexes(): for i in sourceView.selectionModel().selection().indexes():
if i.column() != 0: if i.column() != 0:
continue continue
if i not in indexes: if i not in indexes:
indexes.append(i) indexes.append(i)
return indexes return indexes
def selectionChanged(self, sourceView): def selectionChanged(self, sourceView):
indexes = self.getIndexes(sourceView) indexes = self.getIndexes(sourceView)
if self._lastIndexes == indexes: if self._lastIndexes == indexes:
return return
if len(indexes) == 0: if len(indexes) == 0:
self.setEnabled(False) self.setEnabled(False)
self.revisions.setEnabled(False) self.revisions.setEnabled(False)
elif len(indexes) == 1: elif len(indexes) == 1:
self.setEnabled(True) self.setEnabled(True)
idx = indexes[0] idx = indexes[0]
@ -54,25 +54,25 @@ class metadataView(QWidget, Ui_metadataView):
self.txtNotes.setCurrentModelIndex(idx) self.txtNotes.setCurrentModelIndex(idx)
self.revisions.setEnabled(True) self.revisions.setEnabled(True)
self.revisions.setCurrentModelIndex(idx) self.revisions.setCurrentModelIndex(idx)
else: else:
self.setEnabled(True) self.setEnabled(True)
self.txtSummarySentance.setCurrentModelIndexes(indexes) self.txtSummarySentance.setCurrentModelIndexes(indexes)
self.txtSummaryFull.setCurrentModelIndexes(indexes) self.txtSummaryFull.setCurrentModelIndexes(indexes)
self.txtNotes.setCurrentModelIndexes(indexes) self.txtNotes.setCurrentModelIndexes(indexes)
self.revisions.setEnabled(False) self.revisions.setEnabled(False)
self.properties.selectionChanged(sourceView) self.properties.selectionChanged(sourceView)
self._lastIndexes = indexes self._lastIndexes = indexes
def setDict(self, d): def setDict(self, d):
self.txtNotes.setDict(d) self.txtNotes.setDict(d)
self.txtSummaryFull.setDict(d) self.txtSummaryFull.setDict(d)
def toggleSpellcheck(self, v): def toggleSpellcheck(self, v):
self.txtNotes.toggleSpellcheck(v) self.txtNotes.toggleSpellcheck(v)
self.txtSummaryFull.toggleSpellcheck(v) self.txtSummaryFull.toggleSpellcheck(v)
def saveState(self): def saveState(self):
return [ return [
self.grpProperties.saveState(), self.grpProperties.saveState(),
@ -80,10 +80,10 @@ class metadataView(QWidget, Ui_metadataView):
self.grpNotes.saveState(), self.grpNotes.saveState(),
self.grpRevisions.saveState(), self.grpRevisions.saveState(),
self.revisions.saveState() self.revisions.saveState()
] ]
def restoreState(self, state): def restoreState(self, state):
self.grpProperties.restoreState(state[0]) self.grpProperties.restoreState(state[0])
self.grpSummary.restoreState(state[1]) self.grpSummary.restoreState(state[1])
self.grpNotes.restoreState(state[2]) self.grpNotes.restoreState(state[2])
self.grpRevisions.restoreState(state[3]) self.grpRevisions.restoreState(state[3])

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/views/metadataView_ui.ui' # Form implementation generated from reading ui file 'manuskript/ui/views/metadataView_ui.ui'
# #
# Created by: PyQt5 UI code generator 5.4.1 # Created by: PyQt5 UI code generator 5.4.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -83,9 +83,9 @@ class Ui_metadataView(object):
self.grpNotes.setTitle(_translate("metadataView", "Notes / References")) self.grpNotes.setTitle(_translate("metadataView", "Notes / References"))
self.grpRevisions.setTitle(_translate("metadataView", "Revisions")) self.grpRevisions.setTitle(_translate("metadataView", "Revisions"))
from ui.collapsibleGroupBox2 import collapsibleGroupBox2 from manuskript.ui.collapsibleGroupBox2 import collapsibleGroupBox2
from ui.views.propertiesView import propertiesView from manuskript.ui.revisions import revisions
from ui.views.textEditView import textEditView from manuskript.ui.views.lineEditView import lineEditView
from ui.revisions import revisions from manuskript.ui.views.propertiesView import propertiesView
from ui.views.textEditCompleter import textEditCompleter from manuskript.ui.views.textEditCompleter import textEditCompleter
from ui.views.lineEditView import lineEditView from manuskript.ui.views.textEditView import textEditView

View file

@ -137,34 +137,34 @@
<customwidget> <customwidget>
<class>textEditView</class> <class>textEditView</class>
<extends>QTextEdit</extends> <extends>QTextEdit</extends>
<header>ui.views.textEditView.h</header> <header>manuskript.ui.views.textEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>lineEditView</class> <class>lineEditView</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
<header>ui.views.lineEditView.h</header> <header>manuskript.ui.views.lineEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>collapsibleGroupBox2</class> <class>collapsibleGroupBox2</class>
<extends>QGroupBox</extends> <extends>QGroupBox</extends>
<header>ui.collapsibleGroupBox2.h</header> <header>manuskript.ui.collapsibleGroupBox2.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>propertiesView</class> <class>propertiesView</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.views.propertiesView.h</header> <header>manuskript.ui.views.propertiesView.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>textEditCompleter</class> <class>textEditCompleter</class>
<extends>QTextEdit</extends> <extends>QTextEdit</extends>
<header>ui.views.textEditCompleter.h</header> <header>manuskript.ui.views.textEditCompleter.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>revisions</class> <class>revisions</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>ui.revisions.h</header> <header>manuskript.ui.revisions.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>

View file

@ -1,68 +1,73 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QSignalMapper
from qt import * from PyQt5.QtGui import QIcon
from enums import * from PyQt5.QtWidgets import QAbstractItemView, qApp, QMenu, QAction
from functions import *
from models.outlineModel import * from manuskript import settings
import settings from manuskript.enums import Outline
from manuskript.functions import mainWindow
from manuskript.functions import toInt
from manuskript.models.outlineModel import outlineItem
class outlineBasics(QAbstractItemView): class outlineBasics(QAbstractItemView):
def __init__(self, parent=None): def __init__(self, parent=None):
pass pass
def getSelection(self): def getSelection(self):
sel = [] sel = []
for i in self.selectedIndexes(): for i in self.selectedIndexes():
if i.column() != 0: continue if i.column() != 0:
if not i in sel: sel.append(i) continue
if not i in sel:
sel.append(i)
return sel return sel
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
if event.button() == Qt.RightButton: if event.button() == Qt.RightButton:
self.menu = self.makePopupMenu() self.menu = self.makePopupMenu()
self.menu.popup(event.globalPos()) self.menu.popup(event.globalPos())
else: else:
QAbstractItemView.mouseReleaseEvent(self, event) QAbstractItemView.mouseReleaseEvent(self, event)
def makePopupMenu(self): def makePopupMenu(self):
index = self.currentIndex() index = self.currentIndex()
sel = self.getSelection() sel = self.getSelection()
clipboard = qApp.clipboard() clipboard = qApp.clipboard()
menu = QMenu(self) menu = QMenu(self)
# Add / remove items # Add / remove items
self.actAddFolder = QAction(QIcon.fromTheme("folder-new"), qApp.translate("outlineBasics", "New Folder"), menu) self.actAddFolder = QAction(QIcon.fromTheme("folder-new"), qApp.translate("outlineBasics", "New Folder"), menu)
self.actAddFolder.triggered.connect(self.addFolder) self.actAddFolder.triggered.connect(self.addFolder)
menu.addAction(self.actAddFolder) menu.addAction(self.actAddFolder)
self.actAddText = QAction(QIcon.fromTheme("document-new"), qApp.translate("outlineBasics", "New Text"), menu) self.actAddText = QAction(QIcon.fromTheme("document-new"), qApp.translate("outlineBasics", "New Text"), menu)
self.actAddText.triggered.connect(self.addText) self.actAddText.triggered.connect(self.addText)
menu.addAction(self.actAddText) menu.addAction(self.actAddText)
self.actDelete = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "Delete"), menu) self.actDelete = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "Delete"), menu)
self.actDelete.triggered.connect(self.delete) self.actDelete.triggered.connect(self.delete)
menu.addAction(self.actDelete) menu.addAction(self.actDelete)
menu.addSeparator() menu.addSeparator()
# Copy, cut, paste # Copy, cut, paste
self.actCopy = QAction(QIcon.fromTheme("edit-copy"), qApp.translate("outlineBasics", "Copy"), menu) self.actCopy = QAction(QIcon.fromTheme("edit-copy"), qApp.translate("outlineBasics", "Copy"), menu)
self.actCopy.triggered.connect(self.copy) self.actCopy.triggered.connect(self.copy)
menu.addAction(self.actCopy) menu.addAction(self.actCopy)
self.actCut = QAction(QIcon.fromTheme("edit-cut"), qApp.translate("outlineBasics", "Cut"), menu) self.actCut = QAction(QIcon.fromTheme("edit-cut"), qApp.translate("outlineBasics", "Cut"), menu)
self.actCut.triggered.connect(self.cut) self.actCut.triggered.connect(self.cut)
menu.addAction(self.actCut) menu.addAction(self.actCut)
self.actPaste = QAction(QIcon.fromTheme("edit-paste"), qApp.translate("outlineBasics", "Paste"), menu) self.actPaste = QAction(QIcon.fromTheme("edit-paste"), qApp.translate("outlineBasics", "Paste"), menu)
self.actPaste.triggered.connect(self.paste) self.actPaste.triggered.connect(self.paste)
menu.addAction(self.actPaste) menu.addAction(self.actPaste)
menu.addSeparator() menu.addSeparator()
# POV # POV
self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), menu) self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), menu)
mw = mainWindow() mw = mainWindow()
@ -70,33 +75,33 @@ class outlineBasics(QAbstractItemView):
a.triggered.connect(lambda: self.setPOV("")) a.triggered.connect(lambda: self.setPOV(""))
self.menuPOV.addAction(a) self.menuPOV.addAction(a)
self.menuPOV.addSeparator() self.menuPOV.addSeparator()
menus = [] menus = []
for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]: for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]:
m = QMenu(i, self.menuPOV) m = QMenu(i, self.menuPOV)
menus.append(m) menus.append(m)
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.mdlPersos.rowCount()):
a = QAction(mw.mdlPersos.icon(i), mw.mdlPersos.name(i), self.menuPOV) a = QAction(mw.mdlPersos.icon(i), mw.mdlPersos.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.mdlPersos.ID(i)))
imp = toInt(mw.mdlPersos.importance(i)) imp = toInt(mw.mdlPersos.importance(i))
menus[2-imp].addAction(a) menus[2 - imp].addAction(a)
mpr.mapped.connect(self.setPOV) mpr.mapped.connect(self.setPOV)
menu.addMenu(self.menuPOV) menu.addMenu(self.menuPOV)
# Status # Status
self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"), menu) self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"), menu)
#a = QAction(QIcon.fromTheme("dialog-no"), qApp.translate("outlineBasics", "None"), self.menuStatus) # a = QAction(QIcon.fromTheme("dialog-no"), qApp.translate("outlineBasics", "None"), self.menuStatus)
#a.triggered.connect(lambda: self.setStatus("")) # a.triggered.connect(lambda: self.setStatus(""))
#self.menuStatus.addAction(a) # self.menuStatus.addAction(a)
#self.menuStatus.addSeparator() # self.menuStatus.addSeparator()
mpr = QSignalMapper(self.menuStatus) mpr = QSignalMapper(self.menuStatus)
for i in range(mw.mdlStatus.rowCount()): for i in range(mw.mdlStatus.rowCount()):
a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus) a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus)
@ -105,29 +110,28 @@ class outlineBasics(QAbstractItemView):
self.menuStatus.addAction(a) self.menuStatus.addAction(a)
mpr.mapped.connect(self.setStatus) mpr.mapped.connect(self.setStatus)
menu.addMenu(self.menuStatus) menu.addMenu(self.menuStatus)
# Labels # Labels
self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"), menu) self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"), menu)
mpr = QSignalMapper(self.menuLabel) mpr = QSignalMapper(self.menuLabel)
for i in range(mw.mdlLabels.rowCount()): for i in range(mw.mdlLabels.rowCount()):
a = QAction(mw.mdlLabels.item(i, 0).icon(), a = QAction(mw.mdlLabels.item(i, 0).icon(),
mw.mdlLabels.item(i, 0).text(), mw.mdlLabels.item(i, 0).text(),
self.menuLabel) self.menuLabel)
a.triggered.connect(mpr.map) a.triggered.connect(mpr.map)
mpr.setMapping(a, i) mpr.setMapping(a, i)
self.menuLabel.addAction(a) self.menuLabel.addAction(a)
mpr.mapped.connect(self.setLabel) mpr.mapped.connect(self.setLabel)
menu.addMenu(self.menuLabel) menu.addMenu(self.menuLabel)
if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder() \ if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder() \
or not clipboard.mimeData().hasFormat("application/xml"): or not clipboard.mimeData().hasFormat("application/xml"):
self.actPaste.setEnabled(False) self.actPaste.setEnabled(False)
if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder(): if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder():
self.actAddFolder.setEnabled(False) self.actAddFolder.setEnabled(False)
self.actAddText.setEnabled(False) self.actAddText.setEnabled(False)
if len(sel) == 0: if len(sel) == 0:
self.actCopy.setEnabled(False) self.actCopy.setEnabled(False)
self.actCut.setEnabled(False) self.actCut.setEnabled(False)
@ -135,53 +139,53 @@ class outlineBasics(QAbstractItemView):
self.menuPOV.setEnabled(False) self.menuPOV.setEnabled(False)
self.menuStatus.setEnabled(False) self.menuStatus.setEnabled(False)
self.menuLabel.setEnabled(False) self.menuLabel.setEnabled(False)
return menu return menu
def addFolder(self): def addFolder(self):
self.addItem("folder") self.addItem("folder")
def addText(self): def addText(self):
self.addItem("text") self.addItem("text")
def addItem(self, _type="folder"): def addItem(self, _type="folder"):
if len(self.selectedIndexes()) == 0: if len(self.selectedIndexes()) == 0:
parent = self.rootIndex() parent = self.rootIndex()
else: else:
parent = self.currentIndex() parent = self.currentIndex()
if _type == "text": if _type == "text":
_type = settings.defaultTextType _type = settings.defaultTextType
item = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=_type) item = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=_type)
self.model().appendItem(item, parent) self.model().appendItem(item, parent)
def copy(self): def copy(self):
mimeData = self.model().mimeData(self.selectionModel().selectedIndexes()) mimeData = self.model().mimeData(self.selectionModel().selectedIndexes())
qApp.clipboard().setMimeData(mimeData) qApp.clipboard().setMimeData(mimeData)
def paste(self): def paste(self):
index = self.currentIndex() index = self.currentIndex()
if len(self.getSelection()) == 0: if len(self.getSelection()) == 0:
index = self.rootIndex() index = self.rootIndex()
data = qApp.clipboard().mimeData() data = qApp.clipboard().mimeData()
self.model().dropMimeData(data, Qt.CopyAction, -1, 0, index) self.model().dropMimeData(data, Qt.CopyAction, -1, 0, index)
def cut(self): def cut(self):
self.copy() self.copy()
self.delete() self.delete()
def delete(self): def delete(self):
self.model().removeIndexes(self.getSelection()) self.model().removeIndexes(self.getSelection())
def setPOV(self, POV): def setPOV(self, POV):
for i in self.getSelection(): for i in self.getSelection():
self.model().setData(i.sibling(i.row(), Outline.POV.value), str(POV)) self.model().setData(i.sibling(i.row(), Outline.POV.value), str(POV))
def setStatus(self, status): def setStatus(self, status):
for i in self.getSelection(): for i in self.getSelection():
self.model().setData(i.sibling(i.row(), Outline.status.value), str(status)) self.model().setData(i.sibling(i.row(), Outline.status.value), str(status))
def setLabel(self, label): def setLabel(self, label):
for i in self.getSelection(): for i in self.getSelection():
self.model().setData(i.sibling(i.row(), Outline.label.value), str(label)) self.model().setData(i.sibling(i.row(), Outline.label.value), str(label))

View file

@ -1,49 +1,53 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QSize, QModelIndex
from PyQt5.QtGui import QColor, QPalette, QIcon, QFont, QFontMetrics, QBrush
from PyQt5.QtWidgets import QStyledItemDelegate, QStyleOptionViewItem, QStyle, QComboBox, QStyleOptionComboBox
from PyQt5.QtWidgets import qApp
from manuskript import settings
from manuskript.enums import Perso, Outline
from manuskript.functions import outlineItemColors, mixColors, colorifyPixmap, toInt, toFloat, drawProgress
from qt import *
from enums import *
from functions import *
import settings
class outlineTitleDelegate(QStyledItemDelegate): class outlineTitleDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self._view = None self._view = None
def setView(self, view): def setView(self, view):
self._view = view self._view = view
def paint(self, painter, option, index): def paint(self, painter, option, index):
item = index.internalPointer() item = index.internalPointer()
colors = outlineItemColors(item) colors = outlineItemColors(item)
style = qApp.style() style = qApp.style()
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, index) self.initStyleOption(opt, index)
iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt) iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt)
textRect = style.subElementRect(style.SE_ItemViewItemText, opt) textRect = style.subElementRect(style.SE_ItemViewItemText, opt)
# Background # Background
style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter) style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter)
if settings.viewSettings["Outline"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected: if settings.viewSettings["Outline"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected:
col = colors[settings.viewSettings["Outline"]["Background"]] col = colors[settings.viewSettings["Outline"]["Background"]]
if col != QColor(Qt.transparent): if col != QColor(Qt.transparent):
col2 = QColor(Qt.white) col2 = QColor(Qt.white)
if opt.state & QStyle.State_Selected: if opt.state & QStyle.State_Selected:
col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color() col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color()
col = mixColors(col, col2, .2) col = mixColors(col, col2, .2)
painter.save() painter.save()
painter.setBrush(col) painter.setBrush(col)
painter.setPen(Qt.NoPen) painter.setPen(Qt.NoPen)
rect = opt.rect rect = opt.rect
if self._view: if self._view:
r2 = self._view.visualRect(index) r2 = self._view.visualRect(index)
@ -51,10 +55,10 @@ class outlineTitleDelegate(QStyledItemDelegate):
rect.setLeft(r2.left()) rect.setLeft(r2.left())
rect.setTop(r2.top()) rect.setTop(r2.top())
rect.setBottom(r2.bottom()) rect.setBottom(r2.bottom())
painter.drawRoundedRect(rect, 5, 5) painter.drawRoundedRect(rect, 5, 5)
painter.restore() painter.restore()
# Icon # Icon
mode = QIcon.Normal mode = QIcon.Normal
if not opt.state & QStyle.State_Enabled: if not opt.state & QStyle.State_Enabled:
@ -68,7 +72,7 @@ class outlineTitleDelegate(QStyledItemDelegate):
colorifyPixmap(icon, color) colorifyPixmap(icon, color)
opt.icon = QIcon(icon) opt.icon = QIcon(icon)
opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state) opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state)
# Text # Text
if opt.text: if opt.text:
painter.save() painter.save()
@ -82,49 +86,49 @@ class outlineTitleDelegate(QStyledItemDelegate):
fm = QFontMetrics(f) fm = QFontMetrics(f)
elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width()) elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width())
painter.drawText(textRect, Qt.AlignLeft, elidedText) painter.drawText(textRect, Qt.AlignLeft, elidedText)
painter.restore() painter.restore()
#QStyledItemDelegate.paint(self, painter, option, index) # QStyledItemDelegate.paint(self, painter, option, index)
class outlinePersoDelegate(QStyledItemDelegate): class outlinePersoDelegate(QStyledItemDelegate):
def __init__(self, mdlPersos, parent=None): def __init__(self, mdlPersos, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self.mdlPersos = mdlPersos self.mdlPersos = mdlPersos
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()): for i in range(self.mdlPersos.rowCount()):
if self.mdlPersos.ID(i) == index.data(): if self.mdlPersos.ID(i) == index.data():
item = self.mdlPersos.index(i, Perso.name.value) item = self.mdlPersos.index(i, Perso.name.value)
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, item) self.initStyleOption(opt, item)
s = QStyledItemDelegate.sizeHint(self, opt, item) s = QStyledItemDelegate.sizeHint(self, opt, item)
if s.width() > 200: if s.width() > 200:
s.setWidth(200) s.setWidth(200)
elif s.width() < 100: elif s.width() < 100:
s.setWidth(100) s.setWidth(100)
return s + QSize(18, 0) return s + QSize(18, 0)
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
item = index.internalPointer() item = index.internalPointer()
#if item.isFolder(): # No POV for folders # if item.isFolder(): # No POV for folders
#return # return
editor = QComboBox(parent) editor = QComboBox(parent)
editor.setAutoFillBackground(True) editor.setAutoFillBackground(True)
editor.setFrame(False) editor.setFrame(False)
return editor return editor
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
#editor.addItem("") # editor.addItem("")
editor.addItem(QIcon.fromTheme("dialog-no"), self.tr("None")) editor.addItem(QIcon.fromTheme("dialog-no"), self.tr("None"))
l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]
for importance in range(3): for importance in range(3):
editor.addItem(l[importance]) editor.addItem(l[importance])
@ -134,112 +138,110 @@ class outlinePersoDelegate(QStyledItemDelegate):
item.setFlags(Qt.ItemIsEnabled) item.setFlags(Qt.ItemIsEnabled)
for i in range(self.mdlPersos.rowCount()): for i in range(self.mdlPersos.rowCount()):
imp = toInt(self.mdlPersos.importance(i)) imp = toInt(self.mdlPersos.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.mdlPersos.icon(i), self.mdlPersos.name(i), self.mdlPersos.ID(i))
editor.setItemData(editor.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole) editor.setItemData(editor.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole)
#except: # except:
#pass # pass
editor.setCurrentIndex(editor.findData(index.data())) editor.setCurrentIndex(editor.findData(index.data()))
editor.showPopup() editor.showPopup()
def setModelData(self, editor, model, index): def setModelData(self, editor, model, index):
val = editor.currentData() val = editor.currentData()
model.setData(index, val) model.setData(index, val)
def paint(self, painter, option, index): def paint(self, painter, option, index):
##option.rect.setWidth(option.rect.width() - 18) ##option.rect.setWidth(option.rect.width() - 18)
#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() item = QModelIndex()
for i in range(self.mdlPersos.rowCount()): for i in range(self.mdlPersos.rowCount()):
if self.mdlPersos.ID(i) == index.data(): if self.mdlPersos.ID(i) == index.data():
item = self.mdlPersos.index(i, Perso.name.value) item = self.mdlPersos.index(i, Perso.name.value)
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, item) self.initStyleOption(opt, item)
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 index.isValid() and self.mdlPersos.data(index) 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)
option.rect = r option.rect = r
qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter) qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)
class outlineCompileDelegate(QStyledItemDelegate): class outlineCompileDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
def displayText(self, value, locale): def displayText(self, value, locale):
return "" return ""
class outlineGoalPercentageDelegate(QStyledItemDelegate): class outlineGoalPercentageDelegate(QStyledItemDelegate):
def __init__(self, rootIndex=None, parent=None): def __init__(self, rootIndex=None, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self.rootIndex = rootIndex self.rootIndex = rootIndex
def sizeHint(self, option, index): def sizeHint(self, option, index):
sh = QStyledItemDelegate.sizeHint(self, option, index) sh = QStyledItemDelegate.sizeHint(self, option, index)
#if sh.width() > 50: # if sh.width() > 50:
sh.setWidth(100) sh.setWidth(100)
return sh return sh
def paint(self, painter, option, index): def paint(self, painter, option, index):
if not index.isValid(): if not index.isValid():
return QStyledItemDelegate.paint(self, painter, option, index) return QStyledItemDelegate.paint(self, painter, option, index)
QStyledItemDelegate.paint(self, painter, option, index) QStyledItemDelegate.paint(self, painter, option, index)
item = index.internalPointer() item = index.internalPointer()
if not item.data(Outline.goal.value): if not item.data(Outline.goal.value):
return return
p = toFloat(item.data(Outline.goalPercentage.value)) p = toFloat(item.data(Outline.goalPercentage.value))
typ = item.data(Outline.type.value) typ = item.data(Outline.type.value)
level = item.level() level = item.level()
if self.rootIndex and self.rootIndex.isValid(): if self.rootIndex and self.rootIndex.isValid():
level -= self.rootIndex.internalPointer().level() + 1 level -= self.rootIndex.internalPointer().level() + 1
margin = 5 margin = 5
height = max(min(option.rect.height() - 2*margin, 12) - 2 * level, 6) height = max(min(option.rect.height() - 2 * margin, 12) - 2 * level, 6)
painter.save() painter.save()
rect = option.rect.adjusted(margin, margin, -margin, -margin) rect = option.rect.adjusted(margin, margin, -margin, -margin)
# Move # Move
rect.translate(level * rect.width() / 10, 0) rect.translate(level * rect.width() / 10, 0)
rect.setWidth(rect.width() - level * rect.width() / 10) rect.setWidth(rect.width() - level * rect.width() / 10)
rect.setHeight(height) rect.setHeight(height)
rect.setTop(option.rect.top() + (option.rect.height() - height) / 2) rect.setTop(option.rect.top() + (option.rect.height() - height) / 2)
drawProgress(painter, rect, p) # from functions drawProgress(painter, rect, p) # from functions
painter.restore() painter.restore()
def displayText(self, value, locale): def displayText(self, value, locale):
return "" return ""
class outlineStatusDelegate(QStyledItemDelegate): class outlineStatusDelegate(QStyledItemDelegate):
def __init__(self, mdlStatus, parent=None): def __init__(self, mdlStatus, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self.mdlStatus = mdlStatus self.mdlStatus = mdlStatus
def sizeHint(self, option, index): def sizeHint(self, option, index):
s = QStyledItemDelegate.sizeHint(self, option, index) s = QStyledItemDelegate.sizeHint(self, option, index)
if s.width() > 150: if s.width() > 150:
@ -247,52 +249,51 @@ class outlineStatusDelegate(QStyledItemDelegate):
elif s.width() < 50: elif s.width() < 50:
s.setWidth(50) s.setWidth(50)
return s + QSize(18, 0) return s + QSize(18, 0)
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
editor = QComboBox(parent) editor = QComboBox(parent)
editor.setAutoFillBackground(True) editor.setAutoFillBackground(True)
editor.setFrame(False) editor.setFrame(False)
return editor return editor
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
for i in range(self.mdlStatus.rowCount()): for i in range(self.mdlStatus.rowCount()):
editor.addItem(self.mdlStatus.item(i, 0).text()) editor.addItem(self.mdlStatus.item(i, 0).text())
val = index.internalPointer().data(Outline.status.value) val = index.internalPointer().data(Outline.status.value)
if not val: val = 0 if not val: val = 0
editor.setCurrentIndex(int(val)) editor.setCurrentIndex(int(val))
editor.showPopup() editor.showPopup()
def setModelData(self, editor, model, index): def setModelData(self, editor, model, index):
val = editor.currentIndex() val = editor.currentIndex()
model.setData(index, val) model.setData(index, val)
def displayText(self, value, locale): def displayText(self, value, locale):
try: try:
return self.mdlStatus.item(int(value), 0).text() return self.mdlStatus.item(int(value), 0).text()
except: except:
return "" return ""
def paint(self, painter, option, index): def paint(self, painter, option, index):
QStyledItemDelegate.paint(self, painter, option, index) QStyledItemDelegate.paint(self, painter, option, index)
if index.isValid() and index.internalPointer().data(Outline.status.value) not in ["", None, "0"]: if index.isValid() and index.internalPointer().data(Outline.status.value) not in ["", None, "0"]:
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)
option.rect = r option.rect = r
qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter) qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)
class outlineLabelDelegate(QStyledItemDelegate): class outlineLabelDelegate(QStyledItemDelegate):
def __init__(self, mdlLabels, parent=None): def __init__(self, mdlLabels, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self.mdlLabels = mdlLabels self.mdlLabels = mdlLabels
def sizeHint(self, option, index): def sizeHint(self, option, index):
d = index.internalPointer().data(index.column(), Qt.DisplayRole) d = index.internalPointer().data(index.column(), Qt.DisplayRole)
if not d: if not d:
d = 0 d = 0
item = self.mdlLabels.item(int(d), 0) item = self.mdlLabels.item(int(d), 0)
idx = self.mdlLabels.indexFromItem(item) idx = self.mdlLabels.indexFromItem(item)
@ -304,44 +305,44 @@ class outlineLabelDelegate(QStyledItemDelegate):
elif s.width() < 50: elif s.width() < 50:
s.setWidth(50) s.setWidth(50)
return s + QSize(18, 0) return s + QSize(18, 0)
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
item = index.internalPointer() item = index.internalPointer()
editor = QComboBox(parent) editor = QComboBox(parent)
#editor.setAutoFillBackground(True) # editor.setAutoFillBackground(True)
editor.setFrame(False) editor.setFrame(False)
return editor return editor
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
for i in range(self.mdlLabels.rowCount()): for i in range(self.mdlLabels.rowCount()):
editor.addItem(self.mdlLabels.item(i, 0).icon(), editor.addItem(self.mdlLabels.item(i, 0).icon(),
self.mdlLabels.item(i, 0).text()) self.mdlLabels.item(i, 0).text())
val = index.internalPointer().data(Outline.label.value) val = index.internalPointer().data(Outline.label.value)
if not val: val = 0 if not val: val = 0
editor.setCurrentIndex(int(val)) editor.setCurrentIndex(int(val))
editor.showPopup() editor.showPopup()
def setModelData(self, editor, model, index): def setModelData(self, editor, model, index):
val = editor.currentIndex() val = editor.currentIndex()
model.setData(index, val) model.setData(index, val)
def paint(self, painter, option, index): def paint(self, painter, option, index):
if not index.isValid(): if not index.isValid():
return QStyledItemDelegate.paint(self, painter, option, index) return QStyledItemDelegate.paint(self, painter, option, index)
else: else:
item = index.internalPointer() item = index.internalPointer()
d = item.data(index.column(), Qt.DisplayRole) d = item.data(index.column(), Qt.DisplayRole)
if not d: if not d:
d = 0 d = 0
lbl = self.mdlLabels.item(int(d), 0) lbl = self.mdlLabels.item(int(d), 0)
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, self.mdlLabels.indexFromItem(lbl)) self.initStyleOption(opt, self.mdlLabels.indexFromItem(lbl))
qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter) qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
# Drop down indicator # Drop down indicator
if index.isValid() and index.internalPointer().data(Outline.label.value) not in ["", None, "0"]: if index.isValid() and index.internalPointer().data(Outline.label.value) not in ["", None, "0"]:
opt = QStyleOptionComboBox() opt = QStyleOptionComboBox()
@ -349,4 +350,3 @@ class outlineLabelDelegate(QStyledItemDelegate):
r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow) r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow)
option.rect = r option.rect = r
qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter) qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)

View file

@ -1,47 +1,45 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QTreeView, QHeaderView
from manuskript import settings
from manuskript.enums import Outline
from manuskript.ui.views.dndView import dndView
from manuskript.ui.views.outlineBasics import outlineBasics
from manuskript.ui.views.outlineDelegates import outlineTitleDelegate, outlinePersoDelegate, outlineCompileDelegate, \
outlineStatusDelegate, outlineGoalPercentageDelegate, outlineLabelDelegate
from qt import *
from enums import *
from functions import *
from ui.views.outlineDelegates import *
from ui.views.dndView import *
from ui.views.outlineBasics import *
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, modelPersos=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.modelPersos = modelPersos
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 setModelPersos(self, model):
# This is used by outlinePersoDelegate to select character # This is used by outlinePersoDelegate to select character
self.modelPersos = model self.modelPersos = 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
self.modelLabels = model self.modelLabels = model
def setModelStatus(self, model): def setModelStatus(self, model):
# This is used by outlineStatusDelegate to display statuses # This is used by outlineStatusDelegate to display statuses
self.modelStatus = model self.modelStatus = model
def setModel(self, model): def setModel(self, model):
QTreeView.setModel(self, model) QTreeView.setModel(self, model)
# Setting delegates # Setting delegates
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.outlinePersoDelegate = outlinePersoDelegate(self.modelPersos)
self.setItemDelegateForColumn(Outline.POV.value, self.outlinePersoDelegate) self.setItemDelegateForColumn(Outline.POV.value, self.outlinePersoDelegate)
@ -53,10 +51,10 @@ class outlineView(QTreeView, dndView, outlineBasics):
self.setItemDelegateForColumn(Outline.goalPercentage.value, self.outlineGoalPercentageDelegate) self.setItemDelegateForColumn(Outline.goalPercentage.value, self.outlineGoalPercentageDelegate)
self.outlineLabelDelegate = outlineLabelDelegate(self.modelLabels) self.outlineLabelDelegate = outlineLabelDelegate(self.modelLabels)
self.setItemDelegateForColumn(Outline.label.value, self.outlineLabelDelegate) self.setItemDelegateForColumn(Outline.label.value, self.outlineLabelDelegate)
# Hiding columns # Hiding columns
self.hideColumns() self.hideColumns()
self.header().setSectionResizeMode(Outline.title.value, QHeaderView.Stretch) self.header().setSectionResizeMode(Outline.title.value, QHeaderView.Stretch)
self.header().setSectionResizeMode(Outline.POV.value, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(Outline.POV.value, QHeaderView.ResizeToContents)
self.header().setSectionResizeMode(Outline.status.value, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(Outline.status.value, QHeaderView.ResizeToContents)
@ -65,23 +63,22 @@ class outlineView(QTreeView, dndView, outlineBasics):
self.header().setSectionResizeMode(Outline.wordCount.value, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(Outline.wordCount.value, QHeaderView.ResizeToContents)
self.header().setSectionResizeMode(Outline.goal.value, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(Outline.goal.value, QHeaderView.ResizeToContents)
self.header().setSectionResizeMode(Outline.goalPercentage.value, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(Outline.goalPercentage.value, QHeaderView.ResizeToContents)
def hideColumns(self): def hideColumns(self):
for c in range(self.model().columnCount()): for c in range(self.model().columnCount()):
self.hideColumn(c) self.hideColumn(c)
for c in settings.outlineViewColumns: for c in settings.outlineViewColumns:
self.showColumn(c) self.showColumn(c)
def setRootIndex(self, index): def setRootIndex(self, index):
QTreeView.setRootIndex(self, index) QTreeView.setRootIndex(self, index)
self.outlineGoalPercentageDelegate = outlineGoalPercentageDelegate(index) self.outlineGoalPercentageDelegate = outlineGoalPercentageDelegate(index)
self.setItemDelegateForColumn(Outline.goalPercentage.value, self.outlineGoalPercentageDelegate) self.setItemDelegateForColumn(Outline.goalPercentage.value, self.outlineGoalPercentageDelegate)
def dragMoveEvent(self, event): def dragMoveEvent(self, event):
dndView.dragMoveEvent(self, event) dndView.dragMoveEvent(self, event)
QTreeView.dragMoveEvent(self, event) QTreeView.dragMoveEvent(self, event)
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
QTreeView.mouseReleaseEvent(self, event) QTreeView.mouseReleaseEvent(self, event)
outlineBasics.mouseReleaseEvent(self, event) outlineBasics.mouseReleaseEvent(self, event)

View file

@ -1,13 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import QSize, QModelIndex, Qt
from qt import * from PyQt5.QtGui import QPixmap, QColor, QIcon, QBrush
from enums import * from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem
from functions import *
import settings from manuskript.enums import Perso
class persoTreeView(QTreeWidget): class persoTreeView(QTreeWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeWidget.__init__(self, parent) QTreeWidget.__init__(self, parent)
self._model = None self._model = None
@ -19,43 +19,43 @@ class persoTreeView(QTreeWidget):
self.setIndentation(10) self.setIndentation(10)
self.setHeaderHidden(True) self.setHeaderHidden(True)
self.setIconSize(QSize(24, 24)) self.setIconSize(QSize(24, 24))
self.setColumnCount(1) self.setColumnCount(1)
self._rootItem = QTreeWidgetItem() self._rootItem = QTreeWidgetItem()
self.insertTopLevelItem(0, self._rootItem) self.insertTopLevelItem(0, self._rootItem)
def setPersosModel(self, model): def setPersosModel(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)
self._model.rowsRemoved.connect(self.updateMaybe2) self._model.rowsRemoved.connect(self.updateMaybe2)
self.updateItems() self.updateItems()
def setFilter(self, text): def setFilter(self, text):
self._filter = text self._filter = text
self.updateItems() self.updateItems()
def updateMaybe(self, topLeft, bottomRight): def updateMaybe(self, topLeft, bottomRight):
if topLeft.parent() != QModelIndex(): if topLeft.parent() != QModelIndex():
return return
if topLeft.column() <= Perso.name.value <= bottomRight.column(): if topLeft.column() <= Perso.name.value <= bottomRight.column():
# Update name # Update name
self.updateNames() self.updateNames()
elif topLeft.column() <= Perso.importance.value <= bottomRight.column(): elif topLeft.column() <= Perso.importance.value <= bottomRight.column():
# Importance changed # Importance changed
self.updateItems() self.updateItems()
def updateMaybe2(self, parent, first, last): def updateMaybe2(self, parent, first, last):
#Rows inserted or removed, we update only if they are topLevel rows. # Rows inserted or removed, we update only if they are topLevel rows.
if parent == QModelIndex(): if parent == QModelIndex():
self.updateItems() self.updateItems()
def updateNames(self): def updateNames(self):
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 c in range(item.childCount()):
sub = item.child(c) sub = item.child(c)
ID = sub.data(0, Qt.UserRole) ID = sub.data(0, Qt.UserRole)
@ -68,18 +68,18 @@ class persoTreeView(QTreeWidget):
color = QColor(self._model.getPersoColorByID(ID)) color = QColor(self._model.getPersoColorByID(ID))
px.fill(color) px.fill(color)
sub.setIcon(0, QIcon(px)) sub.setIcon(0, QIcon(px))
def updateItems(self): def updateItems(self):
if not self._model: if not self._model:
return return
if self.currentItem(): if self.currentItem():
self._lastID = self.currentItem().data(0, Qt.UserRole) self._lastID = self.currentItem().data(0, Qt.UserRole)
self._updating = True self._updating = True
self.clear() self.clear()
persos = self._model.getPersosByImportance() persos = self._model.getPersosByImportance()
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):
cat = QTreeWidgetItem(self, [h[i]]) cat = QTreeWidgetItem(self, [h[i]])
@ -90,11 +90,11 @@ class persoTreeView(QTreeWidget):
f.setBold(True) f.setBold(True)
cat.setFont(0, f) cat.setFont(0, f)
self.addTopLevelItem(cat) self.addTopLevelItem(cat)
#cat.setChildIndicatorPolicy(cat.DontShowIndicator) # cat.setChildIndicatorPolicy(cat.DontShowIndicator)
for ID in persos[i]: for ID in persos[i]:
name = self._model.getPersoNameByID(ID) name = self._model.getPersoNameByID(ID)
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, ID)
@ -102,30 +102,29 @@ class persoTreeView(QTreeWidget):
color = QColor(self._model.getPersoColorByID(ID)) color = QColor(self._model.getPersoColorByID(ID))
px.fill(color) px.fill(color)
item.setIcon(0, QIcon(px)) item.setIcon(0, QIcon(px))
if ID == self._lastID: if ID == self._lastID:
self.setCurrentItem(item) self.setCurrentItem(item)
self.expandAll() self.expandAll()
self._updating = False self._updating = False
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()):
item = self.topLevelItem(t).child(i) item = self.topLevelItem(t).child(i)
if item.data(0, Qt.UserRole) == ID: if item.data(0, Qt.UserRole) == ID:
return item return item
def currentPersoIndex(self): def currentPersoIndex(self):
ID = None ID = None
if self.currentItem(): if self.currentItem():
ID = self.currentItem().data(0, Qt.UserRole) ID = self.currentItem().data(0, Qt.UserRole)
return self._model.getIndexFromID(ID) 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
if item.parent(): if item.parent():
QTreeWidget.mouseDoubleClickEvent(self, event) QTreeWidget.mouseDoubleClickEvent(self, event)

View file

@ -1,52 +1,53 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from functions import *
import settings
import collections import collections
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QStyledItemDelegate, QLineEdit, QMenu, QAction
class plotDelegate(QStyledItemDelegate): class plotDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
def sizeHint(self, option, index): def sizeHint(self, option, index):
s = QStyledItemDelegate.sizeHint(self, option, index) s = QStyledItemDelegate.sizeHint(self, option, index)
if s.width() < 200: if s.width() < 200:
s.setWidth(200) s.setWidth(200)
return s return s
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
editor = QLineEdit(parent) editor = QLineEdit(parent)
editor.setFrame(False) editor.setFrame(False)
editor.setAlignment(Qt.AlignRight | Qt.AlignVCenter) editor.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
return editor return editor
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
editor.setText(index.model().data(index)) editor.setText(index.model().data(index))
self.txt = editor self.txt = editor
self.menu = QMenu(editor) self.menu = QMenu(editor)
plotsTypes = collections.OrderedDict({ plotsTypes = collections.OrderedDict({
self.tr("General"): [ self.tr("General"): [
self.tr("Promise"), self.tr("Promise"),
self.tr("Problem"), self.tr("Problem"),
self.tr("Progress"), self.tr("Progress"),
self.tr("Resolution") self.tr("Resolution")
], ],
self.tr("Try / Fail"): [ self.tr("Try / Fail"): [
self.tr("No and"), self.tr("No and"),
self.tr("Yes but"), self.tr("Yes but"),
], ],
self.tr("Freytag's pyramid"): [ self.tr("Freytag's pyramid"): [
self.tr("Exposition"), self.tr("Exposition"),
self.tr("Rising action"), self.tr("Rising action"),
self.tr("Climax"), self.tr("Climax"),
self.tr("Falling action"), self.tr("Falling action"),
self.tr("Resolution"), self.tr("Resolution"),
], ],
self.tr("Three acts"): [ self.tr("Three acts"): [
self.tr("1. Setup"), self.tr("1. Setup"),
self.tr("1. Inciting event"), self.tr("1. Inciting event"),
@ -59,8 +60,8 @@ class plotDelegate(QStyledItemDelegate):
self.tr("3. Stand up"), self.tr("3. Stand up"),
self.tr("3. Climax"), self.tr("3. Climax"),
self.tr("3. Ending"), self.tr("3. Ending"),
], ],
self.tr("Hero's journey"): [ self.tr("Hero's journey"): [
self.tr("Ordinary world"), self.tr("Ordinary world"),
self.tr("Call to adventure"), self.tr("Call to adventure"),
@ -74,12 +75,12 @@ class plotDelegate(QStyledItemDelegate):
self.tr("Transformation"), self.tr("Transformation"),
self.tr("Atonement"), self.tr("Atonement"),
self.tr("Return"), self.tr("Return"),
], ],
}) })
for name in plotsTypes: for name in plotsTypes:
m = QMenu(name, self.menu) m = QMenu(name, self.menu)
for sub in plotsTypes[name]: for sub in plotsTypes[name]:
if sub == "---": if sub == "---":
m.addSeparator() m.addSeparator()
@ -87,19 +88,19 @@ class plotDelegate(QStyledItemDelegate):
a = QAction(sub, m) a = QAction(sub, m)
a.triggered.connect(self.submit) a.triggered.connect(self.submit)
m.addAction(a) m.addAction(a)
self.menu.addMenu(m) self.menu.addMenu(m)
editor.addAction(QIcon.fromTheme("list-add"), QLineEdit.LeadingPosition).triggered.connect(self.popupMenu) editor.addAction(QIcon.fromTheme("list-add"), QLineEdit.LeadingPosition).triggered.connect(self.popupMenu)
def setModelData(self, editor, model, index): def setModelData(self, editor, model, index):
val = editor.text() val = editor.text()
model.setData(index, val) model.setData(index, val)
def popupMenu(self): def popupMenu(self):
act = self.sender() act = self.sender()
self.menu.popup(self.txt.parent().mapToGlobal(self.txt.geometry().bottomLeft())) self.menu.popup(self.txt.parent().mapToGlobal(self.txt.geometry().bottomLeft()))
def submit(self): def submit(self):
act = self.sender() act = self.sender()
self.txt.setText(act.text()) self.txt.setText(act.text())

View file

@ -1,15 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QModelIndex, QMimeData
from qt import * from PyQt5.QtGui import QBrush, QColor
from enums import * from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem
from functions import *
import settings
from lxml import etree as ET from lxml import etree as ET
import models.references as Ref
from manuskript import settings
from manuskript.enums import Plot, Outline
from manuskript.models import references as Ref
class plotTreeView(QTreeWidget): class plotTreeView(QTreeWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeWidget.__init__(self, parent) QTreeWidget.__init__(self, parent)
self._model = None self._model = None
@ -20,37 +21,38 @@ class plotTreeView(QTreeWidget):
self._showSubPlot = False self._showSubPlot = False
self.setRootIsDecorated(False) self.setRootIsDecorated(False)
self.setIndentation(10) self.setIndentation(10)
self.setColumnCount(1) self.setColumnCount(1)
self._rootItem = QTreeWidgetItem() self._rootItem = QTreeWidgetItem()
self.insertTopLevelItem(0, self._rootItem) self.insertTopLevelItem(0, self._rootItem)
#self.currentItemChanged.connect(self._currentItemChanged) # self.currentItemChanged.connect(self._currentItemChanged)
############################################################################### ###############################################################################
# SETTERS # SETTERS
############################################################################### ###############################################################################
def setShowSubPlot(self, v): def setShowSubPlot(self, v):
self._showSubPlot = v self._showSubPlot = v
self.updateItems() self.updateItems()
def setPlotModel(self, model): def setPlotModel(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)
self._model.rowsRemoved.connect(self.updateMaybe2) self._model.rowsRemoved.connect(self.updateMaybe2)
self.updateItems() self.updateItems()
def setFilter(self, text): def setFilter(self, text):
self._filter = text self._filter = text
self.updateItems() self.updateItems()
############################################################################### ###############################################################################
# GETTERS # GETTERS
############################################################################### ###############################################################################
def getItemByID(self, ID): def getItemByID(self, ID):
"Recursively search items to find one whose data is ``ID``." "Recursively search items to find one whose data is ``ID``."
def find(item, ID): def find(item, ID):
if item.data(0, Qt.UserRole) == ID: if item.data(0, Qt.UserRole) == ID:
return item return item
@ -58,63 +60,63 @@ class plotTreeView(QTreeWidget):
r = find(item.child(i), ID) r = find(item.child(i), ID)
if r: if r:
return r return r
return find(self.invisibleRootItem(), ID) return find(self.invisibleRootItem(), ID)
def currentPlotIndex(self): def currentPlotIndex(self):
"Returns index of the current item in plot model." "Returns index of the current item in plot model."
ID = None ID = None
if self.currentItem(): if self.currentItem():
ID = self.currentItem().data(0, Qt.UserRole) ID = self.currentItem().data(0, Qt.UserRole)
return self._model.getIndexFromID(ID) return self._model.getIndexFromID(ID)
############################################################################### ###############################################################################
# UPDATES # UPDATES
############################################################################### ###############################################################################
def updateMaybe(self, topLeft, bottomRight): def updateMaybe(self, topLeft, bottomRight):
if topLeft.parent() != QModelIndex(): if topLeft.parent() != QModelIndex():
return return
if topLeft.column() <= Plot.name.value <= bottomRight.column(): if topLeft.column() <= Plot.name.value <= bottomRight.column():
# Update name # Update name
self.updateNames() self.updateNames()
elif topLeft.column() <= Plot.importance.value <= bottomRight.column(): elif topLeft.column() <= Plot.importance.value <= bottomRight.column():
# Importance changed # Importance changed
self.updateItems() self.updateItems()
def updateMaybe2(self, parent, first, last): def updateMaybe2(self, parent, first, last):
"Rows inserted or removed" "Rows inserted or removed"
if parent == QModelIndex(): if parent == QModelIndex():
self.updateItems() self.updateItems()
elif self._showSubPlot: elif self._showSubPlot:
self.updateItems() self.updateItems()
def updateNames(self): def updateNames(self):
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 c in range(item.childCount()):
sub = item.child(c) sub = item.child(c)
ID = sub.data(0, Qt.UserRole) ID = sub.data(0, Qt.UserRole)
if ID: if ID:
name = self._model.getPlotNameByID(ID) name = self._model.getPlotNameByID(ID)
sub.setText(0, name) sub.setText(0, name)
def updateItems(self): def updateItems(self):
if not self._model: if not self._model:
return return
if self.currentItem(): if self.currentItem():
self._lastID = self.currentItem().data(0, Qt.UserRole) self._lastID = self.currentItem().data(0, Qt.UserRole)
self._updating = True self._updating = True
self.clear() self.clear()
plots = self._model.getPlotsByImportance() plots = self._model.getPlotsByImportance()
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):
cat = QTreeWidgetItem(self, [h[i]]) cat = QTreeWidgetItem(self, [h[i]])
@ -126,71 +128,71 @@ class plotTreeView(QTreeWidget):
cat.setFont(0, f) cat.setFont(0, f)
cat.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) cat.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
self.addTopLevelItem(cat) self.addTopLevelItem(cat)
#cat.setChildIndicatorPolicy(cat.DontShowIndicator) # cat.setChildIndicatorPolicy(cat.DontShowIndicator)
for ID in plots[i]: for ID in plots[i]:
name = self._model.getPlotNameByID(ID) name = self._model.getPlotNameByID(ID)
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, ID)
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
if self._showSubPlot: if self._showSubPlot:
f = item.font(0) f = item.font(0)
f.setBold(True) f.setBold(True)
item.setFont(0, f) item.setFont(0, f)
for subID, name, summary in self._model.getSubPlotsByID(ID): for subID, name, summary in self._model.getSubPlotsByID(ID):
sub = QTreeWidgetItem(item, [name]) sub = QTreeWidgetItem(item, [name])
#sub.setData(0, Qt.UserRole, "{}:{}".format(ID, subID)) # sub.setData(0, Qt.UserRole, "{}:{}".format(ID, subID))
sub.setData(0, Qt.UserRole, ID) sub.setData(0, Qt.UserRole, ID)
if ID == self._lastID: if ID == self._lastID:
self.setCurrentItem(item) self.setCurrentItem(item)
self.expandAll() self.expandAll()
self._updating = False self._updating = False
############################################################################### ###############################################################################
# DRAG N DROP # DRAG N DROP
############################################################################### ###############################################################################
def mimeTypes(self): def mimeTypes(self):
return ["application/xml"] return ["application/xml"]
def mimeData(self, items): def mimeData(self, items):
mimeData = QMimeData() mimeData = QMimeData()
encodedData = "" encodedData = ""
root = ET.Element("outlineItems") root = ET.Element("outlineItems")
for item in items: for item in items:
plotID = item.data(0, Qt.UserRole) plotID = item.data(0, Qt.UserRole)
subplotRaw = item.parent().indexOfChild(item) subplotRaw = item.parent().indexOfChild(item)
_id, name, summary = self._model.getSubPlotsByID(plotID)[subplotRaw] _id, name, summary = self._model.getSubPlotsByID(plotID)[subplotRaw]
sub = ET.Element("outlineItem") sub = ET.Element("outlineItem")
sub.set(Outline.title.name, name) sub.set(Outline.title.name, name)
sub.set(Outline.type.name, settings.defaultTextType) sub.set(Outline.type.name, settings.defaultTextType)
sub.set(Outline.summaryFull.name, summary) sub.set(Outline.summaryFull.name, summary)
sub.set(Outline.notes.name, self.tr("**Plot:** {}").format( sub.set(Outline.notes.name, self.tr("**Plot:** {}").format(
Ref.plotReference(plotID))) Ref.plotReference(plotID)))
root.append(sub)
encodedData = ET.tostring(root)
mimeData.setData("application/xml", encodedData)
return mimeData
############################################################################### root.append(sub)
# EVENTS
############################################################################### encodedData = ET.tostring(root)
mimeData.setData("application/xml", encodedData)
return mimeData
###############################################################################
# EVENTS
###############################################################################
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
if item.parent(): if item.parent():
QTreeWidget.mouseDoubleClickEvent(self, event) QTreeWidget.mouseDoubleClickEvent(self, event)

View file

@ -1,17 +1,17 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtWidgets import QWidget
from qt import *
from enums import * from manuskript.enums import Outline
from ui.views.propertiesView_ui import * from manuskript.ui.views.propertiesView_ui import Ui_propertiesView
class propertiesView(QWidget, Ui_propertiesView): class propertiesView(QWidget, Ui_propertiesView):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self) QWidget.__init__(self)
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, mdlPersos, mdlLabels, mdlStatus):
self.cmbPOV.setModels(mdlPersos, mdlOutline) self.cmbPOV.setModels(mdlPersos, mdlOutline)
self.cmbLabel.setModels(mdlLabels, mdlOutline) self.cmbLabel.setModels(mdlLabels, mdlOutline)
@ -20,27 +20,27 @@ class propertiesView(QWidget, Ui_propertiesView):
self.chkCompile.setModel(mdlOutline) self.chkCompile.setModel(mdlOutline)
self.txtTitle.setModel(mdlOutline) self.txtTitle.setModel(mdlOutline)
self.txtGoal.setModel(mdlOutline) self.txtGoal.setModel(mdlOutline)
def getIndexes(self, sourceView): def getIndexes(self, sourceView):
"Returns a list of indexes from list of QItemSelectionRange" """Returns a list of indexes from list of QItemSelectionRange"""
indexes = [] indexes = []
for i in sourceView.selectionModel().selection().indexes(): for i in sourceView.selectionModel().selection().indexes():
if i.column() != 0: if i.column() != 0:
continue continue
if i not in indexes: if i not in indexes:
indexes.append(i) indexes.append(i)
return indexes return indexes
def selectionChanged(self, sourceView): def selectionChanged(self, sourceView):
indexes = self.getIndexes(sourceView) indexes = self.getIndexes(sourceView)
#print(indexes) # print(indexes)
if len(indexes) == 0: if len(indexes) == 0:
self.setEnabled(False) self.setEnabled(False)
elif len(indexes) == 1: elif len(indexes) == 1:
self.setEnabled(True) self.setEnabled(True)
self.setLabelsItalic(False) self.setLabelsItalic(False)
@ -51,9 +51,9 @@ class propertiesView(QWidget, Ui_propertiesView):
self.chkCompile.setCurrentModelIndex(idx) self.chkCompile.setCurrentModelIndex(idx)
self.txtTitle.setCurrentModelIndex(idx) self.txtTitle.setCurrentModelIndex(idx)
self.txtGoal.setCurrentModelIndex(idx) self.txtGoal.setCurrentModelIndex(idx)
self.cmbType.setCurrentModelIndex(idx) self.cmbType.setCurrentModelIndex(idx)
else: else:
self.setEnabled(True) self.setEnabled(True)
self.setLabelsItalic(True) self.setLabelsItalic(True)
@ -63,9 +63,9 @@ class propertiesView(QWidget, Ui_propertiesView):
self.cmbPOV.setCurrentModelIndexes(indexes) self.cmbPOV.setCurrentModelIndexes(indexes)
self.cmbLabel.setCurrentModelIndexes(indexes) self.cmbLabel.setCurrentModelIndexes(indexes)
self.cmbStatus.setCurrentModelIndexes(indexes) self.cmbStatus.setCurrentModelIndexes(indexes)
self.cmbType.setCurrentModelIndexes(indexes) self.cmbType.setCurrentModelIndexes(indexes)
def setLabelsItalic(self, value): def setLabelsItalic(self, value):
f = self.lblPOV.font() f = self.lblPOV.font()
f.setItalic(value) f.setItalic(value)
@ -75,5 +75,5 @@ class propertiesView(QWidget, Ui_propertiesView):
self.lblLabel, self.lblLabel,
self.lblCompile, self.lblCompile,
self.lblGoal self.lblGoal
]: ]:
lbl.setFont(f) lbl.setFont(f)

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 by: PyQt5 UI code generator 5.4.1 # Created by: PyQt5 UI code generator 5.4.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -107,8 +107,8 @@ class Ui_propertiesView(object):
self.page_2 = QtWidgets.QWidget() self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2") self.page_2.setObjectName("page_2")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page_2) self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page_2)
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_3.setObjectName("verticalLayout_3")
self.formLayout_2 = QtWidgets.QFormLayout() self.formLayout_2 = QtWidgets.QFormLayout()
self.formLayout_2.setObjectName("formLayout_2") self.formLayout_2.setObjectName("formLayout_2")
@ -194,9 +194,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 ui.views.lineEditView import lineEditView from manuskript.ui.views.chkOutlineCompile import chkOutlineCompile
from ui.views.chkOutlineCompile import chkOutlineCompile from manuskript.ui.views.cmbOutlineLabelChoser import cmbOutlineLabelChoser
from ui.views.cmbOutlineTypeChoser import cmbOutlineTypeChoser from manuskript.ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser
from ui.views.cmbOutlineLabelChoser import cmbOutlineLabelChoser from manuskript.ui.views.cmbOutlineStatusChoser import cmbOutlineStatusChoser
from ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser from manuskript.ui.views.cmbOutlineTypeChoser import cmbOutlineTypeChoser
from ui.views.cmbOutlineStatusChoser import cmbOutlineStatusChoser from manuskript.ui.views.lineEditView import lineEditView

View file

@ -297,32 +297,32 @@
<customwidget> <customwidget>
<class>lineEditView</class> <class>lineEditView</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
<header>ui.views.lineEditView.h</header> <header>manuskript.ui.views.lineEditView.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlinePersoChoser</class> <class>cmbOutlinePersoChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>ui.views.cmbOutlinePersoChoser.h</header> <header>manuskript.ui.views.cmbOutlinePersoChoser.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlineStatusChoser</class> <class>cmbOutlineStatusChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>ui.views.cmbOutlineStatusChoser.h</header> <header>manuskript.ui.views.cmbOutlineStatusChoser.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>chkOutlineCompile</class> <class>chkOutlineCompile</class>
<extends>QCheckBox</extends> <extends>QCheckBox</extends>
<header>ui.views.chkOutlineCompile.h</header> <header>manuskript.ui.views.chkOutlineCompile.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlineLabelChoser</class> <class>cmbOutlineLabelChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>ui.views.cmbOutlineLabelChoser.h</header> <header>manuskript.ui.views.cmbOutlineLabelChoser.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>cmbOutlineTypeChoser</class> <class>cmbOutlineTypeChoser</class>
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>ui.views.cmbOutlineTypeChoser.h</header> <header>manuskript.ui.views.cmbOutlineTypeChoser.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -1,53 +1,55 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from functions import *
from ui.views.textEditView import *
from ui.editors.completer import *
import models.references as Ref
import settings
import re import re
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextCursor, QFont, QFontMetrics
from PyQt5.QtWidgets import QAction, qApp, QToolTip, QTextEdit
from manuskript.ui.editors.completer import completer
from manuskript.ui.views.textEditView import textEditView
from manuskript.models import references as Ref
try: try:
import enchant import enchant
except ImportError: except ImportError:
enchant = None enchant = None
class textEditCompleter(textEditView): class textEditCompleter(textEditView):
def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="",
def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="", autoResize=False): autoResize=False):
textEditView.__init__(self, parent=parent, index=index, html=html, spellcheck=spellcheck, highlighting=True, dict=dict, autoResize=autoResize) textEditView.__init__(self, parent=parent, index=index, html=html, spellcheck=spellcheck, highlighting=True,
dict=dict, autoResize=autoResize)
self.completer = None self.completer = None
self.setMouseTracking(True) self.setMouseTracking(True)
self.refRects = [] self.refRects = []
self.textChanged.connect(self.getRefRects) self.textChanged.connect(self.getRefRects)
self.document().documentLayoutChanged.connect(self.getRefRects) self.document().documentLayoutChanged.connect(self.getRefRects)
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
textEditView.setCurrentModelIndex(self, index) textEditView.setCurrentModelIndex(self, index)
if self._index and not self.completer: if self._index and not self.completer:
self.setCompleter(completer()) self.setCompleter(completer())
def setCompleter(self, completer): def setCompleter(self, completer):
self.completer = completer self.completer = completer
self.completer.activated.connect(self.insertCompletion) self.completer.activated.connect(self.insertCompletion)
def insertCompletion(self, txt): def insertCompletion(self, txt):
tc = self.textCursor() tc = self.textCursor()
tc.insertText(txt) tc.insertText(txt)
self.setTextCursor(tc) self.setTextCursor(tc)
def textUnderCursor(self, select=False): def textUnderCursor(self, select=False):
tc = self.textCursor() tc = self.textCursor()
tc.select(QTextCursor.WordUnderCursor) tc.select(QTextCursor.WordUnderCursor)
if select: if select:
self.setTextCursor(tc) self.setTextCursor(tc)
return tc.selectedText() return tc.selectedText()
def refUnderCursor(self, cursor): def refUnderCursor(self, cursor):
pos = cursor.position() pos = cursor.position()
cursor.select(QTextCursor.BlockUnderCursor) cursor.select(QTextCursor.BlockUnderCursor)
@ -57,27 +59,27 @@ class textEditCompleter(textEditView):
for m in match: for m in match:
if text.find(m) <= pos <= text.find(m) + len(m): if text.find(m) <= pos <= text.find(m) + len(m):
return m return m
#def event(self, event): # def event(self, event):
#if event.type() == QEvent.ToolTip: # if event.type() == QEvent.ToolTip:
#cursor = self.cursorForPosition(event.pos()) # cursor = self.cursorForPosition(event.pos())
#ref = self.refUnderCursor(cursor) # ref = self.refUnderCursor(cursor)
#if ref: # if ref:
#QToolTip.showText(self.mapToGlobal(event.pos()), infoForRef(ref)) # QToolTip.showText(self.mapToGlobal(event.pos()), infoForRef(ref))
#else: # else:
#QToolTip.hideText() # QToolTip.hideText()
#return True # return True
#return textEditView.event(self, event) # return textEditView.event(self, event)
def createStandardContextMenu(self): def createStandardContextMenu(self):
menu = textEditView.createStandardContextMenu(self) menu = textEditView.createStandardContextMenu(self)
a = QAction(self.tr("Insert reference"), menu) a = QAction(self.tr("Insert reference"), menu)
a.triggered.connect(self.popupCompleter) a.triggered.connect(self.popupCompleter)
menu.insertSeparator(menu.actions()[0]) menu.insertSeparator(menu.actions()[0])
menu.insertAction(menu.actions()[0], a) menu.insertAction(menu.actions()[0], a)
return menu return menu
def keyPressEvent(self, event): def keyPressEvent(self, event):
if self.completer.isVisible(): if self.completer.isVisible():
if event.key() in ( if event.key() in (
@ -88,17 +90,17 @@ class textEditCompleter(textEditView):
Qt.Key_Backtab): Qt.Key_Backtab):
event.ignore() event.ignore()
return return
isShortcut = (event.modifiers() == Qt.ControlModifier and\ isShortcut = (event.modifiers() == Qt.ControlModifier and \
event.key() == Qt.Key_Space) event.key() == Qt.Key_Space)
if not self.completer or not isShortcut: if not self.completer or not isShortcut:
self.completer.setVisible(False) self.completer.setVisible(False)
textEditView.keyPressEvent(self, event) textEditView.keyPressEvent(self, event)
return return
self.popupCompleter() self.popupCompleter()
def popupCompleter(self): def popupCompleter(self):
if self.completer: if self.completer:
cr = self.cursorRect() cr = self.cursorRect()
@ -106,24 +108,24 @@ class textEditCompleter(textEditView):
cr.setWidth(self.completer.sizeHint().width()) cr.setWidth(self.completer.sizeHint().width())
self.completer.setGeometry(cr) self.completer.setGeometry(cr)
self.completer.popup(self.textUnderCursor(select=True)) self.completer.popup(self.textUnderCursor(select=True))
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
textEditView.mouseMoveEvent(self, event) textEditView.mouseMoveEvent(self, event)
onRef = [r for r in self.refRects if r.contains(event.pos())] onRef = [r for r in self.refRects if r.contains(event.pos())]
if not onRef: if not onRef:
qApp.restoreOverrideCursor() qApp.restoreOverrideCursor()
QToolTip.hideText() QToolTip.hideText()
return return
cursor = self.cursorForPosition(event.pos()) cursor = self.cursorForPosition(event.pos())
ref = self.refUnderCursor(cursor) ref = self.refUnderCursor(cursor)
if ref: if ref:
if not qApp.overrideCursor(): if not qApp.overrideCursor():
qApp.setOverrideCursor(Qt.PointingHandCursor) qApp.setOverrideCursor(Qt.PointingHandCursor)
QToolTip.showText(self.mapToGlobal(event.pos()), Ref.tooltip(ref)) QToolTip.showText(self.mapToGlobal(event.pos()), Ref.tooltip(ref))
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
textEditView.mouseReleaseEvent(self, event) textEditView.mouseReleaseEvent(self, event)
onRef = [r for r in self.refRects if r.contains(event.pos())] onRef = [r for r in self.refRects if r.contains(event.pos())]
@ -133,11 +135,11 @@ class textEditCompleter(textEditView):
if ref: if ref:
Ref.open(ref) Ref.open(ref)
qApp.restoreOverrideCursor() qApp.restoreOverrideCursor()
def resizeEvent(self, event): def resizeEvent(self, event):
textEditView.resizeEvent(self, event) textEditView.resizeEvent(self, event)
self.getRefRects() self.getRefRects()
def getRefRects(self): def getRefRects(self):
cursor = self.textCursor() cursor = self.textCursor()
f = self.font() f = self.font()
@ -151,12 +153,12 @@ class textEditCompleter(textEditView):
r.setWidth(fm.width(txt.group(0))) r.setWidth(fm.width(txt.group(0)))
refs.append(r) refs.append(r)
self.refRects = refs self.refRects = refs
def paintEvent(self, event): def paintEvent(self, event):
QTextEdit.paintEvent(self, event) QTextEdit.paintEvent(self, event)
# Debug: paint rects # Debug: paint rects
#painter = QPainter(self.viewport()) # painter = QPainter(self.viewport())
#painter.setPen(Qt.gray) # painter.setPen(Qt.gray)
#for r in self.refRects: # for r in self.refRects:
#painter.drawRect(r) # painter.drawRect(r)

View file

@ -1,25 +1,31 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from enums import *
from ui.editors.t2tHighlighter import *
from ui.editors.t2tFunctions import *
from ui.editors.basicHighlighter import *
from ui.editors.textFormat import *
from models.outlineModel import *
from functions import *
import settings
import re import re
from PyQt5.QtCore import QTimer, QModelIndex, Qt, QEvent, pyqtSignal, QRegExp
from PyQt5.QtGui import QTextBlockFormat, QTextCharFormat, QFont, QColor, QMouseEvent, QTextCursor
from PyQt5.QtWidgets import QTextEdit, qApp, QAction, QMenu
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import AUC
from manuskript.functions import toString
from manuskript.models.outlineModel import outlineModel
from manuskript.ui.editors.basicHighlighter import basicHighlighter
from manuskript.ui.editors.t2tFunctions import t2tClearFormat
from manuskript.ui.editors.t2tFunctions import t2tFormatSelection
from manuskript.ui.editors.t2tHighlighter import t2tHighlighter
from manuskript.ui.editors.textFormat import textFormat
try: try:
import enchant import enchant
except ImportError: except ImportError:
enchant = None enchant = None
class textEditView(QTextEdit): class textEditView(QTextEdit):
def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="",
def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="", autoResize=False): autoResize=False):
QTextEdit.__init__(self, parent) QTextEdit.__init__(self, parent)
self._column = Outline.text.value self._column = Outline.text.value
self._index = None self._index = None
@ -32,8 +38,8 @@ class textEditView(QTextEdit):
self._textFormat = "text" self._textFormat = "text"
self.setAcceptRichText(False) self.setAcceptRichText(False)
# When setting up a theme, this becomes true. # When setting up a theme, this becomes true.
self._fromTheme = False self._fromTheme = False
self.spellcheck = spellcheck self.spellcheck = spellcheck
self.currentDict = dict if dict else settings.dict self.currentDict = dict if dict else settings.dict
self.highlighter = None self.highlighter = None
@ -44,41 +50,40 @@ class textEditView(QTextEdit):
self.highligtCS = False self.highligtCS = False
self.defaultFontPointSize = qApp.font().pointSize() self.defaultFontPointSize = qApp.font().pointSize()
self._dict = None self._dict = None
#self.document().contentsChanged.connect(self.submit, AUC) # self.document().contentsChanged.connect(self.submit, AUC)
# Submit text changed only after 500ms without modifications # Submit text changed only after 500ms without modifications
self.updateTimer = QTimer() self.updateTimer = QTimer()
self.updateTimer.setInterval(500) self.updateTimer.setInterval(500)
self.updateTimer.setSingleShot(True) self.updateTimer.setSingleShot(True)
self.updateTimer.timeout.connect(self.submit) self.updateTimer.timeout.connect(self.submit)
#self.updateTimer.timeout.connect(lambda: print("Timeout")) # self.updateTimer.timeout.connect(lambda: print("Timeout"))
self.updateTimer.stop() self.updateTimer.stop()
self.document().contentsChanged.connect(self.updateTimer.start, AUC) self.document().contentsChanged.connect(self.updateTimer.start, AUC)
#self.document().contentsChanged.connect(lambda: print("Document changed")) # self.document().contentsChanged.connect(lambda: print("Document changed"))
#self.document().contentsChanged.connect(lambda: print(self.objectName(), "Contents changed")) # self.document().contentsChanged.connect(lambda: print(self.objectName(), "Contents changed"))
self.setEnabled(False) self.setEnabled(False)
if index: if index:
self.setCurrentModelIndex(index) self.setCurrentModelIndex(index)
elif html: elif html:
self.document().setHtml(html) self.document().setHtml(html)
self.setReadOnly(True) self.setReadOnly(True)
# Spellchecking # Spellchecking
if enchant and self.spellcheck: if enchant and self.spellcheck:
self._dict = enchant.Dict(self.currentDict if self.currentDict else enchant.get_default_language()) self._dict = enchant.Dict(self.currentDict if self.currentDict else enchant.get_default_language())
else: else:
self.spellcheck = False self.spellcheck = False
if self._highlighting and not self.highlighter: if self._highlighting and not self.highlighter:
self.highlighter = basicHighlighter(self) self.highlighter = basicHighlighter(self)
self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat) self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat)
def setModel(self, model): def setModel(self, model):
self._model = model self._model = model
try: try:
@ -89,18 +94,18 @@ class textEditView(QTextEdit):
self._model.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC) self._model.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC)
except TypeError: except TypeError:
pass pass
def setColumn(self, col): def setColumn(self, col):
self._column = col self._column = col
def setHighlighting(self, val): def setHighlighting(self, val):
self._highlighting = val self._highlighting = val
def setDefaultBlockFormat(self, bf): def setDefaultBlockFormat(self, bf):
self._defaultBlockFormat = bf self._defaultBlockFormat = bf
if self.highlighter: if self.highlighter:
self.highlighter.setDefaultBlockFormat(bf) self.highlighter.setDefaultBlockFormat(bf)
def setCurrentModelIndex(self, index): def setCurrentModelIndex(self, index):
self._indexes = None self._indexes = None
if index.isValid(): if index.isValid():
@ -108,9 +113,9 @@ class textEditView(QTextEdit):
if index.column() != self._column: if index.column() != self._column:
index = index.sibling(index.row(), self._column) index = index.sibling(index.row(), self._column)
self._index = index self._index = index
self.setPlaceholderText(self._placeholderText) self.setPlaceholderText(self._placeholderText)
if not self._model: if not self._model:
self.setModel(index.model()) self.setModel(index.model())
@ -123,32 +128,32 @@ class textEditView(QTextEdit):
self.setPlainText("") self.setPlainText("")
self.setEnabled(False) self.setEnabled(False)
def setCurrentModelIndexes(self, indexes): def setCurrentModelIndexes(self, indexes):
self._index = None self._index = None
self._indexes = [] self._indexes = []
for i in indexes: for i in indexes:
if i.isValid(): if i.isValid():
self.setEnabled(True) self.setEnabled(True)
if i.column() != self._column: if i.column() != self._column:
i = i.sibling(i.row(), self._column) i = i.sibling(i.row(), self._column)
self._indexes.append(i) self._indexes.append(i)
if not self._model: if not self._model:
self.setModel(i.model()) self.setModel(i.model())
self.updateText() self.updateText()
def setupEditorForIndex(self, index): def setupEditorForIndex(self, index):
# what type of text are we editing? # what type of text are we editing?
if type(index.model()) != outlineModel: if type(index.model()) != outlineModel:
self._textFormat = "text" self._textFormat = "text"
return return
if self._column not in [Outline.text.value, Outline.notes.value]: if self._column not in [Outline.text.value, Outline.notes.value]:
self._textFormat = "text" self._textFormat = "text"
else: else:
item = index.internalPointer() item = index.internalPointer()
if item.isHTML(): if item.isHTML():
@ -157,13 +162,13 @@ class textEditView(QTextEdit):
self._textFormat = "t2t" self._textFormat = "t2t"
else: else:
self._textFormat = "text" self._textFormat = "text"
# Accept richtext maybe # Accept richtext maybe
if self._textFormat == "html": if self._textFormat == "html":
self.setAcceptRichText(True) self.setAcceptRichText(True)
else: else:
self.setAcceptRichText(False) self.setAcceptRichText(False)
# Setting highlighter # Setting highlighter
if self._highlighting: if self._highlighting:
item = index.internalPointer() item = index.internalPointer()
@ -171,20 +176,20 @@ class textEditView(QTextEdit):
self.highlighter = basicHighlighter(self) self.highlighter = basicHighlighter(self)
else: else:
self.highlighter = t2tHighlighter(self) self.highlighter = t2tHighlighter(self)
self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat) self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat)
def loadFontSettings(self): def loadFontSettings(self):
if self._fromTheme or \ if self._fromTheme or \
not self._index or \ not self._index or \
type(self._index.model()) != outlineModel or \ type(self._index.model()) != outlineModel or \
self._column != Outline.text.value: self._column != Outline.text.value:
return return
opt = settings.textEditor opt = settings.textEditor
f = QFont() f = QFont()
f.fromString(opt["font"]) f.fromString(opt["font"])
#self.setFont(f) # self.setFont(f)
self.setStyleSheet(""" self.setStyleSheet("""
background: {bg}; background: {bg};
color: {foreground}; color: {foreground};
@ -195,52 +200,52 @@ class textEditView(QTextEdit):
foreground=opt["fontColor"], foreground=opt["fontColor"],
ff=f.family(), ff=f.family(),
fs="{}pt".format(str(f.pointSize())))) fs="{}pt".format(str(f.pointSize()))))
cf = QTextCharFormat() cf = QTextCharFormat()
#cf.setFont(f) # cf.setFont(f)
#cf.setForeground(QColor(opt["fontColor"])) # cf.setForeground(QColor(opt["fontColor"]))
bf = QTextBlockFormat() bf = QTextBlockFormat()
bf.setLineHeight(opt["lineSpacing"], bf.ProportionalHeight) bf.setLineHeight(opt["lineSpacing"], bf.ProportionalHeight)
bf.setTextIndent(opt["tabWidth"] * 1 if opt["indent"] else 0) bf.setTextIndent(opt["tabWidth"] * 1 if opt["indent"] else 0)
bf.setTopMargin(opt["spacingAbove"]) bf.setTopMargin(opt["spacingAbove"])
bf.setBottomMargin(opt["spacingBelow"]) bf.setBottomMargin(opt["spacingBelow"])
self._defaultCharFormat = cf self._defaultCharFormat = cf
self._defaultBlockFormat = bf self._defaultBlockFormat = bf
if self.highlighter: if self.highlighter:
self.highlighter.setMisspelledColor(QColor(opt["misspelled"])) self.highlighter.setMisspelledColor(QColor(opt["misspelled"]))
self.highlighter.setDefaultCharFormat(self._defaultCharFormat) self.highlighter.setDefaultCharFormat(self._defaultCharFormat)
self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat) self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat)
def update(self, topLeft, bottomRight): def update(self, topLeft, bottomRight):
if self._updating: if self._updating:
return return
elif self._index: elif self._index:
if topLeft.parent() != self._index.parent(): if topLeft.parent() != self._index.parent():
return return
#print("Model changed: ({}:{}), ({}:{}/{}), ({}:{}) for {} of {}".format( # print("Model changed: ({}:{}), ({}:{}/{}), ({}:{}) for {} of {}".format(
#topLeft.row(), topLeft.column(), # topLeft.row(), topLeft.column(),
#self._index.row(), self._index.row(), self._column, # self._index.row(), self._index.row(), self._column,
#bottomRight.row(), bottomRight.column(), # bottomRight.row(), bottomRight.column(),
#self.objectName(), self.parent().objectName())) # self.objectName(), self.parent().objectName()))
if topLeft.row() <= self._index.row() <= bottomRight.row(): if topLeft.row() <= self._index.row() <= bottomRight.row():
if self._column == Outline.text.value and \ if self._column == Outline.text.value and \
topLeft.column() <= Outline.type.value <= bottomRight.column(): topLeft.column() <= Outline.type.value <= bottomRight.column():
# If item type change, and we display the main text, # If item type change, and we display the main text,
# we reset the index to set the proper # we reset the index to set the proper
# highlighter and other defaults # highlighter and other defaults
self.setupEditorForIndex(self._index) self.setupEditorForIndex(self._index)
self.updateText() self.updateText()
elif topLeft.column() <= self._column <= bottomRight.column(): elif topLeft.column() <= self._column <= bottomRight.column():
self.updateText() self.updateText()
elif self._indexes: elif self._indexes:
update = False update = False
for i in self._indexes: for i in self._indexes:
@ -248,43 +253,43 @@ class textEditView(QTextEdit):
update = True update = True
if update: if update:
self.updateText() self.updateText()
def rowsAboutToBeRemoved(self, parent, first, last): def rowsAboutToBeRemoved(self, parent, first, last):
if self._index: if self._index:
if self._index.parent() == parent and \ if self._index.parent() == parent and \
first <= self._index.row() <= last: first <= self._index.row() <= last:
self._index = None self._index = None
self.setEnabled(False) self.setEnabled(False)
#FIXME: self._indexes # FIXME: self._indexes
def disconnectDocument(self): def disconnectDocument(self):
try: try:
self.document().contentsChanged.disconnect(self.updateTimer.start) self.document().contentsChanged.disconnect(self.updateTimer.start)
except: except:
pass pass
def reconnectDocument(self): def reconnectDocument(self):
self.document().contentsChanged.connect(self.updateTimer.start, AUC) self.document().contentsChanged.connect(self.updateTimer.start, AUC)
def updateText(self): def updateText(self):
if self._updating: if self._updating:
return return
#print("Updating", self.objectName()) # print("Updating", self.objectName())
self._updating = True self._updating = True
if self._index: if self._index:
self.disconnectDocument() self.disconnectDocument()
if self._textFormat == "html": if self._textFormat == "html":
if self.toHtml() != toString(self._model.data(self._index)): if self.toHtml() != toString(self._model.data(self._index)):
#print(" Updating html") # print(" Updating html")
html = self._model.data(self._index) html = self._model.data(self._index)
self.document().setHtml(toString(html)) self.document().setHtml(toString(html))
else: else:
if self.toPlainText() != toString(self._model.data(self._index)): if self.toPlainText() != toString(self._model.data(self._index)):
#print(" Updating plaintext") # print(" Updating plaintext")
self.document().setPlainText(toString(self._model.data(self._index))) self.document().setPlainText(toString(self._model.data(self._index)))
self.reconnectDocument() self.reconnectDocument()
elif self._indexes: elif self._indexes:
self.disconnectDocument() self.disconnectDocument()
t = [] t = []
@ -292,35 +297,35 @@ class textEditView(QTextEdit):
for i in self._indexes: for i in self._indexes:
item = i.internalPointer() item = i.internalPointer()
t.append(toString(item.data(self._column))) t.append(toString(item.data(self._column)))
for t2 in t[1:]: for t2 in t[1:]:
if t2 != t[0]: if t2 != t[0]:
same = False same = False
break break
if same: if same:
# Assuming that we don't use HTML with multiple items # Assuming that we don't use HTML with multiple items
self.document().setPlainText(t[0]) self.document().setPlainText(t[0])
else: else:
self.document().setPlainText("") self.document().setPlainText("")
if not self._placeholderText: if not self._placeholderText:
self._placeholderText = self.placeholderText() self._placeholderText = self.placeholderText()
self.setPlaceholderText(self.tr("Various")) self.setPlaceholderText(self.tr("Various"))
self.reconnectDocument() self.reconnectDocument()
self._updating = False self._updating = False
def submit(self): def submit(self):
self.updateTimer.stop() self.updateTimer.stop()
if self._updating: if self._updating:
return return
#print("Submitting", self.objectName()) # print("Submitting", self.objectName())
if self._index: if self._index:
#item = self._index.internalPointer() # item = self._index.internalPointer()
if self._textFormat == "html": if self._textFormat == "html":
if self.toHtml() != self._model.data(self._index): if self.toHtml() != self._model.data(self._index):
#print(" Submitting html") # print(" Submitting html")
self._updating = True self._updating = True
html = self.toHtml() html = self.toHtml()
# We don't store paragraph and font settings # We don't store paragraph and font settings
@ -329,16 +334,16 @@ class textEditView(QTextEdit):
html = re.sub(r"margin-.*?;\s*", "", html) html = re.sub(r"margin-.*?;\s*", "", html)
html = re.sub(r"text-indent:.*?;\s*", "", html) html = re.sub(r"text-indent:.*?;\s*", "", html)
html = re.sub(r"line-height:.*?;\s*", "", html) html = re.sub(r"line-height:.*?;\s*", "", html)
#print("Submitting:", html) # print("Submitting:", html)
self._model.setData(self._index, html) self._model.setData(self._index, html)
self._updating = False self._updating = False
else: else:
if self.toPlainText() != self._model.data(self._index): if self.toPlainText() != self._model.data(self._index):
#print(" Submitting plain text") # print(" Submitting plain text")
self._updating = True self._updating = True
self._model.setData(self._index, self.toPlainText()) self._model.setData(self._index, self.toPlainText())
self._updating = False self._updating = False
elif self._indexes: elif self._indexes:
self._updating = True self._updating = True
for i in self._indexes: for i in self._indexes:
@ -347,15 +352,15 @@ class textEditView(QTextEdit):
print("Submitting many indexes") print("Submitting many indexes")
self._model.setData(i, self.toPlainText()) self._model.setData(i, self.toPlainText())
self._updating = False self._updating = False
def keyPressEvent(self, event): def keyPressEvent(self, event):
QTextEdit.keyPressEvent(self, event) QTextEdit.keyPressEvent(self, event)
if event.key() == Qt.Key_Space: if event.key() == Qt.Key_Space:
self.submit() self.submit()
# ----------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------
# Resize stuff # Resize stuff
def resizeEvent(self, e): def resizeEvent(self, e):
QTextEdit.resizeEvent(self, e) QTextEdit.resizeEvent(self, e)
if self._autoResize: if self._autoResize:
@ -365,7 +370,7 @@ class textEditView(QTextEdit):
docHeight = self.document().size().height() docHeight = self.document().size().height()
if self.heightMin <= docHeight <= self.heightMax: if self.heightMin <= docHeight <= self.heightMax:
self.setMinimumHeight(docHeight) self.setMinimumHeight(docHeight)
def setAutoResize(self, val): def setAutoResize(self, val):
self._autoResize = val self._autoResize = val
if self._autoResize: if self._autoResize:
@ -373,18 +378,18 @@ class textEditView(QTextEdit):
self.heightMin = 0 self.heightMin = 0
self.heightMax = 65000 self.heightMax = 65000
self.sizeChange() self.sizeChange()
############################################################################### ###############################################################################
# SPELLCHECKING # SPELLCHECKING
############################################################################### ###############################################################################
# Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ # Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/
def setDict(self, d): def setDict(self, d):
self.currentDict = d self.currentDict = d
self._dict = enchant.Dict(d) self._dict = enchant.Dict(d)
if self.highlighter: if self.highlighter:
self.highlighter.rehighlight() self.highlighter.rehighlight()
def toggleSpellcheck(self, v): def toggleSpellcheck(self, v):
self.spellcheck = v self.spellcheck = v
if enchant and self.spellcheck and not self._dict: if enchant and self.spellcheck and not self._dict:
@ -399,34 +404,34 @@ class textEditView(QTextEdit):
# Rewrite the mouse event to a left button event so the cursor is # Rewrite the mouse event to a left button event so the cursor is
# moved to the location of the pointer. # moved to the location of the pointer.
event = QMouseEvent(QEvent.MouseButtonPress, event.pos(), event = QMouseEvent(QEvent.MouseButtonPress, event.pos(),
Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
QTextEdit.mousePressEvent(self, event) QTextEdit.mousePressEvent(self, event)
class SpellAction(QAction): class SpellAction(QAction):
"A special QAction that returns the text in a signal. Used for spellckech." """A special QAction that returns the text in a signal. Used for spellckech."""
correct = pyqtSignal(str) correct = pyqtSignal(str)
def __init__(self, *args): def __init__(self, *args):
QAction.__init__(self, *args) QAction.__init__(self, *args)
self.triggered.connect(lambda x: self.correct.emit( self.triggered.connect(lambda x: self.correct.emit(
str(self.text()))) str(self.text())))
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
# Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ # Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/
popup_menu = self.createStandardContextMenu() popup_menu = self.createStandardContextMenu()
popup_menu.exec_(event.globalPos()) popup_menu.exec_(event.globalPos())
def createStandardContextMenu(self): def createStandardContextMenu(self):
popup_menu = QTextEdit.createStandardContextMenu(self) popup_menu = QTextEdit.createStandardContextMenu(self)
if not self.spellcheck: if not self.spellcheck:
return popup_menu return popup_menu
# Select the word under the cursor. # Select the word under the cursor.
cursor = self.textCursor() cursor = self.textCursor()
#cursor = self.cursorForPosition(pos) # cursor = self.cursorForPosition(pos)
cursor.select(QTextCursor.WordUnderCursor) cursor.select(QTextCursor.WordUnderCursor)
self.setTextCursor(cursor) self.setTextCursor(cursor)
# Check if the selected word is misspelled and offer spelling # Check if the selected word is misspelled and offer spelling
@ -446,97 +451,97 @@ class textEditView(QTextEdit):
popup_menu.insertMenu(popup_menu.actions()[0], spell_menu) popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)
return popup_menu return popup_menu
def correctWord(self, word): def correctWord(self, word):
''' """
Replaces the selected text with word. Replaces the selected text with word.
''' """
cursor = self.textCursor() cursor = self.textCursor()
cursor.beginEditBlock() cursor.beginEditBlock()
cursor.removeSelectedText() cursor.removeSelectedText()
cursor.insertText(word) cursor.insertText(word)
cursor.endEditBlock() cursor.endEditBlock()
############################################################################### ###############################################################################
# FORMATTING # FORMATTING
############################################################################### ###############################################################################
def focusOutEvent(self, event): def focusOutEvent(self, event):
"Submit changes just before focusing out." """Submit changes just before focusing out."""
QTextEdit.focusOutEvent(self, event) QTextEdit.focusOutEvent(self, event)
self.submit() self.submit()
def focusInEvent(self, event): def focusInEvent(self, event):
"Finds textFormatter and attach them to that view." """Finds textFormatter and attach them to that view."""
QTextEdit.focusInEvent(self, event) QTextEdit.focusInEvent(self, event)
p = self.parent() p = self.parent()
while p.parent(): while p.parent():
p = p.parent() p = p.parent()
if self._index: if self._index:
for tF in p.findChildren(textFormat, QRegExp(".*"), Qt.FindChildrenRecursively): for tF in p.findChildren(textFormat, QRegExp(".*"), Qt.FindChildrenRecursively):
tF.updateFromIndex(self._index) tF.updateFromIndex(self._index)
tF.setTextEdit(self) tF.setTextEdit(self)
def applyFormat(self, _format): def applyFormat(self, _format):
if self._textFormat == "html": if self._textFormat == "html":
if _format == "Clear": if _format == "Clear":
cursor = self.textCursor() cursor = self.textCursor()
if _format == "Clear": if _format == "Clear":
fmt = self._defaultCharFormat fmt = self._defaultCharFormat
cursor.setCharFormat(fmt) cursor.setCharFormat(fmt)
bf = self._defaultBlockFormat bf = self._defaultBlockFormat
cursor.setBlockFormat(bf) cursor.setBlockFormat(bf)
elif _format in ["Bold", "Italic", "Underline"]: elif _format in ["Bold", "Italic", "Underline"]:
cursor = self.textCursor() cursor = self.textCursor()
# If no selection, selects the word in which the cursor is now # If no selection, selects the word in which the cursor is now
if not cursor.hasSelection(): if not cursor.hasSelection():
cursor.movePosition(QTextCursor.StartOfWord, cursor.movePosition(QTextCursor.StartOfWord,
QTextCursor.MoveAnchor) QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.EndOfWord, cursor.movePosition(QTextCursor.EndOfWord,
QTextCursor.KeepAnchor) QTextCursor.KeepAnchor)
fmt = cursor.charFormat() fmt = cursor.charFormat()
if _format == "Bold": if _format == "Bold":
fmt.setFontWeight(QFont.Bold if fmt.fontWeight() != QFont.Bold else QFont.Normal) fmt.setFontWeight(QFont.Bold if fmt.fontWeight() != QFont.Bold else QFont.Normal)
elif _format == "Italic": elif _format == "Italic":
fmt.setFontItalic(not fmt.fontItalic()) fmt.setFontItalic(not fmt.fontItalic())
elif _format == "Underline": elif _format == "Underline":
fmt.setFontUnderline(not fmt.fontUnderline()) fmt.setFontUnderline(not fmt.fontUnderline())
fmt2 = self._defaultCharFormat fmt2 = self._defaultCharFormat
fmt2.setFontWeight(fmt.fontWeight()) fmt2.setFontWeight(fmt.fontWeight())
fmt2.setFontItalic(fmt.fontItalic()) fmt2.setFontItalic(fmt.fontItalic())
fmt2.setFontUnderline(fmt.fontUnderline()) fmt2.setFontUnderline(fmt.fontUnderline())
cursor.mergeCharFormat(fmt2) cursor.mergeCharFormat(fmt2)
elif _format in ["Left", "Center", "Right", "Justify"]: elif _format in ["Left", "Center", "Right", "Justify"]:
cursor = self.textCursor() cursor = self.textCursor()
#bf = cursor.blockFormat() # bf = cursor.blockFormat()
bf = QTextBlockFormat() bf = QTextBlockFormat()
bf.setAlignment( bf.setAlignment(
Qt.AlignLeft if _format == "Left" else Qt.AlignLeft if _format == "Left" else
Qt.AlignHCenter if _format == "Center" else Qt.AlignHCenter if _format == "Center" else
Qt.AlignRight if _format == "Right" else Qt.AlignRight if _format == "Right" else
Qt.AlignJustify) Qt.AlignJustify)
cursor.setBlockFormat(bf) cursor.setBlockFormat(bf)
self.setTextCursor(cursor) self.setTextCursor(cursor)
elif self._textFormat == "t2t": elif self._textFormat == "t2t":
if _format == "Bold": if _format == "Bold":
t2tFormatSelection(self, 0) t2tFormatSelection(self, 0)
@ -546,6 +551,3 @@ class textEditView(QTextEdit):
t2tFormatSelection(self, 2) t2tFormatSelection(self, 2)
elif _format == "Clear": elif _format == "Clear":
t2tClearFormat(self) t2tClearFormat(self)

View file

@ -1,52 +1,58 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QColor, QPalette, QIcon, QFont, QFontMetrics
from PyQt5.QtWidgets import QStyledItemDelegate, qApp, QStyleOptionViewItem, QStyle
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import mixColors, colorifyPixmap
from manuskript.functions import outlineItemColors
from manuskript.functions import toFloat
from qt import *
from enums import *
from functions import *
import settings
class treeTitleDelegate(QStyledItemDelegate): class treeTitleDelegate(QStyledItemDelegate):
"""The main purpose of ``treeTitleDelegate`` is to paint outline items """The main purpose of ``treeTitleDelegate`` is to paint outline items
in the treeview with propers colors according to settings. in the treeview with propers colors according to settings.
""" """
def __init__(self, parent=None): def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent) QStyledItemDelegate.__init__(self, parent)
self._view = None self._view = None
def setView(self, view): def setView(self, view):
self._view = view self._view = view
def paint(self, painter, option, index): def paint(self, painter, option, index):
item = index.internalPointer() item = index.internalPointer()
colors = outlineItemColors(item) colors = outlineItemColors(item)
style = qApp.style() style = qApp.style()
opt = QStyleOptionViewItem(option) opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, index) self.initStyleOption(opt, index)
iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt) iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt)
textRect = style.subElementRect(style.SE_ItemViewItemText, opt) textRect = style.subElementRect(style.SE_ItemViewItemText, opt)
# Background # Background
style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter) style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter)
if settings.viewSettings["Tree"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected: if settings.viewSettings["Tree"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected:
col = colors[settings.viewSettings["Tree"]["Background"]] col = colors[settings.viewSettings["Tree"]["Background"]]
if col != QColor(Qt.transparent): if col != QColor(Qt.transparent):
col2 = QColor(Qt.white) col2 = QColor(Qt.white)
if opt.state & QStyle.State_Selected: if opt.state & QStyle.State_Selected:
col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color() col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color()
col = mixColors(col, col2, .2) col = mixColors(col, col2, .2)
painter.save() painter.save()
painter.setBrush(col) painter.setBrush(col)
painter.setPen(Qt.NoPen) painter.setPen(Qt.NoPen)
rect = opt.rect rect = opt.rect
if self._view: if self._view:
r2 = self._view.visualRect(index) r2 = self._view.visualRect(index)
@ -54,10 +60,10 @@ class treeTitleDelegate(QStyledItemDelegate):
rect.setLeft(r2.left()) rect.setLeft(r2.left())
rect.setTop(r2.top()) rect.setTop(r2.top())
rect.setBottom(r2.bottom()) rect.setBottom(r2.bottom())
painter.drawRoundedRect(rect, 5, 5) painter.drawRoundedRect(rect, 5, 5)
painter.restore() painter.restore()
# Icon # Icon
mode = QIcon.Normal mode = QIcon.Normal
if not opt.state & QStyle.State_Enabled: if not opt.state & QStyle.State_Enabled:
@ -71,7 +77,7 @@ class treeTitleDelegate(QStyledItemDelegate):
colorifyPixmap(icon, color) colorifyPixmap(icon, color)
opt.icon = QIcon(icon) opt.icon = QIcon(icon)
opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state) opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state)
# Text # Text
if opt.text: if opt.text:
painter.save() painter.save()
@ -85,7 +91,7 @@ class treeTitleDelegate(QStyledItemDelegate):
fm = QFontMetrics(f) fm = QFontMetrics(f)
elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width()) elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width())
painter.drawText(textRect, Qt.AlignLeft, elidedText) painter.drawText(textRect, Qt.AlignLeft, elidedText)
extraText = "" extraText = ""
if item.isFolder() and settings.viewSettings["Tree"]["InfoFolder"] != "Nothing": if item.isFolder() and settings.viewSettings["Tree"]["InfoFolder"] != "Nothing":
if settings.viewSettings["Tree"]["InfoFolder"] == "Count": if settings.viewSettings["Tree"]["InfoFolder"] == "Count":
@ -98,7 +104,7 @@ class treeTitleDelegate(QStyledItemDelegate):
extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100) extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100)
if extraText: if extraText:
extraText = " ({}%)".format(extraText) extraText = " ({}%)".format(extraText)
if item.isText() and settings.viewSettings["Tree"]["InfoText"] != "Nothing": if item.isText() and settings.viewSettings["Tree"]["InfoText"] != "Nothing":
if settings.viewSettings["Tree"]["InfoText"] == "WC": if settings.viewSettings["Tree"]["InfoText"] == "WC":
extraText = item.data(Outline.wordCount.value) extraText = item.data(Outline.wordCount.value)
@ -106,19 +112,17 @@ class treeTitleDelegate(QStyledItemDelegate):
elif settings.viewSettings["Tree"]["InfoText"] == "Progress": elif settings.viewSettings["Tree"]["InfoText"] == "Progress":
extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100) extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100)
if extraText: if extraText:
extraText = " ({}%)".format(extraText) extraText = " ({}%)".format(extraText)
if extraText: if extraText:
r = QRect(textRect) r = QRect(textRect)
r.setLeft(r.left() + fm.width(opt.text + " ")) r.setLeft(r.left() + fm.width(opt.text + " "))
painter.save() painter.save()
painter.setPen(Qt.darkGray) painter.setPen(Qt.darkGray)
painter.drawText(r, Qt.AlignLeft | Qt.AlignBottom, extraText) painter.drawText(r, Qt.AlignLeft | Qt.AlignBottom, extraText)
painter.restore() painter.restore()
painter.restore() painter.restore()
#QStyledItemDelegate.paint(self, painter, option, index) # QStyledItemDelegate.paint(self, painter, option, index)

View file

@ -1,117 +1,116 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QTreeView, QAction
from manuskript.enums import Outline
from manuskript.functions import mainWindow
from manuskript.ui.views.dndView import dndView
from manuskript.ui.views.outlineBasics import outlineBasics
from manuskript.ui.views.treeDelegates import treeTitleDelegate
from qt import *
from enums import *
from functions import *
from ui.views.dndView import *
from ui.views.outlineBasics import *
from ui.views.treeDelegates import *
class treeView(QTreeView, dndView, outlineBasics): class treeView(QTreeView, dndView, outlineBasics):
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeView.__init__(self, parent) QTreeView.__init__(self, parent)
dndView.__init__(self, parent) dndView.__init__(self, parent)
outlineBasics.__init__(self, parent) outlineBasics.__init__(self, parent)
self._indexesToOpen = None self._indexesToOpen = None
def setModel(self, model): def setModel(self, model):
QTreeView.setModel(self, model) QTreeView.setModel(self, model)
# Hiding columns # Hiding columns
for c in range(1, self.model().columnCount()): for c in range(1, self.model().columnCount()):
self.hideColumn(c) self.hideColumn(c)
# Setting delegate # Setting delegate
self.titleDelegate = treeTitleDelegate() self.titleDelegate = treeTitleDelegate()
self.setItemDelegateForColumn(Outline.title.value, self.titleDelegate) self.setItemDelegateForColumn(Outline.title.value, self.titleDelegate)
def makePopupMenu(self): def makePopupMenu(self):
menu = outlineBasics.makePopupMenu(self) menu = outlineBasics.makePopupMenu(self)
first = menu.actions()[0] first = menu.actions()[0]
# Open item in new tab # Open item in new tab
sel = self.selectedIndexes() sel = self.selectedIndexes()
pos = self.viewport().mapFromGlobal(QCursor.pos()) pos = self.viewport().mapFromGlobal(QCursor.pos())
mouseIndex = self.indexAt(pos) mouseIndex = self.indexAt(pos)
if mouseIndex.isValid(): if mouseIndex.isValid():
mouseTitle = mouseIndex.internalPointer().title() mouseTitle = mouseIndex.internalPointer().title()
else: else:
mouseTitle = self.tr("Root") mouseTitle = self.tr("Root")
if mouseIndex in sel and len(sel) > 1: if mouseIndex in sel and len(sel) > 1:
actionTitle = self.tr("Open {} items in new tabs").format(len(sel)) actionTitle = self.tr("Open {} items in new tabs").format(len(sel))
self._indexesToOpen = sel self._indexesToOpen = sel
else: else:
actionTitle = self.tr("Open {} in a new tab").format(mouseTitle) actionTitle = self.tr("Open {} in a new tab").format(mouseTitle)
self._indexesToOpen = [mouseIndex] self._indexesToOpen = [mouseIndex]
self.actNewTab = QAction(actionTitle, menu) self.actNewTab = QAction(actionTitle, menu)
self.actNewTab.triggered.connect(self.openNewTab) self.actNewTab.triggered.connect(self.openNewTab)
menu.insertAction(first, self.actNewTab) menu.insertAction(first, self.actNewTab)
menu.insertSeparator(first) menu.insertSeparator(first)
# Expand /collapse item # Expand /collapse item
if mouseIndex.isValid(): if mouseIndex.isValid():
#index = self.currentIndex() # index = self.currentIndex()
item = mouseIndex.internalPointer() item = mouseIndex.internalPointer()
self.actExpand = QAction(self.tr("Expand {}").format(item.title()), menu) self.actExpand = QAction(self.tr("Expand {}").format(item.title()), menu)
self.actExpand.triggered.connect(self.expandCurrentIndex) self.actExpand.triggered.connect(self.expandCurrentIndex)
menu.insertAction(first, self.actExpand) menu.insertAction(first, self.actExpand)
self.actCollapse = QAction(self.tr("Collapse {}").format(item.title()), menu) self.actCollapse = QAction(self.tr("Collapse {}").format(item.title()), menu)
self.actCollapse.triggered.connect(self.collapseCurrentIndex) self.actCollapse.triggered.connect(self.collapseCurrentIndex)
menu.insertAction(first, self.actCollapse) menu.insertAction(first, self.actCollapse)
menu.insertSeparator(first) menu.insertSeparator(first)
# Expand /collapse all # Expand /collapse all
self.actExpandAll = QAction(self.tr("Expand All"), menu) self.actExpandAll = QAction(self.tr("Expand All"), menu)
self.actExpandAll.triggered.connect(self.expandAll) self.actExpandAll.triggered.connect(self.expandAll)
menu.insertAction(first, self.actExpandAll) menu.insertAction(first, self.actExpandAll)
self.actCollapseAll = QAction(self.tr("Collapse All"), menu) self.actCollapseAll = QAction(self.tr("Collapse All"), menu)
self.actCollapseAll.triggered.connect(self.collapseAll) self.actCollapseAll.triggered.connect(self.collapseAll)
menu.insertAction(first, self.actCollapseAll) menu.insertAction(first, self.actCollapseAll)
menu.insertSeparator(first) menu.insertSeparator(first)
return menu return menu
def openNewTab(self): def openNewTab(self):
mainWindow().mainEditor.openIndexes(self._indexesToOpen, newTab=True) mainWindow().mainEditor.openIndexes(self._indexesToOpen, newTab=True)
def expandCurrentIndex(self, index=None): def expandCurrentIndex(self, index=None):
if index is None or type(index) == bool: if index is None or type(index) == bool:
index = self._indexesToOpen[0] #self.currentIndex() index = self._indexesToOpen[0] # self.currentIndex()
self.expand(index) self.expand(index)
for i in range(self.model().rowCount(index)): for i in range(self.model().rowCount(index)):
idx = self.model().index(i, 0, index) idx = self.model().index(i, 0, index)
self.expandCurrentIndex(index=idx) self.expandCurrentIndex(index=idx)
def collapseCurrentIndex(self, index=None): def collapseCurrentIndex(self, index=None):
if index is None or type(index) == bool: if index is None or type(index) == bool:
index = self._indexesToOpen[0] #self.currentIndex() index = self._indexesToOpen[0] # self.currentIndex()
self.collapse(index) self.collapse(index)
for i in range(self.model().rowCount(index)): for i in range(self.model().rowCount(index)):
idx = self.model().index(i, 0, index) idx = self.model().index(i, 0, index)
self.collapseCurrentIndex(index=idx) self.collapseCurrentIndex(index=idx)
def dragMoveEvent(self, event): def dragMoveEvent(self, event):
dndView.dragMoveEvent(self, event) dndView.dragMoveEvent(self, event)
QTreeView.dragMoveEvent(self, event) QTreeView.dragMoveEvent(self, event)
def mousePressEvent(self, event): def mousePressEvent(self, event):
if event.button() == Qt.RightButton: if event.button() == Qt.RightButton:
# Capture mouse press so that selection doesn't change # Capture mouse press so that selection doesn't change
# on right click # on right click
pass pass
else: else:
QTreeView.mousePressEvent(self, event) QTreeView.mousePressEvent(self, event)

View file

@ -1,16 +1,22 @@
#!/usr/bin/env python #!/usr/bin/env python
#--!-- coding: utf8 --!-- # --!-- coding: utf8 --!--
from qt import *
from functions import *
from ui.welcome_ui import *
from models.outlineModel import *
from models.persosModel import *
from models.plotModel import *
#from models.persosProxyModel import *
import settings
import locale import locale
import imp import imp
import os
from PyQt5.QtCore import QSettings, QRegExp, Qt
from PyQt5.QtGui import QIcon, QBrush, QColor, QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QWidget, QAction, QFileDialog, QSpinBox, QLineEdit, QLabel, QPushButton, QTreeWidgetItem
from manuskript import settings
from manuskript.enums import Outline
from manuskript.functions import mainWindow, iconFromColor
from manuskript.models.outlineModel import outlineItem
from manuskript.models.outlineModel import outlineModel
from manuskript.models.persosModel import persosModel
from manuskript.models.plotModel import plotModel
from manuskript.ui.welcome_ui import Ui_welcome
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
@ -19,9 +25,9 @@ class welcome(QWidget, Ui_welcome):
def __init__(self, parent=None): def __init__(self, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.template = [] self.template = []
self.mw = mainWindow() self.mw = mainWindow()
self.btnOpen.clicked.connect(self.openFile) self.btnOpen.clicked.connect(self.openFile)
self.btnCreate.clicked.connect(self.createFile) self.btnCreate.clicked.connect(self.createFile)
@ -29,31 +35,31 @@ class welcome(QWidget, Ui_welcome):
self.tree.itemActivated.connect(self.changeTemplate) self.tree.itemActivated.connect(self.changeTemplate)
self.btnAddLevel.clicked.connect(self.templateAddLevel) self.btnAddLevel.clicked.connect(self.templateAddLevel)
self.btnAddWC.clicked.connect(self.templateAddWordCount) self.btnAddWC.clicked.connect(self.templateAddWordCount)
self.populateTemplates() self.populateTemplates()
def updateValues(self): def updateValues(self):
# Auto load # Auto load
autoLoad, last = self.getAutoLoadValues() autoLoad, last = self.getAutoLoadValues()
self.chkLoadLastProject.setChecked(autoLoad) self.chkLoadLastProject.setChecked(autoLoad)
# Recent Files # Recent Files
self.loadRecents() self.loadRecents()
############################################################################### ###############################################################################
# AUTOLOAD # AUTOLOAD
############################################################################### ###############################################################################
def showEvent(self, event): def showEvent(self, event):
"""Waiting for things to be fully loaded to start opening projects.""" """Waiting for things to be fully loaded to start opening projects."""
QWidget.showEvent(self, event) QWidget.showEvent(self, event)
# Auto load last project # Auto load last project
autoLoad, last = self.getAutoLoadValues() autoLoad, last = self.getAutoLoadValues()
if autoLoad and last: if autoLoad and last:
self.mw.loadProject(last) self.mw.loadProject(last)
def getAutoLoadValues(self): def getAutoLoadValues(self):
sttgns = QSettings() sttgns = QSettings()
if sttgns.contains("autoLoad"): if sttgns.contains("autoLoad"):
@ -64,16 +70,16 @@ class welcome(QWidget, Ui_welcome):
last = sttgns.value("lastProject") last = sttgns.value("lastProject")
else: else:
last = "" last = ""
return autoLoad, last return autoLoad, last
def setAutoLoad(self, v): def setAutoLoad(self, v):
QSettings().setValue("autoLoad", v) QSettings().setValue("autoLoad", v)
############################################################################### ###############################################################################
# RECENTS # RECENTS
############################################################################### ###############################################################################
def loadRecents(self): def loadRecents(self):
sttgns = QSettings() sttgns = QSettings()
self.mw.menuRecents.setIcon(QIcon.fromTheme("folder-recent")) self.mw.menuRecents.setIcon(QIcon.fromTheme("folder-recent"))
@ -87,16 +93,16 @@ class welcome(QWidget, Ui_welcome):
a.setStatusTip(f) a.setStatusTip(f)
a.triggered.connect(self.loadRecentFile) a.triggered.connect(self.loadRecentFile)
self.mw.menuRecents.addAction(a) self.mw.menuRecents.addAction(a)
self.btnRecent.setMenu(self.mw.menuRecents) self.btnRecent.setMenu(self.mw.menuRecents)
def appendToRecentFiles(self, project): def appendToRecentFiles(self, project):
sttgns = QSettings() sttgns = QSettings()
if sttgns.contains("recentFiles"): if sttgns.contains("recentFiles"):
recentFiles = sttgns.value("recentFiles") recentFiles = sttgns.value("recentFiles")
else: else:
recentFiles = [] recentFiles = []
while project in recentFiles: while project in recentFiles:
recentFiles.remove(project) recentFiles.remove(project)
recentFiles.insert(0, project) recentFiles.insert(0, project)
@ -108,92 +114,92 @@ class welcome(QWidget, Ui_welcome):
self.appendToRecentFiles(act.data()) self.appendToRecentFiles(act.data())
self.mw.loadProject(act.data()) self.mw.loadProject(act.data())
############################################################################### ###############################################################################
# DIALOGS # DIALOGS
############################################################################### ###############################################################################
def openFile(self): def openFile(self):
"""File dialog that request an existing file. For opening project.""" """File dialog that request an existing file. For opening project."""
filename = QFileDialog.getOpenFileName(self, filename = QFileDialog.getOpenFileName(self,
self.tr("Open project"), self.tr("Open project"),
".", ".",
self.tr("Manuskript project (*.msk)"))[0] self.tr("Manuskript project (*.msk)"))[0]
if filename: if filename:
self.appendToRecentFiles(filename) self.appendToRecentFiles(filename)
self.mw.loadProject(filename) self.mw.loadProject(filename)
def saveAsFile(self): def saveAsFile(self):
"""File dialog that request a file, existing or not. """File dialog that request a file, existing or not.
Save datas to that file, which then becomes the current project.""" Save datas to that file, which then becomes the current project."""
filename = QFileDialog.getSaveFileName(self, filename = QFileDialog.getSaveFileName(self,
self.tr("Save project as..."), self.tr("Save project as..."),
".", ".",
self.tr("Manuskript project (*.msk)"))[0] self.tr("Manuskript project (*.msk)"))[0]
if filename: if filename:
self.appendToRecentFiles(filename) self.appendToRecentFiles(filename)
self.mw.saveDatas(filename) self.mw.saveDatas(filename)
def createFile(self): def createFile(self):
"""When starting a new project, ask for a place to save it. """When starting a new project, ask for a place to save it.
Datas are not loaded from file, so they must be populated another way.""" Datas are not loaded from file, so they must be populated another way."""
filename = QFileDialog.getSaveFileName(self, filename = QFileDialog.getSaveFileName(self,
self.tr("Create New Project"), self.tr("Create New Project"),
".", ".",
self.tr("Manuskript project (*.msk)"))[0] self.tr("Manuskript project (*.msk)"))[0]
if filename: if filename:
self.appendToRecentFiles(filename) self.appendToRecentFiles(filename)
self.loadDefaultDatas() self.loadDefaultDatas()
self.mw.loadProject(filename, loadFromFile=False) self.mw.loadProject(filename, loadFromFile=False)
############################################################################### ###############################################################################
# TEMPLATES # TEMPLATES
############################################################################### ###############################################################################
def templates(self): def templates(self):
return [ return [
(self.tr("Empty"), []), (self.tr("Empty"), []),
(self.tr("Novel"), [ (self.tr("Novel"), [
( 20, self.tr("Chapter")), (20, self.tr("Chapter")),
( 5, self.tr("Scene")), (5, self.tr("Scene")),
( 500, None) # A line with None is word count (500, None) # A line with None is word count
]), ]),
(self.tr("Novella"), [ (self.tr("Novella"), [
( 10, self.tr("Chapter")), (10, self.tr("Chapter")),
( 5, self.tr("Scene")), (5, self.tr("Scene")),
( 500, None) (500, None)
]), ]),
(self.tr("Short Story"), [ (self.tr("Short Story"), [
( 10, self.tr("Scene")), (10, self.tr("Scene")),
(1000, None) (1000, None)
]), ]),
(self.tr("Trilogy"), [ (self.tr("Trilogy"), [
( 3, self.tr("Book")), (3, self.tr("Book")),
( 3, self.tr("Section")), (3, self.tr("Section")),
( 10, self.tr("Chapter")), (10, self.tr("Chapter")),
( 5, self.tr("Scene")), (5, self.tr("Scene")),
( 500, None) (500, None)
]), ]),
(self.tr("Research paper"), [ (self.tr("Research paper"), [
( 3, self.tr("Section")), (3, self.tr("Section")),
(1000, None) (1000, None)
]) ])
] ]
def defaultTextType(self): def defaultTextType(self):
return [ return [
("t2t", self.tr("Txt2Tags"), "text-x-generic"), ("t2t", self.tr("Txt2Tags"), "text-x-generic"),
("html", self.tr("Rich Text (html)"), "text-html"), ("html", self.tr("Rich Text (html)"), "text-html"),
("txt", self.tr("Plain Text"), "text-x-generic"), ("txt", self.tr("Plain Text"), "text-x-generic"),
] ]
def changeTemplate(self, item, column): def changeTemplate(self, item, column):
template = [i for i in self.templates() if i[0] == item.text(0)] template = [i for i in self.templates() if i[0] == item.text(0)]
if len(template): if len(template):
self.template = template[0][1] self.template = template[0][1]
self.updateTemplate() self.updateTemplate()
def updateTemplate(self): def updateTemplate(self):
# Clear layout # Clear layout
def clearLayout(l): def clearLayout(l):
@ -203,13 +209,13 @@ class welcome(QWidget, Ui_welcome):
i.widget().deleteLater() i.widget().deleteLater()
if i.layout(): if i.layout():
clearLayout(i.layout()) clearLayout(i.layout())
clearLayout(self.lytTemplate) clearLayout(self.lytTemplate)
#self.templateLayout.addStretch() # self.templateLayout.addStretch()
#l = QGridLayout() # l = QGridLayout()
#self.templateLayout.addLayout(l) # self.templateLayout.addLayout(l)
k = 0 k = 0
hasWC = False hasWC = False
for d in self.template: for d in self.template:
@ -217,70 +223,69 @@ class welcome(QWidget, Ui_welcome):
spin.setRange(0, 999999) spin.setRange(0, 999999)
spin.setValue(d[0]) spin.setValue(d[0])
spin.valueChanged.connect(self.updateWordCount) spin.valueChanged.connect(self.updateWordCount)
if d[1] != None: if d[1] != None:
txt = QLineEdit(self) txt = QLineEdit(self)
txt.setText(d[1]) txt.setText(d[1])
else: else:
hasWC = True hasWC = True
txt = QLabel(self.tr("words each."), self) txt = QLabel(self.tr("words each."), self)
if k != 0: if k != 0:
of = QLabel(self.tr("of"), self) of = QLabel(self.tr("of"), self)
self.lytTemplate.addWidget(of, k, 0) self.lytTemplate.addWidget(of, k, 0)
btn = QPushButton("", self) btn = QPushButton("", self)
btn.setIcon(QIcon.fromTheme("edit-delete")) btn.setIcon(QIcon.fromTheme("edit-delete"))
btn.setProperty("deleteRow", k) btn.setProperty("deleteRow", k)
btn.clicked.connect(self.deleteTemplateRow) btn.clicked.connect(self.deleteTemplateRow)
self.lytTemplate.addWidget(btn, k, 3) self.lytTemplate.addWidget(btn, k, 3)
self.lytTemplate.addWidget(spin, k, 1) self.lytTemplate.addWidget(spin, k, 1)
self.lytTemplate.addWidget(txt, k, 2) self.lytTemplate.addWidget(txt, k, 2)
k += 1 k += 1
self.btnAddWC.setEnabled(not hasWC and len(self.template) > 0) self.btnAddWC.setEnabled(not hasWC and len(self.template) > 0)
self.btnAddLevel.setEnabled(True) self.btnAddLevel.setEnabled(True)
self.lblTotal.setVisible(hasWC) self.lblTotal.setVisible(hasWC)
self.updateWordCount() self.updateWordCount()
def templateAddLevel(self): def templateAddLevel(self):
if len(self.template) > 0 and \ if len(self.template) > 0 and \
self.template[len(self.template) - 1][1] == None: self.template[len(self.template) - 1][1] == None:
# has word cound, so insert before # has word cound, so insert before
self.template.insert(len(self.template) - 1, (10, self.tr("Text"))) self.template.insert(len(self.template) - 1, (10, self.tr("Text")))
else: else:
# No word count, so insert at end # No word count, so insert at end
self.template.append((10, self.tr("Something"))) self.template.append((10, self.tr("Something")))
self.updateTemplate() self.updateTemplate()
def templateAddWordCount(self): def templateAddWordCount(self):
self.template.append((500, None)) self.template.append((500, None))
self.updateTemplate() self.updateTemplate()
def deleteTemplateRow(self): def deleteTemplateRow(self):
btn = self.sender() btn = self.sender()
row = btn.property("deleteRow") row = btn.property("deleteRow")
self.template.pop(row) self.template.pop(row)
self.updateTemplate() self.updateTemplate()
def updateWordCount(self): def updateWordCount(self):
total = 1 total = 1
for s in self.findChildren(QSpinBox, QRegExp(".*"), for s in self.findChildren(QSpinBox, QRegExp(".*"),
Qt.FindChildrenRecursively): Qt.FindChildrenRecursively):
total = total * s.value() total = total * s.value()
if total == 1: if total == 1:
total = 0 total = 0
self.lblTotal.setText(self.tr("<b>Total:</b> {} words (~ {} pages)").format( self.lblTotal.setText(self.tr("<b>Total:</b> {} words (~ {} pages)").format(
locale.format("%d", total, grouping=True), locale.format("%d", total, grouping=True),
locale.format("%d", total / 250, grouping=True) locale.format("%d", total / 250, grouping=True)
)) ))
def addTopLevelItem(self, name): def addTopLevelItem(self, name):
item = QTreeWidgetItem(self.tree, [name]) item = QTreeWidgetItem(self.tree, [name])
item.setBackground(0, QBrush(QColor(Qt.blue).lighter(190))) item.setBackground(0, QBrush(QColor(Qt.blue).lighter(190)))
@ -291,45 +296,45 @@ class welcome(QWidget, Ui_welcome):
f.setBold(True) f.setBold(True)
item.setFont(0, f) item.setFont(0, f)
return item return item
def populateTemplates(self): def populateTemplates(self):
self.tree.clear() self.tree.clear()
self.tree.setIndentation(0) self.tree.setIndentation(0)
# Add templates # Add templates
item = self.addTopLevelItem(self.tr("Templates")) item = self.addTopLevelItem(self.tr("Templates"))
templates = self.templates() templates = self.templates()
for t in templates: for t in templates:
sub = QTreeWidgetItem(item, [t[0]]) sub = QTreeWidgetItem(item, [t[0]])
# Add Demo project # Add Demo project
item = self.addTopLevelItem(self.tr("Demo projects")) item = self.addTopLevelItem(self.tr("Demo projects"))
# FIXME: none yet # FIXME: none yet
# Populates default text type # Populates default text type
self.cmbDefaultType.clear() self.cmbDefaultType.clear()
for t in self.defaultTextType(): for t in self.defaultTextType():
self.cmbDefaultType.addItem(QIcon.fromTheme(t[2]), t[1], t[0]) self.cmbDefaultType.addItem(QIcon.fromTheme(t[2]), t[1], t[0])
self.tree.expandAll() self.tree.expandAll()
def loadDefaultDatas(self): def loadDefaultDatas(self):
# Empty settings # Empty settings
imp.reload(settings) imp.reload(settings)
# Données # Données
self.mw.mdlFlatData = QStandardItemModel(2, 8, self.mw) self.mw.mdlFlatData = QStandardItemModel(2, 8, self.mw)
# 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.mdlPersos = persosModel(self.mw)
#self.mdlPersosProxy = None # persosProxyModel() # None # self.mdlPersosProxy = None # persosProxyModel() # None
#self.mw.mdlPersosProxy = persosProxyModel(self.mw) # self.mw.mdlPersosProxy = persosProxyModel(self.mw)
#self.mw.mdlPersosInfos = QStandardItemModel(1, 0, self.mw) # self.mw.mdlPersosInfos = QStandardItemModel(1, 0, self.mw)
#self.mw.mdlPersosInfos.insertColumn(0, [QStandardItem("ID")]) # self.mw.mdlPersosInfos.insertColumn(0, [QStandardItem("ID")])
#self.mw.mdlPersosInfos.setHorizontalHeaderLabels(["Description"]) # self.mw.mdlPersosInfos.setHorizontalHeaderLabels(["Description"])
# Labels # Labels
self.mw.mdlLabels = QStandardItemModel(self.mw) self.mw.mdlLabels = QStandardItemModel(self.mw)
@ -340,18 +345,18 @@ class welcome(QWidget, Ui_welcome):
(Qt.blue, self.tr("Chapter")), (Qt.blue, self.tr("Chapter")),
(Qt.red, self.tr("Scene")), (Qt.red, self.tr("Scene")),
(Qt.cyan, self.tr("Research")) (Qt.cyan, self.tr("Research"))
]: ]:
self.mw.mdlLabels.appendRow(QStandardItem(iconFromColor(color), text)) self.mw.mdlLabels.appendRow(QStandardItem(iconFromColor(color), text))
# Status # Status
self.mw.mdlStatus = QStandardItemModel(self.mw) self.mw.mdlStatus = QStandardItemModel(self.mw)
for text in [ for text in [
"", "",
self.tr("TODO"), self.tr("TODO"),
self.tr("First draft"), self.tr("First draft"),
self.tr("Second draft"), self.tr("Second draft"),
self.tr("Final") self.tr("Final")
]: ]:
self.mw.mdlStatus.appendRow(QStandardItem(text)) self.mw.mdlStatus.appendRow(QStandardItem(text))
# Plot # Plot
@ -359,38 +364,37 @@ class welcome(QWidget, Ui_welcome):
# Outline # Outline
self.mw.mdlOutline = outlineModel(self.mw) self.mw.mdlOutline = outlineModel(self.mw)
root = self.mw.mdlOutline.rootItem root = self.mw.mdlOutline.rootItem
_type = self.cmbDefaultType.currentData() _type = self.cmbDefaultType.currentData()
settings.defaultTextType = _type settings.defaultTextType = _type
def addElement(parent, datas): def addElement(parent, datas):
if len(datas) == 2 and datas[1][1] == None or \ if len(datas) == 2 and datas[1][1] == None or \
len(datas) == 1: len(datas) == 1:
# Next item is word count # Next item is word count
n = 0 n = 0
for i in range(datas[0][0]): for i in range(datas[0][0]):
n += 1 n += 1
item = outlineItem(title="{} {}".format( item = outlineItem(title="{} {}".format(
datas[0][1], datas[0][1],
str(n)), str(n)),
_type=_type, _type=_type,
parent=parent) parent=parent)
if len(datas) == 2: if len(datas) == 2:
item.setData(Outline.setGoal.value, datas[1][0]) item.setData(Outline.setGoal.value, datas[1][0])
#parent.appendChild(item) # parent.appendChild(item)
else: else:
n = 0 n = 0
for i in range(datas[0][0]): for i in range(datas[0][0]):
n += 1 n += 1
item = outlineItem(title="{} {}".format( item = outlineItem(title="{} {}".format(
datas[0][1], datas[0][1],
str(n)), str(n)),
_type="folder", _type="folder",
parent=parent) parent=parent)
#parent.appendChild(item) # parent.appendChild(item)
addElement(item, datas[1:]) addElement(item, datas[1:])
if self.template: if self.template:
addElement(root, self.template) addElement(root, self.template)