Restore revisions, and better html output

This commit is contained in:
Olivier Keshavjee 2015-07-04 10:54:06 +02:00
parent 3f175f2d4b
commit 92b270c651
7 changed files with 121 additions and 63 deletions

Binary file not shown.

View file

@ -214,7 +214,7 @@
<translation>Contexte</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1022"/>
<location filename="../src/mainWindow.py" line="1042"/>
<source>Outline</source>
<translation>Plan</translation>
</message>
@ -329,62 +329,62 @@
<translation>Mode</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="854"/>
<location filename="../src/mainWindow.py" line="875"/>
<source> (~{} pages)</source>
<translation> (~{} pages)</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="881"/>
<location filename="../src/mainWindow.py" line="901"/>
<source>Enter infos about your book, and yourself.</source>
<translation>Entrez toutes les informations relatives au livre, ainsi qu&apos;à vous.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="887"/>
<location filename="../src/mainWindow.py" line="907"/>
<source>Take time to think about a one sentance (~50 words) summary of your book. Then expand it to a paragraph, then to a page, then to a full summary.</source>
<translation>Prenez le temps de réfléchir à un résumé de votre livre, en une phrase (~50 mots). Puis augmentez cette phrase en un paragraphe, puis en une page, puis en un résumé complet.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="890"/>
<location filename="../src/mainWindow.py" line="910"/>
<source>Create your characters.</source>
<translation>Créez ici vos personnage.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="893"/>
<location filename="../src/mainWindow.py" line="913"/>
<source>Develop plots.</source>
<translation>Développez vos intrigues.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="896"/>
<location filename="../src/mainWindow.py" line="916"/>
<source>Create the outline of your masterpiece.</source>
<translation>Créez le plan de votre chef-d&apos;œuvre.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="899"/>
<location filename="../src/mainWindow.py" line="919"/>
<source>Write.</source>
<translation>Écrivez.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="902"/>
<location filename="../src/mainWindow.py" line="922"/>
<source>Debug infos. Sometimes useful.</source>
<translation>Des infos pour débugger des fois pendant qu&apos;on code c&apos;est utile.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="916"/>
<location filename="../src/mainWindow.py" line="936"/>
<source>Dictionary</source>
<translation>Dictionnaire</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="929"/>
<location filename="../src/mainWindow.py" line="949"/>
<source>Install PyEnchant to use spellcheck</source>
<translation>Installez PyEnchant pour profiter du correcteur orthographique</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="858"/>
<location filename="../src/mainWindow.py" line="879"/>
<source>Words: {}{}</source>
<translation>Mots: {}{}</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1033"/>
<location filename="../src/mainWindow.py" line="1053"/>
<source>Text</source>
<translation>Texte</translation>
</message>
@ -424,7 +424,7 @@
<translation>Et si...?</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1021"/>
<location filename="../src/mainWindow.py" line="1041"/>
<source>Index cards</source>
<translation>Cartes</translation>
</message>
@ -444,7 +444,7 @@
<translation>F9</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1020"/>
<location filename="../src/mainWindow.py" line="1040"/>
<source>Tree</source>
<translation>Arbre</translation>
</message>
@ -469,77 +469,77 @@
<translation>Réglages</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="512"/>
<location filename="../src/mainWindow.py" line="533"/>
<source>Project {} saved.</source>
<translation>Le projet {} a é enregistré.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="583"/>
<location filename="../src/mainWindow.py" line="604"/>
<source>Project {} loaded.</source>
<translation>Le projet {} a é chargé.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="884"/>
<location filename="../src/mainWindow.py" line="904"/>
<source>The basic situation, in the form of a &apos;What if...?&apos; question. Ex: &apos;What if the most dangerous evil wizard could wasn&apos;t abled to kill a baby?&apos; (Harry Potter)</source>
<translation>La situation de base, sous la forme d&apos;une question: &quot;Et si...?&quot; Par exemple: &quot;Et si le plus dangereux magiciens mauvais n&apos;était pas capable de tuer un bébé?&quot; (Harry Potter)</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1012"/>
<location filename="../src/mainWindow.py" line="1032"/>
<source>Nothing</source>
<translation>Rien</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1013"/>
<location filename="../src/mainWindow.py" line="1033"/>
<source>POV</source>
<translation>POV</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1014"/>
<location filename="../src/mainWindow.py" line="1034"/>
<source>Label</source>
<translation>Label</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1015"/>
<location filename="../src/mainWindow.py" line="1035"/>
<source>Progress</source>
<translation>Progrès</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1016"/>
<location filename="../src/mainWindow.py" line="1036"/>
<source>Compile</source>
<translation>Compilation</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1039"/>
<location filename="../src/mainWindow.py" line="1059"/>
<source>Icon color</source>
<translation>Couleur de l&apos;icone</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1040"/>
<location filename="../src/mainWindow.py" line="1060"/>
<source>Text color</source>
<translation>Couleur du texte</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1041"/>
<location filename="../src/mainWindow.py" line="1061"/>
<source>Background color</source>
<translation>Couleur de l&apos;arrière-plan</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1032"/>
<location filename="../src/mainWindow.py" line="1052"/>
<source>Icon</source>
<translation>Icone</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1034"/>
<location filename="../src/mainWindow.py" line="1054"/>
<source>Background</source>
<translation>Arrière-plan</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1035"/>
<location filename="../src/mainWindow.py" line="1055"/>
<source>Border</source>
<translation>Bordure</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="1036"/>
<location filename="../src/mainWindow.py" line="1056"/>
<source>Corner</source>
<translation>Coin</translation>
</message>
@ -554,17 +554,17 @@
<translation>Le fichier {} n&apos;existe pas. Essayez encore.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="586"/>
<location filename="../src/mainWindow.py" line="607"/>
<source>Project {} loaded with some errors:</source>
<translation>Le projet {} a é chargé, avec des erreurs:</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="588"/>
<location filename="../src/mainWindow.py" line="609"/>
<source> * {} wasn&apos;t found in project file.</source>
<translation>* {} n&apos;a pas é trouvé dans le fichier du projet.</translation>
</message>
<message>
<location filename="../src/mainWindow.py" line="589"/>
<location filename="../src/mainWindow.py" line="610"/>
<source>Project {} loaded with some errors.</source>
<translation>Le projet {} a é chargé avec des erreurs.</translation>
</message>
@ -1826,27 +1826,27 @@ des lignes:</translation>
<translation>Supprimer</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="93"/>
<location filename="../src/ui/revisions.py" line="98"/>
<source>1 day ago</source>
<translation>Il y a un jour</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="95"/>
<location filename="../src/ui/revisions.py" line="100"/>
<source>{} days ago</source>
<translation>Il y a {} jours</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="97"/>
<location filename="../src/ui/revisions.py" line="102"/>
<source>{} hours ago</source>
<translation>Il y a {} heures</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="99"/>
<location filename="../src/ui/revisions.py" line="104"/>
<source>{} minutes ago</source>
<translation>Il y a {} minutes</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="101"/>
<location filename="../src/ui/revisions.py" line="106"/>
<source>{} seconds ago</source>
<translation>Il y a {} secondes</translation>
</message>
@ -1856,25 +1856,30 @@ des lignes:</translation>
<translation>Options</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="29"/>
<location filename="../src/ui/revisions.py" line="34"/>
<source>Show modifications</source>
<translation>Montrer les modifications</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="36"/>
<location filename="../src/ui/revisions.py" line="41"/>
<source>Show ancient version</source>
<translation>Montrer la version ancienne</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="44"/>
<location filename="../src/ui/revisions.py" line="49"/>
<source>Show spaces</source>
<translation>Montrer les espaces</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="50"/>
<location filename="../src/ui/revisions.py" line="55"/>
<source>Show modifications only</source>
<translation>Montrer les modifications seulement</translation>
</message>
<message>
<location filename="../src/ui/revisions.py" line="171"/>
<source>Line {}:</source>
<translation>Ligne {}:</translation>
</message>
</context>
<context>
<name>settingsWindow</name>

