ProjectDjango/DjangoMigrationsListDialog.py

branch
eric7
changeset 180
64339135bd61
parent 175
30cb5e553e7e
child 181
2f5c3487139c
diff -r 8413c2429808 -r 64339135bd61 ProjectDjango/DjangoMigrationsListDialog.py
--- a/ProjectDjango/DjangoMigrationsListDialog.py	Fri Dec 31 13:17:55 2021 +0100
+++ b/ProjectDjango/DjangoMigrationsListDialog.py	Wed Sep 21 16:42:20 2022 +0200
@@ -9,9 +9,15 @@
 
 from PyQt6.QtCore import pyqtSlot, Qt, QProcess, QTimer, QPoint
 from PyQt6.QtWidgets import (
-    QDialog, QDialogButtonBox, QAbstractButton,
-    QHeaderView, QTreeWidgetItem, QMenu, QAbstractItemView, QInputDialog,
-    QLineEdit
+    QDialog,
+    QDialogButtonBox,
+    QAbstractButton,
+    QHeaderView,
+    QTreeWidgetItem,
+    QMenu,
+    QAbstractItemView,
+    QInputDialog,
+    QLineEdit,
 )
 
 from EricWidgets import EricMessageBox
@@ -25,13 +31,14 @@
     """
     Class implementing a dialog show a list of all available migrations.
     """
+
     MigrationsListMode = "L"
     MigrationsPlanMode = "P"
-    
+
     def __init__(self, mode, django, parent=None):
         """
         Constructor
-        
+
         @param mode mode of the dialog
         @type str
         @param django reference to the Django project object
@@ -41,114 +48,112 @@
         """
         super().__init__(parent)
         self.setupUi(self)
-        
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setEnabled(False)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setDefault(True)
-        
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
+
         self.ioEncoding = Preferences.getSystem("IOEncoding")
-        
+
         self.proc = QProcess()
         self.proc.finished.connect(self.__procFinished)
         self.proc.readyReadStandardOutput.connect(self.__readStdout)
         self.proc.readyReadStandardError.connect(self.__readStderr)
-        
+
         self.__pyExe = ""
         self.__sitePath = ""
-        
+
         self.__django = django
-        
+
         self.__mode = mode
         if self.__mode == DjangoMigrationsListDialog.MigrationsListMode:
             self.setWindowTitle(self.tr("Available Migrations"))
-            self.migrationsList.setHeaderLabels([
-                self.tr("Name"),
-            ])
+            self.migrationsList.setHeaderLabels(
+                [
+                    self.tr("Name"),
+                ]
+            )
             self.migrationsList.setSelectionMode(
-                QAbstractItemView.SelectionMode.ExtendedSelection)
+                QAbstractItemView.SelectionMode.ExtendedSelection
+            )
         else:
             self.setWindowTitle(self.tr("Migrations Plan"))
-            self.migrationsList.setHeaderLabels([
-                self.tr("Migration"),
-                self.tr("Dependencies"),
-            ])
+            self.migrationsList.setHeaderLabels(
+                [
+                    self.tr("Migration"),
+                    self.tr("Dependencies"),
+                ]
+            )
             self.migrationsList.setSelectionMode(
-                QAbstractItemView.SelectionMode.SingleSelection)
-        
+                QAbstractItemView.SelectionMode.SingleSelection
+            )
+
         self.refreshButton = self.buttonBox.addButton(
-            self.tr("&Refresh"), QDialogButtonBox.ButtonRole.ActionRole)
-        self.refreshButton.setToolTip(
-            self.tr("Press to refresh the list"))
+            self.tr("&Refresh"), QDialogButtonBox.ButtonRole.ActionRole
+        )
+        self.refreshButton.setToolTip(self.tr("Press to refresh the list"))
         self.refreshButton.setEnabled(False)
-    
+
     @pyqtSlot(QAbstractButton)
     def on_buttonBox_clicked(self, button):
         """
         Private slot called by a button of the button box clicked.
-        
+
         @param button button that was clicked
         @type QAbstractButton
         """
-        if button == self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close
-        ):
+        if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
             self.close()
-        elif button == self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel
-        ):
+        elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel):
             self.__finish()
         elif button == self.refreshButton:
             self.on_refreshButton_clicked()
-    
+
     def __finish(self):
         """
         Private slot called when the process finished or the user pressed the
         button.
         """
         if (
-            self.proc is not None and
-            self.proc.state() != QProcess.ProcessState.NotRunning
+            self.proc is not None
+            and self.proc.state() != QProcess.ProcessState.NotRunning
         ):
             self.proc.terminate()
             QTimer.singleShot(2000, self.proc.kill)
             self.proc.waitForFinished(3000)
-        
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setEnabled(True)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setDefault(True)
-        
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
+
         self.refreshButton.setEnabled(True)
-        
+
         self.__resizeColumns()
