Fixes more bugs in drag n drop: seg fault when creating an item after deleting an item that was open for editing, and other small stuff

This commit is contained in:
Olivier Keshavjee 2017-10-20 23:39:57 +02:00
parent 1a8d4c5c72
commit 648b4b67eb
8 changed files with 97 additions and 43 deletions

View file

@ -25,10 +25,11 @@ class outlineModel(QAbstractItemModel):
def __init__(self, parent):
QAbstractItemModel.__init__(self, parent)
self.rootItem = outlineItem(self, title="root", ID="0")
self.rootItem = outlineItem(self, title="Root", ID="0")
# Stores removed item, in order to remove them on disk when saving, depending on the file format.
self.removed = []
self._removingRows = False
def index(self, row, column, parent):
@ -408,11 +409,14 @@ class outlineModel(QAbstractItemModel):
else:
parentItem = parent.internalPointer()
self._removingRows = True # Views that are updating can easily know
# if this is due to row removal.
self.beginRemoveRows(parent, row, row + count - 1)
for i in range(count):
item = parentItem.removeChild(row)
self.removed.append(item)
self._removingRows = False
self.endRemoveRows()
return True

View file

@ -53,6 +53,7 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
self.spellcheck = True
self.folderView = "cork"
self.mw = mainWindow()
self._tabWidget = None # set by mainEditor on creation
# def setModel(self, model):
# self._model = model
@ -88,6 +89,25 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
for c in range(count):
self.corkView.itemDelegate().sizeHintChanged.emit(r.child(c, 0))
def updateTabTitle(self):
"""
`editorWidget` belongs to a `QTabWidget` in a `tabSplitter`. We update
the tab title to reflect that of current item.
"""
# `self._tabWidget` is set by mainEditor when creating tab and `editorWidget`.
# if `editorWidget` is ever used out of `mainEditor`, this could throw
# an error.
if not self._tabWidget:
return
if self.currentIndex.isValid():
item = self.currentIndex.internalPointer()
else:
item = self.mw.mdlOutline.rootItem
i = self._tabWidget.indexOf(self)
self._tabWidget.setTabText(i, item.title())
def setView(self):
# index = mainWindow().treeRedacOutline.currentIndex()
@ -110,6 +130,8 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
else:
item = self.mw.mdlOutline.rootItem
self.updateTabTitle()
def addTitle(itm):
edt = textEditView(self, html="<h{l}>{t}</h{l}>".format(l=min(itm.level() + 1, 5), t=itm.title()),
autoResize=True)
@ -213,14 +235,17 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
except TypeError:
pass
else:
if item and item.isText():
self.txtRedacText.setCurrentModelIndex(self.currentIndex)
self.stack.setCurrentIndex(0) # Single text item
else:
self.txtRedacText.setCurrentModelIndex(QModelIndex())
try:
self.mw.mdlOutline.dataChanged.connect(self.modelDataChanged, AUC)
self.mw.mdlOutline.rowsInserted.connect(self.updateIndexFromID, AUC)
self.mw.mdlOutline.rowsRemoved.connect(self.updateIndexFromID, AUC)
#self.mw.mdlOutline.rowsAboutToBeRemoved.connect(self.rowsAboutToBeRemoved, AUC)
except TypeError:
pass
@ -233,16 +258,30 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
# self._model = index.model()
else:
self.currentIndex = QModelIndex()
self.currentID = None
self.setView()
def updateIndexFromID(self):
"""
Index might have changed (through drag an drop), so we keep current
item's ID and update index.
item's ID and update index. Item might have been deleted too.
"""
idx = self.mw.mdlOutline.getIndexByID(self.currentID)
if idx != self.currentIndex:
# If we have an ID but the ID does not exist, it has been deleted
if self.currentID and idx == QModelIndex():
# Item has been deleted, we open the parent instead
self.setCurrentModelIndex(self.currentIndex.parent())
# FIXME: selection in self.mw.treeRedacOutline is not updated
# but we cannot simply setCurrentIndex through treeRedacOutline
# because this might be a tab in the background / out of focus
# Also the UI of mainEditor is not updated (so the folder icons
# are not display, button "up" doesn't work, etc.).
# Item has been moved
elif idx != self.currentIndex:
# We update the index
self.currentIndex = idx
self.setView()
@ -254,6 +293,13 @@ class editorWidget(QWidget, Ui_editorWidget_ui):
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:
## 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():

View file

@ -179,6 +179,9 @@ class mainEditor(QWidget, Ui_mainEditor):
if self._updating:
return
# This might be called during a drag n drop operation, or while deleting
# items. If so, we don't want to do anything.
if not self.mw.mdlOutline._removingRows:
if len(self.mw.treeRedacOutline.selectionModel().
selection().indexes()) == 0:
idx = QModelIndex()
@ -194,8 +197,7 @@ class mainEditor(QWidget, Ui_mainEditor):
def goToParentItem(self):
idx = self.currentEditor().currentIndex
from manuskript.functions import MW
MW.treeRedacOutline.setCurrentIndex(idx.parent())
self.mw.treeRedacOutline.setCurrentIndex(idx.parent())
def setCurrentModelIndex(self, index, newTab=False, tabWidget=None):
@ -216,11 +218,12 @@ class mainEditor(QWidget, Ui_mainEditor):
if newTab or not tabWidget.count():
editor = editorWidget(self)
editor.setCurrentModelIndex(index)
editor._tabWidget = tabWidget
tabWidget.addTab(editor, title)
tabWidget.setCurrentIndex(tabWidget.count() - 1)
else:
self.currentEditor(tabWidget).setCurrentModelIndex(index)
tabWidget.setTabText(tabWidget.currentIndex(), title)
#tabWidget.setTabText(tabWidget.currentIndex(), title)
def updateTargets(self):
"""Updates all tabSplitter that are targets. This is called from editorWidget."""

View file

@ -60,6 +60,9 @@ class metadataView(QWidget, Ui_metadataView):
if len(indexes) == 0:
self.setEnabled(False)
self.revisions.setEnabled(False)
self.txtSummarySentence.setCurrentModelIndex(QModelIndex())
self.txtSummaryFull.setCurrentModelIndex(QModelIndex())
self.txtNotes.setCurrentModelIndex(QModelIndex())
# One item selected
elif len(indexes) == 1:

View file

@ -237,8 +237,7 @@ class textEditView(QTextEdit):
if self._updating:
return
elif self._index:
elif self._index and self._index.isValid():
if topLeft.parent() != self._index.parent():
return
@ -266,7 +265,6 @@ class textEditView(QTextEdit):
first <= self._index.row() <= last:
self._index = None
self.setEnabled(False)
# FIXME: self._indexes
def disconnectDocument(self):