ProjectDjango/Project.py

branch
eric7
changeset 180
64339135bd61
parent 178
60c87e256fc7
child 184
9585686bc532
equal deleted inserted replaced
179:8413c2429808 180:64339135bd61
28 import Preferences 28 import Preferences
29 import Utilities 29 import Utilities
30 import UI.PixmapCache 30 import UI.PixmapCache
31 31
32 32
33 class DjangoNoSiteSelectedException(Exception): 33 class DjangoNoSiteSelectedError(Exception):
34 """ 34 """
35 Exception thrown to signal, that there is no current site. 35 Exception thrown to signal, that there is no current site.
36 """ 36 """
37
37 pass 38 pass
38 39
39 40
40 class QProcess(QProcessPyQt): 41 class QProcess(QProcessPyQt):
41 """ 42 """
42 Class transforming the call arguments in case of gnome-terminal. 43 Class transforming the call arguments in case of gnome-terminal.
43 """ 44 """
45
44 def start(self, cmd, args=None, mode=QIODeviceBase.OpenModeFlag.ReadWrite): 46 def start(self, cmd, args=None, mode=QIODeviceBase.OpenModeFlag.ReadWrite):
45 """ 47 """
46 Public method to start the given program (cmd) in a new process, if 48 Public method to start the given program (cmd) in a new process, if
47 none is already running, passing the command line arguments in args. 49 none is already running, passing the command line arguments in args.
48 50
49 @param cmd start the given program cmd 51 @param cmd start the given program cmd
50 @type str 52 @type str
51 @param args list of parameters 53 @param args list of parameters
52 @type list of str 54 @type list of str
53 @param mode access mode 55 @param mode access mode
54 @type QIODeviceBase.OpenMode 56 @type QIODeviceBase.OpenMode
55 """ 57 """
56 if args is None: 58 if args is None:
57 args = [] 59 args = []
58 60
59 if ( 61 if (
60 cmd.endswith(('gnome-terminal', 'konsole', 'xfce4-terminal', 62 cmd.endswith(
61 'mate-terminal')) and 63 ("gnome-terminal", "konsole", "xfce4-terminal", "mate-terminal")
62 '-e' in args 64 )
65 and "-e" in args
63 ): 66 ):
64 index = args.index('-e') + 1 67 index = args.index("-e") + 1
65 cargs = ' '.join(args[index:]) 68 cargs = " ".join(args[index:])
66 args[index:] = [cargs] 69 args[index:] = [cargs]
67 70
68 super().start(cmd, args, mode) 71 super().start(cmd, args, mode)
69 72
70 @staticmethod 73 @staticmethod
71 def startDetached(cmd, args=None, path=''): 74 def startDetached(cmd, args=None, path=""):
72 """ 75 """
73 Public static method to start the given program (cmd) in a new process, 76 Public static method to start the given program (cmd) in a new process,
74 if none is already running, passing the command line arguments in args. 77 if none is already running, passing the command line arguments in args.
75 78
76 @param cmd start the given program cmd 79 @param cmd start the given program cmd
77 @type str 80 @type str
78 @param args list of parameters 81 @param args list of parameters
79 @type list of str 82 @type list of str
80 @param path new working directory 83 @param path new working directory
82 @return tuple of successful start and process id 85 @return tuple of successful start and process id
83 @rtype tuple of (bool, int) 86 @rtype tuple of (bool, int)
84 """ 87 """
85 if args is None: 88 if args is None:
86 args = [] 89 args = []
87 90
88 if ( 91 if (
89 cmd.endswith(('gnome-terminal', 'konsole', 'xfce4-terminal', 92 cmd.endswith(
90 'mate-terminal')) and 93 ("gnome-terminal", "konsole", "xfce4-terminal", "mate-terminal")
91 '-e' in args 94 )
95 and "-e" in args
92 ): 96 ):
93 index = args.index('-e') + 1 97 index = args.index("-e") + 1
94 cargs = ' '.join(args[index:]) 98 cargs = " ".join(args[index:])
95 args[index:] = [cargs] 99 args[index:] = [cargs]
96 100
97 return QProcessPyQt.startDetached(cmd, args, path) 101 return QProcessPyQt.startDetached(cmd, args, path)
98 102
99 103
100 class Project(QObject): 104 class Project(QObject):
101 """ 105 """
102 Class implementing the Django project support. 106 Class implementing the Django project support.
103 """ 107 """
108
104 RecentApplicationsKey = "Django/RecentApplications" 109 RecentApplicationsKey = "Django/RecentApplications"
105 RecentDatabaseNamesKey = "Django/RecentDatabaseNames" 110 RecentDatabaseNamesKey = "Django/RecentDatabaseNames"
106 111
107 def __init__(self, plugin, iconSuffix, parent=None): 112 def __init__(self, plugin, iconSuffix, parent=None):
108 """ 113 """
109 Constructor 114 Constructor
110 115
111 @param plugin reference to the plugin object 116 @param plugin reference to the plugin object
112 @type ProjectDjangoPlugin 117 @type ProjectDjangoPlugin
113 @param iconSuffix suffix for the icons 118 @param iconSuffix suffix for the icons
114 @type str 119 @type str
115 @param parent parent 120 @param parent parent
116 @type QObject 121 @type QObject
117 """ 122 """
118 super().__init__(parent) 123 super().__init__(parent)
119 124
120 self.__plugin = plugin 125 self.__plugin = plugin
121 self.__iconSuffix = iconSuffix 126 self.__iconSuffix = iconSuffix
122 self.__ui = parent 127 self.__ui = parent
123 128
124 self.__ericProject = ericApp().getObject("Project") 129 self.__ericProject = ericApp().getObject("Project")
125 self.__virtualEnvManager = ericApp().getObject("VirtualEnvManager") 130 self.__virtualEnvManager = ericApp().getObject("VirtualEnvManager")
126 self.__hooksInstalled = False 131 self.__hooksInstalled = False
127 132
128 self.__menus = {} # dictionary with references to menus 133 self.__menus = {} # dictionary with references to menus
129 134
130 self.__serverProc = None 135 self.__serverProc = None
131 self.__testServerProc = None 136 self.__testServerProc = None
132 137
133 self.__recentApplications = [] 138 self.__recentApplications = []
134 self.__loadRecentApplications() 139 self.__loadRecentApplications()
135 140
136 self.__recentDatabaseNames = [] 141 self.__recentDatabaseNames = []
137 self.__loadRecentDatabaseNames() 142 self.__loadRecentDatabaseNames()
138 143
139 self.__recentTestData = { 144 self.__recentTestData = {
140 "RecentTestLabels": [], 145 "RecentTestLabels": [],
141 "RecentTestTags": [], 146 "RecentTestTags": [],
142 "RecentTestExcludeTags": [], 147 "RecentTestExcludeTags": [],
143 } 148 }
144 self.__loadRecentTestData() 149 self.__loadRecentTestData()
145 150
146 def initActions(self): 151 def initActions(self):
147 """ 152 """
148 Public method to define the Django actions. 153 Public method to define the Django actions.
149 """ 154 """
150 self.actions = [] 155 self.actions = []
151 156
152 self.selectSiteAct = EricAction( 157 self.selectSiteAct = EricAction(
153 self.tr('Current Project'), 158 self.tr("Current Project"), "", 0, 0, self, "django_current_project"
154 "", 159 )
155 0, 0, 160 self.selectSiteAct.setStatusTip(self.tr("Selects the current project"))
156 self, 'django_current_project') 161 self.selectSiteAct.setWhatsThis(
157 self.selectSiteAct.setStatusTip(self.tr( 162 self.tr(
158 'Selects the current project')) 163 """<b>Current Project</b>"""
159 self.selectSiteAct.setWhatsThis(self.tr( 164 """<p>Selects the current project. Used for multi-project """
160 """<b>Current Project</b>""" 165 """Django projects to switch between the projects.</p>"""
161 """<p>Selects the current project. Used for multi-project """ 166 )
162 """Django projects to switch between the projects.</p>""" 167 )
163 ))
164 self.selectSiteAct.triggered.connect(self.__selectSite) 168 self.selectSiteAct.triggered.connect(self.__selectSite)
165 self.actions.append(self.selectSiteAct) 169 self.actions.append(self.selectSiteAct)
166 self.__setCurrentSite(None) 170 self.__setCurrentSite(None)
167 171
168 ############################## 172 ##############################
169 ## start actions below ## 173 ## start actions below ##
170 ############################## 174 ##############################
171 175
172 self.startProjectAct = EricAction( 176 self.startProjectAct = EricAction(
173 self.tr('Start Project'), 177 self.tr("Start Project"),
174 self.tr('Start &Project'), 178 self.tr("Start &Project"),
175 0, 0, 179 0,
176 self, 'django_start_project') 180 0,
177 self.startProjectAct.setStatusTip(self.tr( 181 self,
178 'Starts a new Django project')) 182 "django_start_project",
179 self.startProjectAct.setWhatsThis(self.tr( 183 )
180 """<b>Start Project</b>""" 184 self.startProjectAct.setStatusTip(self.tr("Starts a new Django project"))
181 """<p>Starts a new Django project using "django-admin.py""" 185 self.startProjectAct.setWhatsThis(
182 """ startproject".</p>""" 186 self.tr(
183 )) 187 """<b>Start Project</b>"""
188 """<p>Starts a new Django project using "django-admin.py"""
189 """ startproject".</p>"""
190 )
191 )
184 self.startProjectAct.triggered.connect(self.__startProject) 192 self.startProjectAct.triggered.connect(self.__startProject)
185 self.actions.append(self.startProjectAct) 193 self.actions.append(self.startProjectAct)
186 194
187 self.startGlobalApplicationAct = EricAction( 195 self.startGlobalApplicationAct = EricAction(
188 self.tr('Start Application (global)'), 196 self.tr("Start Application (global)"),
189 self.tr('Start Application (&global)'), 197 self.tr("Start Application (&global)"),
190 0, 0, 198 0,
191 self, 'django_start_global_application') 199 0,
192 self.startGlobalApplicationAct.setStatusTip(self.tr( 200 self,
193 'Starts a new global Django application')) 201 "django_start_global_application",
194 self.startGlobalApplicationAct.setWhatsThis(self.tr( 202 )
195 """<b>Start Application (global)</b>""" 203 self.startGlobalApplicationAct.setStatusTip(
196 """<p>Starts a new global Django application using""" 204 self.tr("Starts a new global Django application")
197 """ "django-admin.py startapp".</p>""" 205 )
198 )) 206 self.startGlobalApplicationAct.setWhatsThis(
199 self.startGlobalApplicationAct.triggered.connect( 207 self.tr(
200 self.__startGlobalApplication) 208 """<b>Start Application (global)</b>"""
209 """<p>Starts a new global Django application using"""
210 """ "django-admin.py startapp".</p>"""
211 )
212 )
213 self.startGlobalApplicationAct.triggered.connect(self.__startGlobalApplication)
201 self.actions.append(self.startGlobalApplicationAct) 214 self.actions.append(self.startGlobalApplicationAct)
202 215
203 self.startLocalApplicationAct = EricAction( 216 self.startLocalApplicationAct = EricAction(
204 self.tr('Start Application (local)'), 217 self.tr("Start Application (local)"),
205 self.tr('Start Application (&local)'), 218 self.tr("Start Application (&local)"),
206 0, 0, 219 0,
207 self, 'django_start_local_application') 220 0,
208 self.startLocalApplicationAct.setStatusTip(self.tr( 221 self,
209 'Starts a new local Django application')) 222 "django_start_local_application",
210 self.startLocalApplicationAct.setWhatsThis(self.tr( 223 )
211 """<b>Start Application (local)</b>""" 224 self.startLocalApplicationAct.setStatusTip(
212 """<p>Starts a new local Django application using""" 225 self.tr("Starts a new local Django application")
213 """ "manage.py startapp".</p>""" 226 )
214 )) 227 self.startLocalApplicationAct.setWhatsThis(
215 self.startLocalApplicationAct.triggered.connect( 228 self.tr(
216 self.__startLocalApplication) 229 """<b>Start Application (local)</b>"""
230 """<p>Starts a new local Django application using"""
231 """ "manage.py startapp".</p>"""
232 )
233 )
234 self.startLocalApplicationAct.triggered.connect(self.__startLocalApplication)
217 self.actions.append(self.startLocalApplicationAct) 235 self.actions.append(self.startLocalApplicationAct)
218 236
219 ############################## 237 ##############################
220 ## run actions below ## 238 ## run actions below ##
221 ############################## 239 ##############################
222 240
223 self.runServerAct = EricAction( 241 self.runServerAct = EricAction(
224 self.tr('Run Server'), 242 self.tr("Run Server"),
225 self.tr('Run &Server'), 243 self.tr("Run &Server"),
226 0, 0, 244 0,
227 self, 'django_run_server') 245 0,
228 self.runServerAct.setStatusTip(self.tr( 246 self,
229 'Starts the Django Web server')) 247 "django_run_server",
230 self.runServerAct.setWhatsThis(self.tr( 248 )
231 """<b>Run Server</b>""" 249 self.runServerAct.setStatusTip(self.tr("Starts the Django Web server"))
232 """<p>Starts the Django Web server using "manage.py""" 250 self.runServerAct.setWhatsThis(
233 """ runserver".</p>""" 251 self.tr(
234 )) 252 """<b>Run Server</b>"""
253 """<p>Starts the Django Web server using "manage.py"""
254 """ runserver".</p>"""
255 )
256 )
235 self.runServerAct.triggered.connect(self.__runServer) 257 self.runServerAct.triggered.connect(self.__runServer)
236 self.actions.append(self.runServerAct) 258 self.actions.append(self.runServerAct)
237 259
238 self.runBrowserAct = EricAction( 260 self.runBrowserAct = EricAction(
239 self.tr('Run Web-Browser'), 261 self.tr("Run Web-Browser"),
240 self.tr('Run &Web-Browser'), 262 self.tr("Run &Web-Browser"),
241 0, 0, 263 0,
242 self, 'django_run_browser') 264 0,
243 self.runBrowserAct.setStatusTip(self.tr( 265 self,
244 'Starts the default Web-Browser with the URL of the Django Web' 266 "django_run_browser",
245 ' server')) 267 )
246 self.runBrowserAct.setWhatsThis(self.tr( 268 self.runBrowserAct.setStatusTip(
247 """<b>Run Web-Browser</b>""" 269 self.tr(
248 """<p>Starts the default Web-Browser with the URL of the """ 270 "Starts the default Web-Browser with the URL of the Django Web"
249 """Django Web server.</p>""" 271 " server"
250 )) 272 )
273 )
274 self.runBrowserAct.setWhatsThis(
275 self.tr(
276 """<b>Run Web-Browser</b>"""
277 """<p>Starts the default Web-Browser with the URL of the """
278 """Django Web server.</p>"""
279 )
280 )
251 self.runBrowserAct.triggered.connect(self.__runBrowser) 281 self.runBrowserAct.triggered.connect(self.__runBrowser)
252 self.actions.append(self.runBrowserAct) 282 self.actions.append(self.runBrowserAct)
253 283
254 ############################## 284 ##############################
255 ## caching actions below ## 285 ## caching actions below ##
256 ############################## 286 ##############################
257 287
258 self.createCacheTableAct = EricAction( 288 self.createCacheTableAct = EricAction(
259 self.tr('Create Cache Tables'), 289 self.tr("Create Cache Tables"),
260 self.tr('C&reate Cache Tables'), 290 self.tr("C&reate Cache Tables"),
261 0, 0, 291 0,
262 self, 'django_create_cache_tables') 292 0,
263 self.createCacheTableAct.setStatusTip(self.tr( 293 self,
264 'Creates the tables needed to use the SQL cache backend')) 294 "django_create_cache_tables",
265 self.createCacheTableAct.setWhatsThis(self.tr( 295 )
266 """<b>Create Cache Tables</b>""" 296 self.createCacheTableAct.setStatusTip(
267 """<p>Creates the tables needed to use the SQL cache""" 297 self.tr("Creates the tables needed to use the SQL cache backend")
268 """ backend.</p>""" 298 )
269 )) 299 self.createCacheTableAct.setWhatsThis(
270 self.createCacheTableAct.triggered.connect( 300 self.tr(
271 self.__createCacheTables) 301 """<b>Create Cache Tables</b>"""
302 """<p>Creates the tables needed to use the SQL cache"""
303 """ backend.</p>"""
304 )
305 )
306 self.createCacheTableAct.triggered.connect(self.__createCacheTables)
272 self.actions.append(self.createCacheTableAct) 307 self.actions.append(self.createCacheTableAct)
273 308
274 ############################## 309 ##############################
275 ## help action below ## 310 ## help action below ##
276 ############################## 311 ##############################
277 312
278 self.helpAct = EricAction( 313 self.helpAct = EricAction(
279 self.tr('Help'), 314 self.tr("Help"), self.tr("&Help"), 0, 0, self, "django_help"
280 self.tr('&Help'), 315 )
281 0, 0, 316 self.helpAct.setStatusTip(self.tr("Shows the Django help index"))
282 self, 'django_help') 317 self.helpAct.setWhatsThis(
283 self.helpAct.setStatusTip(self.tr( 318 self.tr("""<b>Help</b>""" """<p>Shows the Django help index page.</p>""")
284 'Shows the Django help index')) 319 )
285 self.helpAct.setWhatsThis(self.tr(
286 """<b>Help</b>"""
287 """<p>Shows the Django help index page.</p>"""
288 ))
289 self.helpAct.triggered.connect(self.__showHelpIndex) 320 self.helpAct.triggered.connect(self.__showHelpIndex)
290 self.actions.append(self.helpAct) 321 self.actions.append(self.helpAct)
291 322
292 ############################## 323 ##############################
293 ## about action below ## 324 ## about action below ##
294 ############################## 325 ##############################
295 326
296 self.aboutDjangoAct = EricAction( 327 self.aboutDjangoAct = EricAction(
297 self.tr('About Django'), 328 self.tr("About Django"),
298 self.tr('About D&jango'), 329 self.tr("About D&jango"),
299 0, 0, 330 0,
300 self, 'django_about') 331 0,
301 self.aboutDjangoAct.setStatusTip(self.tr( 332 self,
302 'Shows some information about Django')) 333 "django_about",
303 self.aboutDjangoAct.setWhatsThis(self.tr( 334 )
304 """<b>About Django</b>""" 335 self.aboutDjangoAct.setStatusTip(self.tr("Shows some information about Django"))
305 """<p>Shows some information about Django.</p>""" 336 self.aboutDjangoAct.setWhatsThis(
306 )) 337 self.tr(
338 """<b>About Django</b>"""
339 """<p>Shows some information about Django.</p>"""
340 )
341 )
307 self.aboutDjangoAct.triggered.connect(self.__djangoInfo) 342 self.aboutDjangoAct.triggered.connect(self.__djangoInfo)
308 self.actions.append(self.aboutDjangoAct) 343 self.actions.append(self.aboutDjangoAct)
309 344
310 ############################## 345 ##############################
311 ## check action below ## 346 ## check action below ##
312 ############################## 347 ##############################
313 348
314 self.checkAct = EricAction( 349 self.checkAct = EricAction(
315 self.tr('Check Project'), 350 self.tr("Check Project"),
316 self.tr('Check Project'), 351 self.tr("Check Project"),
317 0, 0, 352 0,
318 self, 'django_check_project') 353 0,
319 self.checkAct.setStatusTip(self.tr( 354 self,
320 'Inspects the Django project for common problems')) 355 "django_check_project",
321 self.checkAct.setWhatsThis(self.tr( 356 )
322 """<b>Check Project</b>""" 357 self.checkAct.setStatusTip(
323 """<p>This inspects the Django project for common problems.</p>""" 358 self.tr("Inspects the Django project for common problems")
324 )) 359 )
360 self.checkAct.setWhatsThis(
361 self.tr(
362 """<b>Check Project</b>"""
363 """<p>This inspects the Django project for common problems.</p>"""
364 )
365 )
325 self.checkAct.triggered.connect(self.__performCheck) 366 self.checkAct.triggered.connect(self.__performCheck)
326 self.actions.append(self.checkAct) 367 self.actions.append(self.checkAct)
327 368
328 self.__initDatabaseActions() 369 self.__initDatabaseActions()
329 self.__initDatabaseSqlActions() 370 self.__initDatabaseSqlActions()
330 self.__initMigrationActions() 371 self.__initMigrationActions()
331 self.__initToolsActions() 372 self.__initToolsActions()
332 self.__initTestingActions() 373 self.__initTestingActions()
336 def __initDatabaseActions(self): 377 def __initDatabaseActions(self):
337 """ 378 """
338 Private method to define the database related actions. 379 Private method to define the database related actions.
339 """ 380 """
340 self.selectDatabaseNameAct = EricAction( 381 self.selectDatabaseNameAct = EricAction(
341 self.tr('Current Database'), 382 self.tr("Current Database"), "", 0, 0, self, "django_current_database"
342 "", 383 )
343 0, 0, 384 self.selectDatabaseNameAct.setStatusTip(self.tr("Selects the current database"))
344 self, 'django_current_database') 385 self.selectDatabaseNameAct.setWhatsThis(
345 self.selectDatabaseNameAct.setStatusTip(self.tr( 386 self.tr(
346 'Selects the current database')) 387 """<b>Current Database</b>"""
347 self.selectDatabaseNameAct.setWhatsThis(self.tr( 388 """<p>Selects the database name to be used by all database"""
348 """<b>Current Database</b>""" 389 """ actions. An empty database name indicates to use the default"""
349 """<p>Selects the database name to be used by all database""" 390 """ name.</p>"""
350 """ actions. An empty database name indicates to use the default""" 391 )
351 """ name.</p>""" 392 )
352 ))
353 self.selectDatabaseNameAct.triggered.connect(self.__selectDatabaseName) 393 self.selectDatabaseNameAct.triggered.connect(self.__selectDatabaseName)
354 self.actions.append(self.selectDatabaseNameAct) 394 self.actions.append(self.selectDatabaseNameAct)
355 self.__setCurrentDatabase(None) 395 self.__setCurrentDatabase(None)
356 396
357 self.inspectDatabaseAct = EricAction( 397 self.inspectDatabaseAct = EricAction(
358 self.tr('Introspect'), 398 self.tr("Introspect"),
359 self.tr('&Introspect'), 399 self.tr("&Introspect"),
360 0, 0, 400 0,
361 self, 'django_database_inspect') 401 0,
362 self.inspectDatabaseAct.setStatusTip(self.tr( 402 self,
363 'Introspects the database tables and outputs a Django model' 403 "django_database_inspect",
364 ' module')) 404 )
365 self.inspectDatabaseAct.setWhatsThis(self.tr( 405 self.inspectDatabaseAct.setStatusTip(
366 """<b>Introspect</b>""" 406 self.tr(
367 """<p>Introspects the database tables and outputs a """ 407 "Introspects the database tables and outputs a Django model" " module"
368 """Django model module.</p>""" 408 )
369 )) 409 )
410 self.inspectDatabaseAct.setWhatsThis(
411 self.tr(
412 """<b>Introspect</b>"""
413 """<p>Introspects the database tables and outputs a """
414 """Django model module.</p>"""
415 )
416 )
370 self.inspectDatabaseAct.triggered.connect(self.__databaseInspect) 417 self.inspectDatabaseAct.triggered.connect(self.__databaseInspect)
371 self.actions.append(self.inspectDatabaseAct) 418 self.actions.append(self.inspectDatabaseAct)
372 419
373 self.flushDatabaseAct = EricAction( 420 self.flushDatabaseAct = EricAction(
374 self.tr('Flush'), 421 self.tr("Flush"), self.tr("&Flush"), 0, 0, self, "django_database_flush"
375 self.tr('&Flush'), 422 )
376 0, 0, 423 self.flushDatabaseAct.setStatusTip(
377 self, 'django_database_flush') 424 self.tr(
378 self.flushDatabaseAct.setStatusTip(self.tr( 425 "Returns all database tables to the state just after their"
379 'Returns all database tables to the state just after their' 426 " installation"
380 ' installation')) 427 )
381 self.flushDatabaseAct.setWhatsThis(self.tr( 428 )
382 """<b>Flush</b>""" 429 self.flushDatabaseAct.setWhatsThis(
383 """<p>Returns all database tables to the state """ 430 self.tr(
384 """just after their installation.</p>""" 431 """<b>Flush</b>"""
385 )) 432 """<p>Returns all database tables to the state """
433 """just after their installation.</p>"""
434 )
435 )
386 self.flushDatabaseAct.triggered.connect(self.__databaseFlush) 436 self.flushDatabaseAct.triggered.connect(self.__databaseFlush)
387 self.actions.append(self.flushDatabaseAct) 437 self.actions.append(self.flushDatabaseAct)
388 438
389 self.databaseClientAct = EricAction( 439 self.databaseClientAct = EricAction(
390 self.tr('Start Client Console'), 440 self.tr("Start Client Console"),
391 self.tr('Start &Client Console'), 441 self.tr("Start &Client Console"),
392 0, 0, 442 0,
393 self, 'django_database_client') 443 0,
394 self.databaseClientAct.setStatusTip(self.tr( 444 self,
395 'Starts a console window for the database client')) 445 "django_database_client",
396 self.databaseClientAct.setWhatsThis(self.tr( 446 )
397 """<b>Start Client Console</b>""" 447 self.databaseClientAct.setStatusTip(
398 """<p>Starts a console window for the database client.</p>""" 448 self.tr("Starts a console window for the database client")
399 )) 449 )
450 self.databaseClientAct.setWhatsThis(
451 self.tr(
452 """<b>Start Client Console</b>"""
453 """<p>Starts a console window for the database client.</p>"""
454 )
455 )
400 self.databaseClientAct.triggered.connect(self.__runDatabaseClient) 456 self.databaseClientAct.triggered.connect(self.__runDatabaseClient)
401 self.actions.append(self.databaseClientAct) 457 self.actions.append(self.databaseClientAct)
402 458
403 def __initDatabaseSqlActions(self): 459 def __initDatabaseSqlActions(self):
404 """ 460 """
405 Private method to define the database SQL related actions. 461 Private method to define the database SQL related actions.
406 """ 462 """
407 self.databaseSqlFlushAct = EricAction( 463 self.databaseSqlFlushAct = EricAction(
408 self.tr('Flush Database'), 464 self.tr("Flush Database"),
409 self.tr('&Flush Database'), 465 self.tr("&Flush Database"),
410 0, 0, 466 0,
411 self, 'django_database_sql_flush_database') 467 0,
412 self.databaseSqlFlushAct.setStatusTip(self.tr( 468 self,
413 'Prints a list of statements to return all database tables to the' 469 "django_database_sql_flush_database",
414 ' state just after their installation')) 470 )
415 self.databaseSqlFlushAct.setWhatsThis(self.tr( 471 self.databaseSqlFlushAct.setStatusTip(
416 """<b>Flush Database</b>""" 472 self.tr(
417 """<p>Prints a list of statements to return all database tables""" 473 "Prints a list of statements to return all database tables to the"
418 """ to the state just after their installation.</p>""" 474 " state just after their installation"
419 )) 475 )
420 self.databaseSqlFlushAct.triggered.connect( 476 )
421 self.__databaseSqlFlushDatabase) 477 self.databaseSqlFlushAct.setWhatsThis(
478 self.tr(
479 """<b>Flush Database</b>"""
480 """<p>Prints a list of statements to return all database tables"""
481 """ to the state just after their installation.</p>"""
482 )
483 )
484 self.databaseSqlFlushAct.triggered.connect(self.__databaseSqlFlushDatabase)
422 self.actions.append(self.databaseSqlFlushAct) 485 self.actions.append(self.databaseSqlFlushAct)
423 486
424 self.databaseSqlResetSeqAct = EricAction( 487 self.databaseSqlResetSeqAct = EricAction(
425 self.tr('Reset Sequences'), 488 self.tr("Reset Sequences"),
426 self.tr('Reset &Sequences'), 489 self.tr("Reset &Sequences"),
427 0, 0, 490 0,
428 self, 'django_database_sql_reset_sequences') 491 0,
429 self.databaseSqlResetSeqAct.setStatusTip(self.tr( 492 self,
430 'Prints the SQL statements for resetting sequences for ' 493 "django_database_sql_reset_sequences",
431 'one or more applications')) 494 )
432 self.databaseSqlResetSeqAct.setWhatsThis(self.tr( 495 self.databaseSqlResetSeqAct.setStatusTip(
433 """<b>Reset Sequences</b>""" 496 self.tr(
434 """<p>Prints the SQL statements for resetting sequences for """ 497 "Prints the SQL statements for resetting sequences for "
435 """one or more applications.</p>""" 498 "one or more applications"
436 )) 499 )
437 self.databaseSqlResetSeqAct.triggered.connect( 500 )
438 self.__databaseSqlResetSequences) 501 self.databaseSqlResetSeqAct.setWhatsThis(
502 self.tr(
503 """<b>Reset Sequences</b>"""
504 """<p>Prints the SQL statements for resetting sequences for """
505 """one or more applications.</p>"""
506 )
507 )
508 self.databaseSqlResetSeqAct.triggered.connect(self.__databaseSqlResetSequences)
439 self.actions.append(self.databaseSqlResetSeqAct) 509 self.actions.append(self.databaseSqlResetSeqAct)
440 510
441 self.databaseSqlMigrateAct = EricAction( 511 self.databaseSqlMigrateAct = EricAction(
442 self.tr('Apply Migration'), 512 self.tr("Apply Migration"),
443 self.tr('&Apply Migration'), 513 self.tr("&Apply Migration"),
444 0, 0, 514 0,
445 self, 'django_database_sql_apply_migration') 515 0,
446 self.databaseSqlMigrateAct.setStatusTip(self.tr( 516 self,
447 'Prints the SQL statements to apply a migration of an' 517 "django_database_sql_apply_migration",
448 ' application')) 518 )
449 self.databaseSqlMigrateAct.setWhatsThis(self.tr( 519 self.databaseSqlMigrateAct.setStatusTip(
450 """<b>Apply Migration</b>""" 520 self.tr(
451 """<p>Prints the SQL statements to apply a migration of an""" 521 "Prints the SQL statements to apply a migration of an" " application"
452 """ application.</p>""" 522 )
453 )) 523 )
454 self.databaseSqlMigrateAct.triggered.connect( 524 self.databaseSqlMigrateAct.setWhatsThis(
455 self.__databaseSqlMigrate) 525 self.tr(
526 """<b>Apply Migration</b>"""
527 """<p>Prints the SQL statements to apply a migration of an"""
528 """ application.</p>"""
529 )
530 )
531 self.databaseSqlMigrateAct.triggered.connect(self.__databaseSqlMigrate)
456 self.actions.append(self.databaseSqlMigrateAct) 532 self.actions.append(self.databaseSqlMigrateAct)
457 533
458 self.databaseSqlMigrateBackwardsAct = EricAction( 534 self.databaseSqlMigrateBackwardsAct = EricAction(
459 self.tr('Unapply Migration'), 535 self.tr("Unapply Migration"),
460 self.tr('&Unapply Migration'), 536 self.tr("&Unapply Migration"),
461 0, 0, 537 0,
462 self, 'django_database_sql_unapply_migration') 538 0,
463 self.databaseSqlMigrateBackwardsAct.setStatusTip(self.tr( 539 self,
464 'Prints the SQL statements to unapply a migration of an' 540 "django_database_sql_unapply_migration",
465 ' application')) 541 )
466 self.databaseSqlMigrateBackwardsAct.setWhatsThis(self.tr( 542 self.databaseSqlMigrateBackwardsAct.setStatusTip(
467 """<b>Unapply Migration</b>""" 543 self.tr(
468 """<p>Prints the SQL statements to unapply a migration of an""" 544 "Prints the SQL statements to unapply a migration of an" " application"
469 """ application.</p>""" 545 )
470 )) 546 )
547 self.databaseSqlMigrateBackwardsAct.setWhatsThis(
548 self.tr(
549 """<b>Unapply Migration</b>"""
550 """<p>Prints the SQL statements to unapply a migration of an"""
551 """ application.</p>"""
552 )
553 )
471 self.databaseSqlMigrateBackwardsAct.triggered.connect( 554 self.databaseSqlMigrateBackwardsAct.triggered.connect(
472 lambda: self.__databaseSqlMigrate(backwards=True)) 555 lambda: self.__databaseSqlMigrate(backwards=True)
556 )
473 self.actions.append(self.databaseSqlMigrateBackwardsAct) 557 self.actions.append(self.databaseSqlMigrateBackwardsAct)
474 558
475 def __initToolsActions(self): 559 def __initToolsActions(self):
476 """ 560 """
477 Private method to define the tool actions. 561 Private method to define the tool actions.
478 """ 562 """
479 self.diffSettingsAct = EricAction( 563 self.diffSettingsAct = EricAction(
480 self.tr('Diff Settings'), 564 self.tr("Diff Settings"),
481 self.tr('&Diff Settings'), 565 self.tr("&Diff Settings"),
482 0, 0, 566 0,
483 self, 'django_tools_diffsettings') 567 0,
484 self.diffSettingsAct.setStatusTip(self.tr( 568 self,
485 'Shows the modification made to the settings')) 569 "django_tools_diffsettings",
486 self.diffSettingsAct.setWhatsThis(self.tr( 570 )
487 """<b>Diff Settings</b>""" 571 self.diffSettingsAct.setStatusTip(
488 """<p>Shows the modification made to the settings.</p>""" 572 self.tr("Shows the modification made to the settings")
489 )) 573 )
574 self.diffSettingsAct.setWhatsThis(
575 self.tr(
576 """<b>Diff Settings</b>"""
577 """<p>Shows the modification made to the settings.</p>"""
578 )
579 )
490 self.diffSettingsAct.triggered.connect(self.__diffSettings) 580 self.diffSettingsAct.triggered.connect(self.__diffSettings)
491 self.actions.append(self.diffSettingsAct) 581 self.actions.append(self.diffSettingsAct)
492 582
493 self.runPythonShellAct = EricAction( 583 self.runPythonShellAct = EricAction(
494 self.tr('Start Python Console'), 584 self.tr("Start Python Console"),
495 self.tr('Start &Python Console'), 585 self.tr("Start &Python Console"),
496 0, 0, 586 0,
497 self, 'django_tools_pythonconsole') 587 0,
498 self.runPythonShellAct.setStatusTip(self.tr( 588 self,
499 'Starts a Python interactive interpreter')) 589 "django_tools_pythonconsole",
500 self.runPythonShellAct.setWhatsThis(self.tr( 590 )
501 """<b>Start Python Console</b>""" 591 self.runPythonShellAct.setStatusTip(
502 """<p>Starts a Python interactive interpreter.</p>""" 592 self.tr("Starts a Python interactive interpreter")
503 )) 593 )
594 self.runPythonShellAct.setWhatsThis(
595 self.tr(
596 """<b>Start Python Console</b>"""
597 """<p>Starts a Python interactive interpreter.</p>"""
598 )
599 )
504 self.runPythonShellAct.triggered.connect(self.__runPythonShell) 600 self.runPythonShellAct.triggered.connect(self.__runPythonShell)
505 self.actions.append(self.runPythonShellAct) 601 self.actions.append(self.runPythonShellAct)
506 602
507 self.testEmailAct = EricAction( 603 self.testEmailAct = EricAction(
508 self.tr('Send Test Email'), 604 self.tr("Send Test Email"),
509 self.tr('Send Test &Email'), 605 self.tr("Send Test &Email"),
510 0, 0, 606 0,
511 self, 'django_tools_sendtestemail') 607 0,
512 self.testEmailAct.setStatusTip(self.tr( 608 self,
513 'Send a test email through Django')) 609 "django_tools_sendtestemail",
514 self.testEmailAct.setWhatsThis(self.tr( 610 )
515 """<b>Send Test Email</b>""" 611 self.testEmailAct.setStatusTip(self.tr("Send a test email through Django"))
516 """<p>Sends a test email to confirm email sending through Django""" 612 self.testEmailAct.setWhatsThis(
517 """ is working.</p>""" 613 self.tr(
518 )) 614 """<b>Send Test Email</b>"""
615 """<p>Sends a test email to confirm email sending through Django"""
616 """ is working.</p>"""
617 )
618 )
519 self.testEmailAct.triggered.connect(self.__sendTestEmail) 619 self.testEmailAct.triggered.connect(self.__sendTestEmail)
520 self.actions.append(self.testEmailAct) 620 self.actions.append(self.testEmailAct)
521 621
522 def __initTestingActions(self): 622 def __initTestingActions(self):
523 """ 623 """
524 Private method to define the testing actions. 624 Private method to define the testing actions.
525 """ 625 """
526 self.dumpDataAct = EricAction( 626 self.dumpDataAct = EricAction(
527 self.tr('Dump Data'), 627 self.tr("Dump Data"),
528 self.tr('&Dump Data'), 628 self.tr("&Dump Data"),
529 0, 0, 629 0,
530 self, 'django_tools_dumpdata') 630 0,
531 self.dumpDataAct.setStatusTip(self.tr( 631 self,
532 'Dump the database data to a fixture')) 632 "django_tools_dumpdata",
533 self.dumpDataAct.setWhatsThis(self.tr( 633 )
534 """<b>Dump Data</b>""" 634 self.dumpDataAct.setStatusTip(self.tr("Dump the database data to a fixture"))
535 """<p>Dump the database data to a fixture.</p>""" 635 self.dumpDataAct.setWhatsThis(
536 )) 636 self.tr(
637 """<b>Dump Data</b>""" """<p>Dump the database data to a fixture.</p>"""
638 )
639 )
537 self.dumpDataAct.triggered.connect(self.__dumpData) 640 self.dumpDataAct.triggered.connect(self.__dumpData)
538 self.actions.append(self.dumpDataAct) 641 self.actions.append(self.dumpDataAct)
539 642
540 self.loadDataAct = EricAction( 643 self.loadDataAct = EricAction(
541 self.tr('Load Data'), 644 self.tr("Load Data"),
542 self.tr('&Load Data'), 645 self.tr("&Load Data"),
543 0, 0, 646 0,
544 self, 'django_tools_loaddata') 647 0,
545 self.loadDataAct.setStatusTip(self.tr( 648 self,
546 'Load data from fixture files')) 649 "django_tools_loaddata",
547 self.loadDataAct.setWhatsThis(self.tr( 650 )
548 """<b>Load Data</b>""" 651 self.loadDataAct.setStatusTip(self.tr("Load data from fixture files"))
549 """<p>Load data from fixture files.</p>""" 652 self.loadDataAct.setWhatsThis(
550 )) 653 self.tr("""<b>Load Data</b>""" """<p>Load data from fixture files.</p>""")
654 )
551 self.loadDataAct.triggered.connect(self.__loadData) 655 self.loadDataAct.triggered.connect(self.__loadData)
552 self.actions.append(self.loadDataAct) 656 self.actions.append(self.loadDataAct)
553 657
554 self.runTestAct = EricAction( 658 self.runTestAct = EricAction(
555 self.tr('Run Testsuite'), 659 self.tr("Run Testsuite"),
556 self.tr('Run &Testsuite'), 660 self.tr("Run &Testsuite"),
557 0, 0, 661 0,
558 self, 'django_tools_run_test') 662 0,
559 self.runTestAct.setStatusTip(self.tr( 663 self,
560 'Run the test suite for applications or the whole site')) 664 "django_tools_run_test",
561 self.runTestAct.setWhatsThis(self.tr( 665 )
562 """<b>Run Testsuite</b>""" 666 self.runTestAct.setStatusTip(
563 """<p>Run the test suite for applications or the whole site.</p>""" 667 self.tr("Run the test suite for applications or the whole site")
564 )) 668 )
669 self.runTestAct.setWhatsThis(
670 self.tr(
671 """<b>Run Testsuite</b>"""
672 """<p>Run the test suite for applications or the whole site.</p>"""
673 )
674 )
565 self.runTestAct.triggered.connect(self.__runTestSuite) 675 self.runTestAct.triggered.connect(self.__runTestSuite)
566 self.actions.append(self.runTestAct) 676 self.actions.append(self.runTestAct)
567 677
568 self.runDeprecationTestAct = EricAction( 678 self.runDeprecationTestAct = EricAction(
569 self.tr('Run Testsuite (-Wall)'), 679 self.tr("Run Testsuite (-Wall)"),
570 self.tr('Run Testsuite (-Wall)'), 680 self.tr("Run Testsuite (-Wall)"),
571 0, 0, 681 0,
572 self, 'django_tools_run_deprecation_test') 682 0,
573 self.runDeprecationTestAct.setStatusTip(self.tr( 683 self,
574 'Run the test suite for applications or the whole site with' 684 "django_tools_run_deprecation_test",
575 ' activated deprecation warnings')) 685 )
576 self.runDeprecationTestAct.setWhatsThis(self.tr( 686 self.runDeprecationTestAct.setStatusTip(
577 """<b>Run Testsuite (-Wall)</b>""" 687 self.tr(
578 """<p>Run the test suite for applications or the whole site""" 688 "Run the test suite for applications or the whole site with"
579 """ with activated deprecation warnings.</p>""" 689 " activated deprecation warnings"
580 )) 690 )
691 )
692 self.runDeprecationTestAct.setWhatsThis(
693 self.tr(
694 """<b>Run Testsuite (-Wall)</b>"""
695 """<p>Run the test suite for applications or the whole site"""
696 """ with activated deprecation warnings.</p>"""
697 )
698 )
581 self.runDeprecationTestAct.triggered.connect( 699 self.runDeprecationTestAct.triggered.connect(
582 lambda: self.__runTestSuite(deprecation=True)) 700 lambda: self.__runTestSuite(deprecation=True)
701 )
583 self.actions.append(self.runDeprecationTestAct) 702 self.actions.append(self.runDeprecationTestAct)
584 703
585 self.runTestServerAct = EricAction( 704 self.runTestServerAct = EricAction(
586 self.tr('Run Testserver'), 705 self.tr("Run Testserver"),
587 self.tr('Run Test&server'), 706 self.tr("Run Test&server"),
588 0, 0, 707 0,
589 self, 'django_tools_run_test_server') 708 0,
590 self.runTestServerAct.setStatusTip(self.tr( 709 self,
591 'Run a development server with data from a set of fixtures')) 710 "django_tools_run_test_server",
592 self.runTestServerAct.setWhatsThis(self.tr( 711 )
593 """<b>Run Testserver</b>""" 712 self.runTestServerAct.setStatusTip(
594 """<p>Run a development server with data from a set of""" 713 self.tr("Run a development server with data from a set of fixtures")
595 """ fixtures.</p>""" 714 )
596 )) 715 self.runTestServerAct.setWhatsThis(
716 self.tr(
717 """<b>Run Testserver</b>"""
718 """<p>Run a development server with data from a set of"""
719 """ fixtures.</p>"""
720 )
721 )
597 self.runTestServerAct.triggered.connect(self.__runTestServer) 722 self.runTestServerAct.triggered.connect(self.__runTestServer)
598 self.actions.append(self.runTestServerAct) 723 self.actions.append(self.runTestServerAct)
599 724
600 def __initAuthorizationActions(self): 725 def __initAuthorizationActions(self):
601 """ 726 """
602 Private method to define the authorization actions. 727 Private method to define the authorization actions.
603 """ 728 """
604 self.changePasswordAct = EricAction( 729 self.changePasswordAct = EricAction(
605 self.tr('Change Password'), 730 self.tr("Change Password"),
606 self.tr('Change &Password'), 731 self.tr("Change &Password"),
607 0, 0, 732 0,
608 self, 'django_auth_changepassword') 733 0,
609 self.changePasswordAct.setStatusTip(self.tr( 734 self,
610 'Change the password of a user')) 735 "django_auth_changepassword",
611 self.changePasswordAct.setWhatsThis(self.tr( 736 )
612 """<b>Change Password</b>""" 737 self.changePasswordAct.setStatusTip(self.tr("Change the password of a user"))
613 """<p>Change the password of a user of the Django project.</p>""" 738 self.changePasswordAct.setWhatsThis(
614 )) 739 self.tr(
740 """<b>Change Password</b>"""
741 """<p>Change the password of a user of the Django project.</p>"""
742 )
743 )
615 self.changePasswordAct.triggered.connect(self.__changePassword) 744 self.changePasswordAct.triggered.connect(self.__changePassword)
616 self.actions.append(self.changePasswordAct) 745 self.actions.append(self.changePasswordAct)
617 746
618 self.createSuperUserAct = EricAction( 747 self.createSuperUserAct = EricAction(
619 self.tr('Create Superuser'), 748 self.tr("Create Superuser"),
620 self.tr('Create &Superuser'), 749 self.tr("Create &Superuser"),
621 0, 0, 750 0,
622 self, 'django_auth_createsuperuser') 751 0,
623 self.createSuperUserAct.setStatusTip(self.tr( 752 self,
624 'Create a superuser account')) 753 "django_auth_createsuperuser",
625 self.createSuperUserAct.setWhatsThis(self.tr( 754 )
626 """<b>Create Superuser</b>""" 755 self.createSuperUserAct.setStatusTip(self.tr("Create a superuser account"))
627 """<p>Create a superuser account for the Django project.</p>""" 756 self.createSuperUserAct.setWhatsThis(
628 )) 757 self.tr(
758 """<b>Create Superuser</b>"""
759 """<p>Create a superuser account for the Django project.</p>"""
760 )
761 )
629 self.createSuperUserAct.triggered.connect(self.__createSuperUser) 762 self.createSuperUserAct.triggered.connect(self.__createSuperUser)
630 self.actions.append(self.createSuperUserAct) 763 self.actions.append(self.createSuperUserAct)
631 764
632 def __initSessionActions(self): 765 def __initSessionActions(self):
633 """ 766 """
634 Private method to define the session actions. 767 Private method to define the session actions.
635 """ 768 """
636 self.clearSessionsAct = EricAction( 769 self.clearSessionsAct = EricAction(
637 self.tr('Clear Sessions'), 770 self.tr("Clear Sessions"),
638 self.tr('Clear &Sessions'), 771 self.tr("Clear &Sessions"),
639 0, 0, 772 0,
640 self, 'django_session_clearsessions') 773 0,
641 self.clearSessionsAct.setStatusTip(self.tr( 774 self,
642 'Clear expired sessions')) 775 "django_session_clearsessions",
643 self.clearSessionsAct.setWhatsThis(self.tr( 776 )
644 """<b>Clear Sessions</b>""" 777 self.clearSessionsAct.setStatusTip(self.tr("Clear expired sessions"))
645 """<p>Clear expired sessions of the Django project.</p>""" 778 self.clearSessionsAct.setWhatsThis(
646 )) 779 self.tr(
780 """<b>Clear Sessions</b>"""
781 """<p>Clear expired sessions of the Django project.</p>"""
782 )
783 )
647 self.clearSessionsAct.triggered.connect(self.__clearSessions) 784 self.clearSessionsAct.triggered.connect(self.__clearSessions)
648 self.actions.append(self.clearSessionsAct) 785 self.actions.append(self.clearSessionsAct)
649 786
650 def __initMigrationActions(self): 787 def __initMigrationActions(self):
651 """ 788 """
652 Private method to define the migration actions. 789 Private method to define the migration actions.
653 """ 790 """
654 self.showMigrationsAct = EricAction( 791 self.showMigrationsAct = EricAction(
655 self.tr('Show Migrations'), 792 self.tr("Show Migrations"),
656 self.tr('&Show Migrations'), 793 self.tr("&Show Migrations"),
657 0, 0, 794 0,
658 self, 'django_migration_show') 795 0,
659 self.showMigrationsAct.setStatusTip(self.tr( 796 self,
660 'Show a list of available migrations')) 797 "django_migration_show",
661 self.showMigrationsAct.setWhatsThis(self.tr( 798 )
662 """<b>Show Migrations</b>""" 799 self.showMigrationsAct.setStatusTip(
663 """<p>This shows a list of available migrations of the Django""" 800 self.tr("Show a list of available migrations")
664 """ project and their status.</p>""" 801 )
665 )) 802 self.showMigrationsAct.setWhatsThis(
803 self.tr(
804 """<b>Show Migrations</b>"""
805 """<p>This shows a list of available migrations of the Django"""
806 """ project and their status.</p>"""
807 )
808 )
666 self.showMigrationsAct.triggered.connect(self.__showMigrationsList) 809 self.showMigrationsAct.triggered.connect(self.__showMigrationsList)
667 self.actions.append(self.showMigrationsAct) 810 self.actions.append(self.showMigrationsAct)
668 811
669 self.showMigrationsPlanAct = EricAction( 812 self.showMigrationsPlanAct = EricAction(
670 self.tr('Show Migrations Plan'), 813 self.tr("Show Migrations Plan"),
671 self.tr('Show Migrations &Plan'), 814 self.tr("Show Migrations &Plan"),
672 0, 0, 815 0,
673 self, 'django_migration_show_plan') 816 0,
674 self.showMigrationsPlanAct.setStatusTip(self.tr( 817 self,
675 'Show a list with the migrations plan')) 818 "django_migration_show_plan",
676 self.showMigrationsPlanAct.setWhatsThis(self.tr( 819 )
677 """<b>Show Migrations Plan</b>""" 820 self.showMigrationsPlanAct.setStatusTip(
678 """<p>This shows a list with the migrations plan of the Django""" 821 self.tr("Show a list with the migrations plan")
679 """ project.</p>""" 822 )
680 )) 823 self.showMigrationsPlanAct.setWhatsThis(
824 self.tr(
825 """<b>Show Migrations Plan</b>"""
826 """<p>This shows a list with the migrations plan of the Django"""
827 """ project.</p>"""
828 )
829 )
681 self.showMigrationsPlanAct.triggered.connect(self.__showMigrationsPlan) 830 self.showMigrationsPlanAct.triggered.connect(self.__showMigrationsPlan)
682 self.actions.append(self.showMigrationsPlanAct) 831 self.actions.append(self.showMigrationsPlanAct)
683 832
684 self.migrateAllAct = EricAction( 833 self.migrateAllAct = EricAction(
685 self.tr('Apply All Migrations'), 834 self.tr("Apply All Migrations"),
686 self.tr('&Apply All Migrations'), 835 self.tr("&Apply All Migrations"),
687 0, 0, 836 0,
688 self, 'django_migration_apply_all') 837 0,
689 self.migrateAllAct.setStatusTip(self.tr( 838 self,
690 'Apply all available migrations')) 839 "django_migration_apply_all",
691 self.migrateAllAct.setWhatsThis(self.tr( 840 )
692 """<b>Apply All Migrations</b>""" 841 self.migrateAllAct.setStatusTip(self.tr("Apply all available migrations"))
693 """<p>This applies all migrations of the Django project.</p>""" 842 self.migrateAllAct.setWhatsThis(
694 )) 843 self.tr(
844 """<b>Apply All Migrations</b>"""
845 """<p>This applies all migrations of the Django project.</p>"""
846 )
847 )
695 self.migrateAllAct.triggered.connect(self.__applyAllMigrations) 848 self.migrateAllAct.triggered.connect(self.__applyAllMigrations)
696 self.actions.append(self.migrateAllAct) 849 self.actions.append(self.migrateAllAct)
697 850
698 self.migrateSelectedAct = EricAction( 851 self.migrateSelectedAct = EricAction(
699 self.tr('Apply Selected Migrations'), 852 self.tr("Apply Selected Migrations"),
700 self.tr('Apply Selected Migrations'), 853 self.tr("Apply Selected Migrations"),
701 0, 0, 854 0,
702 self, 'django_migration_apply_selected') 855 0,
703 self.migrateSelectedAct.setStatusTip(self.tr( 856 self,
704 'Apply selected migrations')) 857 "django_migration_apply_selected",
705 self.migrateSelectedAct.setWhatsThis(self.tr( 858 )
706 """<b>Apply Selected Migrations</b>""" 859 self.migrateSelectedAct.setStatusTip(self.tr("Apply selected migrations"))
707 """<p>This applies selected migrations of the Django""" 860 self.migrateSelectedAct.setWhatsThis(
708 """ project.</p>""" 861 self.tr(
709 )) 862 """<b>Apply Selected Migrations</b>"""
710 self.migrateSelectedAct.triggered.connect( 863 """<p>This applies selected migrations of the Django"""
711 self.__applySelectedMigrations) 864 """ project.</p>"""
865 )
866 )
867 self.migrateSelectedAct.triggered.connect(self.__applySelectedMigrations)
712 self.actions.append(self.migrateSelectedAct) 868 self.actions.append(self.migrateSelectedAct)
713 869
714 self.unmigrateAct = EricAction( 870 self.unmigrateAct = EricAction(
715 self.tr('Unapply Migrations'), 871 self.tr("Unapply Migrations"),
716 self.tr('&Unapply Migrations'), 872 self.tr("&Unapply Migrations"),
717 0, 0, 873 0,
718 self, 'django_migration_unapply') 874 0,
719 self.unmigrateAct.setStatusTip(self.tr( 875 self,
720 'Unapply all migrations for an app')) 876 "django_migration_unapply",
721 self.unmigrateAct.setWhatsThis(self.tr( 877 )
722 """<b>Unapply Migrations</b>""" 878 self.unmigrateAct.setStatusTip(self.tr("Unapply all migrations for an app"))
723 """<p>This unapplies all migrations for an app of the Django""" 879 self.unmigrateAct.setWhatsThis(
724 """ project.</p>""" 880 self.tr(
725 )) 881 """<b>Unapply Migrations</b>"""
882 """<p>This unapplies all migrations for an app of the Django"""
883 """ project.</p>"""
884 )
885 )
726 self.unmigrateAct.triggered.connect(self.__unapplyMigrations) 886 self.unmigrateAct.triggered.connect(self.__unapplyMigrations)
727 self.actions.append(self.unmigrateAct) 887 self.actions.append(self.unmigrateAct)
728 888
729 self.makeMigrationsAct = EricAction( 889 self.makeMigrationsAct = EricAction(
730 self.tr('Make Migrations'), 890 self.tr("Make Migrations"),
731 self.tr('&Make Migrations'), 891 self.tr("&Make Migrations"),
732 0, 0, 892 0,
733 self, 'django_migration_make') 893 0,
734 self.makeMigrationsAct.setStatusTip(self.tr( 894 self,
735 'Generate migrations for the project')) 895 "django_migration_make",
736 self.makeMigrationsAct.setWhatsThis(self.tr( 896 )
737 """<b>Make Migrations</b>""" 897 self.makeMigrationsAct.setStatusTip(
738 """<p>This generates migrations for the Django project.</p>""" 898 self.tr("Generate migrations for the project")
739 )) 899 )
900 self.makeMigrationsAct.setWhatsThis(
901 self.tr(
902 """<b>Make Migrations</b>"""
903 """<p>This generates migrations for the Django project.</p>"""
904 )
905 )
740 self.makeMigrationsAct.triggered.connect(self.__makeMigrations) 906 self.makeMigrationsAct.triggered.connect(self.__makeMigrations)
741 self.actions.append(self.makeMigrationsAct) 907 self.actions.append(self.makeMigrationsAct)
742 908
743 self.squashMigrationsAct = EricAction( 909 self.squashMigrationsAct = EricAction(
744 self.tr('Squash Migrations'), 910 self.tr("Squash Migrations"),
745 self.tr('S&quash Migrations'), 911 self.tr("S&quash Migrations"),
746 0, 0, 912 0,
747 self, 'django_migration_squash') 913 0,
748 self.squashMigrationsAct.setStatusTip(self.tr( 914 self,
749 'Squash migrations of an application of the project')) 915 "django_migration_squash",
750 self.squashMigrationsAct.setWhatsThis(self.tr( 916 )
751 """<b>Squash Migrations</b>""" 917 self.squashMigrationsAct.setStatusTip(
752 """<p>This squashes migrations of an application of the""" 918 self.tr("Squash migrations of an application of the project")
753 """ Django project.</p>""" 919 )
754 )) 920 self.squashMigrationsAct.setWhatsThis(
921 self.tr(
922 """<b>Squash Migrations</b>"""
923 """<p>This squashes migrations of an application of the"""
924 """ Django project.</p>"""
925 )
926 )
755 self.squashMigrationsAct.triggered.connect(self.__squashMigrations) 927 self.squashMigrationsAct.triggered.connect(self.__squashMigrations)
756 self.actions.append(self.squashMigrationsAct) 928 self.actions.append(self.squashMigrationsAct)
757 929
758 def initMenu(self): 930 def initMenu(self):
759 """ 931 """
760 Public method to initialize the Django menu. 932 Public method to initialize the Django menu.
761 933
762 @return the menu generated 934 @return the menu generated
763 @rtype QMenu 935 @rtype QMenu
764 """ 936 """
765 self.__menus = {} # clear menus references 937 self.__menus = {} # clear menus references
766 938
767 menu = QMenu(self.tr('D&jango'), self.__ui) 939 menu = QMenu(self.tr("D&jango"), self.__ui)
768 menu.setTearOffEnabled(True) 940 menu.setTearOffEnabled(True)
769 941
770 menu.addAction(self.selectSiteAct) 942 menu.addAction(self.selectSiteAct)
771 menu.addSeparator() 943 menu.addSeparator()
772 menu.addAction(self.runServerAct) 944 menu.addAction(self.runServerAct)
773 menu.addAction(self.runBrowserAct) 945 menu.addAction(self.runBrowserAct)
774 menu.addSeparator() 946 menu.addSeparator()
792 menu.addMenu(self.__initSessionMenu()) 964 menu.addMenu(self.__initSessionMenu())
793 menu.addSeparator() 965 menu.addSeparator()
794 menu.addAction(self.aboutDjangoAct) 966 menu.addAction(self.aboutDjangoAct)
795 menu.addSeparator() 967 menu.addSeparator()
796 menu.addAction(self.helpAct) 968 menu.addAction(self.helpAct)
797 969
798 self.__menus["main"] = menu 970 self.__menus["main"] = menu
799 971
800 return menu 972 return menu
801 973
802 def __initDatabaseMenu(self): 974 def __initDatabaseMenu(self):
803 """ 975 """
804 Private method to initialize the database menu. 976 Private method to initialize the database menu.
805 977
806 @return the menu generated 978 @return the menu generated
807 @rtype QMenu 979 @rtype QMenu
808 """ 980 """
809 menu = QMenu(self.tr("&Database"), self.__ui) 981 menu = QMenu(self.tr("&Database"), self.__ui)
810 menu.setTearOffEnabled(True) 982 menu.setTearOffEnabled(True)
811 983
812 menu.addAction(self.selectDatabaseNameAct) 984 menu.addAction(self.selectDatabaseNameAct)
813 menu.addSeparator() 985 menu.addSeparator()
814 menu.addAction(self.inspectDatabaseAct) 986 menu.addAction(self.inspectDatabaseAct)
815 menu.addSeparator() 987 menu.addSeparator()
816 menu.addAction(self.flushDatabaseAct) 988 menu.addAction(self.flushDatabaseAct)
817 menu.addSeparator() 989 menu.addSeparator()
818 menu.addAction(self.databaseClientAct) 990 menu.addAction(self.databaseClientAct)
819 menu.addSeparator() 991 menu.addSeparator()
820 menu.addMenu(self.__initDatabaseSqlMenu()) 992 menu.addMenu(self.__initDatabaseSqlMenu())
821 993
822 self.__menus["database"] = menu 994 self.__menus["database"] = menu
823 995
824 return menu 996 return menu
825 997
826 def __initDatabaseSqlMenu(self): 998 def __initDatabaseSqlMenu(self):
827 """ 999 """
828 Private method to initialize the database SQL submenu. 1000 Private method to initialize the database SQL submenu.
829 1001
830 @return the menu generated 1002 @return the menu generated
831 @rtype QMenu 1003 @rtype QMenu
832 """ 1004 """
833 menu = QMenu(self.tr("Show &SQL"), self.__ui) 1005 menu = QMenu(self.tr("Show &SQL"), self.__ui)
834 menu.setTearOffEnabled(True) 1006 menu.setTearOffEnabled(True)
835 1007
836 menu.addAction(self.databaseSqlFlushAct) 1008 menu.addAction(self.databaseSqlFlushAct)
837 menu.addAction(self.databaseSqlResetSeqAct) 1009 menu.addAction(self.databaseSqlResetSeqAct)
838 menu.addSeparator() 1010 menu.addSeparator()
839 menu.addAction(self.databaseSqlMigrateAct) 1011 menu.addAction(self.databaseSqlMigrateAct)
840 menu.addAction(self.databaseSqlMigrateBackwardsAct) 1012 menu.addAction(self.databaseSqlMigrateBackwardsAct)
841 1013
842 self.__menus["sql"] = menu 1014 self.__menus["sql"] = menu
843 1015
844 return menu 1016 return menu
845 1017
846 def __initMigrationsMenu(self): 1018 def __initMigrationsMenu(self):
847 """ 1019 """
848 Private method to initialize the Migrations submenu. 1020 Private method to initialize the Migrations submenu.
849 1021
850 @return the menu generated 1022 @return the menu generated
851 @rtype QMenu 1023 @rtype QMenu
852 """ 1024 """
853 menu = QMenu(self.tr("&Migrations"), self.__ui) 1025 menu = QMenu(self.tr("&Migrations"), self.__ui)
854 menu.setTearOffEnabled(True) 1026 menu.setTearOffEnabled(True)
855 1027
856 menu.addAction(self.showMigrationsAct) 1028 menu.addAction(self.showMigrationsAct)
857 menu.addAction(self.showMigrationsPlanAct) 1029 menu.addAction(self.showMigrationsPlanAct)
858 menu.addSeparator() 1030 menu.addSeparator()
859 menu.addAction(self.migrateAllAct) 1031 menu.addAction(self.migrateAllAct)
860 menu.addAction(self.migrateSelectedAct) 1032 menu.addAction(self.migrateSelectedAct)
861 menu.addAction(self.unmigrateAct) 1033 menu.addAction(self.unmigrateAct)
862 menu.addSeparator() 1034 menu.addSeparator()
863 menu.addAction(self.makeMigrationsAct) 1035 menu.addAction(self.makeMigrationsAct)
864 menu.addSeparator() 1036 menu.addSeparator()
865 menu.addAction(self.squashMigrationsAct) 1037 menu.addAction(self.squashMigrationsAct)
866 1038
867 self.__menus["migrations"] = menu 1039 self.__menus["migrations"] = menu
868 1040
869 return menu 1041 return menu
870 1042
871 def __initToolsMenu(self): 1043 def __initToolsMenu(self):
872 """ 1044 """
873 Private method to initialize the tools menu. 1045 Private method to initialize the tools menu.
874 1046
875 @return the menu generated 1047 @return the menu generated
876 @rtype QMenu 1048 @rtype QMenu
877 """ 1049 """
878 menu = QMenu(self.tr("&Tools"), self.__ui) 1050 menu = QMenu(self.tr("&Tools"), self.__ui)
879 menu.setTearOffEnabled(True) 1051 menu.setTearOffEnabled(True)
880 1052
881 menu.addAction(self.diffSettingsAct) 1053 menu.addAction(self.diffSettingsAct)
882 menu.addSeparator() 1054 menu.addSeparator()
883 menu.addAction(self.runPythonShellAct) 1055 menu.addAction(self.runPythonShellAct)
884 menu.addSeparator() 1056 menu.addSeparator()
885 menu.addAction(self.testEmailAct) 1057 menu.addAction(self.testEmailAct)
886 1058
887 self.__menus["tools"] = menu 1059 self.__menus["tools"] = menu
888 1060
889 return menu 1061 return menu
890 1062
891 def __initTestingMenu(self): 1063 def __initTestingMenu(self):
892 """ 1064 """
893 Private method to initialize the testing menu. 1065 Private method to initialize the testing menu.
894 1066
895 @return the menu generated 1067 @return the menu generated
896 @rtype QMenu 1068 @rtype QMenu
897 """ 1069 """
898 menu = QMenu(self.tr("T&esting"), self.__ui) 1070 menu = QMenu(self.tr("T&esting"), self.__ui)
899 menu.setTearOffEnabled(True) 1071 menu.setTearOffEnabled(True)
900 1072
901 menu.addAction(self.dumpDataAct) 1073 menu.addAction(self.dumpDataAct)
902 menu.addAction(self.loadDataAct) 1074 menu.addAction(self.loadDataAct)
903 menu.addSeparator() 1075 menu.addSeparator()
904 menu.addAction(self.runTestAct) 1076 menu.addAction(self.runTestAct)
905 menu.addAction(self.runDeprecationTestAct) 1077 menu.addAction(self.runDeprecationTestAct)
906 menu.addAction(self.runTestServerAct) 1078 menu.addAction(self.runTestServerAct)
907 1079
908 self.__menus["testing"] = menu 1080 self.__menus["testing"] = menu
909 1081
910 return menu 1082 return menu
911 1083
912 def __initAuthorizationMenu(self): 1084 def __initAuthorizationMenu(self):
913 """ 1085 """
914 Private method to initialize the authorization menu. 1086 Private method to initialize the authorization menu.
915 1087
916 @return the menu generated 1088 @return the menu generated
917 @rtype QMenu 1089 @rtype QMenu
918 """ 1090 """
919 menu = QMenu(self.tr("&Authorization"), self.__ui) 1091 menu = QMenu(self.tr("&Authorization"), self.__ui)
920 menu.setTearOffEnabled(True) 1092 menu.setTearOffEnabled(True)
921 1093
922 menu.addAction(self.changePasswordAct) 1094 menu.addAction(self.changePasswordAct)
923 menu.addAction(self.createSuperUserAct) 1095 menu.addAction(self.createSuperUserAct)
924 1096
925 self.__menus["authorization"] = menu 1097 self.__menus["authorization"] = menu
926 1098
927 return menu 1099 return menu
928 1100
929 def __initSessionMenu(self): 1101 def __initSessionMenu(self):
930 """ 1102 """
931 Private method to initialize the authorization menu. 1103 Private method to initialize the authorization menu.
932 1104
933 @return the menu generated 1105 @return the menu generated
934 @rtype QMenu 1106 @rtype QMenu
935 """ 1107 """
936 menu = QMenu(self.tr("&Session"), self.__ui) 1108 menu = QMenu(self.tr("&Session"), self.__ui)
937 menu.setTearOffEnabled(True) 1109 menu.setTearOffEnabled(True)
938 1110
939 menu.addAction(self.clearSessionsAct) 1111 menu.addAction(self.clearSessionsAct)
940 1112
941 self.__menus["session"] = menu 1113 self.__menus["session"] = menu
942 1114
943 return menu 1115 return menu
944 1116
945 def getMenu(self, name): 1117 def getMenu(self, name):
946 """ 1118 """
947 Public method to get a reference to the requested menu. 1119 Public method to get a reference to the requested menu.
948 1120
949 @param name name of the menu 1121 @param name name of the menu
950 @type str 1122 @type str
951 @return reference to the menu or None, if no menu with the given 1123 @return reference to the menu or None, if no menu with the given
952 name exists 1124 name exists
953 @rtype QMenu 1125 @rtype QMenu
954 """ 1126 """
955 if name in self.__menus: 1127 if name in self.__menus:
956 return self.__menus[name] 1128 return self.__menus[name]
957 else: 1129 else:
958 return None 1130 return None
959 1131
960 def getMenuNames(self): 1132 def getMenuNames(self):
961 """ 1133 """
962 Public method to get the names of all menus. 1134 Public method to get the names of all menus.
963 1135
964 @return menu names 1136 @return menu names
965 @rtype list of str 1137 @rtype list of str
966 """ 1138 """
967 return list(self.__menus.keys()) 1139 return list(self.__menus.keys())
968 1140
969 ################################################################## 1141 ##################################################################
970 ## methods below implement the various hook related functions 1142 ## methods below implement the various hook related functions
971 ################################################################## 1143 ##################################################################
972 1144
973 def registerOpenHook(self): 1145 def registerOpenHook(self):
974 """ 1146 """
975 Public method to register the open hook to open a translations file 1147 Public method to register the open hook to open a translations file
976 in a translations editor. 1148 in a translations editor.
977 """ 1149 """
979 editor = self.__plugin.getPreferences("TranslationsEditor") 1151 editor = self.__plugin.getPreferences("TranslationsEditor")
980 if editor: 1152 if editor:
981 self.__translationsBrowser.addHookMethodAndMenuEntry( 1153 self.__translationsBrowser.addHookMethodAndMenuEntry(
982 "open", 1154 "open",
983 self.openPOEditor, 1155 self.openPOEditor,
984 self.tr("Open with {0}").format( 1156 self.tr("Open with {0}").format(os.path.basename(editor)),
985 os.path.basename(editor))) 1157 )
986 else: 1158 else:
987 self.__translationsBrowser.removeHookMethod("open") 1159 self.__translationsBrowser.removeHookMethod("open")
988 1160
989 def projectOpenedHooks(self): 1161 def projectOpenedHooks(self):
990 """ 1162 """
991 Public method to add our hook methods. 1163 Public method to add our hook methods.
992 """ 1164 """
993 if self.__ericProject.getProjectType() == "Django": 1165 if self.__ericProject.getProjectType() == "Django":
994 self.__formsBrowser = ( 1166 self.__formsBrowser = (
995 ericApp().getObject("ProjectBrowser") 1167 ericApp().getObject("ProjectBrowser").getProjectBrowser("forms")
996 .getProjectBrowser("forms")
997 ) 1168 )
998 self.__formsBrowser.addHookMethodAndMenuEntry( 1169 self.__formsBrowser.addHookMethodAndMenuEntry(
999 "newForm", 1170 "newForm", self.newForm, self.tr("New template...")
1000 self.newForm, self.tr("New template...")) 1171 )
1001 1172
1002 self.__ericProject.projectLanguageAddedByCode.connect( 1173 self.__ericProject.projectLanguageAddedByCode.connect(
1003 self.__projectLanguageAdded) 1174 self.__projectLanguageAdded
1175 )
1004 self.__translationsBrowser = ( 1176 self.__translationsBrowser = (
1005 ericApp().getObject("ProjectBrowser") 1177 ericApp().getObject("ProjectBrowser").getProjectBrowser("translations")
1006 .getProjectBrowser("translations")) 1178 )
1007 self.__translationsBrowser.addHookMethodAndMenuEntry( 1179 self.__translationsBrowser.addHookMethodAndMenuEntry(
1008 "generateAll", 1180 "generateAll", self.updateCatalogs, self.tr("Update all catalogs")
1009 self.updateCatalogs, self.tr("Update all catalogs")) 1181 )
1010 self.__translationsBrowser.addHookMethodAndMenuEntry( 1182 self.__translationsBrowser.addHookMethodAndMenuEntry(
1011 "generateSelected", 1183 "generateSelected",
1012 self.updateSelectedCatalogs, 1184 self.updateSelectedCatalogs,
1013 self.tr("Update selected catalogs")) 1185 self.tr("Update selected catalogs"),
1186 )
1014 self.__translationsBrowser.addHookMethodAndMenuEntry( 1187 self.__translationsBrowser.addHookMethodAndMenuEntry(
1015 "generateAllWithObsolete", self.updateCatalogsWithObsolete, 1188 "generateAllWithObsolete",
1016 self.tr("Update all catalogs (with obsolete)")) 1189 self.updateCatalogsWithObsolete,
1190 self.tr("Update all catalogs (with obsolete)"),
1191 )
1017 self.__translationsBrowser.addHookMethodAndMenuEntry( 1192 self.__translationsBrowser.addHookMethodAndMenuEntry(
1018 "generateSelectedWithObsolete", 1193 "generateSelectedWithObsolete",
1019 self.updateSelectedCatalogsWithObsolete, 1194 self.updateSelectedCatalogsWithObsolete,
1020 self.tr("Update selected catalogs (with obsolete)")) 1195 self.tr("Update selected catalogs (with obsolete)"),
1196 )
1021 self.__translationsBrowser.addHookMethodAndMenuEntry( 1197 self.__translationsBrowser.addHookMethodAndMenuEntry(
1022 "releaseAll", 1198 "releaseAll", self.compileCatalogs, self.tr("Compile all catalogs")
1023 self.compileCatalogs, self.tr("Compile all catalogs")) 1199 )
1024 self.__translationsBrowser.addHookMethodAndMenuEntry( 1200 self.__translationsBrowser.addHookMethodAndMenuEntry(
1025 "releaseSelected", 1201 "releaseSelected",
1026 self.compileSelectedCatalogs, 1202 self.compileSelectedCatalogs,
1027 self.tr("Compile selected catalogs")) 1203 self.tr("Compile selected catalogs"),
1028 1204 )
1205
1029 self.__hooksInstalled = True 1206 self.__hooksInstalled = True
1030 1207
1031 self.registerOpenHook() 1208 self.registerOpenHook()
1032 1209
1033 def projectClosedHooks(self): 1210 def projectClosedHooks(self):
1034 """ 1211 """
1035 Public method to remove our hook methods. 1212 Public method to remove our hook methods.
1036 """ 1213 """
1037 if self.__hooksInstalled: 1214 if self.__hooksInstalled:
1038 self.__formsBrowser.removeHookMethod("newForm") 1215 self.__formsBrowser.removeHookMethod("newForm")
1039 self.__formsBrowser = None 1216 self.__formsBrowser = None
1040 1217
1041 self.__ericProject.projectLanguageAddedByCode.disconnect( 1218 self.__ericProject.projectLanguageAddedByCode.disconnect(
1042 self.__projectLanguageAdded) 1219 self.__projectLanguageAdded
1043 self.__translationsBrowser.removeHookMethod( 1220 )
1044 "generateAll") 1221 self.__translationsBrowser.removeHookMethod("generateAll")
1045 self.__translationsBrowser.removeHookMethod( 1222 self.__translationsBrowser.removeHookMethod("generateSelected")
1046 "generateSelected") 1223 self.__translationsBrowser.removeHookMethod("generateAllWithObsolete")
1047 self.__translationsBrowser.removeHookMethod( 1224 self.__translationsBrowser.removeHookMethod("generateSelectedWithObsolete")
1048 "generateAllWithObsolete") 1225 self.__translationsBrowser.removeHookMethod("releaseAll")
1049 self.__translationsBrowser.removeHookMethod( 1226 self.__translationsBrowser.removeHookMethod("releaseSelected")
1050 "generateSelectedWithObsolete")
1051 self.__translationsBrowser.removeHookMethod(
1052 "releaseAll")
1053 self.__translationsBrowser.removeHookMethod(
1054 "releaseSelected")
1055 self.__translationsBrowser.removeHookMethod("open") 1227 self.__translationsBrowser.removeHookMethod("open")
1056 self.__translationsBrowser = None 1228 self.__translationsBrowser = None
1057 1229
1058 self.__hooksInstalled = False 1230 self.__hooksInstalled = False
1059 1231
1060 def newForm(self, path): 1232 def newForm(self, path):
1061 """ 1233 """
1062 Public method to create a new form. 1234 Public method to create a new form.
1063 1235
1064 @param path full directory path for the new form file 1236 @param path full directory path for the new form file
1065 @type str 1237 @type str
1066 """ 1238 """
1067 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 1239 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
1068 self.__ui, 1240 self.__ui,
1069 self.tr("New Form"), 1241 self.tr("New Form"),
1070 path, 1242 path,
1071 filter, 1243 filter,
1072 None, 1244 None,
1073 EricFileDialog.DontConfirmOverwrite) 1245 EricFileDialog.DontConfirmOverwrite,
1074 1246 )
1247
1075 if not fname: 1248 if not fname:
1076 # user aborted or didn't enter a filename 1249 # user aborted or didn't enter a filename
1077 return 1250 return
1078 1251
1079 ext = QFileInfo(fname).suffix() 1252 ext = QFileInfo(fname).suffix()
1080 if not ext: 1253 if not ext:
1081 ex = selectedFilter.split("(*")[1].split(")")[0] 1254 ex = selectedFilter.split("(*")[1].split(")")[0]
1082 if ex: 1255 if ex:
1083 fname += ex 1256 fname += ex
1084 1257
1085 if os.path.exists(fname): 1258 if os.path.exists(fname):
1086 res = EricMessageBox.yesNo( 1259 res = EricMessageBox.yesNo(
1087 self.__ui, 1260 self.__ui,
1088 self.tr("New Form"), 1261 self.tr("New Form"),
1089 self.tr("The file already exists! Overwrite it?"), 1262 self.tr("The file already exists! Overwrite it?"),
1090 icon=EricMessageBox.Warning) 1263 icon=EricMessageBox.Warning,
1091 1264 )
1265
1092 if not res: 1266 if not res:
1093 # user selected to not overwrite 1267 # user selected to not overwrite
1094 return 1268 return
1095 1269
1096 try: 1270 try:
1097 with open(fname, "w") as f: 1271 with open(fname, "w") as f:
1098 f.write('<!DOCTYPE html>') 1272 f.write("<!DOCTYPE html>")
1099 f.write('<html>\n') 1273 f.write("<html>\n")
1100 f.write(' <head>\n') 1274 f.write(" <head>\n")
1101 f.write(' <meta content="" />\n') 1275 f.write(' <meta content="" />\n')
1102 f.write(' <title></title>\n') 1276 f.write(" <title></title>\n")
1103 f.write(' <link rel="stylesheet" type="text/css"' 1277 f.write(
1104 ' href="style.css"/>') 1278 ' <link rel="stylesheet" type="text/css"' ' href="style.css"/>'
1105 f.write(' <!--[if lte IE 7]>') 1279 )
1106 f.write(' <link rel="stylesheet" type="text/css"' 1280 f.write(" <!--[if lte IE 7]>")
1107 ' href="ie.css"/>') 1281 f.write(
1108 f.write(' <![endif]-->') 1282 ' <link rel="stylesheet" type="text/css"' ' href="ie.css"/>'
1109 f.write(' </head>\n') 1283 )
1110 f.write('\n') 1284 f.write(" <![endif]-->")
1285 f.write(" </head>\n")
1286 f.write("\n")
1111 f.write(' <body class="bodyclass">\n') 1287 f.write(' <body class="bodyclass">\n')
1112 f.write(' <div id="container">') 1288 f.write(' <div id="container">')
1113 f.write(' </div>') 1289 f.write(" </div>")
1114 f.write(' </body>\n') 1290 f.write(" </body>\n")
1115 f.close() 1291 f.close()
1116 f.write('</html>\n') 1292 f.write("</html>\n")
1117 except OSError as e: 1293 except OSError as e:
1118 EricMessageBox.critical( 1294 EricMessageBox.critical(
1119 self.__ui, 1295 self.__ui,
1120 self.tr("New Form"), 1296 self.tr("New Form"),
1121 self.tr("<p>The new form file <b>{0}</b> could not be" 1297 self.tr(
1122 " created.<br> Problem: {1}</p>") 1298 "<p>The new form file <b>{0}</b> could not be"
1123 .format(fname, str(e))) 1299 " created.<br> Problem: {1}</p>"
1300 ).format(fname, str(e)),
1301 )
1124 return 1302 return
1125 1303
1126 self.__ericProject.appendFile(fname) 1304 self.__ericProject.appendFile(fname)
1127 self.__formsBrowser.sourceFile.emit(fname) 1305 self.__formsBrowser.sourceFile.emit(fname)
1128 1306
1129 ################################################################## 1307 ##################################################################
1130 ## slots below implement general functionality 1308 ## slots below implement general functionality
1131 ################################################################## 1309 ##################################################################
1132 1310
1133 def projectClosed(self): 1311 def projectClosed(self):
1134 """ 1312 """
1135 Public method to handle the closing of a project. 1313 Public method to handle the closing of a project.
1136 """ 1314 """
1137 if self.__serverProc is not None: 1315 if self.__serverProc is not None:
1138 self.__serverProcFinished() 1316 self.__serverProcFinished()
1139 self.__setCurrentSite(None) 1317 self.__setCurrentSite(None)
1140 1318
1141 def __getExecutablePaths(self, file): 1319 def __getExecutablePaths(self, file):
1142 """ 1320 """
1143 Private method to build all full paths of an executable file from 1321 Private method to build all full paths of an executable file from
1144 the environment. 1322 the environment.
1145 1323
1146 @param file filename of the executable 1324 @param file filename of the executable
1147 @type str 1325 @type str
1148 @return list of full executable names, if the executable file is 1326 @return list of full executable names, if the executable file is
1149 accessible via the searchpath defined by the PATH environment 1327 accessible via the searchpath defined by the PATH environment
1150 variable, or an empty list otherwise. 1328 variable, or an empty list otherwise.
1151 @rtype list of str 1329 @rtype list of str
1152 """ 1330 """
1153 paths = [] 1331 paths = []
1154 1332
1155 if os.path.isabs(file): 1333 if os.path.isabs(file):
1156 if os.access(file, os.X_OK): 1334 if os.access(file, os.X_OK):
1157 return [file] 1335 return [file]
1158 else: 1336 else:
1159 return [] 1337 return []
1160 1338
1161 cur_path = os.path.join(os.curdir, file) 1339 cur_path = os.path.join(os.curdir, file)
1162 if os.path.exists(cur_path) and os.access(cur_path, os.X_OK): 1340 if os.path.exists(cur_path) and os.access(cur_path, os.X_OK):
1163 paths.append(cur_path) 1341 paths.append(cur_path)
1164 1342
1165 path = os.getenv('PATH') 1343 path = os.getenv("PATH")
1166 1344
1167 # environment variable not defined 1345 # environment variable not defined
1168 if path is not None: 1346 if path is not None:
1169 dirs = path.split(os.pathsep) 1347 dirs = path.split(os.pathsep)
1170 for directory in dirs: 1348 for directory in dirs:
1171 exe = os.path.join(directory, file) 1349 exe = os.path.join(directory, file)
1172 if os.access(exe, os.X_OK) and exe not in paths: 1350 if os.access(exe, os.X_OK) and exe not in paths:
1173 paths.append(exe) 1351 paths.append(exe)
1174 1352
1175 return paths 1353 return paths
1176 1354
1177 def supportedPythonVariants(self): 1355 def supportedPythonVariants(self):
1178 """ 1356 """
1179 Public method to get the supported Python variants. 1357 Public method to get the supported Python variants.
1180 1358
1181 @return list of supported Python variants 1359 @return list of supported Python variants
1182 @rtype list of str 1360 @rtype list of str
1183 """ 1361 """
1184 variants = [] 1362 variants = []
1185 for variant in ['Python3']: 1363 for variant in ["Python3"]:
1186 virtEnv = self.__getVirtualEnvironment(variant) 1364 virtEnv = self.__getVirtualEnvironment(variant)
1187 if virtEnv: 1365 if virtEnv:
1188 if self.__getDjangoAdminCommand(variant): 1366 if self.__getDjangoAdminCommand(variant):
1189 variants.append(variant) 1367 variants.append(variant)
1190 else: 1368 else:
1198 fullCmds = Utilities.getExecutablePaths(cmd) 1376 fullCmds = Utilities.getExecutablePaths(cmd)
1199 except AttributeError: 1377 except AttributeError:
1200 fullCmds = self.__getExecutablePaths(cmd) 1378 fullCmds = self.__getExecutablePaths(cmd)
1201 for fullCmd in fullCmds: 1379 for fullCmd in fullCmds:
1202 try: 1380 try:
1203 with open(fullCmd, 'r', encoding='utf-8') as f: 1381 with open(fullCmd, "r", encoding="utf-8") as f:
1204 l0 = f.readline() 1382 l0 = f.readline()
1205 except OSError: 1383 except OSError:
1206 l0 = "" 1384 l0 = ""
1207 if self.__isSuitableForVariant(variant, l0): 1385 if self.__isSuitableForVariant(variant, l0):
1208 variants.append(variant) 1386 variants.append(variant)
1209 break 1387 break
1210 1388
1211 return variants 1389 return variants
1212 1390
1213 def __isSuitableForVariant(self, variant, line0): 1391 def __isSuitableForVariant(self, variant, line0):
1214 """ 1392 """
1215 Private method to test, if a detected command file is suitable for the 1393 Private method to test, if a detected command file is suitable for the
1216 given Python variant. 1394 given Python variant.
1217 1395
1218 @param variant Python variant to test for 1396 @param variant Python variant to test for
1219 @type str 1397 @type str
1220 @param line0 first line of the executable 1398 @param line0 first line of the executable
1221 @type str 1399 @type str
1222 @return flag indicating a suitable file was found 1400 @return flag indicating a suitable file was found
1223 @rtype bool 1401 @rtype bool
1224 """ 1402 """
1225 l0 = line0.lower() 1403 l0 = line0.lower()
1226 ok = (variant.lower() in l0 or 1404 ok = variant.lower() in l0 or "{0}.".format(variant[-1]) in l0
1227 "{0}.".format(variant[-1]) in l0)
1228 ok |= "pypy3" in l0 1405 ok |= "pypy3" in l0
1229 1406
1230 return ok 1407 return ok
1231 1408
1232 def __getVirtualEnvironment(self, language=""): 1409 def __getVirtualEnvironment(self, language=""):
1233 """ 1410 """
1234 Private method to get the path of the virtual environment. 1411 Private method to get the path of the virtual environment.
1235 1412
1236 @param language Python variant to get the virtual environment 1413 @param language Python variant to get the virtual environment
1237 for (one of '' or 'Python3') 1414 for (one of '' or 'Python3')
1238 @type str 1415 @type str
1239 @return path of the virtual environment 1416 @return path of the virtual environment
1240 @rtype str 1417 @rtype str
1241 """ 1418 """
1242 if not language: 1419 if not language:
1243 language = self.__ericProject.getProjectLanguage() 1420 language = self.__ericProject.getProjectLanguage()
1244 venvName = ( 1421 venvName = (
1245 self.__plugin.getPreferences("VirtualEnvironmentNamePy3") 1422 self.__plugin.getPreferences("VirtualEnvironmentNamePy3")
1246 if language == "Python3" else 1423 if language == "Python3"
1247 "" 1424 else ""
1248 ) 1425 )
1249 if venvName: 1426 if venvName:
1250 virtEnv = self.__virtualEnvManager.getVirtualenvDirectory( 1427 virtEnv = self.__virtualEnvManager.getVirtualenvDirectory(venvName)
1251 venvName)
1252 if not virtEnv: 1428 if not virtEnv:
1253 virtEnv = os.path.dirname( 1429 virtEnv = os.path.dirname(
1254 self.__virtualEnvManager.getVirtualenvInterpreter( 1430 self.__virtualEnvManager.getVirtualenvInterpreter(venvName)
1255 venvName)) 1431 )
1256 if virtEnv.endswith(("Scripts", "bin")): 1432 if virtEnv.endswith(("Scripts", "bin")):
1257 virtEnv = os.path.dirname(virtEnv) 1433 virtEnv = os.path.dirname(virtEnv)
1258 else: 1434 else:
1259 virtEnv = "" 1435 virtEnv = ""
1260 if virtEnv and not os.path.exists(virtEnv): 1436 if virtEnv and not os.path.exists(virtEnv):
1262 return virtEnv 1438 return virtEnv
1263 1439
1264 def __getDebugEnvironment(self, language=""): 1440 def __getDebugEnvironment(self, language=""):
1265 """ 1441 """
1266 Private method to get the path of the debugger environment. 1442 Private method to get the path of the debugger environment.
1267 1443
1268 @param language Python variant to get the debugger environment 1444 @param language Python variant to get the debugger environment
1269 for (one of '' or 'Python3') 1445 for (one of '' or 'Python3')
1270 @type str 1446 @type str
1271 @return path of the debugger environment 1447 @return path of the debugger environment
1272 @rtype str 1448 @rtype str
1277 if not debugEnv: 1453 if not debugEnv:
1278 if language == "Python3": 1454 if language == "Python3":
1279 venvName = Preferences.getDebugger("Python3VirtualEnv") 1455 venvName = Preferences.getDebugger("Python3VirtualEnv")
1280 else: 1456 else:
1281 venvName = "" 1457 venvName = ""
1282 1458
1283 if venvName: 1459 if venvName:
1284 debugEnv = self.__virtualEnvManager.getVirtualenvDirectory( 1460 debugEnv = self.__virtualEnvManager.getVirtualenvDirectory(venvName)
1285 venvName)
1286 else: 1461 else:
1287 debugEnv = "" 1462 debugEnv = ""
1288 return debugEnv 1463 return debugEnv
1289 1464
1290 def __getDjangoAdminCommand(self, language=""): 1465 def __getDjangoAdminCommand(self, language=""):
1291 """ 1466 """
1292 Private method to build a django-admin.py command. 1467 Private method to build a django-admin.py command.
1293 1468
1294 @param language Python variant to get the django-admin.py 1469 @param language Python variant to get the django-admin.py
1295 command for (one of '' or 'Python3') 1470 command for (one of '' or 'Python3')
1296 @type str 1471 @type str
1297 @return full django-admin.py command 1472 @return full django-admin.py command
1298 @rtype str 1473 @rtype str
1299 """ 1474 """
1300 if not language: 1475 if not language:
1301 language = self.__ericProject.getProjectLanguage() 1476 language = self.__ericProject.getProjectLanguage()
1302 1477
1303 virtualEnv = self.__getVirtualEnvironment(language) 1478 virtualEnv = self.__getVirtualEnvironment(language)
1304 if virtualEnv: 1479 if virtualEnv:
1305 if isWindowsPlatform(): 1480 if isWindowsPlatform():
1306 for cmd in [ 1481 for cmd in [
1307 # standard Python 1482 # standard Python
1316 else: 1491 else:
1317 cmds = [ 1492 cmds = [
1318 os.path.join(virtualEnv, "bin", "django-admin"), 1493 os.path.join(virtualEnv, "bin", "django-admin"),
1319 os.path.join(virtualEnv, "bin", "django-admin.py"), 1494 os.path.join(virtualEnv, "bin", "django-admin.py"),
1320 os.path.join(virtualEnv, "local", "bin", "django-admin"), 1495 os.path.join(virtualEnv, "local", "bin", "django-admin"),
1321 os.path.join(virtualEnv, "local", "bin", 1496 os.path.join(virtualEnv, "local", "bin", "django-admin.py"),
1322 "django-admin.py"),
1323 ] 1497 ]
1324 for cmd in cmds: 1498 for cmd in cmds:
1325 if os.path.exists(cmd): 1499 if os.path.exists(cmd):
1326 break 1500 break
1327 else: 1501 else:
1339 break 1513 break
1340 else: 1514 else:
1341 cmd = "" 1515 cmd = ""
1342 else: 1516 else:
1343 if language == "Python3": 1517 if language == "Python3":
1344 cmds = ["django-admin3", 1518 cmds = [
1345 "django-admin3.py", 1519 "django-admin3",
1346 "django-admin.py-3.10", 1520 "django-admin3.py",
1347 "django-admin.py-3.9", 1521 "django-admin.py-3.10",
1348 "django-admin.py-3.8", 1522 "django-admin.py-3.9",
1349 "django-admin.py-3.7", 1523 "django-admin.py-3.8",
1350 "django-admin.py-3.6", 1524 "django-admin.py-3.7",
1351 ] 1525 "django-admin.py-3.6",
1526 ]
1352 else: 1527 else:
1353 cmds = [] 1528 cmds = []
1354 cmds.extend(["django-admin", "django-admin.py"]) 1529 cmds.extend(["django-admin", "django-admin.py"])
1355 for cmd in cmds: 1530 for cmd in cmds:
1356 if Utilities.isinpath(cmd): 1531 if Utilities.isinpath(cmd):
1357 break 1532 break
1358 else: 1533 else:
1359 cmd = "" 1534 cmd = ""
1360 1535
1361 return cmd 1536 return cmd
1362 1537
1363 def __getPythonExecutable(self): 1538 def __getPythonExecutable(self):
1364 """ 1539 """
1365 Private method to build the Python command. 1540 Private method to build the Python command.
1366 1541
1367 @return python command 1542 @return python command
1368 @rtype str 1543 @rtype str
1369 """ 1544 """
1370 language = self.__ericProject.getProjectLanguage() 1545 language = self.__ericProject.getProjectLanguage()
1371 if language == "Python3": 1546 if language == "Python3":
1372 venvName = self.__plugin.getPreferences( 1547 venvName = self.__plugin.getPreferences("VirtualEnvironmentNamePy3")
1373 "VirtualEnvironmentNamePy3")
1374 if not venvName: 1548 if not venvName:
1375 # if none configured, use the global one 1549 # if none configured, use the global one
1376 venvName = Preferences.getDebugger("Python3VirtualEnv") 1550 venvName = Preferences.getDebugger("Python3VirtualEnv")
1377 else: 1551 else:
1378 venvName = "" 1552 venvName = ""
1379 python = ( 1553 python = (
1380 self.__virtualEnvManager.getVirtualenvInterpreter(venvName) 1554 self.__virtualEnvManager.getVirtualenvInterpreter(venvName)
1381 if venvName else 1555 if venvName
1382 "" 1556 else ""
1383 ) 1557 )
1384 1558
1385 return python 1559 return python
1386 1560
1387 def __djangoInfo(self): 1561 def __djangoInfo(self):
1388 """ 1562 """
1389 Private slot to show some info about Django. 1563 Private slot to show some info about Django.
1390 """ 1564 """
1391 version = self.getDjangoVersionString() 1565 version = self.getDjangoVersionString()
1392 url = "https://www.djangoproject.com" 1566 url = "https://www.djangoproject.com"
1393 1567
1394 msgBox = EricMessageBox.EricMessageBox( 1568 msgBox = EricMessageBox.EricMessageBox(
1395 EricMessageBox.Question, 1569 EricMessageBox.Question,
1396 self.tr("About Django"), 1570 self.tr("About Django"),
1397 self.tr( 1571 self.tr(
1398 "<p>Django is a high-level Python Web framework that" 1572 "<p>Django is a high-level Python Web framework that"
1399 " encourages rapid development and clean, pragmatic" 1573 " encourages rapid development and clean, pragmatic"
1400 " design.</p>" 1574 " design.</p>"
1401 "<p><table>" 1575 "<p><table>"
1402 "<tr><td>Version:</td><td>{0}</td></tr>" 1576 "<tr><td>Version:</td><td>{0}</td></tr>"
1403 "<tr><td>URL:</td><td><a href=\"{1}\">" 1577 '<tr><td>URL:</td><td><a href="{1}">'
1404 "{1}</a></td></tr>" 1578 "{1}</a></td></tr>"
1405 "</table></p>" 1579 "</table></p>"
1406 ).format(version, url), 1580 ).format(version, url),
1407 modal=True, 1581 modal=True,
1408 buttons=EricMessageBox.Ok) 1582 buttons=EricMessageBox.Ok,
1409 msgBox.setIconPixmap(UI.PixmapCache.getPixmap( 1583 )
1410 os.path.join("ProjectDjango", "icons", 1584 msgBox.setIconPixmap(
1411 "django64-{0}".format(self.__iconSuffix)))) 1585 UI.PixmapCache.getPixmap(
1586 os.path.join(
1587 "ProjectDjango", "icons", "django64-{0}".format(self.__iconSuffix)
1588 )
1589 )
1590 )
1412 msgBox.exec() 1591 msgBox.exec()
1413 1592
1414 def getDjangoVersionString(self): 1593 def getDjangoVersionString(self):
1415 """ 1594 """
1416 Public method to get the Django version as a string. 1595 Public method to get the Django version as a string.
1417 1596
1418 @return Django version 1597 @return Django version
1419 @rtype str 1598 @rtype str
1420 """ 1599 """
1421 djangoVersion = "" 1600 djangoVersion = ""
1422 1601
1423 args = ['--version'] 1602 args = ["--version"]
1424 ioEncoding = Preferences.getSystem("IOEncoding") 1603 ioEncoding = Preferences.getSystem("IOEncoding")
1425 cmd = self.__getDjangoAdminCommand() 1604 cmd = self.__getDjangoAdminCommand()
1426 if cmd: 1605 if cmd:
1427 if isWindowsPlatform(): 1606 if isWindowsPlatform():
1428 args.insert(0, cmd) 1607 args.insert(0, cmd)
1429 cmd = self.__getPythonExecutable() 1608 cmd = self.__getPythonExecutable()
1430 1609
1431 process = QProcess() 1610 process = QProcess()
1432 process.start(cmd, args) 1611 process.start(cmd, args)
1433 procStarted = process.waitForStarted() 1612 procStarted = process.waitForStarted()
1434 if procStarted: 1613 if procStarted:
1435 finished = process.waitForFinished(30000) 1614 finished = process.waitForFinished(30000)
1436 if finished and process.exitCode() == 0: 1615 if finished and process.exitCode() == 0:
1437 output = str(process.readAllStandardOutput(), ioEncoding, 1616 output = str(process.readAllStandardOutput(), ioEncoding, "replace")
1438 'replace')
1439 djangoVersion = output.splitlines()[0].strip() 1617 djangoVersion = output.splitlines()[0].strip()
1440 1618
1441 return djangoVersion 1619 return djangoVersion
1442 1620
1443 def getDjangoVersion(self): 1621 def getDjangoVersion(self):
1444 """ 1622 """
1445 Public method to get the Django version as a tuple. 1623 Public method to get the Django version as a tuple.
1446 1624
1447 @return Django version 1625 @return Django version
1448 @rtype tuple of int 1626 @rtype tuple of int
1449 """ 1627 """
1450 djangoVersionStr = self.getDjangoVersionString() 1628 djangoVersionStr = self.getDjangoVersionString()
1451 djangoVersionList = [] 1629 djangoVersionList = []
1453 for part in djangoVersionStr.split("."): 1631 for part in djangoVersionStr.split("."):
1454 try: 1632 try:
1455 djangoVersionList.append(int(part)) 1633 djangoVersionList.append(int(part))
1456 except ValueError: 1634 except ValueError:
1457 djangoVersionList.append(part) 1635 djangoVersionList.append(part)
1458 1636
1459 return tuple(djangoVersionList) 1637 return tuple(djangoVersionList)
1460 1638
1461 def __getApplications(self): 1639 def __getApplications(self):
1462 """ 1640 """
1463 Private method to ask the user for a list of application names. 1641 Private method to ask the user for a list of application names.
1464 1642
1465 @return list of application names 1643 @return list of application names
1466 @rtype list of str 1644 @rtype list of str
1467 """ 1645 """
1468 applStr, ok = QInputDialog.getItem( 1646 applStr, ok = QInputDialog.getItem(
1469 self.__ui, 1647 self.__ui,
1470 self.tr("Select Applications"), 1648 self.tr("Select Applications"),
1471 self.tr("Enter the list of applications separated by spaces."), 1649 self.tr("Enter the list of applications separated by spaces."),
1472 self.getRecentApplications(), 1650 self.getRecentApplications(),
1473 0, True) 1651 0,
1652 True,
1653 )
1474 if ok and applStr != "": 1654 if ok and applStr != "":
1475 self.setMostRecentApplication(applStr) 1655 self.setMostRecentApplication(applStr)
1476 return applStr.split() 1656 return applStr.split()
1477 else: 1657 else:
1478 return [] 1658 return []
1485 Preferences.Prefs.rsettings.sync() 1665 Preferences.Prefs.rsettings.sync()
1486 ra = Preferences.Prefs.rsettings.value(self.RecentApplicationsKey) 1666 ra = Preferences.Prefs.rsettings.value(self.RecentApplicationsKey)
1487 if ra is not None: 1667 if ra is not None:
1488 maxRecentApps = self.__plugin.getPreferences("RecentNumberApps") 1668 maxRecentApps = self.__plugin.getPreferences("RecentNumberApps")
1489 self.__recentApplications = ra[:maxRecentApps] 1669 self.__recentApplications = ra[:maxRecentApps]
1490 1670
1491 def __saveRecentApplications(self): 1671 def __saveRecentApplications(self):
1492 """ 1672 """
1493 Private method to save the list of recently used applications list. 1673 Private method to save the list of recently used applications list.
1494 """ 1674 """
1495 Preferences.Prefs.rsettings.setValue(self.RecentApplicationsKey, 1675 Preferences.Prefs.rsettings.setValue(
1496 self.__recentApplications) 1676 self.RecentApplicationsKey, self.__recentApplications
1677 )
1497 Preferences.Prefs.rsettings.sync() 1678 Preferences.Prefs.rsettings.sync()
1498 1679
1499 def getRecentApplications(self): 1680 def getRecentApplications(self):
1500 """ 1681 """
1501 Public method to get the list of recent applications. 1682 Public method to get the list of recent applications.
1502 1683
1503 @return list of recent applications entries (list of strings) 1684 @return list of recent applications entries (list of strings)
1504 """ 1685 """
1505 self.__loadRecentApplications() 1686 self.__loadRecentApplications()
1506 return self.__recentApplications 1687 return self.__recentApplications
1507 1688
1508 def setMostRecentApplication(self, applStr): 1689 def setMostRecentApplication(self, applStr):
1509 """ 1690 """
1510 Public method to set the most recently used applications entry. 1691 Public method to set the most recently used applications entry.
1511 1692
1512 @param applStr applications entry 1693 @param applStr applications entry
1513 @type str 1694 @type str
1514 """ 1695 """
1515 if applStr in self.__recentApplications: 1696 if applStr in self.__recentApplications:
1516 self.__recentApplications.remove(applStr) 1697 self.__recentApplications.remove(applStr)
1517 self.__recentApplications.insert(0, applStr) 1698 self.__recentApplications.insert(0, applStr)
1518 1699
1519 maxRecentApps = self.__plugin.getPreferences("RecentNumberApps") 1700 maxRecentApps = self.__plugin.getPreferences("RecentNumberApps")
1520 if len(self.__recentApplications) > maxRecentApps: 1701 if len(self.__recentApplications) > maxRecentApps:
1521 self.__recentApplications = ( 1702 self.__recentApplications = self.__recentApplications[:maxRecentApps]
1522 self.__recentApplications[:maxRecentApps])
1523 self.__saveRecentApplications() 1703 self.__saveRecentApplications()
1524 1704
1525 def __loadRecentTestData(self): 1705 def __loadRecentTestData(self):
1526 """ 1706 """
1527 Private method to load the recently used test data lists. 1707 Private method to load the recently used test data lists.
1528 """ 1708 """
1529 self.__recentTestData = { 1709 self.__recentTestData = {
1530 "RecentTestLabels": [], 1710 "RecentTestLabels": [],
1531 "RecentTestTags": [], 1711 "RecentTestTags": [],
1532 "RecentTestExcludeTags": [], 1712 "RecentTestExcludeTags": [],
1533 } 1713 }
1534 Preferences.Prefs.rsettings.sync() 1714 Preferences.Prefs.rsettings.sync()
1535 maxRecentTestData = self.__plugin.getPreferences( 1715 maxRecentTestData = self.__plugin.getPreferences("RecentNumberTestData")
1536 "RecentNumberTestData")
1537 for key in self.__recentTestData: 1716 for key in self.__recentTestData:
1538 recent = Preferences.Prefs.rsettings.value("Django/" + key) 1717 recent = Preferences.Prefs.rsettings.value("Django/" + key)
1539 if recent is not None: 1718 if recent is not None:
1540 self.__recentTestData[key] = recent[:maxRecentTestData] 1719 self.__recentTestData[key] = recent[:maxRecentTestData]
1541 1720
1542 def __saveRecentTestData(self): 1721 def __saveRecentTestData(self):
1543 """ 1722 """
1544 Private method to save the list of recently used test data. 1723 Private method to save the list of recently used test data.
1545 """ 1724 """
1546 for key in self.__recentTestData: 1725 for key in self.__recentTestData:
1547 Preferences.Prefs.rsettings.setValue("Django/" + key, 1726 Preferences.Prefs.rsettings.setValue(
1548 self.__recentTestData[key]) 1727 "Django/" + key, self.__recentTestData[key]
1728 )
1549 Preferences.Prefs.rsettings.sync() 1729 Preferences.Prefs.rsettings.sync()
1550 1730
1551 def getRecentTestData(self, key): 1731 def getRecentTestData(self, key):
1552 """ 1732 """
1553 Public method to get the list of recent test data. 1733 Public method to get the list of recent test data.
1554 1734
1555 @param key key (name) of the test data to get 1735 @param key key (name) of the test data to get
1556 @type str 1736 @type str
1557 @return list of recent test data entries 1737 @return list of recent test data entries
1558 @rtype list of str 1738 @rtype list of str
1559 """ 1739 """
1560 self.__loadRecentTestData() 1740 self.__loadRecentTestData()
1561 return self.__recentTestData[key] 1741 return self.__recentTestData[key]
1562 1742
1563 def setMostRecentTestData(self, key, data): 1743 def setMostRecentTestData(self, key, data):
1564 """ 1744 """
1565 Public method to set the most recently used test data entry. 1745 Public method to set the most recently used test data entry.
1566 1746
1567 @param key key (name) of the test data to set 1747 @param key key (name) of the test data to set
1568 @type str 1748 @type str
1569 @param data test data entry to be set 1749 @param data test data entry to be set
1570 @type str 1750 @type str
1571 """ 1751 """
1572 if data in self.__recentTestData[key]: 1752 if data in self.__recentTestData[key]:
1573 self.__recentTestData[key].remove(data) 1753 self.__recentTestData[key].remove(data)
1574 self.__recentTestData[key].insert(0, data) 1754 self.__recentTestData[key].insert(0, data)
1575 1755
1576 maxRecentTestData = self.__plugin.getPreferences( 1756 maxRecentTestData = self.__plugin.getPreferences("RecentNumberTestData")
1577 "RecentNumberTestData")
1578 if len(self.__recentTestData[key]) > maxRecentTestData: 1757 if len(self.__recentTestData[key]) > maxRecentTestData:
1579 self.__recentTestData[key] = ( 1758 self.__recentTestData[key] = self.__recentTestData[key][:maxRecentTestData]
1580 self.__recentTestData[key][:maxRecentTestData])
1581 self.__saveRecentTestData() 1759 self.__saveRecentTestData()
1582 1760
1583 def getProjectPath(self): 1761 def getProjectPath(self):
1584 """ 1762 """
1585 Public method to get the path of the eric7 project. 1763 Public method to get the path of the eric7 project.
1586 1764
1587 @return path of the eric7 project 1765 @return path of the eric7 project
1588 @rtype str 1766 @rtype str
1589 """ 1767 """
1590 return self.__ericProject.getProjectPath() 1768 return self.__ericProject.getProjectPath()
1591 1769
1592 def __showHelpIndex(self): 1770 def __showHelpIndex(self):
1593 """ 1771 """
1594 Private slot to show the help index page. 1772 Private slot to show the help index page.
1595 """ 1773 """
1596 page = os.path.join(os.path.dirname(__file__), 1774 page = os.path.join(
1597 "Documentation", "help", "index.html") 1775 os.path.dirname(__file__), "Documentation", "help", "index.html"
1776 )
1598 self.__ui.launchHelpViewer(page) 1777 self.__ui.launchHelpViewer(page)
1599 1778
1600 def __isSpawningConsole(self, consoleCmd): 1779 def __isSpawningConsole(self, consoleCmd):
1601 """ 1780 """
1602 Private method to check, if the given console is a spawning console. 1781 Private method to check, if the given console is a spawning console.
1603 1782
1604 @param consoleCmd console command 1783 @param consoleCmd console command
1605 @type str 1784 @type str
1606 @return tuple of two entries giving an indication, if the console 1785 @return tuple of two entries giving an indication, if the console
1607 is spawning and the (possibly) cleaned console command 1786 is spawning and the (possibly) cleaned console command
1608 @rtype tuple of (bool, str) 1787 @rtype tuple of (bool, str)
1609 """ 1788 """
1610 if consoleCmd and consoleCmd[0] == '@': 1789 if consoleCmd and consoleCmd[0] == "@":
1611 return (True, consoleCmd[1:]) 1790 return (True, consoleCmd[1:])
1612 else: 1791 else:
1613 return (False, consoleCmd) 1792 return (False, consoleCmd)
1614 1793
1615 def __adjustWorkingDirectory(self, args, wd): 1794 def __adjustWorkingDirectory(self, args, wd):
1616 """ 1795 """
1617 Private method to adjust the working directory in the arguments list. 1796 Private method to adjust the working directory in the arguments list.
1618 1797
1619 @param args list of arguments to be modified 1798 @param args list of arguments to be modified
1620 @type list of str 1799 @type list of str
1621 @param wd working directory 1800 @param wd working directory
1622 @type str 1801 @type str
1623 """ 1802 """
1627 elif args[0].endswith(("gnome-terminal", "mate-terminal")): 1806 elif args[0].endswith(("gnome-terminal", "mate-terminal")):
1628 for index in range(len(args)): 1807 for index in range(len(args)):
1629 if args[index].startswith("--working-directory="): 1808 if args[index].startswith("--working-directory="):
1630 args[index] = "--working-directory={0}".format(wd) 1809 args[index] = "--working-directory={0}".format(wd)
1631 break 1810 break
1632 1811
1633 ################################################################## 1812 ##################################################################
1634 ## slots below implement creation functions 1813 ## slots below implement creation functions
1635 ################################################################## 1814 ##################################################################
1636 1815
1637 def newProjectCreated(self): 1816 def newProjectCreated(self):
1638 """ 1817 """
1639 Public slot to finish up the newly generated project. 1818 Public slot to finish up the newly generated project.
1640 """ 1819 """
1641 if self.__ericProject.getProjectType() == "Django": 1820 if self.__ericProject.getProjectType() == "Django":
1642 ppath = self.__ericProject.getProjectPath() 1821 ppath = self.__ericProject.getProjectPath()
1643 1822
1644 # get rid of an __init__.py file because it would be in our way 1823 # get rid of an __init__.py file because it would be in our way
1645 initModule = os.path.join(ppath, "__init__.py") 1824 initModule = os.path.join(ppath, "__init__.py")
1646 if os.path.exists(initModule): 1825 if os.path.exists(initModule):
1647 self.__ericProject.deleteFile("__init__.py") 1826 self.__ericProject.deleteFile("__init__.py")
1648 self.__ericProject.saveProject() 1827 self.__ericProject.saveProject()
1649 1828
1650 def startProjectOrApplication(self): 1829 def startProjectOrApplication(self):
1651 """ 1830 """
1652 Public slot to start a new Django project or application. 1831 Public slot to start a new Django project or application.
1653 """ 1832 """
1654 if self.__ericProject.getProjectType() == "Django": 1833 if self.__ericProject.getProjectType() == "Django":
1656 applStr = self.tr("Application") 1835 applStr = self.tr("Application")
1657 selections = ["", projectStr, applStr] 1836 selections = ["", projectStr, applStr]
1658 selection, ok = QInputDialog.getItem( 1837 selection, ok = QInputDialog.getItem(
1659 self.__ui, 1838 self.__ui,
1660 self.tr("Start Django"), 1839 self.tr("Start Django"),
1661 self.tr("Select if this project should be a " 1840 self.tr(
1662 "Django Project or Application.<br />" 1841 "Select if this project should be a "
1663 "Select the empty entry for none."), 1842 "Django Project or Application.<br />"
1843 "Select the empty entry for none."
1844 ),
1664 selections, 1845 selections,
1665 0, False) 1846 0,
1847 False,
1848 )
1666 if ok and bool(selection): 1849 if ok and bool(selection):
1667 if selection == projectStr: 1850 if selection == projectStr:
1668 path, projectName = os.path.split( 1851 path, projectName = os.path.split(
1669 self.__ericProject.getProjectPath()) 1852 self.__ericProject.getProjectPath()
1853 )
1670 self.__createProject(projectName, path) 1854 self.__createProject(projectName, path)
1671 elif selection == applStr: 1855 elif selection == applStr:
1672 path, applName = os.path.split( 1856 path, applName = os.path.split(self.__ericProject.getProjectPath())
1673 self.__ericProject.getProjectPath())
1674 self.__createApplication(applName, path) 1857 self.__createApplication(applName, path)
1675 1858
1676 def __createProject(self, projectName, path): 1859 def __createProject(self, projectName, path):
1677 """ 1860 """
1678 Private slot to create a new Django project. 1861 Private slot to create a new Django project.
1679 1862
1680 @param projectName name of the new project 1863 @param projectName name of the new project
1681 @type str 1864 @type str
1682 @param path the directory where the project should be created 1865 @param path the directory where the project should be created
1683 @type str 1866 @type str
1684 @return flag indicating a successful creation 1867 @return flag indicating a successful creation
1685 @rtype bool 1868 @rtype bool
1686 """ 1869 """
1687 title = self.tr("Start Django Project") 1870 title = self.tr("Start Django Project")
1688 1871
1689 # remove the project directory if it exists already 1872 # remove the project directory if it exists already
1690 ppath = os.path.join(path, projectName) 1873 ppath = os.path.join(path, projectName)
1691 if os.path.exists(ppath): 1874 if os.path.exists(ppath):
1692 okToRemove = EricMessageBox.yesNo( 1875 okToRemove = EricMessageBox.yesNo(
1693 self.__ui, 1876 self.__ui,
1694 title, 1877 title,
1695 self.tr("""<p>The Django project path <b>{0}</b> exists""" 1878 self.tr(
1696 """ already. Shall it be removed and recreated?""" 1879 """<p>The Django project path <b>{0}</b> exists"""
1697 """</p>""").format(ppath)) 1880 """ already. Shall it be removed and recreated?"""
1881 """</p>"""
1882 ).format(ppath),
1883 )
1698 if not okToRemove: 1884 if not okToRemove:
1699 EricMessageBox.information( 1885 EricMessageBox.information(
1700 self.__ui, 1886 self.__ui,
1701 title, 1887 title,
1702 self.tr("""<p>Please add the files to the eric project""" 1888 self.tr(
1703 """ manually.</p>""")) 1889 """<p>Please add the files to the eric project"""
1890 """ manually.</p>"""
1891 ),
1892 )
1704 return True 1893 return True
1705 1894
1706 shutil.rmtree(ppath, ignore_errors=True) 1895 shutil.rmtree(ppath, ignore_errors=True)
1707 1896
1708 args = [] 1897 args = []
1709 cmd = self.__getDjangoAdminCommand() 1898 cmd = self.__getDjangoAdminCommand()
1710 if cmd: 1899 if cmd:
1711 if Utilities.isWindowsPlatform(): 1900 if Utilities.isWindowsPlatform():
1712 args.append(self.__getPythonExecutable()) 1901 args.append(self.__getPythonExecutable())
1713 args.append(cmd) 1902 args.append(cmd)
1714 else: 1903 else:
1715 EricMessageBox.critical( 1904 EricMessageBox.critical(
1716 self.__ui, 1905 self.__ui,
1717 title, 1906 title,
1718 self.tr("""<p>The <b>django-admin.py</b> script is""" 1907 self.tr(
1719 """ not in the path. Aborting...</p>""")) 1908 """<p>The <b>django-admin.py</b> script is"""
1909 """ not in the path. Aborting...</p>"""
1910 ),
1911 )
1720 return False 1912 return False
1721 1913
1722 args.append("startproject") 1914 args.append("startproject")
1723 args.append(projectName) 1915 args.append(projectName)
1724 1916
1725 dia = DjangoDialog( 1917 dia = DjangoDialog(
1726 title, 1918 title, msgSuccess=self.tr("Django project created successfully.")
1727 msgSuccess=self.tr("Django project created successfully.")) 1919 )
1728 res = dia.startProcess(args, path) 1920 res = dia.startProcess(args, path)
1729 if res: 1921 if res:
1730 dia.exec() 1922 dia.exec()
1731 1923
1732 # create the base directory for translations 1924 # create the base directory for translations
1733 i18nPath = os.path.join(path, projectName, "locale") 1925 i18nPath = os.path.join(path, projectName, "locale")
1734 if not os.path.exists(i18nPath): 1926 if not os.path.exists(i18nPath):
1735 os.makedirs(i18nPath) 1927 os.makedirs(i18nPath)
1736 1928
1737 if ( 1929 if os.path.join(path, projectName) == self.__ericProject.getProjectPath():
1738 os.path.join(path, projectName) ==
1739 self.__ericProject.getProjectPath()
1740 ):
1741 self.__setCurrentSite("") 1930 self.__setCurrentSite("")
1742 else: 1931 else:
1743 self.__setCurrentSite(projectName) 1932 self.__setCurrentSite(projectName)
1744 1933
1745 return res 1934 return res
1746 1935
1747 def __startProject(self): 1936 def __startProject(self):
1748 """ 1937 """
1749 Private slot to start a new Django project. 1938 Private slot to start a new Django project.
1750 """ 1939 """
1751 projectName, ok = QInputDialog.getText( 1940 projectName, ok = QInputDialog.getText(
1752 self.__ui, 1941 self.__ui,
1753 self.tr("Start Django Project"), 1942 self.tr("Start Django Project"),
1754 self.tr("Enter the name of the new Django project."), 1943 self.tr("Enter the name of the new Django project."),
1755 QLineEdit.EchoMode.Normal) 1944 QLineEdit.EchoMode.Normal,
1945 )
1756 if ok and projectName != "": 1946 if ok and projectName != "":
1757 res = self.__createProject(projectName, 1947 res = self.__createProject(projectName, self.__ericProject.getProjectPath())
1758 self.__ericProject.getProjectPath())
1759 if res: 1948 if res:
1760 # search for new files and add them to the project 1949 # search for new files and add them to the project
1761 sitePath = os.path.join(self.__ericProject.getProjectPath(), 1950 sitePath = os.path.join(
1762 projectName) 1951 self.__ericProject.getProjectPath(), projectName
1952 )
1763 for entry in os.walk(sitePath): 1953 for entry in os.walk(sitePath):
1764 for fileName in entry[2]: 1954 for fileName in entry[2]:
1765 fullName = os.path.join(entry[0], fileName) 1955 fullName = os.path.join(entry[0], fileName)
1766 self.__ericProject.appendFile(fullName) 1956 self.__ericProject.appendFile(fullName)
1767 1957
1768 def __createApplication(self, applName, path, isGlobal=True): 1958 def __createApplication(self, applName, path, isGlobal=True):
1769 """ 1959 """
1770 Private slot to create a new Django application. 1960 Private slot to create a new Django application.
1771 1961
1772 @param applName name of the new application 1962 @param applName name of the new application
1773 @type str 1963 @type str
1774 @param path the directory where the application should be created 1964 @param path the directory where the application should be created
1775 @type str 1965 @type str
1776 @param isGlobal flag indicating a standalone Django application 1966 @param isGlobal flag indicating a standalone Django application
1777 @type bool 1967 @type bool
1778 @return flag indicating a successful creation 1968 @return flag indicating a successful creation
1779 @rtype bool 1969 @rtype bool
1780 """ 1970 """
1781 title = self.tr("Start Django Application") 1971 title = self.tr("Start Django Application")
1782 1972
1783 # remove the application directory if it exists already 1973 # remove the application directory if it exists already
1784 apath = os.path.join(path, applName) 1974 apath = os.path.join(path, applName)
1785 if os.path.exists(apath): 1975 if os.path.exists(apath):
1786 shutil.rmtree(apath, ignore_errors=True) 1976 shutil.rmtree(apath, ignore_errors=True)
1787 1977
1788 args = [] 1978 args = []
1789 if isGlobal: 1979 if isGlobal:
1790 cmd = self.__getDjangoAdminCommand() 1980 cmd = self.__getDjangoAdminCommand()
1791 if cmd: 1981 if cmd:
1792 if Utilities.isWindowsPlatform(): 1982 if Utilities.isWindowsPlatform():
1794 args.append(cmd) 1984 args.append(cmd)
1795 else: 1985 else:
1796 EricMessageBox.critical( 1986 EricMessageBox.critical(
1797 self.__ui, 1987 self.__ui,
1798 title, 1988 title,
1799 self.tr("""<p>The <b>django-admin.py</b> script""" 1989 self.tr(
1800 """ is not in the path.""" 1990 """<p>The <b>django-admin.py</b> script"""
1801 """ Aborting...</p>""")) 1991 """ is not in the path."""
1992 """ Aborting...</p>"""
1993 ),
1994 )
1802 return False 1995 return False
1803 else: 1996 else:
1804 args.append(self.__getPythonExecutable()) 1997 args.append(self.__getPythonExecutable())
1805 args.append("manage.py") 1998 args.append("manage.py")
1806 try: 1999 try:
1807 path = self.__sitePath() 2000 path = self.__sitePath()
1808 except DjangoNoSiteSelectedException: 2001 except DjangoNoSiteSelectedError:
1809 return False 2002 return False
1810 args.append("startapp") 2003 args.append("startapp")
1811 args.append(applName) 2004 args.append(applName)
1812 2005
1813 dia = DjangoDialog( 2006 dia = DjangoDialog(
1814 title, 2007 title, msgSuccess=self.tr("Django application created successfully.")
1815 msgSuccess=self.tr("Django application created successfully.")) 2008 )
1816 res = dia.startProcess(args, path) 2009 res = dia.startProcess(args, path)
1817 if res: 2010 if res:
1818 dia.exec() 2011 dia.exec()
1819 return res 2012 return res
1820 2013
1821 def __startGlobalApplication(self): 2014 def __startGlobalApplication(self):
1822 """ 2015 """
1823 Private slot to start a new global Django application. 2016 Private slot to start a new global Django application.
1824 """ 2017 """
1825 applName, ok = QInputDialog.getText( 2018 applName, ok = QInputDialog.getText(
1826 self.__ui, 2019 self.__ui,
1827 self.tr("Start Global Django Application"), 2020 self.tr("Start Global Django Application"),
1828 self.tr("Enter the name of the new global Django" 2021 self.tr("Enter the name of the new global Django" " application."),
1829 " application."), 2022 QLineEdit.EchoMode.Normal,
1830 QLineEdit.EchoMode.Normal) 2023 )
1831 if ok and applName != "": 2024 if ok and applName != "":
1832 res = self.__createApplication(applName, 2025 res = self.__createApplication(
1833 self.__ericProject.getProjectPath()) 2026 applName, self.__ericProject.getProjectPath()
2027 )
1834 if res: 2028 if res:
1835 # search for new files and add them to the project 2029 # search for new files and add them to the project
1836 appPath = os.path.join(self.__ericProject.getProjectPath(), 2030 appPath = os.path.join(self.__ericProject.getProjectPath(), applName)
1837 applName)
1838 for entry in os.walk(appPath): 2031 for entry in os.walk(appPath):
1839 for fileName in entry[2]: 2032 for fileName in entry[2]:
1840 fullName = os.path.join(entry[0], fileName) 2033 fullName = os.path.join(entry[0], fileName)
1841 self.__ericProject.appendFile(fullName) 2034 self.__ericProject.appendFile(fullName)
1842 2035
1843 def __startLocalApplication(self): 2036 def __startLocalApplication(self):
1844 """ 2037 """
1845 Private slot to start a new local Django application. 2038 Private slot to start a new local Django application.
1846 """ 2039 """
1847 applName, ok = QInputDialog.getText( 2040 applName, ok = QInputDialog.getText(
1848 self.__ui, 2041 self.__ui,
1849 self.tr("Start Local Django Application"), 2042 self.tr("Start Local Django Application"),
1850 self.tr("Enter the name of the new local Django application."), 2043 self.tr("Enter the name of the new local Django application."),
1851 QLineEdit.EchoMode.Normal) 2044 QLineEdit.EchoMode.Normal,
2045 )
1852 if ok and applName != "": 2046 if ok and applName != "":
1853 res = self.__createApplication(applName, "", False) 2047 res = self.__createApplication(applName, "", False)
1854 if res: 2048 if res:
1855 try: 2049 try:
1856 # search for new files and add them to the project 2050 # search for new files and add them to the project
1857 appPath = os.path.join(self.__sitePath(), applName) 2051 appPath = os.path.join(self.__sitePath(), applName)
1858 for entry in os.walk(appPath): 2052 for entry in os.walk(appPath):
1859 for fileName in entry[2]: 2053 for fileName in entry[2]:
1860 fullName = os.path.join(entry[0], fileName) 2054 fullName = os.path.join(entry[0], fileName)
1861 self.__ericProject.appendFile(fullName) 2055 self.__ericProject.appendFile(fullName)
1862 except DjangoNoSiteSelectedException: 2056 except DjangoNoSiteSelectedError:
1863 return 2057 return
1864 2058
1865 ################################################################## 2059 ##################################################################
1866 ## methods below implement site related functions 2060 ## methods below implement site related functions
1867 ################################################################## 2061 ##################################################################
1868 2062
1869 def __findSites(self): 2063 def __findSites(self):
1870 """ 2064 """
1871 Private method to determine the relative path to all manage.py scripts. 2065 Private method to determine the relative path to all manage.py scripts.
1872 2066
1873 @return list of sites 2067 @return list of sites
1874 @rtype list of str 2068 @rtype list of str
1875 """ 2069 """
1876 sites = [] 2070 sites = []
1877 for file in sorted(self.__ericProject.getSources()): 2071 for file in sorted(self.__ericProject.getSources()):
1878 if os.path.basename(file) == "manage.py": 2072 if os.path.basename(file) == "manage.py":
1879 sites.append(os.path.dirname(file)) 2073 sites.append(os.path.dirname(file))
1880 return sites 2074 return sites
1881 2075
1882 def __selectSite(self): 2076 def __selectSite(self):
1883 """ 2077 """
1884 Private method to select a site to work with. 2078 Private method to select a site to work with.
1885 """ 2079 """
1886 sites = self.__findSites() 2080 sites = self.__findSites()
1897 site, ok = QInputDialog.getItem( 2091 site, ok = QInputDialog.getItem(
1898 self.__ui, 2092 self.__ui,
1899 self.tr("Select Project"), 2093 self.tr("Select Project"),
1900 self.tr("Select the Django project to work with."), 2094 self.tr("Select the Django project to work with."),
1901 sites, 2095 sites,
1902 cur, False) 2096 cur,
2097 False,
2098 )
1903 if not ok: 2099 if not ok:
1904 site = None 2100 site = None
1905 self.__setCurrentSite(site) 2101 self.__setCurrentSite(site)
1906 2102
1907 def __sitePath(self): 2103 def __sitePath(self):
1908 """ 2104 """
1909 Private method to calculate the full path of the Django site. 2105 Private method to calculate the full path of the Django site.
1910 2106
1911 @return path of the site 2107 @return path of the site
1912 @rtype str 2108 @rtype str
1913 @exception DjangoNoSiteSelectedException raised, if no site is selected 2109 @exception DjangoNoSiteSelectedError raised, if no site is selected
1914 """ 2110 """
1915 if self.__currentSite is None: 2111 if self.__currentSite is None:
1916 self.__selectSite() 2112 self.__selectSite()
1917 2113
1918 if self.__currentSite is None: 2114 if self.__currentSite is None:
1919 raise DjangoNoSiteSelectedException 2115 raise DjangoNoSiteSelectedError
1920 else: 2116 else:
1921 path = os.path.join(self.__ericProject.getProjectPath(), 2117 path = os.path.join(self.__ericProject.getProjectPath(), self.__currentSite)
1922 self.__currentSite)
1923 return path 2118 return path
1924 2119
1925 def __setCurrentSite(self, site): 2120 def __setCurrentSite(self, site):
1926 """ 2121 """
1927 Private slot to set the current site. 2122 Private slot to set the current site.
1928 2123
1929 @param site name of the site 2124 @param site name of the site
1930 @type str 2125 @type str
1931 """ 2126 """
1932 self.__currentSite = site 2127 self.__currentSite = site
1933 if self.__currentSite is None: 2128 if self.__currentSite is None:
1935 elif self.__currentSite == "": 2130 elif self.__currentSite == "":
1936 curSite = self.tr("Project") 2131 curSite = self.tr("Project")
1937 else: 2132 else:
1938 curSite = self.__currentSite 2133 curSite = self.__currentSite
1939 self.selectSiteAct.setText( 2134 self.selectSiteAct.setText(
1940 self.tr('&Current Django project ({0})').format(curSite)) 2135 self.tr("&Current Django project ({0})").format(curSite)
1941 2136 )
2137
1942 if self.__currentSite is None: 2138 if self.__currentSite is None:
1943 self.__ericProject.setTranslationPattern("") 2139 self.__ericProject.setTranslationPattern("")
1944 else: 2140 else:
1945 self.__ericProject.setTranslationPattern( 2141 self.__ericProject.setTranslationPattern(
1946 os.path.join(site, "locale", "%language%", "LC_MESSAGES", 2142 os.path.join(site, "locale", "%language%", "LC_MESSAGES", "django.po")
1947 "django.po") 2143 )
1948 ) 2144
1949
1950 def __site(self): 2145 def __site(self):
1951 """ 2146 """
1952 Private method to get the name of the current site. 2147 Private method to get the name of the current site.
1953 2148
1954 @return name of the site 2149 @return name of the site
1955 @rtype str 2150 @rtype str
1956 @exception DjangoNoSiteSelectedException raised, if no site is selected 2151 @exception DjangoNoSiteSelectedError raised, if no site is selected
1957 """ 2152 """
1958 if self.__currentSite is None: 2153 if self.__currentSite is None:
1959 self.__selectSite() 2154 self.__selectSite()
1960 2155
1961 if self.__currentSite is None: 2156 if self.__currentSite is None:
1962 raise DjangoNoSiteSelectedException 2157 raise DjangoNoSiteSelectedError
1963 else: 2158 else:
1964 return self.__currentSite 2159 return self.__currentSite
1965 2160
1966 ################################################################## 2161 ##################################################################
1967 ## slots below implement run functions 2162 ## slots below implement run functions
1968 ################################################################## 2163 ##################################################################
1969 2164
1970 def __runServer(self): 2165 def __runServer(self):
1971 """ 2166 """
1972 Private slot to start the Django Web server. 2167 Private slot to start the Django Web server.
1973 """ 2168 """
1974 consoleCmd = self.__isSpawningConsole( 2169 consoleCmd = self.__isSpawningConsole(
1975 self.__plugin.getPreferences("ConsoleCommand"))[1] 2170 self.__plugin.getPreferences("ConsoleCommand")
2171 )[1]
1976 if consoleCmd: 2172 if consoleCmd:
1977 args = Utilities.parseOptionString(consoleCmd) 2173 args = Utilities.parseOptionString(consoleCmd)
1978 args[0] = Utilities.getExecutablePath(args[0]) 2174 args[0] = Utilities.getExecutablePath(args[0])
1979 args.append(self.__getPythonExecutable()) 2175 args.append(self.__getPythonExecutable())
1980 args.append("manage.py") 2176 args.append("manage.py")
1984 if not self.__plugin.getPreferences("UseThreading"): 2180 if not self.__plugin.getPreferences("UseThreading"):
1985 args.append("--nothreading") 2181 args.append("--nothreading")
1986 addr = self.__plugin.getPreferences("ServerAddress") 2182 addr = self.__plugin.getPreferences("ServerAddress")
1987 if addr: 2183 if addr:
1988 args.append(addr) 2184 args.append(addr)
1989 2185
1990 with contextlib.suppress(DjangoNoSiteSelectedException): 2186 with contextlib.suppress(DjangoNoSiteSelectedError):
1991 if Utilities.isWindowsPlatform(): 2187 if Utilities.isWindowsPlatform():
1992 serverProcStarted, pid = QProcess.startDetached( 2188 serverProcStarted, pid = QProcess.startDetached(
1993 args[0], args[1:], self.__sitePath()) 2189 args[0], args[1:], self.__sitePath()
2190 )
1994 else: 2191 else:
1995 if self.__serverProc is not None: 2192 if self.__serverProc is not None:
1996 self.__serverProcFinished() 2193 self.__serverProcFinished()
1997 2194
1998 self.__serverProc = QProcess() 2195 self.__serverProc = QProcess()
1999 self.__serverProc.finished.connect( 2196 self.__serverProc.finished.connect(self.__serverProcFinished)
2000 self.__serverProcFinished)
2001 self.__serverProc.setWorkingDirectory(self.__sitePath()) 2197 self.__serverProc.setWorkingDirectory(self.__sitePath())
2002 self.__serverProc.start(args[0], args[1:]) 2198 self.__serverProc.start(args[0], args[1:])
2003 serverProcStarted = self.__serverProc.waitForStarted() 2199 serverProcStarted = self.__serverProc.waitForStarted()
2004 if not serverProcStarted: 2200 if not serverProcStarted:
2005 EricMessageBox.critical( 2201 EricMessageBox.critical(
2006 None, 2202 None,
2007 self.tr('Process Generation Error'), 2203 self.tr("Process Generation Error"),
2008 self.tr('The Django server could not be started.')) 2204 self.tr("The Django server could not be started."),
2009 2205 )
2206
2010 def __serverProcFinished(self): 2207 def __serverProcFinished(self):
2011 """ 2208 """
2012 Private slot connected to the finished signal. 2209 Private slot connected to the finished signal.
2013 """ 2210 """
2014 if ( 2211 if (
2015 self.__serverProc is not None and 2212 self.__serverProc is not None
2016 self.__serverProc.state() != QProcess.ProcessState.NotRunning 2213 and self.__serverProc.state() != QProcess.ProcessState.NotRunning
2017 ): 2214 ):
2018 self.__serverProc.terminate() 2215 self.__serverProc.terminate()
2019 QTimer.singleShot(2000, self.__serverProc.kill) 2216 QTimer.singleShot(2000, self.__serverProc.kill)
2020 self.__serverProc.waitForFinished(3000) 2217 self.__serverProc.waitForFinished(3000)
2021 self.__serverProc = None 2218 self.__serverProc = None
2022 2219
2023 def __runBrowser(self): 2220 def __runBrowser(self):
2024 """ 2221 """
2025 Private slot to start the default web browser with the server URL. 2222 Private slot to start the default web browser with the server URL.
2026 """ 2223 """
2027 addr = self.__plugin.getPreferences("ServerAddress") 2224 addr = self.__plugin.getPreferences("ServerAddress")
2028 ipv6 = self.__plugin.getPreferences("UseIPv6") 2225 ipv6 = self.__plugin.getPreferences("UseIPv6")
2029 if addr: 2226 if addr:
2030 # test for an IPv6 and port address 2227 # test for an IPv6 and port address
2031 if ']:' in addr: 2228 if "]:" in addr:
2032 addr, port = addr.rsplit(':', 1) 2229 addr, port = addr.rsplit(":", 1)
2033 elif ':' in addr: 2230 elif ":" in addr:
2034 addr, port = addr.split(':', 1) 2231 addr, port = addr.split(":", 1)
2035 else: 2232 else:
2036 port = addr 2233 port = addr
2037 if ipv6: 2234 if ipv6:
2038 addr = "[::1]" 2235 addr = "[::1]"
2039 else: 2236 else:
2048 if self.__plugin.getPreferences("UseExternalBrowser"): 2245 if self.__plugin.getPreferences("UseExternalBrowser"):
2049 res = QDesktopServices.openUrl(QUrl(url)) 2246 res = QDesktopServices.openUrl(QUrl(url))
2050 if not res: 2247 if not res:
2051 EricMessageBox.critical( 2248 EricMessageBox.critical(
2052 None, 2249 None,
2053 self.tr('Run Web-Browser'), 2250 self.tr("Run Web-Browser"),
2054 self.tr('Could not start the web-browser for the' 2251 self.tr(
2055 ' url "{0}".').format(url.toString())) 2252 "Could not start the web-browser for the" ' url "{0}".'
2253 ).format(url.toString()),
2254 )
2056 else: 2255 else:
2057 self.__ui.launchHelpViewer(url) 2256 self.__ui.launchHelpViewer(url)
2058 2257
2059 ################################################################## 2258 ##################################################################
2060 ## slots below implement functions to save and load recently used 2259 ## slots below implement functions to save and load recently used
2061 ## database names 2260 ## database names
2062 ################################################################## 2261 ##################################################################
2063 2262
2064 def __loadRecentDatabaseNames(self): 2263 def __loadRecentDatabaseNames(self):
2065 """ 2264 """
2066 Private method to load the list of recently used database names. 2265 Private method to load the list of recently used database names.
2067 """ 2266 """
2068 self.__recentDatabaseNames = [""] 2267 self.__recentDatabaseNames = [""]
2069 Preferences.Prefs.rsettings.sync() 2268 Preferences.Prefs.rsettings.sync()
2070 rdb = Preferences.Prefs.rsettings.value(self.RecentDatabaseNamesKey) 2269 rdb = Preferences.Prefs.rsettings.value(self.RecentDatabaseNamesKey)
2071 if rdb is not None: 2270 if rdb is not None:
2072 maxRecentDatabaseNames = ( 2271 maxRecentDatabaseNames = self.__plugin.getPreferences(
2073 self.__plugin.getPreferences("RecentNumberDatabaseNames")) 2272 "RecentNumberDatabaseNames"
2273 )
2074 self.__recentDatabaseNames = rdb[:maxRecentDatabaseNames] 2274 self.__recentDatabaseNames = rdb[:maxRecentDatabaseNames]
2075 2275
2076 def __saveRecentDatabaseNames(self): 2276 def __saveRecentDatabaseNames(self):
2077 """ 2277 """
2078 Private method to save the list of recently used database names. 2278 Private method to save the list of recently used database names.
2079 """ 2279 """
2080 Preferences.Prefs.rsettings.setValue(self.RecentDatabaseNamesKey, 2280 Preferences.Prefs.rsettings.setValue(
2081 self.__recentDatabaseNames) 2281 self.RecentDatabaseNamesKey, self.__recentDatabaseNames
2282 )
2082 Preferences.Prefs.rsettings.sync() 2283 Preferences.Prefs.rsettings.sync()
2083 2284
2084 def getRecentDatabaseNames(self): 2285 def getRecentDatabaseNames(self):
2085 """ 2286 """
2086 Public method to get the list of recently used database names. 2287 Public method to get the list of recently used database names.
2087 2288
2088 @return list of recently used database names 2289 @return list of recently used database names
2089 @rtype list of str 2290 @rtype list of str
2090 """ 2291 """
2091 self.__loadRecentDatabaseNames() 2292 self.__loadRecentDatabaseNames()
2092 return self.__recentDatabaseNames 2293 return self.__recentDatabaseNames
2093 2294
2094 def setMostRecentDatabaseNames(self, dbName): 2295 def setMostRecentDatabaseNames(self, dbName):
2095 """ 2296 """
2096 Public method to set the most recently used database names. 2297 Public method to set the most recently used database names.
2097 2298
2098 @param dbName database name 2299 @param dbName database name
2099 @type str 2300 @type str
2100 """ 2301 """
2101 if dbName in self.__recentDatabaseNames: 2302 if dbName in self.__recentDatabaseNames:
2102 self.__recentDatabaseNames.remove(dbName) 2303 self.__recentDatabaseNames.remove(dbName)
2103 self.__recentDatabaseNames.insert(0, dbName) 2304 self.__recentDatabaseNames.insert(0, dbName)
2104 2305
2105 maxRecentDatabaseNames = ( 2306 maxRecentDatabaseNames = self.__plugin.getPreferences(
2106 self.__plugin.getPreferences("RecentNumberDatabaseNames")) 2307 "RecentNumberDatabaseNames"
2308 )
2107 if len(self.__recentDatabaseNames) > maxRecentDatabaseNames: 2309 if len(self.__recentDatabaseNames) > maxRecentDatabaseNames:
2108 self.__recentDatabaseNames = ( 2310 self.__recentDatabaseNames = self.__recentDatabaseNames[
2109 self.__recentDatabaseNames[:maxRecentDatabaseNames]) 2311 :maxRecentDatabaseNames
2312 ]
2110 self.__saveRecentDatabaseNames() 2313 self.__saveRecentDatabaseNames()
2111 2314
2112 def __selectDatabaseName(self): 2315 def __selectDatabaseName(self):
2113 """ 2316 """
2114 Private method to select the name of the database to work with. 2317 Private method to select the name of the database to work with.
2115 """ 2318 """
2116 recentDatabases = self.getRecentDatabaseNames()[:] 2319 recentDatabases = self.getRecentDatabaseNames()[:]
2117 if "" not in recentDatabases: 2320 if "" not in recentDatabases:
2118 recentDatabases.insert(1, "") 2321 recentDatabases.insert(1, "")
2119 2322
2120 selectedDatabase, ok = QInputDialog.getItem( 2323 selectedDatabase, ok = QInputDialog.getItem(
2121 self.__ui, 2324 self.__ui,
2122 self.tr("Database Name"), 2325 self.tr("Database Name"),
2123 self.tr("Select a database name (leave empty for default):"), 2326 self.tr("Select a database name (leave empty for default):"),
2124 recentDatabases, 2327 recentDatabases,
2125 0, True) 2328 0,
2126 2329 True,
2330 )
2331
2127 if ok: 2332 if ok:
2128 self.setMostRecentDatabaseNames(selectedDatabase) 2333 self.setMostRecentDatabaseNames(selectedDatabase)
2129 self.__setCurrentDatabase(selectedDatabase) 2334 self.__setCurrentDatabase(selectedDatabase)
2130 2335
2131 def __setCurrentDatabase(self, database): 2336 def __setCurrentDatabase(self, database):
2132 """ 2337 """
2133 Private method to set the database name to be used. 2338 Private method to set the database name to be used.
2134 2339
2135 @param database name of the database 2340 @param database name of the database
2136 @type str 2341 @type str
2137 """ 2342 """
2138 if database is None: 2343 if database is None:
2139 database = self.getRecentDatabaseNames()[0] 2344 database = self.getRecentDatabaseNames()[0]
2140 2345
2141 self.__currentDatabase = database 2346 self.__currentDatabase = database
2142 curDb = database if database else self.tr("<default>") 2347 curDb = database if database else self.tr("<default>")
2143 self.selectDatabaseNameAct.setText( 2348 self.selectDatabaseNameAct.setText(
2144 self.tr('&Current Database ({0})').format(curDb)) 2349 self.tr("&Current Database ({0})").format(curDb)
2145 2350 )
2351
2146 def currentDatabase(self): 2352 def currentDatabase(self):
2147 """ 2353 """
2148 Public method to get the database name to be used. 2354 Public method to get the database name to be used.
2149 2355
2150 @return database name 2356 @return database name
2151 @rtype str 2357 @rtype str
2152 """ 2358 """
2153 return self.__currentDatabase 2359 return self.__currentDatabase
2154 2360
2155 ################################################################## 2361 ##################################################################
2156 ## slots below implement database related functions 2362 ## slots below implement database related functions
2157 ################################################################## 2363 ##################################################################
2158 2364
2159 def __databaseInspect(self): 2365 def __databaseInspect(self):
2160 """ 2366 """
2161 Private slot to introspect the database and output a Django model 2367 Private slot to introspect the database and output a Django model
2162 module. 2368 module.
2163 """ 2369 """
2164 title = self.tr("Introspect Database") 2370 title = self.tr("Introspect Database")
2165 2371
2166 args = [] 2372 args = []
2167 args.append(self.__getPythonExecutable()) 2373 args.append(self.__getPythonExecutable())
2168 args.append("manage.py") 2374 args.append("manage.py")
2169 args.append("inspectdb") 2375 args.append("inspectdb")
2170 if self.__currentDatabase: 2376 if self.__currentDatabase:
2171 args.append("--database={0}".format(self.__currentDatabase)) 2377 args.append("--database={0}".format(self.__currentDatabase))
2172 2378
2173 try: 2379 try:
2174 path = self.__sitePath() 2380 path = self.__sitePath()
2175 except DjangoNoSiteSelectedException: 2381 except DjangoNoSiteSelectedError:
2176 return 2382 return
2177 2383
2178 dia = DjangoDialog(title, fixed=True, linewrap=False) 2384 dia = DjangoDialog(title, fixed=True, linewrap=False)
2179 res = dia.startProcess(args, path, False) 2385 res = dia.startProcess(args, path, False)
2180 if res: 2386 if res:
2181 dia.exec() 2387 dia.exec()
2182 2388
2183 def __databaseFlush(self): 2389 def __databaseFlush(self):
2184 """ 2390 """
2185 Private slot to return all database tables to the state just after 2391 Private slot to return all database tables to the state just after
2186 their installation. 2392 their installation.
2187 """ 2393 """
2188 try: 2394 try:
2189 path = self.__sitePath() 2395 path = self.__sitePath()
2190 except DjangoNoSiteSelectedException: 2396 except DjangoNoSiteSelectedError:
2191 return 2397 return
2192 2398
2193 title = self.tr("Flush Database") 2399 title = self.tr("Flush Database")
2194 2400
2195 res = EricMessageBox.yesNo( 2401 res = EricMessageBox.yesNo(
2196 self.__ui, 2402 self.__ui,
2197 title, 2403 title,
2198 self.tr("""Flushing the database will destroy all data.""" 2404 self.tr(
2199 """ Are you sure?""")) 2405 """Flushing the database will destroy all data.""" """ Are you sure?"""
2406 ),
2407 )
2200 if res: 2408 if res:
2201 args = [] 2409 args = []
2202 args.append(self.__getPythonExecutable()) 2410 args.append(self.__getPythonExecutable())
2203 args.append("manage.py") 2411 args.append("manage.py")
2204 args.append("flush") 2412 args.append("flush")
2205 args.append("--noinput") 2413 args.append("--noinput")
2206 if self.__currentDatabase: 2414 if self.__currentDatabase:
2207 args.append("--database={0}".format(self.__currentDatabase)) 2415 args.append("--database={0}".format(self.__currentDatabase))
2208 2416
2209 dia = DjangoDialog( 2417 dia = DjangoDialog(
2210 title, 2418 title, msgSuccess=self.tr("Database tables flushed" " successfully.")
2211 msgSuccess=self.tr("Database tables flushed" 2419 )
2212 " successfully."))
2213 res = dia.startProcess(args, path) 2420 res = dia.startProcess(args, path)
2214 if res: 2421 if res:
2215 dia.exec() 2422 dia.exec()
2216 2423
2217 def __runDatabaseClient(self): 2424 def __runDatabaseClient(self):
2218 """ 2425 """
2219 Private slot to start a database client for a Django project. 2426 Private slot to start a database client for a Django project.
2220 """ 2427 """
2221 consoleCmd = self.__isSpawningConsole( 2428 consoleCmd = self.__isSpawningConsole(
2222 self.__plugin.getPreferences("ConsoleCommand"))[1] 2429 self.__plugin.getPreferences("ConsoleCommand")
2430 )[1]
2223 if consoleCmd: 2431 if consoleCmd:
2224 args = Utilities.parseOptionString(consoleCmd) 2432 args = Utilities.parseOptionString(consoleCmd)
2225 args[0] = Utilities.getExecutablePath(args[0]) 2433 args[0] = Utilities.getExecutablePath(args[0])
2226 args.append(self.__getPythonExecutable()) 2434 args.append(self.__getPythonExecutable())
2227 args.append("manage.py") 2435 args.append("manage.py")
2228 args.append("dbshell") 2436 args.append("dbshell")
2229 if self.__currentDatabase: 2437 if self.__currentDatabase:
2230 args.append("--database={0}".format(self.__currentDatabase)) 2438 args.append("--database={0}".format(self.__currentDatabase))
2231 with contextlib.suppress(DjangoNoSiteSelectedException): 2439 with contextlib.suppress(DjangoNoSiteSelectedError):
2232 wd = self.__sitePath() 2440 wd = self.__sitePath()
2233 self.__adjustWorkingDirectory(args, wd) 2441 self.__adjustWorkingDirectory(args, wd)
2234 started, pid = QProcess.startDetached(args[0], args[1:], wd) 2442 started, pid = QProcess.startDetached(args[0], args[1:], wd)
2235 if not started: 2443 if not started:
2236 EricMessageBox.critical( 2444 EricMessageBox.critical(
2237 None, 2445 None,
2238 self.tr('Process Generation Error'), 2446 self.tr("Process Generation Error"),
2239 self.tr('The Django process could not be started.')) 2447 self.tr("The Django process could not be started."),
2240 2448 )
2449
2241 ####################################################################### 2450 #######################################################################
2242 ## slots below implement database functions outputting SQL statements 2451 ## slots below implement database functions outputting SQL statements
2243 ####################################################################### 2452 #######################################################################
2244 2453
2245 def __sqlCommand(self, title, command, requestApps=True): 2454 def __sqlCommand(self, title, command, requestApps=True):
2246 """ 2455 """
2247 Private method to perform an SQL creation function. 2456 Private method to perform an SQL creation function.
2248 2457
2249 @param title dialog title 2458 @param title dialog title
2250 @type str 2459 @type str
2251 @param command Django sql... command 2460 @param command Django sql... command
2252 @type str 2461 @type str
2253 @param requestApps flag indicating to request a list of applications 2462 @param requestApps flag indicating to request a list of applications
2254 to work on 2463 to work on
2255 @type bool 2464 @type bool
2256 """ 2465 """
2257 try: 2466 try:
2258 path = self.__sitePath() 2467 path = self.__sitePath()
2259 except DjangoNoSiteSelectedException: 2468 except DjangoNoSiteSelectedError:
2260 return 2469 return
2261 2470
2262 if requestApps: 2471 if requestApps:
2263 apps = self.__getApplications() 2472 apps = self.__getApplications()
2264 if not apps: 2473 if not apps:
2265 return 2474 return
2266 else: 2475 else:
2267 apps = [] 2476 apps = []
2268 2477
2269 args = [] 2478 args = []
2270 args.append(self.__getPythonExecutable()) 2479 args.append(self.__getPythonExecutable())
2271 args.append("manage.py") 2480 args.append("manage.py")
2272 args.append(command) 2481 args.append(command)
2273 if self.__currentDatabase: 2482 if self.__currentDatabase:
2274 args.append("--database={0}".format(self.__currentDatabase)) 2483 args.append("--database={0}".format(self.__currentDatabase))
2275 args += apps 2484 args += apps
2276 2485
2277 fileFilter = self.tr("SQL Files (*.sql)") 2486 fileFilter = self.tr("SQL Files (*.sql)")
2278 2487
2279 dia = DjangoDialog(title, fixed=True, linewrap=False, 2488 dia = DjangoDialog(title, fixed=True, linewrap=False, saveFilters=fileFilter)
2280 saveFilters=fileFilter)
2281 res = dia.startProcess(args, path, False) 2489 res = dia.startProcess(args, path, False)
2282 if res: 2490 if res:
2283 dia.exec() 2491 dia.exec()
2284 2492
2285 def __databaseSqlFlushDatabase(self): 2493 def __databaseSqlFlushDatabase(self):
2286 """ 2494 """
2287 Private slot to print a list of statements to return all database 2495 Private slot to print a list of statements to return all database
2288 tables to their initial state. 2496 tables to their initial state.
2289 """ 2497 """
2290 self.__sqlCommand(self.tr("Flush Database"), "sqlflush", False) 2498 self.__sqlCommand(self.tr("Flush Database"), "sqlflush", False)
2291 2499
2292 def __databaseSqlResetSequences(self): 2500 def __databaseSqlResetSequences(self):
2293 """ 2501 """
2294 Private slot to print the SQL statements for resetting sequences for 2502 Private slot to print the SQL statements for resetting sequences for
2295 one or more applications. 2503 one or more applications.
2296 """ 2504 """
2297 self.__sqlCommand(self.tr("Reset Sequences"), "sqlsequencereset") 2505 self.__sqlCommand(self.tr("Reset Sequences"), "sqlsequencereset")
2298 2506
2299 def __databaseSqlMigrate(self, backwards=False): 2507 def __databaseSqlMigrate(self, backwards=False):
2300 """ 2508 """
2301 Private slot to print the SQL statements for a migration of an 2509 Private slot to print the SQL statements for a migration of an
2302 application. 2510 application.
2303 2511
2304 @param backwards flag indicating to generate the SQL code to revert 2512 @param backwards flag indicating to generate the SQL code to revert
2305 a migration 2513 a migration
2306 @type bool 2514 @type bool
2307 """ 2515 """
2308 try: 2516 try:
2309 path = self.__sitePath() 2517 path = self.__sitePath()
2310 except DjangoNoSiteSelectedException: 2518 except DjangoNoSiteSelectedError:
2311 return 2519 return
2312 2520
2313 migrations = self.__getMigrations() 2521 migrations = self.__getMigrations()
2314 if not migrations: 2522 if not migrations:
2315 EricMessageBox.information( 2523 EricMessageBox.information(
2316 None, 2524 None, self.tr("SQL Migrate"), self.tr("""No migrations available.""")
2317 self.tr("SQL Migrate"), 2525 )
2318 self.tr("""No migrations available."""))
2319 return 2526 return
2320 2527
2321 title = self.tr("SQL Migrate") 2528 title = self.tr("SQL Migrate")
2322 2529
2323 from .DjangoMigrationSelectionDialog import ( 2530 from .DjangoMigrationSelectionDialog import DjangoMigrationSelectionDialog
2324 DjangoMigrationSelectionDialog 2531
2325 ) 2532 dlg = DjangoMigrationSelectionDialog(
2326 dlg = DjangoMigrationSelectionDialog(migrations, 2533 migrations, migrationRequired=True, suffix=self.__iconSuffix
2327 migrationRequired=True, 2534 )
2328 suffix=self.__iconSuffix)
2329 if dlg.exec() == QDialog.DialogCode.Accepted: 2535 if dlg.exec() == QDialog.DialogCode.Accepted:
2330 app, migration = dlg.getData() 2536 app, migration = dlg.getData()
2331 2537
2332 args = [] 2538 args = []
2333 args.append(self.__getPythonExecutable()) 2539 args.append(self.__getPythonExecutable())
2334 args.append("manage.py") 2540 args.append("manage.py")
2335 args.append("sqlmigrate") 2541 args.append("sqlmigrate")
2336 if self.__currentDatabase: 2542 if self.__currentDatabase:
2337 args.append("--database={0}".format(self.__currentDatabase)) 2543 args.append("--database={0}".format(self.__currentDatabase))
2338 if backwards: 2544 if backwards:
2339 args.append("--backwards") 2545 args.append("--backwards")
2340 args.append(app) 2546 args.append(app)
2341 args.append(migration) 2547 args.append(migration)
2342 2548
2343 fileFilter = self.tr("SQL Files (*.sql)") 2549 fileFilter = self.tr("SQL Files (*.sql)")
2344 2550
2345 dia = DjangoDialog(title, fixed=True, linewrap=False, 2551 dia = DjangoDialog(
2346 saveFilters=fileFilter) 2552 title, fixed=True, linewrap=False, saveFilters=fileFilter
2553 )
2347 res = dia.startProcess(args, path, False) 2554 res = dia.startProcess(args, path, False)
2348 if res: 2555 if res:
2349 dia.exec() 2556 dia.exec()
2350 2557
2351 ################################################################## 2558 ##################################################################
2352 ## slots below implement migration related functions 2559 ## slots below implement migration related functions
2353 ################################################################## 2560 ##################################################################
2354 2561
2355 def __showMigrationsList(self): 2562 def __showMigrationsList(self):
2356 """ 2563 """
2357 Private slot to show the available migrations and their status. 2564 Private slot to show the available migrations and their status.
2358 """ 2565 """
2359 try: 2566 try:
2360 path = self.__sitePath() 2567 path = self.__sitePath()
2361 except DjangoNoSiteSelectedException: 2568 except DjangoNoSiteSelectedError:
2362 return 2569 return
2363 2570
2364 from .DjangoMigrationsListDialog import DjangoMigrationsListDialog 2571 from .DjangoMigrationsListDialog import DjangoMigrationsListDialog
2572
2365 self.__migrationsListDialog = DjangoMigrationsListDialog( 2573 self.__migrationsListDialog = DjangoMigrationsListDialog(
2366 DjangoMigrationsListDialog.MigrationsListMode, self, self.__ui) 2574 DjangoMigrationsListDialog.MigrationsListMode, self, self.__ui
2575 )
2367 self.__migrationsListDialog.show() 2576 self.__migrationsListDialog.show()
2368 self.__migrationsListDialog.start(self.__getPythonExecutable(), path, 2577 self.__migrationsListDialog.start(
2369 self.__currentDatabase) 2578 self.__getPythonExecutable(), path, self.__currentDatabase
2370 2579 )
2580
2371 def __showMigrationsPlan(self): 2581 def __showMigrationsPlan(self):
2372 """ 2582 """
2373 Private slot to show the migrations plan. 2583 Private slot to show the migrations plan.
2374 """ 2584 """
2375 try: 2585 try:
2376 path = self.__sitePath() 2586 path = self.__sitePath()
2377 except DjangoNoSiteSelectedException: 2587 except DjangoNoSiteSelectedError:
2378 return 2588 return
2379 2589
2380 from .DjangoMigrationsListDialog import DjangoMigrationsListDialog 2590 from .DjangoMigrationsListDialog import DjangoMigrationsListDialog
2591
2381 self.__migrationsPlanDialog = DjangoMigrationsListDialog( 2592 self.__migrationsPlanDialog = DjangoMigrationsListDialog(
2382 DjangoMigrationsListDialog.MigrationsPlanMode, self, self.__ui) 2593 DjangoMigrationsListDialog.MigrationsPlanMode, self, self.__ui
2594 )
2383 self.__migrationsPlanDialog.show() 2595 self.__migrationsPlanDialog.show()
2384 self.__migrationsPlanDialog.start(self.__getPythonExecutable(), path, 2596 self.__migrationsPlanDialog.start(
2385 self.__currentDatabase) 2597 self.__getPythonExecutable(), path, self.__currentDatabase
2386 2598 )
2599
2387 def __applyAllMigrations(self): 2600 def __applyAllMigrations(self):
2388 """ 2601 """
2389 Private slot to apply all migrations. 2602 Private slot to apply all migrations.
2390 """ 2603 """
2391 self.applyMigrations() 2604 self.applyMigrations()
2392 2605
2393 def __applySelectedMigrations(self): 2606 def __applySelectedMigrations(self):
2394 """ 2607 """
2395 Private slot to apply selected migrations of a selected app. 2608 Private slot to apply selected migrations of a selected app.
2396 """ 2609 """
2397 migrations = self.__getMigrations() 2610 migrations = self.__getMigrations()
2398 if not migrations: 2611 if not migrations:
2399 EricMessageBox.information( 2612 EricMessageBox.information(
2400 None, 2613 None,
2401 self.tr("Apply Selected Migrations"), 2614 self.tr("Apply Selected Migrations"),
2402 self.tr("""No migrations available.""")) 2615 self.tr("""No migrations available."""),
2616 )
2403 return 2617 return
2404 2618
2405 from .DjangoMigrationSelectionDialog import ( 2619 from .DjangoMigrationSelectionDialog import DjangoMigrationSelectionDialog
2406 DjangoMigrationSelectionDialog 2620
2407 ) 2621 dlg = DjangoMigrationSelectionDialog(migrations, suffix=self.__iconSuffix)
2408 dlg = DjangoMigrationSelectionDialog(migrations,
2409 suffix=self.__iconSuffix)
2410 if dlg.exec() == QDialog.DialogCode.Accepted: 2622 if dlg.exec() == QDialog.DialogCode.Accepted:
2411 app, migration = dlg.getData() 2623 app, migration = dlg.getData()
2412 self.applyMigrations(app=app, migration=migration) 2624 self.applyMigrations(app=app, migration=migration)
2413 2625
2414 def applyMigrations(self, app=None, migration=None): 2626 def applyMigrations(self, app=None, migration=None):
2415 """ 2627 """
2416 Public slot to apply migrations. 2628 Public slot to apply migrations.
2417 2629
2418 @param app name of an application to apply migrations for 2630 @param app name of an application to apply migrations for
2419 @type str 2631 @type str
2420 @param migration name of a migration to update to 2632 @param migration name of a migration to update to
2421 @type str 2633 @type str
2422 """ 2634 """
2423 title = ( 2635 title = (
2424 self.tr("Unapply Migrations") 2636 self.tr("Unapply Migrations")
2425 if migration == "zero" else 2637 if migration == "zero"
2426 self.tr("Apply Migrations") 2638 else self.tr("Apply Migrations")
2427 ) 2639 )
2428 2640
2429 try: 2641 try:
2430 path = self.__sitePath() 2642 path = self.__sitePath()
2431 except DjangoNoSiteSelectedException: 2643 except DjangoNoSiteSelectedError:
2432 return 2644 return
2433 2645
2434 args = [] 2646 args = []
2435 args.append(self.__getPythonExecutable()) 2647 args.append(self.__getPythonExecutable())
2436 args.append("manage.py") 2648 args.append("manage.py")
2437 args.append("migrate") 2649 args.append("migrate")
2438 args.append("--noinput") 2650 args.append("--noinput")
2439 if app: 2651 if app:
2440 args.append(app) 2652 args.append(app)
2441 if migration: 2653 if migration:
2442 args.append(migration) 2654 args.append(migration)
2443 2655
2444 dia = DjangoDialog(title) 2656 dia = DjangoDialog(title)
2445 res = dia.startProcess(args, path) 2657 res = dia.startProcess(args, path)
2446 if res: 2658 if res:
2447 dia.exec() 2659 dia.exec()
2448 2660
2449 def __unapplyMigrations(self): 2661 def __unapplyMigrations(self):
2450 """ 2662 """
2451 Private slot to revert all migrations of an application. 2663 Private slot to revert all migrations of an application.
2452 """ 2664 """
2453 apps = sorted(self.__getMigrations().keys()) 2665 apps = sorted(self.__getMigrations().keys())
2454 if not apps: 2666 if not apps:
2455 EricMessageBox.information( 2667 EricMessageBox.information(
2456 None, 2668 None,
2457 self.tr("Unapply Migrations"), 2669 self.tr("Unapply Migrations"),
2458 self.tr("""No migrations available.""")) 2670 self.tr("""No migrations available."""),
2671 )
2459 return 2672 return
2460 2673
2461 app, ok = QInputDialog.getItem( 2674 app, ok = QInputDialog.getItem(
2462 None, 2675 None,
2463 self.tr("Unapply Migrations"), 2676 self.tr("Unapply Migrations"),
2464 self.tr("Select an application:"), 2677 self.tr("Select an application:"),
2465 [""] + apps, 2678 [""] + apps,
2466 0, False) 2679 0,
2680 False,
2681 )
2467 if ok and app: 2682 if ok and app:
2468 self.applyMigrations(app=app, migration="zero") 2683 self.applyMigrations(app=app, migration="zero")
2469 2684
2470 def __getMigrations(self): 2685 def __getMigrations(self):
2471 """ 2686 """
2472 Private method to get the available migrations. 2687 Private method to get the available migrations.
2473 2688
2474 @return dictionary containing the available migrations 2689 @return dictionary containing the available migrations
2475 @rtype dict with app name as key (str) and list of tuples of 2690 @rtype dict with app name as key (str) and list of tuples of
2476 applied indication (bool) and migration name (str) as value 2691 applied indication (bool) and migration name (str) as value
2477 """ 2692 """
2478 try: 2693 try:
2479 path = self.__sitePath() 2694 path = self.__sitePath()
2480 except DjangoNoSiteSelectedException: 2695 except DjangoNoSiteSelectedError:
2481 return {} 2696 return {}
2482 2697
2483 args = [] 2698 args = []
2484 args.append("manage.py") 2699 args.append("manage.py")
2485 args.append("showmigrations") 2700 args.append("showmigrations")
2486 args.append("--list") 2701 args.append("--list")
2487 if self.__currentDatabase: 2702 if self.__currentDatabase:
2488 args.append("--database={0}".format(self.__currentDatabase)) 2703 args.append("--database={0}".format(self.__currentDatabase))
2489 2704
2490 migrations = {} 2705 migrations = {}
2491 proc = QProcess() 2706 proc = QProcess()
2492 if path: 2707 if path:
2493 proc.setWorkingDirectory(path) 2708 proc.setWorkingDirectory(path)
2494 proc.start(self.__getPythonExecutable(), args) 2709 proc.start(self.__getPythonExecutable(), args)
2495 if proc.waitForStarted() and proc.waitForFinished(): 2710 if proc.waitForStarted() and proc.waitForFinished():
2496 output = str(proc.readAllStandardOutput(), 2711 output = str(
2497 Preferences.getSystem("IOEncoding"), 'replace') 2712 proc.readAllStandardOutput(),
2713 Preferences.getSystem("IOEncoding"),
2714 "replace",
2715 )
2498 if output: 2716 if output:
2499 recentApp = "" 2717 recentApp = ""
2500 for line in output.splitlines(): 2718 for line in output.splitlines():
2501 if not line.startswith(" "): 2719 if not line.startswith(" "):
2502 # application name 2720 # application name
2508 applied = line[1] != " " 2726 applied = line[1] != " "
2509 name = line[3:].strip() 2727 name = line[3:].strip()
2510 if recentApp: 2728 if recentApp:
2511 migrations[recentApp].append((applied, name)) 2729 migrations[recentApp].append((applied, name))
2512 return migrations 2730 return migrations
2513 2731
2514 def __makeMigrations(self): 2732 def __makeMigrations(self):
2515 """ 2733 """
2516 Private slot to generate migrations for the Django project. 2734 Private slot to generate migrations for the Django project.
2517 """ 2735 """
2518 from .DjangoMakeMigrationsDialog import DjangoMakeMigrationsDialog 2736 from .DjangoMakeMigrationsDialog import DjangoMakeMigrationsDialog
2737
2519 dlg = DjangoMakeMigrationsDialog(self.getRecentApplications()) 2738 dlg = DjangoMakeMigrationsDialog(self.getRecentApplications())
2520 if dlg.exec() == QDialog.DialogCode.Accepted: 2739 if dlg.exec() == QDialog.DialogCode.Accepted:
2521 apps, migration, dryRun, empty, merge = dlg.getData() 2740 apps, migration, dryRun, empty, merge = dlg.getData()
2522 if apps: 2741 if apps:
2523 self.setMostRecentApplication(apps) 2742 self.setMostRecentApplication(apps)
2524 apps = apps.split() 2743 apps = apps.split()
2525 self.makeMigrations(apps, migration, dryRun, empty, merge) 2744 self.makeMigrations(apps, migration, dryRun, empty, merge)
2526 2745
2527 def makeMigrations(self, apps, migration=None, dryRun=False, empty=False, 2746 def makeMigrations(
2528 merge=False): 2747 self, apps, migration=None, dryRun=False, empty=False, merge=False
2748 ):
2529 """ 2749 """
2530 Public method to generate migrations. 2750 Public method to generate migrations.
2531 2751
2532 @param apps list of application names to generate migrations for 2752 @param apps list of application names to generate migrations for
2533 @type list of str 2753 @type list of str
2534 @param migration name of the migration to generate 2754 @param migration name of the migration to generate
2535 @type str 2755 @type str
2536 @param dryRun flag indicating a dry run 2756 @param dryRun flag indicating a dry run
2539 @type bool 2759 @type bool
2540 @param merge flag indicating to fix migration conflicts 2760 @param merge flag indicating to fix migration conflicts
2541 @type bool 2761 @type bool
2542 """ 2762 """
2543 title = self.tr("Make Migrations") 2763 title = self.tr("Make Migrations")
2544 2764
2545 try: 2765 try:
2546 path = self.__sitePath() 2766 path = self.__sitePath()
2547 except DjangoNoSiteSelectedException: 2767 except DjangoNoSiteSelectedError:
2548 return 2768 return
2549 2769
2550 args = [] 2770 args = []
2551 args.append(self.__getPythonExecutable()) 2771 args.append(self.__getPythonExecutable())
2552 args.append("manage.py") 2772 args.append("manage.py")
2553 args.append("makemigrations") 2773 args.append("makemigrations")
2554 if migration: 2774 if migration:
2560 args.append("--empty") 2780 args.append("--empty")
2561 if merge: 2781 if merge:
2562 args.append("--merge") 2782 args.append("--merge")
2563 if apps: 2783 if apps:
2564 args += apps 2784 args += apps
2565 2785
2566 dia = DjangoDialog(title, showInput=True) 2786 dia = DjangoDialog(title, showInput=True)
2567 res = dia.startProcess(args, path) 2787 res = dia.startProcess(args, path)
2568 if res: 2788 if res:
2569 dia.exec() 2789 dia.exec()
2570 2790
2571 def __squashMigrations(self): 2791 def __squashMigrations(self):
2572 """ 2792 """
2573 Private slot to squash migrations. 2793 Private slot to squash migrations.
2574 """ 2794 """
2575 migrations = self.__getMigrations() 2795 migrations = self.__getMigrations()
2576 if not migrations: 2796 if not migrations:
2577 EricMessageBox.information( 2797 EricMessageBox.information(
2578 None, 2798 None,
2579 self.tr("Squash Migrations"), 2799 self.tr("Squash Migrations"),
2580 self.tr("""No migrations available.""")) 2800 self.tr("""No migrations available."""),
2801 )
2581 return 2802 return
2582 2803
2583 from .DjangoSquashMigrationSelectionDialog import ( 2804 from .DjangoSquashMigrationSelectionDialog import (
2584 DjangoSquashMigrationSelectionDialog 2805 DjangoSquashMigrationSelectionDialog,
2585 ) 2806 )
2586 dlg = DjangoSquashMigrationSelectionDialog( 2807
2587 migrations, self, self.__iconSuffix) 2808 dlg = DjangoSquashMigrationSelectionDialog(migrations, self, self.__iconSuffix)
2588 if dlg.exec() == QDialog.DialogCode.Accepted: 2809 if dlg.exec() == QDialog.DialogCode.Accepted:
2589 app, start, end, noOptimize, name = dlg.getData() 2810 app, start, end, noOptimize, name = dlg.getData()
2590 2811
2591 title = self.tr("Squash Migrations") 2812 title = self.tr("Squash Migrations")
2592 2813
2593 try: 2814 try:
2594 path = self.__sitePath() 2815 path = self.__sitePath()
2595 except DjangoNoSiteSelectedException: 2816 except DjangoNoSiteSelectedError:
2596 return 2817 return
2597 2818
2598 args = [] 2819 args = []
2599 args.append(self.__getPythonExecutable()) 2820 args.append(self.__getPythonExecutable())
2600 args.append("manage.py") 2821 args.append("manage.py")
2601 args.append("squashmigrations") 2822 args.append("squashmigrations")
2602 args.append("--noinput") 2823 args.append("--noinput")
2606 args.append("--squashed-name={0}".format(name)) 2827 args.append("--squashed-name={0}".format(name))
2607 args.append(app) 2828 args.append(app)
2608 if start: 2829 if start:
2609 args.append(start) 2830 args.append(start)
2610 args.append(end) 2831 args.append(end)
2611 2832
2612 dia = DjangoDialog(title) 2833 dia = DjangoDialog(title)
2613 res = dia.startProcess(args, path) 2834 res = dia.startProcess(args, path)
2614 if res: 2835 if res:
2615 dia.exec() 2836 dia.exec()
2616 2837
2617 ################################################################## 2838 ##################################################################
2618 ## slots below implement some tool functions 2839 ## slots below implement some tool functions
2619 ################################################################## 2840 ##################################################################
2620 2841
2621 def __diffSettings(self): 2842 def __diffSettings(self):
2622 """ 2843 """
2623 Private slot to show the changes made to the settings.py file. 2844 Private slot to show the changes made to the settings.py file.
2624 """ 2845 """
2625 title = self.tr("Diff Settings") 2846 title = self.tr("Diff Settings")
2626 2847
2627 from .DjangoDiffsettingsDataDialog import DjangoDiffsettingsDataDialog 2848 from .DjangoDiffsettingsDataDialog import DjangoDiffsettingsDataDialog
2849
2628 dlg = DjangoDiffsettingsDataDialog(self, self.__ui) 2850 dlg = DjangoDiffsettingsDataDialog(self, self.__ui)
2629 if dlg.exec() == QDialog.DialogCode.Accepted: 2851 if dlg.exec() == QDialog.DialogCode.Accepted:
2630 showAll, defaultModule, outputFormat = dlg.getData() 2852 showAll, defaultModule, outputFormat = dlg.getData()
2631 2853
2632 args = [] 2854 args = []
2633 args.append(self.__getPythonExecutable()) 2855 args.append(self.__getPythonExecutable())
2634 args.append("manage.py") 2856 args.append("manage.py")
2635 args.append("diffsettings") 2857 args.append("diffsettings")
2636 if showAll: 2858 if showAll:
2637 args.append("--all") 2859 args.append("--all")
2638 if defaultModule: 2860 if defaultModule:
2639 args.append("--default={0}".format(defaultModule)) 2861 args.append("--default={0}".format(defaultModule))
2640 if outputFormat: 2862 if outputFormat:
2641 args.append("--output={0}".format(outputFormat)) 2863 args.append("--output={0}".format(outputFormat))
2642 2864
2643 try: 2865 try:
2644 path = self.__sitePath() 2866 path = self.__sitePath()
2645 except DjangoNoSiteSelectedException: 2867 except DjangoNoSiteSelectedError:
2646 return 2868 return
2647 2869
2648 dia = DjangoDialog(title, fixed=True, linewrap=False) 2870 dia = DjangoDialog(title, fixed=True, linewrap=False)
2649 res = dia.startProcess(args, path, False) 2871 res = dia.startProcess(args, path, False)
2650 if res: 2872 if res:
2651 dia.exec() 2873 dia.exec()
2652 2874
2653 def __runPythonShell(self): 2875 def __runPythonShell(self):
2654 """ 2876 """
2655 Private slot to start a Python console for a Django project. 2877 Private slot to start a Python console for a Django project.
2656 """ 2878 """
2657 consoleCmd = self.__isSpawningConsole( 2879 consoleCmd = self.__isSpawningConsole(
2658 self.__plugin.getPreferences("ConsoleCommand"))[1] 2880 self.__plugin.getPreferences("ConsoleCommand")
2881 )[1]
2659 if consoleCmd: 2882 if consoleCmd:
2660 args = Utilities.parseOptionString(consoleCmd) 2883 args = Utilities.parseOptionString(consoleCmd)
2661 args[0] = Utilities.getExecutablePath(args[0]) 2884 args[0] = Utilities.getExecutablePath(args[0])
2662 args.append(self.__getPythonExecutable()) 2885 args.append(self.__getPythonExecutable())
2663 args.append("manage.py") 2886 args.append("manage.py")
2664 args.append("shell") 2887 args.append("shell")
2665 args.append("--interface={0}".format( 2888 args.append(
2666 self.__plugin.getPreferences("Python3ConsoleType"))) 2889 "--interface={0}".format(
2667 with contextlib.suppress(DjangoNoSiteSelectedException): 2890 self.__plugin.getPreferences("Python3ConsoleType")
2891 )
2892 )
2893 with contextlib.suppress(DjangoNoSiteSelectedError):
2668 wd = self.__sitePath() 2894 wd = self.__sitePath()
2669 self.__adjustWorkingDirectory(args, wd) 2895 self.__adjustWorkingDirectory(args, wd)
2670 started, pid = QProcess.startDetached(args[0], args[1:], wd) 2896 started, pid = QProcess.startDetached(args[0], args[1:], wd)
2671 if not started: 2897 if not started:
2672 EricMessageBox.critical( 2898 EricMessageBox.critical(
2673 None, 2899 None,
2674 self.tr('Process Generation Error'), 2900 self.tr("Process Generation Error"),
2675 self.tr('The Django process could not be started.')) 2901 self.tr("The Django process could not be started."),
2676 2902 )
2903
2677 def __sendTestEmail(self): 2904 def __sendTestEmail(self):
2678 """ 2905 """
2679 Private slot to send a test email through Django. 2906 Private slot to send a test email through Django.
2680 """ 2907 """
2681 title = self.tr("Send Test Email") 2908 title = self.tr("Send Test Email")
2682 2909
2683 from .DjangoSendTestEmailDataDialog import ( 2910 from .DjangoSendTestEmailDataDialog import DjangoSendTestEmailDataDialog
2684 DjangoSendTestEmailDataDialog 2911
2685 )
2686 dlg = DjangoSendTestEmailDataDialog(self.__ui) 2912 dlg = DjangoSendTestEmailDataDialog(self.__ui)
2687 if dlg.exec() == QDialog.DialogCode.Accepted: 2913 if dlg.exec() == QDialog.DialogCode.Accepted:
2688 managers, admins, recipients = dlg.getData() 2914 managers, admins, recipients = dlg.getData()
2689 2915
2690 args = [] 2916 args = []
2691 args.append(self.__getPythonExecutable()) 2917 args.append(self.__getPythonExecutable())
2692 args.append("manage.py") 2918 args.append("manage.py")
2693 args.append("sendtestemail") 2919 args.append("sendtestemail")
2694 if managers: 2920 if managers:
2695 args.append("--managers") 2921 args.append("--managers")
2696 if admins: 2922 if admins:
2697 args.append("--admins") 2923 args.append("--admins")
2698 args.extend(recipients) 2924 args.extend(recipients)
2699 2925
2700 try: 2926 try:
2701 path = self.__sitePath() 2927 path = self.__sitePath()
2702 except DjangoNoSiteSelectedException: 2928 except DjangoNoSiteSelectedError:
2703 return 2929 return
2704 2930
2705 dia = DjangoDialog( 2931 dia = DjangoDialog(
2706 title, 2932 title,
2707 linewrap=False, 2933 linewrap=False,
2708 msgSuccess=self.tr("Test Email sent successfully."), 2934 msgSuccess=self.tr("Test Email sent successfully."),
2709 msgError=self.tr("Test Email could not be sent.") 2935 msgError=self.tr("Test Email could not be sent."),
2710 ) 2936 )
2711 res = dia.startProcess(args, path, False) 2937 res = dia.startProcess(args, path, False)
2712 if res: 2938 if res:
2713 dia.exec() 2939 dia.exec()
2714 2940
2715 ################################################################## 2941 ##################################################################
2716 ## slots below implement caching functions 2942 ## slots below implement caching functions
2717 ################################################################## 2943 ##################################################################
2718 2944
2719 def __createCacheTables(self): 2945 def __createCacheTables(self):
2720 """ 2946 """
2721 Private slot to create the tables for the SQL caching backend. 2947 Private slot to create the tables for the SQL caching backend.
2722 """ 2948 """
2723 title = self.tr("Create Cache Tables") 2949 title = self.tr("Create Cache Tables")
2724 2950
2725 try: 2951 try:
2726 wd = self.__sitePath() 2952 wd = self.__sitePath()
2727 except DjangoNoSiteSelectedException: 2953 except DjangoNoSiteSelectedError:
2728 return 2954 return
2729 2955
2730 args = [] 2956 args = []
2731 args.append(self.__getPythonExecutable()) 2957 args.append(self.__getPythonExecutable())
2732 args.append("manage.py") 2958 args.append("manage.py")
2733 args.append("createcachetable") 2959 args.append("createcachetable")
2734 if self.__currentDatabase: 2960 if self.__currentDatabase:
2735 args.append("--database={0}".format(self.__currentDatabase)) 2961 args.append("--database={0}".format(self.__currentDatabase))
2736 2962
2737 dia = DjangoDialog( 2963 dia = DjangoDialog(
2738 title, 2964 title, msgSuccess=self.tr("Cache tables created successfully.")
2739 msgSuccess=self.tr("Cache tables created successfully.")) 2965 )
2740 res = dia.startProcess(args, wd) 2966 res = dia.startProcess(args, wd)
2741 if res: 2967 if res:
2742 dia.exec() 2968 dia.exec()
2743 2969
2744 ################################################################## 2970 ##################################################################
2745 ## slots below implement testing functions 2971 ## slots below implement testing functions
2746 ################################################################## 2972 ##################################################################
2747 2973
2748 def __dumpData(self): 2974 def __dumpData(self):
2749 """ 2975 """
2750 Private slot to dump the database data to a fixture. 2976 Private slot to dump the database data to a fixture.
2751 """ 2977 """
2752 title = self.tr("Dump Data") 2978 title = self.tr("Dump Data")
2753 2979
2754 try: 2980 try:
2755 wd = self.__sitePath() 2981 wd = self.__sitePath()
2756 except DjangoNoSiteSelectedException: 2982 except DjangoNoSiteSelectedError:
2757 return 2983 return
2758 2984
2759 from .DjangoDumpdataDataDialog import DjangoDumpdataDataDialog 2985 from .DjangoDumpdataDataDialog import DjangoDumpdataDataDialog
2986
2760 dlg = DjangoDumpdataDataDialog(self, self.__ui) 2987 dlg = DjangoDumpdataDataDialog(self, self.__ui)
2761 if dlg.exec() == QDialog.DialogCode.Accepted: 2988 if dlg.exec() == QDialog.DialogCode.Accepted:
2762 appls, excls, dumpFormat, indent = dlg.getData() 2989 appls, excls, dumpFormat, indent = dlg.getData()
2763 2990
2764 args = [] 2991 args = []
2765 args.append(self.__getPythonExecutable()) 2992 args.append(self.__getPythonExecutable())
2766 args.append("manage.py") 2993 args.append("manage.py")
2767 args.append("dumpdata") 2994 args.append("dumpdata")
2768 args.append("--format={0}".format(dumpFormat)) 2995 args.append("--format={0}".format(dumpFormat))
2770 for excl in excls: 2997 for excl in excls:
2771 args.append("--exclude={0}".format(excl)) 2998 args.append("--exclude={0}".format(excl))
2772 if self.__currentDatabase: 2999 if self.__currentDatabase:
2773 args.append("--database={0}".format(self.__currentDatabase)) 3000 args.append("--database={0}".format(self.__currentDatabase))
2774 args += appls 3001 args += appls
2775 3002
2776 if dumpFormat == "json": 3003 if dumpFormat == "json":
2777 fileFilters = self.tr("JSON Files (*.json)") 3004 fileFilters = self.tr("JSON Files (*.json)")
2778 elif dumpFormat == "xml": 3005 elif dumpFormat == "xml":
2779 fileFilters = self.tr("XML Files (*.xml)") 3006 fileFilters = self.tr("XML Files (*.xml)")
2780 elif dumpFormat == "yaml": 3007 elif dumpFormat == "yaml":
2781 fileFilters = self.tr("YAML Files (*.yaml)") 3008 fileFilters = self.tr("YAML Files (*.yaml)")
2782 3009
2783 dia = DjangoDialog( 3010 dia = DjangoDialog(
2784 title, fixed=True, linewrap=False, saveFilters=fileFilters) 3011 title, fixed=True, linewrap=False, saveFilters=fileFilters
3012 )
2785 res = dia.startProcess(args, wd, showCommand=False) 3013 res = dia.startProcess(args, wd, showCommand=False)
2786 if res: 3014 if res:
2787 dia.exec() 3015 dia.exec()
2788 3016
2789 def __loadData(self): 3017 def __loadData(self):
2790 """ 3018 """
2791 Private slot to load data from fixture files. 3019 Private slot to load data from fixture files.
2792 """ 3020 """
2793 title = self.tr("Load Data") 3021 title = self.tr("Load Data")
2794 3022
2795 try: 3023 try:
2796 wd = self.__sitePath() 3024 wd = self.__sitePath()
2797 except DjangoNoSiteSelectedException: 3025 except DjangoNoSiteSelectedError:
2798 return 3026 return
2799 3027
2800 from .DjangoLoaddataDataDialog import DjangoLoaddataDataDialog 3028 from .DjangoLoaddataDataDialog import DjangoLoaddataDataDialog
3029
2801 dlg = DjangoLoaddataDataDialog(self, self.__ui) 3030 dlg = DjangoLoaddataDataDialog(self, self.__ui)
2802 if dlg.exec() == QDialog.DialogCode.Accepted: 3031 if dlg.exec() == QDialog.DialogCode.Accepted:
2803 fixtures, excludes, appLabel, ignore = dlg.getData() 3032 fixtures, excludes, appLabel, ignore = dlg.getData()
2804 3033
2805 args = [] 3034 args = []
2806 args.append(self.__getPythonExecutable()) 3035 args.append(self.__getPythonExecutable())
2807 args.append("manage.py") 3036 args.append("manage.py")
2808 args.append("loaddata") 3037 args.append("loaddata")
2809 for excl in excludes: 3038 for excl in excludes:
2813 if appLabel: 3042 if appLabel:
2814 args.append("--app={0}".format(appLabel)) 3043 args.append("--app={0}".format(appLabel))
2815 if self.__currentDatabase: 3044 if self.__currentDatabase:
2816 args.append("--database={0}".format(self.__currentDatabase)) 3045 args.append("--database={0}".format(self.__currentDatabase))
2817 args += fixtures 3046 args += fixtures
2818 3047
2819 dia = DjangoDialog(title) 3048 dia = DjangoDialog(title)
2820 res = dia.startProcess(args, wd) 3049 res = dia.startProcess(args, wd)
2821 if res: 3050 if res:
2822 dia.exec() 3051 dia.exec()
2823 3052
2824 def __runTestSuite(self, deprecation=False): 3053 def __runTestSuite(self, deprecation=False):
2825 """ 3054 """
2826 Private slot to run the test suite for applications or the whole site. 3055 Private slot to run the test suite for applications or the whole site.
2827 3056
2828 @param deprecation flag indicating to test for deprecation warnings 3057 @param deprecation flag indicating to test for deprecation warnings
2829 @type bool 3058 @type bool
2830 """ 3059 """
2831 consoleCmd = self.__isSpawningConsole( 3060 consoleCmd = self.__isSpawningConsole(
2832 self.__plugin.getPreferences("ConsoleCommandNoClose"))[1] 3061 self.__plugin.getPreferences("ConsoleCommandNoClose")
3062 )[1]
2833 if consoleCmd: 3063 if consoleCmd:
2834 try: 3064 try:
2835 wd = self.__sitePath() 3065 wd = self.__sitePath()
2836 except DjangoNoSiteSelectedException: 3066 except DjangoNoSiteSelectedError:
2837 return 3067 return
2838 3068
2839 from .DjangoTestDataDialog import DjangoTestDataDialog 3069 from .DjangoTestDataDialog import DjangoTestDataDialog
3070
2840 dlg = DjangoTestDataDialog( 3071 dlg = DjangoTestDataDialog(
2841 self, self.__plugin.getPreferences("KeepTestDatabase"), 3072 self, self.__plugin.getPreferences("KeepTestDatabase"), self.__ui
2842 self.__ui) 3073 )
2843 if dlg.exec() == QDialog.DialogCode.Accepted: 3074 if dlg.exec() == QDialog.DialogCode.Accepted:
2844 labels, pattern, tags, excludeTags, keep, reverse = ( 3075 labels, pattern, tags, excludeTags, keep, reverse = dlg.getData()
2845 dlg.getData()) 3076
2846
2847 self.__plugin.setPreferences("KeepTestDatabase", keep) 3077 self.__plugin.setPreferences("KeepTestDatabase", keep)
2848 3078
2849 args = Utilities.parseOptionString(consoleCmd) 3079 args = Utilities.parseOptionString(consoleCmd)
2850 args[0] = Utilities.getExecutablePath(args[0]) 3080 args[0] = Utilities.getExecutablePath(args[0])
2851 args.append(self.__getPythonExecutable()) 3081 args.append(self.__getPythonExecutable())
2852 if deprecation: 3082 if deprecation:
2853 args.append("-Wall") 3083 args.append("-Wall")
2862 if keep: 3092 if keep:
2863 args.append("--keepdb") 3093 args.append("--keepdb")
2864 if reverse: 3094 if reverse:
2865 args.append("--reverse") 3095 args.append("--reverse")
2866 args.extend(labels) 3096 args.extend(labels)
2867 3097
2868 self.__adjustWorkingDirectory(args, wd) 3098 self.__adjustWorkingDirectory(args, wd)
2869 started, pid = QProcess.startDetached(args[0], args[1:], wd) 3099 started, pid = QProcess.startDetached(args[0], args[1:], wd)
2870 if not started: 3100 if not started:
2871 EricMessageBox.critical( 3101 EricMessageBox.critical(
2872 None, 3102 None,
2873 self.tr('Process Generation Error'), 3103 self.tr("Process Generation Error"),
2874 self.tr('The Django process could not be started.')) 3104 self.tr("The Django process could not be started."),
2875 3105 )
3106
2876 def __runTestServer(self): 3107 def __runTestServer(self):
2877 """ 3108 """
2878 Private slot to run a development server with data from a set of 3109 Private slot to run a development server with data from a set of
2879 fixtures. 3110 fixtures.
2880 """ 3111 """
2881 consoleCmd = self.__isSpawningConsole( 3112 consoleCmd = self.__isSpawningConsole(
2882 self.__plugin.getPreferences("ConsoleCommand"))[1] 3113 self.__plugin.getPreferences("ConsoleCommand")
3114 )[1]
2883 if consoleCmd: 3115 if consoleCmd:
2884 from .DjangoRunTestServerDataDialog import ( 3116 from .DjangoRunTestServerDataDialog import DjangoRunTestServerDataDialog
2885 DjangoRunTestServerDataDialog 3117
2886 )
2887 dlg = DjangoRunTestServerDataDialog(self, self.__ui) 3118 dlg = DjangoRunTestServerDataDialog(self, self.__ui)
2888 if dlg.exec() == QDialog.DialogCode.Accepted: 3119 if dlg.exec() == QDialog.DialogCode.Accepted:
2889 fixtures = dlg.getData() 3120 fixtures = dlg.getData()
2890 3121
2891 args = Utilities.parseOptionString(consoleCmd) 3122 args = Utilities.parseOptionString(consoleCmd)
2892 args[0] = Utilities.getExecutablePath(args[0]) 3123 args[0] = Utilities.getExecutablePath(args[0])
2893 args.append(self.__getPythonExecutable()) 3124 args.append(self.__getPythonExecutable())
2894 args.append("manage.py") 3125 args.append("manage.py")
2895 args.append("testserver") 3126 args.append("testserver")
2897 args.append("--ipv6") 3128 args.append("--ipv6")
2898 addr = self.__plugin.getPreferences("ServerAddress") 3129 addr = self.__plugin.getPreferences("ServerAddress")
2899 if addr: 3130 if addr:
2900 args.append("--addrport={0}".format(addr)) 3131 args.append("--addrport={0}".format(addr))
2901 args += fixtures 3132 args += fixtures
2902 3133
2903 with contextlib.suppress(DjangoNoSiteSelectedException): 3134 with contextlib.suppress(DjangoNoSiteSelectedError):
2904 if Utilities.isWindowsPlatform(): 3135 if Utilities.isWindowsPlatform():
2905 serverProcStarted, pid = QProcess.startDetached( 3136 serverProcStarted, pid = QProcess.startDetached(
2906 args[0], args[1:], self.__sitePath()) 3137 args[0], args[1:], self.__sitePath()
3138 )
2907 else: 3139 else:
2908 if self.__testServerProc is not None: 3140 if self.__testServerProc is not None:
2909 self.__testServerProcFinished() 3141 self.__testServerProcFinished()
2910 3142
2911 self.__testServerProc = QProcess() 3143 self.__testServerProc = QProcess()
2912 self.__testServerProc.finished.connect( 3144 self.__testServerProc.finished.connect(
2913 self.__serverProcFinished) 3145 self.__serverProcFinished
2914 self.__testServerProc.setWorkingDirectory( 3146 )
2915 self.__sitePath()) 3147 self.__testServerProc.setWorkingDirectory(self.__sitePath())
2916 self.__testServerProc.start(args[0], args[1:]) 3148 self.__testServerProc.start(args[0], args[1:])
2917 serverProcStarted = ( 3149 serverProcStarted = self.__testServerProc.waitForStarted()
2918 self.__testServerProc.waitForStarted())
2919 if not serverProcStarted: 3150 if not serverProcStarted:
2920 EricMessageBox.critical( 3151 EricMessageBox.critical(
2921 None, 3152 None,
2922 self.tr('Process Generation Error'), 3153 self.tr("Process Generation Error"),
2923 self.tr('The Django test server could not be' 3154 self.tr("The Django test server could not be" " started."),
2924 ' started.')) 3155 )
2925 3156
2926 def __testServerProcFinished(self): 3157 def __testServerProcFinished(self):
2927 """ 3158 """
2928 Private slot connected to the finished signal of the test server. 3159 Private slot connected to the finished signal of the test server.
2929 """ 3160 """
2930 if ( 3161 if (
2931 self.__testServerProc is not None and 3162 self.__testServerProc is not None
2932 self.__testServerProc.state() != QProcess.ProcessState.NotRunning 3163 and self.__testServerProc.state() != QProcess.ProcessState.NotRunning
2933 ): 3164 ):
2934 self.__testServerProc.terminate() 3165 self.__testServerProc.terminate()
2935 QTimer.singleShot(2000, self.__testServerProc.kill) 3166 QTimer.singleShot(2000, self.__testServerProc.kill)
2936 self.__testServerProc.waitForFinished(3000) 3167 self.__testServerProc.waitForFinished(3000)
2937 self.__testServerProc = None 3168 self.__testServerProc = None
2938 3169
2939 ################################################################## 3170 ##################################################################
2940 ## slots below implement authorization functions 3171 ## slots below implement authorization functions
2941 ################################################################## 3172 ##################################################################
2942 3173
2943 def __changePassword(self): 3174 def __changePassword(self):
2944 """ 3175 """
2945 Private slot to change the password of a user. 3176 Private slot to change the password of a user.
2946 """ 3177 """
2947 consoleCmd = self.__isSpawningConsole( 3178 consoleCmd = self.__isSpawningConsole(
2948 self.__plugin.getPreferences("ConsoleCommandNoClose"))[1] 3179 self.__plugin.getPreferences("ConsoleCommandNoClose")
3180 )[1]
2949 if consoleCmd: 3181 if consoleCmd:
2950 userName, ok = QInputDialog.getText( 3182 userName, ok = QInputDialog.getText(
2951 self.__ui, 3183 self.__ui,
2952 self.tr("Change Password"), 3184 self.tr("Change Password"),
2953 self.tr("Enter the name of the user:"), 3185 self.tr("Enter the name of the user:"),
2954 QLineEdit.EchoMode.Normal) 3186 QLineEdit.EchoMode.Normal,
3187 )
2955 if ok and userName != "": 3188 if ok and userName != "":
2956 args = Utilities.parseOptionString(consoleCmd) 3189 args = Utilities.parseOptionString(consoleCmd)
2957 args[0] = Utilities.getExecutablePath(args[0]) 3190 args[0] = Utilities.getExecutablePath(args[0])
2958 args.append(self.__getPythonExecutable()) 3191 args.append(self.__getPythonExecutable())
2959 args.append("manage.py") 3192 args.append("manage.py")
2960 args.append("changepassword") 3193 args.append("changepassword")
2961 args.append(userName) 3194 args.append(userName)
2962 with contextlib.suppress(DjangoNoSiteSelectedException): 3195 with contextlib.suppress(DjangoNoSiteSelectedError):
2963 wd = self.__sitePath() 3196 wd = self.__sitePath()
2964 self.__adjustWorkingDirectory(args, wd) 3197 self.__adjustWorkingDirectory(args, wd)
2965 started, pid = QProcess.startDetached( 3198 started, pid = QProcess.startDetached(args[0], args[1:], wd)
2966 args[0], args[1:], wd)
2967 if not started: 3199 if not started:
2968 EricMessageBox.critical( 3200 EricMessageBox.critical(
2969 None, 3201 None,
2970 self.tr('Process Generation Error'), 3202 self.tr("Process Generation Error"),
2971 self.tr('The Django process could not be' 3203 self.tr("The Django process could not be" " started."),
2972 ' started.')) 3204 )
2973 3205
2974 def __createSuperUser(self): 3206 def __createSuperUser(self):
2975 """ 3207 """
2976 Private slot to create a super user account. 3208 Private slot to create a super user account.
2977 """ 3209 """
2978 consoleCmd = self.__isSpawningConsole( 3210 consoleCmd = self.__isSpawningConsole(
2979 self.__plugin.getPreferences("ConsoleCommandNoClose"))[1] 3211 self.__plugin.getPreferences("ConsoleCommandNoClose")
3212 )[1]
2980 if consoleCmd: 3213 if consoleCmd:
2981 args = Utilities.parseOptionString(consoleCmd) 3214 args = Utilities.parseOptionString(consoleCmd)
2982 args[0] = Utilities.getExecutablePath(args[0]) 3215 args[0] = Utilities.getExecutablePath(args[0])
2983 args.append(self.__getPythonExecutable()) 3216 args.append(self.__getPythonExecutable())
2984 args.append("manage.py") 3217 args.append("manage.py")
2985 args.append("createsuperuser") 3218 args.append("createsuperuser")
2986 with contextlib.suppress(DjangoNoSiteSelectedException): 3219 with contextlib.suppress(DjangoNoSiteSelectedError):
2987 wd = self.__sitePath() 3220 wd = self.__sitePath()
2988 self.__adjustWorkingDirectory(args, wd) 3221 self.__adjustWorkingDirectory(args, wd)
2989 started, pid = QProcess.startDetached(args[0], args[1:], wd) 3222 started, pid = QProcess.startDetached(args[0], args[1:], wd)
2990 if not started: 3223 if not started:
2991 EricMessageBox.critical( 3224 EricMessageBox.critical(
2992 None, 3225 None,
2993 self.tr('Process Generation Error'), 3226 self.tr("Process Generation Error"),
2994 self.tr('The Django process could not be started.')) 3227 self.tr("The Django process could not be started."),
2995 3228 )
3229
2996 ################################################################## 3230 ##################################################################
2997 ## slots below implement session functions 3231 ## slots below implement session functions
2998 ################################################################## 3232 ##################################################################
2999 3233
3000 def __clearSessions(self): 3234 def __clearSessions(self):
3001 """ 3235 """
3002 Private slot to clear expired sessions. 3236 Private slot to clear expired sessions.
3003 """ 3237 """
3004 title = self.tr("Clear Sessions") 3238 title = self.tr("Clear Sessions")
3005 3239
3006 try: 3240 try:
3007 wd = self.__sitePath() 3241 wd = self.__sitePath()
3008 except DjangoNoSiteSelectedException: 3242 except DjangoNoSiteSelectedError:
3009 return 3243 return
3010 3244
3011 args = [] 3245 args = []
3012 args.append(self.__getPythonExecutable()) 3246 args.append(self.__getPythonExecutable())
3013 args.append("manage.py") 3247 args.append("manage.py")
3014 args.append("clearsessions") 3248 args.append("clearsessions")
3015 3249
3016 dia = DjangoDialog( 3250 dia = DjangoDialog(
3017 title, 3251 title, msgSuccess=self.tr("Expired sessions cleared successfully.")
3018 msgSuccess=self.tr("Expired sessions cleared successfully.")) 3252 )
3019 res = dia.startProcess(args, wd) 3253 res = dia.startProcess(args, wd)
3020 if res: 3254 if res:
3021 dia.exec() 3255 dia.exec()
3022 3256
3023 ################################################################## 3257 ##################################################################
3024 ## slots below implement translation functions 3258 ## slots below implement translation functions
3025 ################################################################## 3259 ##################################################################
3026 3260
3027 def __getLocale(self, filename): 3261 def __getLocale(self, filename):
3028 """ 3262 """
3029 Private method to extract the locale out of a file name. 3263 Private method to extract the locale out of a file name.
3030 3264
3031 @param filename name of the file used for extraction 3265 @param filename name of the file used for extraction
3032 @type str 3266 @type str
3033 @return extracted locale or None 3267 @return extracted locale or None
3034 @rtype str 3268 @rtype str
3035 """ 3269 """
3036 if self.__ericProject.getTranslationPattern(): 3270 if self.__ericProject.getTranslationPattern():
3037 pattern = ( 3271 pattern = self.__ericProject.getTranslationPattern().replace(
3038 self.__ericProject.getTranslationPattern() 3272 "%language%", "(.*?)"
3039 .replace("%language%", "(.*?)")
3040 ) 3273 )
3041 match = re.search(pattern, filename) 3274 match = re.search(pattern, filename)
3042 if match is not None: 3275 if match is not None:
3043 loc = match.group(1) 3276 loc = match.group(1)
3044 return loc 3277 return loc
3045 else: 3278 else:
3046 loc = None 3279 loc = None
3047 else: 3280 else:
3048 loc = None 3281 loc = None
3049 3282
3050 return loc 3283 return loc
3051 3284
3052 def __normalizeList(self, filenames): 3285 def __normalizeList(self, filenames):
3053 """ 3286 """
3054 Private method to normalize a list of file names. 3287 Private method to normalize a list of file names.
3055 3288
3056 @param filenames list of file names to normalize 3289 @param filenames list of file names to normalize
3057 @type list of str 3290 @type list of str
3058 @return normalized file names 3291 @return normalized file names
3059 @rtype list of str 3292 @rtype list of str
3060 """ 3293 """
3062 for filename in filenames: 3295 for filename in filenames:
3063 if filename.endswith(".mo"): 3296 if filename.endswith(".mo"):
3064 filename = filename.replace(".mo", ".po") 3297 filename = filename.replace(".mo", ".po")
3065 if filename not in nfilenames: 3298 if filename not in nfilenames:
3066 nfilenames.append(filename) 3299 nfilenames.append(filename)
3067 3300
3068 return nfilenames 3301 return nfilenames
3069 3302
3070 def __siteFilteredList(self, filenames): 3303 def __siteFilteredList(self, filenames):
3071 """ 3304 """
3072 Private method to filter a list of file names by site. 3305 Private method to filter a list of file names by site.
3073 3306
3074 @param filenames list of file names to be filtered 3307 @param filenames list of file names to be filtered
3075 @type list of str 3308 @type list of str
3076 @return file names belonging to the current site 3309 @return file names belonging to the current site
3077 @rtype list of str 3310 @rtype list of str
3078 """ 3311 """
3079 site = self.__site() 3312 site = self.__site()
3080 nfilenames = [] 3313 nfilenames = []
3081 for filename in filenames: 3314 for filename in filenames:
3082 if site == "" or filename.startswith(site + os.sep): 3315 if site == "" or filename.startswith(site + os.sep):
3083 nfilenames.append(filename) 3316 nfilenames.append(filename)
3084 3317
3085 return nfilenames 3318 return nfilenames
3086 3319
3087 def __projectLanguageAdded(self, code): 3320 def __projectLanguageAdded(self, code):
3088 """ 3321 """
3089 Private slot handling the addition of a new language. 3322 Private slot handling the addition of a new language.
3090 3323
3091 @param code language code of the new language 3324 @param code language code of the new language
3092 @type str 3325 @type str
3093 """ 3326 """
3094 title = ( 3327 title = self.tr("Initializing message catalog for '{0}'").format(code)
3095 self.tr("Initializing message catalog for '{0}'") 3328
3096 .format(code)
3097 )
3098
3099 args = [] 3329 args = []
3100 args.append(self.__getPythonExecutable()) 3330 args.append(self.__getPythonExecutable())
3101 args.append("manage.py") 3331 args.append("manage.py")
3102 args.append("makemessages") 3332 args.append("makemessages")
3103 args.append("--locale={0}".format(code)) 3333 args.append("--locale={0}".format(code))
3104 3334
3105 try: 3335 try:
3106 wd = self.__sitePath() 3336 wd = self.__sitePath()
3107 except DjangoNoSiteSelectedException: 3337 except DjangoNoSiteSelectedError:
3108 EricMessageBox.warning( 3338 EricMessageBox.warning(
3109 None, 3339 None,
3110 title, 3340 title,
3111 self.tr('No current site selected or no site created yet.' 3341 self.tr(
3112 ' Aborting...')) 3342 "No current site selected or no site created yet." " Aborting..."
3343 ),
3344 )
3113 return 3345 return
3114 3346
3115 dia = DjangoDialog( 3347 dia = DjangoDialog(
3116 title, 3348 title, msgSuccess=self.tr("\nMessage catalog initialized successfully.")
3117 msgSuccess=self.tr( 3349 )
3118 "\nMessage catalog initialized successfully."))
3119 res = dia.startProcess(args, wd) 3350 res = dia.startProcess(args, wd)
3120 if res: 3351 if res:
3121 dia.exec() 3352 dia.exec()
3122 3353
3123 langFile = ( 3354 langFile = self.__ericProject.getTranslationPattern().replace(
3124 self.__ericProject.getTranslationPattern() 3355 "%language%", code
3125 .replace("%language%", code)
3126 ) 3356 )
3127 self.__ericProject.appendFile(langFile) 3357 self.__ericProject.appendFile(langFile)
3128 3358
3129 def updateSelectedCatalogs(self, filenames): 3359 def updateSelectedCatalogs(self, filenames):
3130 """ 3360 """
3131 Public method to update the message catalogs. 3361 Public method to update the message catalogs.
3132 3362
3133 @param filenames list of file names 3363 @param filenames list of file names
3134 @type list of str 3364 @type list of str
3135 """ 3365 """
3136 title = self.tr("Updating message catalogs") 3366 title = self.tr("Updating message catalogs")
3137 3367
3138 try: 3368 try:
3139 wd = self.__sitePath() 3369 wd = self.__sitePath()
3140 except DjangoNoSiteSelectedException: 3370 except DjangoNoSiteSelectedError:
3141 EricMessageBox.warning( 3371 EricMessageBox.warning(
3142 None, 3372 None,
3143 title, 3373 title,
3144 self.tr('No current site selected or no site created yet.' 3374 self.tr(
3145 ' Aborting...')) 3375 "No current site selected or no site created yet." " Aborting..."
3376 ),
3377 )
3146 return 3378 return
3147 3379
3148 argsLists = [] 3380 argsLists = []
3149 3381
3150 for filename in self.__normalizeList( 3382 for filename in self.__normalizeList(self.__siteFilteredList(filenames)):
3151 self.__siteFilteredList(filenames)):
3152 locale = self.__getLocale(filename) 3383 locale = self.__getLocale(filename)
3153 if locale: 3384 if locale:
3154 args = [] 3385 args = []
3155 args.append(self.__getPythonExecutable()) 3386 args.append(self.__getPythonExecutable())
3156 args.append("manage.py") 3387 args.append("manage.py")
3157 args.append("makemessages") 3388 args.append("makemessages")
3158 args.append("--no-obsolete") 3389 args.append("--no-obsolete")
3159 args.append("--locale={0}".format(locale)) 3390 args.append("--locale={0}".format(locale))
3160 argsLists.append(args) 3391 argsLists.append(args)
3161 3392
3162 if len(argsLists) == 0: 3393 if len(argsLists) == 0:
3394 EricMessageBox.warning(
3395 None, title, self.tr("No locales detected. Aborting...")
3396 )
3397 return
3398
3399 dia = DjangoDialog(
3400 title, msgSuccess=self.tr("\nMessage catalogs updated successfully.")
3401 )
3402 res = dia.startBatchProcesses(argsLists, wd)
3403 if res:
3404 dia.exec()
3405
3406 def updateSelectedCatalogsWithObsolete(self, filenames):
3407 """
3408 Public method to update the message catalogs keeping obsolete messages.
3409
3410 @param filenames list of filenames
3411 @type list of str
3412 """
3413 title = self.tr("Updating message catalogs (keeping obsolete" " messages)")
3414
3415 try:
3416 wd = self.__sitePath()
3417 except DjangoNoSiteSelectedError:
3163 EricMessageBox.warning( 3418 EricMessageBox.warning(
3164 None, 3419 None,
3165 title, 3420 title,
3166 self.tr('No locales detected. Aborting...')) 3421 self.tr(
3422 "No current site selected or no site created yet." " Aborting..."
3423 ),
3424 )
3167 return 3425 return
3168 3426
3169 dia = DjangoDialog(
3170 title,
3171 msgSuccess=self.tr("\nMessage catalogs updated successfully."))
3172 res = dia.startBatchProcesses(argsLists, wd)
3173 if res:
3174 dia.exec()
3175
3176 def updateSelectedCatalogsWithObsolete(self, filenames):
3177 """
3178 Public method to update the message catalogs keeping obsolete messages.
3179
3180 @param filenames list of filenames
3181 @type list of str
3182 """
3183 title = self.tr("Updating message catalogs (keeping obsolete"
3184 " messages)")
3185
3186 try:
3187 wd = self.__sitePath()
3188 except DjangoNoSiteSelectedException:
3189 EricMessageBox.warning(
3190 None,
3191 title,
3192 self.tr('No current site selected or no site created yet.'
3193 ' Aborting...'))
3194 return
3195
3196 argsLists = [] 3427 argsLists = []
3197 3428
3198 for filename in self.__normalizeList( 3429 for filename in self.__normalizeList(self.__siteFilteredList(filenames)):
3199 self.__siteFilteredList(filenames)):
3200 locale = self.__getLocale(filename) 3430 locale = self.__getLocale(filename)
3201 if locale: 3431 if locale:
3202 args = [] 3432 args = []
3203 args.append(self.__getPythonExecutable()) 3433 args.append(self.__getPythonExecutable())
3204 args.append("manage.py") 3434 args.append("manage.py")
3205 args.append("makemessages") 3435 args.append("makemessages")
3206 args.append("--locale={0}".format(locale)) 3436 args.append("--locale={0}".format(locale))
3207 argsLists.append(args) 3437 argsLists.append(args)
3208 3438
3209 if len(argsLists) == 0: 3439 if len(argsLists) == 0:
3210 EricMessageBox.warning( 3440 EricMessageBox.warning(
3211 None, 3441 None, title, self.tr("No locales detected. Aborting...")
3212 title, 3442 )
3213 self.tr('No locales detected. Aborting...'))
3214 return 3443 return
3215 3444
3216 dia = DjangoDialog( 3445 dia = DjangoDialog(
3217 title, 3446 title, msgSuccess=self.tr("\nMessage catalogs updated successfully.")
3218 msgSuccess=self.tr("\nMessage catalogs updated successfully.")) 3447 )
3219 res = dia.startBatchProcesses(argsLists, wd) 3448 res = dia.startBatchProcesses(argsLists, wd)
3220 if res: 3449 if res:
3221 dia.exec() 3450 dia.exec()
3222 3451
3223 def updateCatalogs(self, filenames): 3452 def updateCatalogs(self, filenames):
3224 """ 3453 """
3225 Public method to update the message catalogs. 3454 Public method to update the message catalogs.
3226 3455
3227 @param filenames list of filenames (not used) 3456 @param filenames list of filenames (not used)
3228 @type list of str 3457 @type list of str
3229 """ 3458 """
3230 title = self.tr("Updating message catalogs") 3459 title = self.tr("Updating message catalogs")
3231 3460
3232 args = [] 3461 args = []
3233 args.append(self.__getPythonExecutable()) 3462 args.append(self.__getPythonExecutable())
3234 args.append("manage.py") 3463 args.append("manage.py")
3235 args.append("makemessages") 3464 args.append("makemessages")
3236 args.append("--all") 3465 args.append("--all")
3237 args.append("--no-obsolete") 3466 args.append("--no-obsolete")
3238 3467
3239 try: 3468 try:
3240 wd = self.__sitePath() 3469 wd = self.__sitePath()
3241 except DjangoNoSiteSelectedException: 3470 except DjangoNoSiteSelectedError:
3242 EricMessageBox.warning( 3471 EricMessageBox.warning(
3243 None, 3472 None,
3244 title, 3473 title,
3245 self.tr('No current site selected or no site created yet.' 3474 self.tr(
3246 ' Aborting...')) 3475 "No current site selected or no site created yet." " Aborting..."
3476 ),
3477 )
3247 return 3478 return
3248 3479
3249 dia = DjangoDialog( 3480 dia = DjangoDialog(
3250 title, 3481 title, msgSuccess=self.tr("\nMessage catalogs updated successfully.")
3251 msgSuccess=self.tr("\nMessage catalogs updated successfully.")) 3482 )
3252 res = dia.startProcess(args, wd) 3483 res = dia.startProcess(args, wd)
3253 if res: 3484 if res:
3254 dia.exec() 3485 dia.exec()
3255 3486
3256 def updateCatalogsWithObsolete(self, filenames): 3487 def updateCatalogsWithObsolete(self, filenames):
3257 """ 3488 """
3258 Public method to update the message catalogs keeping obsolete messages. 3489 Public method to update the message catalogs keeping obsolete messages.
3259 3490
3260 @param filenames list of filenames (not used) 3491 @param filenames list of filenames (not used)
3261 @type list of str 3492 @type list of str
3262 """ 3493 """
3263 title = self.tr("Updating message catalogs (keeping obsolete" 3494 title = self.tr("Updating message catalogs (keeping obsolete" " messages)")
3264 " messages)") 3495
3265
3266 args = [] 3496 args = []
3267 args.append(self.__getPythonExecutable()) 3497 args.append(self.__getPythonExecutable())
3268 args.append("manage.py") 3498 args.append("manage.py")
3269 args.append("makemessages") 3499 args.append("makemessages")
3270 args.append("--all") 3500 args.append("--all")
3271 3501
3272 try: 3502 try:
3273 wd = self.__sitePath() 3503 wd = self.__sitePath()
3274 except DjangoNoSiteSelectedException: 3504 except DjangoNoSiteSelectedError:
3275 EricMessageBox.warning( 3505 EricMessageBox.warning(
3276 None, 3506 None,
3277 title, 3507 title,
3278 self.tr('No current site selected or no site created yet.' 3508 self.tr(
3279 ' Aborting...')) 3509 "No current site selected or no site created yet." " Aborting..."
3510 ),
3511 )
3280 return 3512 return
3281 3513
3282 dia = DjangoDialog( 3514 dia = DjangoDialog(
3283 title, 3515 title, msgSuccess=self.tr("\nMessage catalogs updated successfully.")
3284 msgSuccess=self.tr("\nMessage catalogs updated successfully.")) 3516 )
3285 res = dia.startProcess(args, wd) 3517 res = dia.startProcess(args, wd)
3286 if res: 3518 if res:
3287 dia.exec() 3519 dia.exec()
3288 3520
3289 def compileSelectedCatalogs(self, filenames): 3521 def compileSelectedCatalogs(self, filenames):
3290 """ 3522 """
3291 Public method to update the message catalogs. 3523 Public method to update the message catalogs.
3292 3524
3293 @param filenames list of filenames 3525 @param filenames list of filenames
3294 @type list of str 3526 @type list of str
3295 """ 3527 """
3296 title = self.tr("Compiling message catalogs") 3528 title = self.tr("Compiling message catalogs")
3297 3529
3298 try: 3530 try:
3299 wd = self.__sitePath() 3531 wd = self.__sitePath()
3300 except DjangoNoSiteSelectedException: 3532 except DjangoNoSiteSelectedError:
3301 EricMessageBox.warning( 3533 EricMessageBox.warning(
3302 None, 3534 None,
3303 title, 3535 title,
3304 self.tr('No current site selected or no site created yet.' 3536 self.tr(
3305 ' Aborting...')) 3537 "No current site selected or no site created yet." " Aborting..."
3538 ),
3539 )
3306 return 3540 return
3307 3541
3308 argsLists = [] 3542 argsLists = []
3309 3543
3310 for filename in self.__normalizeList( 3544 for filename in self.__normalizeList(self.__siteFilteredList(filenames)):
3311 self.__siteFilteredList(filenames)):
3312 locale = self.__getLocale(filename) 3545 locale = self.__getLocale(filename)
3313 if locale: 3546 if locale:
3314 args = [] 3547 args = []
3315 args.append(self.__getPythonExecutable()) 3548 args.append(self.__getPythonExecutable())
3316 args.append("manage.py") 3549 args.append("manage.py")
3317 args.append("compilemessages") 3550 args.append("compilemessages")
3318 args.append("--locale={0}".format(locale)) 3551 args.append("--locale={0}".format(locale))
3319 if self.__plugin.getPreferences("FuzzyTranslations"): 3552 if self.__plugin.getPreferences("FuzzyTranslations"):
3320 args.append("--use-fuzzy") 3553 args.append("--use-fuzzy")
3321 argsLists.append(args) 3554 argsLists.append(args)
3322 3555
3323 if len(argsLists) == 0: 3556 if len(argsLists) == 0:
3324 EricMessageBox.warning( 3557 EricMessageBox.warning(
3325 None, 3558 None, title, self.tr("No locales detected. Aborting...")
3326 title, 3559 )
3327 self.tr('No locales detected. Aborting...'))
3328 return 3560 return
3329 3561
3330 dia = DjangoDialog( 3562 dia = DjangoDialog(
3331 title, 3563 title, msgSuccess=self.tr("\nMessage catalogs compiled successfully.")
3332 msgSuccess=self.tr( 3564 )
3333 "\nMessage catalogs compiled successfully."))
3334 res = dia.startBatchProcesses(argsLists, wd, mergedOutput=True) 3565 res = dia.startBatchProcesses(argsLists, wd, mergedOutput=True)
3335 if res: 3566 if res:
3336 dia.exec() 3567 dia.exec()
3337 3568
3338 for entry in os.walk(self.__sitePath()): 3569 for entry in os.walk(self.__sitePath()):
3339 for fileName in entry[2]: 3570 for fileName in entry[2]:
3340 fullName = os.path.join(entry[0], fileName) 3571 fullName = os.path.join(entry[0], fileName)
3341 if fullName.endswith('.mo'): 3572 if fullName.endswith(".mo"):
3342 self.__ericProject.appendFile(fullName) 3573 self.__ericProject.appendFile(fullName)
3343 3574
3344 def compileCatalogs(self, filenames): 3575 def compileCatalogs(self, filenames):
3345 """ 3576 """
3346 Public method to compile the message catalogs. 3577 Public method to compile the message catalogs.
3347 3578
3348 @param filenames list of filenames (not used) 3579 @param filenames list of filenames (not used)
3349 @type list of str 3580 @type list of str
3350 """ 3581 """
3351 title = self.tr("Compiling message catalogs") 3582 title = self.tr("Compiling message catalogs")
3352 3583
3353 args = [] 3584 args = []
3354 args.append(self.__getPythonExecutable()) 3585 args.append(self.__getPythonExecutable())
3355 args.append("manage.py") 3586 args.append("manage.py")
3356 args.append("compilemessages") 3587 args.append("compilemessages")
3357 if self.__plugin.getPreferences("FuzzyTranslations"): 3588 if self.__plugin.getPreferences("FuzzyTranslations"):
3358 args.append("--use-fuzzy") 3589 args.append("--use-fuzzy")
3359 3590
3360 try: 3591 try:
3361 wd = self.__sitePath() 3592 wd = self.__sitePath()
3362 except DjangoNoSiteSelectedException: 3593 except DjangoNoSiteSelectedError:
3363 EricMessageBox.warning( 3594 EricMessageBox.warning(
3364 None, 3595 None,
3365 title, 3596 title,
3366 self.tr('No current site selected or no site created yet.' 3597 self.tr(
3367 ' Aborting...')) 3598 "No current site selected or no site created yet." " Aborting..."
3599 ),
3600 )
3368 return 3601 return
3369 3602
3370 dia = DjangoDialog( 3603 dia = DjangoDialog(
3371 title, 3604 title, msgSuccess=self.tr("\nMessage catalogs compiled successfully.")
3372 msgSuccess=self.tr( 3605 )
3373 "\nMessage catalogs compiled successfully."))
3374 res = dia.startProcess(args, wd, mergedOutput=True) 3606 res = dia.startProcess(args, wd, mergedOutput=True)
3375 if res: 3607 if res:
3376 dia.exec() 3608 dia.exec()
3377 3609
3378 for entry in os.walk(self.__sitePath()): 3610 for entry in os.walk(self.__sitePath()):
3379 for fileName in entry[2]: 3611 for fileName in entry[2]:
3380 fullName = os.path.join(entry[0], fileName) 3612 fullName = os.path.join(entry[0], fileName)
3381 if fullName.endswith('.mo'): 3613 if fullName.endswith(".mo"):
3382 self.__ericProject.appendFile(fullName) 3614 self.__ericProject.appendFile(fullName)
3383 3615
3384 def openPOEditor(self, poFile): 3616 def openPOEditor(self, poFile):
3385 """ 3617 """
3386 Public method to edit the given file in an external .po editor. 3618 Public method to edit the given file in an external .po editor.
3387 3619
3388 @param poFile name of the .po file 3620 @param poFile name of the .po file
3389 @type str 3621 @type str
3390 """ 3622 """
3391 editor = self.__plugin.getPreferences("TranslationsEditor") 3623 editor = self.__plugin.getPreferences("TranslationsEditor")
3392 if poFile.endswith(".po") and editor: 3624 if poFile.endswith(".po") and editor:
3393 try: 3625 try:
3394 wd = self.__sitePath() 3626 wd = self.__sitePath()
3395 except DjangoNoSiteSelectedException: 3627 except DjangoNoSiteSelectedError:
3396 wd = "" 3628 wd = ""
3397 started, pid = QProcess.startDetached(editor, [poFile], wd) 3629 started, pid = QProcess.startDetached(editor, [poFile], wd)
3398 if not started: 3630 if not started:
3399 EricMessageBox.critical( 3631 EricMessageBox.critical(
3400 None, 3632 None,
3401 self.tr('Process Generation Error'), 3633 self.tr("Process Generation Error"),
3402 self.tr('The translations editor process ({0}) could' 3634 self.tr(
3403 ' not be started.') 3635 "The translations editor process ({0}) could" " not be started."
3404 .format(os.path.basename(editor))) 3636 ).format(os.path.basename(editor)),
3405 3637 )
3638
3406 ################################################################## 3639 ##################################################################
3407 ## slots below implement check functions 3640 ## slots below implement check functions
3408 ################################################################## 3641 ##################################################################
3409 3642
3410 def __performCheck(self): 3643 def __performCheck(self):
3411 """ 3644 """
3412 Private slot to inspect the project for common problems. 3645 Private slot to inspect the project for common problems.
3413 """ 3646 """
3414 try: 3647 try:
3415 path = self.__sitePath() 3648 path = self.__sitePath()
3416 except DjangoNoSiteSelectedException: 3649 except DjangoNoSiteSelectedError:
3417 return 3650 return
3418 3651
3419 from .DjangoCheckOptionsDialog import DjangoCheckOptionsDialog 3652 from .DjangoCheckOptionsDialog import DjangoCheckOptionsDialog
3653
3420 dlg = DjangoCheckOptionsDialog( 3654 dlg = DjangoCheckOptionsDialog(
3421 self.__getPythonExecutable(), path, self.getRecentApplications(), 3655 self.__getPythonExecutable(),
3656 path,
3657 self.getRecentApplications(),
3422 self.__plugin.getPreferences("CheckDeployMode"), 3658 self.__plugin.getPreferences("CheckDeployMode"),
3423 ) 3659 )
3424 if dlg.exec() == QDialog.DialogCode.Accepted: 3660 if dlg.exec() == QDialog.DialogCode.Accepted:
3425 deploy, tags, appsStr, settingsFile = dlg.getData() 3661 deploy, tags, appsStr, settingsFile = dlg.getData()
3426 self.__plugin.setPreferences("CheckDeployMode", deploy) 3662 self.__plugin.setPreferences("CheckDeployMode", deploy)
3427 if appsStr != "": 3663 if appsStr != "":
3428 self.setMostRecentApplication(appsStr) 3664 self.setMostRecentApplication(appsStr)
3429 apps = appsStr.split() 3665 apps = appsStr.split()
3430 3666
3431 args = [] 3667 args = []
3432 args.append(self.__getPythonExecutable()) 3668 args.append(self.__getPythonExecutable())
3433 args.append("manage.py") 3669 args.append("manage.py")
3434 args.append("check") 3670 args.append("check")
3435 for tag in tags: 3671 for tag in tags:
3438 if deploy: 3674 if deploy:
3439 args.append("--deploy") 3675 args.append("--deploy")
3440 if settingsFile: 3676 if settingsFile:
3441 args.append("--settings={0}".format(settingsFile)) 3677 args.append("--settings={0}".format(settingsFile))
3442 args += apps 3678 args += apps
3443 3679
3444 dia = DjangoDialog(self.tr("Check Project")) 3680 dia = DjangoDialog(self.tr("Check Project"))
3445 res = dia.startProcess(args, path, mergedOutput=True) 3681 res = dia.startProcess(args, path, mergedOutput=True)
3446 if res: 3682 if res:
3447 dia.exec() 3683 dia.exec()

eric ide

mercurial