-    
+
     def __procFinished(self, exitCode, exitStatus):
         """
         Private slot connected to the finished signal.
-        
+
         @param exitCode exit code of the process
         @type int
         @param exitStatus exit status of the process
         @type QProcess.ExitStatus
         """
         self.__finish()
-    
+
     def __resizeColumns(self):
         """
         Private method to resize the list columns.
         """
         self.migrationsList.header().resizeSections(
-            QHeaderView.ResizeMode.ResizeToContents)
+            QHeaderView.ResizeMode.ResizeToContents
+        )
         if self.__mode == DjangoMigrationsListDialog.MigrationsListMode:
             self.migrationsList.header().setStretchLastSection(True)
-    
+
     def start(self, pythonExecutable, sitePath, databaseName):
         """
         Public slot used to start the process.
-        
+
         @param pythonExecutable Python executable to be used
         @type str
         @param sitePath path of the site
@@ -160,15 +165,15 @@
         """
         self.__pyExe = pythonExecutable
         self.__sitePath = sitePath
-        
+
         self.errorGroup.hide()
         self.migrationsList.clear()
-        
+
         self.__lastTopItem = None
-        
+
         if sitePath:
             self.proc.setWorkingDirectory(sitePath)
-        
+
         args = []
         args.append("manage.py")
         args.append("showmigrations")
@@ -180,45 +185,45 @@
             args.append("2")
         if databaseName:
             args.append("--database={0}".format(databaseName))
-        
+
         self.proc.start(pythonExecutable, args)
         procStarted = self.proc.waitForStarted()
         if not procStarted:
             self.buttonBox.setFocus()
             EricMessageBox.critical(
                 self,
-                self.tr('Process Generation Error'),
+                self.tr("Process Generation Error"),
                 self.tr(
-                    'The process {0} could not be started. '
-                    'Ensure, that it is in the search path.'
-                ).format(pythonExecutable))
+                    "The process {0} could not be started. "
+                    "Ensure, that it is in the search path."
+                ).format(pythonExecutable),
+            )
         return procStarted
-    
+
     def __readStdout(self):
         """
         Private slot to handle the readyReadStdout signal.
-        
+
         It reads the output of the process, formats it and inserts it into
         the contents pane.
         """
         while self.proc.canReadLine():
-            s = str(self.proc.readLine(), self.ioEncoding, 'replace').rstrip()
+            s = str(self.proc.readLine(), self.ioEncoding, "replace").rstrip()
             if self.__mode == DjangoMigrationsListDialog.MigrationsListMode:
                 self.__createListItem(s)
             else:
                 self.__createPlanItem(s)
-    
+
     def __createListItem(self, line):
         """
         Private method to create an item for list mode.
-        
+
         @param line line of text
         @type str
         """
         if not line.startswith(" "):
             # application name
-            self.__lastTopItem = QTreeWidgetItem(
-                self.migrationsList, [line.strip()])
+            self.__lastTopItem = QTreeWidgetItem(self.migrationsList, [line.strip()])
             self.__lastTopItem.setExpanded(True)
         else:
             # migration name
@@ -234,11 +239,11 @@
                     itm.setCheckState(0, Qt.CheckState.Unchecked)
                 else:
                     itm.setCheckState(0, Qt.CheckState.Checked)
-    
+
     def __createPlanItem(self, line):
         """
         Private method to create an item for plan mode.
-        
+
         @param line line of text
         @type str
         """
@@ -246,63 +251,64 @@
         applied = line[:3]
         parts = line[3:].strip().split(None, 2)
         if len(parts) == 3:
-            dependencies = "\n".join([
-                d.strip() for d in parts[2].strip()[1:-1].split(",")
-            ])
-            itm = QTreeWidgetItem(self.migrationsList, [
-                parts[0].strip(),
-                dependencies,
-            ])
+            dependencies = "\n".join(
+                [d.strip() for d in parts[2].strip()[1:-1].split(",")]
+            )
+            itm = QTreeWidgetItem(
+                self.migrationsList,
+                [
+                    parts[0].strip(),
+                    dependencies,
+                ],
+            )
         else:
-            itm = QTreeWidgetItem(self.migrationsList, [
-                parts[0].strip(),
-                "",
-            ])
+            itm = QTreeWidgetItem(
+                self.migrationsList,
+                [
+                    parts[0].strip(),
+                    "",
+                ],
+            )
         if applied[1] != " ":
             itm.setCheckState(0, Qt.CheckState.Checked)
-    
+
     def __readStderr(self):
         """
         Private slot to handle the readyReadStderr signal.
-        
+
         It reads the error output of the process and inserts it into the
         error pane.
         """
         if self.proc is not None:
             self.errorGroup.show()
-            s = str(self.proc.readAllStandardError(), self.ioEncoding,
-                    'replace')
+            s = str(self.proc.readAllStandardError(), self.ioEncoding, "replace")
             self.errors.insertPlainText(s)
             self.errors.ensureCursorVisible()
