From f2d6798e2a25f2729d8def588f9f8b937007527d Mon Sep 17 00:00:00 2001 From: Olivier Keshavjee Date: Wed, 10 Jun 2015 23:36:30 +0200 Subject: [PATCH] PropertyView: all sub-views are multi-indexes friendly. Quite cool. --- src/mainWindow.py | 7 +- src/ui/cmbOutlineLabelChoser.py | 123 ++++++++++++++++++++++------- src/ui/cmbOutlinePersoChoser.py | 124 +++++++++++++++++++++++------ src/ui/cmbOutlineStatusChoser.py | 126 ++++++++++++++++++++++-------- src/ui/editors/editorWidget.py | 10 +++ src/ui/views/lineEditView.py | 5 +- src/ui/views/propertiesView.py | 21 ++++- src/ui/views/propertiesView_ui.py | 34 ++++---- src/ui/views/propertiesView_ui.ui | 8 +- test_project/outline.xml | 16 ++-- 10 files changed, 355 insertions(+), 119 deletions(-) diff --git a/src/mainWindow.py b/src/mainWindow.py index 884bd6e1..341cad6c 100644 --- a/src/mainWindow.py +++ b/src/mainWindow.py @@ -205,7 +205,12 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.treeRedacOutline.selectionModel().currentChanged.connect(lambda idx: self.mprOutline.setRootIndex(idx.parent())) self.treeRedacOutline.selectionModel().currentChanged.connect(self.mprOutline.setCurrentModelIndex) - self.treeRedacOutline.selectionModel().selectionChanged.connect(lambda: self.viewRedacProperties.selectionChanged(self.treeRedacOutline)) + + self.treeRedacOutline.selectionModel().selectionChanged.connect( + lambda: self.viewRedacProperties.selectionChanged(self.treeRedacOutline)) + self.treeRedacOutline.clicked.connect( + lambda: self.viewRedacProperties.selectionChanged(self.treeRedacOutline)) + #self.treeRedacOutline.selectionModel().currentChanged.connect(self.redacEditor.setCurrentModelIndex) self.treeRedacOutline.selectionModel().selectionChanged.connect(self.redacEditor.setView) self.treeRedacOutline.selectionModel().currentChanged.connect(self.redacEditor.txtRedacText.setCurrentModelIndex) diff --git a/src/ui/cmbOutlineLabelChoser.py b/src/ui/cmbOutlineLabelChoser.py index f1bb34b6..1eeb48e6 100644 --- a/src/ui/cmbOutlineLabelChoser.py +++ b/src/ui/cmbOutlineLabelChoser.py @@ -1,9 +1,6 @@ #!/usr/bin/env python #--!-- coding: utf8 --!-- - - - from qt import * from enums import * @@ -11,35 +8,20 @@ class cmbOutlineLabelChoser(QComboBox): def __init__(self, parent=None): QComboBox.__init__(self, parent) - self.activated[int].connect(self.changed) - self.currentModelIndex = None + self.activated[int].connect(self.submit) + self._column = Outline.label.value + self._index = None + self._indexes = None + self._updating = False def setModels(self, mdlLabels, mdlOutline): self.mdlLabels = mdlLabels - self.mdlLabels.dataChanged.connect(self.updateItems) # Not emiting? + self.mdlLabels.dataChanged.connect(self.updateItems) self.mdlOutline = mdlOutline - self.mdlOutline.dataChanged.connect(self.updateSelectedItem) + self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - def updateSelectedItem(self, idx1=None, idx2=None): - if not self.currentModelIndex or not self.currentModelIndex.isValid(): - self.setCurrentIndex(0) - else: - val = self.currentModelIndex.internalPointer().data(Outline.label.value) - if not val: val = 0 - self.setCurrentIndex(int(val)) - - def changed(self, idx): - if self.currentModelIndex: - modelIndex = self.mdlOutline.index(self.currentModelIndex.row(), Outline.label.value, self.currentModelIndex.parent()) - self.mdlOutline.setData(modelIndex, self.currentIndex()) - - def setCurrentModelIndex(self, idx): - self.currentModelIndex = idx - self.updateItems() - self.updateSelectedItem() - - def updateItems(self, topLeft=None, bottomRight=None, roles=None): + def updateItems(self): self.clear() for i in range(self.mdlLabels.rowCount()): item = self.mdlLabels.item(i, 0) @@ -47,5 +29,90 @@ class cmbOutlineLabelChoser(QComboBox): self.addItem(item.icon(), item.text()) - if self.currentModelIndex: - self.updateSelectedItem() \ No newline at end of file + if self._index or self._indexes: + self.updateSelectedItem() + + def setCurrentModelIndex(self, index): + self._indexes = None + if index.column() != self._column: + index = index.sibling(index.row(), self._column) + self._index = index + self.updateSelectedItem() + + def setCurrentModelIndexes(self, indexes): + self._indexes = [] + self._index = None + + for i in indexes: + if i.isValid(): + if i.column() != self._column: + i = i.sibling(i.row(), self._column) + self._indexes.append(i) + + self.updateSelectedItem() + + def update(self, topLeft, bottomRight): + + if self._updating: + # We are currently putting data in the model, so no updates + return + + if self._index: + if topLeft.row() <= self._index.row() <= bottomRight.row(): + self.updateSelectedItem() + + elif self._indexes: + update = False + for i in self._indexes: + if topLeft.row() <= i.row() <= bottomRight.row(): + update = True + if update: + self.updateSelectedItem() + + def getLabel(self, index): + item = index.internalPointer() + label = item.data(self._column) + if not label: + label = 0 + return int(label) + + def updateSelectedItem(self): + + if self._updating: + return + + if self._index: + label = self.getLabel(self._index) + self.setCurrentIndex(label) + + elif self._indexes: + labels = [] + same = True + + for i in self._indexes: + labels.append(self.getLabel(i)) + + for lbl in labels[1:]: + if lbl != labels[0]: + same = False + break + + if same: + self.setCurrentIndex(labels[0]) + + else: + self.setCurrentIndex(0) + + else: + self.setCurrentIndex(0) + + def submit(self, idx): + if self._index: + self.mdlOutline.setData(self._index, self.currentIndex()) + + elif self._indexes: + self._updating = True + for i in self._indexes: + self.mdlOutline.setData(i, self.currentIndex()) + self._updating = False + \ No newline at end of file diff --git a/src/ui/cmbOutlinePersoChoser.py b/src/ui/cmbOutlinePersoChoser.py index a763099c..f1886228 100644 --- a/src/ui/cmbOutlinePersoChoser.py +++ b/src/ui/cmbOutlinePersoChoser.py @@ -11,37 +11,19 @@ class cmbOutlinePersoChoser(QComboBox): def __init__(self, parent=None): QComboBox.__init__(self, parent) - self.activated[int].connect(self.changed) - self.currentModelIndex = None + self.activated[int].connect(self.submit) + self._column = Outline.POV.value + self._index = None + self._indexes = None + self._updating = False def setModels(self, mdlPersos, mdlOutline): self.mdlPersos = mdlPersos self.mdlPersos.dataChanged.connect(self.updateItems) self.mdlOutline = mdlOutline - self.mdlOutline.dataChanged.connect(self.updateSelectedItem) + self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - def updateSelectedItem(self, idx1=None, idx2=None): - if not self.currentModelIndex or not self.currentModelIndex.isValid(): - self.setCurrentIndex(0) - else: - item = self.currentModelIndex.internalPointer() - POV = item.data(Outline.POV.value) - idx = self.findData(POV) - if idx != -1: - self.setCurrentIndex(idx) - else: - self.setCurrentIndex(0) - - def changed(self, idx): - if self.currentModelIndex: - modelIndex = self.mdlOutline.index(self.currentModelIndex.row(), Outline.POV.value, self.currentModelIndex.parent()) - self.mdlOutline.setData(modelIndex, self.currentData()) - - def setCurrentModelIndex(self, idx): - self.currentModelIndex = idx - self.updateSelectedItem() - def updateItems(self): self.clear() self.addItem("") @@ -51,5 +33,95 @@ class cmbOutlinePersoChoser(QComboBox): self.setItemData(i+1, self.mdlPersos.item(i, Perso.name.value).text(), Qt.ToolTipRole) except: pass - if self.currentModelIndex: - self.updateSelectedItem() \ No newline at end of file + + if self._index or self._indexes: + self.updateSelectedItem() + + def setCurrentModelIndex(self, index): + self._indexes = None + if index.column() != self._column: + index = index.sibling(index.row(), self._column) + self._index = index + self.updateSelectedItem() + + def setCurrentModelIndexes(self, indexes): + self._indexes = [] + self._index = None + + for i in indexes: + if i.isValid(): + if i.column() != self._column: + i = i.sibling(i.row(), self._column) + self._indexes.append(i) + + self.updateSelectedItem() + + def update(self, topLeft, bottomRight): + + if self._updating: + # We are currently putting data in the model, so no updates + return + + if self._index: + if topLeft.row() <= self._index.row() <= bottomRight.row(): + self.updateSelectedItem() + + elif self._indexes: + update = False + for i in self._indexes: + if topLeft.row() <= i.row() <= bottomRight.row(): + update = True + if update: + self.updateSelectedItem() + + def getPOV(self, index): + item = index.internalPointer() + POV = item.data(self._column) + return POV + + def selectPOV(self, POV): + idx = self.findData(POV) + if idx != -1: + self.setCurrentIndex(idx) + else: + self.setCurrentIndex(0) + + def updateSelectedItem(self, idx1=None, idx2=None): + + if self._updating: + return + + if self._index: + POV = self.getPOV(self._index) + self.selectPOV(POV) + + elif self._indexes: + POVs = [] + same = True + + for i in self._indexes: + POVs.append(self.getPOV(i)) + + for POV in POVs[1:]: + if POV != POVs[0]: + same = False + break + + if same: + self.selectPOV(POVs[0]) + + else: + self.setCurrentIndex(0) + + else: + self.setCurrentIndex(0) + + def submit(self, idx): + if self._index: + self.mdlOutline.setData(self._index, self.currentData()) + + elif self._indexes: + self._updating = True + for i in self._indexes: + self.mdlOutline.setData(i, self.currentData()) + self._updating = False \ No newline at end of file diff --git a/src/ui/cmbOutlineStatusChoser.py b/src/ui/cmbOutlineStatusChoser.py index 2a24a4ed..aec34f39 100644 --- a/src/ui/cmbOutlineStatusChoser.py +++ b/src/ui/cmbOutlineStatusChoser.py @@ -1,53 +1,117 @@ #!/usr/bin/env python #--!-- coding: utf8 --!-- - - - from qt import * from enums import * + class cmbOutlineStatusChoser(QComboBox): def __init__(self, parent=None): QComboBox.__init__(self, parent) - self.activated[int].connect(self.changed) - self.currentModelIndex = None + self.activated[int].connect(self.submit) + self._column = Outline.status.value + self._index = None + self._indexes = None + self._updating = False def setModels(self, mdlStatus, mdlOutline): self.mdlStatus = mdlStatus - self.mdlStatus.dataChanged.connect(self.updateItems) # Not emiting? + self.mdlStatus.dataChanged.connect(self.updateItems) self.mdlOutline = mdlOutline - self.mdlOutline.dataChanged.connect(self.updateSelectedItem) + self.mdlOutline.dataChanged.connect(self.update) self.updateItems() - def updateSelectedItem(self, idx1=None, idx2=None): - if not self.currentModelIndex or not self.currentModelIndex.isValid(): - self.setCurrentIndex(0) - else: - val = self.currentModelIndex.internalPointer().data(Outline.status.value) - if not val: val = 0 - try: - self.setCurrentIndex(int(val)) - except: - pass - - def changed(self, idx): - if self.currentModelIndex: - modelIndex = self.mdlOutline.index(self.currentModelIndex.row(), Outline.status.value, self.currentModelIndex.parent()) - self.mdlOutline.setData(modelIndex, self.currentIndex()) - - def setCurrentModelIndex(self, idx): - self.currentModelIndex = idx - self.updateItems() - self.updateSelectedItem() - - def updateItems(self, topLeft=None, bottomRight=None, roles=None): + def updateItems(self): self.clear() for i in range(self.mdlStatus.rowCount()): item = self.mdlStatus.item(i, 0) if item: self.addItem(item.text()) - if self.currentModelIndex: - self.updateSelectedItem() \ No newline at end of file + if self._index or self._indexes: + self.updateSelectedItem() + + def setCurrentModelIndex(self, index): + self._indexes = None + if index.column() != self._column: + index = index.sibling(index.row(), self._column) + self._index = index + self.updateSelectedItem() + + def setCurrentModelIndexes(self, indexes): + self._indexes = [] + self._index = None + + for i in indexes: + if i.isValid(): + if i.column() != self._column: + i = i.sibling(i.row(), self._column) + self._indexes.append(i) + + self.updateSelectedItem() + + def update(self, topLeft, bottomRight): + + if self._updating: + # We are currently putting data in the model, so no updates + return + + if self._index: + if topLeft.row() <= self._index.row() <= bottomRight.row(): + self.updateSelectedItem() + + elif self._indexes: + update = False + for i in self._indexes: + if topLeft.row() <= i.row() <= bottomRight.row(): + update = True + if update: + self.updateSelectedItem() + + def getStatus(self, index): + item = index.internalPointer() + status = item.data(self._column) + if not status: + status = 0 + return int(status) + + def updateSelectedItem(self): + + if self._updating: + return + + if self._index: + status = self.getStatus(self._index) + self.setCurrentIndex(status) + + elif self._indexes: + statuses = [] + same = True + + for i in self._indexes: + statuses.append(self.getStatus(i)) + + for s in statuses[1:]: + if s != statuses[0]: + same = False + break + + if same: + self.setCurrentIndex(statuses[0]) + + else: + self.setCurrentIndex(0) + + else: + self.setCurrentIndex(0) + + def submit(self, idx): + if self._index: + self.mdlOutline.setData(self._index, self.currentIndex()) + + elif self._indexes: + self._updating = True + for i in self._indexes: + self.mdlOutline.setData(i, self.currentIndex()) + self._updating = False \ No newline at end of file diff --git a/src/ui/editors/editorWidget.py b/src/ui/editors/editorWidget.py index a08af02c..81b814bb 100644 --- a/src/ui/editors/editorWidget.py +++ b/src/ui/editors/editorWidget.py @@ -144,6 +144,11 @@ class editorWidget(QWidget, Ui_editorWidget_ui): self.stack.setCurrentIndex(2) self.corkView.setModel(self._model) self.corkView.setRootIndex(index) + self.corkView.selectionModel().selectionChanged.connect( + lambda: mainWindow().viewRedacProperties.selectionChanged(self.corkView)) + self.corkView.clicked.connect( + lambda: mainWindow().viewRedacProperties.selectionChanged(self.corkView)) + elif item.isFolder() and self.folderView == "outline": self.stack.setCurrentIndex(3) @@ -152,6 +157,11 @@ class editorWidget(QWidget, Ui_editorWidget_ui): self.outlineView.setModelStatus(mainWindow().mdlStatus) self.outlineView.setModel(self._model) self.outlineView.setRootIndex(index) + self.outlineView.selectionModel().selectionChanged.connect( + lambda: mainWindow().viewRedacProperties.selectionChanged(self.outlineView)) + self.outlineView.clicked.connect( + lambda: mainWindow().viewRedacProperties.selectionChanged(self.outlineView)) + else: self.stack.setCurrentIndex(0) diff --git a/src/ui/views/lineEditView.py b/src/ui/views/lineEditView.py index 7cc8c66b..b6a395d8 100644 --- a/src/ui/views/lineEditView.py +++ b/src/ui/views/lineEditView.py @@ -103,6 +103,9 @@ class lineEditView(QLineEdit): self.setText(t[0]) else: self.setText("") - self._placeholderText = self.placeholderText() + + if not self._placeholderText: + self._placeholderText = self.placeholderText() + self.setPlaceholderText("Various") \ No newline at end of file diff --git a/src/ui/views/propertiesView.py b/src/ui/views/propertiesView.py index 865450cc..7aa583a1 100644 --- a/src/ui/views/propertiesView.py +++ b/src/ui/views/propertiesView.py @@ -42,6 +42,7 @@ class propertiesView(QWidget, Ui_propertiesView): elif len(indexes) == 1: self.setEnabled(True) + self.setLabelsItalic(False) idx = indexes[0] self.cmbPOV.setCurrentModelIndex(idx) self.cmbLabel.setCurrentModelIndex(idx) @@ -51,9 +52,23 @@ class propertiesView(QWidget, Ui_propertiesView): self.txtGoal.setCurrentModelIndex(idx) else: - print("Multiple selection, Work in progress") + self.setEnabled(True) + self.setLabelsItalic(True) self.txtTitle.setCurrentModelIndexes(indexes) self.txtGoal.setCurrentModelIndexes(indexes) self.chkCompile.setCurrentModelIndexes(indexes) - #FIXME: do the other views - \ No newline at end of file + self.cmbPOV.setCurrentModelIndexes(indexes) + self.cmbLabel.setCurrentModelIndexes(indexes) + self.cmbStatus.setCurrentModelIndexes(indexes) + + def setLabelsItalic(self, value): + f = self.lblPOV.font() + f.setItalic(value) + for lbl in [ + self.lblPOV, + self.lblStatus, + self.lblLabel, + self.lblCompile, + self.lblGoal + ]: + lbl.setFont(f) \ No newline at end of file diff --git a/src/ui/views/propertiesView_ui.py b/src/ui/views/propertiesView_ui.py index 5c9a3aad..120f0ae7 100644 --- a/src/ui/views/propertiesView_ui.py +++ b/src/ui/views/propertiesView_ui.py @@ -45,9 +45,9 @@ class Ui_propertiesView(object): self.cmbPOV.setFrame(False) self.cmbPOV.setObjectName("cmbPOV") self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.cmbPOV) - self.label_30 = QtWidgets.QLabel(self.page) - self.label_30.setObjectName("label_30") - self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_30) + self.lblStatus = QtWidgets.QLabel(self.page) + self.lblStatus.setObjectName("lblStatus") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.lblStatus) self.cmbStatus = cmbOutlineStatusChoser(self.page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -57,9 +57,9 @@ class Ui_propertiesView(object): self.cmbStatus.setFrame(False) self.cmbStatus.setObjectName("cmbStatus") self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.cmbStatus) - self.label_33 = QtWidgets.QLabel(self.page) - self.label_33.setObjectName("label_33") - self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_33) + self.lblLabel = QtWidgets.QLabel(self.page) + self.lblLabel.setObjectName("lblLabel") + self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.lblLabel) self.cmbLabel = cmbOutlineLabelChoser(self.page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -69,16 +69,16 @@ class Ui_propertiesView(object): self.cmbLabel.setFrame(False) self.cmbLabel.setObjectName("cmbLabel") self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.cmbLabel) - self.label_32 = QtWidgets.QLabel(self.page) - self.label_32.setObjectName("label_32") - self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_32) + self.lblCompile = QtWidgets.QLabel(self.page) + self.lblCompile.setObjectName("lblCompile") + self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.lblCompile) self.chkCompile = chkOutlineCompile(self.page) self.chkCompile.setText("") self.chkCompile.setObjectName("chkCompile") self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.chkCompile) - self.label_29 = QtWidgets.QLabel(self.page) - self.label_29.setObjectName("label_29") - self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_29) + self.lblGoal = QtWidgets.QLabel(self.page) + self.lblGoal.setObjectName("lblGoal") + self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.lblGoal) self.txtGoal = lineEditView(self.page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -169,10 +169,10 @@ class Ui_propertiesView(object): _translate = QtCore.QCoreApplication.translate propertiesView.setWindowTitle(_translate("propertiesView", "Form")) self.lblPOV.setText(_translate("propertiesView", "POV")) - self.label_30.setText(_translate("propertiesView", "Status")) - self.label_33.setText(_translate("propertiesView", "Label")) - self.label_32.setText(_translate("propertiesView", "Compile")) - self.label_29.setText(_translate("propertiesView", "Goal")) + self.lblStatus.setText(_translate("propertiesView", "Status")) + self.lblLabel.setText(_translate("propertiesView", "Label")) + self.lblCompile.setText(_translate("propertiesView", "Compile")) + self.lblGoal.setText(_translate("propertiesView", "Goal")) self.txtGoal.setPlaceholderText(_translate("propertiesView", "Word count")) self.lblPOV_2.setText(_translate("propertiesView", "POV")) self.label_31.setText(_translate("propertiesView", "Status")) @@ -181,8 +181,8 @@ class Ui_propertiesView(object): self.label_36.setText(_translate("propertiesView", "Goal")) self.txtGoalMulti.setPlaceholderText(_translate("propertiesView", "Word count")) +from ui.views.lineEditView import lineEditView from ui.chkOutlineCompile import chkOutlineCompile from ui.cmbOutlineLabelChoser import cmbOutlineLabelChoser from ui.cmbOutlineStatusChoser import cmbOutlineStatusChoser -from ui.views.lineEditView import lineEditView from ui.cmbOutlinePersoChoser import cmbOutlinePersoChoser diff --git a/src/ui/views/propertiesView_ui.ui b/src/ui/views/propertiesView_ui.ui index 30133081..a17f8210 100644 --- a/src/ui/views/propertiesView_ui.ui +++ b/src/ui/views/propertiesView_ui.ui @@ -66,7 +66,7 @@ - + Status @@ -86,7 +86,7 @@ - + Label @@ -106,7 +106,7 @@ - + Compile @@ -120,7 +120,7 @@ - + Goal diff --git a/test_project/outline.xml b/test_project/outline.xml index fdf2471d..f47da017 100644 --- a/test_project/outline.xml +++ b/test_project/outline.xml @@ -51,13 +51,13 @@ - - - - - - - + + + + + + + - +