From 69e0ca93be44776cb787244a1a3887fb6c7f1738 Mon Sep 17 00:00:00 2001 From: Olivier Keshavjee Date: Sat, 6 Feb 2016 12:34:22 +0100 Subject: [PATCH] Cleaning up imports, at last --- makefile | 15 +- manuskript/exporter/__init__.py | 33 +- manuskript/exporter/arbo.py | 39 +- manuskript/exporter/basic.py | 23 +- manuskript/exporter/html.py | 52 +-- manuskript/exporter/odt.py | 69 ++- manuskript/exporter/odt_old.py | 48 +- manuskript/functions.py | 78 ++-- manuskript/loadSave.py | 11 +- manuskript/main.py | 11 +- manuskript/mainWindow.py | 45 +- manuskript/models/outlineModel.py | 20 +- manuskript/models/persosModel.py | 24 +- manuskript/models/persosProxyModel.py | 5 +- manuskript/models/plotModel.py | 138 +++--- manuskript/models/plotsProxyModel.py | 106 ++--- manuskript/models/references.py | 409 +++++++++--------- manuskript/models/worldModel.py | 155 +++---- manuskript/qt.py | 8 - manuskript/settings.py | 9 +- manuskript/settingsWindow.py | 322 +++++++------- manuskript/ui/cheatSheet.py | 95 ++-- manuskript/ui/cheatSheet_ui.py | 2 +- manuskript/ui/collapsibleDockWidgets.py | 49 ++- manuskript/ui/collapsibleGroupBox.py | 85 ++-- manuskript/ui/collapsibleGroupBox2.py | 28 +- manuskript/ui/compileDialog.py | 79 ++-- manuskript/ui/compileDialog_ui.py | 2 +- manuskript/ui/editors/basicHighlighter.py | 40 +- manuskript/ui/editors/blockUserData.py | 10 +- manuskript/ui/editors/completer.py | 51 +-- manuskript/ui/editors/completer_ui.py | 2 +- manuskript/ui/editors/editorWidget.py | 204 ++++----- manuskript/ui/editors/editorWidget_ui.py | 8 +- manuskript/ui/editors/editorWidget_ui.ui | 65 ++- manuskript/ui/editors/fullScreenEditor.py | 186 ++++---- manuskript/ui/editors/locker.py | 52 +-- manuskript/ui/editors/mainEditor.py | 163 +++---- manuskript/ui/editors/mainEditor_ui.py | 4 +- manuskript/ui/editors/mainEditor_ui.ui | 2 +- manuskript/ui/editors/t2tFunctions.py | 45 +- manuskript/ui/editors/t2tHighlighter.py | 248 +++++------ manuskript/ui/editors/t2tHighlighterStyle.py | 136 +++--- manuskript/ui/editors/textFormat.py | 61 ++- manuskript/ui/editors/themes.py | 185 ++++---- manuskript/ui/helpLabel.py | 16 +- manuskript/ui/mainWindow.py | 81 ++-- manuskript/ui/mainWindow.ui | 113 +++-- manuskript/ui/revisions.py | 156 +++---- manuskript/ui/search.py | 95 ++-- manuskript/ui/{settings.py => settings_ui.py} | 0 manuskript/ui/{settings.ui => settings_ui.ui} | 0 manuskript/ui/sldImportance.py | 56 +-- manuskript/ui/sldImportance_ui.py | 2 +- manuskript/ui/views/basicItemView.py | 42 +- manuskript/ui/views/basicItemView_ui.py | 8 +- manuskript/ui/views/basicItemView_ui.ui | 6 +- manuskript/ui/views/chkOutlineCompile.py | 57 ++- manuskript/ui/views/cmbOutlineLabelChoser.py | 71 +-- manuskript/ui/views/cmbOutlinePersoChoser.py | 86 ++-- manuskript/ui/views/cmbOutlineStatusChoser.py | 69 +-- manuskript/ui/views/cmbOutlineTypeChoser.py | 69 +-- manuskript/ui/views/corkDelegate.py | 162 +++---- manuskript/ui/views/corkView.py | 30 +- manuskript/ui/views/dndView.py | 21 +- manuskript/ui/views/lineEditView.py | 63 ++- manuskript/ui/views/metadataView.py | 50 +-- manuskript/ui/views/metadataView_ui.py | 14 +- manuskript/ui/views/metadataView_ui.ui | 12 +- manuskript/ui/views/outlineBasics.py | 116 ++--- manuskript/ui/views/outlineDelegates.py | 204 ++++----- manuskript/ui/views/outlineView.py | 47 +- manuskript/ui/views/persoTreeView.py | 61 ++- manuskript/ui/views/plotDelegate.py | 51 +-- manuskript/ui/views/plotTreeView.py | 130 +++--- manuskript/ui/views/propertiesView.py | 46 +- manuskript/ui/views/propertiesView_ui.py | 16 +- manuskript/ui/views/propertiesView_ui.ui | 12 +- manuskript/ui/views/textEditCompleter.py | 106 ++--- manuskript/ui/views/textEditView.py | 310 ++++++------- manuskript/ui/views/treeDelegates.py | 64 +-- manuskript/ui/views/treeView.py | 73 ++-- manuskript/ui/welcome.py | 284 ++++++------ 83 files changed, 3189 insertions(+), 3032 deletions(-) delete mode 100644 manuskript/qt.py rename manuskript/ui/{settings.py => settings_ui.py} (100%) rename manuskript/ui/{settings.ui => settings_ui.ui} (100%) diff --git a/makefile b/makefile index e423f96..bb57cb0 100644 --- a/makefile +++ b/makefile @@ -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) TS := $(wildcard i18n/*.ts) QMs= $(TS:.ts=.qm) @@ -6,22 +6,23 @@ QMs= $(TS:.ts=.qm) ui: $(UIs) run: $(UIs) - python3 src/main.py +# python3 manuskript/main.py + bin/manuskript debug: $(UIs) - gdb --args python3 src/main.py + gdb --args python3 manuskript/main.py lineprof: - kernprof -l -v src/main.py + kernprof -l -v manuskript/main.py profile: - python3 -m cProfile -s 'cumtime' src/main.py | more + python3 -m cProfile -s 'cumtime' manuskript/main.py | more compile: - cd src && python3 setup.py build_ext --inplace + cd manuskript && python3 setup.py build_ext --inplace callgraph: - cd src; pycallgraph myoutput -- main.py + cd manuskript; pycallgraph myoutput -- main.py translation: pylupdate5 -noobsolete i18n/manuskript.pro diff --git a/manuskript/exporter/__init__.py b/manuskript/exporter/__init__.py index cf9be85..a1c718d 100644 --- a/manuskript/exporter/__init__.py +++ b/manuskript/exporter/__init__.py @@ -1,31 +1,32 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - +# --!-- coding: utf8 --!-- import collections -from qt import * -from .html import htmlExporter -from .arbo import arboExporter -from .odt import odtExporter + +from PyQt5.QtWidgets import qApp + +from manuskript.exporter.arbo import arboExporter +from manuskript.exporter.html import htmlExporter +from manuskript.exporter.odt import odtExporter formats = collections.OrderedDict([ - #Format - # Readable name - # Class - # QFileDialog filter + # Format + # Readable name + # Class + # QFileDialog filter ('html', ( - qApp.translate("exporter", "HTML"), + qApp.translate("exporter", "HTML"), htmlExporter, qApp.translate("exporter", "HTML Document (*.html)"))), ('arbo', ( - qApp.translate("exporter", "Arborescence"), + qApp.translate("exporter", "Arborescence"), arboExporter, None)), - ('odt', ( - qApp.translate("exporter", "OpenDocument (LibreOffice)"), + ('odt', ( + qApp.translate("exporter", "OpenDocument (LibreOffice)"), odtExporter, qApp.translate("exporter", "OpenDocument (*.odt)"))), ('epub', ( - "ePub (not yet)", + "ePub (not yet)", None, None)), -]) \ No newline at end of file +]) diff --git a/manuskript/exporter/arbo.py b/manuskript/exporter/arbo.py index 2664eeb..cece381 100644 --- a/manuskript/exporter/arbo.py +++ b/manuskript/exporter/arbo.py @@ -1,53 +1,48 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * +# --!-- coding: utf8 --!-- +import os + +from manuskript.functions import mainWindow + class arboExporter(): - requires = ["path"] - + def __init__(self): pass - + def doCompile(self, path): - #FIXME: overwrites when items have identical names + # FIXME: overwrites when items have identical names mw = mainWindow() root = mw.mdlOutline.rootItem - + def writeItem(item, path): if item.isFolder(): path2 = os.path.join(path, item.title()) - + try: os.mkdir(path2) except FileExistsError: pass - + for c in item.children(): writeItem(c, path2) - + else: ext = ".t2t" if item.isT2T() else \ - ".html" if item.isHTML() else \ - ".txt" + ".html" if item.isHTML() else \ + ".txt" path2 = os.path.join(path, item.title() + ext) f = open(path2, "w") text = self.formatText(item.text(), item.type()) f.write(text) - + for c in root.children(): writeItem(c, path) - - + def formatText(self, text, _type): if _type == "t2t": # Empty lines for headers text = "\n\n\n" + text - + return text - - - diff --git a/manuskript/exporter/basic.py b/manuskript/exporter/basic.py index 46136d8..a53c434 100644 --- a/manuskript/exporter/basic.py +++ b/manuskript/exporter/basic.py @@ -1,31 +1,28 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -import subprocess +# --!-- coding: utf8 --!-- + import re +import subprocess + class basicExporter(): - def __init__(self): pass - + def runT2T(self, text, target="html"): - + cmdl = ['txt2tags', '-t', target, '--enc=utf-8', '--no-headers', '-o', '-', '-'] - + cmd = subprocess.Popen(('echo', text), stdout=subprocess.PIPE) 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: print("Error!") return text cmd.wait() - + return output.decode("utf-8") - + def htmlBody(self, text): text = text.replace("\n", "") text = re.sub(r".*]*?>(.*).*", "\\1", text) diff --git a/manuskript/exporter/html.py b/manuskript/exporter/html.py index 82e83e8..69b704f 100644 --- a/manuskript/exporter/html.py +++ b/manuskript/exporter/html.py @@ -1,45 +1,41 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -from exporter.basic import basicExporter +# --!-- coding: utf8 --!-- +from manuskript.exporter.basic import basicExporter +from manuskript.functions import mainWindow + class htmlExporter(basicExporter): - requires = ["filename"] - + def __init__(self): pass - + def doCompile(self, filename): mw = mainWindow() root = mw.mdlOutline.rootItem - + html = "" - + def appendItem(item): if item.isFolder(): html = "" title = "{t}\n".format( - l = str(item.level() + 1), - t = item.title()) + l=str(item.level() + 1), + t=item.title()) html += title - + for c in item.children(): html += appendItem(c) - + return html - + else: text = self.formatText(item.text(), item.type()) return text - + for c in root.children(): html += appendItem(c) - - + template = """ @@ -51,25 +47,25 @@ class htmlExporter(basicExporter): {BODY} """ - + f = open(filename, "w") f.write(template.format( - TITLE="FIXME", - BODY=html)) - + TITLE="FIXME", + BODY=html)) + def formatText(self, text, _type): - + if not text: return text - + if _type == "t2t": text = self.runT2T(text) - + elif _type == "txt": text = text.replace("\n", "
") - + elif _type == "html": # keep only body text = self.htmlBody(text) - + return text + "
" diff --git a/manuskript/exporter/odt.py b/manuskript/exporter/odt.py index 0480a04..8e59e05 100644 --- a/manuskript/exporter/odt.py +++ b/manuskript/exporter/odt.py @@ -1,75 +1,74 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -from exporter.basic import basicExporter +# --!-- coding: utf8 --!-- +import os +import sys + +from PyQt5.QtGui import QTextDocument + +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")) -from odf.opendocument import OpenDocumentText -from odf.style import Style, TextProperties -from odf.text import H, P, Span - class odtExporter(basicExporter): - requires = ["filename"] - + def __init__(self): pass - + def doCompile(self, filename): mw = mainWindow() root = mw.mdlOutline.rootItem - + doc = OpenDocumentText() - + def appendItem(item): if item.isFolder(): - + self.addHeading(item.title(), item.level() + 1, doc) - + for c in item.children(): appendItem(c) - + else: text = self.formatText(item.text(), item.type()) if text: for l in text.split("\n"): self.addParagraph(l, doc) - + for c in root.children(): appendItem(c) - + doc.save(filename) - + def formatText(self, text, _type): - + if not text: return text - - #if _type == "t2t": - #text = self.runT2T(text) - - #elif _type == "txt": - #text = text.replace("\n", "
") - + + # if _type == "t2t": + # text = self.runT2T(text) + + # elif _type == "txt": + # text = text.replace("\n", "
") + elif _type == "html": doc = QTextDocument() doc.setHtml(text) text = doc.toPlainText() - #text = self.htmlBody(text) - + # text = self.htmlBody(text) + return text - + def addHeading(self, text, level, doc): doc.text.addElement(H(outlinelevel=int(level), text=text)) return doc - + def addParagraph(self, text, doc): p = P(stylename="Text Body", text=text) doc.text.addElement(p) - return doc \ No newline at end of file + return doc diff --git a/manuskript/exporter/odt_old.py b/manuskript/exporter/odt_old.py index 5534fa5..e68e39c 100644 --- a/manuskript/exporter/odt_old.py +++ b/manuskript/exporter/odt_old.py @@ -1,61 +1,59 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -from exporter.basic import basicExporter +# --!-- coding: utf8 --!-- +from PyQt5.QtGui import QTextDocument, QTextCursor, QTextDocumentWriter + +from manuskript.exporter.basic import basicExporter +from manuskript.functions import mainWindow + class odtExporter(basicExporter): - requires = ["filename"] - + def __init__(self): pass - + def doCompile(self, filename): mw = mainWindow() root = mw.mdlOutline.rootItem - + doc = QTextDocument() cursor = QTextCursor(doc) - - + def appendItem(item): if item.isFolder(): - + cursor.setPosition(doc.characterCount() - 1) title = "{t}
\n".format( - l = str(item.level() + 1), - t = item.title()) + l=str(item.level() + 1), + t=item.title()) cursor.insertHtml(title) - + for c in item.children(): appendItem(c) - + else: text = self.formatText(item.text(), item.type()) cursor.setPosition(doc.characterCount() - 1) cursor.insertHtml(text) - + for c in root.children(): appendItem(c) - + dw = QTextDocumentWriter(filename, "odt") dw.write(doc) - + def formatText(self, text, _type): - + if not text: return text - + if _type == "t2t": text = self.runT2T(text) - + elif _type == "txt": text = text.replace("\n", "
") - + elif _type == "html": text = self.htmlBody(text) - + return text + "
" diff --git a/manuskript/functions.py b/manuskript/functions.py index acc2c58..2e442fd 100644 --- a/manuskript/functions.py +++ b/manuskript/functions.py @@ -1,12 +1,20 @@ #!/usr/bin/env python #--!-- coding: utf8 --!-- -from qt import * -from random import * -from enums import * import os +from random import * + +from PyQt5.QtCore import Qt, QRect, QStandardPaths, QObject # 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 MW = None @@ -70,7 +78,7 @@ def mainWindow(): return MW 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) if px.width() != 0: return QColor(QImage(px).pixel(2, 2)) @@ -86,7 +94,7 @@ def iconFromColorString(string): return iconFromColor(QColor(string)) 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) g = randint(0, 255) b = randint(0, 255) @@ -106,36 +114,36 @@ def mixColors(col1, col2, f=.5): return QColor(r, g, b) def outlineItemColors(item): - "Takes an OutlineItem and returns a dict of colors." - colors = {} - mw = mainWindow() - - # POV - colors["POV"] = QColor(Qt.transparent) - POV = item.data(Outline.POV.value) - for i in range(mw.mdlPersos.rowCount()): - if mw.mdlPersos.ID(i) == POV: - colors["POV"] = iconColor(mw.mdlPersos.icon(i)) - - # Label - lbl = item.data(Outline.label.value) - col = iconColor(mw.mdlLabels.item(toInt(lbl)).icon()) - if col == Qt.black: - # Don't know why, but transparent is rendered as black - col = QColor(Qt.transparent) - colors["Label"] = col - - # Progress - pg = item.data(Outline.goalPercentage.value) - colors["Progress"] = colorFromProgress(pg) - - # Compile - if item.compile() in [0, "0"]: - colors["Compile"] = QColor(Qt.gray) - else: - colors["Compile"] = QColor(Qt.black) - - return colors + """Takes an OutlineItem and returns a dict of colors.""" + colors = {} + mw = mainWindow() + + # POV + colors["POV"] = QColor(Qt.transparent) + POV = item.data(Outline.POV.value) + for i in range(mw.mdlPersos.rowCount()): + if mw.mdlPersos.ID(i) == POV: + colors["POV"] = iconColor(mw.mdlPersos.icon(i)) + + # Label + lbl = item.data(Outline.label.value) + col = iconColor(mw.mdlLabels.item(toInt(lbl)).icon()) + if col == Qt.black: + # Don't know why, but transparent is rendered as black + col = QColor(Qt.transparent) + colors["Label"] = col + + # Progress + pg = item.data(Outline.goalPercentage.value) + colors["Progress"] = colorFromProgress(pg) + + # Compile + if item.compile() in [0, "0"]: + colors["Compile"] = QColor(Qt.gray) + else: + colors["Compile"] = QColor(Qt.black) + + return colors def colorifyPixmap(pixmap, color): # FIXME: ugly diff --git a/manuskript/loadSave.py b/manuskript/loadSave.py index f8ee363..af5dfc6 100644 --- a/manuskript/loadSave.py +++ b/manuskript/loadSave.py @@ -1,10 +1,15 @@ #!/usr/bin/env python #--!-- coding: utf8 --!-- -from qt import * -from functions import * -from lxml import etree as ET 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: import zlib # Used with zipfile for compression compression = zipfile.ZIP_DEFLATED diff --git a/manuskript/main.py b/manuskript/main.py index 4e333e8..58628a8 100644 --- a/manuskript/main.py +++ b/manuskript/main.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -import sys -from qt import * - -from functions import * import faulthandler +import sys + +from PyQt5.QtCore import QLocale, QTranslator, QSettings +from PyQt5.QtWidgets import QApplication +from .functions import * _version = "0.1" @@ -49,7 +50,7 @@ def run(): def launch(): - from mainWindow import MainWindow + from .mainWindow import MainWindow main = MainWindow() main.show() diff --git a/manuskript/mainWindow.py b/manuskript/mainWindow.py index a7d97e2..b71a161 100644 --- a/manuskript/mainWindow.py +++ b/manuskript/mainWindow.py @@ -1,27 +1,33 @@ #!/usr/bin/env python # --!-- 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 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 +from manuskript.ui.views.textEditView import textEditView + try: import enchant except ImportError: @@ -907,6 +913,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): w.setDict(settings.dict) def openPyEnchantWebPage(self): + from PyQt5.QtGui import QDesktopServices QDesktopServices.openUrl(QUrl("http://pythonhosted.org/pyenchant/")) def toggleSpellcheck(self, val): diff --git a/manuskript/models/outlineModel.py b/manuskript/models/outlineModel.py index 1073cfc..6e4b42d 100644 --- a/manuskript/models/outlineModel.py +++ b/manuskript/models/outlineModel.py @@ -1,14 +1,22 @@ #!/usr/bin/env python # --!-- 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 +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, '') import time diff --git a/manuskript/models/persosModel.py b/manuskript/models/persosModel.py index 714afcb..38a470f 100644 --- a/manuskript/models/persosModel.py +++ b/manuskript/models/persosModel.py @@ -1,9 +1,16 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import QModelIndex, Qt +from PyQt5.QtGui import QStandardItemModel, QStandardItem, QColor, QPixmap, QIcon +from PyQt5.QtWidgets import QColorDialog + +from manuskript.enums import Perso +from manuskript.enums import Plot +from manuskript.functions import iconColor +from manuskript.functions import mainWindow +from manuskript.functions import randomColor +from manuskript.functions import toInt + class persosModel(QStandardItemModel): @@ -11,8 +18,8 @@ class persosModel(QStandardItemModel): QStandardItemModel.__init__(self, 0, 3, parent) self.setHorizontalHeaderLabels([i.name for i in Plot]) self.mw = mainWindow() - #self._proxy = plotsProxyModel() - #self._proxy.setSourceModel(self) + # self._proxy = plotsProxyModel() + # self._proxy.setSourceModel(self) ############################################################################### # PERSOS QUERRIES @@ -126,7 +133,7 @@ class persosModel(QStandardItemModel): ############################################################################### def updatePersoColor(self, idx): - #idx = self.currentPersoIndex() + # idx = self.currentPersoIndex() color = self.getPersoColorName(idx) self.mw.btnPersoColor.setStyleSheet("background:{};".format(color)) @@ -174,4 +181,3 @@ class persosModel(QStandardItemModel): infos.append((name, val)) return infos - \ No newline at end of file diff --git a/manuskript/models/persosProxyModel.py b/manuskript/models/persosProxyModel.py index 6e4a70c..48aa637 100644 --- a/manuskript/models/persosProxyModel.py +++ b/manuskript/models/persosProxyModel.py @@ -1,11 +1,8 @@ #!/usr/bin/env python #--!-- coding: utf8 --!-- -from qt import * -from enums import * +from manuskript import enums -from enum import Enum -from lxml import etree as ET class persosProxyModel(QSortFilterProxyModel): diff --git a/manuskript/models/plotModel.py b/manuskript/models/plotModel.py index 3883417..456b850 100644 --- a/manuskript/models/plotModel.py +++ b/manuskript/models/plotModel.py @@ -1,31 +1,38 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import QModelIndex +from PyQt5.QtCore import QSignalMapper +from PyQt5.QtCore import Qt +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): - def __init__(self, parent): QStandardItemModel.__init__(self, 0, 3, parent) self.setHorizontalHeaderLabels([i.name for i in Plot]) self.mw = mainWindow() - + self.updatePlotPersoButton() - -############################################################################### -# QUERIES -############################################################################### + + ############################################################################### + # QUERIES + ############################################################################### def getPlotsByImportance(self): plots = [[], [], []] for i in range(self.rowCount()): importance = self.item(i, Plot.importance.value).text() ID = self.item(i, Plot.ID.value).text() - plots[2-toInt(importance)].append(ID) + plots[2 - toInt(importance)].append(ID) return plots - + def getSubPlotsByID(self, ID): index = self.getIndexFromID(ID) if not index.isValid(): @@ -39,7 +46,7 @@ class plotModel(QStandardItemModel): summary = item.child(i, 3).text() lst.append((_ID, name, summary)) return lst - + def getPlotNameByID(self, ID): for i in range(self.rowCount()): _ID = self.item(i, Plot.ID.value).text() @@ -47,7 +54,7 @@ class plotModel(QStandardItemModel): name = self.item(i, Plot.name.value).text() return name return None - + def getSubPlotTextsByID(self, plotID, subplotRaw): """Returns a tuple (name, summary) for the suplot whose raw in the model is ``subplotRaw``, of plot whose ID is ``plotID``. @@ -55,53 +62,54 @@ class plotModel(QStandardItemModel): plotIndex = self.getIndexFromID(plotID) name = plotIndex.child(subplotRaw, Plot.name.value).data() summary = plotIndex.child(subplotRaw, 3).data() # 3 is for summary - return (name, summary) - + return name, summary + def getIndexFromID(self, ID): for i in range(self.rowCount()): _ID = self.item(i, Plot.ID.value).text() if _ID == ID or toInt(_ID) == ID: return self.index(i, 0) return QModelIndex() - + def currentIndex(self): i = self.mw.lstPlots.currentIndex() - if i .isValid(): + if i.isValid(): return i else: return None - -############################################################################### -# ADDING / REMOVING -############################################################################### - + + ############################################################################### + # ADDING / REMOVING + ############################################################################### + def addPlot(self): p = QStandardItem(self.tr("New plot")) _id = QStandardItem(self.getUniqueID()) importance = QStandardItem(str(0)) - self.appendRow([p, _id, importance, QStandardItem("Persos"), + self.appendRow([p, _id, importance, QStandardItem("Persos"), QStandardItem(), QStandardItem(), QStandardItem("Subplots")]) - + def getUniqueID(self, parent=QModelIndex()): - "Returns an unused ID" + """Returns an unused ID""" parentItem = self.itemFromIndex(parent) vals = [] for i in range(self.rowCount(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(): vals.append(int(index.data())) - + k = 0 - while k in vals: k += 1 + while k in vals: + k += 1 return str(k) - + def removePlot(self, index): self.takeRow(index.row()) - -############################################################################### -# SUBPLOTS -############################################################################### + + ############################################################################### + # SUBPLOTS + ############################################################################### def headerData(self, section, orientation, role=Qt.DisplayRole): if role == Qt.DisplayRole: @@ -116,42 +124,42 @@ class plotModel(QStandardItemModel): return "" else: return QStandardItemModel.headerData(self, section, orientation, role) - + def data(self, index, role=Qt.DisplayRole): if index.parent().isValid() and \ - index.parent().column() == Plot.subplots.value and \ - index.column() == Subplot.meta.value: + index.parent().column() == Plot.subplots.value and \ + index.column() == Subplot.meta.value: if role == Qt.TextAlignmentRole: return Qt.AlignRight | Qt.AlignVCenter elif role == Qt.ForegroundRole: return QBrush(Qt.gray) else: return QStandardItemModel.data(self, index, role) - + else: return QStandardItemModel.data(self, index, role) - + def addSubPlot(self): index = self.mw.lstPlots.currentPlotIndex() if not index.isValid(): return - + parent = index.sibling(index.row(), Plot.subplots.value) parentItem = self.item(index.row(), Plot.subplots.value) - + if not parentItem: return - + p = QStandardItem(self.tr("New subplot")) _id = QStandardItem(self.getUniqueID(parent)) summary = QStandardItem() - + # Don't know why, if summary is in third position, then drag/drop deletes it... parentItem.appendRow([p, _id, QStandardItem(), summary]) - + # 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): index = self.mw.lstSubPlots.currentIndex() if not index.isValid(): @@ -159,33 +167,33 @@ class plotModel(QStandardItemModel): parent = index.parent() parentItem = self.itemFromIndex(parent) parentItem.takeRow(index.row()) - + def flags(self, index): parent = index.parent() - if parent.isValid(): # this is a subitem - return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled + if parent.isValid(): # this is a subitem + return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled else: return QStandardItemModel.flags(self, index) -############################################################################### -# PLOT PERSOS -############################################################################### + ############################################################################### + # PLOT PERSOS + ############################################################################### def addPlotPerso(self, v): index = self.mw.lstPlots.currentPlotIndex() if index.isValid(): if not self.item(index.row(), Plot.persos.value): self.setItem(index.row(), Plot.persos.value, QStandardItem()) - + item = self.item(index.row(), Plot.persos.value) - + # We check that the PersoID is not in the list yet for i in range(item.rowCount()): if item.child(i).text() == str(v): return - + item.appendRow(QStandardItem(str(v))) - + def removePlotPerso(self): index = self.mw.lstPlotPerso.currentIndex() if not index.isValid(): @@ -193,26 +201,26 @@ class plotModel(QStandardItemModel): parent = index.parent() parentItem = self.itemFromIndex(parent) parentItem.takeRow(index.row()) - + def updatePlotPersoButton(self): menu = QMenu(self.mw) - + menus = [] for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]: m = QMenu(i, menu) menus.append(m) menu.addMenu(m) - + mpr = QSignalMapper(menu) for i in range(self.mw.mdlPersos.rowCount()): a = QAction(self.mw.mdlPersos.name(i), menu) a.setIcon(self.mw.mdlPersos.icon(i)) a.triggered.connect(mpr.map) mpr.setMapping(a, int(self.mw.mdlPersos.ID(i))) - + imp = toInt(self.mw.mdlPersos.importance(i)) - - menus[2-imp].addAction(a) - + + menus[2 - imp].addAction(a) + mpr.mapped.connect(self.addPlotPerso) - self.mw.btnAddPlotPerso.setMenu(menu) \ No newline at end of file + self.mw.btnAddPlotPerso.setMenu(menu) diff --git a/manuskript/models/plotsProxyModel.py b/manuskript/models/plotsProxyModel.py index 9a807d7..f182795 100644 --- a/manuskript/models/plotsProxyModel.py +++ b/manuskript/models/plotsProxyModel.py @@ -1,107 +1,109 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import QModelIndex +from PyQt5.QtCore import QSortFilterProxyModel +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): - newStatuses = pyqtSignal() - + def __init__(self, parent=None): QSortFilterProxyModel.__init__(self, parent) - - #self.rootItem = QStandardItem() + + # self.rootItem = QStandardItem() self.p1 = QStandardItem(self.tr("Main")) self.p2 = QStandardItem(self.tr("Secundary")) self.p3 = QStandardItem(self.tr("Minors")) - + self._cats = [ self.p1, self.p2, self.p3 - ] - + ] + def mapFromSource(self, sourceIndex): if not sourceIndex.isValid(): return QModelIndex() - + row = self._map.index(sourceIndex.row()) - #item = sourceIndex.internalPointer() + # item = sourceIndex.internalPointer() item = self.sourceModel().itemFromIndex(sourceIndex) - + return self.createIndex(row, sourceIndex.column(), item) - + def flags(self, index): if not index.isValid(): return Qt.NoItemFlags - + if index.isValid() and not self.mapToSource(index).isValid(): - return Qt.NoItemFlags#Qt.ItemIsEnabled + return Qt.NoItemFlags # Qt.ItemIsEnabled else: return Qt.ItemIsEnabled | Qt.ItemIsSelectable - + def mapToSource(self, proxyIndex): if not proxyIndex.isValid(): return QModelIndex() - + row = self._map[proxyIndex.row()] - + if type(row) != int: return QModelIndex() - - #item = proxyIndex.internalPointer() + + # item = proxyIndex.internalPointer() item = self.sourceModel().item(row, proxyIndex.column()) - + return self.sourceModel().indexFromItem(item) - + def setSourceModel(self, model): QSortFilterProxyModel.setSourceModel(self, model) self.sourceModel().dataChanged.connect(self.mapModelMaybe) self.sourceModel().rowsInserted.connect(self.mapModel) self.sourceModel().rowsRemoved.connect(self.mapModel) self.sourceModel().rowsMoved.connect(self.mapModel) - + self.mapModel() - + def mapModelMaybe(self, topLeft, bottomRight): if topLeft.column() <= Plot.importance.value <= bottomRight.column(): self.mapModel() - + def mapModel(self): self.beginResetModel() src = self.sourceModel() - + self._map = [] - + for i in range(len(self._cats)): self._map.append(self._cats[i]) - + for p in range(src.rowCount()): item = src.item(p, Plot.importance.value) - + if item: imp = int(item.text()) else: imp = 0 - - if 2-imp == i: + + if 2 - imp == i: self._map.append(p) - + self.endResetModel() - - + def data(self, index, role=Qt.DisplayRole): - + if index.isValid() and not self.mapToSource(index).isValid(): row = index.row() - + if role == Qt.DisplayRole: return self._map[row].text() - + elif role == Qt.ForegroundRole: return QBrush(Qt.darkBlue) elif role == Qt.BackgroundRole: @@ -110,32 +112,32 @@ class plotsProxyModel(QSortFilterProxyModel): return Qt.AlignCenter elif role == Qt.FontRole: f = QFont() - #f.setPointSize(f.pointSize() + 1) + # f.setPointSize(f.pointSize() + 1) f.setWeight(QFont.Bold) return f 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) - + def index(self, row, column, parent): - + i = self._map[row] - + if type(i) != int: return self.createIndex(row, column, i) - + else: return self.mapFromSource(self.sourceModel().index(i, column, QModelIndex())) - + def parent(self, index=QModelIndex()): return QModelIndex() - + def rowCount(self, parent=QModelIndex()): return len(self._map) - + def columnCount(self, parent=QModelIndex()): return self.sourceModel().columnCount(QModelIndex()) - + def item(self, row, col, parent=QModelIndex()): idx = self.mapToSource(self.index(row, col, parent)) - return self.sourceModel().item(idx.row(), idx.column()) \ No newline at end of file + return self.sourceModel().item(idx.row(), idx.column()) diff --git a/manuskript/models/references.py b/manuskript/models/references.py index e156793..8afa728 100644 --- a/manuskript/models/references.py +++ b/manuskript/models/references.py @@ -1,9 +1,6 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * +# --!-- coding: utf8 --!-- + import re ############################################################################### @@ -11,6 +8,14 @@ import re ############################################################################### # 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+):?.*?}" # A non-capturing regex used to identify references RegExNonCapturing = r"{\w:\d+:?.*?}" @@ -21,21 +26,26 @@ TextLetter = "T" PlotLetter = "P" WorldLetter = "W" + 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, "") + 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, "") + 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, "") + def worldReference(ID): - "Takes the ID of a world item and returns a reference for that item." - return EmptyRef.format(WordLetter, ID, "") + """Takes the ID of a world item and returns a reference for that item.""" + return EmptyRef.format(WorldLetter, ID, "") + ############################################################################### # READABLE INFOS @@ -48,21 +58,21 @@ def infos(ref): match = re.fullmatch(RegEx, ref) if not match: return qApp.translate("references", "Not a reference: {}.").format(ref) - + _type = match.group(1) _ref = match.group(2) - + # A text or outine item if _type == TextLetter: m = mainWindow().mdlOutline idx = m.getIndexByID(_ref) - + if not idx.isValid(): return qApp.translate("references", "Unknown reference: {}.").format(ref) - + item = idx.internalPointer() - - #Titles + + # Titles pathTitle = qApp.translate("references", "Path:") statsTitle = qApp.translate("references", "Stats:") POVTitle = qApp.translate("references", "POV:") @@ -71,42 +81,42 @@ def infos(ref): ssTitle = qApp.translate("references", "Short summary:") lsTitle = qApp.translate("references", "Long summary:") notesTitle = qApp.translate("references", "Notes:") - + # The POV of the scene POV = "" if item.POV(): POV = "{text}".format( - ref=persoReference(item.POV()), - text=mainWindow().mdlPersos.getPersoNameByID(item.POV())) - + ref=persoReference(item.POV()), + text=mainWindow().mdlPersos.getPersoNameByID(item.POV())) + # The status of the scene status = item.status() if status: status = mainWindow().mdlStatus.item(int(status), 0).text() else: status = "" - + # The label of the scene label = item.label() if label: label = mainWindow().mdlLabels.item(int(label), 0).text() else: label = "" - + # The path of the scene path = item.pathID() pathStr = [] for _id, title in path: pathStr.append("{text}".format( - ref=textReference(_id), - text=title)) + ref=textReference(_id), + text=title)) path = " > ".join(pathStr) - + # Summaries and notes ss = item.data(Outline.summarySentance.value) ls = item.data(Outline.summaryFull.value) notes = item.data(Outline.notes.value) - + text = """

{title}

{pathTitle} {path}

{statsTitle} {stats}
@@ -118,86 +128,86 @@ def infos(ref): {notes} {references} """.format( - title=item.title(), - pathTitle=pathTitle, - path=path, - statsTitle=statsTitle, - stats=item.stats(), - POV="{POVTitle} {POV}
".format( - POVTitle=POVTitle, - POV=POV) if POV else "", - status="{statusTitle} {status}
".format( - statusTitle=statusTitle, - status=status) if status else "", - label="{labelTitle} {label}

".format( - labelTitle=labelTitle, - label=label) if label else "", - ss="

{ssTitle} {ss}

".format( - ssTitle=ssTitle, - ss=ss.replace("\n", "
")) if ss.strip() else "", - ls="

{lsTitle}
{ls}

".format( - lsTitle=lsTitle, - ls=ls.replace("\n", "
")) if ls.strip() else "", - notes="

{notesTitle}
{notes}

".format( - notesTitle=notesTitle, - notes=linkifyAllRefs(basicT2TFormat(notes))) if notes.strip() else "", - references=listReferences(ref) - ) - + title=item.title(), + pathTitle=pathTitle, + path=path, + statsTitle=statsTitle, + stats=item.stats(), + POV="{POVTitle} {POV}
".format( + POVTitle=POVTitle, + POV=POV) if POV else "", + status="{statusTitle} {status}
".format( + statusTitle=statusTitle, + status=status) if status else "", + label="{labelTitle} {label}

".format( + labelTitle=labelTitle, + label=label) if label else "", + ss="

{ssTitle} {ss}

".format( + ssTitle=ssTitle, + ss=ss.replace("\n", "
")) if ss.strip() else "", + ls="

{lsTitle}
{ls}

".format( + lsTitle=lsTitle, + ls=ls.replace("\n", "
")) if ls.strip() else "", + notes="

{notesTitle}
{notes}

".format( + notesTitle=notesTitle, + notes=linkifyAllRefs(basicT2TFormat(notes))) if notes.strip() else "", + references=listReferences(ref) + ) + return text - + # A character elif _type == PersoLetter: m = mainWindow().mdlPersos index = m.getIndexFromID(_ref) name = m.name(index.row()) - + # Titles basicTitle = qApp.translate("references", "Basic infos") detailedTitle = qApp.translate("references", "Detailed infos") POVof = qApp.translate("references", "POV of:") - + # Goto (link) goto = qApp.translate("references", "Go to {}.") goto = goto.format(refToLink(ref)) - + # basic infos basic = [] for i in [ - (Perso.motivation, qApp.translate("references", "Motivation"), False), - (Perso.goal, qApp.translate("references", "Goal"), False), - (Perso.conflict, qApp.translate("references", "Conflict"), False), - (Perso.epiphany, qApp.translate("references", "Epiphany"), False), - (Perso.summarySentance, qApp.translate("references", "Short summary"), True), + (Perso.motivation, qApp.translate("references", "Motivation"), False), + (Perso.goal, qApp.translate("references", "Goal"), False), + (Perso.conflict, qApp.translate("references", "Conflict"), False), + (Perso.epiphany, qApp.translate("references", "Epiphany"), False), + (Perso.summarySentance, qApp.translate("references", "Short summary"), True), (Perso.summaryPara, qApp.translate("references", "Longer summary"), True), - ]: + ]: val = m.data(index.sibling(index.row(), i[0].value)) if val: - basic .append("{title}:{n}{val}".format( - title=i[1], - n = "\n" if i[2] else " ", - val=val)) + basic.append("{title}:{n}{val}".format( + title=i[1], + n="\n" if i[2] else " ", + val=val)) basic = "
".join(basic) - + # detailed infos detailed = [] for _name, _val in m.listPersoInfos(index): detailed.append("{}: {}".format( - _name, - _val)) + _name, + _val)) detailed = "
".join(detailed) - + # list scenes of which it is POV oM = mainWindow().mdlOutline lst = oM.findItemsByPOV(_ref) - + listPOV = "" for t in lst: idx = oM.getIndexByID(t) listPOV += "
  • {text}
  • ".format( - link=textReference(t), - text=oM.data(idx, Outline.title.value)) - + link=textReference(t), + text=oM.data(idx, Outline.title.value)) + text = """

    {name}

    {goto} {basicInfos} @@ -205,45 +215,45 @@ def infos(ref): {POV} {references} """.format( - name=name, - goto=goto, - basicInfos="

    {basicTitle}

    {basic}".format( - basicTitle=basicTitle, - basic=basic) if basic else "", - detailedInfos="

    {detailedTitle}

    {detailed}".format( - detailedTitle=detailedTitle, - detailed=detailed) if detailed else "", - POV="

    {POVof}

    ".format( - POVof=POVof, - listPOV=listPOV) if listPOV else "", - references=listReferences(ref) - ) + name=name, + goto=goto, + basicInfos="

    {basicTitle}

    {basic}".format( + basicTitle=basicTitle, + basic=basic) if basic else "", + detailedInfos="

    {detailedTitle}

    {detailed}".format( + detailedTitle=detailedTitle, + detailed=detailed) if detailed else "", + POV="

    {POVof}

    ".format( + POVof=POVof, + listPOV=listPOV) if listPOV else "", + references=listReferences(ref) + ) return text - + # A plot elif _type == PlotLetter: m = mainWindow().mdlPlots index = m.getIndexFromID(_ref) name = m.getPlotNameByID(_ref) - + # Titles descriptionTitle = qApp.translate("references", "Description") resultTitle = qApp.translate("references", "Result") charactersTitle = qApp.translate("references", "Characters") stepsTitle = qApp.translate("references", "Resolution steps") - + # Goto (link) goto = qApp.translate("references", "Go to {}.") goto = goto.format(refToLink(ref)) - + # Description - description = m.data(index.sibling(index.row(), + description = m.data(index.sibling(index.row(), Plot.description.value)) - + # Result - result = m.data(index.sibling(index.row(), - Plot.result.value)) - + result = m.data(index.sibling(index.row(), + Plot.result.value)) + # Characters pM = mainWindow().mdlPersos item = m.item(index.row(), Plot.persos.value) @@ -252,9 +262,9 @@ def infos(ref): for r in range(item.rowCount()): ID = item.child(r, 0).text() characters += "
  • {text}".format( - link=persoReference(ID), - text=pM.getPersoNameByID(ID)) - + link=persoReference(ID), + text=pM.getPersoNameByID(ID)) + # Resolution steps steps = "" item = m.item(index.row(), Plot.subplots.value) @@ -266,10 +276,10 @@ def infos(ref): if meta: meta = " ({})".format(meta) steps += "
  • {title}{summary}{meta}
  • ".format( - title=title, - summary=": {}".format(summary) if summary else "", - meta = meta if meta else "") - + title=title, + summary=": {}".format(summary) if summary else "", + meta=meta if meta else "") + text = """

    {name}

    {goto} {characters} @@ -278,48 +288,48 @@ def infos(ref): {steps} {references} """.format( - name=name, - goto=goto, - description="

    {title}

    {text}".format( - title=descriptionTitle, - text=description) if description else "", - result="

    {title}

    {text}".format( - title=resultTitle, - text=result) if result else "", - characters="

    {title}

    ".format( - title=charactersTitle, - lst=characters) if characters else "", - steps="

    {title}

    ".format( - title=stepsTitle, - steps=steps) if steps else "", - references=listReferences(ref, referenceTitle) - ) + name=name, + goto=goto, + description="

    {title}

    {text}".format( + title=descriptionTitle, + text=description) if description else "", + result="

    {title}

    {text}".format( + title=resultTitle, + text=result) if result else "", + characters="

    {title}

    ".format( + title=charactersTitle, + lst=characters) if characters else "", + steps="

    {title}

    ".format( + title=stepsTitle, + steps=steps) if steps else "", + references=listReferences(ref) + ) return text - + # A World item elif _type == WorldLetter: m = mainWindow().mdlWorld index = m.indexByID(_ref) name = m.name(index) - + # Titles descriptionTitle = qApp.translate("references", "Description") passionTitle = qApp.translate("references", "Passion") conflictTitle = qApp.translate("references", "Conflict") - + # Goto (link) goto = qApp.translate("references", "Go to {}.") goto = goto.format(refToLink(ref)) - + # Description description = basicFormat(m.description(index)) - + # Passion - passion = basicFormat(m.passion(index)) - + passion = basicFormat(m.passion(index)) + # Conflict - conflict = basicFormat(m.conflict(index)) - + conflict = basicFormat(m.conflict(index)) + text = """

    {name}

    {goto} {description} @@ -327,60 +337,61 @@ def infos(ref): {conflict} {references} """.format( - name=name, - goto=goto, - description="

    {title}

    {text}".format( - title=descriptionTitle, - text=description) if description else "", - passion="

    {title}

    {text}".format( - title=passionTitle, - text=passion) if passion else "", - conflict="

    {title}

    ".format( - title=conflictTitle, - lst=conflict) if conflict else "", - references=listReferences(ref) - ) + name=name, + goto=goto, + description="

    {title}

    {text}".format( + title=descriptionTitle, + text=description) if description else "", + passion="

    {title}

    {text}".format( + title=passionTitle, + text=passion) if passion else "", + conflict="

    {title}

    ".format( + title=conflictTitle, + lst=conflict) if conflict else "", + references=listReferences(ref) + ) return text - + else: return qApp.translate("references", "Unknown reference: {}.").format(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) - + if not match: return qApp.translate("references", "Not a reference: {}.").format(ref) - + _type = match.group(1) _ref = match.group(2) - + if _type == TextLetter: m = mainWindow().mdlOutline idx = m.getIndexByID(_ref) - + if not idx.isValid(): return qApp.translate("references", "Unknown reference: {}.").format(ref) - + item = idx.internalPointer() - - tooltip = qApp.translate("references", "Text: {}").format(item.title()) - tooltip += "
    {}".format(item.path()) - - return tooltip - + + tt = qApp.translate("references", "Text: {}").format(item.title()) + tt += "
    {}".format(item.path()) + + return tt + elif _type == PersoLetter: m = mainWindow().mdlPersos item = m.item(int(_ref), Perso.name.value) if item: return qApp.translate("references", "Character: {}").format(item.text()) - + elif _type == PlotLetter: m = mainWindow().mdlPlots name = m.getPlotNameByID(_ref) if name: return qApp.translate("references", "Plot: {}").format(name) - + elif _type == WorldLetter: m = mainWindow().mdlWorld item = m.itemByID(_ref) @@ -388,15 +399,16 @@ def tooltip(ref): name = item.text() path = m.path(item) return qApp.translate("references", "World: {name}{path}").format( - name=name, - path=" ({})".format(path) if path else "") - + name=name, + path=" ({})".format(path) if path else "") + return qApp.translate("references", "Unknown reference: {}.").format(ref) - + + ############################################################################### # FUNCTIONS ############################################################################### - + def refToLink(ref): """Transforms the reference ``ref`` in a link displaying useful infos about that reference. For character, character's name. For text item, @@ -413,30 +425,32 @@ def refToLink(ref): if idx.isValid(): item = idx.internalPointer() text = item.title() - + elif _type == PersoLetter: m = mainWindow().mdlPersos text = m.item(int(_ref), Perso.name.value).text() - + elif _type == PlotLetter: m = mainWindow().mdlPlots text = m.getPlotNameByID(_ref) - + elif _type == WorldLetter: m = mainWindow().mdlWorld text = m.itemByID(_ref).text() - + if text: return "{text}".format( ref=ref, text=text) else: return ref - + + 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) - + + def listReferences(ref, title=qApp.translate("references", "Referenced in:")): oM = mainWindow().mdlOutline listRefs = "" @@ -445,22 +459,23 @@ def listReferences(ref, title=qApp.translate("references", "Referenced in:")): for t in lst: idx = oM.getIndexByID(t) listRefs += "
  • {text}
  • ".format( - link=textReference(t), - text=oM.data(idx, Outline.title.value)) - + link=textReference(t), + text=oM.data(idx, Outline.title.value)) + return "

    {title}

    ".format( - title=title, - ref=listRefs) if listRefs else "" - + title=title, + ref=listRefs) if listRefs else "" + + 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() for n, line in enumerate(text): if formatting: line = re.sub("\*\*(.*?)\*\*", "\\1", line) line = re.sub("//(.*?)//", "\\1", line) line = re.sub("__(.*?)__", "\\1", line) - + if titles: for i in range(1, 6): 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) if EOL: text = text.replace("\n", "
    ") - + return text + def basicFormat(text): if not text: return "" @@ -482,31 +498,32 @@ def basicFormat(text): text = linkifyAllRefs(text) return text + def open(ref): - "Identify ``ref`` and open it." + """Identify ``ref`` and open it.""" match = re.fullmatch(RegEx, ref) if not match: return - + _type = match.group(1) _ref = match.group(2) - + if _type == PersoLetter: mw = mainWindow() item = mw.lstPersos.getItemByID(_ref) - + if item: mw.tabMain.setCurrentIndex(mw.TabPersos) mw.lstPersos.setCurrentItem(item) return True - + print("Ref not found") return False - + elif _type == TextLetter: mw = mainWindow() index = mw.mdlOutline.getIndexByID(_ref) - + if index.isValid(): mw.tabMain.setCurrentIndex(mw.TabRedac) mw.mainEditor.setCurrentModelIndex(index, newTab=True) @@ -514,31 +531,31 @@ def open(ref): else: print("Ref not found") return False - - elif _type == PlotLetter: + + elif _type == PlotLetter: mw = mainWindow() item = mw.lstPlots.getItemByID(_ref) - + if item: mw.tabMain.setCurrentIndex(mw.TabPlots) mw.lstPlots.setCurrentItem(item) return True - + print("Ref not found") return False - - elif _type == WorldLetter: + + elif _type == WorldLetter: mw = mainWindow() item = mw.mdlWorld.itemByID(_ref) - + if item: mw.tabMain.setCurrentIndex(mw.TabWorld) mw.treeWorld.setCurrentIndex( - mw.mdlWorld.indexFromItem(item)) + mw.mdlWorld.indexFromItem(item)) return True - + print("Ref not found") return False - + print("Ref not implemented") - return False \ No newline at end of file + return False diff --git a/manuskript/models/worldModel.py b/manuskript/models/worldModel.py index a07ea39..5f600e6 100644 --- a/manuskript/models/worldModel.py +++ b/manuskript/models/worldModel.py @@ -1,23 +1,27 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -import collections +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import QModelIndex +from PyQt5.QtCore import QSize +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QStandardItem, QBrush, QFontMetrics +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): - def __init__(self, parent): QStandardItemModel.__init__(self, 0, 3, parent) self.mw = mainWindow() -############################################################################### -# SELECTION -############################################################################### + ############################################################################### + # SELECTION + ############################################################################### 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() item = self.itemFromIndex(index) if item: @@ -26,57 +30,57 @@ class worldModel(QStandardItemModel): return self.invisibleRootItem() def selectedIndex(self): - "Returns the selected index in the treeView." + """Returns the selected index in the treeView.""" if self.mw.treeWorld.selectedIndexes(): return self.mw.treeWorld.currentIndex() else: return QModelIndex() - + def selectedIndexes(self): return self.mw.treeWorld.selectedIndexes() -############################################################################### -# GETTERS -############################################################################### + ############################################################################### + # GETTERS + ############################################################################### 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) return self.data(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) return self.data(index) - + def description(self, index): index = index.sibling(index.row(), World.description.value) return self.data(index) - + def conflict(self, index): index = index.sibling(index.row(), World.conflict.value) return self.data(index) - + def passion(self, index): index = index.sibling(index.row(), World.passion.value) return self.data(index) - + def itemID(self, item): - "Returns the ID of the given item." + """Returns the ID of the given item.""" index = self.indexFromItem(item) return self.ID(index) - + def children(self, item): - "Returns a list of all item's children." + """Returns a list of all item's children.""" c = [] for i in range(item.rowCount()): c.append(item.child(i)) return c - + 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 = [] - + def readAll(item): name = item.text() ID = self.itemID(item) @@ -85,17 +89,18 @@ class worldModel(QStandardItemModel): lst.append((name, ID, path)) for c in self.children(item): readAll(c) - + readAll(self.invisibleRootItem()) - + return lst - + 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)) - + def itemByID(self, ID): - "Returns the item whose ID is ID." + """Returns the item whose ID is ID.""" + def browse(item): if self.itemID(item) == ID: return item @@ -103,25 +108,25 @@ class worldModel(QStandardItemModel): r = browse(c) if r: return r - + r = browse(self.invisibleRootItem()) return r if r else None - + 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 = [] while item.parent(): item = item.parent() path.append(item.text()) path = " > ".join(path) return path - -############################################################################### -# ADDING AND REMOVE -############################################################################### + + ############################################################################### + # ADDING AND REMOVE + ############################################################################### def addItem(self, title=None, parent=None): - "Adds an item, and returns it." + """Adds an item, and returns it.""" if not parent: parent = self.selectedItem() if not title: @@ -133,21 +138,22 @@ class worldModel(QStandardItemModel): return name def getUniqueID(self): - "Returns an unused ID" - + """Returns an unused ID""" + parentItem = self.invisibleRootItem() vals = [] - + def collectIDs(item): vals.append(int(self.itemID(item))) for c in self.children(item): collectIDs(c) - + for c in self.children(parentItem): collectIDs(c) - + k = 0 - while k in vals: k += 1 + while k in vals: + k += 1 return str(k) def removeItem(self): @@ -155,12 +161,12 @@ class worldModel(QStandardItemModel): index = self.selectedIndexes()[0] self.removeRows(index.row(), 1, index.parent()) -############################################################################### -# TEMPLATES -############################################################################### + ############################################################################### + # TEMPLATES + ############################################################################### 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 = { self.tr("Fantasy world building"): [ (self.tr("Physical"), [ @@ -173,7 +179,7 @@ class worldModel(QStandardItemModel): self.tr("History"), self.tr("Races"), self.tr("Diseases"), - ]), + ]), (self.tr("Cultural"), [ self.tr("Customs"), self.tr("Food"), @@ -196,34 +202,34 @@ class worldModel(QStandardItemModel): self.tr("Demography"), self.tr("Transportation"), self.tr("Medicine"), - ]), + ]), (self.tr("Magic system"), [ self.tr("Rules"), self.tr("Organization"), self.tr("Magical objects"), self.tr("Magical places"), self.tr("Magical races"), - ]), + ]), self.tr("Important places"), self.tr("Important objects"), - ] - } + ] + } return dataset - + def emptyDataMenu(self): - "Returns a menu with the empty data sets." + """Returns a menu with the empty data sets.""" self.menu = QMenu("menu") for name in self.dataSets(): a = QAction(name, self.menu) a.triggered.connect(self.setEmptyData) self.menu.addAction(a) return self.menu - + def setEmptyData(self): - "Called from the menu generated with ``emptyDataMenu``." + """Called from the menu generated with ``emptyDataMenu``.""" act = self.sender() data = self.dataSets()[act.text()] - + def addItems(data, parent): for d in data: if len(d) == 1 or type(d) == str: @@ -231,39 +237,39 @@ class worldModel(QStandardItemModel): else: i = self.addItem(d[0], parent) addItems(d[1], i) - + addItems(data, None) self.mw.treeWorld.expandAll() -############################################################################### -# APPEARANCE -############################################################################### - + ############################################################################### + # APPEARANCE + ############################################################################### + def data(self, index, role=Qt.EditRole): level = 0 i = index while i.parent() != QModelIndex(): i = i.parent() level += 1 - + if role == Qt.BackgroundRole: if level == 0: return QBrush(lightBlue()) - + if role == Qt.TextAlignmentRole: if level == 0: return Qt.AlignCenter - + if role == Qt.FontRole: if level in [0, 1]: f = qApp.font() f.setBold(True) return f - + if role == Qt.ForegroundRole: if level == 0: return QBrush(Qt.darkBlue) - + if role == Qt.SizeHintRole: fm = QFontMetrics(qApp.font()) h = fm.height() @@ -271,6 +277,5 @@ class worldModel(QStandardItemModel): return QSize(0, h + 12) elif level == 1: return QSize(0, h + 6) - + return QStandardItemModel.data(self, index, role) - \ No newline at end of file diff --git a/manuskript/qt.py b/manuskript/qt.py deleted file mode 100644 index 08b5a73..0000000 --- a/manuskript/qt.py +++ /dev/null @@ -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 * \ No newline at end of file diff --git a/manuskript/settings.py b/manuskript/settings.py index cba3c87..d2de98c 100644 --- a/manuskript/settings.py +++ b/manuskript/settings.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -import pickle -import pprint -from enums import * -from qt import * import collections +import pickle + +from PyQt5.QtWidgets import qApp + +from manuskript.enums import Outline viewSettings = { "Tree": { diff --git a/manuskript/settingsWindow.py b/manuskript/settingsWindow.py index 23c0b87..d1589c7 100644 --- a/manuskript/settingsWindow.py +++ b/manuskript/settingsWindow.py @@ -1,41 +1,48 @@ #!/usr/bin/env python -#--!-- 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 +# --!-- coding: utf8 --!-- 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 +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: import enchant except ImportError: enchant = None + class settingsWindow(QWidget, Ui_Settings): - def __init__(self, mainWindow): QWidget.__init__(self) self.setupUi(self) self.mw = mainWindow - + # UI for i in range(self.lstMenu.count()): item = self.lstMenu.item(i) item.setSizeHint(QSize(item.sizeHint().width(), 42)) item.setTextAlignment(Qt.AlignCenter) self.lstMenu.setMaximumWidth(150) - + # General self.cmbStyle.addItems(list(QStyleFactory.keys())) self.cmbStyle.setCurrentIndex([i.lower() for i in list(QStyleFactory.keys())].index(qApp.style().objectName())) self.cmbStyle.currentIndexChanged[str].connect(self.setStyle) - + self.txtAutoSave.setValidator(QIntValidator(0, 999, self)) self.txtAutoSaveNoChanges.setValidator(QIntValidator(0, 999, self)) self.chkAutoSave.setChecked(settings.autoSave) @@ -51,12 +58,12 @@ class settingsWindow(QWidget, Ui_Settings): autoLoad, last = self.mw.welcome.getAutoLoadValues() self.chkAutoLoad.setChecked(autoLoad) self.chkAutoLoad.stateChanged.connect(self.saveSettingsChanged) - + dtt = [ ("t2t", self.tr("Txt2Tags"), "text-x-script"), ("html", self.tr("Rich Text (html)"), "text-html"), ("txt", self.tr("Plain Text"), "text-x-generic"), - ] + ] self.cmbDefaultTextType.clear() for t in dtt: self.cmbDefaultTextType.addItem(QIcon.fromTheme(t[2]), t[1], t[0]) @@ -64,7 +71,7 @@ class settingsWindow(QWidget, Ui_Settings): if i != -1: self.cmbDefaultTextType.setCurrentIndex(i) self.cmbDefaultTextType.currentIndexChanged.connect(self.saveSettingsChanged) - + # Revisions opt = settings.revisions self.chkRevisionsKeep.setChecked(opt["keep"]) @@ -81,7 +88,7 @@ class settingsWindow(QWidget, Ui_Settings): self.spnRevisionsMonth.valueChanged.connect(self.revisionsSettingsChanged) self.spnRevisionsEternity.setValue(60 * 60 * 24 * 7 / opt["rules"][None]) self.spnRevisionsEternity.valueChanged.connect(self.revisionsSettingsChanged) - + # Views self.tabViews.setCurrentIndex(0) lst = ["Nothing", "POV", "Label", "Progress", "Compile"] @@ -89,12 +96,12 @@ class settingsWindow(QWidget, Ui_Settings): item, part = self.viewSettingsDatas()[cmb] cmb.setCurrentIndex(lst.index(settings.viewSettings[item][part])) cmb.currentIndexChanged.connect(self.viewSettingsChanged) - + for chk in self.outlineColumnsData(): col = self.outlineColumnsData()[chk] chk.setChecked(col in settings.outlineViewColumns) chk.stateChanged.connect(self.outlineColumnsChanged) - + for item, what, value in [ (self.rdoTreeItemCount, "InfoFolder", "Count"), (self.rdoTreeWC, "InfoFolder", "WC"), @@ -103,16 +110,16 @@ class settingsWindow(QWidget, Ui_Settings): (self.rdoTreeTextWC, "InfoText", "WC"), (self.rdoTreeTextProgress, "InfoText", "Progress"), (self.rdoTreeTextNothing, "InfoText", "Nothing"), - ]: + ]: item.setChecked(settings.viewSettings["Tree"][what] == value) item.toggled.connect(self.treeViewSettignsChanged) - + self.populatesCmbBackgrounds(self.cmbCorkImage) self.setCorkImageDefault() self.updateCorkColor() self.cmbCorkImage.currentIndexChanged.connect(self.setCorkBackground) self.btnCorkColor.clicked.connect(self.setCorkColor) - + # Text editor opt = settings.textEditor self.setButtonColor(self.btnEditorFontColor, opt["fontColor"]) @@ -128,10 +135,10 @@ class settingsWindow(QWidget, Ui_Settings): self.spnEditorFontSize.setValue(f.pointSize()) self.spnEditorFontSize.valueChanged.connect(self.updateEditorSettings) self.cmbEditorLineSpacing.setCurrentIndex( - 0 if opt["lineSpacing"] == 100 else - 1 if opt["lineSpacing"] == 150 else - 2 if opt["lineSpacing"] == 200 else - 3) + 0 if opt["lineSpacing"] == 100 else + 1 if opt["lineSpacing"] == 150 else + 2 if opt["lineSpacing"] == 200 else + 3) self.cmbEditorLineSpacing.currentIndexChanged.connect(self.updateEditorSettings) self.spnEditorLineSpacing.setValue(opt["lineSpacing"]) self.spnEditorLineSpacing.valueChanged.connect(self.updateEditorSettings) @@ -145,7 +152,7 @@ class settingsWindow(QWidget, Ui_Settings): self.spnEditorParaAbove.valueChanged.connect(self.updateEditorSettings) self.spnEditorParaBelow.setValue(opt["spacingBelow"]) self.spnEditorParaAbove.valueChanged.connect(self.updateEditorSettings) - + # Labels self.lstLabels.setModel(self.mw.mdlLabels) self.lstLabels.setRowHidden(0, True) @@ -153,13 +160,13 @@ class settingsWindow(QWidget, Ui_Settings): self.btnLabelAdd.clicked.connect(self.addLabel) self.btnLabelRemove.clicked.connect(self.removeLabel) self.btnLabelColor.clicked.connect(self.setLabelColor) - + # Statuses self.lstStatus.setModel(self.mw.mdlStatus) self.lstStatus.setRowHidden(0, True) self.btnStatusAdd.clicked.connect(self.addStatus) self.btnStatusRemove.clicked.connect(self.removeStatus) - + # Fullscreen self._editingTheme = None 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.btnThemeEdit.clicked.connect(self.editTheme) self.btnThemeRemove.clicked.connect(self.removeTheme) - - + def setTab(self, tab): - + tabs = { - "General":0, - "Views":1, - "Labels":2, - "Status":3, - "Fullscreen":4, - } - + "General": 0, + "Views": 1, + "Labels": 2, + "Status": 3, + "Fullscreen": 4, + } + if tab in tabs: self.lstMenu.setCurrentRow(tabs[tab]) else: self.lstMenu.setCurrentRow(tab) -#################################################################################################### -# GENERAL # -#################################################################################################### - + #################################################################################################### + # GENERAL # + #################################################################################################### + def setStyle(self, style): - #Save style to Qt Settings + # Save style to Qt Settings sttgs = QSettings(qApp.organizationName(), qApp.applicationName()) sttgs.setValue("applicationStyle", style) qApp.setStyle(style) - + def saveSettingsChanged(self): if self.txtAutoSave.text() in ["", "0"]: self.txtAutoSave.setText("1") if self.txtAutoSaveNoChanges.text() in ["", "0"]: self.txtAutoSaveNoChanges.setText("1") - + sttgs = QSettings() sttgs.setValue("autoLoad", True if self.chkAutoLoad.checkState() else False) sttgs.sync() - + settings.autoSave = True if self.chkAutoSave.checkState() else False settings.autoSaveNoChanges = True if self.chkAutoSaveNoChanges.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) settings.defaultTextType = self.cmbDefaultTextType.currentData() - -#################################################################################################### -# REVISION # -#################################################################################################### + #################################################################################################### + # REVISION # + #################################################################################################### def revisionsSettingsChanged(self): 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 * 30] = 60 * 60 * 24 / self.spnRevisionsMonth.value() opt["rules"][None] = 60 * 60 * 24 * 7 / self.spnRevisionsEternity.value() - -#################################################################################################### -# VIEWS # -#################################################################################################### + + #################################################################################################### + # VIEWS # + #################################################################################################### def viewSettingsDatas(self): return { @@ -252,15 +257,15 @@ class settingsWindow(QWidget, Ui_Settings): self.cmbCorkBackground: ("Cork", "Background"), self.cmbCorkBorder: ("Cork", "Border"), self.cmbCorkCorner: ("Cork", "Corner") - } - + } + def viewSettingsChanged(self): cmb = self.sender() lst = ["Nothing", "POV", "Label", "Progress", "Compile"] item, part = self.viewSettingsDatas()[cmb] element = lst[cmb.currentIndex()] self.mw.setViewSettings(item, part, element) - + def outlineColumnsData(self): return { self.chkOutlineTitle: Outline.title.value, @@ -271,8 +276,8 @@ class settingsWindow(QWidget, Ui_Settings): self.chkOutlineWordCount: Outline.wordCount.value, self.chkOutlineGoal: Outline.goal.value, self.chkOutlinePercentage: Outline.goalPercentage.value, - } - + } + def outlineColumnsChanged(self): chk = self.sender() val = True if chk.checkState() else False @@ -281,11 +286,11 @@ class settingsWindow(QWidget, Ui_Settings): settings.outlineViewColumns.append(col) elif not val and col in settings.outlineViewColumns: settings.outlineViewColumns.remove(col) - + # Update views self.mw.redacEditor.outlineView.hideColumns() self.mw.treePlanOutline.hideColumns() - + def treeViewSettignsChanged(self): for item, what, value in [ (self.rdoTreeItemCount, "InfoFolder", "Count"), @@ -295,12 +300,12 @@ class settingsWindow(QWidget, Ui_Settings): (self.rdoTreeTextWC, "InfoText", "WC"), (self.rdoTreeTextProgress, "InfoText", "Progress"), (self.rdoTreeTextNothing, "InfoText", "Nothing"), - ]: + ]: if item.isChecked(): settings.viewSettings["Tree"][what] = value - + self.mw.treeRedacOutline.viewport().update() - + def setCorkColor(self): color = QColor(settings.corkBackground["color"]) self.colorDialog = QColorDialog(color, self) @@ -310,10 +315,10 @@ class settingsWindow(QWidget, Ui_Settings): self.updateCorkColor() # Update Cork view self.mw.mainEditor.updateCorkBackground() - + def updateCorkColor(self): self.btnCorkColor.setStyleSheet("background:{};".format(settings.corkBackground["color"])) - + def setCorkBackground(self, i): img = self.cmbCorkImage.itemData(i) if img: @@ -322,11 +327,11 @@ class settingsWindow(QWidget, Ui_Settings): settings.corkBackground["image"] = "" # Update Cork view self.mw.mainEditor.updateCorkBackground() - + def populatesCmbBackgrounds(self, cmb): - #self.cmbDelegate = cmbPixmapDelegate() - #self.cmbCorkImage.setItemDelegate(self.cmbDelegate) - + # self.cmbDelegate = cmbPixmapDelegate() + # self.cmbCorkImage.setItemDelegate(self.cmbDelegate) + paths = allPaths("resources/backgrounds") cmb.clear() cmb.addItem(QIcon.fromTheme("list-remove"), "", "") @@ -334,21 +339,21 @@ class settingsWindow(QWidget, Ui_Settings): lst = os.listdir(p) for l in lst: 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) cmb.addItem(QIcon(px), "", os.path.join(p, l)) - + cmb.setIconSize(QSize(128, 64)) - + def setCorkImageDefault(self): if settings.corkBackground["image"] != "": i = self.cmbCorkImage.findData(settings.corkBackground["image"]) if i != -1: self.cmbCorkImage.setCurrentIndex(i) -#################################################################################################### -# VIEWS / EDITOR -#################################################################################################### + #################################################################################################### + # VIEWS / EDITOR + #################################################################################################### def updateEditorSettings(self): # Store settings @@ -356,20 +361,20 @@ class settingsWindow(QWidget, Ui_Settings): f.setPointSize(self.spnEditorFontSize.value()) settings.textEditor["font"] = f.toString() settings.textEditor["lineSpacing"] = \ - 100 if self.cmbEditorLineSpacing.currentIndex() == 0 else\ - 150 if self.cmbEditorLineSpacing.currentIndex() == 1 else\ - 200 if self.cmbEditorLineSpacing.currentIndex() == 2 else\ + 100 if self.cmbEditorLineSpacing.currentIndex() == 0 else \ + 150 if self.cmbEditorLineSpacing.currentIndex() == 1 else \ + 200 if self.cmbEditorLineSpacing.currentIndex() == 2 else \ self.spnEditorLineSpacing.value() self.spnEditorLineSpacing.setEnabled(self.cmbEditorLineSpacing.currentIndex() == 3) settings.textEditor["tabWidth"] = self.spnEditorTabWidth.value() settings.textEditor["indent"] = True if self.chkEditorIndent.checkState() else False settings.textEditor["spacingAbove"] = self.spnEditorParaAbove.value() settings.textEditor["spacingBelow"] = self.spnEditorParaBelow.value() - + # Update font and defaultBlockFormat to all textEditView. Drastically. for w in mainWindow().findChildren(textEditView, QRegExp(".*")): w.loadFontSettings() - + def choseEditorFontColor(self): color = settings.textEditor["fontColor"] self.colorDialog = QColorDialog(QColor(color), self) @@ -387,7 +392,7 @@ class settingsWindow(QWidget, Ui_Settings): settings.textEditor["misspelled"] = color.name() self.setButtonColor(self.btnEditorMisspelledColor, color.name()) self.updateEditorSettings() - + def choseEditorBackgroundColor(self): color = settings.textEditor["background"] self.colorDialog = QColorDialog(QColor(color), self) @@ -396,40 +401,39 @@ class settingsWindow(QWidget, Ui_Settings): settings.textEditor["background"] = color.name() self.setButtonColor(self.btnEditorBackgroundColor, color.name()) self.updateEditorSettings() - - -#################################################################################################### -# STATUS # -#################################################################################################### + #################################################################################################### + # STATUS # + #################################################################################################### def addStatus(self): self.mw.mdlStatus.appendRow(QStandardItem(self.tr("New status"))) - + def removeStatus(self): for i in self.lstStatus.selectedIndexes(): self.mw.mdlStatus.removeRows(i.row(), 1) - -#################################################################################################### -# LABELS # -#################################################################################################### - + + #################################################################################################### + # LABELS # + #################################################################################################### + def updateLabelColor(self, index): - #px = QPixmap(64, 64) - #px.fill(iconColor(self.mw.mdlLabels.item(index.row()).icon())) - #self.btnLabelColor.setIcon(QIcon(px)) - self.btnLabelColor.setStyleSheet("background:{};".format(iconColor(self.mw.mdlLabels.item(index.row()).icon()).name())) + # px = QPixmap(64, 64) + # px.fill(iconColor(self.mw.mdlLabels.item(index.row()).icon())) + # self.btnLabelColor.setIcon(QIcon(px)) + self.btnLabelColor.setStyleSheet( + "background:{};".format(iconColor(self.mw.mdlLabels.item(index.row()).icon()).name())) self.btnLabelColor.setEnabled(True) - + def addLabel(self): px = QPixmap(32, 32) px.fill(Qt.transparent) self.mw.mdlLabels.appendRow(QStandardItem(QIcon(px), self.tr("New label"))) - + def removeLabel(self): for i in self.lstLabels.selectedIndexes(): self.mw.mdlLabels.removeRows(i.row(), 1) - + def setLabelColor(self): index = self.lstLabels.currentIndex() color = iconColor(self.mw.mdlLabels.item(index.row()).icon()) @@ -440,16 +444,16 @@ class settingsWindow(QWidget, Ui_Settings): px.fill(color) self.mw.mdlLabels.item(index.row()).setIcon(QIcon(px)) self.updateLabelColor(index) - -#################################################################################################### -# FULLSCREEN # -#################################################################################################### + + #################################################################################################### + # FULLSCREEN # + #################################################################################################### def themeSelected(self, current, previous): if current: # UI updates - self.btnThemeEdit.setEnabled(current.data(Qt.UserRole+1)) - self.btnThemeRemove.setEnabled(current.data(Qt.UserRole+1)) + self.btnThemeEdit.setEnabled(current.data(Qt.UserRole + 1)) + self.btnThemeRemove.setEnabled(current.data(Qt.UserRole + 1)) # Save settings theme = current.data(Qt.UserRole) settings.fullScreenTheme = os.path.splitext(os.path.split(theme)[1])[0] @@ -457,7 +461,7 @@ class settingsWindow(QWidget, Ui_Settings): # UI updates self.btnThemeEdit.setEnabled(False) self.btnThemeRemove.setEnabled(False) - + def newTheme(self): path = writablePath("resources/themes") name = self.tr("newtheme") @@ -468,41 +472,41 @@ class settingsWindow(QWidget, Ui_Settings): name = os.path.join(path, "{}_{}.theme".format(name, i)) else: name = os.path.join(path, "{}.theme".format(name)) - + settings = QSettings(name, QSettings.IniFormat) settings.setValue("Name", self.tr("New theme")) settings.sync() - + self.populatesThemesList() - + def editTheme(self): item = self.lstThemes.currentItem() theme = item.data(Qt.UserRole) self.loadTheme(theme) self.themeStack.setCurrentIndex(1) - + def removeTheme(self): item = self.lstThemes.currentItem() theme = item.data(Qt.UserRole) os.remove(theme) self.populatesThemesList() - + def populatesThemesList(self): paths = allPaths("resources/themes") current = settings.fullScreenTheme self.lstThemes.clear() - + for p in paths: lst = [i for i in os.listdir(p) if os.path.splitext(i)[1] == ".theme"] for t in lst: theme = os.path.join(p, t) editable = not appPath() in theme n = getThemeName(theme) - + item = QListWidgetItem(n) 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")) px = QPixmap(200, 120) px.fill(Qt.white) @@ -510,32 +514,32 @@ class settingsWindow(QWidget, Ui_Settings): currentScreen = qApp.desktop().screenNumber(self) screenRect = qApp.desktop().screenGeometry(currentScreen) thumb = createThemePreview(theme, screenRect) - + icon = QPixmap(thumb).scaled(200, 120, Qt.KeepAspectRatio) painter = QPainter(px) - painter.drawPixmap(px.rect().center()-icon.rect().center(), icon) + painter.drawPixmap(px.rect().center() - icon.rect().center(), icon) painter.end() item.setIcon(QIcon(px)) - + self.lstThemes.addItem(item) - + if current and current in t: self.lstThemes.setCurrentItem(item) current = None - + self.lstThemes.setIconSize(QSize(200, 120)) - + 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) - + def loadTheme(self, theme): self._editingTheme = theme self._loadingTheme = True # So we don't generate preview while loading - + # Load datas self._themeData = loadThemeDatas(theme) - + # Window Background self.btnThemWindowBackgroundColor.clicked.connect(lambda: self.getThemeColor("Background/Color")) try: @@ -545,7 +549,7 @@ class settingsWindow(QWidget, Ui_Settings): self.populatesCmbBackgrounds(self.cmbThemeBackgroundImage) self.cmbThemeBackgroundImage.currentIndexChanged.connect(self.updateThemeBackground) self.cmbThemBackgroundType.currentIndexChanged.connect(lambda i: self.setSetting("Background/Type", i)) - + # Text Background self.btnThemeTextBackgroundColor.clicked.connect(lambda: self.getThemeColor("Foreground/Color")) 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.spnThemeTextRadius.valueChanged.connect(lambda v: self.setSetting("Foreground/Rounding", v)) self.spnThemeTextWidth.valueChanged.connect(lambda v: self.setSetting("Foreground/Width", v)) - + # Text Options self.btnThemeTextColor.clicked.connect(lambda: self.getThemeColor("Text/Color")) self.cmbThemeFont.currentFontChanged.connect(self.updateThemeFont) @@ -565,37 +569,37 @@ class settingsWindow(QWidget, Ui_Settings): self.populatesFontSize() self.cmbThemeFontSize.currentIndexChanged.connect(self.updateThemeFont) self.btnThemeMisspelledColor.clicked.connect(lambda: self.getThemeColor("Text/Misspelled")) - + # 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.spnThemeLineSpacing.valueChanged.connect(lambda v: self.setSetting("Spacings/LineSpacing", v)) self.spnThemeParaAbove.valueChanged.connect(lambda v: self.setSetting("Spacings/ParagraphAbove", v)) self.spnThemeParaBelow.valueChanged.connect(lambda v: self.setSetting("Spacings/ParagraphBelow", v)) self.spnThemeTabWidth.valueChanged.connect(lambda v: self.setSetting("Spacings/TabWidth", v)) - + # Update UI self.updateUIFromTheme() - + # Generate preview self._loadingTheme = False self.updatePreview() - + def setSetting(self, key, val): self._themeData[key] = val self.updatePreview() - + def updateUIFromTheme(self): self.txtThemeName.setText(self._themeData["Name"]) - + # Window Background self.setButtonColor(self.btnThemWindowBackgroundColor, self._themeData["Background/Color"]) i = self.cmbThemeBackgroundImage.findData(self._themeData["Background/ImageFile"], flags=Qt.MatchContains) if i != -1: self.cmbThemeBackgroundImage.setCurrentIndex(i) self.cmbThemBackgroundType.setCurrentIndex(self._themeData["Background/Type"]) - + # Text background self.setButtonColor(self.btnThemeTextBackgroundColor, self._themeData["Foreground/Color"]) self.spnThemeTextBackgroundOpacity.setValue(self._themeData["Foreground/Opacity"]) @@ -604,7 +608,7 @@ class settingsWindow(QWidget, Ui_Settings): self.cmbThemeTextPosition.setCurrentIndex(self._themeData["Foreground/Position"]) self.spnThemeTextRadius.setValue(self._themeData["Foreground/Rounding"]) self.spnThemeTextWidth.setValue(self._themeData["Foreground/Width"]) - + # Text Options self.setButtonColor(self.btnThemeTextColor, self._themeData["Text/Color"]) f = QFont() @@ -615,9 +619,9 @@ class settingsWindow(QWidget, Ui_Settings): self.cmbThemeFontSize.setCurrentIndex(i) else: 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"]) - + # Paragraph Options self.chkThemeIndent.setCheckState(Qt.Checked if self._themeData["Spacings/IndendFirstLine"] else Qt.Unchecked) self.spnThemeLineSpacing.setEnabled(False) @@ -634,22 +638,22 @@ class settingsWindow(QWidget, Ui_Settings): self.spnThemeParaAbove.setValue(self._themeData["Spacings/ParagraphAbove"]) self.spnThemeParaBelow.setValue(self._themeData["Spacings/ParagraphBelow"]) self.spnThemeTabWidth.setValue(self._themeData["Spacings/TabWidth"]) - + def populatesFontSize(self): 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: self.cmbThemeFontSize.addItem(str(i)) - + def updateThemeFont(self, v): f = self.cmbThemeFont.currentFont() s = self.cmbThemeFontSize.itemText(self.cmbThemeFontSize.currentIndex()) if s: f.setPointSize(int(s)) - + self._themeData["Text/Font"] = f.toString() self.updatePreview() - + def updateLineSpacing(self, i): if i == 0: self._themeData["Spacings/LineSpacing"] = 100 @@ -661,16 +665,16 @@ class settingsWindow(QWidget, Ui_Settings): self._themeData["Spacings/LineSpacing"] = self.spnThemeLineSpacing.value() self.spnThemeLineSpacing.setEnabled(i == 3) self.updatePreview() - + def updateThemeBackground(self, i): img = self.cmbCorkImage.itemData(i) - + if img: self._themeData["Background/ImageFile"] = os.path.split(img)[1] else: self._themeData["Background/ImageFile"] = "" self.updatePreview() - + def getThemeColor(self, key): color = self._themeData[key] self.colorDialog = QColorDialog(QColor(color), self) @@ -679,37 +683,37 @@ class settingsWindow(QWidget, Ui_Settings): self._themeData[key] = color.name() self.updateUIFromTheme() self.updatePreview() - + def updatePreview(self): if self._loadingTheme: return - + currentScreen = qApp.desktop().screenNumber(self) screen = qApp.desktop().screenGeometry(currentScreen) - + px = createThemePreview(self._themeData, screen, self.lblPreview.size()) self.lblPreview.setPixmap(px) - + def setButtonColor(self, btn, color): btn.setStyleSheet("background:{};".format(color)) - + def saveTheme(self): settings = QSettings(self._editingTheme, QSettings.IniFormat) - + self._themeData["Name"] = self.txtThemeName.text() for key in self._themeData: settings.setValue(key, self._themeData[key]) - + settings.sync() self.populatesThemesList() self.themeStack.setCurrentIndex(0) self._editingTheme = None - + def cancelEdit(self): self.themeStack.setCurrentIndex(0) self._editingTheme = None - + def resizeEvent(self, event): QWidget.resizeEvent(self, event) if self._editingTheme: - self.updatePreview() \ No newline at end of file + self.updatePreview() diff --git a/manuskript/ui/cheatSheet.py b/manuskript/ui/cheatSheet.py index 6e73445..5890339 100644 --- a/manuskript/ui/cheatSheet.py +++ b/manuskript/ui/cheatSheet.py @@ -1,23 +1,26 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from models.outlineModel import * -from ui.cheatSheet_ui import * -from functions import * -import models.references as Ref +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import pyqtSignal, Qt, QTimer, QRect +from PyQt5.QtGui import QBrush, QCursor, QPalette, QFontMetrics +from PyQt5.QtWidgets import QWidget, QListWidgetItem, QToolTip, QStyledItemDelegate, QStyle + +from manuskript.enums import Perso +from manuskript.enums import Plot +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): - activated = pyqtSignal(str) - + def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) self.splitter.setStretchFactor(0, 5) self.splitter.setStretchFactor(1, 70) - + self.txtFilter.textChanged.connect(self.updateListFromData) self.txtFilter.returnPressed.connect(self.showInfos) self.listDelegate = listCompleterDelegate(self) @@ -26,80 +29,80 @@ class cheatSheet(QWidget, Ui_cheatSheet): self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.linkActivated.connect(self.openLink) self.view.linkHovered.connect(self.linkHovered) - + self.outlineModel = None self.persoModel = None self.plotModel = None self.worldModel = None - + self.populateTimer = QTimer(self) self.populateTimer.setSingleShot(True) self.populateTimer.setInterval(500) self.populateTimer.timeout.connect(self.populate) self.populateTimer.stop() - + self.data = {} - + self.populate() - + def setModels(self): mw = mainWindow() self.outlineModel = mw.mdlOutline self.persoModel = mw.mdlPersos self.plotModel = mw.mdlPlots self.worldModel = mw.mdlWorld - + self.outlineModel.dataChanged.connect(self.populateTimer.start) self.persoModel.dataChanged.connect(self.populateTimer.start) self.plotModel.dataChanged.connect(self.populateTimer.start) self.worldModel.dataChanged.connect(self.populateTimer.start) - + self.populate() - + def populate(self): if self.persoModel: d = [] - + for r in range(self.persoModel.rowCount()): name = self.persoModel.item(r, Perso.name.value).text() ID = self.persoModel.item(r, Perso.ID.value).text() imp = self.persoModel.item(r, Perso.importance.value).text() imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)] d.append((name, ID, imp)) - + self.data[(self.tr("Characters"), Ref.PersoLetter)] = d - + if self.outlineModel: d = [] - + def addChildren(item): for c in item.children(): d.append((c.title(), c.ID(), c.path())) addChildren(c) - + r = self.outlineModel.rootItem addChildren(r) - + self.data[(self.tr("Texts"), Ref.TextLetter)] = d - + if self.plotModel: d = [] - + for r in range(self.plotModel.rowCount()): name = self.plotModel.item(r, Plot.name.value).text() ID = self.plotModel.item(r, Plot.ID.value).text() imp = self.plotModel.item(r, Plot.importance.value).text() imp = [self.tr("Minor"), self.tr("Secondary"), self.tr("Main")][int(imp)] d.append((name, ID, imp)) - + self.data[(self.tr("Plots"), Ref.PlotLetter)] = d - + if self.worldModel: d = self.worldModel.listAll() self.data[(self.tr("World"), Ref.WorldLetter)] = d - + self.updateListFromData() - + def addCategory(self, title): item = QListWidgetItem(title) item.setBackground(QBrush(lightBlue())) @@ -109,7 +112,7 @@ class cheatSheet(QWidget, Ui_cheatSheet): f.setBold(True) item.setFont(f) self.list.addItem(item) - + def updateListFromData(self): self.list.clear() for cat in self.data: @@ -119,48 +122,48 @@ class cheatSheet(QWidget, Ui_cheatSheet): for item in filtered: i = QListWidgetItem(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.setCurrentRow(1) - + def showInfos(self): i = self.list.currentItem() ref = i.data(Qt.UserRole) if ref: self.view.setText(Ref.infos(ref)) - + def openLink(self, link): Ref.open(link) - + def linkHovered(self, link): if link: QToolTip.showText(QCursor.pos(), Ref.tooltip(link)) - + def keyPressEvent(self, event): if event.key() in [Qt.Key_Up, Qt.Key_Down]: self.list.keyPressEvent(event) else: QWidget.keyPressEvent(self, event) - - + + class listCompleterDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) - + def paint(self, painter, option, index): - extra = index.data(Qt.UserRole+1) + extra = index.data(Qt.UserRole + 1) if not extra: return QStyledItemDelegate.paint(self, painter, option, index) - + else: if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) - + title = index.data() extra = " - {}".format(extra) painter.drawText(option.rect, Qt.AlignLeft, title) - + fm = QFontMetrics(option.font) w = fm.width(title) r = QRect(option.rect) @@ -168,4 +171,4 @@ class listCompleterDelegate(QStyledItemDelegate): painter.save() painter.setPen(Qt.gray) painter.drawText(r, Qt.AlignLeft, extra) - painter.restore() \ No newline at end of file + painter.restore() diff --git a/manuskript/ui/cheatSheet_ui.py b/manuskript/ui/cheatSheet_ui.py index fcdd6dc..e514f21 100644 --- a/manuskript/ui/cheatSheet_ui.py +++ b/manuskript/ui/cheatSheet_ui.py @@ -6,7 +6,7 @@ # # 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): def setupUi(self, cheatSheet): diff --git a/manuskript/ui/collapsibleDockWidgets.py b/manuskript/ui/collapsibleDockWidgets.py index 4facddb..b795266 100644 --- a/manuskript/ui/collapsibleDockWidgets.py +++ b/manuskript/ui/collapsibleDockWidgets.py @@ -1,7 +1,8 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QToolBar, QDockWidget, QAction, QToolButton, QSizePolicy, QStylePainter, \ + QStyleOptionButton, QStyle class collapsibleDockWidgets(QToolBar): @@ -14,7 +15,7 @@ class collapsibleDockWidgets(QToolBar): Qt.RightDockWidgetArea: Qt.RightToolBarArea, Qt.TopDockWidgetArea: Qt.TopToolBarArea, Qt.BottomDockWidgetArea: Qt.BottomToolBarArea, - } + } def __init__(self, area, parent, name=""): QToolBar.__init__(self, parent) @@ -26,18 +27,18 @@ class collapsibleDockWidgets(QToolBar): self.setFloatable(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) - + # Dock widgets for d in self._dockWidgets(): b = verticalButton(self) b.setDefaultAction(d.toggleViewAction()) self.addWidget(b) - + self.addSeparator() - + # Other widgets self.otherWidgets = [] self.currentGroup = None @@ -47,41 +48,41 @@ class collapsibleDockWidgets(QToolBar): for w in mw.findChildren(QDockWidget, None): yield w - def addCustomWidget(self, text, widget, group=None): + def addCustomWidget(self, text, widget, group=None): a = QAction(text, self) a.setCheckable(True) a.setChecked(widget.isVisible()) a.toggled.connect(widget.setVisible) - #widget.installEventFilter(self) + # widget.installEventFilter(self) b = verticalButton(self) b.setDefaultAction(a) a2 = self.addWidget(b) self.otherWidgets.append((b, a2, widget, group)) - - #def eventFilter(self, widget, event): - #if event.type() in [QEvent.Show, QEvent.Hide]: - #for btn, action, w, grp in self.otherWidgets: - #if w == widget: - #btn.defaultAction().setChecked(event.type() == QEvent.Show) - #return False - + + # def eventFilter(self, widget, event): + # if event.type() in [QEvent.Show, QEvent.Hide]: + # for btn, action, w, grp in self.otherWidgets: + # if w == widget: + # btn.defaultAction().setChecked(event.type() == QEvent.Show) + # return False + def setCurrentGroup(self, group): self.currentGroup = group 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) else: action.setVisible(True) - + class verticalButton(QToolButton): def __init__(self, parent): QToolButton.__init__(self, parent) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum) - + def sizeHint(self): return QToolButton.sizeHint(self).transposed() - + def paintEvent(self, event): p = QStylePainter(self) p.rotate(90) @@ -93,4 +94,4 @@ class verticalButton(QToolButton): opt.state |= QStyle.State_On s = opt.rect.size().transposed() opt.rect.setSize(s) - p.drawControl(QStyle.CE_PushButton, opt) \ No newline at end of file + p.drawControl(QStyle.CE_PushButton, opt) diff --git a/manuskript/ui/collapsibleGroupBox.py b/manuskript/ui/collapsibleGroupBox.py index 0f71f4f..dac9cfc 100644 --- a/manuskript/ui/collapsibleGroupBox.py +++ b/manuskript/ui/collapsibleGroupBox.py @@ -1,31 +1,30 @@ #!/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): - def __init__(self, parent=None): QGroupBox.__init__(self) - + self.toggled.connect(self.setExpanded) self.tempWidget = QWidget() - + self.customStyle = False - + def setExpanded(self, val): self.setCollapsed(not val) - + def setCollapsed(self, val): if val: # Save layout self.tempWidget.setLayout(self.layout()) # Set empty layout 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) self.setLayout(l) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) @@ -35,37 +34,37 @@ class collapsibleGroupBox(QGroupBox): # Set saved layout self.setLayout(self.tempWidget.layout()) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) - + def paintEvent(self, event): - + if not self.customStyle: return QGroupBox.paintEvent(self, event) - + p = QStylePainter(self) opt = QStyleOptionGroupBox() self.initStyleOption(opt) - + style = qApp.style() groupBox = opt - - #// Draw frame + + # // Draw frame textRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxLabel) checkBoxRect = style.subControlRect(style.CC_GroupBox, opt, style.SC_GroupBoxCheckBox) - + p.save() 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.moveTop(textRect.top()) - + p.setBrush(QBrush(QColor(Qt.blue).lighter(190))) p.setPen(Qt.NoPen) p.drawRoundedRect(titleRect, 10, 10) p.restore() - + if groupBox.subControls & QStyle.SC_GroupBoxFrame: frame = QStyleOptionFrame() - #frame.operator=(groupBox) + # frame.operator=(groupBox) frame.state = groupBox.state frame.features = groupBox.features 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) else: finalRect = textRect - + region -= QRegion(finalRect) - + p.setClipRegion(region) style.drawPrimitive(style.PE_FrameGroupBox, frame, p) p.restore() - ##// Draw title + # // Draw title if groupBox.subControls & QStyle.SC_GroupBoxLabel and groupBox.text: - #textColor = QColor(groupBox.textColor) - #if textColor.isValid(): - #p.setPen(textColor) - #alignment = int(groupBox.textAlignment) - #if not style.styleHint(QStyle.SH_UnderlineShortcut, opt): - #alignment |= Qt.TextHideMnemonic + # textColor = QColor(groupBox.textColor) + # if textColor.isValid(): + # p.setPen(textColor) + # alignment = int(groupBox.textAlignment) + # if not style.styleHint(QStyle.SH_UnderlineShortcut, opt): + # 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() topt = QTextOption(Qt.AlignHCenter | Qt.AlignVCenter) f = QFont() @@ -112,15 +111,15 @@ class collapsibleGroupBox(QGroupBox): if groupBox.state & style.State_HasFocus: fropt = QStyleOptionFocusRect() - #fropt.operator=(groupBox) + # fropt.operator=(groupBox) fropt.state = groupBox.state fropt.rect = textRect style.drawPrimitive(style.PE_FrameFocusRect, fropt, p) - #// Draw checkbox - #if groupBox.subControls & style.SC_GroupBoxCheckBox: - #box = QStyleOptionButton() - ##box.operator=(groupBox) - #box.state = groupBox.state - #box.rect = checkBoxRect - #style.drawPrimitive(style.PE_IndicatorCheckBox, box, p) \ No newline at end of file + # // Draw checkbox + # if groupBox.subControls & style.SC_GroupBoxCheckBox: + # box = QStyleOptionButton() + # box.operator=(groupBox) + # box.state = groupBox.state + # box.rect = checkBoxRect + # style.drawPrimitive(style.PE_IndicatorCheckBox, box, p) diff --git a/manuskript/ui/collapsibleGroupBox2.py b/manuskript/ui/collapsibleGroupBox2.py index 216be43..d62757b 100644 --- a/manuskript/ui/collapsibleGroupBox2.py +++ b/manuskript/ui/collapsibleGroupBox2.py @@ -1,10 +1,10 @@ #!/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): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.frame = QFrame(self) @@ -14,12 +14,12 @@ class collapsibleGroupBox2(QWidget): self.switched = False self.vPolicy = None self.button.setStyleSheet("background: lightBlue;") - + def resizeEvent(self, event): if not self.switched: self.switchLayout() return QWidget.resizeEvent(self, event) - + def switchLayout(self): self.frame.setLayout(self.layout()) self.wLayout = QVBoxLayout(self) @@ -29,31 +29,31 @@ class collapsibleGroupBox2(QWidget): self.button.toggled.connect(self.setExpanded) self.frame.layout().setContentsMargins(5, 0, 5, 0) self.switched = True - + self.vPolicy = self.sizePolicy().verticalPolicy() self.parent().layout().setAlignment(Qt.AlignTop) - + self.setExpanded(self.button.isChecked()) - + def setFlat(self, val): if val: self.frame.setFrameShape(QFrame.NoFrame) - + def setCheckable(self, val): pass - + def setTitle(self, title): self.button.setText(title) - + def setExpanded(self, val): self.frame.setVisible(val) if val: self.setSizePolicy(QSizePolicy.Preferred, self.vPolicy) else: self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) - + def saveState(self): return self.button.isChecked() - + def restoreState(self, val): - self.button.setChecked(val) \ No newline at end of file + self.button.setChecked(val) diff --git a/manuskript/ui/compileDialog.py b/manuskript/ui/compileDialog.py index 87e19c7..baa8a73 100644 --- a/manuskript/ui/compileDialog.py +++ b/manuskript/ui/compileDialog.py @@ -1,107 +1,102 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from models.outlineModel import * -from ui.compileDialog_ui import * -from functions import * -import os -import exporter +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog, qApp, QFileDialog + +from manuskript import exporter +from manuskript.ui.compileDialog_ui import Ui_compileDialog + class compileDialog(QDialog, Ui_compileDialog): - def __init__(self, parent=None): QDialog.__init__(self, parent) self.setupUi(self) - + self.btnPath.clicked.connect(self.getPath) self.btnFilename.clicked.connect(self.getFilename) - + self.btnCompile.clicked.connect(self.doCompile) self.cmbTargets.activated.connect(self.updateUI) - + 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.populatesTarget() self.updateUI() - -############################################################################### -# UI -############################################################################### - + + ############################################################################### + # UI + ############################################################################### + def populatesTarget(self): for code in exporter.formats: self.cmbTargets.addItem(exporter.formats[code][0], code) - + def updateUI(self): target = self.cmbTargets.currentData() - + if not exporter.formats[target][1]: self.btnCompile.setEnabled(False) requires = [] else: self.btnCompile.setEnabled(True) requires = exporter.formats[target][1].requires - + self.wPath.setVisible("path" in requires) self.wFilename.setVisible("filename" in requires) - + def startWorking(self): # Setting override cursor qApp.setOverrideCursor(Qt.WaitCursor) - + # Button self.btnCompile.setEnabled(False) self.txtBtn = self.btnCompile.text() self.btnCompile.setText(self.tr("Working...")) - + def stopWorking(self): # Removing override cursor qApp.restoreOverrideCursor() - + # Button self.btnCompile.setEnabled(True) self.btnCompile.setText(self.txtBtn) -############################################################################### -# USER INPUTS -############################################################################### + ############################################################################### + # USER INPUTS + ############################################################################### def getPath(self): path = self.txtPath.text() path = QFileDialog.getExistingDirectory(self, self.tr("Chose export folder"), path) if path: self.txtPath.setText(path) - + def getFilename(self): fn = self.txtFilename.text() target = self.cmbTargets.currentData() fltr = exporter.formats[target][2] fn = QFileDialog.getSaveFileName(self, self.tr("Chose export target"), fn, fltr) - + if fn[0]: self.txtFilename.setText(fn[0]) - -############################################################################### -# COMPILE -############################################################################### - + + ############################################################################### + # COMPILE + ############################################################################### + def doCompile(self): target = self.cmbTargets.currentData() - + self.startWorking() - + if target == "arbo": compiler = exporter.formats[target][1]() compiler.doCompile(self.txtPath.text()) - + elif target in ["html", "odt"]: compiler = exporter.formats[target][1]() compiler.doCompile(self.txtFilename.text()) - + self.stopWorking() - \ No newline at end of file diff --git a/manuskript/ui/compileDialog_ui.py b/manuskript/ui/compileDialog_ui.py index e7c6d28..6000e97 100644 --- a/manuskript/ui/compileDialog_ui.py +++ b/manuskript/ui/compileDialog_ui.py @@ -6,7 +6,7 @@ # # 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): def setupUi(self, compileDialog): diff --git a/manuskript/ui/editors/basicHighlighter.py b/manuskript/ui/editors/basicHighlighter.py index 0cdbb4a..b505506 100644 --- a/manuskript/ui/editors/basicHighlighter.py +++ b/manuskript/ui/editors/basicHighlighter.py @@ -1,13 +1,15 @@ #!/usr/bin/python # -*- coding: utf8 -*- -from qt import * 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): - def __init__(self, editor): QSyntaxHighlighter.__init__(self, editor.document()) @@ -19,21 +21,20 @@ class basicHighlighter(QSyntaxHighlighter): def setDefaultBlockFormat(self, bf): self._defaultBlockFormat = bf self.rehighlight() - + def setDefaultCharFormat(self, cf): self._defaultCharFormat = cf self.rehighlight() - + def setMisspelledColor(self, color): self._misspelledColor = color - - + def highlightBlock(self, text): """Apply syntax highlighting to the given block of text. """ self.highlightBlockBefore(text) self.highlightBlockAfter(text) - + def highlightBlockBefore(self, text): """Highlighting to do before anything else. @@ -43,16 +44,16 @@ class basicHighlighter(QSyntaxHighlighter): bf = QTextBlockFormat(self._defaultBlockFormat) bf.setAlignment(QTextCursor(self.currentBlock()).blockFormat().alignment()) QTextCursor(self.currentBlock()).setBlockFormat(bf) - - #self.setFormat(0, len(text), self._defaultCharFormat) - + + # self.setFormat(0, len(text), self._defaultCharFormat) + def highlightBlockAfter(self, text): """Highlighting to do after everything else. When subclassing basicHighlighter, you must call highlightBlockAfter after your custom highlighting. """ - + # References for txt in re.finditer(Ref.RegEx, text): fmt = self.format(txt.start()) @@ -66,11 +67,11 @@ class basicHighlighter(QSyntaxHighlighter): fmt.setBackground(QBrush(QColor(Qt.red).lighter(170))) elif txt.group(1) == Ref.WorldLetter: fmt.setBackground(QBrush(QColor(Qt.green).lighter(170))) - + self.setFormat(txt.start(), - txt.end() - txt.start(), - fmt) - + txt.end() - txt.start(), + fmt) + # Spell checking # Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ WORDS = '(?iu)[\w\']+' @@ -81,7 +82,4 @@ class basicHighlighter(QSyntaxHighlighter): format.setUnderlineColor(self._misspelledColor) format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline) self.setFormat(word_object.start(), - word_object.end() - word_object.start(), format) - - - \ No newline at end of file + word_object.end() - word_object.start(), format) diff --git a/manuskript/ui/editors/blockUserData.py b/manuskript/ui/editors/blockUserData.py index c25b1c9..7f39c2c 100644 --- a/manuskript/ui/editors/blockUserData.py +++ b/manuskript/ui/editors/blockUserData.py @@ -1,14 +1,12 @@ #!/usr/bin/python # -*- coding: utf8 -*- - -from qt import * +from PyQt5.QtGui import QTextBlockUserData -class blockUserData (QTextBlockUserData): - +class blockUserData(QTextBlockUserData): @staticmethod def getUserData(block): - "Returns userData if it exists, or a blank one." + """Returns userData if it exists, or a blank one.""" data = block.userData() if data is None: data = blockUserData() @@ -16,7 +14,7 @@ class blockUserData (QTextBlockUserData): @staticmethod def getUserState(block): - "Returns the block state." + """Returns the block state.""" state = block.userState() while state >= 100: state -= 100 # +100 means in a list diff --git a/manuskript/ui/editors/completer.py b/manuskript/ui/editors/completer.py index 4bfa06e..f215255 100644 --- a/manuskript/ui/editors/completer.py +++ b/manuskript/ui/editors/completer.py @@ -1,17 +1,18 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from models.outlineModel import * -from ui.editors.completer_ui import * -from functions import * -import models.references as Ref +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import pyqtSignal, Qt, QRect +from PyQt5.QtGui import QBrush, QFontMetrics, QPalette +from PyQt5.QtWidgets import QWidget, QListWidgetItem, QStyledItemDelegate, QStyle + +from manuskript.functions import lightBlue +from manuskript.functions import mainWindow +from manuskript.ui.editors.completer_ui import Ui_completer +from manuskript.models import references as Ref + class completer(QWidget, Ui_completer): - activated = pyqtSignal(str) - + def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) @@ -23,20 +24,20 @@ class completer(QWidget, Ui_completer): self.list.itemActivated.connect(self.submit) self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.hide() - + def popup(self, completion=""): self.updateListFromData() self.text.setText(completion) self.text.setFocus(Qt.PopupFocusReason) self.show() - + def addCategory(self, title): item = QListWidgetItem(title) item.setBackground(QBrush(lightBlue())) item.setForeground(QBrush(Qt.darkBlue)) item.setFlags(Qt.ItemIsEnabled) self.list.addItem(item) - + def updateListFromData(self): data = mainWindow().cheatSheet.data self.list.clear() @@ -47,41 +48,41 @@ class completer(QWidget, Ui_completer): for item in filtered: i = QListWidgetItem(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.setCurrentRow(1) self.text.setFocus(Qt.PopupFocusReason) - + def submit(self): i = self.list.currentItem() self.activated.emit(i.data(Qt.UserRole)) self.hide() - + def keyPressEvent(self, event): if event.key() in [Qt.Key_Up, Qt.Key_Down]: self.list.keyPressEvent(event) else: QWidget.keyPressEvent(self, event) - - + + class listCompleterDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) - + def paint(self, painter, option, index): - extra = index.data(Qt.UserRole+1) + extra = index.data(Qt.UserRole + 1) if not extra: return QStyledItemDelegate.paint(self, painter, option, index) - + else: if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) - + title = index.data() extra = " - {}".format(extra) painter.drawText(option.rect, Qt.AlignLeft, title) - + fm = QFontMetrics(option.font) w = fm.width(title) r = QRect(option.rect) @@ -89,4 +90,4 @@ class listCompleterDelegate(QStyledItemDelegate): painter.save() painter.setPen(Qt.gray) painter.drawText(r, Qt.AlignLeft, extra) - painter.restore() \ No newline at end of file + painter.restore() diff --git a/manuskript/ui/editors/completer_ui.py b/manuskript/ui/editors/completer_ui.py index df0acca..093ec83 100644 --- a/manuskript/ui/editors/completer_ui.py +++ b/manuskript/ui/editors/completer_ui.py @@ -6,7 +6,7 @@ # # 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): def setupUi(self, completer): diff --git a/manuskript/ui/editors/editorWidget.py b/manuskript/ui/editors/editorWidget.py index eff606e..0451377 100644 --- a/manuskript/ui/editors/editorWidget.py +++ b/manuskript/ui/editors/editorWidget.py @@ -1,20 +1,19 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from ui.editors.editorWidget_ui import * -from ui.editors.fullScreenEditor import * -from ui.editors.textFormat import * -from ui.views.textEditView import * -from functions import * -import settings +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import pyqtSignal, QModelIndex +from PyQt5.QtGui import QPalette +from PyQt5.QtWidgets import QWidget, QFrame, QSpacerItem, QSizePolicy, QVBoxLayout + +from manuskript import settings +from manuskript.functions import AUC, mainWindow +from manuskript.ui.editors.editorWidget_ui import Ui_editorWidget_ui +from manuskript.ui.views.textEditView import textEditView + class editorWidget(QWidget, Ui_editorWidget_ui): - toggledSpellcheck = pyqtSignal(bool) dictChanged = pyqtSignal(str) - + def __init__(self, parent): QWidget.__init__(self, parent) self.setupUi(self) @@ -29,11 +28,11 @@ class editorWidget(QWidget, Ui_editorWidget_ui): self.spellcheck = True self.folderView = "cork" self.mw = mainWindow() - - #def setModel(self, model): - #self._model = model - #self.setView() - + + # def setModel(self, model): + # self._model = model + # self.setView() + def setFolderView(self, v): oldV = self.folderView if v == "cork": @@ -42,66 +41,67 @@ class editorWidget(QWidget, Ui_editorWidget_ui): self.folderView = "outline" else: self.folderView = "text" - + # Saving value settings.folderView = self.folderView - + if oldV != self.folderView and self.currentIndex: self.setCurrentModelIndex(self.currentIndex) - + def setCorkSizeFactor(self, v): self.corkView.itemDelegate().setCorkSizeFactor(v) self.redrawCorkItems() - + def redrawCorkItems(self): r = self.corkView.rootIndex() - + if r.isValid(): count = r.internalPointer().childCount() else: count = self.mw.mdlOutline.rootItem.childCount() - + for c in range(count): self.corkView.itemDelegate().sizeHintChanged.emit(r.child(c, 0)) - + def setView(self): - #index = mainWindow().treeRedacOutline.currentIndex() - - ## Couting the number of other selected items - #sel = [] - #for i in mainWindow().treeRedacOutline.selectionModel().selection().indexes(): - #if i.column() != 0: continue - #if i not in sel: sel.append(i) - - #if len(sel) != 0: - #item = index.internalPointer() - #else: - #index = QModelIndex() - #item = self.mw.mdlOutline.rootItem - - #self.currentIndex = index - + # index = mainWindow().treeRedacOutline.currentIndex() + + # Couting the number of other selected items + # sel = [] + # for i in mainWindow().treeRedacOutline.selectionModel().selection().indexes(): + # if i.column() != 0: continue + # if i not in sel: sel.append(i) + + # if len(sel) != 0: + # item = index.internalPointer() + # else: + # index = QModelIndex() + # item = self.mw.mdlOutline.rootItem + + # self.currentIndex = index + if self.currentIndex.isValid(): item = self.currentIndex.internalPointer() else: item = self.mw.mdlOutline.rootItem - + def addTitle(itm): - edt = textEditView(self, html="{t}".format(l=min(itm.level()+1, 5), t=itm.title()), autoResize=True) + edt = textEditView(self, html="{t}".format(l=min(itm.level() + 1, 5), t=itm.title()), + autoResize=True) edt.setFrameShape(QFrame.NoFrame) self.txtEdits.append(edt) l.addWidget(edt) - + def addLine(): line = QFrame(self.text) line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) l.addWidget(line) - + def addText(itm): - edt = textEditView(self, - index=itm.index(), - spellcheck=self.spellcheck, + edt = textEditView(self, + index=itm.index(), + spellcheck=self.spellcheck, dict=settings.dict, highlighting=True, autoResize=True) @@ -110,67 +110,67 @@ class editorWidget(QWidget, Ui_editorWidget_ui): edt.setStatusTip("{} ({})".format(itm.path(), itm.type())) self.toggledSpellcheck.connect(edt.toggleSpellcheck, AUC) self.dictChanged.connect(edt.setDict, AUC) - #edt.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + # edt.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.txtEdits.append(edt) l.addWidget(edt) - + def addChildren(itm): for c in range(itm.childCount()): child = itm.child(c) - + if child.isFolder(): addTitle(child) addChildren(child) - + else: addText(child) addLine() - + def addSpacer(): l.addItem(QSpacerItem(10, 1000, QSizePolicy.Minimum, QSizePolicy.Expanding)) - - # Display multiple selected items - #if len(sel) > 1 and False: # Buggy and not very useful, skip - #self.stack.setCurrentIndex(1) - #w = QWidget() - #l = QVBoxLayout(w) - #self.txtEdits = [] - #for idx in sel: - #sItem = idx.internalPointer() - #addTitle(sItem) - #if sItem.isFolder(): - #addChildren(sItem) - #else: - #addText(sItem) - #addLine() - #addSpacer() - #self.scroll.setWidget(w) - + + # Display multiple selected items + # if len(sel) > 1 and False: # Buggy and not very useful, skip + # self.stack.setCurrentIndex(1) + # w = QWidget() + # l = QVBoxLayout(w) + # self.txtEdits = [] + # for idx in sel: + # sItem = idx.internalPointer() + # addTitle(sItem) + # if sItem.isFolder(): + # addChildren(sItem) + # else: + # addText(sItem) + # addLine() + # addSpacer() + # self.scroll.setWidget(w) + if item and item.isFolder() and self.folderView == "text": self.stack.setCurrentIndex(1) w = QWidget() l = QVBoxLayout(w) w.setStyleSheet("background: {};".format(settings.textEditor["background"])) - #self.scroll.setWidgetResizable(False) - + # self.scroll.setWidgetResizable(False) + self.txtEdits = [] - + if item != self.mw.mdlOutline.rootItem: addTitle(item) - + addChildren(item) addSpacer() self.scroll.setWidget(w) - + elif item and item.isFolder() and self.folderView == "cork": self.stack.setCurrentIndex(2) self.corkView.setModel(self.mw.mdlOutline) self.corkView.setRootIndex(self.currentIndex) self.corkView.selectionModel().selectionChanged.connect( - lambda: mainWindow().redacMetadata.selectionChanged(self.corkView), AUC) + lambda: mainWindow().redacMetadata.selectionChanged(self.corkView), AUC) 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": self.stack.setCurrentIndex(3) self.outlineView.setModelPersos(mainWindow().mdlPersos) @@ -179,14 +179,14 @@ class editorWidget(QWidget, Ui_editorWidget_ui): self.outlineView.setModel(self.mw.mdlOutline) self.outlineView.setRootIndex(self.currentIndex) self.outlineView.selectionModel().selectionChanged.connect( - lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC) + lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC) self.outlineView.clicked.connect( - lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC) - + lambda: mainWindow().redacMetadata.selectionChanged(self.outlineView), AUC) + else: self.txtRedacText.setCurrentModelIndex(self.currentIndex) - self.stack.setCurrentIndex(0) # Single text item - + self.stack.setCurrentIndex(0) # Single text item + try: self.mw.mdlOutline.dataChanged.connect(self.modelDataChanged, 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) except TypeError: pass - + self.updateStatusBar() - - + def setCurrentModelIndex(self, index=None): if index.isValid(): self.currentIndex = index self.currentID = self.mw.mdlOutline.ID(index) - #self._model = index.model() + # self._model = index.model() else: self.currentIndex = QModelIndex() - + self.setView() - + def updateIndexFromID(self): idx = self.mw.mdlOutline.getIndexByID(self.currentID) if idx != self.currentIndex: self.currentIndex = idx self.setView() - + def modelDataChanged(self, topLeft, bottomRight): - #if self.currentID: - #self.updateIndexFromID() + # if self.currentID: + # self.updateIndexFromID() if not self.currentIndex: return if topLeft.row() <= self.currentIndex.row() <= bottomRight.row(): self.updateStatusBar() - + def rowsAboutToBeRemoved(self, parent, first, last): if self.currentIndex: if self.currentIndex.parent() == parent and \ - first <= self.currentIndex.row() <= last: + first <= self.currentIndex.row() <= last: # Item deleted, close tab self.mw.mainEditor.tab.removeTab(self.mw.mainEditor.tab.indexOf(self)) - + def updateStatusBar(self): # Update progress - #if self.currentIndex and self.currentIndex.isValid(): - #if self._model: + # if self.currentIndex and self.currentIndex.isValid(): + # if self._model: mw = mainWindow() - if not mw: return - + if not mw: + return + mw.mainEditor.updateStats() - + def toggleSpellcheck(self, v): self.spellcheck = v self.toggledSpellcheck.emit(v) - + def setDict(self, dct): self.currentDict = dct - self.dictChanged.emit(dct) \ No newline at end of file + self.dictChanged.emit(dct) diff --git a/manuskript/ui/editors/editorWidget_ui.py b/manuskript/ui/editors/editorWidget_ui.py index 382ab1f..a210a79 100644 --- a/manuskript/ui/editors/editorWidget_ui.py +++ b/manuskript/ui/editors/editorWidget_ui.py @@ -37,7 +37,7 @@ class Ui_editorWidget_ui(object): self.scroll.setWidgetResizable(True) self.scroll.setObjectName("scroll") 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.scroll.setWidget(self.scrollAreaWidgetContents) self.verticalLayout.addWidget(self.scroll) @@ -70,6 +70,6 @@ class Ui_editorWidget_ui(object): _translate = QtCore.QCoreApplication.translate editorWidget_ui.setWindowTitle(_translate("editorWidget_ui", "Form")) -from ui.views.corkView import corkView -from ui.views.outlineView import outlineView -from ui.views.textEditView import textEditView +from manuskript.ui.views.corkView import corkView +from manuskript.ui.views.outlineView import outlineView +from manuskript.ui.views.textEditView import textEditView diff --git a/manuskript/ui/editors/editorWidget_ui.ui b/manuskript/ui/editors/editorWidget_ui.ui index 142df9b..b59b2c4 100644 --- a/manuskript/ui/editors/editorWidget_ui.ui +++ b/manuskript/ui/editors/editorWidget_ui.ui @@ -14,7 +14,16 @@ Form - + + 0 + + + 0 + + + 0 + + 0 @@ -24,7 +33,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -37,7 +55,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -53,8 +80,8 @@ 0 0 - 396 - 296 + 96 + 26 @@ -64,7 +91,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -74,7 +110,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -90,17 +135,17 @@ textEditView QTextEdit -
    ui.views.textEditView.h
    +
    manuskript.ui.views.textEditView.h
    outlineView QTreeView -
    ui.views.outlineView.h
    +
    manuskript.ui.views.outlineView.h
    corkView QListView -
    ui.views.corkView.h
    +
    manuskript.ui.views.corkView.h
    diff --git a/manuskript/ui/editors/fullScreenEditor.py b/manuskript/ui/editors/fullScreenEditor.py index ac77d58..a7283d3 100644 --- a/manuskript/ui/editors/fullScreenEditor.py +++ b/manuskript/ui/editors/fullScreenEditor.py @@ -1,24 +1,30 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -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 +# --!-- coding: utf8 --!-- +import os -from functions import * -import settings +from PyQt5.QtCore import Qt, QSize, QPoint, QRect, QEvent, QTimer +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 +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: import enchant except ImportError: enchant = None + class fullScreenEditor(QWidget): - def __init__(self, index, parent=None): QWidget.__init__(self, parent) self._background = None @@ -27,9 +33,9 @@ class fullScreenEditor(QWidget): self._themeDatas = loadThemeDatas(self._theme) self.setMouseTracking(True) self._geometries = {} - + # Text editor - self.editor = textEditView(self, + self.editor = textEditView(self, index=index, spellcheck=settings.spellcheck, highlighting=True, @@ -42,11 +48,11 @@ class fullScreenEditor(QWidget): self.editor.setVerticalScrollBar(myScrollBar()) self.scrollBar = self.editor.verticalScrollBar() self.scrollBar.setParent(self) - + # Top Panel self.topPanel = myPanel(parent=self) - #self.topPanel.layout().addStretch(1) - + # self.topPanel.layout().addStretch(1) + # Spell checking if enchant: self.btnSpellCheck = QPushButton(self) @@ -56,30 +62,30 @@ class fullScreenEditor(QWidget): self.btnSpellCheck.setChecked(self.editor.spellcheck) self.btnSpellCheck.toggled.connect(self.editor.toggleSpellcheck) self.topPanel.layout().addWidget(self.btnSpellCheck) - + self.topPanel.layout().addStretch(1) - + # Formatting self.textFormat = textFormat(self) self.topPanel.layout().addWidget(self.textFormat) self.topPanel.layout().addStretch(1) - + self.btnClose = QPushButton(self) self.btnClose.setIcon(qApp.style().standardIcon(QStyle.SP_DialogCloseButton)) self.btnClose.clicked.connect(self.close) self.btnClose.setFlat(True) self.topPanel.layout().addWidget(self.btnClose) - + # Left Panel self._locked = False self.leftPanel = myPanel(vertical=True, parent=self) self.locker = locker(self) self.locker.lockChanged.connect(self.setLocked) self.leftPanel.layout().addWidget(self.locker) - + # Bottom Panel self.bottomPanel = myPanel(parent=self) - + self.bottomPanel.layout().addSpacing(24) self.lstThemes = QComboBox(self) 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(self.lstThemes) self.bottomPanel.layout().addStretch(1) - + self.lblProgress = QLabel(self) self.lblProgress.setMaximumSize(QSize(200, 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.lblProgress) self.updateStatusBar() - + self.bottomPanel.layout().addSpacing(24) - + # Connection self._index.model().dataChanged.connect(self.dataChanged) - - #self.updateTheme() + + # self.updateTheme() self.showFullScreen() - #self.showMaximized() - #self.show() - + # self.showMaximized() + # self.show() + def setLocked(self, val): self._locked = val self.btnClose.setVisible(not val) - + def setTheme(self, themeName): settings.fullScreenTheme = themeName self._theme = findThemePath(themeName) self._themeDatas = loadThemeDatas(self._theme) self.updateTheme() - + def updateTheme(self): # Reinit stored geometries for hiding widgets self._geometries = {} rect = self.geometry() self._background = generateTheme(self._themeDatas, rect) - + setThemeEditorDatas(self.editor, self._themeDatas, self._background, rect) - + # Colors if self._themeDatas["Foreground/Color"] == self._themeDatas["Background/Color"] or \ - self._themeDatas["Foreground/Opacity"] < 5: - self._bgcolor = QColor(self._themeDatas["Text/Color"]) - self._fgcolor = QColor(self._themeDatas["Background/Color"]) + self._themeDatas["Foreground/Opacity"] < 5: + self._bgcolor = QColor(self._themeDatas["Text/Color"]) + self._fgcolor = QColor(self._themeDatas["Background/Color"]) else: self._bgcolor = QColor(self._themeDatas["Foreground/Color"]) self._bgcolor.setAlpha(self._themeDatas["Foreground/Opacity"] * 255 / 100) self._fgcolor = QColor(self._themeDatas["Text/Color"]) if self._themeDatas["Text/Color"] == self._themeDatas["Foreground/Color"]: self._fgcolor = QColor(self._themeDatas["Background/Color"]) - + # ScrollBar r = self.editor.geometry() w = qApp.style().pixelMetric(QStyle.PM_ScrollBarExtent) r.setWidth(w) r.moveRight(rect.right() - rect.left()) self.scrollBar.setGeometry(r) - #self.scrollBar.setVisible(False) + # self.scrollBar.setVisible(False) self.hideWidget(self.scrollBar) p = self.scrollBar.palette() b = QBrush(self._background.copy(self.scrollBar.geometry())) p.setBrush(QPalette.Base, b) self.scrollBar.setPalette(p) - + self.scrollBar.setColor(self._bgcolor) - + # Left Panel r = self.locker.geometry() r.moveTopLeft(QPoint( - 0, - self.geometry().height() / 2 - r.height() / 2 - )) + 0, + self.geometry().height() / 2 - r.height() / 2 + )) self.leftPanel.setGeometry(r) self.hideWidget(self.leftPanel) self.leftPanel.setColor(self._bgcolor) - + # Top / Bottom Panels r = QRect(0, 0, 0, 24) 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.setVisible(False) + # self.topPanel.setVisible(False) self.hideWidget(self.topPanel) r.moveBottom(rect.bottom() - rect.top()) self.bottomPanel.setGeometry(r) - #self.bottomPanel.setVisible(False) + # self.bottomPanel.setVisible(False) self.hideWidget(self.bottomPanel) self.topPanel.setColor(self._bgcolor) self.bottomPanel.setColor(self._bgcolor) - + # Lst theme - #p = self.lstThemes.palette() + # p = self.lstThemes.palette() p = self.palette() p.setBrush(QPalette.Button, self._bgcolor) p.setBrush(QPalette.ButtonText, self._fgcolor) p.setBrush(QPalette.WindowText, self._fgcolor) - + for panel in (self.bottomPanel, self.topPanel): for i in range(panel.layout().count()): item = panel.layout().itemAt(i) - if item.widget(): + if item.widget(): item.widget().setPalette(p) - #self.lstThemes.setPalette(p) - #self.lblWC.setPalette(p) - + # self.lstThemes.setPalette(p) + # self.lblWC.setPalette(p) + self.update() - + def paintEvent(self, event): if self._background: painter = QPainter(self) painter.setClipRegion(event.region()) painter.drawPixmap(event.rect(), self._background, event.rect()) painter.end() - + def resizeEvent(self, event): self.updateTheme() - + def keyPressEvent(self, event): if event.key() in [Qt.Key_Escape, Qt.Key_F11] and \ - not self._locked: + not self._locked: self.close() else: QWidget.keyPressEvent(self, event) - + def mouseMoveEvent(self, event): r = self.geometry() - - for w in [self.scrollBar, self.topPanel, + + for w in [self.scrollBar, self.topPanel, 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()): self.showWidget(w) else: self.hideWidget(w) - + def hideWidget(self, widget): if widget not in self._geometries: self._geometries[widget] = widget.geometry() widget.move(self.geometry().bottomRight()) - + def showWidget(self, widget): if widget in self._geometries: widget.move(self._geometries[widget].topLeft()) - + def eventFilter(self, obj, event): 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]: - #w.setVisible(False) + # w.setVisible(False) self.hideWidget(w) return QWidget.eventFilter(self, obj, event) - + def dataChanged(self, topLeft, bottomRight): if not self._index: return if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateStatusBar() - + def updateStatusBar(self): if self._index: item = self._index.internalPointer() - + wc = item.data(Outline.wordCount.value) goal = item.data(Outline.goal.value) pg = item.data(Outline.goalPercentage.value) - + if goal: rect = self.lblProgress.geometry() rect = QRect(QPoint(0, 0), rect.size()) @@ -272,45 +278,47 @@ class fullScreenEditor(QWidget): else: self.lblProgress.hide() self.lblWC.setText(self.tr("{} words").format(wc)) - + self.locker.setWordCount(wc) if not self.locker.isLocked(): if goal - wc > 0: self.locker.spnWordTarget.setValue(goal - wc) - + + class myScrollBar(QScrollBar): def __init__(self, color=Qt.white, parent=None): QScrollBar.__init__(self, parent) self._color = color - #self.setAttribute(Qt.WA_TranslucentBackground) + # self.setAttribute(Qt.WA_TranslucentBackground) self.timer = QTimer() self.timer.setInterval(500) self.timer.setSingleShot(True) self.timer.timeout.connect(lambda: self.parent().hideWidget(self)) self.valueChanged.connect(lambda v: self.timer.start()) self.valueChanged.connect(lambda: self.parent().showWidget(self)) - + def setColor(self, color): self._color = color - + def paintEvent(self, event): opt = QStyleOptionSlider() self.initStyleOption(opt) style = qApp.style() painter = QPainter(self) - + # Background (Necessary with Qt 5.2 it seems, not with 5.4) - #painter.save() - #painter.setPen(Qt.NoPen) - #painter.setBrush(self.palette().brush(QPalette.Base)) - #painter.drawRect(event.rect()) - #painter.restore() - - #slider + # painter.save() + # painter.setPen(Qt.NoPen) + # painter.setBrush(self.palette().brush(QPalette.Base)) + # painter.drawRect(event.rect()) + # painter.restore() + + # slider r = style.subControlRect(style.CC_ScrollBar, opt, style.SC_ScrollBarSlider) painter.fillRect(r, self._color) painter.end() - + + class myPanel(QWidget): def __init__(self, color=Qt.white, vertical=False, parent=None): QWidget.__init__(self, parent) @@ -322,11 +330,11 @@ class myPanel(QWidget): else: self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) - + def setColor(self, color): self._color = color - + def paintEvent(self, event): r = event.rect() painter = QPainter(self) - painter.fillRect(r, self._color) \ No newline at end of file + painter.fillRect(r, self._color) diff --git a/manuskript/ui/editors/locker.py b/manuskript/ui/editors/locker.py index af48b87..d2fc007 100644 --- a/manuskript/ui/editors/locker.py +++ b/manuskript/ui/editors/locker.py @@ -1,19 +1,16 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from ui.editors.locker_ui import Ui_locker -from functions import * -import models.references as Ref +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import pyqtSignal, QTimer +from PyQt5.QtWidgets import QWidget, qApp + +from manuskript.ui.editors.locker_ui import Ui_locker + class locker(QWidget, Ui_locker): - locked = pyqtSignal() unlocked = pyqtSignal() lockChanged = pyqtSignal(bool) - - + def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) @@ -21,7 +18,7 @@ class locker(QWidget, Ui_locker): self._words = None self._target = None self._blackout = [] - + self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.timeout.connect(self.unlock) @@ -34,9 +31,9 @@ class locker(QWidget, Ui_locker): self.rbtnTimeTarget.toggled.connect(self.spnTimeTarget.setVisible) self.rbtnWordTarget.setChecked(True) self.spnTimeTarget.setVisible(False) - + self.btnLock.clicked.connect(self.lock) - + def lock(self): # Block others screens desktop = qApp.desktop() @@ -49,24 +46,24 @@ class locker(QWidget, Ui_locker): w.move(desktop.screenGeometry(d).topLeft()) w.showFullScreen() self._blackout.append(w) - + if self.rbtnWordTarget.isChecked(): self._target = self._words + self.spnWordTarget.value() - + elif self.rbtnTimeTarget.isChecked(): self.timer.setInterval(self.spnTimeTarget.value() * 1000 * 60) self.timer.start() self.timerSec.start() self.updateBtnText() - + self.setEnabled(False) self.locked.emit() self.lockChanged.emit(True) - + def unlock(self): # Remove black screens self._blackout.clear() - + self.setEnabled(True) self.btnLock.setText(self._btnText) self.timer.stop() @@ -74,21 +71,21 @@ class locker(QWidget, Ui_locker): self._target = None self.unlocked.emit() self.lockChanged.emit(False) - + def isLocked(self): return not self.isEnabled() - + def setWordCount(self, wc): self._words = wc if self.isLocked(): self.updateBtnText() if self._words >= self._target: self.unlock() - + def updateBtnText(self): if not self._btnText: self._btnText = self.btnLock.text() - + # Time locked if self.timer.remainingTime() != -1: t = self.timer.remainingTime() @@ -103,12 +100,11 @@ class locker(QWidget, Ui_locker): text = self.tr("{}:{}").format(str(mn), str(sec)) else: text = self.tr("{} s.").format(str(t)) - + self.btnLock.setText(self.tr("{} remaining").format( - text)) - + text)) + # Word locked - elif self._target != None: + elif self._target is not None: self.btnLock.setText(self.tr("{} words remaining").format( - self._target - self._words)) - \ No newline at end of file + self._target - self._words)) diff --git a/manuskript/ui/editors/mainEditor.py b/manuskript/ui/editors/mainEditor.py index c9e204c..88e3c8c 100644 --- a/manuskript/ui/editors/mainEditor.py +++ b/manuskript/ui/editors/mainEditor.py @@ -1,49 +1,56 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from ui.editors.mainEditor_ui import * -from ui.editors.editorWidget import * -from functions import * +# --!-- coding: utf8 --!-- 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, '') class mainEditor(QWidget, Ui_mainEditor): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) self._updating = False - + self.mw = mainWindow() self.tab.tabCloseRequested.connect(self.closeTab) self.tab.currentChanged.connect(self.tabChanged) - + # Connections -------------------------------------------------------- - + self.sldCorkSizeFactor.valueChanged.connect( - self.setCorkSizeFactor, AUC) + self.setCorkSizeFactor, AUC) self.btnRedacFolderCork.toggled.connect( - self.sldCorkSizeFactor.setVisible, AUC) + self.sldCorkSizeFactor.setVisible, AUC) self.btnRedacFolderText.clicked.connect( - lambda v: self.setFolderView("text"), AUC) + lambda v: self.setFolderView("text"), AUC) self.btnRedacFolderCork.clicked.connect( - lambda v: self.setFolderView("cork"), AUC) + lambda v: self.setFolderView("cork"), AUC) self.btnRedacFolderOutline.clicked.connect( - lambda v: self.setFolderView("outline"), AUC) - + lambda v: self.setFolderView("outline"), AUC) + self.btnRedacFullscreen.clicked.connect( - self.showFullScreen, AUC) - -############################################################################### -# TABS -############################################################################### - + self.showFullScreen, AUC) + + ############################################################################### + # TABS + ############################################################################### + def currentEditor(self): return self.tab.currentWidget() - + def tabChanged(self, index): if self.currentEditor(): index = self.currentEditor().currentIndex @@ -56,61 +63,61 @@ class mainEditor(QWidget, Ui_mainEditor): else: index = QModelIndex() hidden = False - + self._updating = True self.mw.treeRedacOutline.setCurrentIndex(index) self._updating = False - + self.updateStats() self.updateThingsVisible(index) - + def closeTab(self, index): - #FIXME: submit data if textedit? + # FIXME: submit data if textedit? w = self.tab.widget(index) self.tab.removeTab(index) w.deleteLater() - + def allTabs(self): return [self.tab.widget(i) for i in range(self.tab.count())] - -############################################################################### -# SELECTION AND UPDATES -############################################################################### - + + ############################################################################### + # SELECTION AND UPDATES + ############################################################################### + def selectionChanged(self): if self._updating: return - + if len(self.mw.treeRedacOutline.selectionModel(). - selection().indexes()) == 0: + selection().indexes()) == 0: idx = QModelIndex() else: idx = self.mw.treeRedacOutline.currentIndex() self.setCurrentModelIndex(idx) - + self.updateThingsVisible(idx) - + def openIndexes(self, indexes, newTab=False): for i in indexes: self.setCurrentModelIndex(i, newTab) - + def setCurrentModelIndex(self, index, newTab=False): - + if not index.isValid(): title = self.tr("Root") else: title = index.internalPointer().title() - + # Checking if tab is already openned for w in self.allTabs(): if w.currentIndex == index: self.tab.setCurrentWidget(w) return - + if qApp.keyboardModifiers() & Qt.ControlModifier: newTab = True - + if newTab or not self.tab.count(): editor = editorWidget(self) editor.setCurrentModelIndex(index) @@ -119,28 +126,26 @@ class mainEditor(QWidget, Ui_mainEditor): else: self.currentEditor().setCurrentModelIndex(index) self.tab.setTabText(self.tab.currentIndex(), title) - - -############################################################################### -# UI -############################################################################### - + + ############################################################################### + # UI + ############################################################################### + def updateThingsVisible(self, index): if index.isValid(): visible = index.internalPointer().isFolder() else: visible = True - + # Hides / show textFormat self.textFormat.updateFromIndex(index) - + self.btnRedacFolderText.setVisible(visible) self.btnRedacFolderCork.setVisible(visible) self.btnRedacFolderOutline.setVisible(visible) self.sldCorkSizeFactor.setVisible(visible) self.btnRedacFullscreen.setVisible(not visible) - - + def updateFolderViewButtons(self, view): if view == "text": self.btnRedacFolderText.setChecked(True) @@ -148,26 +153,26 @@ class mainEditor(QWidget, Ui_mainEditor): self.btnRedacFolderCork.setChecked(True) elif view == "outline": self.btnRedacFolderOutline.setChecked(True) - + def updateStats(self): - + if not self.currentEditor(): return - + index = self.currentEditor().currentIndex if index.isValid(): item = index.internalPointer() else: item = self.mw.mdlOutline.rootItem - + if not item: item = self.mw.mdlOutline.rootItem - + wc = item.data(Outline.wordCount.value) goal = item.data(Outline.goal.value) progress = item.data(Outline.goalPercentage.value) - #mw = qApp.activeWindow() - + # mw = qApp.activeWindow() + if not wc: wc = 0 if goal: @@ -181,53 +186,51 @@ class mainEditor(QWidget, Ui_mainEditor): del p self.lblRedacProgress.setPixmap(self.px) self.lblRedacWC.setText(self.tr("{} words / {}").format( - locale.format("%d", wc, grouping=True), - locale.format("%d", goal, grouping=True))) + locale.format("%d", wc, grouping=True), + locale.format("%d", goal, grouping=True))) else: self.lblRedacProgress.hide() self.lblRedacWC.setText(self.tr("{} words").format( - locale.format("%d", wc, grouping=True))) - -############################################################################### -# VIEWS -############################################################################### - + locale.format("%d", wc, grouping=True))) + + ############################################################################### + # VIEWS + ############################################################################### + def setFolderView(self, view): if self.currentEditor(): self.currentEditor().setFolderView(view) - + def setCorkSizeFactor(self, val): for w in self.allTabs(): w.setCorkSizeFactor(val) settings.corkSizeFactor = val - + def updateCorkView(self): for w in self.allTabs(): w.corkView.viewport().update() - + def updateCorkBackground(self): for w in self.allTabs(): w.corkView.updateBackground() - + def updateTreeView(self): for w in self.allTabs(): w.outlineView.viewport().update() - + def showFullScreen(self): if self.currentEditor(): self._fullScreen = fullScreenEditor(self.currentEditor().currentIndex) - -############################################################################### -# DICT AND STUFF LIKE THAT -############################################################################### + + ############################################################################### + # DICT AND STUFF LIKE THAT + ############################################################################### def setDict(self, dict): print(dict) for w in self.allTabs(): w.setDict(dict) - + def toggleSpellcheck(self, val): for w in self.allTabs(): w.toggleSpellcheck(val) - - \ No newline at end of file diff --git a/manuskript/ui/editors/mainEditor_ui.py b/manuskript/ui/editors/mainEditor_ui.py index a8d84a4..1d5565e 100644 --- a/manuskript/ui/editors/mainEditor_ui.py +++ b/manuskript/ui/editors/mainEditor_ui.py @@ -2,7 +2,7 @@ # 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! @@ -94,4 +94,4 @@ class Ui_mainEditor(object): self.btnRedacFolderOutline.setText(_translate("mainEditor", "Outline")) self.btnRedacFullscreen.setShortcut(_translate("mainEditor", "F11")) -from ui.editors.textFormat import textFormat +from manuskript.ui.editors.textFormat import textFormat diff --git a/manuskript/ui/editors/mainEditor_ui.ui b/manuskript/ui/editors/mainEditor_ui.ui index 4e77ce6..d5b0387 100644 --- a/manuskript/ui/editors/mainEditor_ui.ui +++ b/manuskript/ui/editors/mainEditor_ui.ui @@ -201,7 +201,7 @@ textFormat QWidget -
    ui.editors.textFormat.h
    +
    manuskript.ui.editors.textFormat.h
    1
    diff --git a/manuskript/ui/editors/t2tFunctions.py b/manuskript/ui/editors/t2tFunctions.py index 4c7a269..f226d5d 100644 --- a/manuskript/ui/editors/t2tFunctions.py +++ b/manuskript/ui/editors/t2tFunctions.py @@ -1,9 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from qt import * import re +from PyQt5.QtCore import QRegExp +from PyQt5.QtGui import QTextCursor + + def t2tFormatSelection(editor, 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 while text[start:start + 1] == formatChar: start += 1 - while text[end - 1:end] ==formatChar: + while text[end - 1:end] == formatChar: end -= 1 # 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 # whole selection propperArray = propperArray[:tStart] + [1] * \ - (tEnd - tStart) + propperArray[tEnd:] + (tEnd - tStart) + propperArray[tEnd:] else: # The whole selection is already formatted, so we remove the # formatting propperArray = propperArray[:tStart] + [0] * \ - (tEnd - tStart) + propperArray[tEnd:] + (tEnd - tStart) + propperArray[tEnd:] fArray = fArray[0:style] + [propperArray] + fArray[style + 1:] @@ -92,8 +95,9 @@ def t2tFormatSelection(editor, style): editor.setTextCursor(cursor) + def t2tClearFormat(editor): - "Clears format on ``editor``'s current selection." + """Clears format on ``editor``'s current selection.""" cursor = editor.textCursor() cursor.beginEditBlock() @@ -105,6 +109,7 @@ def t2tClearFormat(editor): cursor.endEditBlock() editor.setTextCursor(cursor) + def textToFormatArray(text): """ Take some text and returns an array of array containing informations @@ -140,7 +145,7 @@ def textToFormatArray(text): pos = r.indexIn(text, 0) lastPos = 0 while pos >= 0: - #We have a winner + # We have a winner rList += [0] * (pos - lastPos) rList += [2] * 2 rList += [1] * len(r.cap(2)) @@ -231,7 +236,7 @@ def reformatText(text, markupArray): markup = ["**", "//", "__", "--", "``", "''"] for k, m in enumerate(markupArray): - #m = markupArray[k] + # m = markupArray[k] _open = False # Are we in an _openned markup d = 0 alreadySeen = [] @@ -256,7 +261,7 @@ def reformatText(text, markupArray): for j, m2 in enumerate(markupArray): # The other array still have the same length 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) alreadySeen = [] @@ -267,24 +272,24 @@ def reformatText(text, markupArray): for j, m2 in enumerate(markupArray): # The other array still have the same length 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) text = rText rText = "" - ## Clean up + # Clean up # Exclude first and last space of the markup for markup in ["\*", "/", "_", "-", "`", "\'"]: - #r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')') - #r.setMinimal(True) - #text.replace(r, "\\2\\1\\3\\4") + # r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')') + # r.setMinimal(True) + # text.replace(r, "\\2\\1\\3\\4") text = re.sub(r'(' + markup * 2 + ')(\s+?)(.+?)(' + markup * 2 + ')', "\\2\\1\\3\\4", text) - #r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')') - #r.setMinimal(True) - #text.replace(r, "\\1\\2\\4\\3") + # r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')') + # r.setMinimal(True) + # text.replace(r, "\\1\\2\\4\\3") text = re.sub(r'(' + markup * 2 + ')(.+?)(\s+?)(' + markup * 2 + ')', "\\1\\2\\4\\3", text) @@ -293,7 +298,7 @@ def reformatText(text, markupArray): def cleanFormat(text): - "Makes markup clean (removes doubles, etc.)" + """Makes markup clean (removes doubles, etc.)""" t, a = textToFormatArrayNoMarkup(text) return reformatText(t, a) @@ -327,7 +332,7 @@ class State: RAW_AREA_ENDS = 20 TAGGED_AREA_BEGINS = 21 TAGGED_AREA_ENDS = 22 - #LINE + # LINE COMMENT_LINE = 30 CODE_LINE = 31 RAW_LINE = 32 @@ -346,7 +351,7 @@ class State: # TABLE TABLE_LINE = 50 TABLE_HEADER = 51 - #OTHER + # OTHER MARKUP = 60 LINKS = 61 MACRO = 62 @@ -368,4 +373,4 @@ class State: State.NUMBERED_TITLE_3: 3, State.NUMBERED_TITLE_4: 4, State.NUMBERED_TITLE_5: 5, - }.get(state, -1) \ No newline at end of file + }.get(state, -1) diff --git a/manuskript/ui/editors/t2tHighlighter.py b/manuskript/ui/editors/t2tHighlighter.py index 0523597..c5f52e8 100644 --- a/manuskript/ui/editors/t2tHighlighter.py +++ b/manuskript/ui/editors/t2tHighlighter.py @@ -1,22 +1,26 @@ #!/usr/bin/python # -*- 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 # 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. """ @@ -25,9 +29,9 @@ class t2tHighlighter (basicHighlighter): # Stupid variable that fixes the loss of QTextBlockUserData. self.thisDocument = editor.document() - + self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style) - + self.inDocRules = [] rules = [ @@ -63,25 +67,25 @@ class t2tHighlighter (basicHighlighter): self._defaultCharFormat = cf self.setStyle() self.rehighlight() - + def highlightBlock(self, text): """Apply syntax highlighting to the given block of text. """ basicHighlighter.highlightBlockBefore(self, text) - + # Check if syntax highlighting is enabled if self.style is None: default = QTextBlockFormat() QTextCursor(self.currentBlock()).setBlockFormat(default) print("t2tHighlighter.py: is style supposed to be None?") return - + block = self.currentBlock() oldState = blockUserData.getUserState(block) self.identifyBlock(block) # formatBlock prevent undo/redo from working # TODO: find a todo/undo compatible way of formatting block - #self.formatBlock(block) + # self.formatBlock(block) state = blockUserData.getUserState(block) data = blockUserData.getUserData(block) @@ -89,14 +93,15 @@ class t2tHighlighter (basicHighlighter): 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, # a comment which contains color infos, or a include conf? # r'^%!p[or][se]t?proc[^\s]*\s*:\s*\'(.*)\'\s*\'.*\'' - rlist = [QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))'), # pre/postproc - QRegExp(r'^%.*\s\((.*)\)'), # comment - QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')] # includeconf + rlist = [QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))'), + # pre/postproc + QRegExp(r'^%.*\s\((.*)\)'), # comment + QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')] # includeconf for r in rlist: if r.indexIn(text) != -1: self.parseInDocRules() @@ -106,7 +111,7 @@ class t2tHighlighter (basicHighlighter): State.BLOCKQUOTE_LINE, State.HORIZONTAL_LINE, State.HEADER_LINE, - ]: + ]: if not inList and state == lineState: self.setFormat(0, len(text), self.style.format(lineState)) @@ -116,9 +121,9 @@ class t2tHighlighter (basicHighlighter): (State.RAW_LINE, "\"\"\""), (State.TAGGED_LINE, "'''"), (State.SETTINGS_LINE, "%!") - ]: + ]: if state == lineState and \ - not (inList and state == State.SETTINGS_LINE): + not (inList and state == State.SETTINGS_LINE): n = 0 # If it's a comment, we want to highlight all '%'. if state == State.COMMENT_LINE: @@ -140,9 +145,9 @@ class t2tHighlighter (basicHighlighter): setting = r.cap(1) val = r.cap(2) if setting == "target" and \ - val in self.editor.main.targetsNames: + val in self.editor.main.targetsNames: self.editor.fileWidget.preview.setPreferredTarget(val) - + # Pre/postproc r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))') if r.indexIn(text) != -1: @@ -161,15 +166,15 @@ class t2tHighlighter (basicHighlighter): self.setFormat(i, 1, self.style.format(lineState)) # Lists - #if text == " p": print(data.isList()) + # if text == " p": print(data.isList()) if data.isList(): r = QRegExp(r'^\s*[\+\-\:]? ?') r.indexIn(text) self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET)) - #if state == State.LIST_BEGINS: - #r = QRegExp(r'^\s*[+-:] ') - #r.indexIn(text) - #self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET)) + # if state == State.LIST_BEGINS: + # r = QRegExp(r'^\s*[+-:] ') + # r.indexIn(text) + # self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET)) if state == State.LIST_ENDS: self.setFormat(0, len(text), self.style.format(State.LIST_BULLET_ENDS)) @@ -181,8 +186,8 @@ class t2tHighlighter (basicHighlighter): if pos >= 0: f = self.style.format(state) # Uncomment for markup to be same size as title - #op = self.formats(preset="markup", - #base=self.formats(preset=state)) + # op = self.formats(preset="markup", + # base=self.formats(preset=state)) self.setFormat(r.pos(2), len(r.cap(2)), f) self.setFormat(r.pos(1), len(r.cap(1)), 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.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS), (State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS), - ]: + ]: if state == middle: self.setFormat(0, len(text), self.style.format(middle)) @@ -202,8 +207,8 @@ class t2tHighlighter (basicHighlighter): # Inline formatting if state not in [ - #State.COMMENT_AREA, - #State.COMMENT_LINE, + # State.COMMENT_AREA, + # State.COMMENT_LINE, State.RAW_AREA, State.RAW_LINE, State.CODE_AREA, @@ -212,7 +217,7 @@ class t2tHighlighter (basicHighlighter): State.TAGGED_LINE, State.SETTINGS_LINE, State.HORIZONTAL_LINE, - ] and state not in State.TITLES: + ] and state not in State.TITLES: formatArray = textToFormatArray(text) # InDocRules @@ -224,10 +229,10 @@ class t2tHighlighter (basicHighlighter): if "," in c: c1, c2 = c.split(",") self.setFormat(m.start(), l, - self.style.makeFormat(color=c1, bgcolor=c2, base=f)) + self.style.makeFormat(color=c1, bgcolor=c2, base=f)) else: self.setFormat(m.start(), l, - self.style.makeFormat(color=c, base=f)) + self.style.makeFormat(color=c, base=f)) # Links if state not in [State.COMMENT_LINE, State.COMMENT_AREA]: @@ -236,8 +241,8 @@ class t2tHighlighter (basicHighlighter): pos = r.indexIn(text) links = [] while pos >= 0: - #TODO: The text should not be formatted if [**not bold**] - #if max([k[pos] for k in formatArray]) == 0 or 1 == 1: + # TODO: The text should not be formatted if [**not bold**] + # if max([k[pos] for k in formatArray]) == 0 or 1 == 1: self.setFormat(pos, 1, self.style.format(State.MARKUP)) self.setFormat(pos + 1, len(r.cap(0)) - 1, @@ -247,29 +252,29 @@ class t2tHighlighter (basicHighlighter): if r.pos(2) > 0: _f = QTextCharFormat(self.style.format(State.LINKS)) _f.setForeground(QBrush(_f.foreground() - .color().lighter())) + .color().lighter())) _f.setFontUnderline(True) 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) - + # Links like www.theologeek.ch, http://www.fsf.org, ... # FIXME: - "http://adresse et http://adresse" is detected also as italic # - some error, like "http://adress.htm." also color the final "." # - also: adresse@email.com, ftp://, www2, www3, etc. # - But for now, does the job 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) while pos >= 0: for k in links: - #print pos, k[0], k[1] - if pos > k[0] and pos < k[0] + k[1]: # already highlighted + # print pos, k[0], k[1] + if k[0] < pos < k[0] + k[1]: # already highlighted break else: self.setFormat(pos, len(r.cap(0)), self.style.format(State.LINKS)) - + pos = r.indexIn(text, pos + 1) # Bold, Italic, Underline, Code, Tagged, Strikeout @@ -288,40 +293,39 @@ class t2tHighlighter (basicHighlighter): self.setFormat(pos, len(r.cap(0)), self.style.format(State.MACRO)) pos = r.indexIn(text, pos + 1) - + # Highlighted word (for search) if self.editor.highlightWord: if self.editor.highligtCS and self.editor.highlightWord in text or \ - not self.editor.highlightCs and self.editor.highlightWord.lower() in text.lower(): - #if self.editor.highlightCS: - #s = self.editor.highlightWord - #else: - #s = self.editor.highlightWord.toLower() - #print(s) + not self.editor.highlightCs and self.editor.highlightWord.lower() in text.lower(): + # if self.editor.highlightCS: + # s = self.editor.highlightWord + # else: + # s = self.editor.highlightWord.toLower() + # print(s) p = text.indexOf(self.editor.highlightWord, cs=self.editor.highlightCS) while p >= 0: self.setFormat(p, len(self.editor.highlightWord), self.style.makeFormat(preset="higlighted", base=self.format(p))) 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 - #for expression, style in self.keywordRules: - #expression.setMinimal( True ) - #index = expression.indexIn(text, 0) + ### 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 + # 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) def identifyBlock(self, block): @@ -333,20 +337,20 @@ class t2tHighlighter (basicHighlighter): # Header Lines # No header line here - #if block.blockNumber() == 0: - #block.setUserState(State.HEADER_LINE) - #return - #elif block.blockNumber() in [1, 2] and \ - #self.document().findBlockByNumber(0).text(): - #block.setUserState(State.HEADER_LINE) - #return + # if block.blockNumber() == 0: + # block.setUserState(State.HEADER_LINE) + # return + # elif block.blockNumber() in [1, 2] and \ + # self.document().findBlockByNumber(0).text(): + # block.setUserState(State.HEADER_LINE) + # return state = 0 inList = False blankLinesBefore = 0 - #if text.contains(QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$')): - if QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$').indexIn(text) != -1: + # if text.contains(QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$')): + if QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$').indexIn(text) != -1: state = State.LIST_BEGINS # List stuff @@ -354,12 +358,12 @@ class t2tHighlighter (basicHighlighter): inList = True # listLevel and leadingSpaces - #FIXME: not behaving exactly correctly... + # FIXME: not behaving exactly correctly... lastData = blockUserData.getUserData(block.previous()) if state == State.LIST_BEGINS: leadingSpaces = QRegExp(r'[-+:]').indexIn(text, 0) data.setLeadingSpaces(leadingSpaces) - + data.setListSymbol(text[leadingSpaces]) if self.isList(block.previous()): # The last block was also a list. @@ -380,13 +384,13 @@ class t2tHighlighter (basicHighlighter): # Blank lines before (two = end of list) blankLinesBefore = self.getBlankLines(block.previous()) if not QRegExp(r'^\s*$').indexIn(block.previous().text()) != -1 and \ - not blockUserData.getUserState(block.previous()) in [State.COMMENT_LINE, - State.COMMENT_AREA, State.COMMENT_AREA_BEGINS, - State.COMMENT_AREA_ENDS]: + not blockUserData.getUserState(block.previous()) in [State.COMMENT_LINE, + State.COMMENT_AREA, State.COMMENT_AREA_BEGINS, + State.COMMENT_AREA_ENDS]: blankLinesBefore = 0 elif not blockUserData.getUserState(block.previous()) in \ - [State.COMMENT_LINE, State.COMMENT_AREA, - State.COMMENT_AREA_BEGINS, State.COMMENT_AREA_ENDS]: + [State.COMMENT_LINE, State.COMMENT_AREA, + State.COMMENT_AREA_BEGINS, State.COMMENT_AREA_ENDS]: blankLinesBefore += 1 if blankLinesBefore == 2: # End of list. @@ -401,7 +405,7 @@ class t2tHighlighter (basicHighlighter): (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.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS, '^\'\'\'\s*$'), - ]: + ]: if QRegExp(marker).indexIn(text) != -1: if blockUserData.getUserState(block.previous()) in [begins, middle]: @@ -423,8 +427,8 @@ class t2tHighlighter (basicHighlighter): break if state in [State.BLOCKQUOTE_LINE, State.LIST_ENDS]: - #FIXME: doesn't work exactly. Closes only the current level, not - #FIXME: the whole list. + # FIXME: doesn't work exactly. Closes only the current level, not + # FIXME: the whole list. inList = False if inList and not state == State.LIST_BEGINS: @@ -439,8 +443,8 @@ class t2tHighlighter (basicHighlighter): """ Formats the block according to its state. """ - #TODO: Use QTextDocument format presets, and QTextBlock's - #TODO: blockFormatIndex. And move that in t2tHighlighterStyle. + # TODO: Use QTextDocument format presets, and QTextBlock's + # TODO: blockFormatIndex. And move that in t2tHighlighterStyle. state = block.userState() blockFormat = QTextBlockFormat() @@ -451,7 +455,7 @@ class t2tHighlighter (basicHighlighter): QTextCursor(block).setBlockFormat(blockFormat) 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() if state >= 200: return 1 @@ -459,9 +463,9 @@ class t2tHighlighter (basicHighlighter): return 0 def isList(self, block): - "Returns TRUE if the block is in a list." - if block.userState() == State.LIST_BEGINS or\ - block.userState() >= 100: + """Returns TRUE if the block is in a list.""" + if block.userState() == State.LIST_BEGINS or \ + block.userState() >= 100: return True def setStyle(self, style="Default"): @@ -481,7 +485,7 @@ class t2tHighlighter (basicHighlighter): self.inDocRules = [] t = self.thisDocument.toPlainText() - + # Get all conf files confs = [] lines = t.split("\n") @@ -489,26 +493,26 @@ class t2tHighlighter (basicHighlighter): r = QRegExp(r'^%!includeconf:\s*([^\s]*)\s*') if r.indexIn(l) != -1: confs.append(r.cap(1)) - + # Try to load conf files for c in confs: try: import codecs 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") except: print(("Error: cannot open {}.".format(c))) - continue - # We add the content to the current lines of the current document - lines += file.readlines() #lines.extend(file.readlines()) - - #b = self.thisDocument.firstBlock() + continue + # We add the content to the current lines of the current document + lines += file.readlines() # lines.extend(file.readlines()) + + # b = self.thisDocument.firstBlock() lastColor = "" - - #while b.isValid(): + + # while b.isValid(): for l in lines: - text = l #b.text() + text = l # b.text() r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*(\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\")') if r.indexIn(text) != -1: rule = r.cap(1)[1:-1] @@ -517,27 +521,27 @@ class t2tHighlighter (basicHighlighter): self.inDocRules.append((str(rule), lastColor)) # Check if previous block is a comment like it should else: - previousText = lines[lines.indexOf(l)-1] #b.previous().text() + previousText = lines[lines.indexOf(l) - 1] # b.previous().text() r = QRegExp(r'^%.*\s\((.*)\)') if r.indexIn(previousText) != -1: lastColor = r.cap(1) self.inDocRules.append((str(rule), lastColor)) else: lastColor = "" - #b = b.next() + # b = b.next() if oldRules != self.inDocRules: - #Rules have changed, we need to rehighlight - #print("Rules have changed.", len(self.inDocRules)) - #self.rehighlight() # Doesn't work (seg fault), why? + # Rules have changed, we need to rehighlight + # print("Rules have changed.", len(self.inDocRules)) + # self.rehighlight() # Doesn't work (seg fault), why? pass - #b = self.thisDocument.firstBlock() - #while b.isValid(): - #for (r, c) in self.inDocRules: - #r = QRegExp(r) - #pos = r.indexIn(b.text()) - #if pos >= 0: - #print("rehighlighting:", b.text()) - #self.rehighlightBlock(b) - #break - #b = b.next() + # b = self.thisDocument.firstBlock() + # while b.isValid(): + # for (r, c) in self.inDocRules: + # r = QRegExp(r) + # pos = r.indexIn(b.text()) + # if pos >= 0: + # print("rehighlighting:", b.text()) + # self.rehighlightBlock(b) + # break + # b = b.next() diff --git a/manuskript/ui/editors/t2tHighlighterStyle.py b/manuskript/ui/editors/t2tHighlighterStyle.py index b1df480..318e217 100644 --- a/manuskript/ui/editors/t2tHighlighterStyle.py +++ b/manuskript/ui/editors/t2tHighlighterStyle.py @@ -1,14 +1,17 @@ #!/usr/bin/python # -*- 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. """ @@ -21,15 +24,15 @@ class t2tHighlighterStyle (): self._defaultCharFormat = charFormat # Defaults - #self.defaultFontPointSize = self.editor.defaultFontPointSize + # self.defaultFontPointSize = self.editor.defaultFontPointSize self.defaultFontFamily = qApp.font().family() self.tabStopWidth = 40 self.setupEditor() - + if self.name == "Default": self.initDefaults() - #Temporary other theme + # Temporary other theme elif self.name == "Monospace": self.defaultFontFamily = "Monospace" self.initDefaults() @@ -46,42 +49,42 @@ class t2tHighlighterStyle (): def initDefaults(self): self.styles = {} for i in [State.CODE_AREA, - State.CODE_LINE, - State.COMMENT_AREA, - State.COMMENT_LINE, - State.SETTINGS_LINE, - State.BLOCKQUOTE_LINE, - State.RAW_AREA, - State.RAW_LINE, - State.TAGGED_AREA, - State.TAGGED_LINE, - State.TITLE_1, - State.TITLE_2, - State.TITLE_3, - State.TITLE_4, - State.TITLE_5, - State.NUMBERED_TITLE_1, - State.NUMBERED_TITLE_2, - State.NUMBERED_TITLE_3, - State.NUMBERED_TITLE_4, - State.NUMBERED_TITLE_5, - State.TABLE_HEADER, - State.TABLE_LINE, - State.HORIZONTAL_LINE, - State.MARKUP, - State.LIST_BULLET, - State.LIST_BULLET_ENDS, - State.LINKS, - State.MACRO, - State.DEFAULT, - State.HEADER_LINE]: + State.CODE_LINE, + State.COMMENT_AREA, + State.COMMENT_LINE, + State.SETTINGS_LINE, + State.BLOCKQUOTE_LINE, + State.RAW_AREA, + State.RAW_LINE, + State.TAGGED_AREA, + State.TAGGED_LINE, + State.TITLE_1, + State.TITLE_2, + State.TITLE_3, + State.TITLE_4, + State.TITLE_5, + State.NUMBERED_TITLE_1, + State.NUMBERED_TITLE_2, + State.NUMBERED_TITLE_3, + State.NUMBERED_TITLE_4, + State.NUMBERED_TITLE_5, + State.TABLE_HEADER, + State.TABLE_LINE, + State.HORIZONTAL_LINE, + State.MARKUP, + State.LIST_BULLET, + State.LIST_BULLET_ENDS, + State.LINKS, + State.MACRO, + State.DEFAULT, + State.HEADER_LINE]: self.styles[i] = self.makeFormat(preset=i) def format(self, state): return self.styles[state] 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: return self.makeFormat(preset=State.MARKUP, base=base) else: @@ -100,21 +103,21 @@ class t2tHighlighterStyle (): return base def formatBlock(self, block, state): - "Apply transformation to given block." + """Apply transformation to given block.""" blockFormat = QTextBlockFormat() - + if state == State.BLOCKQUOTE_LINE: # Number of tabs n = block.text().indexOf(QRegExp(r'[^\t]'), 0) blockFormat.setIndent(0) blockFormat.setTextIndent(-self.tabStopWidth * n) blockFormat.setLeftMargin(self.tabStopWidth * n) - #blockFormat.setRightMargin(self.editor.contentsRect().width() - # - self.editor.lineNumberAreaWidth() - # - fm.width("X") * self.editor.LimitLine - #+ self.editor.tabStopWidth()) + # blockFormat.setRightMargin(self.editor.contentsRect().width() + # - self.editor.lineNumberAreaWidth() + # - fm.width("X") * self.editor.LimitLine + # + self.editor.tabStopWidth()) blockFormat.setAlignment(Qt.AlignJustify) - if self.name == "Default" : + if self.name == "Default": blockFormat.setTopMargin(5) blockFormat.setBottomMargin(5) elif state == State.HEADER_LINE: @@ -126,32 +129,33 @@ class t2tHighlighterStyle (): else: blockFormat.setBackground(QColor("#EEEEFA")) n = blockUserData.getUserData(block).leadingSpaces() + 1 - + f = QFontMetrics(QFont(self.defaultFontFamily, self._defaultCharFormat.font().pointSize())) fm = f.width(" " * n + blockUserData.getUserData(block).listSymbol()) blockFormat.setTextIndent(-fm) blockFormat.setLeftMargin(fm) - if blockUserData.getUserState(block) == State.LIST_BEGINS and\ - self.name == "Default": + if blockUserData.getUserState(block) == State.LIST_BEGINS and \ + self.name == "Default": blockFormat.setTopMargin(5) return blockFormat 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. """ _color = QColor() - #_format = QTextCharFormat() - #_format.setFont(self.editor.font()) - #size = _format.fontPointSize() + # _format = QTextCharFormat() + # _format.setFont(self.editor.font()) + # size = _format.fontPointSize() _format = QTextCharFormat(self._defaultCharFormat) - + # Base - if base: _format = base + if base: + _format = base # Presets if preset in [State.CODE_AREA, State.CODE_LINE, "code"]: @@ -165,15 +169,15 @@ class t2tHighlighterStyle (): color = "darkGreen" if preset in [State.SETTINGS_LINE, "setting", State.MACRO]: - #style = "italic" + # style = "italic" color = "magenta" if preset in [State.BLOCKQUOTE_LINE]: color = "red" - + if preset in [State.HEADER_LINE]: - size = size * 2 - #print size + size *= 2 + # print size if preset in [State.RAW_AREA, State.RAW_LINE, "raw"]: color = "blue" @@ -198,7 +202,7 @@ class t2tHighlighterStyle (): color = "red" style = "bold" fixedPitch = True - + if preset == State.LIST_BULLET_ENDS: color = "darkGray" fixedPitch = True @@ -211,18 +215,18 @@ class t2tHighlighterStyle (): fixedPitch = True if preset == State.LINKS: - color="blue" - #style="underline" + color = "blue" + # style="underline" if preset == "selected": _format.setBackground(QColor("yellow")) - + if preset == "higlighted": bgcolor = "yellow" - #if preset == State.DEFAULT: - #size = self.defaultFontPointSize - #_format.setFontFamily(self.defaultFontFamily) + # if preset == State.DEFAULT: + # size = self.defaultFontPointSize + # _format.setFontFamily(self.defaultFontFamily) # Manual formatting if color: @@ -244,5 +248,5 @@ class t2tHighlighterStyle (): _format.setFontPointSize(size) if fixedPitch: _format.setFontFixedPitch(True) - + return _format diff --git a/manuskript/ui/editors/textFormat.py b/manuskript/ui/editors/textFormat.py index 889bc96..a2eb0e4 100644 --- a/manuskript/ui/editors/textFormat.py +++ b/manuskript/ui/editors/textFormat.py @@ -1,30 +1,30 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from models.outlineModel import * -from ui.editors.textFormat_ui import * -from functions import * +# --!-- coding: utf8 --!-- +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QWidget, QAction + +from manuskript.enums import Outline +from manuskript.models.outlineModel import outlineModel +from manuskript.ui.editors.textFormat_ui import Ui_textFormat + class textFormat(QWidget, Ui_textFormat): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) self._textEdit = None - + formats = { - "Bold": [self.btnBold, "format-text-bold", self.tr("CTRL+B")], - "Italic": [self.btnItalic, "format-text-italic", self.tr("CTRL+I")], + "Bold": [self.btnBold, "format-text-bold", self.tr("CTRL+B")], + "Italic": [self.btnItalic, "format-text-italic", self.tr("CTRL+I")], "Underline": [self.btnUnderlined, "format-text-underline", self.tr("CTRL+U")], - "Clear": [self.btnClear, "edit-clear", self.tr("CTRL+P")], - "Left": [self.btnLeft, "format-justify-left", self.tr("CTRL+L")], - "Center": [self.btnCenter, "format-justify-center", self.tr("CTRL+E")], - "Right": [self.btnRight, "format-justify-right", self.tr("CTRL+R")], - "Justify": [self.btnJustify, "format-justify-fill", self.tr("CTRL+J")], - } - + "Clear": [self.btnClear, "edit-clear", self.tr("CTRL+P")], + "Left": [self.btnLeft, "format-justify-left", self.tr("CTRL+L")], + "Center": [self.btnCenter, "format-justify-center", self.tr("CTRL+E")], + "Right": [self.btnRight, "format-justify-right", self.tr("CTRL+R")], + "Justify": [self.btnJustify, "format-justify-fill", self.tr("CTRL+J")], + } + for f in formats: val = formats[f] 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.triggered.connect(self.setFormat) val[0].setDefaultAction(a) - + def setTextEdit(self, textEdit): self._textEdit = textEdit - + def updateFromIndex(self, index): if not index.isValid(): self.setVisible(False) return - + if type(index.model()) != outlineModel: self.setVisible(False) - return - + return + if index.column() not in [Outline.text.value, Outline.notes.value]: self.setVisible(False) - return - + return + self.setVisible(True) item = index.internalPointer() - + self.align.setVisible(True) self.format.setVisible(True) - + if item.isFolder(): self.setVisible(False) return - + elif item.isText(): self.align.setVisible(False) self.format.setVisible(False) elif item.isT2T(): self.align.setVisible(False) - - + def setFormat(self): act = self.sender() if self._textEdit: - self._textEdit.applyFormat(act.text()) \ No newline at end of file + self._textEdit.applyFormat(act.text()) diff --git a/manuskript/ui/editors/themes.py b/manuskript/ui/editors/themes.py index 3a5d9c8..d2cb94a 100644 --- a/manuskript/ui/editors/themes.py +++ b/manuskript/ui/editors/themes.py @@ -1,27 +1,30 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- +# --!-- coding: utf8 --!-- # Lots of stuff from here comes from the excellet focuswriter. - -from qt import * -from enums import * -from functions import * -from ui.views.textEditView import * -import settings +import os 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): settings = QSettings(themeFile, QSettings.IniFormat) _themeData = {} - + # Theme name _themeData["Name"] = getThemeName(themeFile) - + # Window Background loadThemeSetting(_themeData, settings, "Background/Color", "#000000") loadThemeSetting(_themeData, settings, "Background/ImageFile", "") loadThemeSetting(_themeData, settings, "Background/Type", 0) - + # Text Background loadThemeSetting(_themeData, settings, "Foreground/Color", "#ffffff") loadThemeSetting(_themeData, settings, "Foreground/Opacity", 50) @@ -30,43 +33,45 @@ def loadThemeDatas(themeFile): loadThemeSetting(_themeData, settings, "Foreground/Position", 1) loadThemeSetting(_themeData, settings, "Foreground/Rounding", 5) loadThemeSetting(_themeData, settings, "Foreground/Width", 700) - + # Text Options loadThemeSetting(_themeData, settings, "Text/Color", "#ffffff") loadThemeSetting(_themeData, settings, "Text/Font", qApp.font().toString()) loadThemeSetting(_themeData, settings, "Text/Misspelled", "#ff0000") - + # Paragraph Options loadThemeSetting(_themeData, settings, "Spacings/IndendFirstLine", False) loadThemeSetting(_themeData, settings, "Spacings/LineSpacing", 100) loadThemeSetting(_themeData, settings, "Spacings/ParagraphAbove", 0) loadThemeSetting(_themeData, settings, "Spacings/ParagraphBelow", 0) loadThemeSetting(_themeData, settings, "Spacings/TabWidth", 48) - + return _themeData - + + def loadThemeSetting(datas, settings, key, default): if settings.contains(key): datas[key] = type(default)(settings.value(key)) else: datas[key] = default - + + def getThemeName(theme): settings = QSettings(theme, QSettings.IniFormat) - + if settings.contains("Name"): return settings.value("Name") else: return os.path.splitext(os.path.split(theme)[1])[0] - + + def themeTextRect(themeDatas, screenRect): - margin = themeDatas["Foreground/Margin"] x = 0 y = margin width = min(themeDatas["Foreground/Width"], screenRect.width() - 2 * margin) height = screenRect.height() - 2 * margin - + if themeDatas["Foreground/Position"] == 0: # Left x = margin elif themeDatas["Foreground/Position"] == 1: # Center @@ -77,33 +82,35 @@ def themeTextRect(themeDatas, screenRect): x = margin width = screenRect.width() - 2 * margin return QRect(x, y, width, height) - + + def createThemePreview(theme, screenRect, size=QSize(200, 120)): - if type(theme) == str and os.path.exists(theme): # Theme is the path to an ini file themeDatas = loadThemeDatas(theme) else: themeDatas = theme - + pixmap = generateTheme(themeDatas, screenRect) - + addThemePreviewText(pixmap, themeDatas, screenRect) - + px = QPixmap(pixmap).scaled(size, Qt.KeepAspectRatio) - + w = px.width() / 10 h = px.height() / 10 r = themeTextRect(themeDatas, screenRect) - + 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.drawRect(QRect(w, h, w*4, h*5)) + painter.drawRect(QRect(w, h, w * 4, h * 5)) painter.end() - + return px + def findThemePath(themeName): p = findFirstFile(re.escape("{}.theme".format(themeName)), "resources/themes") if not p: @@ -111,9 +118,11 @@ def findThemePath(themeName): else: return p + def findBackground(filename): return findFirstFile(re.escape(filename), "resources/backgrounds") + def findFirstFile(regex, path="resources"): paths = allPaths(path) for p in paths: @@ -121,35 +130,36 @@ def findFirstFile(regex, path="resources"): for l in lst: if re.match(regex, l): return os.path.join(p, l) - + + def generateTheme(themeDatas, screenRect): - # Window Background px = QPixmap(screenRect.size()) px.fill(QColor(themeDatas["Background/Color"])) - + painter = QPainter(px) if themeDatas["Background/ImageFile"]: path = findBackground(themeDatas["Background/ImageFile"]) _type = themeDatas["Background/Type"] if path and _type > 0: - if _type == 1: # Tiled + if _type == 1: # Tiled painter.fillRect(screenRect, QBrush(QImage(path))) else: img = QImage(path) scaled = img.size() - if _type == 3: # Stretched + if _type == 3: # Stretched scaled.scale(screenRect.size(), Qt.IgnoreAspectRatio) - elif _type == 4: # Scaled + elif _type == 4: # Scaled scaled.scale(screenRect.size(), Qt.KeepAspectRatio) - elif _type == 5: # Zoomed + elif _type == 5: # Zoomed 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 textRect = themeTextRect(themeDatas, screenRect) - + painter.save() color = QColor(themeDatas["Foreground/Color"]) color.setAlpha(themeDatas["Foreground/Opacity"] * 255 / 100) @@ -158,19 +168,20 @@ def generateTheme(themeDatas, screenRect): r = themeDatas["Foreground/Rounding"] painter.drawRoundedRect(textRect, r, r) painter.restore() - + painter.end() return px - + + def themeEditorGeometry(themeDatas, textRect): - padding = themeDatas["Foreground/Padding"] x = textRect.x() + padding y = textRect.y() + padding + themeDatas["Spacings/ParagraphAbove"] width = textRect.width() - 2 * padding height = textRect.height() - 2 * padding - themeDatas["Spacings/ParagraphAbove"] return x, y, width, height - + + def getThemeBlockFormat(themeDatas): bf = QTextBlockFormat() bf.setLineHeight(themeDatas["Spacings/LineSpacing"], QTextBlockFormat.ProportionalHeight) @@ -178,51 +189,51 @@ def getThemeBlockFormat(themeDatas): bf.setTopMargin(themeDatas["Spacings/ParagraphAbove"]) bf.setBottomMargin(themeDatas["Spacings/ParagraphBelow"]) return bf - + + def setThemeEditorDatas(editor, themeDatas, pixmap, screenRect): - textRect = themeTextRect(themeDatas, screenRect) x, y, width, height = themeEditorGeometry(themeDatas, textRect) 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, QColor(Qt.transparent)) - #p.setColor(QPalette.Text, 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) - #editor.setPalette(p) - + # p.setBrush(QPalette.Base, QColor(Qt.transparent)) + # p.setColor(QPalette.Text, 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) + # editor.setPalette(p) + editor.setAttribute(Qt.WA_NoSystemBackground, True) - + bf = getThemeBlockFormat(themeDatas) editor.setDefaultBlockFormat(bf) - - #b = editor.document().firstBlock() - #cursor = editor.textCursor() - #cursor.setBlockFormat(bf) - #while b.isValid(): - #bf2 = b.blockFormat() - #bf2.merge(bf) - #cursor.setPosition(b.position()) - ##cursor.setPosition(b.position(), QTextCursor.KeepAnchor) - #cursor.setBlockFormat(bf2) - #b = b.next() - + + # b = editor.document().firstBlock() + # cursor = editor.textCursor() + # cursor.setBlockFormat(bf) + # while b.isValid(): + # bf2 = b.blockFormat() + # bf2.merge(bf) + # cursor.setPosition(b.position()) + ##cursor.setPosition(b.position(), QTextCursor.KeepAnchor) + # cursor.setBlockFormat(bf2) + # b = b.next() + editor.setTabStopWidth(themeDatas["Spacings/TabWidth"]) editor.document().setIndentWidth(themeDatas["Spacings/TabWidth"]) - + editor.highlighter.setMisspelledColor(QColor(themeDatas["Text/Misspelled"])) - + cf = QTextCharFormat() - #f = QFont() - #f.fromString(themeDatas["Text/Font"]) - #cf.setFont(f) + # f = QFont() + # f.fromString(themeDatas["Text/Font"]) + # cf.setFont(f) editor.highlighter.setDefaultCharFormat(cf) f = QFont() f.fromString(themeDatas["Text/Font"]) - #editor.setFont(f) - + # editor.setFont(f) + editor.setStyleSheet(""" background: transparent; color: {foreground}; @@ -236,15 +247,13 @@ def setThemeEditorDatas(editor, themeDatas, pixmap, screenRect): fs="{}pt".format(str(f.pointSize())), sc="black" if qGray(QColor(themeDatas["Text/Color"]).rgb()) > 127 else "white", sbc=themeDatas["Text/Color"], - ) - ) - + ) + ) + editor._fromTheme = True - - - + + def addThemePreviewText(pixmap, themeDatas, screenRect): - # Text previewText = textEditView(highlighting=True) previewText.setFrameStyle(QFrame.NoFrame) @@ -253,11 +262,11 @@ def addThemePreviewText(pixmap, themeDatas, screenRect): f = QFile(appPath("resources/themes/preview.txt")) f.open(QIODevice.ReadOnly) previewText.setPlainText(QTextStream(f).readAll()) - + setThemeEditorDatas(previewText, themeDatas, pixmap, screenRect) - + previewText.render(pixmap, previewText.pos()) - + ## Text Background ##themeDatas["Foreground/Color"] ##themeDatas["Foreground/Opacity"] @@ -266,15 +275,15 @@ def addThemePreviewText(pixmap, themeDatas, screenRect): ##themeDatas["Foreground/Position"] ##themeDatas["Foreground/Rounding"] ##themeDatas["Foreground/Width"] - + ## Text Options ##themeDatas["Text/Color"] ##themeDatas["Text/Font"] - #themeDatas["Text/Misspelled"] - + # themeDatas["Text/Misspelled"] + ## Paragraph Options ##themeDatas["Spacings/IndendFirstLine"] ##themeDatas["Spacings/LineSpacing"] ##themeDatas["Spacings/ParagraphAbove"] ##themeDatas["Spacings/ParagraphBelow"] - ##themeDatas["Spacings/TabWidth"] \ No newline at end of file + ##themeDatas["Spacings/TabWidth"] diff --git a/manuskript/ui/helpLabel.py b/manuskript/ui/helpLabel.py index ec7574b..ac42da0 100644 --- a/manuskript/ui/helpLabel.py +++ b/manuskript/ui/helpLabel.py @@ -1,20 +1,16 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - +# --!-- coding: utf8 --!-- +from PyQt5.QtWidgets import QLabel, QSizePolicy - -from qt import * - class helpLabel(QLabel): - def __init__(self, text=None, parent=None): QLabel.__init__(self, text, parent) - + 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.setStyleSheet(""" QLabel { background-color:lightYellow; @@ -23,4 +19,4 @@ class helpLabel(QLabel): margin: 3px; padding:10px; color:gray; - }""") \ No newline at end of file + }""") diff --git a/manuskript/ui/mainWindow.py b/manuskript/ui/mainWindow.py index 9e745db..5761427 100644 --- a/manuskript/ui/mainWindow.py +++ b/manuskript/ui/mainWindow.py @@ -2,7 +2,7 @@ # 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! @@ -40,8 +40,8 @@ class Ui_MainWindow(object): self.page_4 = QtWidgets.QWidget() self.page_4.setObjectName("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.setSpacing(0) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.tabMain = QtWidgets.QTabWidget(self.page_4) self.tabMain.setDocumentMode(True) @@ -352,7 +352,7 @@ class Ui_MainWindow(object): self.btnRmPerso.setObjectName("btnRmPerso") self.horizontalLayout_14.addWidget(self.btnRmPerso) self.txtPersosFilter = QtWidgets.QLineEdit(self.groupBox) - self.txtPersosFilter.setProperty("clearButtonEnabled", True) + self.txtPersosFilter.setClearButtonEnabled(True) self.txtPersosFilter.setObjectName("txtPersosFilter") self.horizontalLayout_14.addWidget(self.txtPersosFilter) self.verticalLayout_8.addLayout(self.horizontalLayout_14) @@ -536,7 +536,7 @@ class Ui_MainWindow(object): self.btnRmPlot.setObjectName("btnRmPlot") self.horizontalLayout_15.addWidget(self.btnRmPlot) self.txtPlotFilter = QtWidgets.QLineEdit(self.groupBox_2) - self.txtPlotFilter.setProperty("clearButtonEnabled", True) + self.txtPlotFilter.setClearButtonEnabled(True) self.txtPlotFilter.setObjectName("txtPlotFilter") self.horizontalLayout_15.addWidget(self.txtPlotFilter) self.verticalLayout_10.addLayout(self.horizontalLayout_15) @@ -732,7 +732,7 @@ class Ui_MainWindow(object): self.btnRmWorld.setObjectName("btnRmWorld") self.horizontalLayout_19.addWidget(self.btnRmWorld) self.txtWorldFilter = QtWidgets.QLineEdit(self.frame_3) - self.txtWorldFilter.setProperty("clearButtonEnabled", True) + self.txtWorldFilter.setClearButtonEnabled(True) self.txtWorldFilter.setObjectName("txtWorldFilter") self.horizontalLayout_19.addWidget(self.txtWorldFilter) self.btnWorldEmptyData = QtWidgets.QPushButton(self.frame_3) @@ -799,7 +799,6 @@ class Ui_MainWindow(object): self.layoutWidget = QtWidgets.QWidget(self.splitterOutlineH) self.layoutWidget.setObjectName("layoutWidget") self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget) - self.verticalLayout_14.setContentsMargins(0, 0, 0, 0) self.verticalLayout_14.setObjectName("verticalLayout_14") self.splitterOutlineV = QtWidgets.QSplitter(self.layoutWidget) self.splitterOutlineV.setOrientation(QtCore.Qt.Vertical) @@ -979,7 +978,7 @@ class Ui_MainWindow(object): self.horizontalLayout_12.addWidget(self.stack) MainWindow.setCentralWidget(self.centralwidget) 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.menuFile = QtWidgets.QMenu(self.menubar) 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), _translate("MainWindow", "Labels")) self.tabMain.setTabText(self.tabMain.indexOf(self.lytTabDebug), _translate("MainWindow", "Debug")) - self.menuFile.setTitle(_translate("MainWindow", "File")) - self.menuRecents.setTitle(_translate("MainWindow", "Recents")) - self.menuMode.setTitle(_translate("MainWindow", "Mode")) + self.menuFile.setTitle(_translate("MainWindow", "Fi&le")) + self.menuRecents.setTitle(_translate("MainWindow", "&Recents")) + self.menuMode.setTitle(_translate("MainWindow", "&Mode")) self.menuHelp.setTitle(_translate("MainWindow", "Help")) self.menuTools.setTitle(_translate("MainWindow", "Tools")) self.menuEdit.setTitle(_translate("MainWindow", "Edit")) - self.menuView.setTitle(_translate("MainWindow", "View")) - self.dckCheatSheet.setWindowTitle(_translate("MainWindow", "Cheat sheet")) - self.dckSearch.setWindowTitle(_translate("MainWindow", "Search")) - self.actOpen.setText(_translate("MainWindow", "Open")) + self.menuView.setTitle(_translate("MainWindow", "&View")) + self.dckCheatSheet.setWindowTitle(_translate("MainWindow", "&Cheat sheet")) + self.dckSearch.setWindowTitle(_translate("MainWindow", "Sea&rch")) + self.actOpen.setText(_translate("MainWindow", "&Open")) 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.actSaveAs.setText(_translate("MainWindow", "Save as...")) + self.actSaveAs.setText(_translate("MainWindow", "Sa&ve as...")) 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.actShowHelp.setText(_translate("MainWindow", "Show help texts")) + self.actShowHelp.setText(_translate("MainWindow", "&Show help texts")) 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.actLabels.setText(_translate("MainWindow", "Labels...")) - self.actStatus.setText(_translate("MainWindow", "Status...")) + self.actLabels.setText(_translate("MainWindow", "&Labels...")) + self.actStatus.setText(_translate("MainWindow", "&Status...")) self.actViewTree.setText(_translate("MainWindow", "Tree")) - self.actModeNorma.setText(_translate("MainWindow", "Normal")) - self.actModeSimple.setText(_translate("MainWindow", "Simple")) - self.actModeFractal.setText(_translate("MainWindow", "Fractal")) + self.actModeNorma.setText(_translate("MainWindow", "&Normal")) + self.actModeSimple.setText(_translate("MainWindow", "&Simple")) + self.actModeFractal.setText(_translate("MainWindow", "&Fractal")) self.actViewCork.setText(_translate("MainWindow", "Index cards")) 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.actCloseProject.setText(_translate("MainWindow", "Close project")) - self.actCompile.setText(_translate("MainWindow", "Compile")) + self.actCloseProject.setText(_translate("MainWindow", "&Close project")) + self.actCompile.setText(_translate("MainWindow", "Co&mpile")) self.actCompile.setShortcut(_translate("MainWindow", "F6")) -from ui.views.basicItemView import basicItemView -from ui.views.plotTreeView import plotTreeView -from ui.search import search -from ui.views.textEditCompleter import textEditCompleter -from ui.views.treeView import treeView -from ui.editors.mainEditor import mainEditor -from ui.views.outlineView import outlineView -from ui.views.lineEditView import lineEditView -from ui.views.textEditView import textEditView -from ui.welcome import welcome -from ui.sldImportance import sldImportance -from ui.cheatSheet import cheatSheet -from ui.views.metadataView import metadataView -from ui.views.persoTreeView import persoTreeView +from manuskript.ui.cheatSheet import cheatSheet +from manuskript.ui.editors.mainEditor import mainEditor +from manuskript.ui.search import search +from manuskript.ui.sldImportance import sldImportance +from manuskript.ui.views.basicItemView import basicItemView +from manuskript.ui.views.lineEditView import lineEditView +from manuskript.ui.views.metadataView import metadataView +from manuskript.ui.views.outlineView import outlineView +from manuskript.ui.views.persoTreeView import persoTreeView +from manuskript.ui.views.plotTreeView import plotTreeView +from manuskript.ui.views.textEditCompleter import textEditCompleter +from manuskript.ui.views.textEditView import textEditView +from manuskript.ui.views.treeView import treeView +from manuskript.ui.welcome import welcome diff --git a/manuskript/ui/mainWindow.ui b/manuskript/ui/mainWindow.ui index 4ad02c9..64a3bcb 100644 --- a/manuskript/ui/mainWindow.ui +++ b/manuskript/ui/mainWindow.ui @@ -103,7 +103,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -706,7 +715,7 @@ Filter - + true
    @@ -1055,7 +1064,7 @@ Filter - + true @@ -1416,7 +1425,7 @@ Filter - + true @@ -1658,7 +1667,16 @@ Redaction - + + 0 + + + 0 + + + 0 + + 0 @@ -1668,7 +1686,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -1850,19 +1877,21 @@ 0 0 1145 - 21 + 30 - File + Fi&le - Recents + &Recents - + + + @@ -1877,7 +1906,7 @@ - Mode + &Mode @@ -1905,7 +1934,7 @@ - View + &View @@ -1918,7 +1947,7 @@ - Cheat sheet + &Cheat sheet 2 @@ -1940,7 +1969,7 @@ - Search + Sea&rch 2 @@ -1966,7 +1995,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Open + &Open Ctrl+O @@ -1978,7 +2007,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Save + &Save Ctrl+S @@ -1990,7 +2019,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Save as... + Sa&ve as... Ctrl+Shift+S @@ -2002,7 +2031,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Quit + &Quit Ctrl+Q @@ -2020,7 +2049,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Show help texts + &Show help texts Ctrl+Shift+B @@ -2038,7 +2067,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Spellcheck + &Spellcheck F9 @@ -2046,12 +2075,12 @@ - Labels... + &Labels... - Status... + &Status... @@ -2067,7 +2096,7 @@ true - Normal + &Normal @@ -2075,7 +2104,7 @@ true - Simple + &Simple @@ -2083,7 +2112,7 @@ true - Fractal + &Fractal @@ -2102,7 +2131,7 @@ ../../../../../../../.designer/backup../../../../../../../.designer/backup - Settings + S&ettings F8 @@ -2115,12 +2144,12 @@ - Close project + &Close project - Compile + Co&mpile F6 @@ -2131,79 +2160,79 @@ textEditView QTextEdit -
    ui.views.textEditView.h
    +
    manuskript.ui.views.textEditView.h
    lineEditView QLineEdit -
    ui.views.lineEditView.h
    +
    manuskript.ui.views.lineEditView.h
    outlineView QTreeView -
    ui.views.outlineView.h
    +
    manuskript.ui.views.outlineView.h
    sldImportance QWidget -
    ui.sldImportance.h
    +
    manuskript.ui.sldImportance.h
    1
    treeView QTreeView -
    ui.views.treeView.h
    +
    manuskript.ui.views.treeView.h
    metadataView QWidget -
    ui.views.metadataView.h
    +
    manuskript.ui.views.metadataView.h
    1
    basicItemView QWidget -
    ui.views.basicItemView.h
    +
    manuskript.ui.views.basicItemView.h
    1
    plotTreeView QTreeWidget -
    ui.views.plotTreeView.h
    +
    manuskript.ui.views.plotTreeView.h
    welcome QWidget -
    ui.welcome.h
    +
    manuskript.ui.welcome.h
    1
    mainEditor QWidget -
    ui.editors.mainEditor.h
    +
    manuskript.ui.editors.mainEditor.h
    1
    persoTreeView QTreeWidget -
    ui.views.persoTreeView.h
    +
    manuskript.ui.views.persoTreeView.h
    cheatSheet QWidget -
    ui.cheatSheet.h
    +
    manuskript.ui.cheatSheet.h
    1
    search QWidget -
    ui.search.h
    +
    manuskript.ui.search.h
    1
    textEditCompleter QTextEdit -
    ui.views.textEditCompleter.h
    +
    manuskript.ui.views.textEditCompleter.h
    diff --git a/manuskript/ui/revisions.py b/manuskript/ui/revisions.py index 78ad6b8..bdfc006 100644 --- a/manuskript/ui/revisions.py +++ b/manuskript/ui/revisions.py @@ -1,24 +1,26 @@ #!/usr/bin/env python -#--!-- 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 +# --!-- coding: utf8 --!-- + import datetime import difflib 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): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) self.splitter.setStretchFactor(0, 5) self.splitter.setStretchFactor(1, 70) - + self.listDelegate = listCompleterDelegate(self) self.list.setItemDelegate(self.listDelegate) self.list.itemActivated.connect(self.showDiff) @@ -28,79 +30,79 @@ class revisions(QWidget, Ui_revisions): self.btnDelete.clicked.connect(self.delete) self.btnRestore.clicked.connect(self.restore) self.btnRestore.setEnabled(False) - - #self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) - + + # self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + self.updateTimer = QTimer() self.updateTimer.setSingleShot(True) self.updateTimer.setInterval(500) self.updateTimer.timeout.connect(self.update) self.updateTimer.stop() - + self.menu = QMenu(self) self.actGroup = QActionGroup(self) - + self.actShowDiff = QAction(self.tr("Show modifications"), self.menu) self.actShowDiff.setCheckable(True) self.actShowDiff.setChecked(True) self.actShowDiff.triggered.connect(self.showDiff) self.menu.addAction(self.actShowDiff) self.actGroup.addAction(self.actShowDiff) - + self.actShowVersion = QAction(self.tr("Show ancient version"), self.menu) self.actShowVersion.setCheckable(True) self.actShowVersion.setChecked(False) self.actShowVersion.triggered.connect(self.showDiff) self.menu.addAction(self.actShowVersion) self.actGroup.addAction(self.actShowVersion) - + self.menu.addSeparator() self.actShowSpaces = QAction(self.tr("Show spaces"), self.menu) self.actShowSpaces.setCheckable(True) self.actShowSpaces.setChecked(False) self.actShowSpaces.triggered.connect(self.showDiff) self.menu.addAction(self.actShowSpaces) - + self.actDiffOnly = QAction(self.tr("Show modifications only"), self.menu) self.actDiffOnly.setCheckable(True) self.actDiffOnly.setChecked(True) self.actDiffOnly.triggered.connect(self.showDiff) self.menu.addAction(self.actDiffOnly) self.btnOptions.setMenu(self.menu) - + self._model = None self._index = None - + def setModel(self, model): self._model = model self._model.dataChanged.connect(self.updateMaybe) - + def setCurrentModelIndex(self, index): self._index = index self.view.setText("") self.update() - + def updateMaybe(self, topLeft, bottomRight): if self._index and \ - topLeft.column() <= Outline.revisions.value <= bottomRight.column() and \ - topLeft.row() <= self._index.row() <= bottomRight.row(): - #self.update() + topLeft.column() <= Outline.revisions.value <= bottomRight.column() and \ + topLeft.row() <= self._index.row() <= bottomRight.row(): + # self.update() self.updateTimer.start() - + def update(self): self.list.clear() item = self._index.internalPointer() rev = item.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: timestamp = datetime.datetime.fromtimestamp(r[0]).strftime('%Y-%m-%d %H:%M:%S') readable = self.readableDelta(r[0]) i = QListWidgetItem(readable) i.setData(Qt.UserRole, r[0]) - i.setData(Qt.UserRole+1, timestamp) + i.setData(Qt.UserRole + 1, timestamp) self.list.addItem(i) - + def readableDelta(self, timestamp): now = datetime.datetime.now() 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))) else: return self.tr("{} seconds ago").format(str(delta.seconds)) - + def showDiff(self): # UI stuff self.actShowSpaces.setEnabled(self.actShowDiff.isChecked()) self.actDiffOnly.setEnabled(self.actShowDiff.isChecked()) - - #FIXME: Errors in line number + + # FIXME: Errors in line number i = self.list.currentItem() - + if not i: self.btnDelete.setEnabled(False) self.btnRestore.setEnabled(False) return - + self.btnDelete.setEnabled(True) self.btnRestore.setEnabled(True) - + ts = i.data(Qt.UserRole) item = self._index.internalPointer() - + textNow = item.text() textBefore = [r[1] for r in item.revisions() if r[0] == ts][0] - + if self.actShowVersion.isChecked(): if item.type() == "t2t": textBefore = Ref.basicT2TFormat(textBefore) self.view.setText(textBefore) return - + textNow = textNow.splitlines() textBefore = textBefore.splitlines() - + d = difflib.Differ() diff = list(d.compare(textBefore, textNow)) - + if self.actShowSpaces.isChecked(): _format = lambda x: x.replace(" ", "␣ ") else: - _format = lambda x:x - - extra = "" if item.type() == "html" else "
    " + _format = lambda x: x + + extra = "" if item.type() == "html" else "
    " diff = [d for d in diff if d and not d[:2] == "? "] mydiff = "" skip = False @@ -166,23 +168,23 @@ class revisions(QWidget, Ui_revisions): l = diff[n] op = l[:2] txt = l[2:] - op2 = diff[n+1][:2] if n+1 < len(diff) else None - txt2 = 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 + if skip: skip = False continue - + # Same line if op == " " and not self.actDiffOnly.isChecked(): if item.type() == "t2t": txt = Ref.basicT2TFormat(txt) mydiff += "{}{}".format(txt, extra) - + elif op == "- " and op2 == "+ ": if self.actDiffOnly.isChecked(): mydiff += "
    {}
    ".format( - self.tr("Line {}:").format(str(n))) + self.tr("Line {}:").format(str(n))) s = difflib.SequenceMatcher(None, txt, txt2, autojunk=True) newline = "" for tag, i1, i2, j1, j2 in s.get_opcodes(): @@ -191,21 +193,25 @@ class revisions(QWidget, Ui_revisions): elif tag == "delete": newline += "{}".format(_format(txt[i1:i2])) elif tag == "insert": - newline += "{}".format(_format(txt2[j1:j2])) + newline += "{}".format( + _format(txt2[j1:j2])) elif tag == "replace": newline += "{}".format(_format(txt[i1:i2])) - newline += "{}".format(_format(txt2[j1:j2])) - + newline += "{}".format( + _format(txt2[j1:j2])) + # Few ugly tweaks for html diffs newline = re.sub(r"(()", "\\1\\2\\3", newline) - newline = re.sub(r"

    cenrighter\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*?)

    ", - "

    \\1

    ", newline) - newline = re.sub(r"

    centeright\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*)

    ", - "

    \\1

    ", newline) + newline = re.sub( + r"

    cenrighter\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*?)

    ", + "

    \\1

    ", newline) + newline = re.sub( + r"

    centeright\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*)

    ", + "

    \\1

    ", newline) newline = re.sub(r")(.*?)()(.*?)>(.*?)

    ", "\\1\\5\\3

    ", newline) - + mydiff += newline + extra skip = True elif op == "- ": @@ -216,9 +222,9 @@ class revisions(QWidget, Ui_revisions): if self.actDiffOnly.isChecked(): mydiff += "
    {}:
    ".format(str(n)) mydiff += "{}{}".format(txt, extra) - + self.view.setText(mydiff) - + def restore(self): i = self.list.currentItem() 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] index = self._index.sibling(self._index.row(), Outline.text.value) self._index.model().setData(index, textBefore) - #item.setData(Outline.text.value, textBefore) - + # item.setData(Outline.text.value, textBefore) + def delete(self): i = self.list.currentItem() if not i: return ts = i.data(Qt.UserRole) self._index.internalPointer().deleteRevision(ts) - + def clearAll(self): self._index.internalPointer().clearAllRevisions() - + def saveState(self): return [ self.actShowDiff.isChecked(), self.actShowVersion.isChecked(), self.actShowSpaces.isChecked(), self.actDiffOnly.isChecked(), - ] - + ] + def popupMenu(self, pos): i = self.list.itemAt(pos) m = QMenu(self) @@ -257,9 +263,9 @@ class revisions(QWidget, Ui_revisions): m.addSeparator() if self.list.count(): m.addAction(self.tr("Clear all")).triggered.connect(self.clearAll) - + m.popup(self.list.mapToGlobal(pos)) - + def restoreState(self, state): self.actShowDiff.setChecked(state[0]) self.actShowVersion.setChecked(state[1]) @@ -267,25 +273,25 @@ class revisions(QWidget, Ui_revisions): self.actDiffOnly.setChecked(state[3]) self.actShowSpaces.setEnabled(self.actShowDiff.isChecked()) self.actDiffOnly.setEnabled(self.actShowDiff.isChecked()) - - + + class listCompleterDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) - + def paint(self, painter, option, index): - extra = index.data(Qt.UserRole+1) + extra = index.data(Qt.UserRole + 1) if not extra: return QStyledItemDelegate.paint(self, painter, option, index) - + else: if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.color(QPalette.Inactive, QPalette.Highlight)) - + title = index.data() extra = " - {}".format(extra) painter.drawText(option.rect, Qt.AlignLeft, title) - + fm = QFontMetrics(option.font) w = fm.width(title) r = QRect(option.rect) @@ -293,4 +299,4 @@ class listCompleterDelegate(QStyledItemDelegate): painter.save() painter.setPen(Qt.gray) painter.drawText(r, Qt.AlignLeft, extra) - painter.restore() \ No newline at end of file + painter.restore() diff --git a/manuskript/ui/search.py b/manuskript/ui/search.py index 0bc45e3..a75b5ad 100644 --- a/manuskript/ui/search.py +++ b/manuskript/ui/search.py @@ -1,19 +1,20 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from models.outlineModel import * -import models.references as Ref -from ui.search_ui import * -from functions import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt, QRect +from PyQt5.QtGui import QPalette, QFontMetrics +from PyQt5.QtWidgets import QWidget, QMenu, QAction, qApp, QListWidgetItem, QStyledItemDelegate, QStyle + +from manuskript.enums import Outline +from manuskript.functions import mainWindow +from manuskript.ui.search_ui import Ui_search +from manuskript.models import references as Ref + class search(QWidget, Ui_search): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) - + self.options = { "All": True, "Title": True, @@ -24,30 +25,30 @@ class search(QWidget, Ui_search): "Status": False, "Label": False, "CS": True - } - + } + self.text.returnPressed.connect(self.search) self.generateOptionMenu() - + self.delegate = listResultDelegate(self) self.result.setItemDelegate(self.delegate) self.result.itemActivated.connect(self.openItem) - + def generateOptionMenu(self): self.menu = QMenu(self) a = QAction(self.tr("Search in:"), self.menu) a.setEnabled(False) self.menu.addAction(a) for i, d in [ - (self.tr("All"), "All"), - (self.tr("Title"), "Title"), - (self.tr("Text"), "Text"), + (self.tr("All"), "All"), + (self.tr("Title"), "Title"), + (self.tr("Text"), "Text"), (self.tr("Summary"), "Summary"), - (self.tr("Notes"), "Notes"), - (self.tr("POV"), "POV"), - (self.tr("Status"), "Status"), - (self.tr("Label"), "Label"), - ]: + (self.tr("Notes"), "Notes"), + (self.tr("POV"), "POV"), + (self.tr("Status"), "Status"), + (self.tr("Label"), "Label"), + ]: a = QAction(i, self.menu) a.setCheckable(True) a.setChecked(self.options[d]) @@ -55,13 +56,13 @@ class search(QWidget, Ui_search): a.triggered.connect(self.updateOptions) self.menu.addAction(a) self.menu.addSeparator() - + a = QAction(self.tr("Options:"), self.menu) a.setEnabled(False) self.menu.addAction(a) for i, d in [ - (self.tr("Case sensitive"), "CS"), - ]: + (self.tr("Case sensitive"), "CS"), + ]: a = QAction(i, self.menu) a.setCheckable(True) a.setChecked(self.options[d]) @@ -69,36 +70,36 @@ class search(QWidget, Ui_search): a.triggered.connect(self.updateOptions) self.menu.addAction(a) self.menu.addSeparator() - + self.btnOptions.setMenu(self.menu) - + def updateOptions(self): a = self.sender() self.options[a.data()] = a.isChecked() - + def search(self): text = self.text.text() - + # Chosing the right columns lstColumns = [ ("Title", Outline.title.value), ("Text", Outline.text.value), - ("Summary", Outline.summarySentance.value), + ("Summary", Outline.summarySentance.value), ("Summary", Outline.summaryFull.value), ("Notes", Outline.notes.value), ("POV", Outline.POV.value), ("Status", Outline.status.value), ("Label", Outline.label.value), - ] + ] columns = [c[1] for c in lstColumns if self.options[c[0]] or self.options["All"]] - + # Setting override cursor qApp.setOverrideCursor(Qt.WaitCursor) - + # Searching model = mainWindow().mdlOutline results = model.findItemsContaining(text, columns, self.options["CS"]) - + # Showing results self.result.clear() for r in results: @@ -110,35 +111,35 @@ class search(QWidget, Ui_search): i.setData(Qt.UserRole, r) i.setData(Qt.UserRole + 1, item.path()) self.result.addItem(i) - + # Removing override cursor qApp.restoreOverrideCursor() - + def openItem(self, item): r = Ref.textReference(item.data(Qt.UserRole)) Ref.open(r) - #mw = mainWindow() - #index = mw.mdlOutline.getIndexByID(item.data(Qt.UserRole)) - #mw.mainEditor.setCurrentModelIndex(index, newTab=True) - - + # mw = mainWindow() + # index = mw.mdlOutline.getIndexByID(item.data(Qt.UserRole)) + # mw.mainEditor.setCurrentModelIndex(index, newTab=True) + + class listResultDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) - + def paint(self, painter, option, index): - extra = index.data(Qt.UserRole+1) + extra = index.data(Qt.UserRole + 1) if not extra: return QStyledItemDelegate.paint(self, painter, option, index) - + else: if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.color(QPalette.Highlight)) - + title = index.data() extra = " - {}".format(extra) painter.drawText(option.rect.adjusted(2, 1, 0, 0), Qt.AlignLeft, title) - + fm = QFontMetrics(option.font) w = fm.width(title) r = QRect(option.rect) @@ -149,4 +150,4 @@ class listResultDelegate(QStyledItemDelegate): else: painter.setPen(Qt.gray) painter.drawText(r.adjusted(2, 1, 0, 0), Qt.AlignLeft, extra) - painter.restore() \ No newline at end of file + painter.restore() diff --git a/manuskript/ui/settings.py b/manuskript/ui/settings_ui.py similarity index 100% rename from manuskript/ui/settings.py rename to manuskript/ui/settings_ui.py diff --git a/manuskript/ui/settings.ui b/manuskript/ui/settings_ui.ui similarity index 100% rename from manuskript/ui/settings.ui rename to manuskript/ui/settings_ui.ui diff --git a/manuskript/ui/sldImportance.py b/manuskript/ui/sldImportance.py index 22ee0a9..ad239a8 100644 --- a/manuskript/ui/sldImportance.py +++ b/manuskript/ui/sldImportance.py @@ -1,79 +1,80 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from functions import * -from ui.sldImportance_ui import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import pyqtSignal, pyqtProperty +from PyQt5.QtWidgets import QWidget + +from manuskript.functions import toInt +from manuskript.ui.sldImportance_ui import Ui_sldImportance + class sldImportance(QWidget, Ui_sldImportance): - importanceChanged = pyqtSignal(str) - + def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) self._column = 0 self._updating = False self._index = None - + self.lastValue = -1 self.sld.valueChanged.connect(self.changed) self.setValue(0) - + def getImportance(self): return str(self.sld.value()) - + def changed(self, v): val = [ self.tr("Minor"), self.tr("Secondary"), self.tr("Main"), - ] + ] self.lbl.setText(val[v]) - + self.importanceChanged.emit(str(v)) - + if self._index and not self._updating: if str(v) != self._model.data(self._index): self._updating = True self._model.setData(self._index, str(v)) self._updating = False - + def setValue(self, v): - if v != self.lastValue: + if v != self.lastValue: self.sld.setValue(int(v) if v else 0) self.changed(int(v) if v else 0) self.lastValue = v - + def setProperty(): pass - + # MODEL / VIEW - + def setColumn(self, column): self._column = column - + def setModel(self, model): self._model = model self._model.dataChanged.connect(self.update) - + def update(self, topLeft, bottomRight): - + if self._updating: return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateValue() - + def setCurrentModelIndex(self, index): if index.isValid(): if index.column() != self._column: index = index.sibling(index.row(), self._column) self._index = index - + self.updateValue() - + def updateValue(self): if self._index: val = toInt(self._model.data(self._index)) @@ -81,6 +82,5 @@ class sldImportance(QWidget, Ui_sldImportance): self._updating = True self.setValue(val) self._updating = False - - - importance = pyqtProperty(str, fget=getImportance, fset=setValue, notify=importanceChanged) \ No newline at end of file + + importance = pyqtProperty(str, fget=getImportance, fset=setValue, notify=importanceChanged) diff --git a/manuskript/ui/sldImportance_ui.py b/manuskript/ui/sldImportance_ui.py index 688d5b2..f7e3c0b 100644 --- a/manuskript/ui/sldImportance_ui.py +++ b/manuskript/ui/sldImportance_ui.py @@ -6,7 +6,7 @@ # # 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): def setupUi(self, sldImportance): diff --git a/manuskript/ui/views/basicItemView.py b/manuskript/ui/views/basicItemView.py index a5dc845..7b73c00 100644 --- a/manuskript/ui/views/basicItemView.py +++ b/manuskript/ui/views/basicItemView.py @@ -1,45 +1,45 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from ui.views.basicItemView_ui import * +# --!-- coding: utf8 --!-- +from PyQt5.QtWidgets import QWidget + +from manuskript.enums import Outline +from manuskript.ui.views.basicItemView_ui import Ui_basicItemView + class basicItemView(QWidget, Ui_basicItemView): - def __init__(self, parent=None): QWidget.__init__(self) self.setupUi(self) self.txtSummarySentance.setColumn(Outline.summarySentance.value) self.txtSummaryFull.setColumn(Outline.summaryFull.value) self.txtGoal.setColumn(Outline.setGoal.value) - + def setModels(self, mdlOutline, mdlPersos, mdlLabels, mdlStatus): self.cmbPOV.setModels(mdlPersos, mdlOutline) self.txtSummarySentance.setModel(mdlOutline) self.txtSummaryFull.setModel(mdlOutline) self.txtGoal.setModel(mdlOutline) - + def getIndexes(self, sourceView): - "Returns a list of indexes from list of QItemSelectionRange" + """Returns a list of indexes from list of QItemSelectionRange""" indexes = [] - + for i in sourceView.selectionModel().selection().indexes(): - if i.column() != 0: + if i.column() != 0: continue - + if i not in indexes: indexes.append(i) - + return indexes - + def selectionChanged(self, sourceView): - + indexes = self.getIndexes(sourceView) - + if len(indexes) == 0: self.setEnabled(False) - + elif len(indexes) == 1: self.setEnabled(True) idx = indexes[0] @@ -47,18 +47,16 @@ class basicItemView(QWidget, Ui_basicItemView): self.txtSummaryFull.setCurrentModelIndex(idx) self.cmbPOV.setCurrentModelIndex(idx) self.txtGoal.setCurrentModelIndex(idx) - + else: self.setEnabled(True) self.txtSummarySentance.setCurrentModelIndexes(indexes) self.txtSummaryFull.setCurrentModelIndexes(indexes) self.cmbPOV.setCurrentModelIndexes(indexes) self.txtGoal.setCurrentModelIndexes(indexes) - + def setDict(self, d): self.txtSummaryFull.setDict(d) - + def toggleSpellcheck(self, v): self.txtSummaryFull.toggleSpellcheck(v) - - \ No newline at end of file diff --git a/manuskript/ui/views/basicItemView_ui.py b/manuskript/ui/views/basicItemView_ui.py index 8c7dc26..8ba33dd 100644 --- a/manuskript/ui/views/basicItemView_ui.py +++ b/manuskript/ui/views/basicItemView_ui.py @@ -2,7 +2,7 @@ # 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! @@ -66,6 +66,6 @@ class Ui_basicItemView(object): self.txtSummarySentance.setPlaceholderText(_translate("basicItemView", "One line summary")) self.label_9.setText(_translate("basicItemView", "Few sentences summary:")) -from ui.views.textEditView import textEditView -from ui.views.lineEditView import lineEditView -from ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser +from manuskript.ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser +from manuskript.ui.views.lineEditView import lineEditView +from manuskript.ui.views.textEditView import textEditView diff --git a/manuskript/ui/views/basicItemView_ui.ui b/manuskript/ui/views/basicItemView_ui.ui index 2103ece..e632ec2 100644 --- a/manuskript/ui/views/basicItemView_ui.ui +++ b/manuskript/ui/views/basicItemView_ui.ui @@ -109,17 +109,17 @@ textEditView QTextEdit -
    ui.views.textEditView.h
    +
    manuskript.ui.views.textEditView.h
    cmbOutlinePersoChoser QComboBox -
    ui.views.cmbOutlinePersoChoser.h
    +
    manuskript.ui.views.cmbOutlinePersoChoser.h
    lineEditView QLineEdit -
    ui.views.lineEditView.h
    +
    manuskript.ui.views.lineEditView.h
    diff --git a/manuskript/ui/views/chkOutlineCompile.py b/manuskript/ui/views/chkOutlineCompile.py index 7491042..6a024cf 100644 --- a/manuskript/ui/views/chkOutlineCompile.py +++ b/manuskript/ui/views/chkOutlineCompile.py @@ -1,16 +1,16 @@ #!/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. +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QCheckBox + +from manuskript.enums import Outline + class chkOutlineCompile(QCheckBox): - def __init__(self, parent=None): QCheckBox.__init__(self, parent) self.stateChanged.connect(self.submit) @@ -19,11 +19,11 @@ class chkOutlineCompile(QCheckBox): self._indexes = None self._model = None self._updating = False - + def setModel(self, model): self._model = model self._model.dataChanged.connect(self.update) - + def setCurrentModelIndex(self, index): self._indexes = None if index.column() != self._column: @@ -31,7 +31,7 @@ class chkOutlineCompile(QCheckBox): self._index = index self.setTristate(False) self.updateCheckState() - + def setCurrentModelIndexes(self, indexes): self._index = None self._indexes = [] @@ -40,7 +40,7 @@ class chkOutlineCompile(QCheckBox): i = i.sibling(i.row(), self._column) self._indexes.append(i) self.updateCheckState() - + def getCheckedValue(self, index): item = index.internalPointer() c = item.data(Outline.compile) @@ -48,72 +48,71 @@ class chkOutlineCompile(QCheckBox): c = int(c) else: c = Qt.Unchecked - + return c - + def update(self, topLeft, bottomRight): - + if self._updating: # We are currently putting data in the model, so no updates return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateCheckState() - + elif self._indexes: update = False - + for i in self._indexes: if topLeft.row() <= i.row() <= bottomRight.row(): update = True - + if update: self.updateCheckState() - + def updateCheckState(self): - + if self._index: self.setEnabled(True) c = self.getCheckedValue(self._index) self.setCheckState(c) - + elif self._indexes: self.setEnabled(True) values = [] for i in self._indexes: values.append(self.getCheckedValue(i)) - + same = True for v in values[1:]: if v != values[0]: same = False break - + if same: self.setCheckState(values[0]) else: self._updating = True self.setCheckState(Qt.PartiallyChecked) self._updating = False - + else: self.setChecked(False) self.setEnabled(False) - + def submit(self, state): - + if self._updating: return - + if self._index: if self._model.data(self._index) != state: self._model.setData(self._index, state) - + elif self._indexes: for i in self._indexes: if self._model.data(i) != state: self._model.setData(i, state) - + self.setTristate(False) - \ No newline at end of file diff --git a/manuskript/ui/views/cmbOutlineLabelChoser.py b/manuskript/ui/views/cmbOutlineLabelChoser.py index 68d1f54..b9c072a 100644 --- a/manuskript/ui/views/cmbOutlineLabelChoser.py +++ b/manuskript/ui/views/cmbOutlineLabelChoser.py @@ -1,11 +1,13 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QBrush +from PyQt5.QtWidgets import QComboBox + +from manuskript.enums import Outline + class cmbOutlineLabelChoser(QComboBox): - def __init__(self, parent=None): QComboBox.__init__(self, parent) self.activated[int].connect(self.submit) @@ -14,27 +16,27 @@ class cmbOutlineLabelChoser(QComboBox): self._indexes = None self._updating = False self._various = False - + def setModels(self, mdlLabels, mdlOutline): self.mdlLabels = mdlLabels self.mdlLabels.dataChanged.connect(self.updateItems) self.mdlOutline = mdlOutline self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - + def updateItems(self): self.clear() for i in range(self.mdlLabels.rowCount()): item = self.mdlLabels.item(i, 0) if item: self.addItem(item.icon(), - item.text()) - + item.text()) + self._various = False - + if self._index or self._indexes: self.updateSelectedItem() - + def setCurrentModelIndex(self, index): self._indexes = None if index.column() != self._column: @@ -42,30 +44,30 @@ class cmbOutlineLabelChoser(QComboBox): self._index = index self.updateItems() self.updateSelectedItem() - + def setCurrentModelIndexes(self, indexes): self._indexes = [] self._index = None - + for i in indexes: if i.isValid(): if i.column() != self._column: i = i.sibling(i.row(), self._column) self._indexes.append(i) - + self.updateItems() self.updateSelectedItem() - + def update(self, topLeft, bottomRight): - + if self._updating: # We are currently putting data in the model, so no updates return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateSelectedItem() - + elif self._indexes: update = False for i in self._indexes: @@ -73,39 +75,39 @@ class cmbOutlineLabelChoser(QComboBox): update = True if update: self.updateSelectedItem() - + def getLabel(self, index): item = index.internalPointer() label = item.data(self._column) - if not label: + if not label: label = 0 return int(label) - + def updateSelectedItem(self): - + if self._updating: return - + if self._index: label = self.getLabel(self._index) self.setCurrentIndex(label) - + elif self._indexes: labels = [] same = True - + for i in self._indexes: labels.append(self.getLabel(i)) - + for lbl in labels[1:]: if lbl != labels[0]: same = False break - + if same: self._various = False self.setCurrentIndex(labels[0]) - + else: if not self._various: self.insertItem(0, self.tr("Various")) @@ -115,25 +117,24 @@ class cmbOutlineLabelChoser(QComboBox): self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self._various = True self.setCurrentIndex(0) - + else: self.setCurrentIndex(0) - + def submit(self, idx): if self._index: self.mdlOutline.setData(self._index, self.currentIndex()) - + elif self._indexes: value = self.currentIndex() - + if self._various: if value == 0: return - + value -= 1 - + self._updating = True for i in self._indexes: self.mdlOutline.setData(i, value) self._updating = False - \ No newline at end of file diff --git a/manuskript/ui/views/cmbOutlinePersoChoser.py b/manuskript/ui/views/cmbOutlinePersoChoser.py index 1c34e90..6747b51 100644 --- a/manuskript/ui/views/cmbOutlinePersoChoser.py +++ b/manuskript/ui/views/cmbOutlinePersoChoser.py @@ -1,12 +1,14 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon, QBrush, QColor +from PyQt5.QtWidgets import QComboBox + +from manuskript.enums import Outline +from manuskript.functions import toInt + class cmbOutlinePersoChoser(QComboBox): - def __init__(self, parent=None): QComboBox.__init__(self, parent) self.activated[int].connect(self.submit) @@ -15,71 +17,71 @@ class cmbOutlinePersoChoser(QComboBox): self._indexes = None self._updating = False self._various = False - + def setModels(self, mdlPersos, mdlOutline): self.mdlPersos = mdlPersos self.mdlPersos.dataChanged.connect(self.updateItems) self.mdlOutline = mdlOutline self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - + def updateItems(self): self.clear() self.addItem(QIcon.fromTheme("dialog-no"), self.tr("None")) - + l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] - + for importance in range(3): self.addItem(l[importance]) - self.setItemData(self.count()-1, QBrush(QColor(Qt.darkBlue)), Qt.ForegroundRole) - self.setItemData(self.count()-1, QBrush(QColor(Qt.blue).lighter(190)), Qt.BackgroundRole) - item = self.model().item(self.count()-1) + self.setItemData(self.count() - 1, QBrush(QColor(Qt.darkBlue)), Qt.ForegroundRole) + self.setItemData(self.count() - 1, QBrush(QColor(Qt.blue).lighter(190)), Qt.BackgroundRole) + item = self.model().item(self.count() - 1) item.setFlags(Qt.ItemIsEnabled) for i in range(self.mdlPersos.rowCount()): 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.setItemData(self.count() - 1, self.mdlPersos.name(i), Qt.ToolTipRole) - - + self._various = False - + if self._index or self._indexes: self.updateSelectedItem() - + def setCurrentModelIndex(self, index): self._indexes = None if index.column() != self._column: index = index.sibling(index.row(), self._column) self._index = index self.updateItems() - + def setCurrentModelIndexes(self, indexes): self._index = None - + idxes = [] for i in indexes: if i.isValid(): if i.column() != self._column: i = i.sibling(i.row(), self._column) idxes.append(i) - + if idxes != self._indexes: self._indexes = idxes self.updateItems() - + def update(self, topLeft, bottomRight): - + if self._updating: # We are currently putting data in the model, so no updates return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateSelectedItem() - + elif self._indexes: update = False for i in self._indexes: @@ -87,44 +89,44 @@ class cmbOutlinePersoChoser(QComboBox): update = True if update: self.updateSelectedItem() - + def getPOV(self, index): item = index.internalPointer() POV = item.data(self._column) return POV - + def selectPOV(self, POV): idx = self.findData(POV) if idx != -1: self.setCurrentIndex(idx) else: self.setCurrentIndex(0) - + def updateSelectedItem(self, idx1=None, idx2=None): - + if self._updating: return - + if self._index: POV = self.getPOV(self._index) self.selectPOV(POV) - + elif self._indexes: POVs = [] same = True - + for i in self._indexes: POVs.append(self.getPOV(i)) - + for POV in POVs[1:]: if POV != POVs[0]: same = False break - + if same: self._various = False self.selectPOV(POVs[0]) - + else: if not self._various: self.insertItem(0, self.tr("Various")) @@ -134,19 +136,19 @@ class cmbOutlinePersoChoser(QComboBox): self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self._various = True self.setCurrentIndex(0) - + else: self.setCurrentIndex(0) - + def submit(self, idx): if self._index: self.mdlOutline.setData(self._index, self.currentData()) - + elif self._indexes: if self._various and self.currentIndex() == 0: return - + self._updating = True for i in self._indexes: self.mdlOutline.setData(i, self.currentData()) - self._updating = False \ No newline at end of file + self._updating = False diff --git a/manuskript/ui/views/cmbOutlineStatusChoser.py b/manuskript/ui/views/cmbOutlineStatusChoser.py index 89d442d..5e13a98 100644 --- a/manuskript/ui/views/cmbOutlineStatusChoser.py +++ b/manuskript/ui/views/cmbOutlineStatusChoser.py @@ -1,12 +1,13 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QBrush +from PyQt5.QtWidgets import QComboBox + +from manuskript.enums import Outline class cmbOutlineStatusChoser(QComboBox): - def __init__(self, parent=None): QComboBox.__init__(self, parent) self.activated[int].connect(self.submit) @@ -15,26 +16,26 @@ class cmbOutlineStatusChoser(QComboBox): self._indexes = None self._updating = False self._various = False - + def setModels(self, mdlStatus, mdlOutline): self.mdlStatus = mdlStatus self.mdlStatus.dataChanged.connect(self.updateItems) self.mdlOutline = mdlOutline self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - + def updateItems(self): self.clear() for i in range(self.mdlStatus.rowCount()): item = self.mdlStatus.item(i, 0) if item: self.addItem(item.text()) - + self._various = False - + if self._index or self._indexes: self.updateSelectedItem() - + def setCurrentModelIndex(self, index): self._indexes = None if index.column() != self._column: @@ -42,30 +43,30 @@ class cmbOutlineStatusChoser(QComboBox): self._index = index self.updateItems() self.updateSelectedItem() - + def setCurrentModelIndexes(self, indexes): self._indexes = [] self._index = None - + for i in indexes: if i.isValid(): if i.column() != self._column: i = i.sibling(i.row(), self._column) self._indexes.append(i) - + self.updateItems() self.updateSelectedItem() - + def update(self, topLeft, bottomRight): - + if self._updating: # We are currently putting data in the model, so no updates return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateSelectedItem() - + elif self._indexes: update = False for i in self._indexes: @@ -73,39 +74,39 @@ class cmbOutlineStatusChoser(QComboBox): update = True if update: self.updateSelectedItem() - + def getStatus(self, index): item = index.internalPointer() status = item.data(self._column) - if not status: + if not status: status = 0 return int(status) - + def updateSelectedItem(self): - + if self._updating: return - + if self._index: status = self.getStatus(self._index) self.setCurrentIndex(status) - + elif self._indexes: statuses = [] same = True - + for i in self._indexes: statuses.append(self.getStatus(i)) - + for s in statuses[1:]: if s != statuses[0]: same = False break - + if same: self._various = False self.setCurrentIndex(statuses[0]) - + else: if not self._various: self.insertItem(0, self.tr("Various")) @@ -115,24 +116,24 @@ class cmbOutlineStatusChoser(QComboBox): self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self._various = True self.setCurrentIndex(0) - + else: self.setCurrentIndex(0) - + def submit(self, idx): if self._index: self.mdlOutline.setData(self._index, self.currentIndex()) - + elif self._indexes: value = self.currentIndex() - + if self._various: if value == 0: return - + value -= 1 - + self._updating = True for i in self._indexes: self.mdlOutline.setData(i, value) - self._updating = False \ No newline at end of file + self._updating = False diff --git a/manuskript/ui/views/cmbOutlineTypeChoser.py b/manuskript/ui/views/cmbOutlineTypeChoser.py index 1144d50..829cf7e 100644 --- a/manuskript/ui/views/cmbOutlineTypeChoser.py +++ b/manuskript/ui/views/cmbOutlineTypeChoser.py @@ -1,12 +1,13 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon, QBrush +from PyQt5.QtWidgets import QComboBox + +from manuskript.enums import Outline class cmbOutlineTypeChoser(QComboBox): - def __init__(self, parent=None): QComboBox.__init__(self, parent) self.activated[int].connect(self.submit) @@ -15,27 +16,27 @@ class cmbOutlineTypeChoser(QComboBox): self._indexes = None self._updating = False self._various = False - + def setModel(self, mdlOutline): self.mdlOutline = mdlOutline self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - + def updateItems(self): self.clear() types = [ ("t2t", self.tr("Txt2Tags"), "text-x-generic"), ("html", self.tr("Rich Text (html)"), "text-html"), ("txt", self.tr("Plain Text"), "text-x-generic"), - ] + ] for t in types: self.addItem(QIcon.fromTheme(t[2]), t[1], t[0]) - + self._various = False - + if self._index or self._indexes: self.updateSelectedItem() - + def setCurrentModelIndex(self, index): self._indexes = None if index.column() != self._column: @@ -45,11 +46,11 @@ class cmbOutlineTypeChoser(QComboBox): self.setEnabled(index.internalPointer().type() in ["t2t", "html", "txt"]) self.updateItems() self.updateSelectedItem() - + def setCurrentModelIndexes(self, indexes): self._indexes = [] self._index = None - + hasText = False for i in indexes: if i.isValid(): @@ -58,22 +59,22 @@ class cmbOutlineTypeChoser(QComboBox): self._indexes.append(i) if i.internalPointer().type() in ["t2t", "html", "txt"]: hasText = True - + self.setEnabled(hasText) - + self.updateItems() self.updateSelectedItem() - + def update(self, topLeft, bottomRight): - + if self._updating: # We are currently putting data in the model, so no updates return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateSelectedItem() - + elif self._indexes: update = False for i in self._indexes: @@ -81,40 +82,40 @@ class cmbOutlineTypeChoser(QComboBox): update = True if update: self.updateSelectedItem() - + def getType(self, index): item = index.internalPointer() return item.type() - + def updateSelectedItem(self): - + if self._updating: return - + if self._index: _type = self.getType(self._index) i = self.findData(_type) if i != -1: self.setCurrentIndex(i) - + elif self._indexes: types = [] same = True - + for i in self._indexes: types.append(self.getType(i)) - + for t in types[1:]: if t != types[0]: same = False break - + if same: self._various = False i = self.findData(types[0]) if i != -1: self.setCurrentIndex(i) - + else: if not self._various: self.insertItem(0, self.tr("Various")) @@ -124,21 +125,21 @@ class cmbOutlineTypeChoser(QComboBox): self.setItemData(0, QBrush(Qt.darkGray), Qt.ForegroundRole) self._various = True self.setCurrentIndex(0) - + else: self.setCurrentIndex(0) - + def submit(self, idx): if self._index: self.mdlOutline.setData(self._index, self.currentData()) - + elif self._indexes: value = self.currentData() - + if self._various and self.currentIndex() == 0: return - + self._updating = True for i in self._indexes: self.mdlOutline.setData(i, value) - self._updating = False \ No newline at end of file + self._updating = False diff --git a/manuskript/ui/views/corkDelegate.py b/manuskript/ui/views/corkDelegate.py index d7b9ed0..c8aadae 100644 --- a/manuskript/ui/views/corkDelegate.py +++ b/manuskript/ui/views/corkDelegate.py @@ -1,14 +1,18 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -from random import randint -import settings +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import QSize, Qt, QRect, QPoint +from PyQt5.QtGui import QMouseEvent, QFont, QPalette, QRegion, QFontMetrics, QColor, QIcon +from PyQt5.QtWidgets import QStyledItemDelegate, QLineEdit, QPlainTextEdit, QFrame, qApp, QStyle + +from manuskript 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): - def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) self.factor = settings.corkSizeFactor / 100. @@ -16,22 +20,22 @@ class corkDelegate(QStyledItemDelegate): self.lastPos = None self.editing = None self.margin = 5 - + def setCorkSizeFactor(self, v): self.factor = v / 100. - + def sizeHint(self, option, index): return self.defaultSize * self.factor - + def editorEvent(self, event, model, option, index): # We catch the mouse position in the widget to know which part to edit 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) - + def createEditor(self, parent, option, index): self.updateRects(option, index) - + if self.mainLineRect.contains(self.lastPos): # One line summary self.editing = Outline.summarySentance @@ -44,7 +48,7 @@ class corkDelegate(QStyledItemDelegate): f.setItalic(True) edt.setFont(f) return edt - + elif self.titleRect.contains(self.lastPos): # Title self.editing = Outline.title @@ -52,13 +56,13 @@ class corkDelegate(QStyledItemDelegate): edt.setFocusPolicy(Qt.StrongFocus) edt.setFrame(False) f = QFont(option.font) - #f.setPointSize(f.pointSize() + 1) + # f.setPointSize(f.pointSize() + 1) f.setBold(True) edt.setFont(f) edt.setAlignment(Qt.AlignCenter) - #edt.setGeometry(self.titleRect) + # edt.setGeometry(self.titleRect) return edt - + else: # self.mainTextRect.contains(self.lastPos): # Summary self.editing = Outline.summaryFull @@ -67,54 +71,53 @@ class corkDelegate(QStyledItemDelegate): edt.setFrameShape(QFrame.NoFrame) edt.setPlaceholderText(self.tr("Full summary")) return edt - - + def updateEditorGeometry(self, editor, option, index): - + if self.editing == Outline.summarySentance: # One line summary editor.setGeometry(self.mainLineRect) - + elif self.editing == Outline.title: # Title editor.setGeometry(self.titleRect) - + elif self.editing == Outline.summaryFull: # Summary editor.setGeometry(self.mainTextRect) - + def setEditorData(self, editor, index): item = index.internalPointer() - + if self.editing == Outline.summarySentance: # One line summary editor.setText(item.data(Outline.summarySentance.value)) - + elif self.editing == Outline.title: # Title editor.setText(index.data()) - + elif self.editing == Outline.summaryFull: # Summary editor.setPlainText(item.data(Outline.summaryFull.value)) - + def setModelData(self, editor, model, index): - + if self.editing == Outline.summarySentance: # One line summary model.setData(index.sibling(index.row(), Outline.summarySentance.value), editor.text()) - + elif self.editing == Outline.title: # Title model.setData(index, editor.text(), Outline.title.value) - + elif self.editing == Outline.summaryFull: # Summary model.setData(index.sibling(index.row(), Outline.summaryFull.value), editor.toPlainText()) - + def updateRects(self, option, index): margin = self.margin - iconSize = max(16*self.factor, 12) + iconSize = max(16 * self.factor, 12) item = index.internalPointer() self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin) 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.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0), 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())) self.topRect = QRect(self.itemRect.topLeft(), self.bottomRect.topRight()) self.mainRect = self.bottomRect.adjusted(margin, margin, -margin, -margin) @@ -130,50 +133,50 @@ class corkDelegate(QStyledItemDelegate): self.mainRect.topRight() + QPoint(0, iconSize)) self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin), self.mainRect.bottomRight()) - if not item.data(Outline.summarySentance.value) : + if not item.data(Outline.summarySentance.value): self.mainTextRect.setTopLeft(self.mainLineRect.topLeft()) if item.data(Outline.label.value) in ["", "0"]: self.titleRect.setBottomRight(self.labelRect.bottomRight() - QPoint(self.margin, self.margin)) - + def paint(self, p, option, index): - #QStyledItemDelegate.paint(self, p, option, index) + # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return - + item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) - + style = qApp.style() - + def _rotate(angle): p.translate(self.mainRect.center()) p.rotate(angle) p.translate(-self.mainRect.center()) - + # Draw background 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: cg = QPalette.Inactive - - # Selection + + # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) p.drawRoundedRect(option.rect, 12, 12) p.restore() - - # Stack + + # Stack if item.isFolder() and item.childCount() > 0: p.save() p.setBrush(Qt.white) 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() - - # Background + + # Background itemRect = self.itemRect p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": @@ -187,8 +190,8 @@ class corkDelegate(QStyledItemDelegate): p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() - - # Title bar + + # Title bar topRect = self.topRect p.save() if item.isFolder(): @@ -199,10 +202,10 @@ class corkDelegate(QStyledItemDelegate): p.setBrush(color) p.setClipRegion(QRegion(topRect)) p.drawRoundedRect(itemRect, 10, 10) - #p.drawRect(topRect) + # p.drawRect(topRect) p.restore() - - # Label color + + # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] @@ -210,23 +213,23 @@ class corkDelegate(QStyledItemDelegate): p.setBrush(color) p.setClipRegion(QRegion(self.labelRect)) p.drawRoundedRect(itemRect, 10, 10) - #p.drawRect(topRect) + # p.drawRect(topRect) p.restore() p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft()) - - # One line summary background + + # One line summary background lineSummary = item.data(Outline.summarySentance.value) fullSummary = item.data(Outline.summaryFull.value) if lineSummary or not fullSummary: m = self.margin - r = self.mainLineRect.adjusted(-m, -m, m, m/2) + r = self.mainLineRect.adjusted(-m, -m, m, m / 2) p.save() p.setPen(Qt.NoPen) p.setBrush(QColor("#EEE")) p.drawRect(r) p.restore() - - # Border + + # Border p.save() p.setBrush(Qt.NoBrush) pen = p.pen() @@ -239,8 +242,7 @@ class corkDelegate(QStyledItemDelegate): p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() - - + # Draw the icon iconRect = self.iconRect mode = QIcon.Normal @@ -248,13 +250,13 @@ class corkDelegate(QStyledItemDelegate): mode = QIcon.Disabled elif option.state & style.State_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()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) - + # Draw title p.save() text = index.data() @@ -266,23 +268,23 @@ class corkDelegate(QStyledItemDelegate): col = Qt.black p.setPen(col) f = QFont(option.font) - #f.setPointSize(f.pointSize() + 1) + # f.setPointSize(f.pointSize() + 1) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width()) p.drawText(titleRect, Qt.AlignCenter, elidedText) p.restore() - + # Draw the line bottomRect = self.bottomRect p.save() - #p.drawLine(itemRect.x(), iconRect.bottom() + margin, - #itemRect.right(), iconRect.bottom() + margin) + # p.drawLine(itemRect.x(), iconRect.bottom() + margin, + # itemRect.right(), iconRect.bottom() + margin) p.drawLine(bottomRect.topLeft(), bottomRect.topRight()) p.restore() - - # Lines + + # Lines if True: p.save() p.setPen(QColor("#EEE")) @@ -293,7 +295,7 @@ class corkDelegate(QStyledItemDelegate): p.drawLine(l, QPoint(self.mainTextRect.right(), l.y())) l.setY(l.y() + h) p.restore() - + # Draw status mainRect = self.mainRect status = item.data(Outline.status.value) @@ -310,9 +312,9 @@ class corkDelegate(QStyledItemDelegate): _rotate(-35) p.drawText(mainRect, Qt.AlignCenter, it.text()) p.restore() - - # Draw Summary - # One line + + # Draw Summary + # One line if lineSummary: p.save() f = QFont(option.font) @@ -322,12 +324,12 @@ class corkDelegate(QStyledItemDelegate): elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText) p.restore() - - # Full summary + + # Full summary if fullSummary: p.setFont(option.font) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary) - - #Debug - #for r in [self.itemRect, self.iconRect, self.titleRect, self.bottomRect, self.mainLineRect, self.mainTextRect]: - #p.drawRect(r) \ No newline at end of file + + # Debug + # for r in [self.itemRect, self.iconRect, self.titleRect, self.bottomRect, self.mainLineRect, self.mainTextRect]: + # p.drawRect(r) diff --git a/manuskript/ui/views/corkView.py b/manuskript/ui/views/corkView.py index 71bdbea..aeb340f 100644 --- a/manuskript/ui/views/corkView.py +++ b/manuskript/ui/views/corkView.py @@ -1,21 +1,19 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -from ui.views.corkDelegate import * -from ui.views.dndView import * -from ui.views.outlineBasics import * -import settings +# --!-- coding: utf8 --!-- +from PyQt5.QtWidgets import QListView + +from manuskript import settings +from manuskript.ui.views.corkDelegate import corkDelegate +from manuskript.ui.views.dndView import dndView +from manuskript.ui.views.outlineBasics import outlineBasics + class corkView(QListView, dndView, outlineBasics): - def __init__(self, parent=None): QListView.__init__(self, parent) dndView.__init__(self, parent) outlineBasics.__init__(self, parent) - + self.setResizeMode(QListView.Adjust) self.setWrapping(True) self.setItemDelegate(corkDelegate()) @@ -24,7 +22,7 @@ class corkView(QListView, dndView, outlineBasics): self.setFlow(self.LeftToRight) self.setSelectionBehavior(self.SelectRows) self.updateBackground() - + def updateBackground(self): self.setStyleSheet("""QListView {{ background:{color}; @@ -32,12 +30,12 @@ class corkView(QListView, dndView, outlineBasics): }}""".format( color=settings.corkBackground["color"], url=settings.corkBackground["image"] - )) - + )) + def dragMoveEvent(self, event): dndView.dragMoveEvent(self, event) QListView.dragMoveEvent(self, event) - + def mouseReleaseEvent(self, event): QListView.mouseReleaseEvent(self, event) - outlineBasics.mouseReleaseEvent(self, event) \ No newline at end of file + outlineBasics.mouseReleaseEvent(self, event) diff --git a/manuskript/ui/views/dndView.py b/manuskript/ui/views/dndView.py index 9c3f40e..c028964 100644 --- a/manuskript/ui/views/dndView.py +++ b/manuskript/ui/views/dndView.py @@ -1,25 +1,20 @@ #!/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): - def __init__(self, parent=None): - #QAbstractItemView.__init__(self, parent) + # QAbstractItemView.__init__(self, parent) self.setDragDropMode(self.DragDrop) self.setDefaultDropAction(Qt.MoveAction) self.setSelectionMode(self.ExtendedSelection) - + def dragMoveEvent(self, event): - #return QAbstractItemView.dragMoveEvent(self, event) - #print(a) + # return QAbstractItemView.dragMoveEvent(self, event) + # print(a) if event.keyboardModifiers() & Qt.ControlModifier: event.setDropAction(Qt.CopyAction) else: - event.setDropAction(Qt.MoveAction) \ No newline at end of file + event.setDropAction(Qt.MoveAction) diff --git a/manuskript/ui/views/lineEditView.py b/manuskript/ui/views/lineEditView.py index 559c198..67cedcd 100644 --- a/manuskript/ui/views/lineEditView.py +++ b/manuskript/ui/views/lineEditView.py @@ -1,12 +1,12 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * +# --!-- coding: utf8 --!-- +from PyQt5.QtWidgets import QLineEdit + +from manuskript.enums import Outline +from manuskript.functions import toString + class lineEditView(QLineEdit): - def __init__(self, parent=None): QLineEdit.__init__(self, parent) self._column = Outline.title.value @@ -14,14 +14,14 @@ class lineEditView(QLineEdit): self._index = None self._placeholderText = None self._updating = False - + def setModel(self, model): self._model = model self._model.dataChanged.connect(self.update) - + def setColumn(self, col): self._column = col - + def setCurrentModelIndex(self, index): self._indexes = None if index.isValid(): @@ -29,49 +29,49 @@ class lineEditView(QLineEdit): index = index.sibling(index.row(), self._column) self._index = index self._model = index.model() - #self.item = index.internalPointer() - if self._placeholderText != None: + # self.item = index.internalPointer() + if self._placeholderText is not None: self.setPlaceholderText(self._placeholderText) self.textEdited.connect(self.submit) self.updateText() - + def setCurrentModelIndexes(self, indexes): self._indexes = [] self._index = None - + for i in indexes: if i.isValid(): if i.column() != self._column: i = i.sibling(i.row(), self._column) self._indexes.append(i) - + self.textEdited.connect(self.submit) self.updateText() - + def submit(self): if self._index: - #item = self._index.internalPointer() + # item = self._index.internalPointer() if self.text() != self._model.data(self._index): self._model.setData(self._index, self.text()) - + elif self._indexes: self._updating = True for i in self._indexes: - #item = i.internalPointer() + # item = i.internalPointer() if self.text() != self._model.data(i): self._model.setData(i, self.text()) self._updating = False - + def update(self, topLeft, bottomRight): - + if self._updating: # We are currently putting data in the model, so no updates return - + if self._index: if topLeft.row() <= self._index.row() <= bottomRight.row(): self.updateText() - + elif self._indexes: update = False for i in self._indexes: @@ -79,35 +79,34 @@ class lineEditView(QLineEdit): update = True if update: self.updateText() - + def updateText(self): if self._index: - #item = self._index.internalPointer() - #txt = toString(item.data(self._column)) + # item = self._index.internalPointer() + # txt = toString(item.data(self._column)) txt = toString(self._model.data(self._index)) if self.text() != txt: self.setText(txt) - + elif self._indexes: t = [] same = True for i in self._indexes: - #item = i.internalPointer() - #t.append(toString(item.data(self._column))) + # item = i.internalPointer() + # t.append(toString(item.data(self._column))) t.append(toString(self._model.data(i))) for t2 in t[1:]: if t2 != t[0]: same = False break - + if same: self.setText(t[0]) else: self.setText("") - + if not self._placeholderText: self._placeholderText = self.placeholderText() - + self.setPlaceholderText(self.tr("Various")) - \ No newline at end of file diff --git a/manuskript/ui/views/metadataView.py b/manuskript/ui/views/metadataView.py index 58b444a..78916d9 100644 --- a/manuskript/ui/views/metadataView.py +++ b/manuskript/ui/views/metadataView.py @@ -1,12 +1,12 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from ui.views.metadataView_ui import * +# --!-- coding: utf8 --!-- +from PyQt5.QtWidgets import QWidget + +from manuskript.enums import Outline +from manuskript.ui.views.metadataView_ui import Ui_metadataView + class metadataView(QWidget, Ui_metadataView): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) @@ -15,37 +15,37 @@ class metadataView(QWidget, Ui_metadataView): self.txtSummaryFull.setColumn(Outline.summaryFull.value) self.txtNotes.setColumn(Outline.notes.value) self.revisions.setEnabled(False) - + def setModels(self, mdlOutline, mdlPersos, mdlLabels, mdlStatus): self.properties.setModels(mdlOutline, mdlPersos, mdlLabels, mdlStatus) self.txtSummarySentance.setModel(mdlOutline) self.txtSummaryFull.setModel(mdlOutline) self.txtNotes.setModel(mdlOutline) self.revisions.setModel(mdlOutline) - + def getIndexes(self, sourceView): - "Returns a list of indexes from list of QItemSelectionRange" + """Returns a list of indexes from list of QItemSelectionRange""" indexes = [] - + for i in sourceView.selectionModel().selection().indexes(): - if i.column() != 0: + if i.column() != 0: continue - + if i not in indexes: indexes.append(i) - + return indexes - + def selectionChanged(self, sourceView): indexes = self.getIndexes(sourceView) - + if self._lastIndexes == indexes: return - + if len(indexes) == 0: self.setEnabled(False) self.revisions.setEnabled(False) - + elif len(indexes) == 1: self.setEnabled(True) idx = indexes[0] @@ -54,25 +54,25 @@ class metadataView(QWidget, Ui_metadataView): self.txtNotes.setCurrentModelIndex(idx) self.revisions.setEnabled(True) self.revisions.setCurrentModelIndex(idx) - + else: self.setEnabled(True) self.txtSummarySentance.setCurrentModelIndexes(indexes) self.txtSummaryFull.setCurrentModelIndexes(indexes) self.txtNotes.setCurrentModelIndexes(indexes) self.revisions.setEnabled(False) - + self.properties.selectionChanged(sourceView) self._lastIndexes = indexes - + def setDict(self, d): self.txtNotes.setDict(d) self.txtSummaryFull.setDict(d) - + def toggleSpellcheck(self, v): self.txtNotes.toggleSpellcheck(v) self.txtSummaryFull.toggleSpellcheck(v) - + def saveState(self): return [ self.grpProperties.saveState(), @@ -80,10 +80,10 @@ class metadataView(QWidget, Ui_metadataView): self.grpNotes.saveState(), self.grpRevisions.saveState(), self.revisions.saveState() - ] - + ] + def restoreState(self, state): self.grpProperties.restoreState(state[0]) self.grpSummary.restoreState(state[1]) self.grpNotes.restoreState(state[2]) - self.grpRevisions.restoreState(state[3]) \ No newline at end of file + self.grpRevisions.restoreState(state[3]) diff --git a/manuskript/ui/views/metadataView_ui.py b/manuskript/ui/views/metadataView_ui.py index 9a0f4b8..4f891f4 100644 --- a/manuskript/ui/views/metadataView_ui.py +++ b/manuskript/ui/views/metadataView_ui.py @@ -2,7 +2,7 @@ # 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! @@ -83,9 +83,9 @@ class Ui_metadataView(object): self.grpNotes.setTitle(_translate("metadataView", "Notes / References")) self.grpRevisions.setTitle(_translate("metadataView", "Revisions")) -from ui.collapsibleGroupBox2 import collapsibleGroupBox2 -from ui.views.propertiesView import propertiesView -from ui.views.textEditView import textEditView -from ui.revisions import revisions -from ui.views.textEditCompleter import textEditCompleter -from ui.views.lineEditView import lineEditView +from manuskript.ui.collapsibleGroupBox2 import collapsibleGroupBox2 +from manuskript.ui.revisions import revisions +from manuskript.ui.views.lineEditView import lineEditView +from manuskript.ui.views.propertiesView import propertiesView +from manuskript.ui.views.textEditCompleter import textEditCompleter +from manuskript.ui.views.textEditView import textEditView diff --git a/manuskript/ui/views/metadataView_ui.ui b/manuskript/ui/views/metadataView_ui.ui index eb1ebae..abb0cad 100644 --- a/manuskript/ui/views/metadataView_ui.ui +++ b/manuskript/ui/views/metadataView_ui.ui @@ -137,34 +137,34 @@ textEditView QTextEdit -
    ui.views.textEditView.h
    +
    manuskript.ui.views.textEditView.h
    lineEditView QLineEdit -
    ui.views.lineEditView.h
    +
    manuskript.ui.views.lineEditView.h
    collapsibleGroupBox2 QGroupBox -
    ui.collapsibleGroupBox2.h
    +
    manuskript.ui.collapsibleGroupBox2.h
    1
    propertiesView QWidget -
    ui.views.propertiesView.h
    +
    manuskript.ui.views.propertiesView.h
    1
    textEditCompleter QTextEdit -
    ui.views.textEditCompleter.h
    +
    manuskript.ui.views.textEditCompleter.h
    revisions QWidget -
    ui.revisions.h
    +
    manuskript.ui.revisions.h
    1
    diff --git a/manuskript/ui/views/outlineBasics.py b/manuskript/ui/views/outlineBasics.py index 89b2f8b..4d548f6 100644 --- a/manuskript/ui/views/outlineBasics.py +++ b/manuskript/ui/views/outlineBasics.py @@ -1,68 +1,73 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -from models.outlineModel import * -import settings +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt, QSignalMapper +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QAbstractItemView, qApp, QMenu, QAction + +from manuskript 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): - def __init__(self, parent=None): pass - + def getSelection(self): sel = [] for i in self.selectedIndexes(): - if i.column() != 0: continue - if not i in sel: sel.append(i) + if i.column() != 0: + continue + if not i in sel: + sel.append(i) return sel - + def mouseReleaseEvent(self, event): if event.button() == Qt.RightButton: self.menu = self.makePopupMenu() self.menu.popup(event.globalPos()) else: QAbstractItemView.mouseReleaseEvent(self, event) - + def makePopupMenu(self): index = self.currentIndex() sel = self.getSelection() clipboard = qApp.clipboard() - + menu = QMenu(self) - + # Add / remove items self.actAddFolder = QAction(QIcon.fromTheme("folder-new"), qApp.translate("outlineBasics", "New Folder"), menu) self.actAddFolder.triggered.connect(self.addFolder) menu.addAction(self.actAddFolder) - + self.actAddText = QAction(QIcon.fromTheme("document-new"), qApp.translate("outlineBasics", "New Text"), menu) self.actAddText.triggered.connect(self.addText) menu.addAction(self.actAddText) - + self.actDelete = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "Delete"), menu) self.actDelete.triggered.connect(self.delete) menu.addAction(self.actDelete) - + menu.addSeparator() - + # Copy, cut, paste self.actCopy = QAction(QIcon.fromTheme("edit-copy"), qApp.translate("outlineBasics", "Copy"), menu) self.actCopy.triggered.connect(self.copy) menu.addAction(self.actCopy) - + self.actCut = QAction(QIcon.fromTheme("edit-cut"), qApp.translate("outlineBasics", "Cut"), menu) self.actCut.triggered.connect(self.cut) menu.addAction(self.actCut) - + self.actPaste = QAction(QIcon.fromTheme("edit-paste"), qApp.translate("outlineBasics", "Paste"), menu) self.actPaste.triggered.connect(self.paste) menu.addAction(self.actPaste) - + menu.addSeparator() - + # POV self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), menu) mw = mainWindow() @@ -70,33 +75,33 @@ class outlineBasics(QAbstractItemView): a.triggered.connect(lambda: self.setPOV("")) self.menuPOV.addAction(a) self.menuPOV.addSeparator() - + menus = [] for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]: m = QMenu(i, self.menuPOV) menus.append(m) self.menuPOV.addMenu(m) - + mpr = QSignalMapper(self.menuPOV) for i in range(mw.mdlPersos.rowCount()): a = QAction(mw.mdlPersos.icon(i), mw.mdlPersos.name(i), self.menuPOV) a.triggered.connect(mpr.map) mpr.setMapping(a, int(mw.mdlPersos.ID(i))) - + imp = toInt(mw.mdlPersos.importance(i)) - - menus[2-imp].addAction(a) - + + menus[2 - imp].addAction(a) + mpr.mapped.connect(self.setPOV) menu.addMenu(self.menuPOV) - + # Status self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"), menu) - #a = QAction(QIcon.fromTheme("dialog-no"), qApp.translate("outlineBasics", "None"), self.menuStatus) - #a.triggered.connect(lambda: self.setStatus("")) - #self.menuStatus.addAction(a) - #self.menuStatus.addSeparator() - + # a = QAction(QIcon.fromTheme("dialog-no"), qApp.translate("outlineBasics", "None"), self.menuStatus) + # a.triggered.connect(lambda: self.setStatus("")) + # self.menuStatus.addAction(a) + # self.menuStatus.addSeparator() + mpr = QSignalMapper(self.menuStatus) for i in range(mw.mdlStatus.rowCount()): a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus) @@ -105,29 +110,28 @@ class outlineBasics(QAbstractItemView): self.menuStatus.addAction(a) mpr.mapped.connect(self.setStatus) menu.addMenu(self.menuStatus) - + # Labels self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"), menu) mpr = QSignalMapper(self.menuLabel) for i in range(mw.mdlLabels.rowCount()): a = QAction(mw.mdlLabels.item(i, 0).icon(), - mw.mdlLabels.item(i, 0).text(), + mw.mdlLabels.item(i, 0).text(), self.menuLabel) a.triggered.connect(mpr.map) mpr.setMapping(a, i) self.menuLabel.addAction(a) mpr.mapped.connect(self.setLabel) menu.addMenu(self.menuLabel) - - + 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) - + if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder(): self.actAddFolder.setEnabled(False) self.actAddText.setEnabled(False) - + if len(sel) == 0: self.actCopy.setEnabled(False) self.actCut.setEnabled(False) @@ -135,53 +139,53 @@ class outlineBasics(QAbstractItemView): self.menuPOV.setEnabled(False) self.menuStatus.setEnabled(False) self.menuLabel.setEnabled(False) - + return menu - + def addFolder(self): self.addItem("folder") - + def addText(self): self.addItem("text") - + def addItem(self, _type="folder"): if len(self.selectedIndexes()) == 0: parent = self.rootIndex() else: parent = self.currentIndex() - + if _type == "text": _type = settings.defaultTextType - + item = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=_type) self.model().appendItem(item, parent) - + def copy(self): mimeData = self.model().mimeData(self.selectionModel().selectedIndexes()) qApp.clipboard().setMimeData(mimeData) - + def paste(self): index = self.currentIndex() if len(self.getSelection()) == 0: index = self.rootIndex() data = qApp.clipboard().mimeData() self.model().dropMimeData(data, Qt.CopyAction, -1, 0, index) - + def cut(self): self.copy() self.delete() - + def delete(self): self.model().removeIndexes(self.getSelection()) - + def setPOV(self, POV): for i in self.getSelection(): self.model().setData(i.sibling(i.row(), Outline.POV.value), str(POV)) - + def setStatus(self, status): for i in self.getSelection(): self.model().setData(i.sibling(i.row(), Outline.status.value), str(status)) - + def setLabel(self, label): for i in self.getSelection(): - self.model().setData(i.sibling(i.row(), Outline.label.value), str(label)) \ No newline at end of file + self.model().setData(i.sibling(i.row(), Outline.label.value), str(label)) diff --git a/manuskript/ui/views/outlineDelegates.py b/manuskript/ui/views/outlineDelegates.py index 96fe57d..1dcd0c5 100644 --- a/manuskript/ui/views/outlineDelegates.py +++ b/manuskript/ui/views/outlineDelegates.py @@ -1,49 +1,53 @@ #!/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): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) self._view = None - + def setView(self, view): self._view = view - + def paint(self, painter, option, index): - + item = index.internalPointer() colors = outlineItemColors(item) - + style = qApp.style() - + opt = QStyleOptionViewItem(option) self.initStyleOption(opt, index) - + iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt) textRect = style.subElementRect(style.SE_ItemViewItemText, opt) - + # Background style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter) - + if settings.viewSettings["Outline"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected: - + col = colors[settings.viewSettings["Outline"]["Background"]] - + if col != QColor(Qt.transparent): col2 = QColor(Qt.white) if opt.state & QStyle.State_Selected: col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color() col = mixColors(col, col2, .2) - + painter.save() painter.setBrush(col) painter.setPen(Qt.NoPen) - + rect = opt.rect if self._view: r2 = self._view.visualRect(index) @@ -51,10 +55,10 @@ class outlineTitleDelegate(QStyledItemDelegate): rect.setLeft(r2.left()) rect.setTop(r2.top()) rect.setBottom(r2.bottom()) - + painter.drawRoundedRect(rect, 5, 5) painter.restore() - + # Icon mode = QIcon.Normal if not opt.state & QStyle.State_Enabled: @@ -68,7 +72,7 @@ class outlineTitleDelegate(QStyledItemDelegate): colorifyPixmap(icon, color) opt.icon = QIcon(icon) opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state) - + # Text if opt.text: painter.save() @@ -82,49 +86,49 @@ class outlineTitleDelegate(QStyledItemDelegate): fm = QFontMetrics(f) elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width()) painter.drawText(textRect, Qt.AlignLeft, elidedText) - + painter.restore() - - #QStyledItemDelegate.paint(self, painter, option, index) + + # QStyledItemDelegate.paint(self, painter, option, index) + class outlinePersoDelegate(QStyledItemDelegate): - def __init__(self, mdlPersos, parent=None): QStyledItemDelegate.__init__(self, parent) self.mdlPersos = mdlPersos - + def sizeHint(self, option, index): - #s = QStyledItemDelegate.sizeHint(self, option, index) - + # s = QStyledItemDelegate.sizeHint(self, option, index) + item = QModelIndex() for i in range(self.mdlPersos.rowCount()): if self.mdlPersos.ID(i) == index.data(): item = self.mdlPersos.index(i, Perso.name.value) - + opt = QStyleOptionViewItem(option) self.initStyleOption(opt, item) s = QStyledItemDelegate.sizeHint(self, opt, item) - + if s.width() > 200: s.setWidth(200) elif s.width() < 100: s.setWidth(100) return s + QSize(18, 0) - + def createEditor(self, parent, option, index): item = index.internalPointer() - #if item.isFolder(): # No POV for folders - #return - + # if item.isFolder(): # No POV for folders + # return + editor = QComboBox(parent) editor.setAutoFillBackground(True) editor.setFrame(False) return editor - + def setEditorData(self, editor, index): - #editor.addItem("") + # editor.addItem("") editor.addItem(QIcon.fromTheme("dialog-no"), self.tr("None")) - + l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] for importance in range(3): editor.addItem(l[importance]) @@ -134,112 +138,110 @@ class outlinePersoDelegate(QStyledItemDelegate): item.setFlags(Qt.ItemIsEnabled) for i in range(self.mdlPersos.rowCount()): imp = toInt(self.mdlPersos.importance(i)) - if not 2-imp == importance: continue - - #try: + if not 2 - imp == importance: continue + + # try: 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) - #except: - #pass - + # except: + # pass + editor.setCurrentIndex(editor.findData(index.data())) editor.showPopup() - + def setModelData(self, editor, model, index): val = editor.currentData() model.setData(index, val) - + def paint(self, painter, option, index): ##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) - + item = QModelIndex() for i in range(self.mdlPersos.rowCount()): if self.mdlPersos.ID(i) == index.data(): item = self.mdlPersos.index(i, Perso.name.value) - + opt = QStyleOptionViewItem(option) self.initStyleOption(opt, item) - + 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]: opt = QStyleOptionComboBox() opt.rect = option.rect r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow) option.rect = r qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter) - - + + class outlineCompileDelegate(QStyledItemDelegate): - def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) - + def displayText(self, value, locale): return "" - - + + class outlineGoalPercentageDelegate(QStyledItemDelegate): def __init__(self, rootIndex=None, parent=None): QStyledItemDelegate.__init__(self, parent) self.rootIndex = rootIndex - + def sizeHint(self, option, index): sh = QStyledItemDelegate.sizeHint(self, option, index) - #if sh.width() > 50: + # if sh.width() > 50: sh.setWidth(100) return sh - + def paint(self, painter, option, index): if not index.isValid(): return QStyledItemDelegate.paint(self, painter, option, index) - + QStyledItemDelegate.paint(self, painter, option, index) - + item = index.internalPointer() - + if not item.data(Outline.goal.value): return - + p = toFloat(item.data(Outline.goalPercentage.value)) typ = item.data(Outline.type.value) - + level = item.level() if self.rootIndex and self.rootIndex.isValid(): level -= self.rootIndex.internalPointer().level() + 1 - + 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() - + rect = option.rect.adjusted(margin, margin, -margin, -margin) - + # Move rect.translate(level * rect.width() / 10, 0) rect.setWidth(rect.width() - level * rect.width() / 10) - + rect.setHeight(height) rect.setTop(option.rect.top() + (option.rect.height() - height) / 2) - - drawProgress(painter, rect, p) # from functions - + + drawProgress(painter, rect, p) # from functions + painter.restore() - + def displayText(self, value, locale): return "" - - + + class outlineStatusDelegate(QStyledItemDelegate): - def __init__(self, mdlStatus, parent=None): QStyledItemDelegate.__init__(self, parent) self.mdlStatus = mdlStatus - + def sizeHint(self, option, index): s = QStyledItemDelegate.sizeHint(self, option, index) if s.width() > 150: @@ -247,52 +249,51 @@ class outlineStatusDelegate(QStyledItemDelegate): elif s.width() < 50: s.setWidth(50) return s + QSize(18, 0) - + def createEditor(self, parent, option, index): editor = QComboBox(parent) editor.setAutoFillBackground(True) editor.setFrame(False) return editor - + def setEditorData(self, editor, index): for i in range(self.mdlStatus.rowCount()): editor.addItem(self.mdlStatus.item(i, 0).text()) - + val = index.internalPointer().data(Outline.status.value) if not val: val = 0 editor.setCurrentIndex(int(val)) editor.showPopup() - + def setModelData(self, editor, model, index): val = editor.currentIndex() model.setData(index, val) - + def displayText(self, value, locale): try: return self.mdlStatus.item(int(value), 0).text() except: return "" - + def 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"]: opt = QStyleOptionComboBox() opt.rect = option.rect r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow) option.rect = r qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter) - - + + class outlineLabelDelegate(QStyledItemDelegate): - def __init__(self, mdlLabels, parent=None): QStyledItemDelegate.__init__(self, parent) self.mdlLabels = mdlLabels - + def sizeHint(self, option, index): d = index.internalPointer().data(index.column(), Qt.DisplayRole) - if not d: + if not d: d = 0 item = self.mdlLabels.item(int(d), 0) idx = self.mdlLabels.indexFromItem(item) @@ -304,44 +305,44 @@ class outlineLabelDelegate(QStyledItemDelegate): elif s.width() < 50: s.setWidth(50) return s + QSize(18, 0) - + def createEditor(self, parent, option, index): item = index.internalPointer() editor = QComboBox(parent) - #editor.setAutoFillBackground(True) + # editor.setAutoFillBackground(True) editor.setFrame(False) return editor - + def setEditorData(self, editor, index): for i in range(self.mdlLabels.rowCount()): editor.addItem(self.mdlLabels.item(i, 0).icon(), self.mdlLabels.item(i, 0).text()) - + val = index.internalPointer().data(Outline.label.value) if not val: val = 0 editor.setCurrentIndex(int(val)) editor.showPopup() - + def setModelData(self, editor, model, index): val = editor.currentIndex() model.setData(index, val) - + def paint(self, painter, option, index): if not index.isValid(): return QStyledItemDelegate.paint(self, painter, option, index) else: item = index.internalPointer() - + d = item.data(index.column(), Qt.DisplayRole) - if not d: + if not d: d = 0 - + lbl = self.mdlLabels.item(int(d), 0) opt = QStyleOptionViewItem(option) self.initStyleOption(opt, self.mdlLabels.indexFromItem(lbl)) - + qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter) - + # Drop down indicator if index.isValid() and index.internalPointer().data(Outline.label.value) not in ["", None, "0"]: opt = QStyleOptionComboBox() @@ -349,4 +350,3 @@ class outlineLabelDelegate(QStyledItemDelegate): r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow) option.rect = r qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter) - \ No newline at end of file diff --git a/manuskript/ui/views/outlineView.py b/manuskript/ui/views/outlineView.py index d95e4d6..848a824 100644 --- a/manuskript/ui/views/outlineView.py +++ b/manuskript/ui/views/outlineView.py @@ -1,47 +1,45 @@ #!/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): - def __init__(self, parent=None, modelPersos=None, modelLabels=None, modelStatus=None): QTreeView.__init__(self, parent) dndView.__init__(self) outlineBasics.__init__(self, parent) - + self.modelPersos = modelPersos self.modelLabels = modelLabels self.modelStatus = modelStatus - + self.header().setStretchLastSection(False) - + def setModelPersos(self, model): # This is used by outlinePersoDelegate to select character self.modelPersos = model - + def setModelLabels(self, model): # This is used by outlineLabelDelegate to display labels self.modelLabels = model - + def setModelStatus(self, model): # This is used by outlineStatusDelegate to display statuses self.modelStatus = model - + def setModel(self, model): QTreeView.setModel(self, model) - + # Setting delegates self.outlineTitleDelegate = outlineTitleDelegate(self) - #self.outlineTitleDelegate.setView(self) + # self.outlineTitleDelegate.setView(self) self.setItemDelegateForColumn(Outline.title.value, self.outlineTitleDelegate) self.outlinePersoDelegate = outlinePersoDelegate(self.modelPersos) self.setItemDelegateForColumn(Outline.POV.value, self.outlinePersoDelegate) @@ -53,10 +51,10 @@ class outlineView(QTreeView, dndView, outlineBasics): self.setItemDelegateForColumn(Outline.goalPercentage.value, self.outlineGoalPercentageDelegate) self.outlineLabelDelegate = outlineLabelDelegate(self.modelLabels) self.setItemDelegateForColumn(Outline.label.value, self.outlineLabelDelegate) - + # Hiding columns self.hideColumns() - + self.header().setSectionResizeMode(Outline.title.value, QHeaderView.Stretch) self.header().setSectionResizeMode(Outline.POV.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.goal.value, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(Outline.goalPercentage.value, QHeaderView.ResizeToContents) - + def hideColumns(self): for c in range(self.model().columnCount()): self.hideColumn(c) for c in settings.outlineViewColumns: self.showColumn(c) - + def setRootIndex(self, index): QTreeView.setRootIndex(self, index) self.outlineGoalPercentageDelegate = outlineGoalPercentageDelegate(index) self.setItemDelegateForColumn(Outline.goalPercentage.value, self.outlineGoalPercentageDelegate) - + def dragMoveEvent(self, event): dndView.dragMoveEvent(self, event) QTreeView.dragMoveEvent(self, event) - + def mouseReleaseEvent(self, event): QTreeView.mouseReleaseEvent(self, event) outlineBasics.mouseReleaseEvent(self, event) - \ No newline at end of file diff --git a/manuskript/ui/views/persoTreeView.py b/manuskript/ui/views/persoTreeView.py index 2f6c16e..fd60d19 100644 --- a/manuskript/ui/views/persoTreeView.py +++ b/manuskript/ui/views/persoTreeView.py @@ -1,13 +1,13 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -import settings +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import QSize, QModelIndex, Qt +from PyQt5.QtGui import QPixmap, QColor, QIcon, QBrush +from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem + +from manuskript.enums import Perso + class persoTreeView(QTreeWidget): - def __init__(self, parent=None): QTreeWidget.__init__(self, parent) self._model = None @@ -19,43 +19,43 @@ class persoTreeView(QTreeWidget): self.setIndentation(10) self.setHeaderHidden(True) self.setIconSize(QSize(24, 24)) - + self.setColumnCount(1) self._rootItem = QTreeWidgetItem() self.insertTopLevelItem(0, self._rootItem) - + def setPersosModel(self, model): self._model = model self._model.dataChanged.connect(self.updateMaybe) self._model.rowsInserted.connect(self.updateMaybe2) self._model.rowsRemoved.connect(self.updateMaybe2) self.updateItems() - + def setFilter(self, text): self._filter = text self.updateItems() - + def updateMaybe(self, topLeft, bottomRight): if topLeft.parent() != QModelIndex(): return - + if topLeft.column() <= Perso.name.value <= bottomRight.column(): # Update name self.updateNames() - + elif topLeft.column() <= Perso.importance.value <= bottomRight.column(): # Importance changed self.updateItems() - + 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(): self.updateItems() - + def updateNames(self): for i in range(self.topLevelItemCount()): item = self.topLevelItem(i) - + for c in range(item.childCount()): sub = item.child(c) ID = sub.data(0, Qt.UserRole) @@ -68,18 +68,18 @@ class persoTreeView(QTreeWidget): color = QColor(self._model.getPersoColorByID(ID)) px.fill(color) sub.setIcon(0, QIcon(px)) - + def updateItems(self): if not self._model: return - + if self.currentItem(): self._lastID = self.currentItem().data(0, Qt.UserRole) - + self._updating = True self.clear() persos = self._model.getPersosByImportance() - + h = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] for i in range(3): cat = QTreeWidgetItem(self, [h[i]]) @@ -90,11 +90,11 @@ class persoTreeView(QTreeWidget): f.setBold(True) cat.setFont(0, f) self.addTopLevelItem(cat) - #cat.setChildIndicatorPolicy(cat.DontShowIndicator) - + # cat.setChildIndicatorPolicy(cat.DontShowIndicator) + for ID in persos[i]: name = self._model.getPersoNameByID(ID) - if not self._filter.lower() in name.lower(): + if not self._filter.lower() in name.lower(): continue item = QTreeWidgetItem(cat, [name]) item.setData(0, Qt.UserRole, ID) @@ -102,30 +102,29 @@ class persoTreeView(QTreeWidget): color = QColor(self._model.getPersoColorByID(ID)) px.fill(color) item.setIcon(0, QIcon(px)) - + if ID == self._lastID: self.setCurrentItem(item) - + self.expandAll() self._updating = False - + def getItemByID(self, ID): for t in range(self.topLevelItemCount()): for i in range(self.topLevelItem(t).childCount()): item = self.topLevelItem(t).child(i) if item.data(0, Qt.UserRole) == ID: return item - + def currentPersoIndex(self): ID = None if self.currentItem(): ID = self.currentItem().data(0, Qt.UserRole) - + return self._model.getIndexFromID(ID) - + def mouseDoubleClickEvent(self, event): item = self.currentItem() # Catching double clicks to forbid collapsing of toplevel items if item.parent(): QTreeWidget.mouseDoubleClickEvent(self, event) - \ No newline at end of file diff --git a/manuskript/ui/views/plotDelegate.py b/manuskript/ui/views/plotDelegate.py index 1c2b213..06fd379 100644 --- a/manuskript/ui/views/plotDelegate.py +++ b/manuskript/ui/views/plotDelegate.py @@ -1,52 +1,53 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- +# --!-- coding: utf8 --!-- -from qt import * -from enums import * -from functions import * -import settings import collections +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QStyledItemDelegate, QLineEdit, QMenu, QAction + + class plotDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) - + def sizeHint(self, option, index): s = QStyledItemDelegate.sizeHint(self, option, index) if s.width() < 200: s.setWidth(200) return s - + def createEditor(self, parent, option, index): editor = QLineEdit(parent) editor.setFrame(False) editor.setAlignment(Qt.AlignRight | Qt.AlignVCenter) return editor - + def setEditorData(self, editor, index): editor.setText(index.model().data(index)) - + self.txt = editor self.menu = QMenu(editor) - + plotsTypes = collections.OrderedDict({ self.tr("General"): [ self.tr("Promise"), self.tr("Problem"), self.tr("Progress"), self.tr("Resolution") - ], + ], self.tr("Try / Fail"): [ self.tr("No and"), self.tr("Yes but"), - ], + ], self.tr("Freytag's pyramid"): [ self.tr("Exposition"), self.tr("Rising action"), self.tr("Climax"), self.tr("Falling action"), self.tr("Resolution"), - ], + ], self.tr("Three acts"): [ self.tr("1. Setup"), self.tr("1. Inciting event"), @@ -59,8 +60,8 @@ class plotDelegate(QStyledItemDelegate): self.tr("3. Stand up"), self.tr("3. Climax"), self.tr("3. Ending"), - ], - + ], + self.tr("Hero's journey"): [ self.tr("Ordinary world"), self.tr("Call to adventure"), @@ -74,12 +75,12 @@ class plotDelegate(QStyledItemDelegate): self.tr("Transformation"), self.tr("Atonement"), self.tr("Return"), - ], - }) - + ], + }) + for name in plotsTypes: m = QMenu(name, self.menu) - + for sub in plotsTypes[name]: if sub == "---": m.addSeparator() @@ -87,19 +88,19 @@ class plotDelegate(QStyledItemDelegate): a = QAction(sub, m) a.triggered.connect(self.submit) m.addAction(a) - + self.menu.addMenu(m) - + editor.addAction(QIcon.fromTheme("list-add"), QLineEdit.LeadingPosition).triggered.connect(self.popupMenu) - + def setModelData(self, editor, model, index): val = editor.text() model.setData(index, val) - + def popupMenu(self): act = self.sender() self.menu.popup(self.txt.parent().mapToGlobal(self.txt.geometry().bottomLeft())) - + def submit(self): act = self.sender() - self.txt.setText(act.text()) \ No newline at end of file + self.txt.setText(act.text()) diff --git a/manuskript/ui/views/plotTreeView.py b/manuskript/ui/views/plotTreeView.py index e710647..79ab9fa 100644 --- a/manuskript/ui/views/plotTreeView.py +++ b/manuskript/ui/views/plotTreeView.py @@ -1,15 +1,16 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from functions import * -import settings +# --!-- coding: utf8 --!-- +from PyQt5.QtCore import Qt, QModelIndex, QMimeData +from PyQt5.QtGui import QBrush, QColor +from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem 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): - def __init__(self, parent=None): QTreeWidget.__init__(self, parent) self._model = None @@ -20,37 +21,38 @@ class plotTreeView(QTreeWidget): self._showSubPlot = False self.setRootIsDecorated(False) self.setIndentation(10) - + self.setColumnCount(1) self._rootItem = QTreeWidgetItem() self.insertTopLevelItem(0, self._rootItem) - #self.currentItemChanged.connect(self._currentItemChanged) + # self.currentItemChanged.connect(self._currentItemChanged) -############################################################################### -# SETTERS -############################################################################### + ############################################################################### + # SETTERS + ############################################################################### def setShowSubPlot(self, v): self._showSubPlot = v self.updateItems() - + def setPlotModel(self, model): self._model = model self._model.dataChanged.connect(self.updateMaybe) self._model.rowsInserted.connect(self.updateMaybe2) self._model.rowsRemoved.connect(self.updateMaybe2) self.updateItems() - + def setFilter(self, text): self._filter = text self.updateItems() -############################################################################### -# GETTERS -############################################################################### - + ############################################################################### + # GETTERS + ############################################################################### + def getItemByID(self, ID): "Recursively search items to find one whose data is ``ID``." + def find(item, ID): if item.data(0, Qt.UserRole) == ID: return item @@ -58,63 +60,63 @@ class plotTreeView(QTreeWidget): r = find(item.child(i), ID) if r: return r - + return find(self.invisibleRootItem(), ID) - + def currentPlotIndex(self): "Returns index of the current item in plot model." ID = None if self.currentItem(): ID = self.currentItem().data(0, Qt.UserRole) - + return self._model.getIndexFromID(ID) -############################################################################### -# UPDATES -############################################################################### + ############################################################################### + # UPDATES + ############################################################################### def updateMaybe(self, topLeft, bottomRight): if topLeft.parent() != QModelIndex(): return - + if topLeft.column() <= Plot.name.value <= bottomRight.column(): # Update name self.updateNames() - + elif topLeft.column() <= Plot.importance.value <= bottomRight.column(): # Importance changed self.updateItems() - + def updateMaybe2(self, parent, first, last): "Rows inserted or removed" if parent == QModelIndex(): self.updateItems() - + elif self._showSubPlot: self.updateItems() - + def updateNames(self): for i in range(self.topLevelItemCount()): item = self.topLevelItem(i) - + for c in range(item.childCount()): sub = item.child(c) ID = sub.data(0, Qt.UserRole) if ID: name = self._model.getPlotNameByID(ID) sub.setText(0, name) - + def updateItems(self): if not self._model: return - + if self.currentItem(): self._lastID = self.currentItem().data(0, Qt.UserRole) - + self._updating = True self.clear() plots = self._model.getPlotsByImportance() - + h = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")] for i in range(3): cat = QTreeWidgetItem(self, [h[i]]) @@ -126,71 +128,71 @@ class plotTreeView(QTreeWidget): cat.setFont(0, f) cat.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.addTopLevelItem(cat) - #cat.setChildIndicatorPolicy(cat.DontShowIndicator) - + # cat.setChildIndicatorPolicy(cat.DontShowIndicator) + for ID in plots[i]: name = self._model.getPlotNameByID(ID) - if not self._filter.lower() in name.lower(): + if not self._filter.lower() in name.lower(): continue item = QTreeWidgetItem(cat, [name]) item.setData(0, Qt.UserRole, ID) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) - + if self._showSubPlot: - + f = item.font(0) f.setBold(True) item.setFont(0, f) - + for subID, name, summary in self._model.getSubPlotsByID(ID): 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) - + if ID == self._lastID: self.setCurrentItem(item) - + self.expandAll() self._updating = False -############################################################################### -# DRAG N DROP -############################################################################### + ############################################################################### + # DRAG N DROP + ############################################################################### def mimeTypes(self): return ["application/xml"] - + def mimeData(self, items): mimeData = QMimeData() encodedData = "" - + root = ET.Element("outlineItems") - + for item in items: plotID = item.data(0, Qt.UserRole) subplotRaw = item.parent().indexOfChild(item) - + _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.type.name, settings.defaultTextType) sub.set(Outline.summaryFull.name, summary) sub.set(Outline.notes.name, self.tr("**Plot:** {}").format( - Ref.plotReference(plotID))) - - root.append(sub) - - encodedData = ET.tostring(root) - - mimeData.setData("application/xml", encodedData) - return mimeData + Ref.plotReference(plotID))) -############################################################################### -# EVENTS -############################################################################### + root.append(sub) + + encodedData = ET.tostring(root) + + mimeData.setData("application/xml", encodedData) + return mimeData + + ############################################################################### + # EVENTS + ############################################################################### def mouseDoubleClickEvent(self, event): item = self.currentItem() # Catching double clicks to forbid collapsing of toplevel items if item.parent(): - QTreeWidget.mouseDoubleClickEvent(self, event) \ No newline at end of file + QTreeWidget.mouseDoubleClickEvent(self, event) diff --git a/manuskript/ui/views/propertiesView.py b/manuskript/ui/views/propertiesView.py index b458928..8cdedda 100644 --- a/manuskript/ui/views/propertiesView.py +++ b/manuskript/ui/views/propertiesView.py @@ -1,17 +1,17 @@ #!/usr/bin/env python -#--!-- coding: utf8 --!-- - -from qt import * -from enums import * -from ui.views.propertiesView_ui import * +# --!-- coding: utf8 --!-- +from PyQt5.QtWidgets import QWidget + +from manuskript.enums import Outline +from manuskript.ui.views.propertiesView_ui import Ui_propertiesView + class propertiesView(QWidget, Ui_propertiesView): - def __init__(self, parent=None): QWidget.__init__(self) self.setupUi(self) self.txtGoal.setColumn(Outline.setGoal.value) - + def setModels(self, mdlOutline, mdlPersos, mdlLabels, mdlStatus): self.cmbPOV.setModels(mdlPersos, mdlOutline) self.cmbLabel.setModels(mdlLabels, mdlOutline) @@ -20,27 +20,27 @@ class propertiesView(QWidget, Ui_propertiesView): self.chkCompile.setModel(mdlOutline) self.txtTitle.setModel(mdlOutline) self.txtGoal.setModel(mdlOutline) - + def getIndexes(self, sourceView): - "Returns a list of indexes from list of QItemSelectionRange" + """Returns a list of indexes from list of QItemSelectionRange""" indexes = [] - + for i in sourceView.selectionModel().selection().indexes(): - if i.column() != 0: + if i.column() != 0: continue - + if i not in indexes: indexes.append(i) - + return indexes - + def selectionChanged(self, sourceView): - + indexes = self.getIndexes(sourceView) - #print(indexes) + # print(indexes) if len(indexes) == 0: self.setEnabled(False) - + elif len(indexes) == 1: self.setEnabled(True) self.setLabelsItalic(False) @@ -51,9 +51,9 @@ class propertiesView(QWidget, Ui_propertiesView): self.chkCompile.setCurrentModelIndex(idx) self.txtTitle.setCurrentModelIndex(idx) self.txtGoal.setCurrentModelIndex(idx) - + self.cmbType.setCurrentModelIndex(idx) - + else: self.setEnabled(True) self.setLabelsItalic(True) @@ -63,9 +63,9 @@ class propertiesView(QWidget, Ui_propertiesView): self.cmbPOV.setCurrentModelIndexes(indexes) self.cmbLabel.setCurrentModelIndexes(indexes) self.cmbStatus.setCurrentModelIndexes(indexes) - + self.cmbType.setCurrentModelIndexes(indexes) - + def setLabelsItalic(self, value): f = self.lblPOV.font() f.setItalic(value) @@ -75,5 +75,5 @@ class propertiesView(QWidget, Ui_propertiesView): self.lblLabel, self.lblCompile, self.lblGoal - ]: - lbl.setFont(f) \ No newline at end of file + ]: + lbl.setFont(f) diff --git a/manuskript/ui/views/propertiesView_ui.py b/manuskript/ui/views/propertiesView_ui.py index 8a9e961..43c7215 100644 --- a/manuskript/ui/views/propertiesView_ui.py +++ b/manuskript/ui/views/propertiesView_ui.py @@ -2,7 +2,7 @@ # 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! @@ -107,8 +107,8 @@ class Ui_propertiesView(object): self.page_2 = QtWidgets.QWidget() self.page_2.setObjectName("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.setSpacing(0) self.verticalLayout_3.setObjectName("verticalLayout_3") self.formLayout_2 = QtWidgets.QFormLayout() self.formLayout_2.setObjectName("formLayout_2") @@ -194,9 +194,9 @@ class Ui_propertiesView(object): self.label_36.setText(_translate("propertiesView", "Goal")) self.txtGoalMulti.setPlaceholderText(_translate("propertiesView", "Word count")) -from ui.views.lineEditView import lineEditView -from ui.views.chkOutlineCompile import chkOutlineCompile -from ui.views.cmbOutlineTypeChoser import cmbOutlineTypeChoser -from ui.views.cmbOutlineLabelChoser import cmbOutlineLabelChoser -from ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser -from ui.views.cmbOutlineStatusChoser import cmbOutlineStatusChoser +from manuskript.ui.views.chkOutlineCompile import chkOutlineCompile +from manuskript.ui.views.cmbOutlineLabelChoser import cmbOutlineLabelChoser +from manuskript.ui.views.cmbOutlinePersoChoser import cmbOutlinePersoChoser +from manuskript.ui.views.cmbOutlineStatusChoser import cmbOutlineStatusChoser +from manuskript.ui.views.cmbOutlineTypeChoser import cmbOutlineTypeChoser +from manuskript.ui.views.lineEditView import lineEditView diff --git a/manuskript/ui/views/propertiesView_ui.ui b/manuskript/ui/views/propertiesView_ui.ui index e1ee32a..0c342b8 100644 --- a/manuskript/ui/views/propertiesView_ui.ui +++ b/manuskript/ui/views/propertiesView_ui.ui @@ -297,32 +297,32 @@ lineEditView QLineEdit -
    ui.views.lineEditView.h
    +
    manuskript.ui.views.lineEditView.h
    cmbOutlinePersoChoser QComboBox -
    ui.views.cmbOutlinePersoChoser.h
    +
    manuskript.ui.views.cmbOutlinePersoChoser.h
    cmbOutlineStatusChoser QComboBox -
    ui.views.cmbOutlineStatusChoser.h
    +
    manuskript.ui.views.cmbOutlineStatusChoser.h
    chkOutlineCompile QCheckBox -
    ui.views.chkOutlineCompile.h
    +
    manuskript.ui.views.chkOutlineCompile.h
    cmbOutlineLabelChoser QComboBox -
    ui.views.cmbOutlineLabelChoser.h
    +
    manuskript.ui.views.cmbOutlineLabelChoser.h
    cmbOutlineTypeChoser QComboBox -
    ui.views.cmbOutlineTypeChoser.h
    +
    manuskript.ui.views.cmbOutlineTypeChoser.h
    diff --git a/manuskript/ui/views/textEditCompleter.py b/manuskript/ui/views/textEditCompleter.py index 8d40c46..7d16279 100644 --- a/manuskript/ui/views/textEditCompleter.py +++ b/manuskript/ui/views/textEditCompleter.py @@ -1,53 +1,55 @@ #!/usr/bin/env python -#--!-- 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 +# --!-- coding: utf8 --!-- 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: import enchant except ImportError: enchant = None - + + class textEditCompleter(textEditView): - - def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="", autoResize=False): - textEditView.__init__(self, parent=parent, index=index, html=html, spellcheck=spellcheck, highlighting=True, dict=dict, autoResize=autoResize) - + def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="", + autoResize=False): + textEditView.__init__(self, parent=parent, index=index, html=html, spellcheck=spellcheck, highlighting=True, + dict=dict, autoResize=autoResize) + self.completer = None self.setMouseTracking(True) self.refRects = [] - + self.textChanged.connect(self.getRefRects) self.document().documentLayoutChanged.connect(self.getRefRects) - + def setCurrentModelIndex(self, index): textEditView.setCurrentModelIndex(self, index) if self._index and not self.completer: self.setCompleter(completer()) - + def setCompleter(self, completer): self.completer = completer self.completer.activated.connect(self.insertCompletion) - + def insertCompletion(self, txt): tc = self.textCursor() tc.insertText(txt) self.setTextCursor(tc) - + def textUnderCursor(self, select=False): tc = self.textCursor() tc.select(QTextCursor.WordUnderCursor) if select: self.setTextCursor(tc) return tc.selectedText() - + def refUnderCursor(self, cursor): pos = cursor.position() cursor.select(QTextCursor.BlockUnderCursor) @@ -57,27 +59,27 @@ class textEditCompleter(textEditView): for m in match: if text.find(m) <= pos <= text.find(m) + len(m): return m - - #def event(self, event): - #if event.type() == QEvent.ToolTip: - #cursor = self.cursorForPosition(event.pos()) - #ref = self.refUnderCursor(cursor) - #if ref: - #QToolTip.showText(self.mapToGlobal(event.pos()), infoForRef(ref)) - #else: - #QToolTip.hideText() - #return True - #return textEditView.event(self, event) - + + # def event(self, event): + # if event.type() == QEvent.ToolTip: + # cursor = self.cursorForPosition(event.pos()) + # ref = self.refUnderCursor(cursor) + # if ref: + # QToolTip.showText(self.mapToGlobal(event.pos()), infoForRef(ref)) + # else: + # QToolTip.hideText() + # return True + # return textEditView.event(self, event) + def createStandardContextMenu(self): menu = textEditView.createStandardContextMenu(self) - + a = QAction(self.tr("Insert reference"), menu) a.triggered.connect(self.popupCompleter) menu.insertSeparator(menu.actions()[0]) menu.insertAction(menu.actions()[0], a) return menu - + def keyPressEvent(self, event): if self.completer.isVisible(): if event.key() in ( @@ -88,17 +90,17 @@ class textEditCompleter(textEditView): Qt.Key_Backtab): event.ignore() return - - isShortcut = (event.modifiers() == Qt.ControlModifier and\ + + isShortcut = (event.modifiers() == Qt.ControlModifier and \ event.key() == Qt.Key_Space) - + if not self.completer or not isShortcut: self.completer.setVisible(False) textEditView.keyPressEvent(self, event) return - + self.popupCompleter() - + def popupCompleter(self): if self.completer: cr = self.cursorRect() @@ -106,24 +108,24 @@ class textEditCompleter(textEditView): cr.setWidth(self.completer.sizeHint().width()) self.completer.setGeometry(cr) self.completer.popup(self.textUnderCursor(select=True)) - + def mouseMoveEvent(self, event): textEditView.mouseMoveEvent(self, event) - + onRef = [r for r in self.refRects if r.contains(event.pos())] - + if not onRef: qApp.restoreOverrideCursor() QToolTip.hideText() return - + cursor = self.cursorForPosition(event.pos()) ref = self.refUnderCursor(cursor) if ref: if not qApp.overrideCursor(): qApp.setOverrideCursor(Qt.PointingHandCursor) QToolTip.showText(self.mapToGlobal(event.pos()), Ref.tooltip(ref)) - + def mouseReleaseEvent(self, event): textEditView.mouseReleaseEvent(self, event) onRef = [r for r in self.refRects if r.contains(event.pos())] @@ -133,11 +135,11 @@ class textEditCompleter(textEditView): if ref: Ref.open(ref) qApp.restoreOverrideCursor() - + def resizeEvent(self, event): textEditView.resizeEvent(self, event) self.getRefRects() - + def getRefRects(self): cursor = self.textCursor() f = self.font() @@ -151,12 +153,12 @@ class textEditCompleter(textEditView): r.setWidth(fm.width(txt.group(0))) refs.append(r) self.refRects = refs - + def paintEvent(self, event): QTextEdit.paintEvent(self, event) - + # Debug: paint rects - #painter = QPainter(self.viewport()) - #painter.setPen(Qt.gray) - #for r in self.refRects: - #painter.drawRect(r) \ No newline at end of file + # painter = QPainter(self.viewport()) + # painter.setPen(Qt.gray) + # for r in self.refRects: + # painter.drawRect(r) diff --git a/manuskript/ui/views/textEditView.py b/manuskript/ui/views/textEditView.py index 6fe62ff..498bcf6 100644 --- a/manuskript/ui/views/textEditView.py +++ b/manuskript/ui/views/textEditView.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -#--!-- 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 +# --!-- coding: utf8 --!-- 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: import enchant except ImportError: enchant = None - + + class textEditView(QTextEdit): - - def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="", autoResize=False): + def __init__(self, parent=None, index=None, html=None, spellcheck=True, highlighting=False, dict="", + autoResize=False): QTextEdit.__init__(self, parent) self._column = Outline.text.value self._index = None @@ -32,8 +38,8 @@ class textEditView(QTextEdit): self._textFormat = "text" self.setAcceptRichText(False) # When setting up a theme, this becomes true. - self._fromTheme = False - + self._fromTheme = False + self.spellcheck = spellcheck self.currentDict = dict if dict else settings.dict self.highlighter = None @@ -44,41 +50,40 @@ class textEditView(QTextEdit): self.highligtCS = False self.defaultFontPointSize = qApp.font().pointSize() 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 self.updateTimer = QTimer() self.updateTimer.setInterval(500) self.updateTimer.setSingleShot(True) self.updateTimer.timeout.connect(self.submit) - #self.updateTimer.timeout.connect(lambda: print("Timeout")) - + # self.updateTimer.timeout.connect(lambda: print("Timeout")) + self.updateTimer.stop() self.document().contentsChanged.connect(self.updateTimer.start, AUC) - #self.document().contentsChanged.connect(lambda: print("Document changed")) - - #self.document().contentsChanged.connect(lambda: print(self.objectName(), "Contents changed")) - + # self.document().contentsChanged.connect(lambda: print("Document changed")) + + # self.document().contentsChanged.connect(lambda: print(self.objectName(), "Contents changed")) + self.setEnabled(False) - + if index: self.setCurrentModelIndex(index) - + elif html: self.document().setHtml(html) self.setReadOnly(True) - + # Spellchecking if enchant and self.spellcheck: self._dict = enchant.Dict(self.currentDict if self.currentDict else enchant.get_default_language()) else: self.spellcheck = False - + if self._highlighting and not self.highlighter: self.highlighter = basicHighlighter(self) self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat) - + def setModel(self, model): self._model = model try: @@ -89,18 +94,18 @@ class textEditView(QTextEdit): self._model.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC) except TypeError: pass - + def setColumn(self, col): self._column = col - + def setHighlighting(self, val): self._highlighting = val - + def setDefaultBlockFormat(self, bf): self._defaultBlockFormat = bf if self.highlighter: self.highlighter.setDefaultBlockFormat(bf) - + def setCurrentModelIndex(self, index): self._indexes = None if index.isValid(): @@ -108,9 +113,9 @@ class textEditView(QTextEdit): if index.column() != self._column: index = index.sibling(index.row(), self._column) self._index = index - + self.setPlaceholderText(self._placeholderText) - + if not self._model: self.setModel(index.model()) @@ -123,32 +128,32 @@ class textEditView(QTextEdit): self.setPlainText("") self.setEnabled(False) - + def setCurrentModelIndexes(self, indexes): self._index = None self._indexes = [] - + for i in indexes: if i.isValid(): self.setEnabled(True) if i.column() != self._column: i = i.sibling(i.row(), self._column) self._indexes.append(i) - + if not self._model: self.setModel(i.model()) - + self.updateText() - + def setupEditorForIndex(self, index): # what type of text are we editing? if type(index.model()) != outlineModel: self._textFormat = "text" return - + if self._column not in [Outline.text.value, Outline.notes.value]: self._textFormat = "text" - + else: item = index.internalPointer() if item.isHTML(): @@ -157,13 +162,13 @@ class textEditView(QTextEdit): self._textFormat = "t2t" else: self._textFormat = "text" - + # Accept richtext maybe if self._textFormat == "html": self.setAcceptRichText(True) else: self.setAcceptRichText(False) - + # Setting highlighter if self._highlighting: item = index.internalPointer() @@ -171,20 +176,20 @@ class textEditView(QTextEdit): self.highlighter = basicHighlighter(self) else: self.highlighter = t2tHighlighter(self) - + self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat) - + def loadFontSettings(self): if self._fromTheme or \ - not self._index or \ - type(self._index.model()) != outlineModel or \ - self._column != Outline.text.value: + not self._index or \ + type(self._index.model()) != outlineModel or \ + self._column != Outline.text.value: return - + opt = settings.textEditor f = QFont() f.fromString(opt["font"]) - #self.setFont(f) + # self.setFont(f) self.setStyleSheet(""" background: {bg}; color: {foreground}; @@ -195,52 +200,52 @@ class textEditView(QTextEdit): foreground=opt["fontColor"], ff=f.family(), fs="{}pt".format(str(f.pointSize())))) - + cf = QTextCharFormat() - #cf.setFont(f) - #cf.setForeground(QColor(opt["fontColor"])) - + # cf.setFont(f) + # cf.setForeground(QColor(opt["fontColor"])) + bf = QTextBlockFormat() bf.setLineHeight(opt["lineSpacing"], bf.ProportionalHeight) bf.setTextIndent(opt["tabWidth"] * 1 if opt["indent"] else 0) bf.setTopMargin(opt["spacingAbove"]) bf.setBottomMargin(opt["spacingBelow"]) - + self._defaultCharFormat = cf self._defaultBlockFormat = bf - + if self.highlighter: self.highlighter.setMisspelledColor(QColor(opt["misspelled"])) self.highlighter.setDefaultCharFormat(self._defaultCharFormat) self.highlighter.setDefaultBlockFormat(self._defaultBlockFormat) - + def update(self, topLeft, bottomRight): if self._updating: return - + elif self._index: - + if topLeft.parent() != self._index.parent(): return - - #print("Model changed: ({}:{}), ({}:{}/{}), ({}:{}) for {} of {}".format( - #topLeft.row(), topLeft.column(), - #self._index.row(), self._index.row(), self._column, - #bottomRight.row(), bottomRight.column(), - #self.objectName(), self.parent().objectName())) - + + # print("Model changed: ({}:{}), ({}:{}/{}), ({}:{}) for {} of {}".format( + # topLeft.row(), topLeft.column(), + # self._index.row(), self._index.row(), self._column, + # bottomRight.row(), bottomRight.column(), + # self.objectName(), self.parent().objectName())) + if topLeft.row() <= self._index.row() <= bottomRight.row(): 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, # we reset the index to set the proper # highlighter and other defaults self.setupEditorForIndex(self._index) self.updateText() - + elif topLeft.column() <= self._column <= bottomRight.column(): self.updateText() - + elif self._indexes: update = False for i in self._indexes: @@ -248,43 +253,43 @@ class textEditView(QTextEdit): update = True if update: self.updateText() - + def rowsAboutToBeRemoved(self, parent, first, last): if self._index: if self._index.parent() == parent and \ - first <= self._index.row() <= last: + first <= self._index.row() <= last: self._index = None self.setEnabled(False) - - #FIXME: self._indexes - + + # FIXME: self._indexes + def disconnectDocument(self): try: self.document().contentsChanged.disconnect(self.updateTimer.start) except: pass - + def reconnectDocument(self): self.document().contentsChanged.connect(self.updateTimer.start, AUC) - + def updateText(self): if self._updating: return - #print("Updating", self.objectName()) + # print("Updating", self.objectName()) self._updating = True if self._index: self.disconnectDocument() if self._textFormat == "html": if self.toHtml() != toString(self._model.data(self._index)): - #print(" Updating html") + # print(" Updating html") html = self._model.data(self._index) self.document().setHtml(toString(html)) else: 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.reconnectDocument() - + elif self._indexes: self.disconnectDocument() t = [] @@ -292,35 +297,35 @@ class textEditView(QTextEdit): for i in self._indexes: item = i.internalPointer() t.append(toString(item.data(self._column))) - + for t2 in t[1:]: if t2 != t[0]: same = False break - + if same: # Assuming that we don't use HTML with multiple items self.document().setPlainText(t[0]) else: self.document().setPlainText("") - + if not self._placeholderText: self._placeholderText = self.placeholderText() - + self.setPlaceholderText(self.tr("Various")) self.reconnectDocument() self._updating = False - + def submit(self): self.updateTimer.stop() if self._updating: return - #print("Submitting", self.objectName()) + # print("Submitting", self.objectName()) if self._index: - #item = self._index.internalPointer() + # item = self._index.internalPointer() if self._textFormat == "html": if self.toHtml() != self._model.data(self._index): - #print(" Submitting html") + # print(" Submitting html") self._updating = True html = self.toHtml() # 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"text-indent:.*?;\s*", "", html) html = re.sub(r"line-height:.*?;\s*", "", html) - #print("Submitting:", html) + # print("Submitting:", html) self._model.setData(self._index, html) self._updating = False else: if self.toPlainText() != self._model.data(self._index): - #print(" Submitting plain text") + # print(" Submitting plain text") self._updating = True self._model.setData(self._index, self.toPlainText()) self._updating = False - + elif self._indexes: self._updating = True for i in self._indexes: @@ -347,15 +352,15 @@ class textEditView(QTextEdit): print("Submitting many indexes") self._model.setData(i, self.toPlainText()) self._updating = False - + def keyPressEvent(self, event): QTextEdit.keyPressEvent(self, event) if event.key() == Qt.Key_Space: self.submit() - + # ----------------------------------------------------------------------------------------------------- # Resize stuff - + def resizeEvent(self, e): QTextEdit.resizeEvent(self, e) if self._autoResize: @@ -365,7 +370,7 @@ class textEditView(QTextEdit): docHeight = self.document().size().height() if self.heightMin <= docHeight <= self.heightMax: self.setMinimumHeight(docHeight) - + def setAutoResize(self, val): self._autoResize = val if self._autoResize: @@ -373,18 +378,18 @@ class textEditView(QTextEdit): self.heightMin = 0 self.heightMax = 65000 self.sizeChange() - -############################################################################### -# SPELLCHECKING -############################################################################### -# Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ + + ############################################################################### + # SPELLCHECKING + ############################################################################### + # Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ def setDict(self, d): self.currentDict = d self._dict = enchant.Dict(d) if self.highlighter: self.highlighter.rehighlight() - + def toggleSpellcheck(self, v): self.spellcheck = v 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 # moved to the location of the pointer. event = QMouseEvent(QEvent.MouseButtonPress, event.pos(), - Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) + Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) QTextEdit.mousePressEvent(self, event) - + 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) - + def __init__(self, *args): QAction.__init__(self, *args) - + self.triggered.connect(lambda x: self.correct.emit( - str(self.text()))) + str(self.text()))) def contextMenuEvent(self, event): # Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ popup_menu = self.createStandardContextMenu() popup_menu.exec_(event.globalPos()) - + def createStandardContextMenu(self): popup_menu = QTextEdit.createStandardContextMenu(self) - + if not self.spellcheck: return popup_menu - + # Select the word under the cursor. cursor = self.textCursor() - #cursor = self.cursorForPosition(pos) + # cursor = self.cursorForPosition(pos) cursor.select(QTextCursor.WordUnderCursor) self.setTextCursor(cursor) # 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) return popup_menu - + def correctWord(self, word): - ''' + """ Replaces the selected text with word. - ''' + """ cursor = self.textCursor() cursor.beginEditBlock() - + cursor.removeSelectedText() cursor.insertText(word) - + cursor.endEditBlock() - -############################################################################### -# FORMATTING -############################################################################### - + + ############################################################################### + # FORMATTING + ############################################################################### + def focusOutEvent(self, event): - "Submit changes just before focusing out." + """Submit changes just before focusing out.""" QTextEdit.focusOutEvent(self, event) self.submit() - + def focusInEvent(self, event): - "Finds textFormatter and attach them to that view." + """Finds textFormatter and attach them to that view.""" QTextEdit.focusInEvent(self, event) - + p = self.parent() while p.parent(): p = p.parent() - + if self._index: for tF in p.findChildren(textFormat, QRegExp(".*"), Qt.FindChildrenRecursively): tF.updateFromIndex(self._index) tF.setTextEdit(self) - + def applyFormat(self, _format): - + if self._textFormat == "html": - + if _format == "Clear": - + cursor = self.textCursor() - + if _format == "Clear": fmt = self._defaultCharFormat cursor.setCharFormat(fmt) bf = self._defaultBlockFormat cursor.setBlockFormat(bf) - + elif _format in ["Bold", "Italic", "Underline"]: - + cursor = self.textCursor() - + # If no selection, selects the word in which the cursor is now if not cursor.hasSelection(): cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfWord, QTextCursor.KeepAnchor) - + fmt = cursor.charFormat() - + if _format == "Bold": fmt.setFontWeight(QFont.Bold if fmt.fontWeight() != QFont.Bold else QFont.Normal) elif _format == "Italic": fmt.setFontItalic(not fmt.fontItalic()) elif _format == "Underline": fmt.setFontUnderline(not fmt.fontUnderline()) - + fmt2 = self._defaultCharFormat fmt2.setFontWeight(fmt.fontWeight()) fmt2.setFontItalic(fmt.fontItalic()) fmt2.setFontUnderline(fmt.fontUnderline()) - + cursor.mergeCharFormat(fmt2) - + elif _format in ["Left", "Center", "Right", "Justify"]: - + cursor = self.textCursor() - - #bf = cursor.blockFormat() + + # bf = cursor.blockFormat() bf = QTextBlockFormat() bf.setAlignment( - Qt.AlignLeft if _format == "Left" else - Qt.AlignHCenter if _format == "Center" else - Qt.AlignRight if _format == "Right" else - Qt.AlignJustify) - + Qt.AlignLeft if _format == "Left" else + Qt.AlignHCenter if _format == "Center" else + Qt.AlignRight if _format == "Right" else + Qt.AlignJustify) + cursor.setBlockFormat(bf) self.setTextCursor(cursor) - + elif self._textFormat == "t2t": if _format == "Bold": t2tFormatSelection(self, 0) @@ -546,6 +551,3 @@ class textEditView(QTextEdit): t2tFormatSelection(self, 2) elif _format == "Clear": t2tClearFormat(self) - - - \ No newline at end of file diff --git a/manuskript/ui/views/treeDelegates.py b/manuskript/ui/views/treeDelegates.py index 4b881e9..f5223b0 100644 --- a/manuskript/ui/views/treeDelegates.py +++ b/manuskript/ui/views/treeDelegates.py @@ -1,52 +1,58 @@ #!/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): """The main purpose of ``treeTitleDelegate`` is to paint outline items in the treeview with propers colors according to settings. """ + def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) self._view = None - + def setView(self, view): self._view = view - + def paint(self, painter, option, index): - + item = index.internalPointer() colors = outlineItemColors(item) - + style = qApp.style() - + opt = QStyleOptionViewItem(option) self.initStyleOption(opt, index) - + iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt) textRect = style.subElementRect(style.SE_ItemViewItemText, opt) - + # Background style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter) - + if settings.viewSettings["Tree"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected: - + col = colors[settings.viewSettings["Tree"]["Background"]] - + if col != QColor(Qt.transparent): col2 = QColor(Qt.white) if opt.state & QStyle.State_Selected: col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color() col = mixColors(col, col2, .2) - + painter.save() painter.setBrush(col) painter.setPen(Qt.NoPen) - + rect = opt.rect if self._view: r2 = self._view.visualRect(index) @@ -54,10 +60,10 @@ class treeTitleDelegate(QStyledItemDelegate): rect.setLeft(r2.left()) rect.setTop(r2.top()) rect.setBottom(r2.bottom()) - + painter.drawRoundedRect(rect, 5, 5) painter.restore() - + # Icon mode = QIcon.Normal if not opt.state & QStyle.State_Enabled: @@ -71,7 +77,7 @@ class treeTitleDelegate(QStyledItemDelegate): colorifyPixmap(icon, color) opt.icon = QIcon(icon) opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state) - + # Text if opt.text: painter.save() @@ -85,7 +91,7 @@ class treeTitleDelegate(QStyledItemDelegate): fm = QFontMetrics(f) elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width()) painter.drawText(textRect, Qt.AlignLeft, elidedText) - + extraText = "" if item.isFolder() and settings.viewSettings["Tree"]["InfoFolder"] != "Nothing": if settings.viewSettings["Tree"]["InfoFolder"] == "Count": @@ -98,7 +104,7 @@ class treeTitleDelegate(QStyledItemDelegate): extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100) if extraText: extraText = " ({}%)".format(extraText) - + if item.isText() and settings.viewSettings["Tree"]["InfoText"] != "Nothing": if settings.viewSettings["Tree"]["InfoText"] == "WC": extraText = item.data(Outline.wordCount.value) @@ -106,19 +112,17 @@ class treeTitleDelegate(QStyledItemDelegate): elif settings.viewSettings["Tree"]["InfoText"] == "Progress": extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100) if extraText: - extraText = " ({}%)".format(extraText) - + extraText = " ({}%)".format(extraText) + if extraText: - r = QRect(textRect) r.setLeft(r.left() + fm.width(opt.text + " ")) - + painter.save() painter.setPen(Qt.darkGray) painter.drawText(r, Qt.AlignLeft | Qt.AlignBottom, extraText) painter.restore() - - + painter.restore() - - #QStyledItemDelegate.paint(self, painter, option, index) \ No newline at end of file + + # QStyledItemDelegate.paint(self, painter, option, index) diff --git a/manuskript/ui/views/treeView.py b/manuskript/ui/views/treeView.py index 72cb1eb..07f9107 100644 --- a/manuskript/ui/views/treeView.py +++ b/manuskript/ui/views/treeView.py @@ -1,117 +1,116 @@ #!/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): - def __init__(self, parent=None): QTreeView.__init__(self, parent) dndView.__init__(self, parent) outlineBasics.__init__(self, parent) self._indexesToOpen = None - + def setModel(self, model): QTreeView.setModel(self, model) - + # Hiding columns for c in range(1, self.model().columnCount()): self.hideColumn(c) - + # Setting delegate self.titleDelegate = treeTitleDelegate() self.setItemDelegateForColumn(Outline.title.value, self.titleDelegate) - + def makePopupMenu(self): menu = outlineBasics.makePopupMenu(self) first = menu.actions()[0] - + # Open item in new tab sel = self.selectedIndexes() pos = self.viewport().mapFromGlobal(QCursor.pos()) mouseIndex = self.indexAt(pos) - + if mouseIndex.isValid(): mouseTitle = mouseIndex.internalPointer().title() else: mouseTitle = self.tr("Root") - + if mouseIndex in sel and len(sel) > 1: actionTitle = self.tr("Open {} items in new tabs").format(len(sel)) self._indexesToOpen = sel else: actionTitle = self.tr("Open {} in a new tab").format(mouseTitle) self._indexesToOpen = [mouseIndex] - + self.actNewTab = QAction(actionTitle, menu) self.actNewTab.triggered.connect(self.openNewTab) menu.insertAction(first, self.actNewTab) menu.insertSeparator(first) - + # Expand /collapse item if mouseIndex.isValid(): - #index = self.currentIndex() + # index = self.currentIndex() item = mouseIndex.internalPointer() self.actExpand = QAction(self.tr("Expand {}").format(item.title()), menu) self.actExpand.triggered.connect(self.expandCurrentIndex) menu.insertAction(first, self.actExpand) - + self.actCollapse = QAction(self.tr("Collapse {}").format(item.title()), menu) self.actCollapse.triggered.connect(self.collapseCurrentIndex) menu.insertAction(first, self.actCollapse) - + menu.insertSeparator(first) - + # Expand /collapse all self.actExpandAll = QAction(self.tr("Expand All"), menu) self.actExpandAll.triggered.connect(self.expandAll) menu.insertAction(first, self.actExpandAll) - + self.actCollapseAll = QAction(self.tr("Collapse All"), menu) self.actCollapseAll.triggered.connect(self.collapseAll) menu.insertAction(first, self.actCollapseAll) - + menu.insertSeparator(first) - + return menu - + def openNewTab(self): mainWindow().mainEditor.openIndexes(self._indexesToOpen, newTab=True) - + def expandCurrentIndex(self, index=None): if index is None or type(index) == bool: - index = self._indexesToOpen[0] #self.currentIndex() - + index = self._indexesToOpen[0] # self.currentIndex() + self.expand(index) for i in range(self.model().rowCount(index)): idx = self.model().index(i, 0, index) - self.expandCurrentIndex(index=idx) - + self.expandCurrentIndex(index=idx) + def collapseCurrentIndex(self, index=None): if index is None or type(index) == bool: - index = self._indexesToOpen[0] #self.currentIndex() - + index = self._indexesToOpen[0] # self.currentIndex() + self.collapse(index) for i in range(self.model().rowCount(index)): idx = self.model().index(i, 0, index) self.collapseCurrentIndex(index=idx) - + def dragMoveEvent(self, event): dndView.dragMoveEvent(self, event) QTreeView.dragMoveEvent(self, event) - + def mousePressEvent(self, event): if event.button() == Qt.RightButton: # Capture mouse press so that selection doesn't change # on right click pass else: - QTreeView.mousePressEvent(self, event) \ No newline at end of file + QTreeView.mousePressEvent(self, event) diff --git a/manuskript/ui/welcome.py b/manuskript/ui/welcome.py index 6650590..81a2d0c 100644 --- a/manuskript/ui/welcome.py +++ b/manuskript/ui/welcome.py @@ -1,16 +1,22 @@ #!/usr/bin/env python -#--!-- 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 +# --!-- coding: utf8 --!-- + import locale 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, '') @@ -19,9 +25,9 @@ class welcome(QWidget, Ui_welcome): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) - + self.template = [] - + self.mw = mainWindow() self.btnOpen.clicked.connect(self.openFile) self.btnCreate.clicked.connect(self.createFile) @@ -29,31 +35,31 @@ class welcome(QWidget, Ui_welcome): self.tree.itemActivated.connect(self.changeTemplate) self.btnAddLevel.clicked.connect(self.templateAddLevel) self.btnAddWC.clicked.connect(self.templateAddWordCount) - + self.populateTemplates() - + def updateValues(self): # Auto load autoLoad, last = self.getAutoLoadValues() self.chkLoadLastProject.setChecked(autoLoad) - + # Recent Files self.loadRecents() -############################################################################### -# AUTOLOAD -############################################################################### - + ############################################################################### + # AUTOLOAD + ############################################################################### + def showEvent(self, event): """Waiting for things to be fully loaded to start opening projects.""" QWidget.showEvent(self, event) - + # Auto load last project autoLoad, last = self.getAutoLoadValues() - + if autoLoad and last: self.mw.loadProject(last) - + def getAutoLoadValues(self): sttgns = QSettings() if sttgns.contains("autoLoad"): @@ -64,16 +70,16 @@ class welcome(QWidget, Ui_welcome): last = sttgns.value("lastProject") else: last = "" - + return autoLoad, last - + def setAutoLoad(self, v): QSettings().setValue("autoLoad", v) -############################################################################### -# RECENTS -############################################################################### - + ############################################################################### + # RECENTS + ############################################################################### + def loadRecents(self): sttgns = QSettings() self.mw.menuRecents.setIcon(QIcon.fromTheme("folder-recent")) @@ -87,16 +93,16 @@ class welcome(QWidget, Ui_welcome): a.setStatusTip(f) a.triggered.connect(self.loadRecentFile) self.mw.menuRecents.addAction(a) - + self.btnRecent.setMenu(self.mw.menuRecents) - + def appendToRecentFiles(self, project): sttgns = QSettings() if sttgns.contains("recentFiles"): recentFiles = sttgns.value("recentFiles") else: recentFiles = [] - + while project in recentFiles: recentFiles.remove(project) recentFiles.insert(0, project) @@ -108,92 +114,92 @@ class welcome(QWidget, Ui_welcome): self.appendToRecentFiles(act.data()) self.mw.loadProject(act.data()) -############################################################################### -# DIALOGS -############################################################################### - + ############################################################################### + # DIALOGS + ############################################################################### + def openFile(self): """File dialog that request an existing file. For opening project.""" - filename = QFileDialog.getOpenFileName(self, - self.tr("Open project"), - ".", - self.tr("Manuskript project (*.msk)"))[0] + filename = QFileDialog.getOpenFileName(self, + self.tr("Open project"), + ".", + self.tr("Manuskript project (*.msk)"))[0] if filename: self.appendToRecentFiles(filename) self.mw.loadProject(filename) - + def saveAsFile(self): """File dialog that request a file, existing or not. Save datas to that file, which then becomes the current project.""" - filename = QFileDialog.getSaveFileName(self, - self.tr("Save project as..."), - ".", - self.tr("Manuskript project (*.msk)"))[0] - + filename = QFileDialog.getSaveFileName(self, + self.tr("Save project as..."), + ".", + self.tr("Manuskript project (*.msk)"))[0] + if filename: self.appendToRecentFiles(filename) self.mw.saveDatas(filename) - + def createFile(self): """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.""" - filename = QFileDialog.getSaveFileName(self, - self.tr("Create New Project"), - ".", - self.tr("Manuskript project (*.msk)"))[0] - + filename = QFileDialog.getSaveFileName(self, + self.tr("Create New Project"), + ".", + self.tr("Manuskript project (*.msk)"))[0] + if filename: self.appendToRecentFiles(filename) self.loadDefaultDatas() self.mw.loadProject(filename, loadFromFile=False) -############################################################################### -# TEMPLATES -############################################################################### - + ############################################################################### + # TEMPLATES + ############################################################################### + def templates(self): return [ (self.tr("Empty"), []), (self.tr("Novel"), [ - ( 20, self.tr("Chapter")), - ( 5, self.tr("Scene")), - ( 500, None) # A line with None is word count - ]), + (20, self.tr("Chapter")), + (5, self.tr("Scene")), + (500, None) # A line with None is word count + ]), (self.tr("Novella"), [ - ( 10, self.tr("Chapter")), - ( 5, self.tr("Scene")), - ( 500, None) - ]), + (10, self.tr("Chapter")), + (5, self.tr("Scene")), + (500, None) + ]), (self.tr("Short Story"), [ - ( 10, self.tr("Scene")), + (10, self.tr("Scene")), (1000, None) - ]), + ]), (self.tr("Trilogy"), [ - ( 3, self.tr("Book")), - ( 3, self.tr("Section")), - ( 10, self.tr("Chapter")), - ( 5, self.tr("Scene")), - ( 500, None) - ]), + (3, self.tr("Book")), + (3, self.tr("Section")), + (10, self.tr("Chapter")), + (5, self.tr("Scene")), + (500, None) + ]), (self.tr("Research paper"), [ - ( 3, self.tr("Section")), + (3, self.tr("Section")), (1000, None) - ]) - ] - + ]) + ] + def defaultTextType(self): return [ ("t2t", self.tr("Txt2Tags"), "text-x-generic"), ("html", self.tr("Rich Text (html)"), "text-html"), ("txt", self.tr("Plain Text"), "text-x-generic"), - ] - + ] + def changeTemplate(self, item, column): template = [i for i in self.templates() if i[0] == item.text(0)] if len(template): self.template = template[0][1] self.updateTemplate() - + def updateTemplate(self): # Clear layout def clearLayout(l): @@ -203,13 +209,13 @@ class welcome(QWidget, Ui_welcome): i.widget().deleteLater() if i.layout(): clearLayout(i.layout()) - + clearLayout(self.lytTemplate) - - #self.templateLayout.addStretch() - #l = QGridLayout() - #self.templateLayout.addLayout(l) - + + # self.templateLayout.addStretch() + # l = QGridLayout() + # self.templateLayout.addLayout(l) + k = 0 hasWC = False for d in self.template: @@ -217,70 +223,69 @@ class welcome(QWidget, Ui_welcome): spin.setRange(0, 999999) spin.setValue(d[0]) spin.valueChanged.connect(self.updateWordCount) - + if d[1] != None: txt = QLineEdit(self) txt.setText(d[1]) - + else: hasWC = True txt = QLabel(self.tr("words each."), self) - + if k != 0: of = QLabel(self.tr("of"), self) self.lytTemplate.addWidget(of, k, 0) - + btn = QPushButton("", self) btn.setIcon(QIcon.fromTheme("edit-delete")) btn.setProperty("deleteRow", k) btn.clicked.connect(self.deleteTemplateRow) - + self.lytTemplate.addWidget(btn, k, 3) - - + self.lytTemplate.addWidget(spin, k, 1) self.lytTemplate.addWidget(txt, k, 2) k += 1 - + self.btnAddWC.setEnabled(not hasWC and len(self.template) > 0) self.btnAddLevel.setEnabled(True) self.lblTotal.setVisible(hasWC) self.updateWordCount() - + def templateAddLevel(self): 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 self.template.insert(len(self.template) - 1, (10, self.tr("Text"))) else: # No word count, so insert at end self.template.append((10, self.tr("Something"))) self.updateTemplate() - + def templateAddWordCount(self): self.template.append((500, None)) self.updateTemplate() - + def deleteTemplateRow(self): btn = self.sender() row = btn.property("deleteRow") self.template.pop(row) self.updateTemplate() - + def updateWordCount(self): total = 1 for s in self.findChildren(QSpinBox, QRegExp(".*"), Qt.FindChildrenRecursively): total = total * s.value() - - if total == 1: + + if total == 1: total = 0 - + self.lblTotal.setText(self.tr("Total: {} words (~ {} pages)").format( - locale.format("%d", total, grouping=True), - locale.format("%d", total / 250, grouping=True) + locale.format("%d", total, grouping=True), + locale.format("%d", total / 250, grouping=True) )) - + def addTopLevelItem(self, name): item = QTreeWidgetItem(self.tree, [name]) item.setBackground(0, QBrush(QColor(Qt.blue).lighter(190))) @@ -291,45 +296,45 @@ class welcome(QWidget, Ui_welcome): f.setBold(True) item.setFont(0, f) return item - + def populateTemplates(self): self.tree.clear() self.tree.setIndentation(0) - + # Add templates item = self.addTopLevelItem(self.tr("Templates")) templates = self.templates() for t in templates: sub = QTreeWidgetItem(item, [t[0]]) - + # Add Demo project item = self.addTopLevelItem(self.tr("Demo projects")) # FIXME: none yet - + # Populates default text type self.cmbDefaultType.clear() for t in self.defaultTextType(): self.cmbDefaultType.addItem(QIcon.fromTheme(t[2]), t[1], t[0]) - + self.tree.expandAll() - + def loadDefaultDatas(self): - + # Empty settings imp.reload(settings) - + # Données self.mw.mdlFlatData = QStandardItemModel(2, 8, self.mw) # Persos - #self.mw.mdlPersos = QStandardItemModel(0, 0, self.mw) + # self.mw.mdlPersos = QStandardItemModel(0, 0, self.mw) self.mw.mdlPersos = persosModel(self.mw) - #self.mdlPersosProxy = None # persosProxyModel() # None - #self.mw.mdlPersosProxy = persosProxyModel(self.mw) + # self.mdlPersosProxy = None # persosProxyModel() # None + # self.mw.mdlPersosProxy = persosProxyModel(self.mw) - #self.mw.mdlPersosInfos = QStandardItemModel(1, 0, self.mw) - #self.mw.mdlPersosInfos.insertColumn(0, [QStandardItem("ID")]) - #self.mw.mdlPersosInfos.setHorizontalHeaderLabels(["Description"]) + # self.mw.mdlPersosInfos = QStandardItemModel(1, 0, self.mw) + # self.mw.mdlPersosInfos.insertColumn(0, [QStandardItem("ID")]) + # self.mw.mdlPersosInfos.setHorizontalHeaderLabels(["Description"]) # Labels self.mw.mdlLabels = QStandardItemModel(self.mw) @@ -340,18 +345,18 @@ class welcome(QWidget, Ui_welcome): (Qt.blue, self.tr("Chapter")), (Qt.red, self.tr("Scene")), (Qt.cyan, self.tr("Research")) - ]: + ]: self.mw.mdlLabels.appendRow(QStandardItem(iconFromColor(color), text)) # Status self.mw.mdlStatus = QStandardItemModel(self.mw) for text in [ - "", - self.tr("TODO"), - self.tr("First draft"), - self.tr("Second draft"), - self.tr("Final") - ]: + "", + self.tr("TODO"), + self.tr("First draft"), + self.tr("Second draft"), + self.tr("Final") + ]: self.mw.mdlStatus.appendRow(QStandardItem(text)) # Plot @@ -359,38 +364,37 @@ class welcome(QWidget, Ui_welcome): # Outline self.mw.mdlOutline = outlineModel(self.mw) - + root = self.mw.mdlOutline.rootItem _type = self.cmbDefaultType.currentData() settings.defaultTextType = _type - + def addElement(parent, datas): if len(datas) == 2 and datas[1][1] == None or \ - len(datas) == 1: + len(datas) == 1: # Next item is word count n = 0 - for i in range(datas[0][0]): + for i in range(datas[0][0]): n += 1 item = outlineItem(title="{} {}".format( - datas[0][1], - str(n)), - _type=_type, - parent=parent) + datas[0][1], + str(n)), + _type=_type, + parent=parent) if len(datas) == 2: item.setData(Outline.setGoal.value, datas[1][0]) - #parent.appendChild(item) + # parent.appendChild(item) else: n = 0 for i in range(datas[0][0]): n += 1 item = outlineItem(title="{} {}".format( - datas[0][1], - str(n)), - _type="folder", - parent=parent) - #parent.appendChild(item) + datas[0][1], + str(n)), + _type="folder", + parent=parent) + # parent.appendChild(item) addElement(item, datas[1:]) - + if self.template: addElement(root, self.template) - \ No newline at end of file