-    
+
     @pyqtSlot()
     def on_refreshButton_clicked(self):
         """
         Private slot to refresh the log.
         """
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setEnabled(False)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setDefault(True)
-        
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
+
         self.refreshButton.setEnabled(False)
-        
+
         self.start(self.__pyExe, self.__sitePath)
-    
+
     @pyqtSlot(QPoint)
     def on_migrationsList_customContextMenuRequested(self, pos):
         """
         Private slot to show the context menu.
-        
+
         @param pos position the context menu was requested at
         @type QPoint
         """
         menu = QMenu(self.migrationsList)
-        menu.addAction(self.tr("Apply All Migrations"),
-                       self.__applyAllMigrations)
-        
+        menu.addAction(self.tr("Apply All Migrations"), self.__applyAllMigrations)
+
         if self.__mode == DjangoMigrationsListDialog.MigrationsListMode:
             selItems = self.migrationsList.selectedItems()
             if len(selItems) > 0:
@@ -310,38 +316,39 @@
                 for itm in selItems:
                     if itm.parent() is None:
                         selApps.append(itm)
-                
+
                 menu.addAction(
-                    self.tr("Apply Selected Migrations"),
-                    self.__applyMigration).setEnabled(len(selItems) == 1)
+                    self.tr("Apply Selected Migrations"), self.__applyMigration
+                ).setEnabled(len(selItems) == 1)
                 menu.addAction(
-                    self.tr("Unapply Migrations"),
-                    self.__unapplyMigration).setEnabled(len(selApps) == 1)
+                    self.tr("Unapply Migrations"), self.__unapplyMigration
+                ).setEnabled(len(selApps) == 1)
                 menu.addSeparator()
                 menu.addAction(
-                    self.tr("Make Migrations"),
-                    self.__makeMigrations).setEnabled(len(selApps) > 0)
+                    self.tr("Make Migrations"), self.__makeMigrations
+                ).setEnabled(len(selApps) > 0)
                 act = menu.addAction(
                     self.tr("Make Empty Migrations"),
-                    lambda: self.__makeMigrations(empty=True))
+                    lambda: self.__makeMigrations(empty=True),
+                )
                 act.setEnabled(len(selApps) > 0)
                 act = menu.addAction(
                     self.tr("Make Migrations (dry-run)"),
-                    lambda: self.__makeMigrations(dryRun=True))
+                    lambda: self.__makeMigrations(dryRun=True),
+                )
                 act.setEnabled(len(selApps) > 0)
         else:
-            menu.addAction(self.tr("Apply Selected Migrations"),
-                           self.__applyMigration)
-        
+            menu.addAction(self.tr("Apply Selected Migrations"), self.__applyMigration)
+
         menu.popup(self.migrationsList.mapToGlobal(pos))
-    
+
     def __applyAllMigrations(self):
         """
         Private slot to apply all migrations.
         """
         self.__django.applyMigrations()
         self.on_refreshButton_clicked()
-    
+
     def __applyMigration(self):
         """
         Private slot to apply the selected migrations.
@@ -357,11 +364,11 @@
                 app = itm.parent().text(0)
         else:
             app, migration = itm.text(0).split(".", 1)
-        
+
         self.__django.applyMigrations(app=app, migration=migration)
-        
+
         self.on_refreshButton_clicked()
-    
+
     def __unapplyMigration(self):
         """
         Private slot to unapply the selected migrations.
@@ -372,13 +379,13 @@
                 # only valid for app entries
                 app = itm.text(0)
                 self.__django.applyMigrations(app=app, migration="zero")
-                
+
                 self.on_refreshButton_clicked()
-    
+
     def __makeMigrations(self, dryRun=False, empty=False):
         """
         Private slot to make migrations for the selected apps.
-        
+
         @param dryRun flag indicating a dry-run
         @type bool
         @param empty flag indicating an empty migration
@@ -388,17 +395,19 @@
         for itm in self.migrationsList.selectedItems():
             if itm.parent() is None:
                 apps.append(itm.text(0))
-        
+
         if apps:
             migration, ok = QInputDialog.getText(
                 self,
                 self.tr("Make Migrations"),
-                self.tr("Enter a name for the migrations (leave empty to"
-                        " use system supplied name):"),
-                QLineEdit.EchoMode.Normal)
-            
+                self.tr(
+                    "Enter a name for the migrations (leave empty to"
+                    " use system supplied name):"
+                ),
+                QLineEdit.EchoMode.Normal,
+            )
+
             if ok:
-                self.__django.makeMigrations(apps, migration, dryRun, empty,
-                                             True)
-            
+                self.__django.makeMigrations(apps, migration, dryRun, empty, True)
+
             self.on_refreshButton_clicked()

eric ide

mercurial