ProjectPyramid/MigrateSummaryDialog.py

branch
eric7
changeset 159
d4e7f5a389e6
parent 156
62170c2682a3
child 160
41b23683d5a1
equal deleted inserted replaced
158:24582cac737e 159:d4e7f5a389e6
8 """ 8 """
9 9
10 from PyQt6.QtCore import pyqtSlot, Qt, QProcess, QEventLoop, QTimer 10 from PyQt6.QtCore import pyqtSlot, Qt, QProcess, QEventLoop, QTimer
11 from PyQt6.QtGui import QGuiApplication 11 from PyQt6.QtGui import QGuiApplication
12 from PyQt6.QtWidgets import ( 12 from PyQt6.QtWidgets import (
13 QDialog, QDialogButtonBox, QAbstractButton, QTreeWidgetItem, 13 QDialog,
14 QAbstractItemView 14 QDialogButtonBox,
15 QAbstractButton,
16 QTreeWidgetItem,
17 QAbstractItemView,
15 ) 18 )
16 19
17 from EricGui.EricOverrideCursor import EricOverrideCursor, EricOverridenCursor 20 from EricGui.EricOverrideCursor import EricOverrideCursor, EricOverridenCursor
18 from EricWidgets import EricMessageBox 21 from EricWidgets import EricMessageBox
19 22
22 25
23 class MigrateSummaryDialog(QDialog, Ui_MigrateSummaryDialog): 26 class MigrateSummaryDialog(QDialog, Ui_MigrateSummaryDialog):
24 """ 27 """
25 Class implementing a dialog showing a summary of all created.migrations. 28 Class implementing a dialog showing a summary of all created.migrations.
26 """ 29 """
30
27 def __init__(self, project, parent=None): 31 def __init__(self, project, parent=None):
28 """ 32 """
29 Constructor 33 Constructor
30 34
31 @param project reference to the project object 35 @param project reference to the project object
32 @type Project 36 @type Project
33 @param parent reference to the parent widget 37 @param parent reference to the parent widget
34 @type QWidget 38 @type QWidget
35 """ 39 """
36 super().__init__(parent) 40 super().__init__(parent)
37 self.setupUi(self) 41 self.setupUi(self)
38 42
39 self.__refreshButton = self.buttonBox.addButton( 43 self.__refreshButton = self.buttonBox.addButton(
40 self.tr("Refresh"), QDialogButtonBox.ButtonRole.ActionRole) 44 self.tr("Refresh"), QDialogButtonBox.ButtonRole.ActionRole
45 )
41 self.__refreshButton.clicked.connect(self.showSummary) 46 self.__refreshButton.clicked.connect(self.showSummary)
42 47
43 self.__project = project 48 self.__project = project
44 49
45 self.__process = None 50 self.__process = None
46 self.__currentItemIndex = 1000000 51 self.__currentItemIndex = 1000000
47 self.__currentRevision = "" 52 self.__currentRevision = ""
48 53
49 def showSummary(self): 54 def showSummary(self):
50 """ 55 """
51 Public method to show the migrations summary. 56 Public method to show the migrations summary.
52 """ 57 """
53 projectPath = self.__project.projectPath() 58 projectPath = self.__project.projectPath()
54 59
55 self.show() 60 self.show()
56 self.raise_() 61 self.raise_()
57 62
58 self.buttonBox.button( 63 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
59 QDialogButtonBox.StandardButton.Close).setEnabled(False) 64 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
60 self.buttonBox.button( 65 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
61 QDialogButtonBox.StandardButton.Cancel).setDefault(True) 66 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setFocus(
62 self.buttonBox.button( 67 Qt.FocusReason.OtherFocusReason
63 QDialogButtonBox.StandardButton.Cancel).setEnabled(True) 68 )
64 self.buttonBox.button(
65 QDialogButtonBox.StandardButton.Cancel).setFocus(
66 Qt.FocusReason.OtherFocusReason)
67 QGuiApplication.processEvents( 69 QGuiApplication.processEvents(
68 QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents) 70 QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents
69 71 )
72
70 command = self.__project.getAlembicCommand() 73 command = self.__project.getAlembicCommand()
71 74
72 self.__process = QProcess() 75 self.__process = QProcess()
73 self.__process.setWorkingDirectory(projectPath) 76 self.__process.setWorkingDirectory(projectPath)
74 77
75 args = ["-c", "development.ini", "history", "--indicate-current"] 78 args = ["-c", "development.ini", "history", "--indicate-current"]
76 79
77 with EricOverrideCursor(): 80 with EricOverrideCursor():
78 self.__process.start(command, args) 81 self.__process.start(command, args)
79 ok = self.__process.waitForStarted(10000) 82 ok = self.__process.waitForStarted(10000)
80 if ok: 83 if ok:
81 ok = self.__process.waitForFinished(10000) 84 ok = self.__process.waitForFinished(10000)
82 if ok: 85 if ok:
83 out = str(self.__process.readAllStandardOutput(), 86 out = str(self.__process.readAllStandardOutput(), "utf-8")
84 "utf-8")
85 self.__processOutput(out) 87 self.__processOutput(out)
86 self.__selectItem(self.__currentRevision) 88 self.__selectItem(self.__currentRevision)
87 else: 89 else:
88 with EricOverridenCursor(): 90 with EricOverridenCursor():
89 EricMessageBox.critical( 91 EricMessageBox.critical(
90 None, 92 None,
91 self.tr("Migrations Summary"), 93 self.tr("Migrations Summary"),
92 self.tr("""The 'alembic' process did not finish""" 94 self.tr(
93 """ within 10 seconds.""")) 95 """The 'alembic' process did not finish"""
96 """ within 10 seconds."""
97 ),
98 )
94 else: 99 else:
95 with EricOverridenCursor(): 100 with EricOverridenCursor():
96 EricMessageBox.critical( 101 EricMessageBox.critical(
97 None, 102 None,
98 self.tr("Migrations Summary"), 103 self.tr("Migrations Summary"),
99 self.tr("""The 'alembic' process could not be""" 104 self.tr(
100 """ started.""")) 105 """The 'alembic' process could not be""" """ started."""
106 ),
107 )
101 for column in range(self.summaryWidget.columnCount()): 108 for column in range(self.summaryWidget.columnCount()):
102 self.summaryWidget.resizeColumnToContents(column) 109 self.summaryWidget.resizeColumnToContents(column)
103 110
104 self.buttonBox.button( 111 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
105 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) 112 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
106 self.buttonBox.button( 113 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
107 QDialogButtonBox.StandardButton.Close).setEnabled(True) 114 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus(
108 self.buttonBox.button( 115 Qt.FocusReason.OtherFocusReason
109 QDialogButtonBox.StandardButton.Close).setDefault(True) 116 )
110 self.buttonBox.button( 117
111 QDialogButtonBox.StandardButton.Close).setFocus(
112 Qt.FocusReason.OtherFocusReason)
113
114 def __processOutput(self, output): 118 def __processOutput(self, output):
115 """ 119 """
116 Private method to process the flask output and populate the summary 120 Private method to process the flask output and populate the summary
117 list. 121 list.
118 122
119 @param output output of the flask process 123 @param output output of the flask process
120 @type str 124 @type str
121 """ 125 """
122 self.summaryWidget.clear() 126 self.summaryWidget.clear()
123 self.upDownButton.setEnabled(False) 127 self.upDownButton.setEnabled(False)
124 self.__currentItemIndex = 1000000 128 self.__currentItemIndex = 1000000
125 self.__currentRevision = "" 129 self.__currentRevision = ""
126 130
127 lines = output.splitlines() 131 lines = output.splitlines()
128 for line in lines: 132 for line in lines:
129 isCurrent = False 133 isCurrent = False
130 oldRev, rest = line.split("->") 134 oldRev, rest = line.split("->")
131 rest, message = rest.split(",", 1) 135 rest, message = rest.split(",", 1)
132 newRev, *labels = rest.split() 136 newRev, *labels = rest.split()
133 if labels: 137 if labels:
134 labelList = [ 138 labelList = [
135 label.replace("(", "").replace(")", "") 139 label.replace("(", "").replace(")", "") for label in labels
136 for label in labels
137 ] 140 ]
138 labelsStr = ", ".join(labelList) 141 labelsStr = ", ".join(labelList)
139 if "current" in labelList: 142 if "current" in labelList:
140 isCurrent = True 143 isCurrent = True
141 else: 144 else:
142 labelsStr = "" 145 labelsStr = ""
143 146
144 itm = QTreeWidgetItem(self.summaryWidget, [ 147 itm = QTreeWidgetItem(
145 oldRev.strip(), 148 self.summaryWidget,
146 newRev.strip(), 149 [
147 message.strip(), 150 oldRev.strip(),
148 labelsStr, 151 newRev.strip(),
149 ]) 152 message.strip(),
153 labelsStr,
154 ],
155 )
150 if isCurrent: 156 if isCurrent:
151 font = itm.font(0) 157 font = itm.font(0)
152 font.setBold(True) 158 font.setBold(True)
153 for column in range(self.summaryWidget.columnCount()): 159 for column in range(self.summaryWidget.columnCount()):
154 itm.setFont(column, font) 160 itm.setFont(column, font)
155 161
156 self.__currentItemIndex = ( 162 self.__currentItemIndex = self.summaryWidget.indexOfTopLevelItem(itm)
157 self.summaryWidget.indexOfTopLevelItem(itm)
158 )
159 self.__currentRevision = newRev.strip() 163 self.__currentRevision = newRev.strip()
160 164
161 @pyqtSlot() 165 @pyqtSlot()
162 def on_summaryWidget_itemSelectionChanged(self): 166 def on_summaryWidget_itemSelectionChanged(self):
163 """ 167 """
164 Private slot to handle the selection of an entry. 168 Private slot to handle the selection of an entry.
165 """ 169 """
171 elif index > self.__currentItemIndex: 175 elif index > self.__currentItemIndex:
172 self.upDownButton.setText(self.tr("Downgrade")) 176 self.upDownButton.setText(self.tr("Downgrade"))
173 self.upDownButton.setEnabled(index != self.__currentItemIndex) 177 self.upDownButton.setEnabled(index != self.__currentItemIndex)
174 else: 178 else:
175 self.upDownButton.setEnabled(False) 179 self.upDownButton.setEnabled(False)
176 180
177 @pyqtSlot() 181 @pyqtSlot()
178 def on_upDownButton_clicked(self): 182 def on_upDownButton_clicked(self):
179 """ 183 """
180 Private slot to upgrade/downgrade to the selected revision. 184 Private slot to upgrade/downgrade to the selected revision.
181 """ 185 """
184 if self.upDownButton.text() == self.tr("Upgrade"): 188 if self.upDownButton.text() == self.tr("Upgrade"):
185 self.__project.upgradeDatabase(revision=rev) 189 self.__project.upgradeDatabase(revision=rev)
186 else: 190 else:
187 self.__project.downgradeDatabase(revision=rev) 191 self.__project.downgradeDatabase(revision=rev)
188 self.showSummary() 192 self.showSummary()
189 193
190 @pyqtSlot(QAbstractButton) 194 @pyqtSlot(QAbstractButton)
191 def on_buttonBox_clicked(self, button): 195 def on_buttonBox_clicked(self, button):
192 """ 196 """
193 Private slot handling a button press of the button box. 197 Private slot handling a button press of the button box.
194 198
195 @param button reference to the pressed button 199 @param button reference to the pressed button
196 @type QAbstractButton 200 @type QAbstractButton
197 """ 201 """
198 if button is self.buttonBox.button( 202 if button is self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel):
199 QDialogButtonBox.StandardButton.Cancel
200 ):
201 self.__cancelProcess() 203 self.__cancelProcess()
202 204
203 @pyqtSlot() 205 @pyqtSlot()
204 def __cancelProcess(self): 206 def __cancelProcess(self):
205 """ 207 """
206 Private slot to terminate the current process. 208 Private slot to terminate the current process.
207 """ 209 """
208 if ( 210 if (
209 self.__process is not None and 211 self.__process is not None
210 self.__process.state() != QProcess.ProcessState.NotRunning 212 and self.__process.state() != QProcess.ProcessState.NotRunning
211 ): 213 ):
212 self.__process.terminate() 214 self.__process.terminate()
213 QTimer.singleShot(2000, self.__process.kill) 215 QTimer.singleShot(2000, self.__process.kill)
214 self.__process.waitForFinished(3000) 216 self.__process.waitForFinished(3000)
215 217
216 self.__process = None 218 self.__process = None
217 219
218 def __selectItem(self, revision): 220 def __selectItem(self, revision):
219 """ 221 """
220 Private method to select an item given its revision. 222 Private method to select an item given its revision.
221 223
222 @param revision revision of the item to select 224 @param revision revision of the item to select
223 @type str 225 @type str
224 """ 226 """
225 if revision: 227 if revision:
226 items = self.summaryWidget.findItems( 228 items = self.summaryWidget.findItems(revision, Qt.MatchFlag.MatchExactly, 1)
227 revision, Qt.MatchFlag.MatchExactly, 1)
228 if items: 229 if items:
229 # select the first item 230 # select the first item
230 items[0].setSelected(True) 231 items[0].setSelected(True)
231 self.summaryWidget.scrollToItem( 232 self.summaryWidget.scrollToItem(
232 items[0], QAbstractItemView.ScrollHint.PositionAtCenter) 233 items[0], QAbstractItemView.ScrollHint.PositionAtCenter
234 )

eric ide

mercurial