diff --git a/i18n/manuskript.pro b/i18n/manuskript.pro
index bddda7ba..258b7cc6 100644
--- a/i18n/manuskript.pro
+++ b/i18n/manuskript.pro
@@ -4,6 +4,7 @@ FORMS += ../src/ui/welcome_ui.ui
FORMS += ../src/ui/sldImportance_ui.ui
FORMS += ../src/ui/cheatSheet_ui.ui
FORMS += ../src/ui/compileDialog_ui.ui
+FORMS += ../src/ui/revisions_ui.ui
FORMS += ../src/ui/editors/editorWidget_ui.ui
@@ -29,6 +30,7 @@ SOURCES += ../src/ui/sldImportance.py
SOURCES += ../src/ui/welcome.py
SOURCES += ../src/ui/cheatSheet.py
SOURCES += ../src/ui/compileDialog.py
+SOURCES += ../src/ui/revisions.py
SOURCES += ../src/ui/editors/editorWidget.py
SOURCES += ../src/ui/editors/fullScreenEditor.py
diff --git a/i18n/manuskript_fr.qm b/i18n/manuskript_fr.qm
index e44b993f..555063f1 100644
Binary files a/i18n/manuskript_fr.qm and b/i18n/manuskript_fr.qm differ
diff --git a/i18n/manuskript_fr.ts b/i18n/manuskript_fr.ts
index ef021c3a..bc4341ed 100644
--- a/i18n/manuskript_fr.ts
+++ b/i18n/manuskript_fr.ts
@@ -214,7 +214,7 @@
Contexte
-
+
Plan
@@ -329,62 +329,62 @@
Mode
-
+
(~{} pages)
-
+
Entrez toutes les informations relatives au livre, ainsi qu'à vous.
-
+
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.
-
+
Créez ici vos personnage.
-
+
Développez vos intrigues.
-
+
Créez le plan de votre chef-d'œuvre.
-
+
Écrivez.
-
+
Des infos pour débugger des fois pendant qu'on code c'est utile.
-
+
Dictionnaire
-
+
Installez PyEnchant pour profiter du correcteur orthographique
-
+
Mots: {}{}
-
+
Texte
@@ -424,7 +424,7 @@
Et si...?
-
+
Cartes
@@ -444,7 +444,7 @@
F9
-
+
Arbre
@@ -469,77 +469,77 @@
Réglages
-
+
Le projet {} a été enregistré.
-
+
Le projet {} a été chargé.
-
+
La situation de base, sous la forme d'une question: "Et si...?" Par exemple: "Et si le plus dangereux magiciens mauvais n'était pas capable de tuer un bébé?" (Harry Potter)
-
+
Rien
-
+
POV
-
+
Label
-
+
Progrès
-
+
Compilation
-
+
Couleur de l'icone
-
+
Couleur du texte
-
+
Couleur de l'arrière-plan
-
+
Icone
-
+
Arrière-plan
-
+
Bordure
-
+
Coin
@@ -549,22 +549,22 @@
Fermer le projet
-
+
Le fichier {} n'existe pas. Essayez encore.
-
+
Le projet {} a été chargé, avec des erreurs:
-
+
* {} n'a pas été trouvé dans le fichier du projet.
-
+
Le projet {} a été chargé avec des erreurs.
@@ -1051,7 +1051,7 @@ des lignes:
SpellAction
-
+
Suggestions
@@ -1115,27 +1115,27 @@ des lignes:
Filtre
-
+
Mineur
-
+
Secondaire
-
+
Principal
-
+
Personnages
-
+
Textes
@@ -1323,17 +1323,17 @@ des lignes:
mainEditor
-
+
Racine
-
+
{} mots / {}
-
+
{} mots
@@ -1362,8 +1362,13 @@ des lignes:
-
- Notes
+
+ Notes / Références
+
+
+
+
+ Révisions
@@ -1442,47 +1447,47 @@ des lignes:
outlineModel
-
+
Titre
-
+
POV
-
+
Label
-
+
Status
-
+
Compilation
-
+
Nombre de mots
-
+
Goal
-
+
{} mots / {} ({})
-
+
{} mots
@@ -1549,27 +1554,27 @@ des lignes:
plotModel
-
+
Nouvelle intrigue
-
+
Nouvelle sous-intrigue
-
+
Principale
-
+
Secondaire
-
+
Mineure
@@ -1577,20 +1582,25 @@ des lignes:
plotTreeView
-
+
Principale
-
+
Secondaire
-
+
Mineure
+
+
+
+ **Intrigue:** {}
+
propertiesView
@@ -1638,111 +1648,154 @@ des lignes:
references
-
+
Référence inconnue: {}.
-
+
Texte: <b>{}</b>
-
+
Personnage: <b>{}</b>
-
+
Informations générales
-
+
Informations détaillées
-
+
POV de:
-
+
Référencé dans:
-
+
Motivation
-
+
Goal
-
+
Conflit
-
+
Épiphanie
-
+
Résumé court
-
+
Résumé long
-
+
Chemin:
-
+
Stats:
-
+
POV:
-
+
Status:
-
+
Label:
-
+
Résumé court:
-
+
Résumé long:
-
+
Notes:
+
+ revisions
+
+
+
+ Form
+
+
+
+
+ Restaurer
+
+
+
+
+ Supprimer
+
+
+
+
+ Il y a un jour
+
+
+
+
+ Il y a {} jours
+
+
+
+
+ Il y a {} heures
+
+
+
+
+ Il y a {} minutes
+
+
+
+
+ Il y a {} secondes
+
+
settingsWindow
@@ -1812,7 +1865,7 @@ des lignes:
textEditView
-
+
Différentes valeurs
diff --git a/src/enums.py b/src/enums.py
index e30189b6..ef4c0590 100644
--- a/src/enums.py
+++ b/src/enums.py
@@ -52,4 +52,5 @@ class Outline(Enum):
setGoal = 14 # The goal set by the user, if any. Can be different from goal which can be computed
# (sum of all sub-items' goals)
textFormat = 15
+ revisions = 16
diff --git a/src/models/outlineModel.py b/src/models/outlineModel.py
index c7913243..f33748b8 100644
--- a/src/models/outlineModel.py
+++ b/src/models/outlineModel.py
@@ -8,7 +8,8 @@ from lxml import etree as ET
from functions import *
import locale
locale.setlocale(locale.LC_ALL, '')
-
+import time
+import collections
class outlineModel(QAbstractItemModel):
@@ -461,6 +462,9 @@ class outlineItem():
if Outline(column) in self._data:
return self._data[Outline(column)]
+ elif column == Outline.revisions.value:
+ return []
+
else:
return ""
@@ -523,6 +527,9 @@ class outlineItem():
elif oldType in ["txt", "t2t"] and data == "html" and Outline.text in self._data:
self._data[Outline.text] = self._data[Outline.text].replace("\n", "
")
+ elif column == Outline.text.value:
+ self.addRevision()
+
# Setting data
self._data[Outline(column)] = data
@@ -706,11 +713,16 @@ class outlineItem():
return qApp.translate("outlineModel", "{} words").format(
locale.format("%d", wc, grouping=True))
+
+###############################################################################
+# XML
+###############################################################################
+
def toXML(self):
item = ET.Element("outlineItem")
# We don't want to write some datas (computed)
- exclude = [Outline.wordCount, Outline.goal, Outline.goalPercentage]
+ exclude = [Outline.wordCount, Outline.goal, Outline.goalPercentage, Outline.revisions]
# We want to force some data even if they're empty
force = [Outline.compile]
@@ -719,6 +731,14 @@ class outlineItem():
val = self.data(attrib.value)
if val or attrib in force:
item.set(attrib.name, str(val))
+
+ # Saving revisions
+ rev = self.revisions()
+ for r in rev:
+ revItem = ET.Element("revision")
+ revItem.set("timestamp", str(r[0]))
+ revItem.set("text", r[1])
+ item.append(revItem)
for i in self.childItems:
item.append(ET.XML(i.toXML()))
@@ -736,7 +756,15 @@ class outlineItem():
self.setData(Outline.__members__[k].value, str(root.attrib[k]))
for child in root:
- item = outlineItem(self._model, xml=ET.tostring(child), parent=self)
+ if child.tag == "outlineItem":
+ item = outlineItem(self._model, xml=ET.tostring(child), parent=self)
+ elif child.tag == "revision":
+ self.appendRevision(child.attrib["timestamp"], child.attrib["text"])
+
+
+###############################################################################
+# IDS
+###############################################################################
def getUniqueID(self):
self.setData(Outline.ID.value, self._model.rootItem.findUniqueID())
@@ -821,4 +849,74 @@ class outlineItem():
for c in self.children():
lst.extend(c.findItemsContaining(text, columns, mainWindow, caseSensitive))
- return lst
\ No newline at end of file
+ return lst
+
+###############################################################################
+# REVISIONS
+###############################################################################
+
+ def revisions(self):
+ return self.data(Outline.revisions.value)
+
+ def appendRevision(self, ts, text):
+ if not Outline.revisions in self._data:
+ self._data[Outline.revisions] = []
+
+ self._data[Outline.revisions].append((
+ int(ts),
+ text))
+
+ def addRevision(self):
+ # FIXME: only add if significantly different, or enough time span
+
+ if not Outline.text in self._data:
+ return
+
+ self.appendRevision(
+ time.time(),
+ self._data[Outline.text])
+
+ self.cleanRevisions()
+
+ def cleanRevisions(self):
+ "Keep only one some the revisions."
+ rev = self.revisions()
+ rev2 = []
+ now = time.time()
+
+ rule = collections.OrderedDict()
+ rule[5 * 60] = 60 # One per minute for the last 5mn
+ rule[60 * 60] = 60 * 10 # One per 10mn for the last hour
+ rule[60 * 60 * 24] = 60 * 60 # One per hour for the last day
+ rule[60 * 60 * 24 * 30] = 60 * 60 * 24 # One per day for the last month
+ rule[None] = 60 * 60 * 24 * 7 # One per week for eternity
+
+ revs = {}
+ for i in rule:
+ revs[i] = []
+
+ for r in rev:
+ for span in rule:
+ if not span or now - r[0] < span:
+ revs[span].append(r)
+ break
+
+ for span in revs:
+ sortedRev = sorted(revs[span], key=lambda x:x[0])
+ last = None
+ for r in sortedRev:
+ if not last:
+ rev2.append(r)
+ last = r[0]
+ elif r[0] - last >= rule[span]:
+ rev2.append(r)
+ last = r[0]
+
+ if rev2 != rev:
+ self._data[Outline.revisions] = rev2
+ self.emitDataChanged([Outline.revisions.value])
+
+
+
+
+
\ No newline at end of file
diff --git a/src/models/references.py b/src/models/references.py
index 6814d848..7a5b0c5e 100644
--- a/src/models/references.py
+++ b/src/models/references.py
@@ -266,11 +266,21 @@ def refToLink(ref):
def linkifyAllRefs(text):
return re.sub(RegEx, lambda m: refToLink(m.group(0)), text)
-def basicT2TFormat(text):
- text = re.sub("\*\*(.*?)\*\*", "\\1", text)
- text = re.sub("//(.*?)//", "\\1", text)
- text = re.sub("__(.*?)__", "\\1", text)
- text = text.replace("\n", "
")
+def basicT2TFormat(text, formatting=True, EOL=True, titles=True):
+ if formatting:
+ text = re.sub("\*\*(.*?)\*\*", "\\1", text)
+ text = re.sub("//(.*?)//", "\\1", text)
+ text = re.sub("__(.*?)__", "\\1", text)
+ if titles:
+ for i in range(1, 6):
+ r1 = '^\s*{s}([^=].*[^=]){s}\s*$'.format(s="=" * i)
+ r2 = '^\s*{s}([^\+].*[^\+]){s}\s*$'.format(s="\\+" * i)
+ t = "\\1".format(n=i)
+ text = re.sub(r1, t, text)
+ text = re.sub(r2, t, text)
+ if EOL:
+ text = text.replace("\n", "
")
+
return text
def open(ref):
diff --git a/src/ui/revisions.py b/src/ui/revisions.py
new file mode 100644
index 00000000..bf5c5ba2
--- /dev/null
+++ b/src/ui/revisions.py
@@ -0,0 +1,152 @@
+#!/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
+import datetime
+import difflib
+
+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)
+ #self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+
+ 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()
+
+ 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)
+ 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)
+ self.list.addItem(i)
+
+ def readableDelta(self, timestamp):
+ now = datetime.datetime.now()
+ delta = now - datetime.datetime.fromtimestamp(timestamp)
+ if delta.days == 1:
+ return self.tr("1 day ago")
+ elif delta.days > 0:
+ return self.tr("{} days ago").format(str(delta.days))
+ elif delta.seconds > 60 * 60:
+ return self.tr("{} hours ago").format(str(int(delta.seconds / 60 / 60)))
+ elif delta.seconds > 60:
+ return self.tr("{} minutes ago").format(str(int(delta.seconds / 60)))
+ else:
+ return self.tr("{} seconds ago").format(str(delta.seconds))
+
+ def showDiff(self):
+ #FIXME: doesn't work for HTML formatting.
+ i = self.list.currentItem()
+ 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]
+
+ textNow = textNow.splitlines()
+ textBefore = textBefore.splitlines()
+
+ d = difflib.Differ()
+ diff = list(d.compare(textBefore, textNow))
+
+ extra = "" if item.type() == "html" else "
"
+ diff = [d for d in diff if d and not d[:2] == "? "]
+ mydiff = ""
+ skip = False
+ for n in range(len(diff)):
+ 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
+
+ if skip:
+ skip = False
+ continue
+
+ if op == " ":
+ if item.type() == "t2t":
+ txt = Ref.basicT2TFormat(txt)
+ mydiff += "{}{}".format(txt, extra)
+ elif op == "- " and op2 == "+ ":
+ s = difflib.SequenceMatcher(None, txt, txt2, autojunk=False)
+ for tag, i1, i2, j1, j2 in s.get_opcodes():
+ if tag == "equal":
+ mydiff += txt[i1:i2]
+ elif tag == "delete":
+ mydiff += "{}".format(txt[i1:i2].replace(" ", "␣"))
+ elif tag == "insert":
+ mydiff += "{}".format(txt2[j1:j2].replace(" ", "␣"))
+ elif tag == "replace":
+ mydiff += "{}".format(txt[i1:i2].replace(" ", "␣"))
+ mydiff += "{}".format(txt2[j1:j2].replace(" ", "␣"))
+ mydiff += extra
+ skip = True
+ elif op == "- ":
+ mydiff += "{}{}".format(txt, extra)
+ elif op == "+ ":
+ mydiff += "{}{}".format(txt, extra)
+
+ self.view.setText(mydiff)
+
+
+class listCompleterDelegate(QStyledItemDelegate):
+ def __init__(self, parent=None):
+ QStyledItemDelegate.__init__(self, parent)
+
+ def paint(self, painter, option, index):
+ 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)
+ r.setLeft(r.left() + w)
+ painter.save()
+ painter.setPen(Qt.gray)
+ painter.drawText(r, Qt.AlignLeft, extra)
+ painter.restore()
\ No newline at end of file
diff --git a/src/ui/revisions_ui.py b/src/ui/revisions_ui.py
new file mode 100644
index 00000000..54119423
--- /dev/null
+++ b/src/ui/revisions_ui.py
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'src/ui/revisions_ui.ui'
+#
+# Created by: PyQt5 UI code generator 5.4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_revisions(object):
+ def setupUi(self, revisions):
+ revisions.setObjectName("revisions")
+ revisions.resize(400, 344)
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(revisions)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.splitter = QtWidgets.QSplitter(revisions)
+ self.splitter.setOrientation(QtCore.Qt.Vertical)
+ self.splitter.setObjectName("splitter")
+ self.list = QtWidgets.QListWidget(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.list.sizePolicy().hasHeightForWidth())
+ self.list.setSizePolicy(sizePolicy)
+ self.list.setObjectName("list")
+ self.scrollArea = QtWidgets.QScrollArea(self.splitter)
+ self.scrollArea.setWidgetResizable(True)
+ self.scrollArea.setObjectName("scrollArea")
+ self.scrollAreaWidgetContents = QtWidgets.QWidget()
+ self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 396, 70))
+ self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.view = QtWidgets.QLabel(self.scrollAreaWidgetContents)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.view.sizePolicy().hasHeightForWidth())
+ self.view.setSizePolicy(sizePolicy)
+ self.view.setText("")
+ self.view.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
+ self.view.setWordWrap(True)
+ self.view.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
+ self.view.setObjectName("view")
+ self.verticalLayout.addWidget(self.view)
+ self.scrollArea.setWidget(self.scrollAreaWidgetContents)
+ self.layoutWidget = QtWidgets.QWidget(self.splitter)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ 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)
+
+ self.retranslateUi(revisions)
+ QtCore.QMetaObject.connectSlotsByName(revisions)
+
+ def retranslateUi(self, revisions):
+ _translate = QtCore.QCoreApplication.translate
+ revisions.setWindowTitle(_translate("revisions", "Form"))
+ self.btnRestore.setText(_translate("revisions", "Restore"))
+ self.btnDelete.setText(_translate("revisions", "Delete"))
+
diff --git a/src/ui/revisions_ui.ui b/src/ui/revisions_ui.ui
new file mode 100644
index 00000000..51b24a8a
--- /dev/null
+++ b/src/ui/revisions_ui.ui
@@ -0,0 +1,115 @@
+
+
+ revisions
+
+
+
+ 0
+ 0
+ 400
+ 344
+
+
+
+ Form
+
+
+
+ 0
+
+ -
+
+
+ Qt::Vertical
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 396
+ 70
+
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+ true
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+ Restore
+
+
+
+ -
+
+
+ false
+
+
+ Delete
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/views/metadataView.py b/src/ui/views/metadataView.py
index 810d3582..b5f1e6fd 100644
--- a/src/ui/views/metadataView.py
+++ b/src/ui/views/metadataView.py
@@ -14,12 +14,14 @@ class metadataView(QWidget, Ui_metadataView):
self.txtSummarySentance.setColumn(Outline.summarySentance.value)
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"
@@ -42,6 +44,7 @@ class metadataView(QWidget, Ui_metadataView):
if len(indexes) == 0:
self.setEnabled(False)
+ self.revisions.setEnabled(False)
elif len(indexes) == 1:
self.setEnabled(True)
@@ -49,12 +52,15 @@ class metadataView(QWidget, Ui_metadataView):
self.txtSummarySentance.setCurrentModelIndex(idx)
self.txtSummaryFull.setCurrentModelIndex(idx)
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
diff --git a/src/ui/views/metadataView_ui.py b/src/ui/views/metadataView_ui.py
index 98b898ae..4e84d4bd 100644
--- a/src/ui/views/metadataView_ui.py
+++ b/src/ui/views/metadataView_ui.py
@@ -58,6 +58,18 @@ class Ui_metadataView(object):
self.txtNotes.setObjectName("txtNotes")
self.horizontalLayout_29.addWidget(self.txtNotes)
self.verticalLayout.addWidget(self.groupBox_6)
+ self.groupBox_7 = collapsibleGroupBox2(metadataView)
+ self.groupBox_7.setFlat(True)
+ self.groupBox_7.setCheckable(True)
+ self.groupBox_7.setObjectName("groupBox_7")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_7)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.revisions = revisions(self.groupBox_7)
+ self.revisions.setMinimumSize(QtCore.QSize(0, 50))
+ self.revisions.setObjectName("revisions")
+ self.verticalLayout_2.addWidget(self.revisions)
+ self.verticalLayout.addWidget(self.groupBox_7)
self.retranslateUi(metadataView)
QtCore.QMetaObject.connectSlotsByName(metadataView)
@@ -68,10 +80,12 @@ class Ui_metadataView(object):
self.groupBox_4.setTitle(_translate("metadataView", "Properties"))
self.groupBox_5.setTitle(_translate("metadataView", "Summary"))
self.txtSummarySentance.setPlaceholderText(_translate("metadataView", "One line summary"))
- self.groupBox_6.setTitle(_translate("metadataView", "Notes"))
+ self.groupBox_6.setTitle(_translate("metadataView", "Notes / References"))
+ self.groupBox_7.setTitle(_translate("metadataView", "Revisions"))
-from ui.collapsibleGroupBox2 import collapsibleGroupBox2
-from ui.views.propertiesView import propertiesView
from ui.views.textEditCompleter import textEditCompleter
from ui.views.textEditView import textEditView
+from ui.views.propertiesView import propertiesView
from ui.views.lineEditView import lineEditView
+from ui.revisions import revisions
+from ui.collapsibleGroupBox2 import collapsibleGroupBox2
diff --git a/src/ui/views/metadataView_ui.ui b/src/ui/views/metadataView_ui.ui
index e1670f33..1b24f86b 100644
--- a/src/ui/views/metadataView_ui.ui
+++ b/src/ui/views/metadataView_ui.ui
@@ -85,7 +85,7 @@
-
- Notes
+ Notes / References
true
@@ -103,6 +103,34 @@
+ -
+
+
+ Revisions
+
+
+ true
+
+
+ true
+
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 50
+
+
+
+
+
+
+
@@ -133,6 +161,12 @@
QTextEdit
ui.views.textEditCompleter.h
+
+ revisions
+ QWidget
+
+ 1
+
diff --git a/src/ui/views/textEditView.py b/src/ui/views/textEditView.py
index f1c2ac04..44ea165c 100644
--- a/src/ui/views/textEditView.py
+++ b/src/ui/views/textEditView.py
@@ -314,6 +314,7 @@ class textEditView(QTextEdit):
self._updating = False
def submit(self):
+ self.updateTimer.stop()
if self._updating:
return
#print("Submitting", self.objectName())
@@ -350,9 +351,9 @@ class textEditView(QTextEdit):
self._updating = False
def keyPressEvent(self, event):
+ QTextEdit.keyPressEvent(self, event)
if event.key() == Qt.Key_Space:
self.submit()
- QTextEdit.keyPressEvent(self, event)
# -----------------------------------------------------------------------------------------------------
# Resize stuff