mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-05-17 11:22:28 +12:00
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:
parent
1a8d4c5c72
commit
648b4b67eb
|
@ -124,14 +124,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
self.makeUIConnections()
|
||||
|
||||
# self.loadProject(os.path.join(appPath(), "test_project.zip"))
|
||||
|
||||
|
||||
def updateDockVisibility(self, restore=False):
|
||||
"""
|
||||
Saves the state of the docks visibility. Or if `restore` is True,
|
||||
Saves the state of the docks visibility. Or if `restore` is True,
|
||||
restores from `self._dckVisibility`. This allows to hide the docks
|
||||
while showing the welcome screen, and then restore them as they
|
||||
were.
|
||||
|
||||
|
||||
If `self._dckVisibility` contains "LOCK", then we don't override values
|
||||
with current visibility state. This is used the first time we load.
|
||||
"LOCK" is then removed.
|
||||
|
@ -141,7 +141,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
self.dckNavigation,
|
||||
self.dckSearch,
|
||||
]
|
||||
|
||||
|
||||
for d in docks:
|
||||
if not restore:
|
||||
# We store the values, but only if "LOCK" is not present
|
||||
|
@ -152,11 +152,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
else:
|
||||
# Restore the dock's visibily based on stored value
|
||||
d.setVisible(self._dckVisibility[d.objectName()])
|
||||
|
||||
|
||||
# Lock is used only once, at start up. We can remove it
|
||||
if "LOCK" in self._dckVisibility:
|
||||
self._dckVisibility.pop("LOCK")
|
||||
|
||||
|
||||
def switchToWelcome(self):
|
||||
"""
|
||||
While switching to welcome screen, we have to hide all the docks.
|
||||
|
@ -171,7 +171,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
self.toolbar.setVisible(False)
|
||||
# Switch to welcome screen
|
||||
self.stack.setCurrentIndex(0)
|
||||
|
||||
|
||||
def switchToProject(self):
|
||||
"""Restores docks and toolbar visibility, and switch to project."""
|
||||
# Restores the docks visibility
|
||||
|
@ -549,14 +549,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
sttgns.setValue("splitterRedacH", self.splitterRedacH.saveState())
|
||||
sttgns.setValue("splitterRedacV", self.splitterRedacV.saveState())
|
||||
sttgns.setValue("toolbar", self.toolbar.saveState())
|
||||
|
||||
|
||||
# If we are not in the welcome window, we update the visibility
|
||||
# of the docks widgets
|
||||
if self.stack.currentIndex() == 1:
|
||||
self.updateDockVisibility()
|
||||
# Storing the visibility of docks to restore it on restart
|
||||
sttgns.setValue("docks", self._dckVisibility)
|
||||
|
||||
|
||||
# Specific settings to save before quitting
|
||||
settings.lastTab = self.tabMain.currentIndex()
|
||||
|
||||
|
@ -588,7 +588,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
|
||||
r = loadSave.saveProject() # version=0
|
||||
self.saveTimerNoChanges.stop()
|
||||
|
||||
|
||||
if r:
|
||||
feedback = self.tr("Project {} saved.").format(self.currentProject)
|
||||
else:
|
||||
|
@ -976,7 +976,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
#""
|
||||
#]
|
||||
#self.tabMain.setTabIcon(i, QIcon(appPath("icons/Custom/Tabs/{}".format(icons[i]))))
|
||||
|
||||
|
||||
icons = [QIcon.fromTheme("stock_view-details"), #info
|
||||
QIcon.fromTheme("application-text-template"), #applications-publishing
|
||||
F.themeIcon("characters"),
|
||||
|
@ -987,7 +987,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||
QIcon.fromTheme("applications-debugging")
|
||||
]
|
||||
self.tabMain.setTabIcon(i, icons[i])
|
||||
|
||||
|
||||
item = QListWidgetItem(self.tabMain.tabIcon(i),
|
||||
self.tabMain.tabText(i))
|
||||
item.setSizeHint(QSize(item.sizeHint().width(), 64))
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
@ -266,13 +267,13 @@ class outlineModel(QAbstractItemModel):
|
|||
items = self.decodeMimeData(data)
|
||||
if items is None:
|
||||
return False
|
||||
|
||||
|
||||
# Get the parent item
|
||||
if not parent.isValid():
|
||||
parentItem = self.rootItem
|
||||
else:
|
||||
parentItem = parent.internalPointer()
|
||||
|
||||
|
||||
for item in items:
|
||||
# Get parentItem's parents IDs in a list
|
||||
path = parentItem.pathID() # path to item in the form [(ID, title), ...]
|
||||
|
@ -281,7 +282,7 @@ class outlineModel(QAbstractItemModel):
|
|||
# as a children of himself.
|
||||
if item.ID() in path:
|
||||
return False
|
||||
|
||||
|
||||
return True
|
||||
|
||||
def decodeMimeData(self, data):
|
||||
|
@ -300,7 +301,7 @@ class outlineModel(QAbstractItemModel):
|
|||
if child.tag == "outlineItem":
|
||||
item = outlineItem(xml=ET.tostring(child))
|
||||
items.append(item)
|
||||
|
||||
|
||||
return items
|
||||
|
||||
def dropMimeData(self, data, action, row, column, parent):
|
||||
|
@ -311,7 +312,7 @@ class outlineModel(QAbstractItemModel):
|
|||
items = self.decodeMimeData(data)
|
||||
if items is None:
|
||||
return False
|
||||
|
||||
|
||||
if column > 0:
|
||||
column = 0
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -179,14 +179,17 @@ class mainEditor(QWidget, Ui_mainEditor):
|
|||
if self._updating:
|
||||
return
|
||||
|
||||
if len(self.mw.treeRedacOutline.selectionModel().
|
||||
selection().indexes()) == 0:
|
||||
idx = QModelIndex()
|
||||
else:
|
||||
idx = self.mw.treeRedacOutline.currentIndex()
|
||||
# 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()
|
||||
else:
|
||||
idx = self.mw.treeRedacOutline.currentIndex()
|
||||
|
||||
self.setCurrentModelIndex(idx)
|
||||
self.updateThingsVisible(idx)
|
||||
self.setCurrentModelIndex(idx)
|
||||
self.updateThingsVisible(idx)
|
||||
|
||||
def openIndexes(self, indexes, newTab=False):
|
||||
for i in indexes:
|
||||
|
@ -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."""
|
||||
|
|
|
@ -249,4 +249,4 @@ class tabSplitter(QWidget, Ui_tabSplitter):
|
|||
# }}""".format(self.splitter.objectName()))
|
||||
|
||||
self.setStyleSheet(style.mainEditorTabSS())
|
||||
return QWidget.eventFilter(self, object, event)
|
||||
return QWidget.eventFilter(self, object, event)
|
||||
|
|
|
@ -16,9 +16,9 @@ class metadataView(QWidget, Ui_metadataView):
|
|||
self.txtSummaryFull.setColumn(Outline.summaryFull.value)
|
||||
self.txtNotes.setColumn(Outline.notes.value)
|
||||
self.revisions.setEnabled(False)
|
||||
|
||||
|
||||
self.txtSummarySentence.setStyleSheet(style.lineEditSS())
|
||||
self.txtSummaryFull.setStyleSheet(style.transparentSS() +
|
||||
self.txtSummaryFull.setStyleSheet(style.transparentSS() +
|
||||
style.simpleScrollBarV())
|
||||
self.txtNotes.setStyleSheet(style.transparentSS() +
|
||||
style.simpleScrollBarV())
|
||||
|
@ -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:
|
||||
|
@ -89,7 +92,7 @@ class metadataView(QWidget, Ui_metadataView):
|
|||
|
||||
# Behavior 2:
|
||||
# Allow edition of multiple indexes.
|
||||
# Bug: Multiple selections of items sometimes gets Notes/references
|
||||
# Bug: Multiple selections of items sometimes gets Notes/references
|
||||
# field to be ereased. See #10 on github.
|
||||
#self.txtSummarySentence.setCurrentModelIndexes(indexes)
|
||||
#self.txtSummaryFull.setCurrentModelIndexes(indexes)
|
||||
|
|
|
@ -42,9 +42,9 @@ class outlineBasics(QAbstractItemView):
|
|||
self.actOpen = QAction(QIcon.fromTheme("go-right"), qApp.translate("outlineBasic", "Open Item"), menu)
|
||||
self.actOpen.triggered.connect(self.openItem)
|
||||
menu.addAction(self.actOpen)
|
||||
|
||||
|
||||
menu.addSeparator()
|
||||
|
||||
|
||||
# Add / remove items
|
||||
self.actAddFolder = QAction(QIcon.fromTheme("folder-new"), qApp.translate("outlineBasics", "New Folder"), menu)
|
||||
self.actAddFolder.triggered.connect(self.addFolder)
|
||||
|
@ -154,7 +154,7 @@ class outlineBasics(QAbstractItemView):
|
|||
idx = self.currentIndex()
|
||||
from manuskript.functions import MW
|
||||
MW.openIndex(idx)
|
||||
|
||||
|
||||
def addFolder(self):
|
||||
self.addItem("folder")
|
||||
|
||||
|
|
|
@ -208,11 +208,11 @@ class textEditView(QTextEdit):
|
|||
if self.parent().__class__ == QWidget:
|
||||
self.parent().setStyleSheet("background: {bg};".format(
|
||||
bg=opt["background"]))
|
||||
|
||||
|
||||
cf = QTextCharFormat()
|
||||
# cf.setFont(f)
|
||||
# cf.setForeground(QColor(opt["fontColor"]))
|
||||
|
||||
|
||||
self.setCursorWidth(opt["cursorWidth"])
|
||||
|
||||
bf = QTextBlockFormat()
|
||||
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue