diff --git a/i18n/manuskript.pro b/i18n/manuskript.pro index cd3e3c05..b78f9478 100644 --- a/i18n/manuskript.pro +++ b/i18n/manuskript.pro @@ -14,18 +14,25 @@ SOURCES += ../src/loadSave.py SOURCES += ../src/mainWindow.py SOURCES += ../src/settingsWindow.py +SOURCES += ../src/models/outlineModel.py +SOURCES += ../src/models/persosProxyModel.py +SOURCES += ../src/models/plotModel.py + SOURCES += ../src/ui/helpLabel.py SOURCES += ../src/ui/sldImportance.py SOURCES += ../src/ui/welcome.py SOURCES += ../src/ui/editors/editorWidget.py SOURCES += ../src/ui/editors/fullScreenEditor.py +SOURCES += ../src/ui/editors/textFormat.py SOURCES += ../src/ui/views/corkDelegate.py +SOURCES += ../src/ui/views/outlineDelegates.py SOURCES += ../src/ui/views/outlineBasics.py SOURCES += ../src/ui/views/cmbOutlineLabelChoser.py SOURCES += ../src/ui/views/cmbOutlinePersoChoser.py SOURCES += ../src/ui/views/cmbOutlineStatusChoser.py +SOURCES += ../src/ui/views/treeView.py SOURCES += ../src/ui/views/lineEditView.py SOURCES += ../src/ui/views/textEditView.py SOURCES += ../src/ui/views/plotTreeView.py diff --git a/i18n/manuskript_fr.qm b/i18n/manuskript_fr.qm index bf58c90e..14a7417d 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 846db3ee..0444ab4d 100644 --- a/i18n/manuskript_fr.ts +++ b/i18n/manuskript_fr.ts @@ -214,7 +214,7 @@ Contexte - + Outline Plan @@ -359,67 +359,67 @@ Mode - + New character Nouveau perso - + (~{} 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 @@ -459,7 +459,7 @@ Et si...? - + Index cards Cartes @@ -479,7 +479,7 @@ F9 - + Tree Arbre @@ -504,77 +504,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 @@ -584,22 +584,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. @@ -617,17 +617,17 @@ Apparence - + Labels Labels - + Status Status - + Fullscreen Plein écran @@ -672,348 +672,348 @@ Enregistrer en quittant - + Views settings Apparence - + Tree Arbre - + Colors Couleurs - + Icon color: Icone: - + Nothing Rien - + POV POV - + Label Label - + Progress Progrès - + Compile Compilation - + Text color: Texte: - + Background color: Arrière-plan: - + Folders Dossiers - + Show item count Afficher le nombre de sous-éléments - + Show wordcount Afficher le nombre de mots - + Show progress Afficher le progrès - + Text Texte - + Outline Plan - + Visible columns Colonnes visibles - + Goal Goal - + Word count Nombre de mots - + Percentage Pourcentage - + Title Titre - + Index cards Cartes - + Item colors Couleurs des cartes - + Border color: Bordure: - + Corner color: Coin: - + Background Arrière-plan - + Color: Couleur: - + Ctrl+S Ctrl+S - + Image: Image: - + New Nouveau - + Edit Modifier - + Delete Supprimer - + Theme name: Nom du thème: - + Apply Enregistrer - + Cancel Annuler - + Window Background Arrière plan de la fenêtre - + Text Background Arrière plan du texte - + Text Options Options du texte - + Paragraph Options Options des paragraphes - + Type: Type: - + No Image Pas d'image - + Tiled Mosaïque - + Centered Centrée - + Stretched Étirée - + Scaled Mise à l'échelle - + Zoomed Zoomée - + Opacity: Opacité: - + % % - + Position: Position: - + Left Gauche - + Center Centre - + Right Droite - + Width: Largeur: - + px px - + Corner radius: Arrondi: - + Margins: Marges: - + Padding: Intérieur: - + Font: Police: - + Size: Taille: - + Misspelled: Orthographe: - + Line spacing: Espacement des lignes: - + Single Simple - + 1.5 lines 1.5 lignes - + Double Double - + Proportional Proportionnel - + Tab width: Tabulation: - + Spacing: Espacement: - + Indent 1st line Retrait 1ère ligne @@ -1037,11 +1037,41 @@ des lignes: Automatically load last project on startup Charger au démarrage le dernier projet ouvert + + + Default text format + Format de texte par défaut + + + + The format set by default when you create a new text item. You can change this on a per item basis. + Le format définit par défaut lorsque vous créez un nouveau élément texte. Vous pouvez changer ce format pour chaque élément. + + + + Text editor + Éditeur de texte + + + + Font + Police + + + + Family: + Famille: + + + + Paragraphs + Paragraphes + SpellAction - + Spelling Suggestions Suggestions @@ -1152,12 +1182,12 @@ des lignes: editorWidget - + {} words / {} {} mots / {} - + {} words {} mots @@ -1173,17 +1203,17 @@ des lignes: fullScreenEditor - + Theme: Thème: - + {} words / {} {} mots / {} - + {} words {} mots @@ -1212,22 +1242,22 @@ des lignes: Form - + Properties Propriétés - + Summary Résumé - + One line summary Résumé en une ligne - + Notes Notes @@ -1235,76 +1265,183 @@ des lignes: outlineBasics - + Copy Copier - + Cut Couper - + Paste Coller - + Delete Supprimer - + Set POV Choisir le POV - + Set Status Choisir le status - + Set Label Choisir le label - + New Folder Nouveau Dossier - + None Aucun - + New Nouveau - + New Text Nouveau text - + Main Principal - + Secondary Secondaire - + Minor Mineur + + outlineModel + + + Title + Titre + + + + POV + POV + + + + Label + Label + + + + Status + Status + + + + Compile + Compilation + + + + Word count + Nombre de mots + + + + Goal + Goal + + + + outlinePersoDelegate + + + None + Aucun + + + + Main + Principal + + + + Secondary + Secondaire + + + + Minor + Mineur + + + + persosProxyModel + + + Main + Principal + + + + Secundary + Secondaire + + + + Minors + Mineurs + + + + plotModel + + + New plot + Nouvelle intrigue + + + + New subplot + Nouvelle sous-intrigue + + + + Main + Principale + + + + Secondary + Secondaire + + + + Minor + Mineure + + plotTreeView @@ -1331,58 +1468,78 @@ des lignes: Form - + POV POV - + Status Status - + Label Label - + Compile Compile - + Goal Goal - + Word count Nombre de mots + + + Text type: + Format: + settingsWindow - + New status Nouveau status - + New label Nouveau label - + newtheme nouveautheme - + New theme Nouveau Thème + + + Txt2Tags + Txt2Tags + + + + Rich Text (html) + Texte riche (html) + + + + Plain Text + Texte simple + sldImportance @@ -1415,11 +1572,77 @@ des lignes: textEditView - + Various Différentes valeurs + + textFormat + + + CTRL+B + CTRL+G + + + + CTRL+I + CTRL+I + + + + CTRL+U + CTRL+U + + + + CTRL+P + CTRL+P + + + + CTRL+L + CTRL+L + + + + CTRL+E + CTRL+E + + + + CTRL+R + CTRL+R + + + + CTRL+J + CTRL+J + + + + treeView + + + Expand {} + Développer {} + + + + Collapse {} + Fermer {} + + + + Expand All + Tout développer + + + + Collapse All + Tout fermer + + welcome @@ -1433,37 +1656,37 @@ des lignes: - + Templates Modèles - + Empty Vide - + Novel Roman - + Novella Nouvelle - + Short Story - + Research paper - + Demo projects Projets de démonstration @@ -1478,129 +1701,149 @@ des lignes: Ajouter le nombre de mots - + Next time, automatically open last project La prochaine fois, ouvrir automatiquement le dernier projet - + Open... Ouvrir... - + Recent Récents - + Create Créer - + Open project Ouvrir le projet - + Manuskript project (*.msk) Projet Manuskript (*.msk) - + Save project as... Enregistrer le projer sous... - + Create New Project Créer un nouveau projet - + Chapter Chapitre - + Scene Scène - + Trilogy Trilogie - + Book Livre - + Section Section - + words each. mots chacun(e). - + of de - + Text Texte - + Something Quelque chose - + <b>Total:</b> {} words (~ {} pages) <b>Total:</b> {} mots (~ {} pages) - + Idea Idée - + Note Note - + Research Recherche - + TODO TODO - + First draft Premier brouillon - + Second draft Second brouillon - + Final Final + + + Default text type: + + + + + Txt2Tags + + + + + Rich Text (html) + + + + + Plain Text + + diff --git a/src/functions.py b/src/functions.py index 8eacdab7..4a7df449 100644 --- a/src/functions.py +++ b/src/functions.py @@ -124,7 +124,7 @@ def outlineItemColors(item): colors["Progress"] = colorFromProgress(pg) # Compile - if item.isCompile() in [0, "0"]: + if item.compile() in [0, "0"]: colors["Compile"] = QColor(Qt.gray) else: colors["Compile"] = QColor(Qt.black) diff --git a/src/models/outlineModel.py b/src/models/outlineModel.py index 0dbc4732..d8dfca7b 100644 --- a/src/models/outlineModel.py +++ b/src/models/outlineModel.py @@ -387,10 +387,10 @@ class outlineItem(): #print("Data: ", column, role) if role == Qt.DisplayRole or role == Qt.EditRole: - if column == Outline.compile.value: - return self.data(column, Qt.CheckStateRole) + #if column == Outline.compile.value: + #return self.data(column, Qt.CheckStateRole) - elif Outline(column) in self._data: + if Outline(column) in self._data: return self._data[Outline(column)] else: @@ -411,7 +411,11 @@ class outlineItem(): #return QBrush(Qt.gray) elif role == Qt.CheckStateRole and column == Outline.compile.value: - return self._data[Outline(column)] + #print(self.title(), self.compile()) + #if self._data[Outline(column)] and not self.compile(): + #return Qt.PartiallyChecked + #else: + return self._data[Outline(column)] elif role == Qt.FontRole: f = QFont() @@ -458,6 +462,9 @@ class outlineItem(): if column == Outline.text.value: wc = wordCount(data) self.setData(Outline.wordCount.value, wc) + + if column == Outline.compile.value: + self.emitDataChanged(cols=[Outline.title.value, Outline.compile.value], recursive=True) if updateWordCount: self.updateWordCount() @@ -527,16 +534,21 @@ class outlineItem(): else: return QModelIndex() - def emitDataChanged(self, cols=None): + def emitDataChanged(self, cols=None, recursive=False): idx = self.index() if idx and self._model: if not cols: # Emit data changed for the whole item (all columns) self._model.dataChanged.emit(idx, self.index(len(Outline))) + else: # Emit only for the specified columns for c in cols: self._model.dataChanged.emit(self.index(c), self.index(c)) + + if recursive: + for c in self.children(): + c.emitDataChanged(cols, recursive=True) def removeChild(self, row): self.childItems.pop(row) @@ -559,8 +571,13 @@ class outlineItem(): def isText(self): return self._data[Outline.type] == "txt" - def isCompile(self): - return Outline.compile in self._data and self._data[Outline.compile] + def compile(self): + if self._data[Outline.compile] in ["0", 0]: + return False + elif self.parent(): + return self.parent().compile() + else: + return True # rootItem always compile def title(self): if Outline.title in self._data: diff --git a/src/ui/views/outlineBasics.py b/src/ui/views/outlineBasics.py index b09b1e1e..472c9873 100644 --- a/src/ui/views/outlineBasics.py +++ b/src/ui/views/outlineBasics.py @@ -23,119 +23,124 @@ class outlineBasics(QAbstractItemView): if event.button() == Qt.RightButton: - index = self.currentIndex() - sel = self.getSelection() - clipboard = qApp.clipboard() - - self.menu = QMenu(self) - - # Add / remove items - self.actAddFolder = QAction(QIcon.fromTheme("folder-new"), qApp.translate("outlineBasics", "New Folder"), self.menu) - self.actAddFolder.triggered.connect(self.addFolder) - self.menu.addAction(self.actAddFolder) - - self.actAddText = QAction(QIcon.fromTheme("document-new"), qApp.translate("outlineBasics", "New Text"), self.menu) - self.actAddText.triggered.connect(self.addText) - self.menu.addAction(self.actAddText) - - self.actDelete = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "Delete"), self.menu) - self.actDelete.triggered.connect(self.delete) - self.menu.addAction(self.actDelete) - - self.menu.addSeparator() - - # Copy, cut, paste - self.actCopy = QAction(QIcon.fromTheme("edit-copy"), qApp.translate("outlineBasics", "Copy"), self.menu) - self.actCopy.triggered.connect(self.copy) - self.menu.addAction(self.actCopy) - - self.actCut = QAction(QIcon.fromTheme("edit-cut"), qApp.translate("outlineBasics", "Cut"), self.menu) - self.actCut.triggered.connect(self.cut) - self.menu.addAction(self.actCut) - - self.actPaste = QAction(QIcon.fromTheme("edit-paste"), qApp.translate("outlineBasics", "Paste"), self.menu) - self.actPaste.triggered.connect(self.paste) - self.menu.addAction(self.actPaste) - - self.menu.addSeparator() - - # POV - self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), self.menu) - mw = mainWindow() - a = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "None"), self.menuPOV) - a.triggered.connect(lambda: self.setPOV("")) - self.menuPOV.addAction(a) - self.menuPOV.addSeparator() - - menus = [] - for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]: - m = QMenu(i, self.menuPOV) - menus.append(m) - self.menuPOV.addMenu(m) - - mpr = QSignalMapper(self.menuPOV) - for i in range(mw.mdlPersos.rowCount()): - a = QAction(mw.mdlPersos.item(i, Perso.name.value).text(), self.menuPOV) - a.triggered.connect(mpr.map) - mpr.setMapping(a, int(mw.mdlPersos.item(i, Perso.ID.value).text())) - - imp = mw.mdlPersos.item(i, Perso.importance.value) - if imp: - imp = toInt(imp.text()) - else: - imp = 0 - - menus[2-imp].addAction(a) - - mpr.mapped.connect(self.setPOV) - self.menu.addMenu(self.menuPOV) - - # Status - self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"), self.menu) - #a = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "None"), self.menuStatus) - #a.triggered.connect(lambda: self.setStatus("")) - #self.menuStatus.addAction(a) - #self.menuStatus.addSeparator() - - mpr = QSignalMapper(self.menuStatus) - for i in range(mw.mdlStatus.rowCount()): - a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus) - a.triggered.connect(mpr.map) - mpr.setMapping(a, i) - self.menuStatus.addAction(a) - mpr.mapped.connect(self.setStatus) - self.menu.addMenu(self.menuStatus) - - # Labels - self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"), self.menu) - mpr = QSignalMapper(self.menuLabel) - for i in range(mw.mdlLabels.rowCount()): - a = QAction(mw.mdlLabels.item(i, 0).icon(), - mw.mdlLabels.item(i, 0).text(), - self.menuLabel) - a.triggered.connect(mpr.map) - mpr.setMapping(a, i) - self.menuLabel.addAction(a) - mpr.mapped.connect(self.setLabel) - self.menu.addMenu(self.menuLabel) - + self.menu = self.makePopupMenu() self.menu.popup(event.globalPos()) + + def makePopupMenu(self): + index = self.currentIndex() + sel = self.getSelection() + clipboard = qApp.clipboard() + + menu = QMenu(self) + + # Add / remove items + self.actAddFolder = QAction(QIcon.fromTheme("folder-new"), qApp.translate("outlineBasics", "New Folder"), menu) + self.actAddFolder.triggered.connect(self.addFolder) + menu.addAction(self.actAddFolder) + + self.actAddText = QAction(QIcon.fromTheme("document-new"), qApp.translate("outlineBasics", "New Text"), menu) + self.actAddText.triggered.connect(self.addText) + menu.addAction(self.actAddText) + + self.actDelete = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "Delete"), menu) + self.actDelete.triggered.connect(self.delete) + menu.addAction(self.actDelete) + + menu.addSeparator() + + # Copy, cut, paste + self.actCopy = QAction(QIcon.fromTheme("edit-copy"), qApp.translate("outlineBasics", "Copy"), menu) + self.actCopy.triggered.connect(self.copy) + menu.addAction(self.actCopy) + + self.actCut = QAction(QIcon.fromTheme("edit-cut"), qApp.translate("outlineBasics", "Cut"), menu) + self.actCut.triggered.connect(self.cut) + menu.addAction(self.actCut) + + self.actPaste = QAction(QIcon.fromTheme("edit-paste"), qApp.translate("outlineBasics", "Paste"), menu) + self.actPaste.triggered.connect(self.paste) + menu.addAction(self.actPaste) + + menu.addSeparator() - if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder() \ - or not clipboard.mimeData().hasFormat("application/xml"): - self.actPaste.setEnabled(False) - - if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder(): - self.actAddFolder.setEnabled(False) - self.actAddText.setEnabled(False) + # POV + self.menuPOV = QMenu(qApp.translate("outlineBasics", "Set POV"), menu) + mw = mainWindow() + a = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "None"), self.menuPOV) + a.triggered.connect(lambda: self.setPOV("")) + self.menuPOV.addAction(a) + self.menuPOV.addSeparator() + + menus = [] + for i in [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]: + m = QMenu(i, self.menuPOV) + menus.append(m) + self.menuPOV.addMenu(m) + + mpr = QSignalMapper(self.menuPOV) + for i in range(mw.mdlPersos.rowCount()): + a = QAction(mw.mdlPersos.item(i, Perso.name.value).text(), self.menuPOV) + a.triggered.connect(mpr.map) + mpr.setMapping(a, int(mw.mdlPersos.item(i, Perso.ID.value).text())) - if len(sel) == 0: - self.actCopy.setEnabled(False) - self.actCut.setEnabled(False) - self.actDelete.setEnabled(False) - self.menuPOV.setEnabled(False) - self.menuStatus.setEnabled(False) - self.menuLabel.setEnabled(False) + imp = mw.mdlPersos.item(i, Perso.importance.value) + if imp: + imp = toInt(imp.text()) + else: + imp = 0 + + menus[2-imp].addAction(a) + + mpr.mapped.connect(self.setPOV) + menu.addMenu(self.menuPOV) + + # Status + self.menuStatus = QMenu(qApp.translate("outlineBasics", "Set Status"), menu) + #a = QAction(QIcon.fromTheme("edit-delete"), qApp.translate("outlineBasics", "None"), self.menuStatus) + #a.triggered.connect(lambda: self.setStatus("")) + #self.menuStatus.addAction(a) + #self.menuStatus.addSeparator() + + mpr = QSignalMapper(self.menuStatus) + for i in range(mw.mdlStatus.rowCount()): + a = QAction(mw.mdlStatus.item(i, 0).text(), self.menuStatus) + a.triggered.connect(mpr.map) + mpr.setMapping(a, i) + self.menuStatus.addAction(a) + mpr.mapped.connect(self.setStatus) + menu.addMenu(self.menuStatus) + + # Labels + self.menuLabel = QMenu(qApp.translate("outlineBasics", "Set Label"), menu) + mpr = QSignalMapper(self.menuLabel) + for i in range(mw.mdlLabels.rowCount()): + a = QAction(mw.mdlLabels.item(i, 0).icon(), + mw.mdlLabels.item(i, 0).text(), + self.menuLabel) + a.triggered.connect(mpr.map) + mpr.setMapping(a, i) + self.menuLabel.addAction(a) + mpr.mapped.connect(self.setLabel) + menu.addMenu(self.menuLabel) + + + if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder() \ + or not clipboard.mimeData().hasFormat("application/xml"): + self.actPaste.setEnabled(False) + + if len(sel) > 0 and index.isValid() and not index.internalPointer().isFolder(): + self.actAddFolder.setEnabled(False) + self.actAddText.setEnabled(False) + + if len(sel) == 0: + self.actCopy.setEnabled(False) + self.actCut.setEnabled(False) + self.actDelete.setEnabled(False) + self.menuPOV.setEnabled(False) + self.menuStatus.setEnabled(False) + self.menuLabel.setEnabled(False) + + return menu def addFolder(self): self.addItem("folder") diff --git a/src/ui/views/treeView.py b/src/ui/views/treeView.py index 30130989..90fd055e 100644 --- a/src/ui/views/treeView.py +++ b/src/ui/views/treeView.py @@ -29,6 +29,54 @@ class treeView(QTreeView, dndView, outlineBasics): self.titleDelegate = treeTitleDelegate() self.setItemDelegateForColumn(Outline.title.value, self.titleDelegate) + def makePopupMenu(self): + menu = outlineBasics.makePopupMenu(self) + first = menu.actions()[0] + + + if len(self.selectedIndexes()) != 0: + index = self.currentIndex() + item = index.internalPointer() + self.actExpand = QAction(self.tr("Expand {}").format(item.title()), menu) + self.actExpand.triggered.connect(self.expandCurrentIndex) + menu.insertAction(first, self.actExpand) + + self.actCollapse = QAction(self.tr("Collapse {}").format(item.title()), menu) + self.actCollapse.triggered.connect(self.collapseCurrentIndex) + menu.insertAction(first, self.actCollapse) + + menu.insertSeparator(first) + + self.actExpandAll = QAction(self.tr("Expand All"), menu) + self.actExpandAll.triggered.connect(self.expandAll) + menu.insertAction(first, self.actExpandAll) + + self.actCollapseAll = QAction(self.tr("Collapse All"), menu) + self.actCollapseAll.triggered.connect(self.collapseAll) + menu.insertAction(first, self.actCollapseAll) + + menu.insertSeparator(first) + + return menu + + def expandCurrentIndex(self, index=None): + if index is None or type(index) == bool: + index = self.currentIndex() + + self.expand(index) + for i in range(self.model().rowCount(index)): + idx = self.model().index(i, 0, index) + self.expandCurrentIndex(index=idx) + + def collapseCurrentIndex(self, index=None): + if index is None or type(index) == bool: + index = self.currentIndex() + + self.collapse(index) + for i in range(self.model().rowCount(index)): + idx = self.model().index(i, 0, index) + self.collapseCurrentIndex(index=idx) + def dragMoveEvent(self, event): dndView.dragMoveEvent(self, event) QTreeView.dragMoveEvent(self, event)