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: |
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": |
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"]: |