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 - + Outline Plan @@ -329,62 +329,62 @@ Mode - + (~{} pages) (~{} pages) - + Enter infos about your book, and yourself. Entrez toutes les informations relatives au livre, ainsi qu'à vous. - + 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. 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. - + Create your characters. Créez ici vos personnage. - + Develop plots. Développez vos intrigues. - + Create the outline of your masterpiece. Créez le plan de votre chef-d'œuvre. - + Write. Écrivez. - + Debug infos. Sometimes useful. Des infos pour débugger des fois pendant qu'on code c'est utile. - + Dictionary Dictionnaire - + Install PyEnchant to use spellcheck Installez PyEnchant pour profiter du correcteur orthographique - + Words: {}{} Mots: {}{} - + Text Texte @@ -424,7 +424,7 @@ Et si...? - + Index cards Cartes @@ -444,7 +444,7 @@ F9 - + Tree Arbre @@ -469,77 +469,77 @@ Réglages - + Project {} saved. Le projet {} a été enregistré. - + Project {} loaded. Le projet {} a été chargé. - + The basic situation, in the form of a 'What if...?' question. Ex: 'What if the most dangerous evil wizard could wasn't abled to kill a baby?' (Harry Potter) 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) - + Nothing Rien - + POV POV - + Label Label - + Progress Progrès - + Compile Compilation - + Icon color Couleur de l'icone - + Text color Couleur du texte - + Background color Couleur de l'arrière-plan - + Icon Icone - + Background Arrière-plan - + Border Bordure - + Corner Coin @@ -549,22 +549,22 @@ Fermer le projet - + The file {} does not exist. Try again. Le fichier {} n'existe pas. Essayez encore. - + Project {} loaded with some errors: Le projet {} a été chargé, avec des erreurs: - + * {} wasn't found in project file. * {} n'a pas été trouvé dans le fichier du projet. - + Project {} loaded with some errors. Le projet {} a été chargé avec des erreurs. @@ -1051,7 +1051,7 @@ des lignes: SpellAction - + Spelling Suggestions Suggestions @@ -1115,27 +1115,27 @@ des lignes: Filtre - + Minor Mineur - + Secondary Secondaire - + Main Principal - + Characters Personnages - + Texts Textes @@ -1323,17 +1323,17 @@ des lignes: mainEditor - + Root Racine - + {} words / {} {} mots / {} - + {} words {} mots @@ -1362,8 +1362,13 @@ des lignes: - Notes - Notes + Notes / References + Notes / Références + + + + Revisions + Révisions @@ -1442,47 +1447,47 @@ des lignes: outlineModel - + Title Titre - + POV POV - + Label Label - + Status Status - + Compile Compilation - + Word count Nombre de mots - + Goal Goal - + {} words / {} ({}) {} mots / {} ({}) - + {} words {} mots @@ -1549,27 +1554,27 @@ des lignes: plotModel - + New plot Nouvelle intrigue - + New subplot Nouvelle sous-intrigue - + Main Principale - + Secondary Secondaire - + Minor Mineure @@ -1577,20 +1582,25 @@ des lignes: plotTreeView - + Main Principale - + Secondary Secondaire - + Minor Mineure + + + **Plot:** {} + **Intrigue:** {} + propertiesView @@ -1638,111 +1648,154 @@ des lignes: references - + Unknown reference: {}. Référence inconnue: {}. - + Text: <b>{}</b> Texte: <b>{}</b> - + Character: <b>{}</b> Personnage: <b>{}</b> - + Basic infos Informations générales - + Detailed infos Informations détaillées - + POV of: POV de: - + Referenced in: Référencé dans: - + Motivation Motivation - + Goal Goal - + Conflict Conflit - + Epiphany Épiphanie - + Short summary Résumé court - + Longer summary Résumé long - + Path: Chemin: - + Stats: Stats: - + POV: POV: - + Status: Status: - + Label: Label: - + Short summary: Résumé court: - + Long summary: Résumé long: - + Notes: Notes: + + revisions + + + Form + Form + + + + Restore + Restaurer + + + + Delete + Supprimer + + + + 1 day ago + Il y a un jour + + + + {} days ago + Il y a {} jours + + + + {} hours ago + Il y a {} heures + + + + {} minutes ago + Il y a {} minutes + + + + {} seconds ago + Il y a {} secondes + + settingsWindow @@ -1812,7 +1865,7 @@ des lignes: textEditView - + Various 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 +
ui.revisions.h
+ 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