View file

@ -457,6 +457,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
if sttgns.contains("searchState"):
state = False if sttgns.value("searchState") == "false" else True
self.grpSearch.restoreState(state)
if sttgns.contains("revisionsState"):
state = [False if v == "false" else True for v in sttgns.value("revisionsState")]
self.redacMetadata.revisions.restoreState(state)
def closeEvent(self, event):
@ -469,6 +472,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
sttgns.setValue("redacInfosState", self.tabRedacInfos.currentIndex())
sttgns.setValue("cheatSheetState", self.grpCheatSheet.saveState())
sttgns.setValue("searchState", self.grpSearch.saveState())
sttgns.setValue("revisionsState", self.redacMetadata.revisions.saveState())
# Specific settings to save before quitting
settings.lastTab = self.tabMain.currentIndex()

View file

@ -9,6 +9,7 @@ from functions import *
import models.references as Ref
import datetime
import difflib
import re
class revisions(QWidget, Ui_revisions):
@ -21,6 +22,10 @@ class revisions(QWidget, Ui_revisions):
self.listDelegate = listCompleterDelegate(self)
self.list.setItemDelegate(self.listDelegate)
self.list.itemActivated.connect(self.showDiff)
self.btnDelete.setEnabled(False)
self.btnRestore.clicked.connect(self.restore)
self.btnRestore.setEnabled(False)
#self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.menu = QMenu(self)
@ -101,12 +106,21 @@ class revisions(QWidget, Ui_revisions):
return self.tr("{} seconds ago").format(str(delta.seconds))
def showDiff(self):
#FIXME: doesn't work for HTML formatting.
# UI stuff
self.actShowSpaces.setEnabled(self.actShowDiff.isChecked())
self.actDiffOnly.setEnabled(self.actShowDiff.isChecked())
#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()
@ -145,25 +159,40 @@ class revisions(QWidget, Ui_revisions):
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 += "<br>{}:<br>".format(str(n))
mydiff += "<br><span style='color: blue;'>{}</span><br>".format(
self.tr("Line {}:").format(str(n)))
s = difflib.SequenceMatcher(None, txt, txt2, autojunk=False)
newline = ""
for tag, i1, i2, j1, j2 in s.get_opcodes():
if tag == "equal":
mydiff += txt[i1:i2]
newline += txt[i1:i2]
elif tag == "delete":
mydiff += "<span style='color:red;'>{}</span>".format(_format(txt[i1:i2]))
newline += "<span style='color:red;'>{}</span>".format(_format(txt[i1:i2]))
elif tag == "insert":
mydiff += "<span style='color:green;'>{}</span>".format(_format(txt2[j1:j2]))
newline += "<span style='color:green;'>{}</span>".format(_format(txt2[j1:j2]))
elif tag == "replace":
mydiff += "<span style='color:red;'>{}</span>".format(_format(txt[i1:i2]))
mydiff += "<span style='color:green;'>{}</span>".format(_format(txt2[j1:j2]))
mydiff += extra
newline += "<span style='color:red;'>{}</span>".format(_format(txt[i1:i2]))
newline += "<span style='color:green;'>{}</span>".format(_format(txt2[j1:j2]))
# Few ugly tweaks for html diffs
newline = re.sub(r"(<span style='color.*?><span.*?>)</span>(.*)<span style='color:.*?>(</span></span>)",
"\\1\\2\\3", newline)
newline = re.sub(r"<p align=\"<span style='color:red;'>cen</span><span style='color:green;'>righ</span>t<span style='color:red;'>er</span>\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*?)</p>",
"<p align=\"right\"><span style='color:green;'>\\1</span></p>", newline)
newline = re.sub(r"<p align=\"<span style='color:green;'>cente</span>r<span style='color:red;'>ight</span>\" style=\" -qt-block-indent:0; -qt-user-state:0; \">(.*)</p>",
"<p align=\"center\"><span style='color:green;'>\\1</span></p>", newline)
newline = re.sub(r"<p(<span.*?>)(.*?)(</span>)(.*?)>(.*?)</p>",
"<p\\2\\4>\\1\\5\\3</p>", newline)
mydiff += newline + extra
skip = True
elif op == "- ":
if self.actDiffOnly.isChecked():
@ -176,6 +205,34 @@ class revisions(QWidget, Ui_revisions):
self.view.setText(mydiff)
def restore(self):
i = self.list.currentItem()
if not i:
return
ts = i.data(Qt.UserRole)
item = self._index.internalPointer()
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)
def saveState(self):
return [
self.actShowDiff.isChecked(),
self.actShowVersion.isChecked(),
self.actShowSpaces.isChecked(),
self.actDiffOnly.isChecked(),
]
def restoreState(self, state):
self.actShowDiff.setChecked(state[0])
self.actShowVersion.setChecked(state[1])
self.actShowSpaces.setChecked(state[2])
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):

View file

@ -57,11 +57,9 @@ class Ui_revisions(object):
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem)
self.btnRestore = QtWidgets.QPushButton(self.layoutWidget)
self.btnRestore.setEnabled(False)
self.btnRestore.setObjectName("btnRestore")
self.horizontalLayout_2.addWidget(self.btnRestore)
self.btnDelete = QtWidgets.QPushButton(self.layoutWidget)
self.btnDelete.setEnabled(False)
self.btnDelete.setObjectName("btnDelete")
self.horizontalLayout_2.addWidget(self.btnDelete)
self.verticalLayout_2.addWidget(self.splitter)

View file

@ -93,9 +93,6 @@
</item>
<item>
<widget class="QPushButton" name="btnRestore">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restore</string>
</property>
@ -103,9 +100,6 @@
</item>
<item>
<widget class="QPushButton" name="btnDelete">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Delete</string>
</property>

View file

@ -79,11 +79,11 @@ class metadataView(QWidget, Ui_metadataView):
self.grpSummary.saveState(),
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]),
self.grpProperties.restoreState(state[0])
self.grpSummary.restoreState(state[1])
self.grpNotes.restoreState(state[2])
self.grpRevisions.restoreState(state[3])