src/eric7/Project/ProjectFormsBrowser.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9387
ce743c468d09
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
19 from EricWidgets.EricApplication import ericApp 19 from EricWidgets.EricApplication import ericApp
20 from EricWidgets import EricMessageBox, EricFileDialog 20 from EricWidgets import EricMessageBox, EricFileDialog
21 from EricWidgets.EricProgressDialog import EricProgressDialog 21 from EricWidgets.EricProgressDialog import EricProgressDialog
22 22
23 from .ProjectBrowserModel import ( 23 from .ProjectBrowserModel import (
24 ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem, 24 ProjectBrowserFileItem,
25 ProjectBrowserDirectoryItem, ProjectBrowserFormType 25 ProjectBrowserSimpleDirectoryItem,
26 ProjectBrowserDirectoryItem,
27 ProjectBrowserFormType,
26 ) 28 )
27 from .ProjectBaseBrowser import ProjectBaseBrowser 29 from .ProjectBaseBrowser import ProjectBaseBrowser
28 30
29 import UI.PixmapCache 31 import UI.PixmapCache
30 from UI.NotificationWidget import NotificationTypes 32 from UI.NotificationWidget import NotificationTypes
37 39
38 40
39 class ProjectFormsBrowser(ProjectBaseBrowser): 41 class ProjectFormsBrowser(ProjectBaseBrowser):
40 """ 42 """
41 A class used to display the forms part of the project. 43 A class used to display the forms part of the project.
42 44
43 @signal appendStderr(str) emitted after something was received from 45 @signal appendStderr(str) emitted after something was received from
44 a QProcess on stderr 46 a QProcess on stderr
45 @signal uipreview(str) emitted to preview a forms file 47 @signal uipreview(str) emitted to preview a forms file
46 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The 48 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The
47 name of the menu and a reference to the menu are given. 49 name of the menu and a reference to the menu are given.
48 @signal menusAboutToBeCreated() emitted when the context menus are about to 50 @signal menusAboutToBeCreated() emitted when the context menus are about to
49 be created. This is the right moment to add or remove hook methods. 51 be created. This is the right moment to add or remove hook methods.
50 """ 52 """
53
51 appendStderr = pyqtSignal(str) 54 appendStderr = pyqtSignal(str)
52 uipreview = pyqtSignal(str) 55 uipreview = pyqtSignal(str)
53 showMenu = pyqtSignal(str, QMenu) 56 showMenu = pyqtSignal(str, QMenu)
54 menusAboutToBeCreated = pyqtSignal() 57 menusAboutToBeCreated = pyqtSignal()
55 58
56 Pyuic5IndentDefault = 4 59 Pyuic5IndentDefault = 4
57 Pyuic6IndentDefault = 4 60 Pyuic6IndentDefault = 4
58 61
59 def __init__(self, project, parent=None): 62 def __init__(self, project, parent=None):
60 """ 63 """
61 Constructor 64 Constructor
62 65
63 @param project reference to the project object 66 @param project reference to the project object
64 @param parent parent widget of this browser (QWidget) 67 @param parent parent widget of this browser (QWidget)
65 """ 68 """
66 ProjectBaseBrowser.__init__(self, project, ProjectBrowserFormType, 69 ProjectBaseBrowser.__init__(self, project, ProjectBrowserFormType, parent)
67 parent) 70
68 71 self.selectedItemsFilter = [
69 self.selectedItemsFilter = [ProjectBrowserFileItem, 72 ProjectBrowserFileItem,
70 ProjectBrowserSimpleDirectoryItem] 73 ProjectBrowserSimpleDirectoryItem,
71 74 ]
72 self.setWindowTitle(self.tr('Forms')) 75
73 76 self.setWindowTitle(self.tr("Forms"))
74 self.setWhatsThis(self.tr( 77
75 """<b>Project Forms Browser</b>""" 78 self.setWhatsThis(
76 """<p>This allows to easily see all forms contained in the""" 79 self.tr(
77 """ current project. Several actions can be executed via the""" 80 """<b>Project Forms Browser</b>"""
78 """ context menu.</p>""" 81 """<p>This allows to easily see all forms contained in the"""
79 )) 82 """ current project. Several actions can be executed via the"""
80 83 """ context menu.</p>"""
84 )
85 )
86
81 # templates for Qt 87 # templates for Qt
82 # these two lists have to stay in sync 88 # these two lists have to stay in sync
83 self.templates4 = [ 89 self.templates4 = [
84 'dialog4.tmpl', 'widget4.tmpl', 'mainwindow4.tmpl', 90 "dialog4.tmpl",
85 'dialogbuttonboxbottom4.tmpl', 'dialogbuttonboxright4.tmpl', 91 "widget4.tmpl",
86 'dialogbuttonsbottom4.tmpl', 'dialogbuttonsbottomcenter4.tmpl', 92 "mainwindow4.tmpl",
87 'dialogbuttonsright4.tmpl', '', 'wizard4.tmpl', 'wizardpage4.tmpl', 93 "dialogbuttonboxbottom4.tmpl",
88 'qdockwidget4.tmpl', 'qframe4.tmpl', 'qgroupbox4.tmpl', 94 "dialogbuttonboxright4.tmpl",
89 'qscrollarea4.tmpl', 'qmdiarea4.tmpl', 'qtabwidget4.tmpl', 95 "dialogbuttonsbottom4.tmpl",
90 'qtoolbox4.tmpl', 'qstackedwidget4.tmpl' 96 "dialogbuttonsbottomcenter4.tmpl",
97 "dialogbuttonsright4.tmpl",
98 "",
99 "wizard4.tmpl",
100 "wizardpage4.tmpl",
101 "qdockwidget4.tmpl",
102 "qframe4.tmpl",
103 "qgroupbox4.tmpl",
104 "qscrollarea4.tmpl",
105 "qmdiarea4.tmpl",
106 "qtabwidget4.tmpl",
107 "qtoolbox4.tmpl",
108 "qstackedwidget4.tmpl",
91 ] 109 ]
92 self.templateTypes4 = [ 110 self.templateTypes4 = [
93 self.tr("Dialog"), 111 self.tr("Dialog"),
94 self.tr("Widget"), 112 self.tr("Widget"),
95 self.tr("Main Window"), 113 self.tr("Main Window"),
96 self.tr("Dialog with Buttonbox (Bottom)"), 114 self.tr("Dialog with Buttonbox (Bottom)"),
97 self.tr("Dialog with Buttonbox (Right)"), 115 self.tr("Dialog with Buttonbox (Right)"),
98 self.tr("Dialog with Buttons (Bottom)"), 116 self.tr("Dialog with Buttons (Bottom)"),
99 self.tr("Dialog with Buttons (Bottom-Center)"), 117 self.tr("Dialog with Buttons (Bottom-Center)"),
100 self.tr("Dialog with Buttons (Right)"), 118 self.tr("Dialog with Buttons (Right)"),
101 '', 119 "",
102 self.tr("QWizard"), 120 self.tr("QWizard"),
103 self.tr("QWizardPage"), 121 self.tr("QWizardPage"),
104 self.tr("QDockWidget"), 122 self.tr("QDockWidget"),
105 self.tr("QFrame"), 123 self.tr("QFrame"),
106 self.tr("QGroupBox"), 124 self.tr("QGroupBox"),
108 self.tr("QMdiArea"), 126 self.tr("QMdiArea"),
109 self.tr("QTabWidget"), 127 self.tr("QTabWidget"),
110 self.tr("QToolBox"), 128 self.tr("QToolBox"),
111 self.tr("QStackedWidget"), 129 self.tr("QStackedWidget"),
112 ] 130 ]
113 131
114 self.compileProc = None 132 self.compileProc = None
115 self.__uicompiler = "" 133 self.__uicompiler = ""
116 134
117 self.project.projectClosed.connect(self.__resetUiCompiler) 135 self.project.projectClosed.connect(self.__resetUiCompiler)
118 self.project.projectPropertiesChanged.connect(self.__resetUiCompiler) 136 self.project.projectPropertiesChanged.connect(self.__resetUiCompiler)
119 137
120 def _createPopupMenus(self): 138 def _createPopupMenus(self):
121 """ 139 """
122 Protected overloaded method to generate the popup menu. 140 Protected overloaded method to generate the popup menu.
123 """ 141 """
124 self.menuActions = [] 142 self.menuActions = []
125 self.multiMenuActions = [] 143 self.multiMenuActions = []
126 self.dirMenuActions = [] 144 self.dirMenuActions = []
127 self.dirMultiMenuActions = [] 145 self.dirMultiMenuActions = []
128 146
129 self.menusAboutToBeCreated.emit() 147 self.menusAboutToBeCreated.emit()
130 148
131 projectType = self.project.getProjectType() 149 projectType = self.project.getProjectType()
132 150
133 self.menu = QMenu(self) 151 self.menu = QMenu(self)
134 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]: 152 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
153 self.menu.addAction(self.tr("Compile form"), self.__compileForm)
154 self.menu.addAction(self.tr("Compile all forms"), self.__compileAllForms)
135 self.menu.addAction( 155 self.menu.addAction(
136 self.tr('Compile form'), self.__compileForm) 156 self.tr("Generate Dialog Code..."), self.__generateDialogCode
137 self.menu.addAction( 157 )
138 self.tr('Compile all forms'),
139 self.__compileAllForms)
140 self.menu.addAction(
141 self.tr('Generate Dialog Code...'),
142 self.__generateDialogCode)
143 self.menu.addSeparator() 158 self.menu.addSeparator()
144 self.__pyuicConfigAct = self.menu.addAction( 159 self.__pyuicConfigAct = self.menu.addAction(
145 self.tr('Configure uic Compiler'), 160 self.tr("Configure uic Compiler"), self.__configureUicCompiler
146 self.__configureUicCompiler) 161 )
147 self.menu.addSeparator() 162 self.menu.addSeparator()
148 self.menu.addAction( 163 self.menu.addAction(self.tr("Open in Qt-Designer"), self.__openFile)
149 self.tr('Open in Qt-Designer'), self.__openFile) 164 self.menu.addAction(self.tr("Open in Editor"), self.__openFileInEditor)
150 self.menu.addAction(
151 self.tr('Open in Editor'), self.__openFileInEditor)
152 self.menu.addSeparator() 165 self.menu.addSeparator()
153 self.menu.addAction(self.tr('Preview form'), self.__UIPreview) 166 self.menu.addAction(self.tr("Preview form"), self.__UIPreview)
154 self.menu.addAction( 167 self.menu.addAction(self.tr("Preview translations"), self.__TRPreview)
155 self.tr('Preview translations'), self.__TRPreview)
156 else: 168 else:
157 if self.hooks["compileForm"] is not None: 169 if self.hooks["compileForm"] is not None:
158 self.menu.addAction( 170 self.menu.addAction(
159 self.hooksMenuEntries.get( 171 self.hooksMenuEntries.get("compileForm", self.tr("Compile form")),
160 "compileForm", 172 self.__compileForm,
161 self.tr('Compile form')), self.__compileForm) 173 )
162 if self.hooks["compileAllForms"] is not None: 174 if self.hooks["compileAllForms"] is not None:
163 self.menu.addAction( 175 self.menu.addAction(
164 self.hooksMenuEntries.get( 176 self.hooksMenuEntries.get(
165 "compileAllForms", 177 "compileAllForms", self.tr("Compile all forms")
166 self.tr('Compile all forms')), 178 ),
167 self.__compileAllForms) 179 self.__compileAllForms,
180 )
168 if self.hooks["generateDialogCode"] is not None: 181 if self.hooks["generateDialogCode"] is not None:
169 self.menu.addAction( 182 self.menu.addAction(
170 self.hooksMenuEntries.get( 183 self.hooksMenuEntries.get(
171 "generateDialogCode", 184 "generateDialogCode", self.tr("Generate Dialog Code...")
172 self.tr('Generate Dialog Code...')), 185 ),
173 self.__generateDialogCode) 186 self.__generateDialogCode,
187 )
174 if ( 188 if (
175 self.hooks["compileForm"] is not None or 189 self.hooks["compileForm"] is not None
176 self.hooks["compileAllForms"] is not None or 190 or self.hooks["compileAllForms"] is not None
177 self.hooks["generateDialogCode"] is not None 191 or self.hooks["generateDialogCode"] is not None
178 ): 192 ):
179 self.menu.addSeparator() 193 self.menu.addSeparator()
180 if self.hooks["open"] is not None: 194 if self.hooks["open"] is not None:
181 self.menu.addAction( 195 self.menu.addAction(
182 self.hooksMenuEntries.get("open", self.tr('Open')), 196 self.hooksMenuEntries.get("open", self.tr("Open")), self.__openFile
183 self.__openFile) 197 )
184 self.menu.addAction(self.tr('Open'), self.__openFileInEditor) 198 self.menu.addAction(self.tr("Open"), self.__openFileInEditor)
185 self.menu.addSeparator() 199 self.menu.addSeparator()
186 act = self.menu.addAction(self.tr('Rename file'), self._renameFile) 200 act = self.menu.addAction(self.tr("Rename file"), self._renameFile)
187 self.menuActions.append(act) 201 self.menuActions.append(act)
188 act = self.menu.addAction( 202 act = self.menu.addAction(self.tr("Remove from project"), self._removeFile)
189 self.tr('Remove from project'), self._removeFile)
190 self.menuActions.append(act) 203 self.menuActions.append(act)
191 act = self.menu.addAction(self.tr('Delete'), self.__deleteFile) 204 act = self.menu.addAction(self.tr("Delete"), self.__deleteFile)
192 self.menuActions.append(act) 205 self.menuActions.append(act)
193 self.menu.addSeparator() 206 self.menu.addSeparator()
194 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]: 207 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
195 self.menu.addAction(self.tr('New form...'), self.__newForm) 208 self.menu.addAction(self.tr("New form..."), self.__newForm)
196 else: 209 else:
197 if self.hooks["newForm"] is not None: 210 if self.hooks["newForm"] is not None:
198 self.menu.addAction( 211 self.menu.addAction(
199 self.hooksMenuEntries.get( 212 self.hooksMenuEntries.get("newForm", self.tr("New form...")),
200 "newForm", self.tr('New form...')), self.__newForm) 213 self.__newForm,
201 self.menu.addAction(self.tr('Add forms...'), self.__addFormFiles) 214 )
202 self.menu.addAction( 215 self.menu.addAction(self.tr("Add forms..."), self.__addFormFiles)
203 self.tr('Add forms directory...'), self.__addFormsDirectory) 216 self.menu.addAction(self.tr("Add forms directory..."), self.__addFormsDirectory)
204 self.menu.addSeparator() 217 self.menu.addSeparator()
205 self.menu.addAction( 218 self.menu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard)
206 self.tr('Copy Path to Clipboard'), self._copyToClipboard)
207 self.menu.addSeparator() 219 self.menu.addSeparator()
208 self.menu.addAction( 220 self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
209 self.tr('Expand all directories'), self._expandAllDirs) 221 self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs)
210 self.menu.addAction(
211 self.tr('Collapse all directories'), self._collapseAllDirs)
212 self.menu.addSeparator() 222 self.menu.addSeparator()
213 self.menu.addAction(self.tr('Configure...'), self._configure) 223 self.menu.addAction(self.tr("Configure..."), self._configure)
214 224
215 self.backMenu = QMenu(self) 225 self.backMenu = QMenu(self)
216 if ( 226 if (
217 projectType in [ 227 projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]
218 "PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6" 228 or self.hooks["compileAllForms"] is not None
219 ] or self.hooks["compileAllForms"] is not None
220 ): 229 ):
221 self.backMenu.addAction( 230 self.backMenu.addAction(
222 self.tr('Compile all forms'), self.__compileAllForms) 231 self.tr("Compile all forms"), self.__compileAllForms
232 )
223 self.backMenu.addSeparator() 233 self.backMenu.addSeparator()
224 self.__pyuicBackConfigAct = self.backMenu.addAction( 234 self.__pyuicBackConfigAct = self.backMenu.addAction(
225 self.tr('Configure uic Compiler'), 235 self.tr("Configure uic Compiler"), self.__configureUicCompiler
226 self.__configureUicCompiler) 236 )
227 self.backMenu.addSeparator() 237 self.backMenu.addSeparator()
228 self.backMenu.addAction(self.tr('New form...'), self.__newForm) 238 self.backMenu.addAction(self.tr("New form..."), self.__newForm)
229 else: 239 else:
230 if self.hooks["newForm"] is not None: 240 if self.hooks["newForm"] is not None:
231 self.backMenu.addAction( 241 self.backMenu.addAction(
232 self.hooksMenuEntries.get( 242 self.hooksMenuEntries.get("newForm", self.tr("New form...")),
233 "newForm", self.tr('New form...')), self.__newForm) 243 self.__newForm,
244 )
245 self.backMenu.addAction(self.tr("Add forms..."), self.project.addUiFiles)
234 self.backMenu.addAction( 246 self.backMenu.addAction(
235 self.tr('Add forms...'), self.project.addUiFiles) 247 self.tr("Add forms directory..."), self.project.addUiDir
248 )
249 self.backMenu.addSeparator()
250 self.backMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
236 self.backMenu.addAction( 251 self.backMenu.addAction(
237 self.tr('Add forms directory...'), self.project.addUiDir) 252 self.tr("Collapse all directories"), self._collapseAllDirs
253 )
238 self.backMenu.addSeparator() 254 self.backMenu.addSeparator()
239 self.backMenu.addAction( 255 self.backMenu.addAction(self.tr("Configure..."), self._configure)
240 self.tr('Expand all directories'), self._expandAllDirs)
241 self.backMenu.addAction(
242 self.tr('Collapse all directories'), self._collapseAllDirs)
243 self.backMenu.addSeparator()
244 self.backMenu.addAction(self.tr('Configure...'), self._configure)
245 self.backMenu.setEnabled(False) 256 self.backMenu.setEnabled(False)
246 257
247 # create the menu for multiple selected files 258 # create the menu for multiple selected files
248 self.multiMenu = QMenu(self) 259 self.multiMenu = QMenu(self)
249 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]: 260 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
250 self.multiMenu.addAction( 261 self.multiMenu.addAction(
251 self.tr('Compile forms'), self.__compileSelectedForms) 262 self.tr("Compile forms"), self.__compileSelectedForms
263 )
252 self.multiMenu.addSeparator() 264 self.multiMenu.addSeparator()
253 self.__pyuicMultiConfigAct = self.multiMenu.addAction( 265 self.__pyuicMultiConfigAct = self.multiMenu.addAction(
254 self.tr('Configure uic Compiler'), 266 self.tr("Configure uic Compiler"), self.__configureUicCompiler
255 self.__configureUicCompiler) 267 )
256 self.multiMenu.addSeparator() 268 self.multiMenu.addSeparator()
257 self.multiMenu.addAction( 269 self.multiMenu.addAction(self.tr("Open in Qt-Designer"), self.__openFile)
258 self.tr('Open in Qt-Designer'), self.__openFile) 270 self.multiMenu.addAction(self.tr("Open in Editor"), self.__openFileInEditor)
259 self.multiMenu.addAction(
260 self.tr('Open in Editor'), self.__openFileInEditor)
261 self.multiMenu.addSeparator() 271 self.multiMenu.addSeparator()
262 self.multiMenu.addAction( 272 self.multiMenu.addAction(self.tr("Preview translations"), self.__TRPreview)
263 self.tr('Preview translations'), self.__TRPreview)
264 else: 273 else:
265 if self.hooks["compileSelectedForms"] is not None: 274 if self.hooks["compileSelectedForms"] is not None:
266 act = self.multiMenu.addAction( 275 act = self.multiMenu.addAction(
267 self.hooksMenuEntries.get( 276 self.hooksMenuEntries.get(
268 "compileSelectedForms", 277 "compileSelectedForms", self.tr("Compile forms")
269 self.tr('Compile forms')), 278 ),
270 self.__compileSelectedForms) 279 self.__compileSelectedForms,
280 )
271 self.multiMenu.addSeparator() 281 self.multiMenu.addSeparator()
272 if self.hooks["open"] is not None: 282 if self.hooks["open"] is not None:
273 self.multiMenu.addAction( 283 self.multiMenu.addAction(
274 self.hooksMenuEntries.get("open", self.tr('Open')), 284 self.hooksMenuEntries.get("open", self.tr("Open")), self.__openFile
275 self.__openFile) 285 )
276 self.multiMenu.addAction( 286 self.multiMenu.addAction(self.tr("Open"), self.__openFileInEditor)
277 self.tr('Open'), self.__openFileInEditor)
278 self.multiMenu.addSeparator() 287 self.multiMenu.addSeparator()
279 act = self.multiMenu.addAction( 288 act = self.multiMenu.addAction(self.tr("Remove from project"), self._removeFile)
280 self.tr('Remove from project'), self._removeFile)
281 self.multiMenuActions.append(act) 289 self.multiMenuActions.append(act)
282 act = self.multiMenu.addAction( 290 act = self.multiMenu.addAction(self.tr("Delete"), self.__deleteFile)
283 self.tr('Delete'), self.__deleteFile)
284 self.multiMenuActions.append(act) 291 self.multiMenuActions.append(act)
285 self.multiMenu.addSeparator() 292 self.multiMenu.addSeparator()
293 self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
286 self.multiMenu.addAction( 294 self.multiMenu.addAction(
287 self.tr('Expand all directories'), self._expandAllDirs) 295 self.tr("Collapse all directories"), self._collapseAllDirs
288 self.multiMenu.addAction( 296 )
289 self.tr('Collapse all directories'), self._collapseAllDirs)
290 self.multiMenu.addSeparator() 297 self.multiMenu.addSeparator()
291 self.multiMenu.addAction(self.tr('Configure...'), self._configure) 298 self.multiMenu.addAction(self.tr("Configure..."), self._configure)
292 299
293 self.dirMenu = QMenu(self) 300 self.dirMenu = QMenu(self)
294 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]: 301 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
295 self.dirMenu.addAction( 302 self.dirMenu.addAction(self.tr("Compile all forms"), self.__compileAllForms)
296 self.tr('Compile all forms'), self.__compileAllForms)
297 self.dirMenu.addSeparator() 303 self.dirMenu.addSeparator()
298 self.__pyuicDirConfigAct = self.dirMenu.addAction( 304 self.__pyuicDirConfigAct = self.dirMenu.addAction(
299 self.tr('Configure uic Compiler'), 305 self.tr("Configure uic Compiler"), self.__configureUicCompiler
300 self.__configureUicCompiler) 306 )
301 self.dirMenu.addSeparator() 307 self.dirMenu.addSeparator()
302 else: 308 else:
303 if self.hooks["compileAllForms"] is not None: 309 if self.hooks["compileAllForms"] is not None:
304 self.dirMenu.addAction( 310 self.dirMenu.addAction(
305 self.hooksMenuEntries.get( 311 self.hooksMenuEntries.get(
306 "compileAllForms", 312 "compileAllForms", self.tr("Compile all forms")
307 self.tr('Compile all forms')), 313 ),
308 self.__compileAllForms) 314 self.__compileAllForms,
315 )
309 self.dirMenu.addSeparator() 316 self.dirMenu.addSeparator()
310 act = self.dirMenu.addAction( 317 act = self.dirMenu.addAction(self.tr("Remove from project"), self._removeDir)
311 self.tr('Remove from project'), self._removeDir)
312 self.dirMenuActions.append(act) 318 self.dirMenuActions.append(act)
313 act = self.dirMenu.addAction( 319 act = self.dirMenu.addAction(self.tr("Delete"), self._deleteDirectory)
314 self.tr('Delete'), self._deleteDirectory)
315 self.dirMenuActions.append(act) 320 self.dirMenuActions.append(act)
316 self.dirMenu.addSeparator() 321 self.dirMenu.addSeparator()
317 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]: 322 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
318 self.dirMenu.addAction(self.tr('New form...'), self.__newForm) 323 self.dirMenu.addAction(self.tr("New form..."), self.__newForm)
319 else: 324 else:
320 if self.hooks["newForm"] is not None: 325 if self.hooks["newForm"] is not None:
321 self.dirMenu.addAction( 326 self.dirMenu.addAction(
322 self.hooksMenuEntries.get( 327 self.hooksMenuEntries.get("newForm", self.tr("New form...")),
323 "newForm", 328 self.__newForm,
324 self.tr('New form...')), self.__newForm) 329 )
330 self.dirMenu.addAction(self.tr("Add forms..."), self.__addFormFiles)
325 self.dirMenu.addAction( 331 self.dirMenu.addAction(
326 self.tr('Add forms...'), self.__addFormFiles) 332 self.tr("Add forms directory..."), self.__addFormsDirectory
333 )
334 self.dirMenu.addSeparator()
335 self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard)
336 self.dirMenu.addSeparator()
337 self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
327 self.dirMenu.addAction( 338 self.dirMenu.addAction(
328 self.tr('Add forms directory...'), self.__addFormsDirectory) 339 self.tr("Collapse all directories"), self._collapseAllDirs
340 )
329 self.dirMenu.addSeparator() 341 self.dirMenu.addSeparator()
330 self.dirMenu.addAction( 342 self.dirMenu.addAction(self.tr("Configure..."), self._configure)
331 self.tr('Copy Path to Clipboard'), self._copyToClipboard) 343
332 self.dirMenu.addSeparator()
333 self.dirMenu.addAction(
334 self.tr('Expand all directories'), self._expandAllDirs)
335 self.dirMenu.addAction(
336 self.tr('Collapse all directories'), self._collapseAllDirs)
337 self.dirMenu.addSeparator()
338 self.dirMenu.addAction(self.tr('Configure...'), self._configure)
339
340 self.dirMultiMenu = QMenu(self) 344 self.dirMultiMenu = QMenu(self)
341 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]: 345 if projectType in ["PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6"]:
342 self.dirMultiMenu.addAction( 346 self.dirMultiMenu.addAction(
343 self.tr('Compile all forms'), self.__compileAllForms) 347 self.tr("Compile all forms"), self.__compileAllForms
348 )
344 self.dirMultiMenu.addSeparator() 349 self.dirMultiMenu.addSeparator()
345 self.__pyuicDirMultiConfigAct = self.dirMultiMenu.addAction( 350 self.__pyuicDirMultiConfigAct = self.dirMultiMenu.addAction(
346 self.tr('Configure uic Compiler'), 351 self.tr("Configure uic Compiler"), self.__configureUicCompiler
347 self.__configureUicCompiler) 352 )
348 self.dirMultiMenu.addSeparator() 353 self.dirMultiMenu.addSeparator()
349 else: 354 else:
350 if self.hooks["compileAllForms"] is not None: 355 if self.hooks["compileAllForms"] is not None:
351 self.dirMultiMenu.addAction( 356 self.dirMultiMenu.addAction(
352 self.hooksMenuEntries.get( 357 self.hooksMenuEntries.get(
353 "compileAllForms", 358 "compileAllForms", self.tr("Compile all forms")
354 self.tr('Compile all forms')), 359 ),
355 self.__compileAllForms) 360 self.__compileAllForms,
361 )
356 self.dirMultiMenu.addSeparator() 362 self.dirMultiMenu.addSeparator()
363 self.dirMultiMenu.addAction(self.tr("Add forms..."), self.project.addUiFiles)
357 self.dirMultiMenu.addAction( 364 self.dirMultiMenu.addAction(
358 self.tr('Add forms...'), self.project.addUiFiles) 365 self.tr("Add forms directory..."), self.project.addUiDir
359 self.dirMultiMenu.addAction( 366 )
360 self.tr('Add forms directory...'), self.project.addUiDir)
361 self.dirMultiMenu.addSeparator() 367 self.dirMultiMenu.addSeparator()
362 self.dirMultiMenu.addAction( 368 self.dirMultiMenu.addAction(
363 self.tr('Expand all directories'), self._expandAllDirs) 369 self.tr("Expand all directories"), self._expandAllDirs
370 )
364 self.dirMultiMenu.addAction( 371 self.dirMultiMenu.addAction(
365 self.tr('Collapse all directories'), self._collapseAllDirs) 372 self.tr("Collapse all directories"), self._collapseAllDirs
373 )
366 self.dirMultiMenu.addSeparator() 374 self.dirMultiMenu.addSeparator()
367 self.dirMultiMenu.addAction( 375 self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure)
368 self.tr('Configure...'), self._configure) 376
369
370 self.menu.aboutToShow.connect(self.__showContextMenu) 377 self.menu.aboutToShow.connect(self.__showContextMenu)
371 self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti) 378 self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti)
372 self.dirMenu.aboutToShow.connect(self.__showContextMenuDir) 379 self.dirMenu.aboutToShow.connect(self.__showContextMenuDir)
373 self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti) 380 self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti)
374 self.backMenu.aboutToShow.connect(self.__showContextMenuBack) 381 self.backMenu.aboutToShow.connect(self.__showContextMenuBack)
375 self.mainMenu = self.menu 382 self.mainMenu = self.menu
376 383
377 def _contextMenuRequested(self, coord): 384 def _contextMenuRequested(self, coord):
378 """ 385 """
379 Protected slot to show the context menu. 386 Protected slot to show the context menu.
380 387
381 @param coord the position of the mouse pointer (QPoint) 388 @param coord the position of the mouse pointer (QPoint)
382 """ 389 """
383 if not self.project.isOpen(): 390 if not self.project.isOpen():
384 return 391 return
385 392
386 enable = ( 393 enable = self.project.getProjectType() in ("PyQt5", "PyQt6", "E7Plugin")
387 self.project.getProjectType() in ("PyQt5", "PyQt6", "E7Plugin")
388 )
389 self.__pyuicConfigAct.setEnabled(enable) 394 self.__pyuicConfigAct.setEnabled(enable)
390 self.__pyuicMultiConfigAct.setEnabled(enable) 395 self.__pyuicMultiConfigAct.setEnabled(enable)
391 self.__pyuicDirConfigAct.setEnabled(enable) 396 self.__pyuicDirConfigAct.setEnabled(enable)
392 self.__pyuicDirMultiConfigAct.setEnabled(enable) 397 self.__pyuicDirMultiConfigAct.setEnabled(enable)
393 self.__pyuicBackConfigAct.setEnabled(enable) 398 self.__pyuicBackConfigAct.setEnabled(enable)
394 399
395 with contextlib.suppress(Exception): 400 with contextlib.suppress(Exception):
396 categories = self.getSelectedItemsCountCategorized( 401 categories = self.getSelectedItemsCountCategorized(
397 [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem]) 402 [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem]
403 )
398 cnt = categories["sum"] 404 cnt = categories["sum"]
399 if cnt <= 1: 405 if cnt <= 1:
400 index = self.indexAt(coord) 406 index = self.indexAt(coord)
401 if index.isValid(): 407 if index.isValid():
402 self._selectSingleItem(index) 408 self._selectSingleItem(index)
403 categories = self.getSelectedItemsCountCategorized( 409 categories = self.getSelectedItemsCountCategorized(
404 [ProjectBrowserFileItem, 410 [ProjectBrowserFileItem, ProjectBrowserSimpleDirectoryItem]
405 ProjectBrowserSimpleDirectoryItem]) 411 )
406 cnt = categories["sum"] 412 cnt = categories["sum"]
407 413
408 bfcnt = categories[str(ProjectBrowserFileItem)] 414 bfcnt = categories[str(ProjectBrowserFileItem)]
409 sdcnt = categories[str(ProjectBrowserSimpleDirectoryItem)] 415 sdcnt = categories[str(ProjectBrowserSimpleDirectoryItem)]
410 if cnt > 1 and cnt == bfcnt: 416 if cnt > 1 and cnt == bfcnt:
411 self.multiMenu.popup(self.mapToGlobal(coord)) 417 self.multiMenu.popup(self.mapToGlobal(coord))
412 elif cnt > 1 and cnt == sdcnt: 418 elif cnt > 1 and cnt == sdcnt:
420 self.dirMenu.popup(self.mapToGlobal(coord)) 426 self.dirMenu.popup(self.mapToGlobal(coord))
421 else: 427 else:
422 self.backMenu.popup(self.mapToGlobal(coord)) 428 self.backMenu.popup(self.mapToGlobal(coord))
423 else: 429 else:
424 self.backMenu.popup(self.mapToGlobal(coord)) 430 self.backMenu.popup(self.mapToGlobal(coord))
425 431
426 def __showContextMenu(self): 432 def __showContextMenu(self):
427 """ 433 """
428 Private slot called by the menu aboutToShow signal. 434 Private slot called by the menu aboutToShow signal.
429 """ 435 """
430 ProjectBaseBrowser._showContextMenu(self, self.menu) 436 ProjectBaseBrowser._showContextMenu(self, self.menu)
431 437
432 self.showMenu.emit("Main", self.menu) 438 self.showMenu.emit("Main", self.menu)
433 439
434 def __showContextMenuMulti(self): 440 def __showContextMenuMulti(self):
435 """ 441 """
436 Private slot called by the multiMenu aboutToShow signal. 442 Private slot called by the multiMenu aboutToShow signal.
437 """ 443 """
438 ProjectBaseBrowser._showContextMenuMulti(self, self.multiMenu) 444 ProjectBaseBrowser._showContextMenuMulti(self, self.multiMenu)
439 445
440 self.showMenu.emit("MainMulti", self.multiMenu) 446 self.showMenu.emit("MainMulti", self.multiMenu)
441 447
442 def __showContextMenuDir(self): 448 def __showContextMenuDir(self):
443 """ 449 """
444 Private slot called by the dirMenu aboutToShow signal. 450 Private slot called by the dirMenu aboutToShow signal.
445 """ 451 """
446 ProjectBaseBrowser._showContextMenuDir(self, self.dirMenu) 452 ProjectBaseBrowser._showContextMenuDir(self, self.dirMenu)
447 453
448 self.showMenu.emit("MainDir", self.dirMenu) 454 self.showMenu.emit("MainDir", self.dirMenu)
449 455
450 def __showContextMenuDirMulti(self): 456 def __showContextMenuDirMulti(self):
451 """ 457 """
452 Private slot called by the dirMultiMenu aboutToShow signal. 458 Private slot called by the dirMultiMenu aboutToShow signal.
453 """ 459 """
454 ProjectBaseBrowser._showContextMenuDirMulti(self, self.dirMultiMenu) 460 ProjectBaseBrowser._showContextMenuDirMulti(self, self.dirMultiMenu)
455 461
456 self.showMenu.emit("MainDirMulti", self.dirMultiMenu) 462 self.showMenu.emit("MainDirMulti", self.dirMultiMenu)
457 463
458 def __showContextMenuBack(self): 464 def __showContextMenuBack(self):
459 """ 465 """
460 Private slot called by the backMenu aboutToShow signal. 466 Private slot called by the backMenu aboutToShow signal.
461 """ 467 """
462 ProjectBaseBrowser._showContextMenuBack(self, self.backMenu) 468 ProjectBaseBrowser._showContextMenuBack(self, self.backMenu)
463 469
464 self.showMenu.emit("MainBack", self.backMenu) 470 self.showMenu.emit("MainBack", self.backMenu)
465 471
466 def __addFormFiles(self): 472 def __addFormFiles(self):
467 """ 473 """
468 Private method to add form files to the project. 474 Private method to add form files to the project.
469 """ 475 """
470 itm = self.model().item(self.currentIndex()) 476 itm = self.model().item(self.currentIndex())
471 if isinstance(itm, ProjectBrowserFileItem): 477 if isinstance(itm, ProjectBrowserFileItem):
472 dn = os.path.dirname(itm.fileName()) 478 dn = os.path.dirname(itm.fileName())
473 elif isinstance( 479 elif isinstance(
474 itm, 480 itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
475 (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
476 ): 481 ):
477 dn = itm.dirName() 482 dn = itm.dirName()
478 else: 483 else:
479 dn = None 484 dn = None
480 self.project.addFiles('form', dn) 485 self.project.addFiles("form", dn)
481 486
482 def __addFormsDirectory(self): 487 def __addFormsDirectory(self):
483 """ 488 """
484 Private method to add form files of a directory to the project. 489 Private method to add form files of a directory to the project.
485 """ 490 """
486 itm = self.model().item(self.currentIndex()) 491 itm = self.model().item(self.currentIndex())
487 if isinstance(itm, ProjectBrowserFileItem): 492 if isinstance(itm, ProjectBrowserFileItem):
488 dn = os.path.dirname(itm.fileName()) 493 dn = os.path.dirname(itm.fileName())
489 elif isinstance( 494 elif isinstance(
490 itm, 495 itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
491 (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
492 ): 496 ):
493 dn = itm.dirName() 497 dn = itm.dirName()
494 else: 498 else:
495 dn = None 499 dn = None
496 self.project.addDirectory('form', dn) 500 self.project.addDirectory("form", dn)
497 501
498 def __openFile(self): 502 def __openFile(self):
499 """ 503 """
500 Private slot to handle the Open menu action. 504 Private slot to handle the Open menu action.
501 """ 505 """
502 itmList = self.getSelectedItems() 506 itmList = self.getSelectedItems()
506 # hook support 510 # hook support
507 if self.hooks["open"] is not None: 511 if self.hooks["open"] is not None:
508 self.hooks["open"](itm.fileName()) 512 self.hooks["open"](itm.fileName())
509 else: 513 else:
510 self.designerFile.emit(itm.fileName()) 514 self.designerFile.emit(itm.fileName())
511 515
512 def __openFileInEditor(self): 516 def __openFileInEditor(self):
513 """ 517 """
514 Private slot to handle the Open in Editor menu action. 518 Private slot to handle the Open in Editor menu action.
515 """ 519 """
516 itmList = self.getSelectedItems() 520 itmList = self.getSelectedItems()
517 for itm in itmList[:]: 521 for itm in itmList[:]:
518 self.sourceFile.emit(itm.fileName()) 522 self.sourceFile.emit(itm.fileName())
519 523
520 def _openItem(self): 524 def _openItem(self):
521 """ 525 """
522 Protected slot to handle the open popup menu entry. 526 Protected slot to handle the open popup menu entry.
523 """ 527 """
524 itmList = self.getSelectedItems() 528 itmList = self.getSelectedItems()
526 if isinstance(itm, ProjectBrowserFileItem): 530 if isinstance(itm, ProjectBrowserFileItem):
527 if itm.isDesignerFile(): 531 if itm.isDesignerFile():
528 self.designerFile.emit(itm.fileName()) 532 self.designerFile.emit(itm.fileName())
529 else: 533 else:
530 self.sourceFile.emit(itm.fileName()) 534 self.sourceFile.emit(itm.fileName())
531 535
532 def __UIPreview(self): 536 def __UIPreview(self):
533 """ 537 """
534 Private slot to handle the Preview menu action. 538 Private slot to handle the Preview menu action.
535 """ 539 """
536 itmList = self.getSelectedItems() 540 itmList = self.getSelectedItems()
537 self.uipreview.emit(itmList[0].fileName()) 541 self.uipreview.emit(itmList[0].fileName())
538 542
539 def __TRPreview(self): 543 def __TRPreview(self):
540 """ 544 """
541 Private slot to handle the Preview translations action. 545 Private slot to handle the Preview translations action.
542 """ 546 """
543 fileNames = [] 547 fileNames = []
544 for itm in self.getSelectedItems(): 548 for itm in self.getSelectedItems():
545 fileNames.append(itm.fileName()) 549 fileNames.append(itm.fileName())
546 trfiles = sorted(self.project.pdata["TRANSLATIONS"][:]) 550 trfiles = sorted(self.project.pdata["TRANSLATIONS"][:])
547 fileNames.extend([os.path.join(self.project.ppath, trfile) 551 fileNames.extend(
548 for trfile in trfiles 552 [
549 if trfile.endswith('.qm')]) 553 os.path.join(self.project.ppath, trfile)
554 for trfile in trfiles
555 if trfile.endswith(".qm")
556 ]
557 )
550 self.trpreview[list].emit(fileNames) 558 self.trpreview[list].emit(fileNames)
551 559
552 def __newForm(self): 560 def __newForm(self):
553 """ 561 """
554 Private slot to handle the New Form menu action. 562 Private slot to handle the New Form menu action.
555 """ 563 """
556 itm = self.model().item(self.currentIndex()) 564 itm = self.model().item(self.currentIndex())
562 except AttributeError: 570 except AttributeError:
563 try: 571 try:
564 path = itm.dirName() 572 path = itm.dirName()
565 except AttributeError: 573 except AttributeError:
566 path = os.path.join(self.project.ppath, itm.data(0)) 574 path = os.path.join(self.project.ppath, itm.data(0))
567 575
568 if self.hooks["newForm"] is not None: 576 if self.hooks["newForm"] is not None:
569 self.hooks["newForm"](path) 577 self.hooks["newForm"](path)
570 else: 578 else:
571 if self.project.getProjectType() in [ 579 if self.project.getProjectType() in [
572 "PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6" 580 "PyQt5",
581 "PyQt6",
582 "E7Plugin",
583 "PySide2",
584 "PySide6",
573 ]: 585 ]:
574 self.__newUiForm(path) 586 self.__newUiForm(path)
575 587
576 def __newUiForm(self, path): 588 def __newUiForm(self, path):
577 """ 589 """
578 Private slot to handle the New Form menu action for Qt-related 590 Private slot to handle the New Form menu action for Qt-related
579 projects. 591 projects.
580 592
581 @param path full directory path for the new form file (string) 593 @param path full directory path for the new form file (string)
582 """ 594 """
583 selectedForm, ok = QInputDialog.getItem( 595 selectedForm, ok = QInputDialog.getItem(
584 None, 596 None,
585 self.tr("New Form"), 597 self.tr("New Form"),
586 self.tr("Select a form type:"), 598 self.tr("Select a form type:"),
587 self.templateTypes4, 599 self.templateTypes4,
588 0, False) 600 0,
601 False,
602 )
589 if not ok or not selectedForm: 603 if not ok or not selectedForm:
590 # user pressed cancel 604 # user pressed cancel
591 return 605 return
592 606
593 templateIndex = self.templateTypes4.index(selectedForm) 607 templateIndex = self.templateTypes4.index(selectedForm)
594 templateFile = os.path.join( 608 templateFile = os.path.join(
595 getConfig('ericTemplatesDir'), self.templates4[templateIndex]) 609 getConfig("ericTemplatesDir"), self.templates4[templateIndex]
596 610 )
611
597 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 612 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
598 self, 613 self,
599 self.tr("New Form"), 614 self.tr("New Form"),
600 path, 615 path,
601 self.tr("Qt User-Interface Files (*.ui);;All Files (*)"), 616 self.tr("Qt User-Interface Files (*.ui);;All Files (*)"),
602 "", 617 "",
603 EricFileDialog.DontConfirmOverwrite) 618 EricFileDialog.DontConfirmOverwrite,
604 619 )
620
605 if not fname: 621 if not fname:
606 # user aborted or didn't enter a filename 622 # user aborted or didn't enter a filename
607 return 623 return
608 624
609 fpath = pathlib.Path(fname) 625 fpath = pathlib.Path(fname)
610 if not fpath.suffix: 626 if not fpath.suffix:
611 ex = selectedFilter.split("(*")[1].split(")")[0] 627 ex = selectedFilter.split("(*")[1].split(")")[0]
612 if ex: 628 if ex:
613 fpath = fpath.with_suffix(ex) 629 fpath = fpath.with_suffix(ex)
614 if fpath.exists(): 630 if fpath.exists():
615 res = EricMessageBox.yesNo( 631 res = EricMessageBox.yesNo(
616 self, 632 self,
617 self.tr("New Form"), 633 self.tr("New Form"),
618 self.tr("The file already exists! Overwrite it?"), 634 self.tr("The file already exists! Overwrite it?"),
619 icon=EricMessageBox.Warning) 635 icon=EricMessageBox.Warning,
636 )
620 if not res: 637 if not res:
621 # user selected to not overwrite 638 # user selected to not overwrite
622 return 639 return
623 640
624 try: 641 try:
625 shutil.copy(templateFile, fpath) 642 shutil.copy(templateFile, fpath)
626 except OSError as err: 643 except OSError as err:
627 EricMessageBox.critical( 644 EricMessageBox.critical(
628 self, 645 self,
629 self.tr("New Form"), 646 self.tr("New Form"),
630 self.tr( 647 self.tr(
631 "<p>The new form file <b>{0}</b> could not be created.<br>" 648 "<p>The new form file <b>{0}</b> could not be created.<br>"
632 "Problem: {1}</p>").format(fpath, str(err))) 649 "Problem: {1}</p>"
650 ).format(fpath, str(err)),
651 )
633 return 652 return
634 653
635 self.project.appendFile(str(fpath)) 654 self.project.appendFile(str(fpath))
636 self.designerFile.emit(str(fpath)) 655 self.designerFile.emit(str(fpath))
637 656
638 def __deleteFile(self): 657 def __deleteFile(self):
639 """ 658 """
640 Private method to delete a form file from the project. 659 Private method to delete a form file from the project.
641 """ 660 """
642 itmList = self.getSelectedItems() 661 itmList = self.getSelectedItems()
643 662
644 files = [] 663 files = []
645 fullNames = [] 664 fullNames = []
646 for itm in itmList: 665 for itm in itmList:
647 fn2 = itm.fileName() 666 fn2 = itm.fileName()
648 fullNames.append(fn2) 667 fullNames.append(fn2)
649 fn = self.project.getRelativePath(fn2) 668 fn = self.project.getRelativePath(fn2)
650 files.append(fn) 669 files.append(fn)
651 670
652 from UI.DeleteFilesConfirmationDialog import ( 671 from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
653 DeleteFilesConfirmationDialog 672
654 )
655 dlg = DeleteFilesConfirmationDialog( 673 dlg = DeleteFilesConfirmationDialog(
656 self.parent(), 674 self.parent(),
657 self.tr("Delete forms"), 675 self.tr("Delete forms"),
658 self.tr( 676 self.tr("Do you really want to delete these forms from the project?"),
659 "Do you really want to delete these forms from the project?"), 677 files,
660 files) 678 )
661 679
662 if dlg.exec() == QDialog.DialogCode.Accepted: 680 if dlg.exec() == QDialog.DialogCode.Accepted:
663 for fn2, fn in zip(fullNames, files): 681 for fn2, fn in zip(fullNames, files):
664 self.closeSourceWindow.emit(fn2) 682 self.closeSourceWindow.emit(fn2)
665 self.project.deleteFile(fn) 683 self.project.deleteFile(fn)
666 684
667 ########################################################################### 685 ###########################################################################
668 ## Methods to handle the various compile commands 686 ## Methods to handle the various compile commands
669 ########################################################################### 687 ###########################################################################
670 688
671 def __resetUiCompiler(self): 689 def __resetUiCompiler(self):
672 """ 690 """
673 Private slot to reset the determined UI compiler executable. 691 Private slot to reset the determined UI compiler executable.
674 """ 692 """
675 self.__uicompiler = "" 693 self.__uicompiler = ""
676 694
677 def __determineUiCompiler(self): 695 def __determineUiCompiler(self):
678 """ 696 """
679 Private method to determine the UI compiler for the project. 697 Private method to determine the UI compiler for the project.
680 """ 698 """
681 self.__resetUiCompiler() 699 self.__resetUiCompiler()
682 700
683 if self.project.getProjectLanguage() == "Python3": 701 if self.project.getProjectLanguage() == "Python3":
684 if self.project.getProjectType() in ["PyQt5"]: 702 if self.project.getProjectType() in ["PyQt5"]:
685 self.__uicompiler = Utilities.generatePyQtToolPath( 703 self.__uicompiler = Utilities.generatePyQtToolPath(
686 'pyuic5', ["py3uic5"]) 704 "pyuic5", ["py3uic5"]
705 )
687 elif self.project.getProjectType() in ["PyQt6", "E7Plugin"]: 706 elif self.project.getProjectType() in ["PyQt6", "E7Plugin"]:
688 self.__uicompiler = Utilities.generatePyQtToolPath( 707 self.__uicompiler = Utilities.generatePyQtToolPath("pyuic6")
689 'pyuic6')
690 elif self.project.getProjectType() == "PySide2": 708 elif self.project.getProjectType() == "PySide2":
691 self.__uicompiler = Utilities.generatePySideToolPath( 709 self.__uicompiler = Utilities.generatePySideToolPath(
692 'pyside2-uic', variant=2) 710 "pyside2-uic", variant=2
711 )
693 elif self.project.getProjectType() == "PySide6": 712 elif self.project.getProjectType() == "PySide6":
694 self.__uicompiler = Utilities.generatePySideToolPath( 713 self.__uicompiler = Utilities.generatePySideToolPath(
695 'pyside6-uic', variant=6) 714 "pyside6-uic", variant=6
696 715 )
716
697 def getUiCompiler(self): 717 def getUiCompiler(self):
698 """ 718 """
699 Public method to get the UI compiler executable of the project. 719 Public method to get the UI compiler executable of the project.
700 720
701 @return UI compiler executable 721 @return UI compiler executable
702 @rtype str 722 @rtype str
703 """ 723 """
704 if not self.__uicompiler: 724 if not self.__uicompiler:
705 self.__determineUiCompiler() 725 self.__determineUiCompiler()
706 726
707 return self.__uicompiler 727 return self.__uicompiler
708 728
709 def __readStdout(self): 729 def __readStdout(self):
710 """ 730 """
711 Private slot to handle the readyReadStandardOutput signal of the 731 Private slot to handle the readyReadStandardOutput signal of the
712 pyuic5/pyuic6/pyside2-uic/pyside6-uic process. 732 pyuic5/pyuic6/pyside2-uic/pyside6-uic process.
713 """ 733 """
714 if self.compileProc is None: 734 if self.compileProc is None:
715 return 735 return
716 self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardOutput) 736 self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardOutput)
717 737
718 while self.compileProc and self.compileProc.canReadLine(): 738 while self.compileProc and self.compileProc.canReadLine():
719 self.buf += str(self.compileProc.readLine(), 739 self.buf += str(self.compileProc.readLine(), "utf-8", "replace")
720 "utf-8", 'replace') 740
721
722 def __readStderr(self): 741 def __readStderr(self):
723 """ 742 """
724 Private slot to handle the readyReadStandardError signal of the 743 Private slot to handle the readyReadStandardError signal of the
725 pyuic5/pyuic6/pyside2-uic/pyside6-uic process. 744 pyuic5/pyuic6/pyside2-uic/pyside6-uic process.
726 """ 745 """
727 if self.compileProc is None: 746 if self.compileProc is None:
728 return 747 return
729 748
730 ioEncoding = Preferences.getSystem("IOEncoding") 749 ioEncoding = Preferences.getSystem("IOEncoding")
731 750
732 self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardError) 751 self.compileProc.setReadChannel(QProcess.ProcessChannel.StandardError)
733 while self.compileProc and self.compileProc.canReadLine(): 752 while self.compileProc and self.compileProc.canReadLine():
734 s = self.__uicompiler + ': ' 753 s = self.__uicompiler + ": "
735 error = str(self.compileProc.readLine(), 754 error = str(self.compileProc.readLine(), ioEncoding, "replace")
736 ioEncoding, 'replace')
737 s += error 755 s += error
738 self.appendStderr.emit(s) 756 self.appendStderr.emit(s)
739 757
740 def __compileUIDone(self, exitCode, exitStatus): 758 def __compileUIDone(self, exitCode, exitStatus):
741 """ 759 """
742 Private slot to handle the finished signal of the pyuic/rbuic process. 760 Private slot to handle the finished signal of the pyuic/rbuic process.
743 761
744 @param exitCode exit code of the process (integer) 762 @param exitCode exit code of the process (integer)
745 @param exitStatus exit status of the process (QProcess.ExitStatus) 763 @param exitStatus exit status of the process (QProcess.ExitStatus)
746 """ 764 """
747 self.compileRunning = False 765 self.compileRunning = False
748 ericApp().getObject("ViewManager").enableEditorsCheckFocusIn(True) 766 ericApp().getObject("ViewManager").enableEditorsCheckFocusIn(True)
749 ui = ericApp().getObject("UserInterface") 767 ui = ericApp().getObject("UserInterface")
750 if ( 768 if exitStatus == QProcess.ExitStatus.NormalExit and exitCode == 0 and self.buf:
751 exitStatus == QProcess.ExitStatus.NormalExit and
752 exitCode == 0 and
753 self.buf
754 ):
755 ofn = os.path.join(self.project.ppath, self.compiledFile) 769 ofn = os.path.join(self.project.ppath, self.compiledFile)
756 try: 770 try:
757 newline = (None if self.project.useSystemEol() 771 newline = (
758 else self.project.getEolString()) 772 None if self.project.useSystemEol() else self.project.getEolString()
773 )
759 with open(ofn, "w", encoding="utf-8", newline=newline) as f: 774 with open(ofn, "w", encoding="utf-8", newline=newline) as f:
760 for line in self.buf.splitlines(): 775 for line in self.buf.splitlines():
761 f.write(line + "\n") 776 f.write(line + "\n")
762 if self.compiledFile not in self.project.pdata["SOURCES"]: 777 if self.compiledFile not in self.project.pdata["SOURCES"]:
763 self.project.appendFile(ofn) 778 self.project.appendFile(ofn)
764 ui.showNotification( 779 ui.showNotification(
765 UI.PixmapCache.getPixmap("designer48"), 780 UI.PixmapCache.getPixmap("designer48"),
766 self.tr("Form Compilation"), 781 self.tr("Form Compilation"),
767 self.tr("The compilation of the form file" 782 self.tr("The compilation of the form file" " was successful."),
768 " was successful.")) 783 )
769 self.project.projectFormCompiled.emit(self.compiledFile) 784 self.project.projectFormCompiled.emit(self.compiledFile)
770 except OSError as msg: 785 except OSError as msg:
771 ui.showNotification( 786 ui.showNotification(
772 UI.PixmapCache.getPixmap("designer48"), 787 UI.PixmapCache.getPixmap("designer48"),
773 self.tr("Form Compilation"), 788 self.tr("Form Compilation"),
774 self.tr( 789 self.tr(
775 "<p>The compilation of the form file failed.</p>" 790 "<p>The compilation of the form file failed.</p>"
776 "<p>Reason: {0}</p>").format(str(msg)), 791 "<p>Reason: {0}</p>"
792 ).format(str(msg)),
777 kind=NotificationTypes.CRITICAL, 793 kind=NotificationTypes.CRITICAL,
778 timeout=0) 794 timeout=0,
795 )
779 else: 796 else:
780 ui.showNotification( 797 ui.showNotification(
781 UI.PixmapCache.getPixmap("designer48"), 798 UI.PixmapCache.getPixmap("designer48"),
782 self.tr("Form Compilation"), 799 self.tr("Form Compilation"),
783 self.tr("The compilation of the form file failed."), 800 self.tr("The compilation of the form file failed."),
784 kind=NotificationTypes.CRITICAL, 801 kind=NotificationTypes.CRITICAL,
785 timeout=0) 802 timeout=0,
803 )
786 self.compileProc = None 804 self.compileProc = None
787 805
788 def __compileUI(self, fn, noDialog=False, progress=None): 806 def __compileUI(self, fn, noDialog=False, progress=None):
789 """ 807 """
790 Private method to compile a .ui file to a .py/.rb file. 808 Private method to compile a .ui file to a .py/.rb file.
791 809
792 @param fn filename of the .ui file to be compiled 810 @param fn filename of the .ui file to be compiled
793 @param noDialog flag indicating silent operations 811 @param noDialog flag indicating silent operations
794 @param progress reference to the progress dialog 812 @param progress reference to the progress dialog
795 @return reference to the compile process (QProcess) 813 @return reference to the compile process (QProcess)
796 """ 814 """
797 self.compileProc = QProcess() 815 self.compileProc = QProcess()
798 args = [] 816 args = []
799 self.buf = "" 817 self.buf = ""
800 818
801 uicompiler = self.getUiCompiler() 819 uicompiler = self.getUiCompiler()
802 if not uicompiler: 820 if not uicompiler:
803 return None 821 return None
804 822
805 ofn, ext = os.path.splitext(fn) 823 ofn, ext = os.path.splitext(fn)
806 fn = os.path.join(self.project.ppath, fn) 824 fn = os.path.join(self.project.ppath, fn)
807 825
808 if self.project.getProjectLanguage() == "Python3": 826 if self.project.getProjectLanguage() == "Python3":
809 dirname, filename = os.path.split(ofn) 827 dirname, filename = os.path.split(ofn)
810 self.compiledFile = os.path.join(dirname, "Ui_" + filename + ".py") 828 self.compiledFile = os.path.join(dirname, "Ui_" + filename + ".py")
811 829
812 if self.project.getProjectType() == "PySide2": 830 if self.project.getProjectType() == "PySide2":
813 # PySide2 831 # PySide2
814 if Preferences.getQt("PySide2FromImports"): 832 if Preferences.getQt("PySide2FromImports"):
815 args.append("--from-imports") 833 args.append("--from-imports")
816 elif self.project.getProjectType() == "PySide6": 834 elif self.project.getProjectType() == "PySide6":
829 if Preferences.getQt("PyuicExecute"): 847 if Preferences.getQt("PyuicExecute"):
830 args.append("-x") 848 args.append("-x")
831 indentWidth = Preferences.getQt("PyuicIndent") 849 indentWidth = Preferences.getQt("PyuicIndent")
832 if indentWidth != self.Pyuic5IndentDefault: 850 if indentWidth != self.Pyuic5IndentDefault:
833 args.append("--indent={0}".format(indentWidth)) 851 args.append("--indent={0}".format(indentWidth))
834 if ( 852 if "uic5" in uicompiler and self.project.pdata["UICPARAMS"]["Package"]:
835 'uic5' in uicompiler and 853 args.append(
836 self.project.pdata["UICPARAMS"]["Package"] 854 "--import-from={0}".format(
837 ): 855 self.project.pdata["UICPARAMS"]["Package"]
838 args.append("--import-from={0}".format( 856 )
839 self.project.pdata["UICPARAMS"]["Package"])) 857 )
840 elif Preferences.getQt("PyuicFromImports"): 858 elif Preferences.getQt("PyuicFromImports"):
841 args.append("--from-imports") 859 args.append("--from-imports")
842 if self.project.pdata["UICPARAMS"]["RcSuffix"]: 860 if self.project.pdata["UICPARAMS"]["RcSuffix"]:
843 args.append("--resource-suffix={0}".format( 861 args.append(
844 self.project.pdata["UICPARAMS"]["RcSuffix"])) 862 "--resource-suffix={0}".format(
863 self.project.pdata["UICPARAMS"]["RcSuffix"]
864 )
865 )
845 elif self.project.getProjectLanguage() == "Ruby": 866 elif self.project.getProjectLanguage() == "Ruby":
846 self.compiledFile = ofn + '.rb' 867 self.compiledFile = ofn + ".rb"
847 args.append('-x') 868 args.append("-x")
848 869
849 args.append(fn) 870 args.append(fn)
850 self.compileProc.finished.connect(self.__compileUIDone) 871 self.compileProc.finished.connect(self.__compileUIDone)
851 self.compileProc.readyReadStandardOutput.connect(self.__readStdout) 872 self.compileProc.readyReadStandardOutput.connect(self.__readStdout)
852 self.compileProc.readyReadStandardError.connect(self.__readStderr) 873 self.compileProc.readyReadStandardError.connect(self.__readStderr)
853 874
854 self.noDialog = noDialog 875 self.noDialog = noDialog
855 self.compileProc.setWorkingDirectory(self.project.getProjectPath()) 876 self.compileProc.setWorkingDirectory(self.project.getProjectPath())
856 self.compileProc.start(uicompiler, args) 877 self.compileProc.start(uicompiler, args)
857 procStarted = self.compileProc.waitForStarted(5000) 878 procStarted = self.compileProc.waitForStarted(5000)
858 if procStarted: 879 if procStarted:
863 self.compileRunning = False 884 self.compileRunning = False
864 if progress is not None: 885 if progress is not None:
865 progress.cancel() 886 progress.cancel()
866 EricMessageBox.critical( 887 EricMessageBox.critical(
867 self, 888 self,
868 self.tr('Process Generation Error'), 889 self.tr("Process Generation Error"),
869 self.tr( 890 self.tr(
870 'Could not start {0}.<br>' 891 "Could not start {0}.<br>" "Ensure that it is in the search path."
871 'Ensure that it is in the search path.' 892 ).format(uicompiler),
872 ).format(uicompiler)) 893 )
873 return None 894 return None
874 895
875 def __generateDialogCode(self): 896 def __generateDialogCode(self):
876 """ 897 """
877 Private method to generate dialog code for the form (Qt only). 898 Private method to generate dialog code for the form (Qt only).
878 """ 899 """
879 itm = self.model().item(self.currentIndex()) 900 itm = self.model().item(self.currentIndex())
880 fn = itm.fileName() 901 fn = itm.fileName()
881 902
882 if self.hooks["generateDialogCode"] is not None: 903 if self.hooks["generateDialogCode"] is not None:
883 self.hooks["generateDialogCode"](fn) 904 self.hooks["generateDialogCode"](fn)
884 else: 905 else:
885 from .CreateDialogCodeDialog import CreateDialogCodeDialog 906 from .CreateDialogCodeDialog import CreateDialogCodeDialog
886 907
887 # change environment 908 # change environment
888 sys.path.insert(0, self.project.getProjectPath()) 909 sys.path.insert(0, self.project.getProjectPath())
889 cwd = os.getcwd() 910 cwd = os.getcwd()
890 os.chdir(os.path.dirname(os.path.abspath(fn))) 911 os.chdir(os.path.dirname(os.path.abspath(fn)))
891 912
892 dlg = CreateDialogCodeDialog(fn, self.project, self) 913 dlg = CreateDialogCodeDialog(fn, self.project, self)
893 if not dlg.initError(): 914 if not dlg.initError():
894 dlg.exec() 915 dlg.exec()
895 916
896 # reset the environment 917 # reset the environment
897 os.chdir(cwd) 918 os.chdir(cwd)
898 del sys.path[0] 919 del sys.path[0]
899 920
900 def __compileForm(self): 921 def __compileForm(self):
901 """ 922 """
902 Private method to compile a form to a source file. 923 Private method to compile a form to a source file.
903 """ 924 """
904 itm = self.model().item(self.currentIndex()) 925 itm = self.model().item(self.currentIndex())
906 fn = self.project.getRelativePath(fn2) 927 fn = self.project.getRelativePath(fn2)
907 if self.hooks["compileForm"] is not None: 928 if self.hooks["compileForm"] is not None:
908 self.hooks["compileForm"](fn) 929 self.hooks["compileForm"](fn)
909 else: 930 else:
910 self.__compileUI(fn) 931 self.__compileUI(fn)
911 932
912 def __compileAllForms(self): 933 def __compileAllForms(self):
913 """ 934 """
914 Private method to compile all forms to source files. 935 Private method to compile all forms to source files.
915 """ 936 """
916 if self.hooks["compileAllForms"] is not None: 937 if self.hooks["compileAllForms"] is not None:
917 self.hooks["compileAllForms"](self.project.pdata["FORMS"]) 938 self.hooks["compileAllForms"](self.project.pdata["FORMS"])
918 else: 939 else:
919 numForms = len(self.project.pdata["FORMS"]) 940 numForms = len(self.project.pdata["FORMS"])
920 progress = EricProgressDialog( 941 progress = EricProgressDialog(
921 self.tr("Compiling forms..."), 942 self.tr("Compiling forms..."),
922 self.tr("Abort"), 0, numForms, 943 self.tr("Abort"),
923 self.tr("%v/%m Forms"), self) 944 0,
945 numForms,
946 self.tr("%v/%m Forms"),
947 self,
948 )
924 progress.setModal(True) 949 progress.setModal(True)
925 progress.setMinimumDuration(0) 950 progress.setMinimumDuration(0)
926 progress.setWindowTitle(self.tr("Forms")) 951 progress.setWindowTitle(self.tr("Forms"))
927 952
928 for prog, fn in enumerate(self.project.pdata["FORMS"]): 953 for prog, fn in enumerate(self.project.pdata["FORMS"]):
929 progress.setValue(prog) 954 progress.setValue(prog)
930 if progress.wasCanceled(): 955 if progress.wasCanceled():
931 break 956 break
932 957
933 proc = self.__compileUI(fn, True, progress) 958 proc = self.__compileUI(fn, True, progress)
934 if proc is not None: 959 if proc is not None:
935 while proc.state() == QProcess.ProcessState.Running: 960 while proc.state() == QProcess.ProcessState.Running:
936 QThread.msleep(100) 961 QThread.msleep(100)
937 QApplication.processEvents() 962 QApplication.processEvents()
938 else: 963 else:
939 break 964 break
940 progress.setValue(numForms) 965 progress.setValue(numForms)
941 966
942 def __compileSelectedForms(self): 967 def __compileSelectedForms(self):
943 """ 968 """
944 Private method to compile selected forms to source files. 969 Private method to compile selected forms to source files.
945 """ 970 """
946 items = self.getSelectedItems() 971 items = self.getSelectedItems()
947 files = [self.project.getRelativePath(itm.fileName()) 972 files = [self.project.getRelativePath(itm.fileName()) for itm in items]
948 for itm in items] 973
949
950 if self.hooks["compileSelectedForms"] is not None: 974 if self.hooks["compileSelectedForms"] is not None:
951 self.hooks["compileSelectedForms"](files) 975 self.hooks["compileSelectedForms"](files)
952 else: 976 else:
953 numForms = len(files) 977 numForms = len(files)
954 progress = EricProgressDialog( 978 progress = EricProgressDialog(
955 self.tr("Compiling forms..."), 979 self.tr("Compiling forms..."),
956 self.tr("Abort"), 0, numForms, 980 self.tr("Abort"),
957 self.tr("%v/%m Forms"), self) 981 0,
982 numForms,
983 self.tr("%v/%m Forms"),
984 self,
985 )
958 progress.setModal(True) 986 progress.setModal(True)
959 progress.setMinimumDuration(0) 987 progress.setMinimumDuration(0)
960 progress.setWindowTitle(self.tr("Forms")) 988 progress.setWindowTitle(self.tr("Forms"))
961 989
962 for prog, fn in enumerate(files): 990 for prog, fn in enumerate(files):
963 progress.setValue(prog) 991 progress.setValue(prog)
964 if progress.wasCanceled(): 992 if progress.wasCanceled():
965 break 993 break
966 994
967 proc = self.__compileUI(fn, True, progress) 995 proc = self.__compileUI(fn, True, progress)
968 if proc is not None: 996 if proc is not None:
969 while proc.state() == QProcess.ProcessState.Running: 997 while proc.state() == QProcess.ProcessState.Running:
970 QThread.msleep(100) 998 QThread.msleep(100)
971 QApplication.processEvents() 999 QApplication.processEvents()
972 else: 1000 else:
973 break 1001 break
974 progress.setValue(numForms) 1002 progress.setValue(numForms)
975 1003
976 def compileChangedForms(self): 1004 def compileChangedForms(self):
977 """ 1005 """
978 Public method to compile all changed forms to source files. 1006 Public method to compile all changed forms to source files.
979 """ 1007 """
980 if self.hooks["compileChangedForms"] is not None: 1008 if self.hooks["compileChangedForms"] is not None:
981 self.hooks["compileChangedForms"](self.project.pdata["FORMS"]) 1009 self.hooks["compileChangedForms"](self.project.pdata["FORMS"])
982 else: 1010 else:
983 if self.project.getProjectType() not in [ 1011 if self.project.getProjectType() not in [
984 "PyQt5", "PyQt6", "E7Plugin", "PySide2", "PySide6" 1012 "PyQt5",
1013 "PyQt6",
1014 "E7Plugin",
1015 "PySide2",
1016 "PySide6",
985 ]: 1017 ]:
986 # ignore the request for non Qt GUI projects 1018 # ignore the request for non Qt GUI projects
987 return 1019 return
988 1020
989 if len(self.project.pdata["FORMS"]) == 0: 1021 if len(self.project.pdata["FORMS"]) == 0:
990 # The project does not contain form files. 1022 # The project does not contain form files.
991 return 1023 return
992 1024
993 progress = EricProgressDialog( 1025 progress = EricProgressDialog(
994 self.tr("Determining changed forms..."), 1026 self.tr("Determining changed forms..."),
995 self.tr("Abort"), 0, 100, self.tr("%v/%m Forms"), self) 1027 self.tr("Abort"),
1028 0,
1029 100,
1030 self.tr("%v/%m Forms"),
1031 self,
1032 )
996 progress.setMinimumDuration(0) 1033 progress.setMinimumDuration(0)
997 progress.setWindowTitle(self.tr("Forms")) 1034 progress.setWindowTitle(self.tr("Forms"))
998 1035
999 # get list of changed forms 1036 # get list of changed forms
1000 changedForms = [] 1037 changedForms = []
1001 progress.setMaximum(len(self.project.pdata["FORMS"])) 1038 progress.setMaximum(len(self.project.pdata["FORMS"]))
1002 for prog, fn in enumerate(self.project.pdata["FORMS"]): 1039 for prog, fn in enumerate(self.project.pdata["FORMS"]):
1003 progress.setValue(prog) 1040 progress.setValue(prog)
1004 QApplication.processEvents() 1041 QApplication.processEvents()
1005 1042
1006 ifn = os.path.join(self.project.ppath, fn) 1043 ifn = os.path.join(self.project.ppath, fn)
1007 if self.project.getProjectLanguage() == "Python3": 1044 if self.project.getProjectLanguage() == "Python3":
1008 dirname, filename = os.path.split(os.path.splitext(ifn)[0]) 1045 dirname, filename = os.path.split(os.path.splitext(ifn)[0])
1009 ofn = os.path.join(dirname, "Ui_" + filename + ".py") 1046 ofn = os.path.join(dirname, "Ui_" + filename + ".py")
1010 elif self.project.getProjectLanguage() == "Ruby": 1047 elif self.project.getProjectLanguage() == "Ruby":
1011 ofn = os.path.splitext(ifn)[0] + '.rb' 1048 ofn = os.path.splitext(ifn)[0] + ".rb"
1012 if ( 1049 if (
1013 not os.path.exists(ofn) or 1050 not os.path.exists(ofn)
1014 os.stat(ifn).st_mtime > os.stat(ofn).st_mtime 1051 or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
1015 ): 1052 ):
1016 changedForms.append(fn) 1053 changedForms.append(fn)
1017 progress.setValue(len(self.project.pdata["FORMS"])) 1054 progress.setValue(len(self.project.pdata["FORMS"]))
1018 QApplication.processEvents() 1055 QApplication.processEvents()
1019 1056
1020 if changedForms: 1057 if changedForms:
1021 progress.setLabelText( 1058 progress.setLabelText(self.tr("Compiling changed forms..."))
1022 self.tr("Compiling changed forms..."))
1023 progress.setMaximum(len(changedForms)) 1059 progress.setMaximum(len(changedForms))
1024 progress.setValue(prog) 1060 progress.setValue(prog)
1025 QApplication.processEvents() 1061 QApplication.processEvents()
1026 for prog, fn in enumerate(changedForms): 1062 for prog, fn in enumerate(changedForms):
1027 progress.setValue(prog) 1063 progress.setValue(prog)
1028 if progress.wasCanceled(): 1064 if progress.wasCanceled():
1029 break 1065 break
1030 1066
1031 proc = self.__compileUI(fn, True, progress) 1067 proc = self.__compileUI(fn, True, progress)
1032 if proc is not None: 1068 if proc is not None:
1033 while proc.state() == QProcess.ProcessState.Running: 1069 while proc.state() == QProcess.ProcessState.Running:
1034 QApplication.processEvents() 1070 QApplication.processEvents()
1035 QThread.msleep(300) 1071 QThread.msleep(300)
1036 QApplication.processEvents() 1072 QApplication.processEvents()
1037 else: 1073 else:
1038 break 1074 break
1039 progress.setValue(len(changedForms)) 1075 progress.setValue(len(changedForms))
1040 QApplication.processEvents() 1076 QApplication.processEvents()
1041 1077
1042 def handlePreferencesChanged(self): 1078 def handlePreferencesChanged(self):
1043 """ 1079 """
1044 Public slot used to handle the preferencesChanged signal. 1080 Public slot used to handle the preferencesChanged signal.
1045 """ 1081 """
1046 ProjectBaseBrowser.handlePreferencesChanged(self) 1082 ProjectBaseBrowser.handlePreferencesChanged(self)
1047 1083
1048 self.__resetUiCompiler() 1084 self.__resetUiCompiler()
1049 1085
1050 def __configureUicCompiler(self): 1086 def __configureUicCompiler(self):
1051 """ 1087 """
1052 Private slot to configure some non-common uic compiler options. 1088 Private slot to configure some non-common uic compiler options.
1053 """ 1089 """
1054 from .UicCompilerOptionsDialog import UicCompilerOptionsDialog 1090 from .UicCompilerOptionsDialog import UicCompilerOptionsDialog
1055 1091
1056 params = self.project.pdata["UICPARAMS"] 1092 params = self.project.pdata["UICPARAMS"]
1057 1093
1058 if self.project.getProjectType() in ["PyQt5", "PyQt6", "E7Plugin"]: 1094 if self.project.getProjectType() in ["PyQt5", "PyQt6", "E7Plugin"]:
1059 dlg = UicCompilerOptionsDialog(params, self.getUiCompiler()) 1095 dlg = UicCompilerOptionsDialog(params, self.getUiCompiler())
1060 if dlg.exec() == QDialog.DialogCode.Accepted: 1096 if dlg.exec() == QDialog.DialogCode.Accepted:
1061 package, suffix, root = dlg.getData() 1097 package, suffix, root = dlg.getData()
1062 if package != params["Package"]: 1098 if package != params["Package"]:
1066 params["RcSuffix"] = suffix 1102 params["RcSuffix"] = suffix
1067 self.project.setDirty(True) 1103 self.project.setDirty(True)
1068 if root != params["PackagesRoot"]: 1104 if root != params["PackagesRoot"]:
1069 params["PackagesRoot"] = root 1105 params["PackagesRoot"] = root
1070 self.project.setDirty(True) 1106 self.project.setDirty(True)
1071 1107
1072 ########################################################################### 1108 ###########################################################################
1073 ## Support for hooks below 1109 ## Support for hooks below
1074 ########################################################################### 1110 ###########################################################################
1075 1111
1076 def _initHookMethods(self): 1112 def _initHookMethods(self):
1077 """ 1113 """
1078 Protected method to initialize the hooks dictionary. 1114 Protected method to initialize the hooks dictionary.
1079 1115
1080 Supported hook methods are: 1116 Supported hook methods are:
1081 <ul> 1117 <ul>
1082 <li>compileForm: takes filename as parameter</li> 1118 <li>compileForm: takes filename as parameter</li>
1083 <li>compileAllForms: takes list of filenames as parameter</li> 1119 <li>compileAllForms: takes list of filenames as parameter</li>
1084 <li>compileSelectedForms: takes list of filenames as parameter</li> 1120 <li>compileSelectedForms: takes list of filenames as parameter</li>
1085 <li>compileChangedForms: takes list of filenames as parameter</li> 1121 <li>compileChangedForms: takes list of filenames as parameter</li>
1086 <li>generateDialogCode: takes filename as parameter</li> 1122 <li>generateDialogCode: takes filename as parameter</li>
1087 <li>newForm: takes full directory path of new file as parameter</li> 1123 <li>newForm: takes full directory path of new file as parameter</li>
1088 <li>open: takes a filename as parameter</li> 1124 <li>open: takes a filename as parameter</li>
1089 </ul> 1125 </ul>
1090 1126
1091 <b>Note</b>: Filenames are relative to the project directory, if not 1127 <b>Note</b>: Filenames are relative to the project directory, if not
1092 specified differently. 1128 specified differently.
1093 """ 1129 """
1094 self.hooks = { 1130 self.hooks = {
1095 "compileForm": None, 1131 "compileForm": None,

eric ide

mercurial