38 """ |
38 """ |
39 Class implementing the project management functionality. |
39 Class implementing the project management functionality. |
40 |
40 |
41 @signal dirty(int) emitted when the dirty state changes |
41 @signal dirty(int) emitted when the dirty state changes |
42 @signal projectLanguageAdded(str) emitted after a new language was added |
42 @signal projectLanguageAdded(str) emitted after a new language was added |
43 @signal projectLanguageAddedByCode(str) emitted after a new language was added. |
43 @signal projectLanguageAddedByCode(str) emitted after a new language was |
44 The language code is sent by this signal. |
44 added. The language code is sent by this signal. |
45 @signal projectLanguageRemoved(str) emitted after a language was removed |
45 @signal projectLanguageRemoved(str) emitted after a language was removed |
46 @signal projectFormAdded(str) emitted after a new form was added |
46 @signal projectFormAdded(str) emitted after a new form was added |
47 @signal projectFormRemoved(str) emitted after a form was removed |
47 @signal projectFormRemoved(str) emitted after a form was removed |
48 @signal projectFormCompiled(str) emitted after a form was compiled |
48 @signal projectFormCompiled(str) emitted after a form was compiled |
49 @signal projectSourceAdded(str) emitted after a new source file was added |
49 @signal projectSourceAdded(str) emitted after a new source file was added |
50 @signal projectSourceRemoved(str) emitted after a source was removed |
50 @signal projectSourceRemoved(str) emitted after a source was removed |
51 @signal projectInterfaceAdded(str) emitted after a new IDL file was added |
51 @signal projectInterfaceAdded(str) emitted after a new IDL file was added |
52 @signal projectInterfaceRemoved(str) emitted after a IDL file was removed |
52 @signal projectInterfaceRemoved(str) emitted after a IDL file was removed |
53 @signal projectResourceAdded(str) emitted after a new resource file was added |
53 @signal projectResourceAdded(str) emitted after a new resource file was |
|
54 added |
54 @signal projectResourceRemoved(str) emitted after a resource was removed |
55 @signal projectResourceRemoved(str) emitted after a resource was removed |
55 @signal projectOthersAdded(str) emitted after a file or directory was added |
56 @signal projectOthersAdded(str) emitted after a file or directory was added |
56 to the OTHERS project data area |
57 to the OTHERS project data area |
57 @signal projectOthersRemoved(str) emitted after a file was removed from the |
58 @signal projectOthersRemoved(str) emitted after a file was removed from the |
58 OTHERS project data area |
59 OTHERS project data area |
59 @signal projectAboutToBeCreated() emitted just before the project will be created |
60 @signal projectAboutToBeCreated() emitted just before the project will be |
60 @signal newProjectHooks() emitted after a new project was generated but before |
61 created |
61 the newProject() signal is sent |
62 @signal newProjectHooks() emitted after a new project was generated but |
|
63 before the newProject() signal is sent |
62 @signal newProject() emitted after a new project was generated |
64 @signal newProject() emitted after a new project was generated |
63 @signal sourceFile(str) emitted after a project file was read to |
65 @signal sourceFile(str) emitted after a project file was read to |
64 open the main script |
66 open the main script |
65 @signal projectOpenedHooks() emitted after a project file was read but before the |
67 @signal projectOpenedHooks() emitted after a project file was read but |
66 projectOpened() signal is sent |
68 before the projectOpened() signal is sent |
67 @signal projectOpened() emitted after a project file was read |
69 @signal projectOpened() emitted after a project file was read |
68 @signal projectClosedHooks() emitted after a project file was closed but before the |
70 @signal projectClosedHooks() emitted after a project file was closed but |
69 projectClosed() signal is sent |
71 before the projectClosed() signal is sent |
70 @signal projectClosed() emitted after a project was closed |
72 @signal projectClosed() emitted after a project was closed |
71 @signal projectFileRenamed(str, str) emitted after a file of the project |
73 @signal projectFileRenamed(str, str) emitted after a file of the project |
72 has been renamed |
74 has been renamed |
73 @signal projectPropertiesChanged() emitted after the project properties were changed |
75 @signal projectPropertiesChanged() emitted after the project properties |
74 @signal directoryRemoved(str) emitted after a directory has been removed from |
76 were changed |
75 the project |
77 @signal directoryRemoved(str) emitted after a directory has been removed |
|
78 from the project |
76 @signal prepareRepopulateItem(str) emitted before an item of the model is |
79 @signal prepareRepopulateItem(str) emitted before an item of the model is |
77 repopulated |
80 repopulated |
78 @signal completeRepopulateItem(str) emitted after an item of the model was |
81 @signal completeRepopulateItem(str) emitted after an item of the model was |
79 repopulated |
82 repopulated |
80 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of the |
83 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of |
81 monitoring thread (ok, nok, op, off) and a status message |
84 the monitoring thread (ok, nok, op, off) and a status message |
82 @signal reinitVCS() emitted after the VCS has been reinitialized |
85 @signal reinitVCS() emitted after the VCS has been reinitialized |
83 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The name |
86 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The |
84 of the menu and a reference to the menu are given. |
87 name of the menu and a reference to the menu are given. |
85 @signal lexerAssociationsChanged() emitted after the lexer associations have been |
88 @signal lexerAssociationsChanged() emitted after the lexer associations |
86 changed |
89 have been changed |
87 @signal projectChanged() emitted to signal a change of the project |
90 @signal projectChanged() emitted to signal a change of the project |
88 """ |
91 """ |
89 dirty = pyqtSignal(int) |
92 dirty = pyqtSignal(int) |
90 projectLanguageAdded = pyqtSignal(str) |
93 projectLanguageAdded = pyqtSignal(str) |
91 projectLanguageAddedByCode = pyqtSignal(str) |
94 projectLanguageAddedByCode = pyqtSignal(str) |
235 self.__projectTypes["E4Plugin"] = self.trUtf8("Eric Plugin") |
238 self.__projectTypes["E4Plugin"] = self.trUtf8("Eric Plugin") |
236 self.__projectTypes["Console"] = self.trUtf8("Console") |
239 self.__projectTypes["Console"] = self.trUtf8("Console") |
237 self.__projectTypes["Other"] = self.trUtf8("Other") |
240 self.__projectTypes["Other"] = self.trUtf8("Other") |
238 |
241 |
239 self.__projectProgLanguages = { |
242 self.__projectProgLanguages = { |
240 "Python2": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "Console", "Other"], |
243 "Python2": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", |
241 "Python3": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "Console", "Other"], |
244 "Console", "Other"], |
|
245 "Python3": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", |
|
246 "Console", "Other"], |
242 "Ruby": ["Qt4", "Qt4C", "Console", "Other"], |
247 "Ruby": ["Qt4", "Qt4C", "Console", "Other"], |
243 } |
248 } |
244 |
249 |
245 pyside2, pyside3 = Utilities.checkPyside() |
250 pyside2, pyside3 = Utilities.checkPyside() |
246 if pyside2 or pyside3: |
251 if pyside2 or pyside3: |
247 self.__projectTypes["PySide"] = self.trUtf8("PySide GUI") |
252 self.__projectTypes["PySide"] = self.trUtf8("PySide GUI") |
248 self.__projectTypes["PySideC"] = self.trUtf8("PySide Console") |
253 self.__projectTypes["PySideC"] = self.trUtf8("PySide Console") |
249 if pyside2: |
254 if pyside2: |
250 self.__projectProgLanguages["Python2"].extend(["PySide", "PySideC"]) |
255 self.__projectProgLanguages["Python2"].extend( |
|
256 ["PySide", "PySideC"]) |
251 if pyside3: |
257 if pyside3: |
252 self.__projectProgLanguages["Python3"].extend(["PySide", "PySideC"]) |
258 self.__projectProgLanguages["Python3"].extend( |
|
259 ["PySide", "PySideC"]) |
253 |
260 |
254 def getProjectTypes(self, progLanguage=""): |
261 def getProjectTypes(self, progLanguage=""): |
255 """ |
262 """ |
256 Public method to get the list of supported project types. |
263 Public method to get the list of supported project types. |
257 |
264 |
258 @param progLanguage programming language to get project types for (string) |
265 @param progLanguage programming language to get project types for |
|
266 (string) |
259 @return reference to the dictionary of project types. |
267 @return reference to the dictionary of project types. |
260 """ |
268 """ |
261 if progLanguage and progLanguage in self.__projectProgLanguages: |
269 if progLanguage and progLanguage in self.__projectProgLanguages: |
262 ptypes = {} |
270 ptypes = {} |
263 for ptype in self.__projectProgLanguages[progLanguage]: |
271 for ptype in self.__projectProgLanguages[progLanguage]: |
302 if progLanguages: |
310 if progLanguages: |
303 for progLanguage in progLanguages: |
311 for progLanguage in progLanguages: |
304 if progLanguage not in self.__projectProgLanguages: |
312 if progLanguage not in self.__projectProgLanguages: |
305 E5MessageBox.critical(self.ui, |
313 E5MessageBox.critical(self.ui, |
306 self.trUtf8("Registering Project Type"), |
314 self.trUtf8("Registering Project Type"), |
307 self.trUtf8("""<p>The Programming Language <b>{0}</b> is not""" |
315 self.trUtf8( |
308 """ supported.</p>""")\ |
316 """<p>The Programming Language <b>{0}</b> is not""" |
|
317 """ supported.</p>""")\ |
309 .format(progLanguage) |
318 .format(progLanguage) |
310 ) |
319 ) |
311 return |
320 return |
312 |
321 |
313 if type_ in self.__projectProgLanguages[progLanguage]: |
322 if type_ in self.__projectProgLanguages[progLanguage]: |
314 E5MessageBox.critical(self.ui, |
323 E5MessageBox.critical(self.ui, |
315 self.trUtf8("Registering Project Type"), |
324 self.trUtf8("Registering Project Type"), |
316 self.trUtf8("""<p>The Project type <b>{0}</b> is already""" |
325 self.trUtf8( |
317 """ registered with Programming Language""" |
326 """<p>The Project type <b>{0}</b> is already""" |
318 """ <b>{1}</b>.</p>""")\ |
327 """ registered with Programming Language""" |
|
328 """ <b>{1}</b>.</p>""")\ |
319 .format(type_, progLanguage) |
329 .format(type_, progLanguage) |
320 ) |
330 ) |
321 return |
331 return |
322 |
332 |
323 if type_ in self.__projectTypes: |
333 if type_ in self.__projectTypes: |
415 def getData(self, category, key): |
427 def getData(self, category, key): |
416 """ |
428 """ |
417 Public method to get data out of the project data store. |
429 Public method to get data out of the project data store. |
418 |
430 |
419 @param category category of the data to get (string, one of |
431 @param category category of the data to get (string, one of |
420 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, DOCUMENTATIONPARMS |
432 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, |
421 or OTHERTOOLSPARMS) |
433 DOCUMENTATIONPARMS or OTHERTOOLSPARMS) |
422 @param key key of the data entry to get (string). |
434 @param key key of the data entry to get (string). |
423 @return a copy of the requested data or None |
435 @return a copy of the requested data or None |
424 """ |
436 """ |
425 if category in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
437 if category in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", |
426 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"] and \ |
438 "PACKAGERSPARMS", "DOCUMENTATIONPARMS", |
|
439 "OTHERTOOLSPARMS"] and \ |
427 key in self.pdata[category]: |
440 key in self.pdata[category]: |
428 return copy.deepcopy(self.pdata[category][key]) |
441 return copy.deepcopy(self.pdata[category][key]) |
429 else: |
442 else: |
430 return None |
443 return None |
431 |
444 |
432 def setData(self, category, key, data): |
445 def setData(self, category, key, data): |
433 """ |
446 """ |
434 Public method to store data in the project data store. |
447 Public method to store data in the project data store. |
435 |
448 |
436 @param category category of the data to get (string, one of |
449 @param category category of the data to get (string, one of |
437 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, DOCUMENTATIONPARMS |
450 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, |
438 or OTHERTOOLSPARMS) |
451 DOCUMENTATIONPARMS or OTHERTOOLSPARMS) |
439 @param key key of the data entry to get (string). |
452 @param key key of the data entry to get (string). |
440 @param data data to be stored |
453 @param data data to be stored |
441 @return flag indicating success (boolean) |
454 @return flag indicating success (boolean) |
442 """ |
455 """ |
443 if category not in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
456 if category not in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", |
444 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"]: |
457 "PACKAGERSPARMS", "DOCUMENTATIONPARMS", |
|
458 "OTHERTOOLSPARMS"]: |
445 return False |
459 return False |
446 |
460 |
447 # test for changes of data and save them in the project |
461 # test for changes of data and save them in the project |
448 # 1. there were none, now there are |
462 # 1. there were none, now there are |
449 if key not in self.pdata[category] and len(data) > 0: |
463 if key not in self.pdata[category] and len(data) > 0: |
463 return False |
477 return False |
464 return True |
478 return True |
465 |
479 |
466 def initFileTypes(self): |
480 def initFileTypes(self): |
467 """ |
481 """ |
468 Public method to initialize the filetype associations with default values. |
482 Public method to initialize the filetype associations with default |
|
483 values. |
469 """ |
484 """ |
470 self.pdata["FILETYPES"] = {} |
485 self.pdata["FILETYPES"] = {} |
471 if self.pdata["MIXEDLANGUAGE"][0]: |
486 if self.pdata["MIXEDLANGUAGE"][0]: |
472 sourceKey = "Mixed" |
487 sourceKey = "Mixed" |
473 else: |
488 else: |
474 sourceKey = self.pdata["PROGLANGUAGE"][0] |
489 sourceKey = self.pdata["PROGLANGUAGE"][0] |
475 for ext in self.sourceExtensions[sourceKey]: |
490 for ext in self.sourceExtensions[sourceKey]: |
476 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" |
491 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" |
477 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" |
492 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" |
478 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "PyQt5", "E4Plugin", "PySide"]: |
493 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "PyQt5", "E4Plugin", |
|
494 "PySide"]: |
479 self.pdata["FILETYPES"]["*.ui"] = "FORMS" |
495 self.pdata["FILETYPES"]["*.ui"] = "FORMS" |
480 self.pdata["FILETYPES"]["*.ui.h"] = "FORMS" |
496 self.pdata["FILETYPES"]["*.ui.h"] = "FORMS" |
481 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
497 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
482 "PyQt5", "PyQt5C", |
498 "PyQt5", "PyQt5C", |
483 "PySide", "PySideC"]: |
499 "PySide", "PySideC"]: |
486 "PyQt5", "PyQt5C", |
502 "PyQt5", "PyQt5C", |
487 "PySide", "PySideC"]: |
503 "PySide", "PySideC"]: |
488 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
504 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
489 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
505 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
490 try: |
506 try: |
491 if self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]] is not None: |
507 if self.__fileTypeCallbacks[ |
492 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
508 self.pdata["PROJECTTYPE"][0]] is not None: |
|
509 ftypes = \ |
|
510 self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
493 self.pdata["FILETYPES"].update(ftypes) |
511 self.pdata["FILETYPES"].update(ftypes) |
494 except KeyError: |
512 except KeyError: |
495 pass |
513 pass |
496 self.setDirty(True) |
514 self.setDirty(True) |
497 |
515 |
498 def updateFileTypes(self): |
516 def updateFileTypes(self): |
499 """ |
517 """ |
500 Public method to update the filetype associations with new default values. |
518 Public method to update the filetype associations with new default |
|
519 values. |
501 """ |
520 """ |
502 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
521 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
503 "PyQt5", "PyQt5C", |
522 "PyQt5", "PyQt5C", |
504 "PySide", "PySideC"]: |
523 "PySide", "PySideC"]: |
505 if "*.ts" not in self.pdata["FILETYPES"]: |
524 if "*.ts" not in self.pdata["FILETYPES"]: |
506 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
525 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
507 if "*.qm" not in self.pdata["FILETYPES"]: |
526 if "*.qm" not in self.pdata["FILETYPES"]: |
508 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
527 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
509 try: |
528 try: |
510 if self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]] is not None: |
529 if self.__fileTypeCallbacks[ |
511 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
530 self.pdata["PROJECTTYPE"][0]] is not None: |
|
531 ftypes = \ |
|
532 self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
512 for pattern, ftype in list(ftypes.items()): |
533 for pattern, ftype in list(ftypes.items()): |
513 if pattern not in self.pdata["FILETYPES"]: |
534 if pattern not in self.pdata["FILETYPES"]: |
514 self.pdata["FILETYPES"][pattern] = ftype |
535 self.pdata["FILETYPES"][pattern] = ftype |
515 self.setDirty(True) |
536 self.setDirty(True) |
516 except KeyError: |
537 except KeyError: |
658 if res: |
680 if res: |
659 if len(self.pdata["TRANSLATIONPATTERN"]) == 1: |
681 if len(self.pdata["TRANSLATIONPATTERN"]) == 1: |
660 self.translationsRoot = \ |
682 self.translationsRoot = \ |
661 self.pdata["TRANSLATIONPATTERN"][0].split("%language%")[0] |
683 self.pdata["TRANSLATIONPATTERN"][0].split("%language%")[0] |
662 elif len(self.pdata["MAINSCRIPT"]) == 1: |
684 elif len(self.pdata["MAINSCRIPT"]) == 1: |
663 self.translationsRoot = os.path.splitext(self.pdata["MAINSCRIPT"][0])[0] |
685 self.translationsRoot = os.path.splitext( |
|
686 self.pdata["MAINSCRIPT"][0])[0] |
664 if os.path.isdir(os.path.join(self.ppath, self.translationsRoot)): |
687 if os.path.isdir(os.path.join(self.ppath, self.translationsRoot)): |
665 dn = self.translationsRoot |
688 dn = self.translationsRoot |
666 else: |
689 else: |
667 dn = os.path.dirname(self.translationsRoot) |
690 dn = os.path.dirname(self.translationsRoot) |
668 if dn not in self.subdirs: |
691 if dn not in self.subdirs: |
669 self.subdirs.append(dn) |
692 self.subdirs.append(dn) |
670 |
693 |
671 self.name = os.path.splitext(os.path.basename(fn))[0] |
694 self.name = os.path.splitext(os.path.basename(fn))[0] |
672 |
695 |
673 # check, if the files of the project still exist in the project directory |
696 # check, if the files of the project still exist in the |
|
697 # project directory |
674 self.__checkFilesExist("SOURCES") |
698 self.__checkFilesExist("SOURCES") |
675 self.__checkFilesExist("FORMS") |
699 self.__checkFilesExist("FORMS") |
676 self.__checkFilesExist("INTERFACES") |
700 self.__checkFilesExist("INTERFACES") |
677 self.__checkFilesExist("TRANSLATIONS") |
701 self.__checkFilesExist("TRANSLATIONS") |
678 self.__checkFilesExist("RESOURCES") |
702 self.__checkFilesExist("RESOURCES") |
708 def __writeProject(self, fn=None): |
732 def __writeProject(self, fn=None): |
709 """ |
733 """ |
710 Private method to save the project infos to a project file. |
734 Private method to save the project infos to a project file. |
711 |
735 |
712 @param fn optional filename of the project file to be written (string). |
736 @param fn optional filename of the project file to be written (string). |
713 If fn is None, the filename stored in the project object |
737 If fn is None, the filename stored in the project object |
714 is used. This is the 'save' action. If fn is given, this filename |
738 is used. This is the 'save' action. If fn is given, this filename |
715 is used instead of the one in the project object. This is the |
739 is used instead of the one in the project object. This is the |
716 'save as' action. |
740 'save as' action. |
717 @return flag indicating success |
741 @return flag indicating success |
718 """ |
742 """ |
719 if self.vcs is not None: |
743 if self.vcs is not None: |
720 self.pdata["VCSOPTIONS"] = [copy.deepcopy(self.vcs.vcsGetOptions())] |
744 self.pdata["VCSOPTIONS"] = [ |
721 self.pdata["VCSOTHERDATA"] = [copy.deepcopy(self.vcs.vcsGetOtherData())] |
745 copy.deepcopy(self.vcs.vcsGetOptions())] |
|
746 self.pdata["VCSOTHERDATA"] = [ |
|
747 copy.deepcopy(self.vcs.vcsGetOtherData())] |
722 |
748 |
723 if not self.pdata["HASH"][0]: |
749 if not self.pdata["HASH"][0]: |
724 hash = str(QCryptographicHash.hash( |
750 hash = str(QCryptographicHash.hash( |
725 QByteArray(self.ppath.encode("utf-8")), |
751 QByteArray(self.ppath.encode("utf-8")), |
726 QCryptographicHash.Sha1).toHex(), |
752 QCryptographicHash.Sha1).toHex(), |
1134 """ |
1178 """ |
1135 if len(self.pdata["TRANSLATIONPATTERN"]) == 0 or \ |
1179 if len(self.pdata["TRANSLATIONPATTERN"]) == 0 or \ |
1136 self.pdata["TRANSLATIONPATTERN"][0] == '': |
1180 self.pdata["TRANSLATIONPATTERN"][0] == '': |
1137 E5MessageBox.critical(self.ui, |
1181 E5MessageBox.critical(self.ui, |
1138 self.trUtf8("Add Language"), |
1182 self.trUtf8("Add Language"), |
1139 self.trUtf8("You have to specify a translation pattern first.")) |
1183 self.trUtf8( |
|
1184 "You have to specify a translation pattern first.")) |
1140 return |
1185 return |
1141 |
1186 |
1142 from .AddLanguageDialog import AddLanguageDialog |
1187 from .AddLanguageDialog import AddLanguageDialog |
1143 dlg = AddLanguageDialog(self.parent()) |
1188 dlg = AddLanguageDialog(self.parent()) |
1144 if dlg.exec_() == QDialog.Accepted: |
1189 if dlg.exec_() == QDialog.Accepted: |
1145 lang = dlg.getSelectedLanguage() |
1190 lang = dlg.getSelectedLanguage() |
1146 if self.pdata["PROJECTTYPE"][0] in \ |
1191 if self.pdata["PROJECTTYPE"][0] in \ |
1147 ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "PySide", "PySideC"]: |
1192 ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "PySide", |
1148 langFile = self.pdata["TRANSLATIONPATTERN"][0].replace("%language%", lang) |
1193 "PySideC"]: |
|
1194 langFile = self.pdata["TRANSLATIONPATTERN"][0]\ |
|
1195 .replace("%language%", lang) |
1149 self.appendFile(langFile) |
1196 self.appendFile(langFile) |
1150 self.projectLanguageAddedByCode.emit(lang) |
1197 self.projectLanguageAddedByCode.emit(lang) |
1151 |
1198 |
1152 def __binaryTranslationFile(self, langFile): |
1199 def __binaryTranslationFile(self, langFile): |
1153 """ |
1200 """ |
1154 Private method to calculate the filename of the binary translations file |
1201 Private method to calculate the filename of the binary translations |
1155 given the name of the raw translations file. |
1202 file given the name of the raw translations file. |
1156 |
1203 |
1157 @param langFile name of the raw translations file (string) |
1204 @param langFile name of the raw translations file (string) |
1158 @return name of the binary translations file (string) |
1205 @return name of the binary translations file (string) |
1159 """ |
1206 """ |
1160 qmFile = "" |
1207 qmFile = "" |
1161 try: |
1208 try: |
1162 if self.__binaryTranslationsCallbacks[self.pdata["PROJECTTYPE"][0]] \ |
1209 if self.__binaryTranslationsCallbacks[ |
1163 is not None: |
1210 self.pdata["PROJECTTYPE"][0]] is not None: |
1164 qmFile = self.__binaryTranslationsCallbacks[ |
1211 qmFile = self.__binaryTranslationsCallbacks[ |
1165 self.pdata["PROJECTTYPE"][0]](langFile) |
1212 self.pdata["PROJECTTYPE"][0]](langFile) |
1166 except KeyError: |
1213 except KeyError: |
1167 qmFile = langFile.replace('.ts', '.qm') |
1214 qmFile = langFile.replace('.ts', '.qm') |
1168 if qmFile == langFile: |
1215 if qmFile == langFile: |
1244 if os.path.exists(fn): |
1292 if os.path.exists(fn): |
1245 os.remove(fn) |
1293 os.remove(fn) |
1246 except IOError: |
1294 except IOError: |
1247 E5MessageBox.critical(self.ui, |
1295 E5MessageBox.critical(self.ui, |
1248 self.trUtf8("Delete translation"), |
1296 self.trUtf8("Delete translation"), |
1249 self.trUtf8("<p>The selected translation file <b>{0}</b> could not be" |
1297 self.trUtf8( |
1250 " deleted.</p>").format(qmFile)) |
1298 "<p>The selected translation file <b>{0}</b> could" |
|
1299 " not be deleted.</p>").format(qmFile)) |
1251 return |
1300 return |
1252 |
1301 |
1253 def appendFile(self, fn, isSourceFile=False, updateModel=True): |
1302 def appendFile(self, fn, isSourceFile=False, updateModel=True): |
1254 """ |
1303 """ |
1255 Public method to append a file to the project. |
1304 Public method to append a file to the project. |
1256 |
1305 |
1257 @param fn filename to be added to the project (string) |
1306 @param fn filename to be added to the project (string) |
1258 @param isSourceFile flag indicating that this is a source file |
1307 @param isSourceFile flag indicating that this is a source file |
1259 even if it doesn't have the source extension (boolean) |
1308 even if it doesn't have the source extension (boolean) |
1260 @param updateModel flag indicating an update of the model is requested (boolean) |
1309 @param updateModel flag indicating an update of the model is |
|
1310 requested (boolean) |
1261 """ |
1311 """ |
1262 dirty = False |
1312 dirty = False |
1263 |
1313 |
1264 if os.path.isabs(fn): |
1314 if os.path.isabs(fn): |
1265 # make it relative to the project root, if it starts with that path |
1315 # make it relative to the project root, if it starts with that path |
1364 os.makedirs(target) |
1416 os.makedirs(target) |
1365 |
1417 |
1366 if os.path.exists(targetfile): |
1418 if os.path.exists(targetfile): |
1367 res = E5MessageBox.yesNo(self.ui, |
1419 res = E5MessageBox.yesNo(self.ui, |
1368 self.trUtf8("Add file"), |
1420 self.trUtf8("Add file"), |
1369 self.trUtf8("<p>The file <b>{0}</b> already" |
1421 self.trUtf8( |
|
1422 "<p>The file <b>{0}</b> already" |
1370 " exists.</p><p>Overwrite it?</p>") |
1423 " exists.</p><p>Overwrite it?</p>") |
1371 .format(targetfile), |
1424 .format(targetfile), |
1372 icon=E5MessageBox.Warning) |
1425 icon=E5MessageBox.Warning) |
1373 if not res: |
1426 if not res: |
1374 return # don't overwrite |
1427 return # don't overwrite |
1375 |
1428 |
1376 shutil.copy(fn, target) |
1429 shutil.copy(fn, target) |
1377 except IOError as why: |
1430 except IOError as why: |
1378 E5MessageBox.critical(self.ui, |
1431 E5MessageBox.critical(self.ui, |
1379 self.trUtf8("Add file"), |
1432 self.trUtf8("Add file"), |
1380 self.trUtf8("<p>The selected file <b>{0}</b> could not be" |
1433 self.trUtf8( |
1381 " added to <b>{1}</b>.</p><p>Reason: {2}</p>") |
1434 "<p>The selected file <b>{0}</b> could" |
|
1435 " not be added to <b>{1}</b>.</p>" |
|
1436 "<p>Reason: {2}</p>") |
1382 .format(fn, target, str(why))) |
1437 .format(fn, target, str(why))) |
1383 continue |
1438 continue |
1384 |
1439 |
1385 self.appendFile(targetfile, isSource or filter == 'source') |
1440 self.appendFile(targetfile, isSource or filter == 'source') |
1386 else: |
1441 else: |
1439 if not Utilities.samepath(target, source): |
1497 if not Utilities.samepath(target, source): |
1440 try: |
1498 try: |
1441 if os.path.exists(targetfile): |
1499 if os.path.exists(targetfile): |
1442 res = E5MessageBox.yesNo(self.ui, |
1500 res = E5MessageBox.yesNo(self.ui, |
1443 self.trUtf8("Add directory"), |
1501 self.trUtf8("Add directory"), |
1444 self.trUtf8("<p>The file <b>{0}</b> already exists.</p>" |
1502 self.trUtf8( |
1445 "<p>Overwrite it?</p>") |
1503 "<p>The file <b>{0}</b> already exists.</p>" |
|
1504 "<p>Overwrite it?</p>") |
1446 .format(targetfile), |
1505 .format(targetfile), |
1447 icon=E5MessageBox.Warning) |
1506 icon=E5MessageBox.Warning) |
1448 if not res: |
1507 if not res: |
1449 continue # don't overwrite, carry on with next file |
1508 continue # don't overwrite, carry on |
|
1509 # with next file |
1450 |
1510 |
1451 shutil.copy(file, target) |
1511 shutil.copy(file, target) |
1452 except EnvironmentError: |
1512 except EnvironmentError: |
1453 continue |
1513 continue |
1454 self.appendFile(targetfile) |
1514 self.appendFile(targetfile) |
1911 self.menuCheckAct.setEnabled(True) |
1981 self.menuCheckAct.setEnabled(True) |
1912 self.menuShowAct.setEnabled(True) |
1982 self.menuShowAct.setEnabled(True) |
1913 self.menuDiagramAct.setEnabled(True) |
1983 self.menuDiagramAct.setEnabled(True) |
1914 self.menuApidocAct.setEnabled(True) |
1984 self.menuApidocAct.setEnabled(True) |
1915 self.menuPackagersAct.setEnabled(True) |
1985 self.menuPackagersAct.setEnabled(True) |
1916 self.pluginGrp.setEnabled(self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
1986 self.pluginGrp.setEnabled( |
|
1987 self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
1917 self.addLanguageAct.setEnabled( |
1988 self.addLanguageAct.setEnabled( |
1918 len(self.pdata["TRANSLATIONPATTERN"]) > 0 and \ |
1989 len(self.pdata["TRANSLATIONPATTERN"]) > 0 and \ |
1919 self.pdata["TRANSLATIONPATTERN"][0] != '') |
1990 self.pdata["TRANSLATIONPATTERN"][0] != '') |
1920 |
1991 |
1921 self.projectAboutToBeCreated.emit() |
1992 self.projectAboutToBeCreated.emit() |
1922 |
1993 |
1923 hash = str(QCryptographicHash.hash( |
1994 hash = str(QCryptographicHash.hash( |
1924 QByteArray(self.ppath.encode("utf-8")), QCryptographicHash.Sha1).toHex(), |
1995 QByteArray(self.ppath.encode("utf-8")), |
|
1996 QCryptographicHash.Sha1).toHex(), |
1925 encoding="utf-8") |
1997 encoding="utf-8") |
1926 self.pdata["HASH"] = [hash] |
1998 self.pdata["HASH"] = [hash] |
1927 |
1999 |
1928 # create the project directory if it doesn't exist already |
2000 # create the project directory if it doesn't exist already |
1929 if not os.path.isdir(self.ppath): |
2001 if not os.path.isdir(self.ppath): |
1930 try: |
2002 try: |
1931 os.makedirs(self.ppath) |
2003 os.makedirs(self.ppath) |
1932 except EnvironmentError: |
2004 except EnvironmentError: |
1933 E5MessageBox.critical(self.ui, |
2005 E5MessageBox.critical(self.ui, |
1934 self.trUtf8("Create project directory"), |
2006 self.trUtf8("Create project directory"), |
1935 self.trUtf8("<p>The project directory <b>{0}</b> could not" |
2007 self.trUtf8( |
|
2008 "<p>The project directory <b>{0}</b> could not" |
1936 " be created.</p>") |
2009 " be created.</p>") |
1937 .format(self.ppath)) |
2010 .format(self.ppath)) |
1938 self.vcs = self.initVCS() |
2011 self.vcs = self.initVCS() |
1939 return |
2012 return |
1940 # create an empty __init__.py file to make it a Python package |
2013 # create an empty __init__.py file to make it a Python package |
1941 # (only for Python and Python3) |
2014 # (only for Python and Python3) |
1942 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
2015 if self.pdata["PROGLANGUAGE"][0] in \ |
|
2016 ["Python", "Python2", "Python3"]: |
1943 fn = os.path.join(self.ppath, "__init__.py") |
2017 fn = os.path.join(self.ppath, "__init__.py") |
1944 f = open(fn, "w", encoding="utf-8") |
2018 f = open(fn, "w", encoding="utf-8") |
1945 f.close() |
2019 f.close() |
1946 self.appendFile(fn, True) |
2020 self.appendFile(fn, True) |
1947 # create an empty main script file, if a name was given |
2021 # create an empty main script file, if a name was given |
1948 if len(self.pdata["MAINSCRIPT"]) and self.pdata["MAINSCRIPT"][0]: |
2022 if len(self.pdata["MAINSCRIPT"]) and \ |
|
2023 self.pdata["MAINSCRIPT"][0]: |
1949 if not os.path.isabs(self.pdata["MAINSCRIPT"][0]): |
2024 if not os.path.isabs(self.pdata["MAINSCRIPT"][0]): |
1950 ms = os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0]) |
2025 ms = os.path.join( |
|
2026 self.ppath, self.pdata["MAINSCRIPT"][0]) |
1951 else: |
2027 else: |
1952 ms = self.pdata["MAINSCRIPT"][0] |
2028 ms = self.pdata["MAINSCRIPT"][0] |
1953 f = open(ms, "w") |
2029 f = open(ms, "w") |
1954 f.close() |
2030 f.close() |
1955 self.appendFile(ms, True) |
2031 self.appendFile(ms, True) |
2064 self.pdata["VCS"] = ['None'] |
2145 self.pdata["VCS"] = ['None'] |
2065 self.saveProject() |
2146 self.saveProject() |
2066 break |
2147 break |
2067 |
2148 |
2068 # put the project under VCS control |
2149 # put the project under VCS control |
2069 if self.vcs is None and self.vcsSoftwareAvailable() and self.vcsRequested: |
2150 if self.vcs is None and self.vcsSoftwareAvailable() and \ |
|
2151 self.vcsRequested: |
2070 vcsSystemsDict = e5App().getObject("PluginManager")\ |
2152 vcsSystemsDict = e5App().getObject("PluginManager")\ |
2071 .getPluginDisplayStrings("version_control") |
2153 .getPluginDisplayStrings("version_control") |
2072 vcsSystemsDisplay = [self.trUtf8("None")] |
2154 vcsSystemsDisplay = [self.trUtf8("None")] |
2073 keys = sorted(vcsSystemsDict.keys()) |
2155 keys = sorted(vcsSystemsDict.keys()) |
2074 for key in keys: |
2156 for key in keys: |
2075 vcsSystemsDisplay.append(vcsSystemsDict[key]) |
2157 vcsSystemsDisplay.append(vcsSystemsDict[key]) |
2076 vcsSelected, ok = QInputDialog.getItem( |
2158 vcsSelected, ok = QInputDialog.getItem( |
2077 None, |
2159 None, |
2078 self.trUtf8("New Project"), |
2160 self.trUtf8("New Project"), |
2079 self.trUtf8("Select version control system for the project"), |
2161 self.trUtf8( |
|
2162 "Select version control system for the project"), |
2080 vcsSystemsDisplay, |
2163 vcsSystemsDisplay, |
2081 0, False) |
2164 0, False) |
2082 if ok and vcsSelected != self.trUtf8("None"): |
2165 if ok and vcsSelected != self.trUtf8("None"): |
2083 for vcsSystem, vcsSystemDisplay in list(vcsSystemsDict.items()): |
2166 for vcsSystem, vcsSystemDisplay in vcsSystemsDict.items(): |
2084 if vcsSystemDisplay == vcsSelected: |
2167 if vcsSystemDisplay == vcsSelected: |
2085 break |
2168 break |
2086 else: |
2169 else: |
2087 vcsSystem = "None" |
2170 vcsSystem = "None" |
2088 self.pdata["VCS"] = [vcsSystem] |
2171 self.pdata["VCS"] = [vcsSystem] |
2161 # the first entry determines the mainscript name |
2246 # the first entry determines the mainscript name |
2162 mainscriptname = os.path.splitext(mainscript)[0] or \ |
2247 mainscriptname = os.path.splitext(mainscript)[0] or \ |
2163 os.path.basename(tslist[0]).split('_')[0] |
2248 os.path.basename(tslist[0]).split('_')[0] |
2164 self.pdata["TRANSLATIONPATTERN"] = \ |
2249 self.pdata["TRANSLATIONPATTERN"] = \ |
2165 [os.path.join(os.path.dirname(tslist[0]), |
2250 [os.path.join(os.path.dirname(tslist[0]), |
2166 "{0}_%language%{1}".format(os.path.basename(tslist[0]).split('_')[0], |
2251 "{0}_%language%{1}".format( |
|
2252 os.path.basename(tslist[0]).split('_')[0], |
2167 os.path.splitext(tslist[0])[1]))] |
2253 os.path.splitext(tslist[0])[1]))] |
2168 else: |
2254 else: |
2169 pattern, ok = QInputDialog.getText( |
2255 pattern, ok = QInputDialog.getText( |
2170 None, |
2256 None, |
2171 self.trUtf8("Translation Pattern"), |
2257 self.trUtf8("Translation Pattern"), |
2172 self.trUtf8("Enter the path pattern for translation files " |
2258 self.trUtf8( |
2173 "(use '%language%' in place of the language code):"), |
2259 "Enter the path pattern for translation files " |
|
2260 "(use '%language%' in place of the language code):"), |
2174 QLineEdit.Normal, |
2261 QLineEdit.Normal, |
2175 tslist[0]) |
2262 tslist[0]) |
2176 if pattern: |
2263 if pattern: |
2177 self.pdata["TRANSLATIONPATTERN"] = [pattern] |
2264 self.pdata["TRANSLATIONPATTERN"] = [pattern] |
2178 if self.pdata["TRANSLATIONPATTERN"]: |
2265 if self.pdata["TRANSLATIONPATTERN"]: |
2179 self.pdata["TRANSLATIONPATTERN"][0] = \ |
2266 self.pdata["TRANSLATIONPATTERN"][0] = \ |
2180 self.getRelativePath(self.pdata["TRANSLATIONPATTERN"][0]) |
2267 self.getRelativePath(self.pdata["TRANSLATIONPATTERN"][0]) |
2181 pattern = self.pdata["TRANSLATIONPATTERN"][0].replace("%language%", "*") |
2268 pattern = self.pdata["TRANSLATIONPATTERN"][0]\ |
|
2269 .replace("%language%", "*") |
2182 for ts in tslist: |
2270 for ts in tslist: |
2183 if fnmatch.fnmatch(ts, pattern): |
2271 if fnmatch.fnmatch(ts, pattern): |
2184 self.pdata["TRANSLATIONS"].append(ts) |
2272 self.pdata["TRANSLATIONS"].append(ts) |
2185 self.projectLanguageAdded.emit(ts) |
2273 self.projectLanguageAdded.emit(ts) |
2186 if self.pdata["TRANSLATIONSBINPATH"]: |
2274 if self.pdata["TRANSLATIONSBINPATH"]: |
2187 tpd = os.path.join(self.ppath, |
2275 tpd = os.path.join(self.ppath, |
2188 self.pdata["TRANSLATIONSBINPATH"][0]) |
2276 self.pdata["TRANSLATIONSBINPATH"][0]) |
2189 pattern = os.path.basename(self.pdata["TRANSLATIONPATTERN"][0])\ |
2277 pattern = os.path.basename( |
|
2278 self.pdata["TRANSLATIONPATTERN"][0])\ |
2190 .replace("%language%", "*") |
2279 .replace("%language%", "*") |
2191 pattern = self.__binaryTranslationFile(pattern) |
2280 pattern = self.__binaryTranslationFile(pattern) |
2192 qmlist = Utilities.direntries(tpd, True, pattern) |
2281 qmlist = Utilities.direntries(tpd, True, pattern) |
2193 for qm in qmlist: |
2282 for qm in qmlist: |
2194 self.pdata["TRANSLATIONS"].append(qm) |
2283 self.pdata["TRANSLATIONS"].append(qm) |
2195 self.projectLanguageAdded.emit(qm) |
2284 self.projectLanguageAdded.emit(qm) |
2196 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
2285 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
2197 len(self.pdata["MAINSCRIPT"][0]) == 0: |
2286 len(self.pdata["MAINSCRIPT"][0]) == 0: |
2198 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
2287 if self.pdata["PROGLANGUAGE"][0] in \ |
2199 self.pdata["MAINSCRIPT"] = ['{0}.py'.format(mainscriptname)] |
2288 ["Python", "Python2", "Python3"]: |
|
2289 self.pdata["MAINSCRIPT"] = [ |
|
2290 '{0}.py'.format(mainscriptname)] |
2200 elif self.pdata["PROGLANGUAGE"][0] == "Ruby": |
2291 elif self.pdata["PROGLANGUAGE"][0] == "Ruby": |
2201 self.pdata["MAINSCRIPT"] = ['{0}.rb'.format(mainscriptname)] |
2292 self.pdata["MAINSCRIPT"] = [ |
|
2293 '{0}.rb'.format(mainscriptname)] |
2202 self.setDirty(True) |
2294 self.setDirty(True) |
2203 QApplication.restoreOverrideCursor() |
2295 QApplication.restoreOverrideCursor() |
2204 |
2296 |
2205 def __showProperties(self): |
2297 def __showProperties(self): |
2206 """ |
2298 """ |
2233 os.makedirs(tp) |
2325 os.makedirs(tp) |
2234 if tp != self.ppath and tp not in self.subdirs: |
2326 if tp != self.ppath and tp not in self.subdirs: |
2235 self.subdirs.append(tp) |
2327 self.subdirs.append(tp) |
2236 |
2328 |
2237 if self.pdata["TRANSLATIONSBINPATH"]: |
2329 if self.pdata["TRANSLATIONSBINPATH"]: |
2238 tp = os.path.join(self.ppath, self.pdata["TRANSLATIONSBINPATH"][0]) |
2330 tp = os.path.join( |
|
2331 self.ppath, self.pdata["TRANSLATIONSBINPATH"][0]) |
2239 if not os.path.isdir(tp): |
2332 if not os.path.isdir(tp): |
2240 os.makedirs(tp) |
2333 os.makedirs(tp) |
2241 if tp != self.ppath and tp not in self.subdirs: |
2334 if tp != self.ppath and tp not in self.subdirs: |
2242 self.subdirs.append(tp) |
2335 self.subdirs.append(tp) |
2243 |
2336 |
2244 self.pluginGrp.setEnabled(self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
2337 self.pluginGrp.setEnabled( |
|
2338 self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
2245 |
2339 |
2246 self.__model.projectPropertiesChanged() |
2340 self.__model.projectPropertiesChanged() |
2247 self.projectPropertiesChanged.emit() |
2341 self.projectPropertiesChanged.emit() |
2248 |
2342 |
2249 def __showUserProperties(self): |
2343 def __showUserProperties(self): |
2250 """ |
2344 """ |
2251 Private slot to display the user specific properties dialog. |
2345 Private slot to display the user specific properties dialog. |
2252 """ |
2346 """ |
2253 vcsSystem = self.pdata["VCS"] and self.pdata["VCS"][0] or None |
2347 vcsSystem = self.pdata["VCS"] and self.pdata["VCS"][0] or None |
2254 vcsSystemOverride = \ |
2348 vcsSystemOverride = self.pudata["VCSOVERRIDE"] and \ |
2255 self.pudata["VCSOVERRIDE"] and self.pudata["VCSOVERRIDE"][0] or None |
2349 self.pudata["VCSOVERRIDE"][0] or None |
2256 |
2350 |
2257 from .UserPropertiesDialog import UserPropertiesDialog |
2351 from .UserPropertiesDialog import UserPropertiesDialog |
2258 dlg = UserPropertiesDialog(self) |
2352 dlg = UserPropertiesDialog(self) |
2259 if dlg.exec_() == QDialog.Accepted: |
2353 if dlg.exec_() == QDialog.Accepted: |
2260 dlg.storeData() |
2354 dlg.storeData() |
2383 self.vcs = self.initVCS() |
2481 self.vcs = self.initVCS() |
2384 if self.vcs is None and self.isDirty() == oldState: |
2482 if self.vcs is None and self.isDirty() == oldState: |
2385 # check, if project is version controlled |
2483 # check, if project is version controlled |
2386 pluginManager = e5App().getObject("PluginManager") |
2484 pluginManager = e5App().getObject("PluginManager") |
2387 for indicator, vcsData in \ |
2485 for indicator, vcsData in \ |
2388 list(pluginManager.getVcsSystemIndicators().items()): |
2486 pluginManager.getVcsSystemIndicators().items(): |
2389 if os.path.exists(os.path.join(self.ppath, indicator)): |
2487 if os.path.exists( |
|
2488 os.path.join(self.ppath, indicator)): |
2390 if len(vcsData) > 1: |
2489 if len(vcsData) > 1: |
2391 vcsList = [] |
2490 vcsList = [] |
2392 for vcsSystemStr, vcsSystemDisplay in vcsData: |
2491 for vcsSystemStr, vcsSystemDisplay in \ |
|
2492 vcsData: |
2393 vcsList.append(vcsSystemDisplay) |
2493 vcsList.append(vcsSystemDisplay) |
2394 QApplication.restoreOverrideCursor() |
2494 QApplication.restoreOverrideCursor() |
2395 res, vcs_ok = QInputDialog.getItem( |
2495 res, vcs_ok = QInputDialog.getItem( |
2396 None, |
2496 None, |
2397 self.trUtf8("New Project"), |
2497 self.trUtf8("New Project"), |
2398 self.trUtf8("Select Version Control System"), |
2498 self.trUtf8( |
|
2499 "Select Version Control System"), |
2399 vcsList, |
2500 vcsList, |
2400 0, False) |
2501 0, False) |
2401 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
2502 QApplication.setOverrideCursor( |
|
2503 QCursor(Qt.WaitCursor)) |
2402 QApplication.processEvents() |
2504 QApplication.processEvents() |
2403 if vcs_ok: |
2505 if vcs_ok: |
2404 for vcsSystemStr, vcsSystemDisplay in vcsData: |
2506 for vcsSystemStr, vcsSystemDisplay in \ |
|
2507 vcsData: |
2405 if res == vcsSystemDisplay: |
2508 if res == vcsSystemDisplay: |
2406 vcsSystem = vcsSystemStr |
2509 vcsSystem = vcsSystemStr |
2407 break |
2510 break |
2408 else: |
2511 else: |
2409 vcsSystem = "None" |
2512 vcsSystem = "None" |
2454 |
2559 |
2455 if restoreSession: |
2560 if restoreSession: |
2456 # open the main script |
2561 # open the main script |
2457 if len(self.pdata["MAINSCRIPT"]) == 1: |
2562 if len(self.pdata["MAINSCRIPT"]) == 1: |
2458 self.sourceFile.emit( |
2563 self.sourceFile.emit( |
2459 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
2564 os.path.join( |
|
2565 self.ppath, self.pdata["MAINSCRIPT"][0])) |
2460 |
2566 |
2461 # open a project session file being quiet about errors |
2567 # open a project session file being quiet about errors |
2462 if reopen: |
2568 if reopen: |
2463 self.__readSession(quiet=True, indicator="_tmp") |
2569 self.__readSession(quiet=True, indicator="_tmp") |
2464 elif Preferences.getProject("AutoLoadSession"): |
2570 elif Preferences.getProject("AutoLoadSession"): |
2465 self.__readSession(quiet=True) |
2571 self.__readSession(quiet=True) |
2466 |
2572 |
2467 # open a project debugger properties file being quiet about errors |
2573 # open a project debugger properties file being quiet |
|
2574 # about errors |
2468 if Preferences.getProject("AutoLoadDbgProperties"): |
2575 if Preferences.getProject("AutoLoadDbgProperties"): |
2469 self.__readDebugProperties(True) |
2576 self.__readDebugProperties(True) |
2470 |
2577 |
2471 # start the VCS monitor thread |
2578 # start the VCS monitor thread |
2472 if self.vcs is not None: |
2579 if self.vcs is not None: |
2729 filesWithSyntaxErrors += 1 |
2837 filesWithSyntaxErrors += 1 |
2730 |
2838 |
2731 if reportSyntaxErrors and filesWithSyntaxErrors > 0: |
2839 if reportSyntaxErrors and filesWithSyntaxErrors > 0: |
2732 E5MessageBox.critical(self.ui, |
2840 E5MessageBox.critical(self.ui, |
2733 self.trUtf8("Syntax errors detected"), |
2841 self.trUtf8("Syntax errors detected"), |
2734 self.trUtf8("""The project contains %n file(s) with syntax errors.""", |
2842 self.trUtf8( |
|
2843 """The project contains %n file(s) with syntax errors.""", |
2735 "", filesWithSyntaxErrors) |
2844 "", filesWithSyntaxErrors) |
2736 ) |
2845 ) |
2737 return False |
2846 return False |
2738 else: |
2847 else: |
2739 return success |
2848 return success |
2740 |
2849 |
2741 def getMainScript(self, normalized=False): |
2850 def getMainScript(self, normalized=False): |
2742 """ |
2851 """ |
2743 Public method to return the main script filename. |
2852 Public method to return the main script filename. |
2744 |
2853 |
2745 @param normalized flag indicating a normalized filename is wanted (boolean) |
2854 @param normalized flag indicating a normalized filename is wanted |
|
2855 (boolean) |
2746 @return filename of the projects main script (string) |
2856 @return filename of the projects main script (string) |
2747 """ |
2857 """ |
2748 if len(self.pdata["MAINSCRIPT"]): |
2858 if len(self.pdata["MAINSCRIPT"]): |
2749 if normalized: |
2859 if normalized: |
2750 return os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0]) |
2860 return os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0]) |
3039 |
3154 |
3040 return False |
3155 return False |
3041 |
3156 |
3042 def isProjectSource(self, fn): |
3157 def isProjectSource(self, fn): |
3043 """ |
3158 """ |
3044 Public method used to check, if the passed in filename belongs to the project |
3159 Public method used to check, if the passed in filename belongs to the |
3045 sources. |
3160 project sources. |
3046 |
3161 |
3047 @param fn filename to be checked (string) |
3162 @param fn filename to be checked (string) |
3048 @return flag indicating membership (boolean) |
3163 @return flag indicating membership (boolean) |
3049 """ |
3164 """ |
3050 return self.__checkProjectFileGroup(fn, "SOURCES") |
3165 return self.__checkProjectFileGroup(fn, "SOURCES") |
3051 |
3166 |
3052 def isProjectForm(self, fn): |
3167 def isProjectForm(self, fn): |
3053 """ |
3168 """ |
3054 Public method used to check, if the passed in filename belongs to the project |
3169 Public method used to check, if the passed in filename belongs to the |
3055 forms. |
3170 project forms. |
3056 |
3171 |
3057 @param fn filename to be checked (string) |
3172 @param fn filename to be checked (string) |
3058 @return flag indicating membership (boolean) |
3173 @return flag indicating membership (boolean) |
3059 """ |
3174 """ |
3060 return self.__checkProjectFileGroup(fn, "FORMS") |
3175 return self.__checkProjectFileGroup(fn, "FORMS") |
3061 |
3176 |
3062 def isProjectInterface(self, fn): |
3177 def isProjectInterface(self, fn): |
3063 """ |
3178 """ |
3064 Public method used to check, if the passed in filename belongs to the project |
3179 Public method used to check, if the passed in filename belongs to the |
3065 interfaces. |
3180 project interfaces. |
3066 |
3181 |
3067 @param fn filename to be checked (string) |
3182 @param fn filename to be checked (string) |
3068 @return flag indicating membership (boolean) |
3183 @return flag indicating membership (boolean) |
3069 """ |
3184 """ |
3070 return self.__checkProjectFileGroup(fn, "INTERFACES") |
3185 return self.__checkProjectFileGroup(fn, "INTERFACES") |
3071 |
3186 |
3072 def isProjectResource(self, fn): |
3187 def isProjectResource(self, fn): |
3073 """ |
3188 """ |
3074 Public method used to check, if the passed in filename belongs to the project |
3189 Public method used to check, if the passed in filename belongs to the |
3075 resources. |
3190 project resources. |
3076 |
3191 |
3077 @param fn filename to be checked (string) |
3192 @param fn filename to be checked (string) |
3078 @return flag indicating membership (boolean) |
3193 @return flag indicating membership (boolean) |
3079 """ |
3194 """ |
3080 return self.__checkProjectFileGroup(fn, "RESOURCES") |
3195 return self.__checkProjectFileGroup(fn, "RESOURCES") |
3149 |
3265 |
3150 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), |
3266 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), |
3151 UI.PixmapCache.getIcon("fileMisc.png"), |
3267 UI.PixmapCache.getIcon("fileMisc.png"), |
3152 self.trUtf8('Add &files...'), 0, 0, |
3268 self.trUtf8('Add &files...'), 0, 0, |
3153 self.actGrp2, 'project_add_file') |
3269 self.actGrp2, 'project_add_file') |
3154 self.addFilesAct.setStatusTip(self.trUtf8('Add files to the current project')) |
3270 self.addFilesAct.setStatusTip(self.trUtf8( |
|
3271 'Add files to the current project')) |
3155 self.addFilesAct.setWhatsThis(self.trUtf8( |
3272 self.addFilesAct.setWhatsThis(self.trUtf8( |
3156 """<b>Add files...</b>""" |
3273 """<b>Add files...</b>""" |
3157 """<p>This opens a dialog for adding files""" |
3274 """<p>This opens a dialog for adding files""" |
3158 """ to the current project. The place to add is""" |
3275 """ to the current project. The place to add is""" |
3159 """ determined by the file extension.</p>""" |
3276 """ determined by the file extension.</p>""" |
3160 )) |
3277 )) |
3161 self.addFilesAct.triggered[()].connect(self.addFiles) |
3278 self.addFilesAct.triggered[()].connect(self.addFiles) |
3162 self.actions.append(self.addFilesAct) |
3279 self.actions.append(self.addFilesAct) |
3163 |
3280 |
3164 self.addDirectoryAct = E5Action(self.trUtf8('Add directory to project'), |
3281 self.addDirectoryAct = E5Action( |
3165 UI.PixmapCache.getIcon("dirOpen.png"), |
3282 self.trUtf8('Add directory to project'), |
3166 self.trUtf8('Add directory...'), 0, 0, |
3283 UI.PixmapCache.getIcon("dirOpen.png"), |
3167 self.actGrp2, 'project_add_directory') |
3284 self.trUtf8('Add directory...'), 0, 0, |
|
3285 self.actGrp2, 'project_add_directory') |
3168 self.addDirectoryAct.setStatusTip( |
3286 self.addDirectoryAct.setStatusTip( |
3169 self.trUtf8('Add a directory to the current project')) |
3287 self.trUtf8('Add a directory to the current project')) |
3170 self.addDirectoryAct.setWhatsThis(self.trUtf8( |
3288 self.addDirectoryAct.setWhatsThis(self.trUtf8( |
3171 """<b>Add directory...</b>""" |
3289 """<b>Add directory...</b>""" |
3172 """<p>This opens a dialog for adding a directory""" |
3290 """<p>This opens a dialog for adding a directory""" |
3173 """ to the current project.</p>""" |
3291 """ to the current project.</p>""" |
3174 )) |
3292 )) |
3175 self.addDirectoryAct.triggered[()].connect(self.addDirectory) |
3293 self.addDirectoryAct.triggered[()].connect(self.addDirectory) |
3176 self.actions.append(self.addDirectoryAct) |
3294 self.actions.append(self.addDirectoryAct) |
3177 |
3295 |
3178 self.addLanguageAct = E5Action(self.trUtf8('Add translation to project'), |
3296 self.addLanguageAct = E5Action( |
3179 UI.PixmapCache.getIcon("linguist4.png"), |
3297 self.trUtf8('Add translation to project'), |
3180 self.trUtf8('Add &translation...'), 0, 0, |
3298 UI.PixmapCache.getIcon("linguist4.png"), |
3181 self.actGrp2, 'project_add_translation') |
3299 self.trUtf8('Add &translation...'), 0, 0, |
|
3300 self.actGrp2, 'project_add_translation') |
3182 self.addLanguageAct.setStatusTip( |
3301 self.addLanguageAct.setStatusTip( |
3183 self.trUtf8('Add a translation to the current project')) |
3302 self.trUtf8('Add a translation to the current project')) |
3184 self.addLanguageAct.setWhatsThis(self.trUtf8( |
3303 self.addLanguageAct.setWhatsThis(self.trUtf8( |
3185 """<b>Add translation...</b>""" |
3304 """<b>Add translation...</b>""" |
3186 """<p>This opens a dialog for add a translation""" |
3305 """<p>This opens a dialog for add a translation""" |
3190 self.actions.append(self.addLanguageAct) |
3309 self.actions.append(self.addLanguageAct) |
3191 |
3310 |
3192 act = E5Action(self.trUtf8('Search new files'), |
3311 act = E5Action(self.trUtf8('Search new files'), |
3193 self.trUtf8('Searc&h new files...'), 0, 0, |
3312 self.trUtf8('Searc&h new files...'), 0, 0, |
3194 self.actGrp2, 'project_search_new_files') |
3313 self.actGrp2, 'project_search_new_files') |
3195 act.setStatusTip(self.trUtf8('Search new files in the project directory.')) |
3314 act.setStatusTip(self.trUtf8( |
|
3315 'Search new files in the project directory.')) |
3196 act.setWhatsThis(self.trUtf8( |
3316 act.setWhatsThis(self.trUtf8( |
3197 """<b>Search new files...</b>""" |
3317 """<b>Search new files...</b>""" |
3198 """<p>This searches for new files (sources, *.ui, *.idl) in the project""" |
3318 """<p>This searches for new files (sources, *.ui, *.idl) in""" |
3199 """ directory and registered subdirectories.</p>""" |
3319 """ the project directory and registered subdirectories.</p>""" |
3200 )) |
3320 )) |
3201 act.triggered[()].connect(self.__searchNewFiles) |
3321 act.triggered[()].connect(self.__searchNewFiles) |
3202 self.actions.append(act) |
3322 self.actions.append(act) |
3203 |
3323 |
3204 self.propsAct = E5Action(self.trUtf8('Project properties'), |
3324 self.propsAct = E5Action(self.trUtf8('Project properties'), |
3205 UI.PixmapCache.getIcon("projectProps.png"), |
3325 UI.PixmapCache.getIcon("projectProps.png"), |
3206 self.trUtf8('&Properties...'), 0, 0, self, 'project_properties') |
3326 self.trUtf8('&Properties...'), 0, 0, self, |
|
3327 'project_properties') |
3207 self.propsAct.setStatusTip(self.trUtf8('Show the project properties')) |
3328 self.propsAct.setStatusTip(self.trUtf8('Show the project properties')) |
3208 self.propsAct.setWhatsThis(self.trUtf8( |
3329 self.propsAct.setWhatsThis(self.trUtf8( |
3209 """<b>Properties...</b>""" |
3330 """<b>Properties...</b>""" |
3210 """<p>This shows a dialog to edit the project properties.</p>""" |
3331 """<p>This shows a dialog to edit the project properties.</p>""" |
3211 )) |
3332 )) |
3212 self.propsAct.triggered[()].connect(self.__showProperties) |
3333 self.propsAct.triggered[()].connect(self.__showProperties) |
3213 self.actions.append(self.propsAct) |
3334 self.actions.append(self.propsAct) |
3214 |
3335 |
3215 self.userPropsAct = E5Action(self.trUtf8('User project properties'), |
3336 self.userPropsAct = E5Action(self.trUtf8('User project properties'), |
3216 UI.PixmapCache.getIcon("projectUserProps.png"), |
3337 UI.PixmapCache.getIcon("projectUserProps.png"), |
3217 self.trUtf8('&User Properties...'), 0, 0, self, 'project_user_properties') |
3338 self.trUtf8('&User Properties...'), 0, 0, self, |
|
3339 'project_user_properties') |
3218 self.userPropsAct.setStatusTip(self.trUtf8( |
3340 self.userPropsAct.setStatusTip(self.trUtf8( |
3219 'Show the user specific project properties')) |
3341 'Show the user specific project properties')) |
3220 self.userPropsAct.setWhatsThis(self.trUtf8( |
3342 self.userPropsAct.setWhatsThis(self.trUtf8( |
3221 """<b>User Properties...</b>""" |
3343 """<b>User Properties...</b>""" |
3222 """<p>This shows a dialog to edit the user specific project properties.</p>""" |
3344 """<p>This shows a dialog to edit the user specific project""" |
|
3345 """ properties.</p>""" |
3223 )) |
3346 )) |
3224 self.userPropsAct.triggered[()].connect(self.__showUserProperties) |
3347 self.userPropsAct.triggered[()].connect(self.__showUserProperties) |
3225 self.actions.append(self.userPropsAct) |
3348 self.actions.append(self.userPropsAct) |
3226 |
3349 |
3227 self.filetypesAct = E5Action(self.trUtf8('Filetype Associations'), |
3350 self.filetypesAct = E5Action(self.trUtf8('Filetype Associations'), |
3229 self, 'project_filetype_associatios') |
3352 self, 'project_filetype_associatios') |
3230 self.filetypesAct.setStatusTip( |
3353 self.filetypesAct.setStatusTip( |
3231 self.trUtf8('Show the project filetype associations')) |
3354 self.trUtf8('Show the project filetype associations')) |
3232 self.filetypesAct.setWhatsThis(self.trUtf8( |
3355 self.filetypesAct.setWhatsThis(self.trUtf8( |
3233 """<b>Filetype Associations...</b>""" |
3356 """<b>Filetype Associations...</b>""" |
3234 """<p>This shows a dialog to edit the filetype associations of the project.""" |
3357 """<p>This shows a dialog to edit the filetype associations of""" |
3235 """ These associations determine the type (source, form, interface""" |
3358 """ the project. These associations determine the type""" |
3236 """ or others) with a filename pattern. They are used when adding a file""" |
3359 """ (source, form, interface or others) with a filename""" |
3237 """ to the project and when performing a search for new files.</p>""" |
3360 """ pattern. They are used when adding a file to the project""" |
|
3361 """ and when performing a search for new files.</p>""" |
3238 )) |
3362 )) |
3239 self.filetypesAct.triggered[()].connect(self.__showFiletypeAssociations) |
3363 self.filetypesAct.triggered[()].connect( |
|
3364 self.__showFiletypeAssociations) |
3240 self.actions.append(self.filetypesAct) |
3365 self.actions.append(self.filetypesAct) |
3241 |
3366 |
3242 self.lexersAct = E5Action(self.trUtf8('Lexer Associations'), |
3367 self.lexersAct = E5Action(self.trUtf8('Lexer Associations'), |
3243 self.trUtf8('Lexer Associations...'), 0, 0, |
3368 self.trUtf8('Lexer Associations...'), 0, 0, |
3244 self, 'project_lexer_associatios') |
3369 self, 'project_lexer_associatios') |
3245 self.lexersAct.setStatusTip( |
3370 self.lexersAct.setStatusTip(self.trUtf8( |
3246 self.trUtf8('Show the project lexer associations (overriding defaults)')) |
3371 'Show the project lexer associations (overriding defaults)')) |
3247 self.lexersAct.setWhatsThis(self.trUtf8( |
3372 self.lexersAct.setWhatsThis(self.trUtf8( |
3248 """<b>Lexer Associations...</b>""" |
3373 """<b>Lexer Associations...</b>""" |
3249 """<p>This shows a dialog to edit the lexer associations of the project.""" |
3374 """<p>This shows a dialog to edit the lexer associations of""" |
3250 """ These associations override the global lexer associations. Lexers""" |
3375 """ the project. These associations override the global lexer""" |
3251 """ are used to highlight the editor text.</p>""" |
3376 """ associations. Lexers are used to highlight the editor""" |
|
3377 """ text.</p>""" |
3252 )) |
3378 )) |
3253 self.lexersAct.triggered[()].connect(self.__showLexerAssociations) |
3379 self.lexersAct.triggered[()].connect(self.__showLexerAssociations) |
3254 self.actions.append(self.lexersAct) |
3380 self.actions.append(self.lexersAct) |
3255 |
3381 |
3256 self.dbgActGrp = createActionGroup(self) |
3382 self.dbgActGrp = createActionGroup(self) |
3397 self.codeProfileAct.triggered[()].connect(self.__showProfileData) |
3525 self.codeProfileAct.triggered[()].connect(self.__showProfileData) |
3398 self.actions.append(self.codeProfileAct) |
3526 self.actions.append(self.codeProfileAct) |
3399 |
3527 |
3400 self.graphicsGrp = createActionGroup(self) |
3528 self.graphicsGrp = createActionGroup(self) |
3401 |
3529 |
3402 self.applicationDiagramAct = E5Action(self.trUtf8('Application Diagram'), |
3530 self.applicationDiagramAct = E5Action( |
3403 self.trUtf8('&Application Diagram...'), 0, 0, |
3531 self.trUtf8('Application Diagram'), |
3404 self.graphicsGrp, 'project_application_diagram') |
3532 self.trUtf8('&Application Diagram...'), 0, 0, |
|
3533 self.graphicsGrp, 'project_application_diagram') |
3405 self.applicationDiagramAct.setStatusTip( |
3534 self.applicationDiagramAct.setStatusTip( |
3406 self.trUtf8('Show a diagram of the project.')) |
3535 self.trUtf8('Show a diagram of the project.')) |
3407 self.applicationDiagramAct.setWhatsThis(self.trUtf8( |
3536 self.applicationDiagramAct.setWhatsThis(self.trUtf8( |
3408 """<b>Application Diagram...</b>""" |
3537 """<b>Application Diagram...</b>""" |
3409 """<p>This shows a diagram of the project.</p>""" |
3538 """<p>This shows a diagram of the project.</p>""" |
3410 )) |
3539 )) |
3411 self.applicationDiagramAct.triggered[()].connect(self.handleApplicationDiagram) |
3540 self.applicationDiagramAct.triggered[()].connect( |
|
3541 self.handleApplicationDiagram) |
3412 self.actions.append(self.applicationDiagramAct) |
3542 self.actions.append(self.applicationDiagramAct) |
3413 |
3543 |
3414 self.loadDiagramAct = E5Action(self.trUtf8('Load Diagram'), |
3544 self.loadDiagramAct = E5Action(self.trUtf8('Load Diagram'), |
3415 self.trUtf8('&Load Diagram...'), 0, 0, |
3545 self.trUtf8('&Load Diagram...'), 0, 0, |
3416 self.graphicsGrp, 'project_load_diagram') |
3546 self.graphicsGrp, 'project_load_diagram') |
3445 self.pluginGrp, 'project_plugin_archive') |
3576 self.pluginGrp, 'project_plugin_archive') |
3446 self.pluginArchiveAct.setStatusTip( |
3577 self.pluginArchiveAct.setStatusTip( |
3447 self.trUtf8('Create an eric5 plugin archive file.')) |
3578 self.trUtf8('Create an eric5 plugin archive file.')) |
3448 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3579 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3449 """<b>Create Plugin Archive</b>""" |
3580 """<b>Create Plugin Archive</b>""" |
3450 """<p>This creates an eric5 plugin archive file using the list of files """ |
3581 """<p>This creates an eric5 plugin archive file using the list""" |
3451 """given in the PKGLIST file. The archive name is built from the main """ |
3582 """ of files given in the PKGLIST file. The archive name is""" |
3452 """script name.</p>""" |
3583 """ built from the main script name.</p>""" |
3453 )) |
3584 )) |
3454 self.pluginArchiveAct.triggered[()].connect(self.__pluginCreateArchive) |
3585 self.pluginArchiveAct.triggered[()].connect(self.__pluginCreateArchive) |
3455 self.actions.append(self.pluginArchiveAct) |
3586 self.actions.append(self.pluginArchiveAct) |
3456 |
3587 |
3457 self.pluginSArchiveAct = E5Action(self.trUtf8('Create Plugin Archive (Snapshot)'), |
3588 self.pluginSArchiveAct = E5Action( |
3458 UI.PixmapCache.getIcon("pluginArchiveSnapshot.png"), |
3589 self.trUtf8('Create Plugin Archive (Snapshot)'), |
3459 self.trUtf8('Create Plugin Archive (&Snapshot)'), 0, 0, |
3590 UI.PixmapCache.getIcon("pluginArchiveSnapshot.png"), |
3460 self.pluginGrp, 'project_plugin_sarchive') |
3591 self.trUtf8('Create Plugin Archive (&Snapshot)'), 0, 0, |
3461 self.pluginSArchiveAct.setStatusTip( |
3592 self.pluginGrp, 'project_plugin_sarchive') |
3462 self.trUtf8('Create an eric5 plugin archive file (snapshot release).')) |
3593 self.pluginSArchiveAct.setStatusTip(self.trUtf8( |
|
3594 'Create an eric5 plugin archive file (snapshot release).')) |
3463 self.pluginSArchiveAct.setWhatsThis(self.trUtf8( |
3595 self.pluginSArchiveAct.setWhatsThis(self.trUtf8( |
3464 """<b>Create Plugin Archive (Snapshot)</b>""" |
3596 """<b>Create Plugin Archive (Snapshot)</b>""" |
3465 """<p>This creates an eric5 plugin archive file using the list of files """ |
3597 """<p>This creates an eric5 plugin archive file using the list""" |
3466 """given in the PKGLIST file. The archive name is built from the main """ |
3598 """ of files given in the PKGLIST file. The archive name is""" |
3467 """script name. The version entry of the main script is modified to """ |
3599 """ built from the main script name. The version entry of the""" |
3468 """reflect a snapshot release.</p>""" |
3600 """ main script is modified to reflect a snapshot release.</p>""" |
3469 )) |
3601 )) |
3470 self.pluginSArchiveAct.triggered[()].connect(self.__pluginCreateSnapshotArchive) |
3602 self.pluginSArchiveAct.triggered[()].connect( |
|
3603 self.__pluginCreateSnapshotArchive) |
3471 self.actions.append(self.pluginSArchiveAct) |
3604 self.actions.append(self.pluginSArchiveAct) |
3472 |
3605 |
3473 self.closeAct.setEnabled(False) |
3606 self.closeAct.setEnabled(False) |
3474 self.saveAct.setEnabled(False) |
3607 self.saveAct.setEnabled(False) |
3475 self.saveasAct.setEnabled(False) |
3608 self.saveasAct.setEnabled(False) |
3754 for pattern in reversed(sorted(self.pdata["FILETYPES"].keys())): |
3890 for pattern in reversed(sorted(self.pdata["FILETYPES"].keys())): |
3755 if fnmatch.fnmatch(bfn, pattern): |
3891 if fnmatch.fnmatch(bfn, pattern): |
3756 filetype = self.pdata["FILETYPES"][pattern] |
3892 filetype = self.pdata["FILETYPES"][pattern] |
3757 break |
3893 break |
3758 |
3894 |
3759 if (filetype == "SOURCES" and fn not in self.pdata["SOURCES"]) or \ |
3895 if (filetype == "SOURCES" and |
3760 (filetype == "FORMS" and fn not in self.pdata["FORMS"]) or \ |
3896 fn not in self.pdata["SOURCES"]) or \ |
3761 (filetype == "INTERFACES" and fn not in self.pdata["INTERFACES"]) or \ |
3897 (filetype == "FORMS" and |
3762 (filetype == "RESOURCES" and fn not in self.pdata["RESOURCES"]) or \ |
3898 fn not in self.pdata["FORMS"]) or \ |
|
3899 (filetype == "INTERFACES" and |
|
3900 fn not in self.pdata["INTERFACES"]) or \ |
|
3901 (filetype == "RESOURCES" and |
|
3902 fn not in self.pdata["RESOURCES"]) or \ |
3763 (filetype == "OTHERS" and fn not in self.pdata["OTHERS"]): |
3903 (filetype == "OTHERS" and fn not in self.pdata["OTHERS"]): |
3764 if autoInclude and AI: |
3904 if autoInclude and AI: |
3765 self.appendFile(ns) |
3905 self.appendFile(ns) |
3766 else: |
3906 else: |
3767 newFiles.append(ns) |
3907 newFiles.append(ns) |
3768 elif filetype == "TRANSLATIONS" and fn not in self.pdata["TRANSLATIONS"]: |
3908 elif filetype == "TRANSLATIONS" and \ |
3769 if fnmatch.fnmatch(ns, pattern) or fnmatch.fnmatch(ns, binpattern): |
3909 fn not in self.pdata["TRANSLATIONS"]: |
|
3910 if fnmatch.fnmatch(ns, pattern) or \ |
|
3911 fnmatch.fnmatch(ns, binpattern): |
3770 if autoInclude and AI: |
3912 if autoInclude and AI: |
3771 self.appendFile(ns) |
3913 self.appendFile(ns) |
3772 else: |
3914 else: |
3773 newFiles.append(ns) |
3915 newFiles.append(ns) |
3774 |
3916 |
3910 if override: |
4055 if override: |
3911 # override failed, revert to original |
4056 # override failed, revert to original |
3912 QApplication.restoreOverrideCursor() |
4057 QApplication.restoreOverrideCursor() |
3913 E5MessageBox.critical(self.ui, |
4058 E5MessageBox.critical(self.ui, |
3914 self.trUtf8("Version Control System"), |
4059 self.trUtf8("Version Control System"), |
3915 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found." |
4060 self.trUtf8( |
3916 "<br/>Reverting override.</p><p>{1}</p>")\ |
4061 "<p>The selected VCS <b>{0}</b> could not be found." |
|
4062 "<br/>Reverting override.</p><p>{1}</p>")\ |
3917 .format(vcsSystem, msg)) |
4063 .format(vcsSystem, msg)) |
3918 self.pudata["VCSOVERRIDE"] = [] |
4064 self.pudata["VCSOVERRIDE"] = [] |
3919 return self.initVCS(nooverride=True) |
4065 return self.initVCS(nooverride=True) |
3920 |
4066 |
3921 QApplication.restoreOverrideCursor() |
4067 QApplication.restoreOverrideCursor() |
3922 E5MessageBox.critical(self.ui, |
4068 E5MessageBox.critical(self.ui, |
3923 self.trUtf8("Version Control System"), |
4069 self.trUtf8("Version Control System"), |
3924 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found.<br/>" |
4070 self.trUtf8( |
3925 "Disabling version control.</p><p>{1}</p>")\ |
4071 "<p>The selected VCS <b>{0}</b> could not be" |
3926 .format(vcsSystem, msg)) |
4072 " found.<br/>Disabling version control.</p>" |
|
4073 "<p>{1}</p>").format(vcsSystem, msg)) |
3927 vcs = None |
4074 vcs = None |
3928 if forProject: |
4075 if forProject: |
3929 self.pdata["VCS"][0] = 'None' |
4076 self.pdata["VCS"][0] = 'None' |
3930 self.setDirty(True) |
4077 self.setDirty(True) |
3931 else: |
4078 else: |
4301 if self.pdata["EOL"][0] == 0: |
4450 if self.pdata["EOL"][0] == 0: |
4302 newline = None |
4451 newline = None |
4303 else: |
4452 else: |
4304 newline = self.getEolString() |
4453 newline = self.getEolString() |
4305 pkglistFile = open(pkglist, "w", encoding="utf-8", newline=newline) |
4454 pkglistFile = open(pkglist, "w", encoding="utf-8", newline=newline) |
4306 pkglistFile.write("\n".join([Utilities.fromNativeSeparators(f) for f in lst])) |
4455 pkglistFile.write( |
|
4456 "\n".join([Utilities.fromNativeSeparators(f) for f in lst])) |
4307 pkglistFile.write("\n") # ensure the file ends with an empty line |
4457 pkglistFile.write("\n") # ensure the file ends with an empty line |
4308 pkglistFile.close() |
4458 pkglistFile.close() |
4309 except IOError as why: |
4459 except IOError as why: |
4310 E5MessageBox.critical(self.ui, |
4460 E5MessageBox.critical(self.ui, |
4311 self.trUtf8("Create Package List"), |
4461 self.trUtf8("Create Package List"), |
4312 self.trUtf8("""<p>The file <b>PKGLIST</b> could not be created.</p>""" |
4462 self.trUtf8( |
4313 """<p>Reason: {0}</p>""").format(str(why))) |
4463 """<p>The file <b>PKGLIST</b> could not be created.</p>""" |
|
4464 """<p>Reason: {0}</p>""").format(str(why))) |
4314 return |
4465 return |
4315 |
4466 |
4316 if not "PKGLIST" in self.pdata["OTHERS"]: |
4467 if not "PKGLIST" in self.pdata["OTHERS"]: |
4317 self.appendFile("PKGLIST") |
4468 self.appendFile("PKGLIST") |
4318 |
4469 |
4332 |
4483 |
4333 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
4484 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
4334 len(self.pdata["MAINSCRIPT"][0]) == 0: |
4485 len(self.pdata["MAINSCRIPT"][0]) == 0: |
4335 E5MessageBox.critical(self.ui, |
4486 E5MessageBox.critical(self.ui, |
4336 self.trUtf8("Create Plugin Archive"), |
4487 self.trUtf8("Create Plugin Archive"), |
4337 self.trUtf8("""The project does not have a main script defined. """ |
4488 self.trUtf8( |
4338 """Aborting...""")) |
4489 """The project does not have a main script defined. """ |
|
4490 """Aborting...""")) |
4339 return |
4491 return |
4340 |
4492 |
4341 try: |
4493 try: |
4342 pkglistFile = open(pkglist, "r", encoding="utf-8") |
4494 pkglistFile = open(pkglist, "r", encoding="utf-8") |
4343 names = pkglistFile.read() |
4495 names = pkglistFile.read() |
4344 pkglistFile.close() |
4496 pkglistFile.close() |
4345 names = sorted(names.splitlines()) |
4497 names = sorted(names.splitlines()) |
4346 except IOError as why: |
4498 except IOError as why: |
4347 E5MessageBox.critical(self.ui, |
4499 E5MessageBox.critical(self.ui, |
4348 self.trUtf8("Create Plugin Archive"), |
4500 self.trUtf8("Create Plugin Archive"), |
4349 self.trUtf8("""<p>The file <b>PKGLIST</b> could not be read.</p>""" |
4501 self.trUtf8( |
4350 """<p>Reason: {0}</p>""").format(str(why))) |
4502 """<p>The file <b>PKGLIST</b> could not be read.</p>""" |
|
4503 """<p>Reason: {0}</p>""").format(str(why))) |
4351 return |
4504 return |
4352 |
4505 |
4353 archive = \ |
4506 archive = os.path.join( |
4354 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0].replace(".py", ".zip")) |
4507 self.ppath, self.pdata["MAINSCRIPT"][0].replace(".py", ".zip")) |
4355 try: |
4508 try: |
4356 archiveFile = zipfile.ZipFile(archive, "w") |
4509 archiveFile = zipfile.ZipFile(archive, "w") |
4357 except IOError as why: |
4510 except IOError as why: |
4358 E5MessageBox.critical(self.ui, |
4511 E5MessageBox.critical(self.ui, |
4359 self.trUtf8("Create Plugin Archive"), |
4512 self.trUtf8("Create Plugin Archive"), |
4360 self.trUtf8("""<p>The eric5 plugin archive file <b>{0}</b> could """ |
4513 self.trUtf8( |
4361 """not be created.</p>""" |
4514 """<p>The eric5 plugin archive file <b>{0}</b> could """ |
4362 """<p>Reason: {1}</p>""").format(archive, str(why))) |
4515 """not be created.</p>""" |
|
4516 """<p>Reason: {1}</p>""").format(archive, str(why))) |
4363 return |
4517 return |
4364 |
4518 |
4365 for name in names: |
4519 for name in names: |
4366 if name: |
4520 if name: |
4367 try: |
4521 try: |
4368 self.__createZipDirEntries(os.path.split(name)[0], archiveFile) |
4522 self.__createZipDirEntries( |
|
4523 os.path.split(name)[0], archiveFile) |
4369 if snapshot and name == self.pdata["MAINSCRIPT"][0]: |
4524 if snapshot and name == self.pdata["MAINSCRIPT"][0]: |
4370 snapshotSource, version = self.__createSnapshotSource( |
4525 snapshotSource, version = self.__createSnapshotSource( |
4371 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
4526 os.path.join(self.ppath, |
|
4527 self.pdata["MAINSCRIPT"][0])) |
4372 archiveFile.writestr(name, snapshotSource) |
4528 archiveFile.writestr(name, snapshotSource) |
4373 else: |
4529 else: |
4374 archiveFile.write(os.path.join(self.ppath, name), name) |
4530 archiveFile.write(os.path.join(self.ppath, name), name) |
4375 if name == self.pdata["MAINSCRIPT"][0]: |
4531 if name == self.pdata["MAINSCRIPT"][0]: |
4376 version = self.__pluginExtractVersion( |
4532 version = self.__pluginExtractVersion( |
4377 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
4533 os.path.join(self.ppath, |
|
4534 self.pdata["MAINSCRIPT"][0])) |
4378 except OSError as why: |
4535 except OSError as why: |
4379 E5MessageBox.critical(self.ui, |
4536 E5MessageBox.critical(self.ui, |
4380 self.trUtf8("Create Plugin Archive"), |
4537 self.trUtf8("Create Plugin Archive"), |
4381 self.trUtf8("""<p>The file <b>{0}</b> could not be stored """ |
4538 self.trUtf8( |
4382 """in the archive. Ignoring it.</p>""" |
4539 """<p>The file <b>{0}</b> could not be stored """ |
4383 """<p>Reason: {1}</p>""")\ |
4540 """in the archive. Ignoring it.</p>""" |
4384 .format(os.path.join(self.ppath, name), str(why))) |
4541 """<p>Reason: {1}</p>""")\ |
|
4542 .format(os.path.join(self.ppath, name), str(why))) |
4385 archiveFile.writestr("VERSION", version.encode("utf-8")) |
4543 archiveFile.writestr("VERSION", version.encode("utf-8")) |
4386 archiveFile.close() |
4544 archiveFile.close() |
4387 |
4545 |
4388 if not archive in self.pdata["OTHERS"]: |
4546 if not archive in self.pdata["OTHERS"]: |
4389 self.appendFile(archive) |
4547 self.appendFile(archive) |
4390 |
4548 |
4391 if self.ui.notificationsEnabled(): |
4549 if self.ui.notificationsEnabled(): |
4392 self.ui.showNotification(UI.PixmapCache.getPixmap("pluginArchive48.png"), |
4550 self.ui.showNotification( |
|
4551 UI.PixmapCache.getPixmap("pluginArchive48.png"), |
4393 self.trUtf8("Create Plugin Archive"), |
4552 self.trUtf8("Create Plugin Archive"), |
4394 self.trUtf8("""<p>The eric5 plugin archive file <b>{0}</b> was """ |
4553 self.trUtf8( |
4395 """created successfully.</p>""")\ |
4554 """<p>The eric5 plugin archive file <b>{0}</b> was """ |
|
4555 """created successfully.</p>""")\ |
4396 .format(os.path.basename(archive))) |
4556 .format(os.path.basename(archive))) |
4397 else: |
4557 else: |
4398 E5MessageBox.information(self.ui, |
4558 E5MessageBox.information(self.ui, |
4399 self.trUtf8("Create Plugin Archive"), |
4559 self.trUtf8("Create Plugin Archive"), |
4400 self.trUtf8("""<p>The eric5 plugin archive file <b>{0}</b> was """ |
4560 self.trUtf8( |
4401 """created successfully.</p>""").format(archive)) |
4561 """<p>The eric5 plugin archive file <b>{0}</b> was """ |
|
4562 """created successfully.</p>""").format(archive)) |
4402 |
4563 |
4403 def __pluginCreateSnapshotArchive(self): |
4564 def __pluginCreateSnapshotArchive(self): |
4404 """ |
4565 """ |
4405 Private slot to create an eric5 plugin archive snapshot release. |
4566 Private slot to create an eric5 plugin archive snapshot release. |
4406 """ |
4567 """ |
4440 except (IOError, UnicodeError) as why: |
4601 except (IOError, UnicodeError) as why: |
4441 E5MessageBox.critical(self.ui, |
4602 E5MessageBox.critical(self.ui, |
4442 self.trUtf8("Create Plugin Archive"), |
4603 self.trUtf8("Create Plugin Archive"), |
4443 self.trUtf8("""<p>The plugin file <b>{0}</b> could """ |
4604 self.trUtf8("""<p>The plugin file <b>{0}</b> could """ |
4444 """not be read.</p>""" |
4605 """not be read.</p>""" |
4445 """<p>Reason: {1}</p>""").format(filename, str(why))) |
4606 """<p>Reason: {1}</p>""") |
|
4607 .format(filename, str(why))) |
4446 return b"", "" |
4608 return b"", "" |
4447 |
4609 |
4448 lineno = 0 |
4610 lineno = 0 |
4449 while lineno < len(sourcelines): |
4611 while lineno < len(sourcelines): |
4450 if sourcelines[lineno].startswith("version = "): |
4612 if sourcelines[lineno].startswith("version = "): |
4451 # found the line to modify |
4613 # found the line to modify |
4452 datestr = time.strftime("%Y%m%d") |
4614 datestr = time.strftime("%Y%m%d") |
4453 lineend = sourcelines[lineno].replace(sourcelines[lineno].rstrip(), "") |
4615 lineend = sourcelines[lineno]\ |
4454 sversion = "{0}-snapshot-{1}".format( |
4616 .replace(sourcelines[lineno].rstrip(), "") |
4455 sourcelines[lineno].replace("version = ", "").strip()[1:-1], |
4617 sversion = "{0}-snapshot-{1}".format(sourcelines[lineno]\ |
|
4618 .replace("version = ", "").strip()[1:-1], |
4456 datestr) |
4619 datestr) |
4457 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4620 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4458 sourcelines[lineno].rstrip(), datestr, lineend) |
4621 sourcelines[lineno].rstrip(), datestr, lineend) |
4459 break |
4622 break |
4460 |
4623 |