44 """ |
44 """ |
45 Class implementing the project management functionality. |
45 Class implementing the project management functionality. |
46 |
46 |
47 @signal dirty(int) emitted when the dirty state changes |
47 @signal dirty(int) emitted when the dirty state changes |
48 @signal projectLanguageAdded(str) emitted after a new language was added |
48 @signal projectLanguageAdded(str) emitted after a new language was added |
49 @signal projectLanguageAddedByCode(str) emitted after a new language was added. |
49 @signal projectLanguageAddedByCode(str) emitted after a new language was |
50 The language code is sent by this signal. |
50 added. The language code is sent by this signal. |
51 @signal projectLanguageRemoved(str) emitted after a language was removed |
51 @signal projectLanguageRemoved(str) emitted after a language was removed |
52 @signal projectFormAdded(str) emitted after a new form was added |
52 @signal projectFormAdded(str) emitted after a new form was added |
53 @signal projectFormRemoved(str) emitted after a form was removed |
53 @signal projectFormRemoved(str) emitted after a form was removed |
54 @signal projectFormCompiled(str) emitted after a form was compiled |
54 @signal projectFormCompiled(str) emitted after a form was compiled |
55 @signal projectSourceAdded(str) emitted after a new source file was added |
55 @signal projectSourceAdded(str) emitted after a new source file was added |
56 @signal projectSourceRemoved(str) emitted after a source was removed |
56 @signal projectSourceRemoved(str) emitted after a source was removed |
57 @signal projectInterfaceAdded(str) emitted after a new IDL file was added |
57 @signal projectInterfaceAdded(str) emitted after a new IDL file was added |
58 @signal projectInterfaceRemoved(str) emitted after a IDL file was removed |
58 @signal projectInterfaceRemoved(str) emitted after a IDL file was removed |
59 @signal projectResourceAdded(str) emitted after a new resource file was added |
59 @signal projectResourceAdded(str) emitted after a new resource file was |
|
60 added |
60 @signal projectResourceRemoved(str) emitted after a resource was removed |
61 @signal projectResourceRemoved(str) emitted after a resource was removed |
61 @signal projectOthersAdded(str) emitted after a file or directory was added |
62 @signal projectOthersAdded(str) emitted after a file or directory was added |
62 to the OTHERS project data area |
63 to the OTHERS project data area |
63 @signal projectOthersRemoved(str) emitted after a file was removed from the |
64 @signal projectOthersRemoved(str) emitted after a file was removed from the |
64 OTHERS project data area |
65 OTHERS project data area |
65 @signal projectAboutToBeCreated() emitted just before the project will be created |
66 @signal projectAboutToBeCreated() emitted just before the project will be |
66 @signal newProjectHooks() emitted after a new project was generated but before |
67 created |
67 the newProject() signal is sent |
68 @signal newProjectHooks() emitted after a new project was generated but |
|
69 before the newProject() signal is sent |
68 @signal newProject() emitted after a new project was generated |
70 @signal newProject() emitted after a new project was generated |
69 @signal sourceFile(str) emitted after a project file was read to |
71 @signal sourceFile(str) emitted after a project file was read to |
70 open the main script |
72 open the main script |
71 @signal projectOpenedHooks() emitted after a project file was read but before the |
73 @signal projectOpenedHooks() emitted after a project file was read but |
72 projectOpened() signal is sent |
74 before the projectOpened() signal is sent |
73 @signal projectOpened() emitted after a project file was read |
75 @signal projectOpened() emitted after a project file was read |
74 @signal projectClosedHooks() emitted after a project file was closed but before the |
76 @signal projectClosedHooks() emitted after a project file was closed but |
75 projectClosed() signal is sent |
77 before the projectClosed() signal is sent |
76 @signal projectClosed() emitted after a project was closed |
78 @signal projectClosed() emitted after a project was closed |
77 @signal projectFileRenamed(str, str) emitted after a file of the project |
79 @signal projectFileRenamed(str, str) emitted after a file of the project |
78 has been renamed |
80 has been renamed |
79 @signal projectPropertiesChanged() emitted after the project properties were changed |
81 @signal projectPropertiesChanged() emitted after the project properties |
80 @signal directoryRemoved(str) emitted after a directory has been removed from |
82 were changed |
81 the project |
83 @signal directoryRemoved(str) emitted after a directory has been removed |
|
84 from the project |
82 @signal prepareRepopulateItem(str) emitted before an item of the model is |
85 @signal prepareRepopulateItem(str) emitted before an item of the model is |
83 repopulated |
86 repopulated |
84 @signal completeRepopulateItem(str) emitted after an item of the model was |
87 @signal completeRepopulateItem(str) emitted after an item of the model was |
85 repopulated |
88 repopulated |
86 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of the |
89 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of |
87 monitoring thread (ok, nok, op, off) and a status message |
90 the monitoring thread (ok, nok, op, off) and a status message |
88 @signal reinitVCS() emitted after the VCS has been reinitialized |
91 @signal reinitVCS() emitted after the VCS has been reinitialized |
89 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The name |
92 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The |
90 of the menu and a reference to the menu are given. |
93 name of the menu and a reference to the menu are given. |
91 @signal lexerAssociationsChanged() emitted after the lexer associations have been |
94 @signal lexerAssociationsChanged() emitted after the lexer associations |
92 changed |
95 have been changed |
93 @signal projectChanged() emitted to signal a change of the project |
96 @signal projectChanged() emitted to signal a change of the project |
94 """ |
97 """ |
95 dirty = pyqtSignal(int) |
98 dirty = pyqtSignal(int) |
96 projectLanguageAdded = pyqtSignal(str) |
99 projectLanguageAdded = pyqtSignal(str) |
97 projectLanguageAddedByCode = pyqtSignal(str) |
100 projectLanguageAddedByCode = pyqtSignal(str) |
241 self.__projectTypes["E4Plugin"] = self.trUtf8("Eric Plugin") |
244 self.__projectTypes["E4Plugin"] = self.trUtf8("Eric Plugin") |
242 self.__projectTypes["Console"] = self.trUtf8("Console") |
245 self.__projectTypes["Console"] = self.trUtf8("Console") |
243 self.__projectTypes["Other"] = self.trUtf8("Other") |
246 self.__projectTypes["Other"] = self.trUtf8("Other") |
244 |
247 |
245 self.__projectProgLanguages = { |
248 self.__projectProgLanguages = { |
246 "Python2": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "Console", "Other"], |
249 "Python2": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", |
247 "Python3": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "Console", "Other"], |
250 "Console", "Other"], |
|
251 "Python3": ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", |
|
252 "Console", "Other"], |
248 "Ruby": ["Qt4", "Qt4C", "Console", "Other"], |
253 "Ruby": ["Qt4", "Qt4C", "Console", "Other"], |
249 } |
254 } |
250 |
255 |
251 pyside2, pyside3 = Utilities.checkPyside() |
256 pyside2, pyside3 = Utilities.checkPyside() |
252 if pyside2 or pyside3: |
257 if pyside2 or pyside3: |
253 self.__projectTypes["PySide"] = self.trUtf8("PySide GUI") |
258 self.__projectTypes["PySide"] = self.trUtf8("PySide GUI") |
254 self.__projectTypes["PySideC"] = self.trUtf8("PySide Console") |
259 self.__projectTypes["PySideC"] = self.trUtf8("PySide Console") |
255 if pyside2: |
260 if pyside2: |
256 self.__projectProgLanguages["Python2"].extend(["PySide", "PySideC"]) |
261 self.__projectProgLanguages["Python2"].extend( |
|
262 ["PySide", "PySideC"]) |
257 if pyside3: |
263 if pyside3: |
258 self.__projectProgLanguages["Python3"].extend(["PySide", "PySideC"]) |
264 self.__projectProgLanguages["Python3"].extend( |
|
265 ["PySide", "PySideC"]) |
259 |
266 |
260 def getProjectTypes(self, progLanguage=""): |
267 def getProjectTypes(self, progLanguage=""): |
261 """ |
268 """ |
262 Public method to get the list of supported project types. |
269 Public method to get the list of supported project types. |
263 |
270 |
264 @param progLanguage programming language to get project types for (string) |
271 @param progLanguage programming language to get project types for |
|
272 (string) |
265 @return reference to the dictionary of project types. |
273 @return reference to the dictionary of project types. |
266 """ |
274 """ |
267 if progLanguage and progLanguage in self.__projectProgLanguages: |
275 if progLanguage and progLanguage in self.__projectProgLanguages: |
268 ptypes = {} |
276 ptypes = {} |
269 for ptype in self.__projectProgLanguages[progLanguage]: |
277 for ptype in self.__projectProgLanguages[progLanguage]: |
308 if progLanguages: |
316 if progLanguages: |
309 for progLanguage in progLanguages: |
317 for progLanguage in progLanguages: |
310 if progLanguage not in self.__projectProgLanguages: |
318 if progLanguage not in self.__projectProgLanguages: |
311 E5MessageBox.critical(self.ui, |
319 E5MessageBox.critical(self.ui, |
312 self.trUtf8("Registering Project Type"), |
320 self.trUtf8("Registering Project Type"), |
313 self.trUtf8("""<p>The Programming Language <b>{0}</b> is not""" |
321 self.trUtf8( |
314 """ supported.</p>""")\ |
322 """<p>The Programming Language <b>{0}</b> is not""" |
|
323 """ supported.</p>""")\ |
315 .format(progLanguage) |
324 .format(progLanguage) |
316 ) |
325 ) |
317 return |
326 return |
318 |
327 |
319 if type_ in self.__projectProgLanguages[progLanguage]: |
328 if type_ in self.__projectProgLanguages[progLanguage]: |
320 E5MessageBox.critical(self.ui, |
329 E5MessageBox.critical(self.ui, |
321 self.trUtf8("Registering Project Type"), |
330 self.trUtf8("Registering Project Type"), |
322 self.trUtf8("""<p>The Project type <b>{0}</b> is already""" |
331 self.trUtf8( |
323 """ registered with Programming Language""" |
332 """<p>The Project type <b>{0}</b> is already""" |
324 """ <b>{1}</b>.</p>""")\ |
333 """ registered with Programming Language""" |
|
334 """ <b>{1}</b>.</p>""")\ |
325 .format(type_, progLanguage) |
335 .format(type_, progLanguage) |
326 ) |
336 ) |
327 return |
337 return |
328 |
338 |
329 if type_ in self.__projectTypes: |
339 if type_ in self.__projectTypes: |
421 def getData(self, category, key): |
433 def getData(self, category, key): |
422 """ |
434 """ |
423 Public method to get data out of the project data store. |
435 Public method to get data out of the project data store. |
424 |
436 |
425 @param category category of the data to get (string, one of |
437 @param category category of the data to get (string, one of |
426 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, DOCUMENTATIONPARMS |
438 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, |
427 or OTHERTOOLSPARMS) |
439 DOCUMENTATIONPARMS or OTHERTOOLSPARMS) |
428 @param key key of the data entry to get (string). |
440 @param key key of the data entry to get (string). |
429 @return a copy of the requested data or None |
441 @return a copy of the requested data or None |
430 """ |
442 """ |
431 if category in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
443 if category in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", |
432 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"] and \ |
444 "PACKAGERSPARMS", "DOCUMENTATIONPARMS", |
|
445 "OTHERTOOLSPARMS"] and \ |
433 key in self.pdata[category]: |
446 key in self.pdata[category]: |
434 return copy.deepcopy(self.pdata[category][key]) |
447 return copy.deepcopy(self.pdata[category][key]) |
435 else: |
448 else: |
436 return None |
449 return None |
437 |
450 |
438 def setData(self, category, key, data): |
451 def setData(self, category, key, data): |
439 """ |
452 """ |
440 Public method to store data in the project data store. |
453 Public method to store data in the project data store. |
441 |
454 |
442 @param category category of the data to get (string, one of |
455 @param category category of the data to get (string, one of |
443 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, DOCUMENTATIONPARMS |
456 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, |
444 or OTHERTOOLSPARMS) |
457 DOCUMENTATIONPARMS or OTHERTOOLSPARMS) |
445 @param key key of the data entry to get (string). |
458 @param key key of the data entry to get (string). |
446 @param data data to be stored |
459 @param data data to be stored |
447 @return flag indicating success (boolean) |
460 @return flag indicating success (boolean) |
448 """ |
461 """ |
449 if category not in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
462 if category not in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", |
450 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"]: |
463 "PACKAGERSPARMS", "DOCUMENTATIONPARMS", |
|
464 "OTHERTOOLSPARMS"]: |
451 return False |
465 return False |
452 |
466 |
453 # test for changes of data and save them in the project |
467 # test for changes of data and save them in the project |
454 # 1. there were none, now there are |
468 # 1. there were none, now there are |
455 if key not in self.pdata[category] and len(data) > 0: |
469 if key not in self.pdata[category] and len(data) > 0: |
469 return False |
483 return False |
470 return True |
484 return True |
471 |
485 |
472 def initFileTypes(self): |
486 def initFileTypes(self): |
473 """ |
487 """ |
474 Public method to initialize the filetype associations with default values. |
488 Public method to initialize the filetype associations with default |
|
489 values. |
475 """ |
490 """ |
476 self.pdata["FILETYPES"] = {} |
491 self.pdata["FILETYPES"] = {} |
477 if self.pdata["MIXEDLANGUAGE"][0]: |
492 if self.pdata["MIXEDLANGUAGE"][0]: |
478 sourceKey = "Mixed" |
493 sourceKey = "Mixed" |
479 else: |
494 else: |
480 sourceKey = self.pdata["PROGLANGUAGE"][0] |
495 sourceKey = self.pdata["PROGLANGUAGE"][0] |
481 for ext in self.sourceExtensions[sourceKey]: |
496 for ext in self.sourceExtensions[sourceKey]: |
482 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" |
497 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" |
483 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" |
498 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" |
484 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "PyQt5", "E4Plugin", "PySide"]: |
499 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "PyQt5", "E4Plugin", |
|
500 "PySide"]: |
485 self.pdata["FILETYPES"]["*.ui"] = "FORMS" |
501 self.pdata["FILETYPES"]["*.ui"] = "FORMS" |
486 self.pdata["FILETYPES"]["*.ui.h"] = "FORMS" |
502 self.pdata["FILETYPES"]["*.ui.h"] = "FORMS" |
487 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
503 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
488 "PyQt5", "PyQt5C", |
504 "PyQt5", "PyQt5C", |
489 "PySide", "PySideC"]: |
505 "PySide", "PySideC"]: |
492 "PyQt5", "PyQt5C", |
508 "PyQt5", "PyQt5C", |
493 "PySide", "PySideC"]: |
509 "PySide", "PySideC"]: |
494 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
510 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
495 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
511 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
496 try: |
512 try: |
497 if self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]] is not None: |
513 if self.__fileTypeCallbacks[ |
498 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
514 self.pdata["PROJECTTYPE"][0]] is not None: |
|
515 ftypes = \ |
|
516 self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
499 self.pdata["FILETYPES"].update(ftypes) |
517 self.pdata["FILETYPES"].update(ftypes) |
500 except KeyError: |
518 except KeyError: |
501 pass |
519 pass |
502 self.setDirty(True) |
520 self.setDirty(True) |
503 |
521 |
504 def updateFileTypes(self): |
522 def updateFileTypes(self): |
505 """ |
523 """ |
506 Public method to update the filetype associations with new default values. |
524 Public method to update the filetype associations with new default |
|
525 values. |
507 """ |
526 """ |
508 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
527 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
509 "PyQt5", "PyQt5C", |
528 "PyQt5", "PyQt5C", |
510 "PySide", "PySideC"]: |
529 "PySide", "PySideC"]: |
511 if "*.ts" not in self.pdata["FILETYPES"]: |
530 if "*.ts" not in self.pdata["FILETYPES"]: |
512 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
531 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
513 if "*.qm" not in self.pdata["FILETYPES"]: |
532 if "*.qm" not in self.pdata["FILETYPES"]: |
514 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
533 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
515 try: |
534 try: |
516 if self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]] is not None: |
535 if self.__fileTypeCallbacks[ |
517 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
536 self.pdata["PROJECTTYPE"][0]] is not None: |
|
537 ftypes = \ |
|
538 self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]]() |
518 for pattern, ftype in list(ftypes.items()): |
539 for pattern, ftype in list(ftypes.items()): |
519 if pattern not in self.pdata["FILETYPES"]: |
540 if pattern not in self.pdata["FILETYPES"]: |
520 self.pdata["FILETYPES"][pattern] = ftype |
541 self.pdata["FILETYPES"][pattern] = ftype |
521 self.setDirty(True) |
542 self.setDirty(True) |
522 except KeyError: |
543 except KeyError: |
664 if res: |
686 if res: |
665 if len(self.pdata["TRANSLATIONPATTERN"]) == 1: |
687 if len(self.pdata["TRANSLATIONPATTERN"]) == 1: |
666 self.translationsRoot = \ |
688 self.translationsRoot = \ |
667 self.pdata["TRANSLATIONPATTERN"][0].split("%language%")[0] |
689 self.pdata["TRANSLATIONPATTERN"][0].split("%language%")[0] |
668 elif len(self.pdata["MAINSCRIPT"]) == 1: |
690 elif len(self.pdata["MAINSCRIPT"]) == 1: |
669 self.translationsRoot = os.path.splitext(self.pdata["MAINSCRIPT"][0])[0] |
691 self.translationsRoot = os.path.splitext( |
|
692 self.pdata["MAINSCRIPT"][0])[0] |
670 if os.path.isdir(os.path.join(self.ppath, self.translationsRoot)): |
693 if os.path.isdir(os.path.join(self.ppath, self.translationsRoot)): |
671 dn = self.translationsRoot |
694 dn = self.translationsRoot |
672 else: |
695 else: |
673 dn = os.path.dirname(self.translationsRoot) |
696 dn = os.path.dirname(self.translationsRoot) |
674 if dn not in self.subdirs: |
697 if dn not in self.subdirs: |
675 self.subdirs.append(dn) |
698 self.subdirs.append(dn) |
676 |
699 |
677 self.name = os.path.splitext(os.path.basename(fn))[0] |
700 self.name = os.path.splitext(os.path.basename(fn))[0] |
678 |
701 |
679 # check, if the files of the project still exist in the project directory |
702 # check, if the files of the project still exist in the |
|
703 # project directory |
680 self.__checkFilesExist("SOURCES") |
704 self.__checkFilesExist("SOURCES") |
681 self.__checkFilesExist("FORMS") |
705 self.__checkFilesExist("FORMS") |
682 self.__checkFilesExist("INTERFACES") |
706 self.__checkFilesExist("INTERFACES") |
683 self.__checkFilesExist("TRANSLATIONS") |
707 self.__checkFilesExist("TRANSLATIONS") |
684 self.__checkFilesExist("RESOURCES") |
708 self.__checkFilesExist("RESOURCES") |
714 def __writeProject(self, fn=None): |
738 def __writeProject(self, fn=None): |
715 """ |
739 """ |
716 Private method to save the project infos to a project file. |
740 Private method to save the project infos to a project file. |
717 |
741 |
718 @param fn optional filename of the project file to be written (string). |
742 @param fn optional filename of the project file to be written (string). |
719 If fn is None, the filename stored in the project object |
743 If fn is None, the filename stored in the project object |
720 is used. This is the 'save' action. If fn is given, this filename |
744 is used. This is the 'save' action. If fn is given, this filename |
721 is used instead of the one in the project object. This is the |
745 is used instead of the one in the project object. This is the |
722 'save as' action. |
746 'save as' action. |
723 @return flag indicating success |
747 @return flag indicating success |
724 """ |
748 """ |
725 if self.vcs is not None: |
749 if self.vcs is not None: |
726 self.pdata["VCSOPTIONS"] = [copy.deepcopy(self.vcs.vcsGetOptions())] |
750 self.pdata["VCSOPTIONS"] = [ |
727 self.pdata["VCSOTHERDATA"] = [copy.deepcopy(self.vcs.vcsGetOtherData())] |
751 copy.deepcopy(self.vcs.vcsGetOptions())] |
|
752 self.pdata["VCSOTHERDATA"] = [ |
|
753 copy.deepcopy(self.vcs.vcsGetOtherData())] |
728 |
754 |
729 if not self.pdata["HASH"][0]: |
755 if not self.pdata["HASH"][0]: |
730 hash = str(QCryptographicHash.hash( |
756 hash = str(QCryptographicHash.hash( |
731 QByteArray(self.ppath.encode("utf-8")), |
757 QByteArray(self.ppath.encode("utf-8")), |
732 QCryptographicHash.Sha1).toHex(), |
758 QCryptographicHash.Sha1).toHex(), |
812 else: |
843 else: |
813 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
844 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
814 fn = os.path.join(self.getProjectManagementDir(), |
845 fn = os.path.join(self.getProjectManagementDir(), |
815 '{0}.e4s'.format(fn)) |
846 '{0}.e4s'.format(fn)) |
816 enable = os.path.exists(fn) |
847 enable = os.path.exists(fn) |
817 self.sessActGrp.findChild(QAction, "project_load_session").setEnabled(enable) |
848 self.sessActGrp.findChild( |
818 self.sessActGrp.findChild(QAction, "project_delete_session").setEnabled(enable) |
849 QAction, "project_load_session").setEnabled(enable) |
|
850 self.sessActGrp.findChild( |
|
851 QAction, "project_delete_session").setEnabled(enable) |
819 |
852 |
820 def __readSession(self, quiet=False, indicator=""): |
853 def __readSession(self, quiet=False, indicator=""): |
821 """ |
854 """ |
822 Private method to read in the project session file (.e4s) |
855 Private method to read in the project session file (.e4s). |
823 |
856 |
824 @param quiet flag indicating quiet operations. |
857 @param quiet flag indicating quiet operations. |
825 If this flag is true, no errors are reported. |
858 If this flag is true, no errors are reported. |
826 @keyparam indicator indicator string (string) |
859 @keyparam indicator indicator string (string) |
827 """ |
860 """ |
890 self.trUtf8("Please save the project first.")) |
926 self.trUtf8("Please save the project first.")) |
891 return |
927 return |
892 |
928 |
893 fname, ext = os.path.splitext(os.path.basename(self.pfile)) |
929 fname, ext = os.path.splitext(os.path.basename(self.pfile)) |
894 |
930 |
895 for fn in [os.path.join(self.getProjectManagementDir(), "{0}.e4s".format(fname))]: |
931 for fn in [os.path.join( |
|
932 self.getProjectManagementDir(), "{0}.e4s".format(fname))]: |
896 if os.path.exists(fn): |
933 if os.path.exists(fn): |
897 try: |
934 try: |
898 os.remove(fn) |
935 os.remove(fn) |
899 except OSError: |
936 except OSError: |
900 E5MessageBox.critical(self.ui, |
937 E5MessageBox.critical(self.ui, |
901 self.trUtf8("Delete project session"), |
938 self.trUtf8("Delete project session"), |
902 self.trUtf8("<p>The project session file <b>{0}</b> could not be" |
939 self.trUtf8( |
903 " deleted.</p>").format(fn)) |
940 "<p>The project session file <b>{0}</b> could" |
|
941 " not be deleted.</p>").format(fn)) |
904 |
942 |
905 def __readTasks(self): |
943 def __readTasks(self): |
906 """ |
944 """ |
907 Private method to read in the project tasks file (.e4t) |
945 Private method to read in the project tasks file (.e4t). |
908 """ |
946 """ |
909 if self.pfile is None: |
947 if self.pfile is None: |
910 E5MessageBox.critical(self.ui, |
948 E5MessageBox.critical(self.ui, |
911 self.trUtf8("Read tasks"), |
949 self.trUtf8("Read tasks"), |
912 self.trUtf8("Please save the project first.")) |
950 self.trUtf8("Please save the project first.")) |
961 else: |
1002 else: |
962 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
1003 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
963 fn = os.path.join(self.getProjectManagementDir(), |
1004 fn = os.path.join(self.getProjectManagementDir(), |
964 '{0}.e4d'.format(fn)) |
1005 '{0}.e4d'.format(fn)) |
965 enable = os.path.exists(fn) |
1006 enable = os.path.exists(fn) |
966 self.dbgActGrp.findChild(QAction, "project_debugger_properties_load")\ |
1007 self.dbgActGrp.findChild( |
967 .setEnabled(enable) |
1008 QAction, "project_debugger_properties_load").setEnabled(enable) |
968 self.dbgActGrp.findChild(QAction, "project_debugger_properties_delete")\ |
1009 self.dbgActGrp.findChild( |
969 .setEnabled(enable) |
1010 QAction, "project_debugger_properties_delete").setEnabled(enable) |
970 |
1011 |
971 def __readDebugProperties(self, quiet=False): |
1012 def __readDebugProperties(self, quiet=False): |
972 """ |
1013 """ |
973 Private method to read in the project debugger properties file (.e4d) |
1014 Private method to read in the project debugger properties file (.e4d). |
974 |
1015 |
975 @param quiet flag indicating quiet operations. |
1016 @param quiet flag indicating quiet operations. |
976 If this flag is true, no errors are reported. |
1017 If this flag is true, no errors are reported. |
977 """ |
1018 """ |
978 if self.pfile is None: |
1019 if self.pfile is None: |
1016 fn = os.path.join(self.getProjectManagementDir(), '{0}.e4d'.format(fn)) |
1058 fn = os.path.join(self.getProjectManagementDir(), '{0}.e4d'.format(fn)) |
1017 |
1059 |
1018 f = QFile(fn) |
1060 f = QFile(fn) |
1019 if f.open(QIODevice.WriteOnly): |
1061 if f.open(QIODevice.WriteOnly): |
1020 from E5XML.DebuggerPropertiesWriter import DebuggerPropertiesWriter |
1062 from E5XML.DebuggerPropertiesWriter import DebuggerPropertiesWriter |
1021 DebuggerPropertiesWriter(f, os.path.splitext(os.path.basename(fn))[0])\ |
1063 DebuggerPropertiesWriter( |
1022 .writeXML() |
1064 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
1023 f.close() |
1065 f.close() |
1024 else: |
1066 else: |
1025 if not quiet: |
1067 if not quiet: |
1026 E5MessageBox.critical(self.ui, |
1068 E5MessageBox.critical(self.ui, |
1027 self.trUtf8("Save debugger properties"), |
1069 self.trUtf8("Save debugger properties"), |
1028 self.trUtf8("<p>The project debugger properties file <b>{0}</b> could" |
1070 self.trUtf8( |
1029 " not be written.</p>") |
1071 "<p>The project debugger properties file <b>{0}</b>" |
1030 .format(fn)) |
1072 " could not be written.</p>").format(fn)) |
1031 |
1073 |
1032 def __deleteDebugProperties(self): |
1074 def __deleteDebugProperties(self): |
1033 """ |
1075 """ |
1034 Private method to delete the project debugger properties file (.e4d) |
1076 Private method to delete the project debugger properties file (.e4d). |
1035 """ |
1077 """ |
1036 if self.pfile is None: |
1078 if self.pfile is None: |
1037 E5MessageBox.critical(self.ui, |
1079 E5MessageBox.critical(self.ui, |
1038 self.trUtf8("Delete debugger properties"), |
1080 self.trUtf8("Delete debugger properties"), |
1039 self.trUtf8("Please save the project first.")) |
1081 self.trUtf8("Please save the project first.")) |
1040 return |
1082 return |
1041 |
1083 |
1042 fname, ext = os.path.splitext(os.path.basename(self.pfile)) |
1084 fname, ext = os.path.splitext(os.path.basename(self.pfile)) |
1043 |
1085 |
1044 for fn in [os.path.join(self.getProjectManagementDir(), "{0}.e4d".format(fname))]: |
1086 for fn in [os.path.join(self.getProjectManagementDir(), |
|
1087 "{0}.e4d".format(fname))]: |
1045 if os.path.exists(fn): |
1088 if os.path.exists(fn): |
1046 try: |
1089 try: |
1047 os.remove(fn) |
1090 os.remove(fn) |
1048 except OSError: |
1091 except OSError: |
1049 E5MessageBox.critical(self.ui, |
1092 E5MessageBox.critical(self.ui, |
1050 self.trUtf8("Delete debugger properties"), |
1093 self.trUtf8("Delete debugger properties"), |
1051 self.trUtf8("<p>The project debugger properties file <b>{0}</b>" |
1094 self.trUtf8( |
1052 " could not be deleted.</p>") |
1095 "<p>The project debugger properties file" |
|
1096 " <b>{0}</b> could not be deleted.</p>") |
1053 .format(fn)) |
1097 .format(fn)) |
1054 |
1098 |
1055 def __initDebugProperties(self): |
1099 def __initDebugProperties(self): |
1056 """ |
1100 """ |
1057 Private method to initialize the debug properties. |
1101 Private method to initialize the debug properties. |
1140 """ |
1184 """ |
1141 if len(self.pdata["TRANSLATIONPATTERN"]) == 0 or \ |
1185 if len(self.pdata["TRANSLATIONPATTERN"]) == 0 or \ |
1142 self.pdata["TRANSLATIONPATTERN"][0] == '': |
1186 self.pdata["TRANSLATIONPATTERN"][0] == '': |
1143 E5MessageBox.critical(self.ui, |
1187 E5MessageBox.critical(self.ui, |
1144 self.trUtf8("Add Language"), |
1188 self.trUtf8("Add Language"), |
1145 self.trUtf8("You have to specify a translation pattern first.")) |
1189 self.trUtf8( |
|
1190 "You have to specify a translation pattern first.")) |
1146 return |
1191 return |
1147 |
1192 |
1148 from .AddLanguageDialog import AddLanguageDialog |
1193 from .AddLanguageDialog import AddLanguageDialog |
1149 dlg = AddLanguageDialog(self.parent()) |
1194 dlg = AddLanguageDialog(self.parent()) |
1150 if dlg.exec_() == QDialog.Accepted: |
1195 if dlg.exec_() == QDialog.Accepted: |
1151 lang = dlg.getSelectedLanguage() |
1196 lang = dlg.getSelectedLanguage() |
1152 if self.pdata["PROJECTTYPE"][0] in \ |
1197 if self.pdata["PROJECTTYPE"][0] in \ |
1153 ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "PySide", "PySideC"]: |
1198 ["Qt4", "Qt4C", "PyQt5", "PyQt5C", "E4Plugin", "PySide", |
1154 langFile = self.pdata["TRANSLATIONPATTERN"][0].replace("%language%", lang) |
1199 "PySideC"]: |
|
1200 langFile = self.pdata["TRANSLATIONPATTERN"][0]\ |
|
1201 .replace("%language%", lang) |
1155 self.appendFile(langFile) |
1202 self.appendFile(langFile) |
1156 self.projectLanguageAddedByCode.emit(lang) |
1203 self.projectLanguageAddedByCode.emit(lang) |
1157 |
1204 |
1158 def __binaryTranslationFile(self, langFile): |
1205 def __binaryTranslationFile(self, langFile): |
1159 """ |
1206 """ |
1160 Private method to calculate the filename of the binary translations file |
1207 Private method to calculate the filename of the binary translations |
1161 given the name of the raw translations file. |
1208 file given the name of the raw translations file. |
1162 |
1209 |
1163 @param langFile name of the raw translations file (string) |
1210 @param langFile name of the raw translations file (string) |
1164 @return name of the binary translations file (string) |
1211 @return name of the binary translations file (string) |
1165 """ |
1212 """ |
1166 qmFile = "" |
1213 qmFile = "" |
1167 try: |
1214 try: |
1168 if self.__binaryTranslationsCallbacks[self.pdata["PROJECTTYPE"][0]] \ |
1215 if self.__binaryTranslationsCallbacks[ |
1169 is not None: |
1216 self.pdata["PROJECTTYPE"][0]] is not None: |
1170 qmFile = self.__binaryTranslationsCallbacks[ |
1217 qmFile = self.__binaryTranslationsCallbacks[ |
1171 self.pdata["PROJECTTYPE"][0]](langFile) |
1218 self.pdata["PROJECTTYPE"][0]](langFile) |
1172 except KeyError: |
1219 except KeyError: |
1173 qmFile = langFile.replace('.ts', '.qm') |
1220 qmFile = langFile.replace('.ts', '.qm') |
1174 if qmFile == langFile: |
1221 if qmFile == langFile: |
1250 if os.path.exists(fn): |
1298 if os.path.exists(fn): |
1251 os.remove(fn) |
1299 os.remove(fn) |
1252 except IOError: |
1300 except IOError: |
1253 E5MessageBox.critical(self.ui, |
1301 E5MessageBox.critical(self.ui, |
1254 self.trUtf8("Delete translation"), |
1302 self.trUtf8("Delete translation"), |
1255 self.trUtf8("<p>The selected translation file <b>{0}</b> could not be" |
1303 self.trUtf8( |
1256 " deleted.</p>").format(qmFile)) |
1304 "<p>The selected translation file <b>{0}</b> could" |
|
1305 " not be deleted.</p>").format(qmFile)) |
1257 return |
1306 return |
1258 |
1307 |
1259 def appendFile(self, fn, isSourceFile=False, updateModel=True): |
1308 def appendFile(self, fn, isSourceFile=False, updateModel=True): |
1260 """ |
1309 """ |
1261 Public method to append a file to the project. |
1310 Public method to append a file to the project. |
1262 |
1311 |
1263 @param fn filename to be added to the project (string) |
1312 @param fn filename to be added to the project (string) |
1264 @param isSourceFile flag indicating that this is a source file |
1313 @param isSourceFile flag indicating that this is a source file |
1265 even if it doesn't have the source extension (boolean) |
1314 even if it doesn't have the source extension (boolean) |
1266 @param updateModel flag indicating an update of the model is requested (boolean) |
1315 @param updateModel flag indicating an update of the model is |
|
1316 requested (boolean) |
1267 """ |
1317 """ |
1268 dirty = False |
1318 dirty = False |
1269 |
1319 |
1270 if os.path.isabs(fn): |
1320 if os.path.isabs(fn): |
1271 # make it relative to the project root, if it starts with that path |
1321 # make it relative to the project root, if it starts with that path |
1370 os.makedirs(target) |
1422 os.makedirs(target) |
1371 |
1423 |
1372 if os.path.exists(targetfile): |
1424 if os.path.exists(targetfile): |
1373 res = E5MessageBox.yesNo(self.ui, |
1425 res = E5MessageBox.yesNo(self.ui, |
1374 self.trUtf8("Add file"), |
1426 self.trUtf8("Add file"), |
1375 self.trUtf8("<p>The file <b>{0}</b> already" |
1427 self.trUtf8( |
|
1428 "<p>The file <b>{0}</b> already" |
1376 " exists.</p><p>Overwrite it?</p>") |
1429 " exists.</p><p>Overwrite it?</p>") |
1377 .format(targetfile), |
1430 .format(targetfile), |
1378 icon=E5MessageBox.Warning) |
1431 icon=E5MessageBox.Warning) |
1379 if not res: |
1432 if not res: |
1380 return # don't overwrite |
1433 return # don't overwrite |
1381 |
1434 |
1382 shutil.copy(fn, target) |
1435 shutil.copy(fn, target) |
1383 except IOError as why: |
1436 except IOError as why: |
1384 E5MessageBox.critical(self.ui, |
1437 E5MessageBox.critical(self.ui, |
1385 self.trUtf8("Add file"), |
1438 self.trUtf8("Add file"), |
1386 self.trUtf8("<p>The selected file <b>{0}</b> could not be" |
1439 self.trUtf8( |
1387 " added to <b>{1}</b>.</p><p>Reason: {2}</p>") |
1440 "<p>The selected file <b>{0}</b> could" |
|
1441 " not be added to <b>{1}</b>.</p>" |
|
1442 "<p>Reason: {2}</p>") |
1388 .format(fn, target, str(why))) |
1443 .format(fn, target, str(why))) |
1389 continue |
1444 continue |
1390 |
1445 |
1391 self.appendFile(targetfile, isSource or filter == 'source') |
1446 self.appendFile(targetfile, isSource or filter == 'source') |
1392 else: |
1447 else: |
1445 if not Utilities.samepath(target, source): |
1503 if not Utilities.samepath(target, source): |
1446 try: |
1504 try: |
1447 if os.path.exists(targetfile): |
1505 if os.path.exists(targetfile): |
1448 res = E5MessageBox.yesNo(self.ui, |
1506 res = E5MessageBox.yesNo(self.ui, |
1449 self.trUtf8("Add directory"), |
1507 self.trUtf8("Add directory"), |
1450 self.trUtf8("<p>The file <b>{0}</b> already exists.</p>" |
1508 self.trUtf8( |
1451 "<p>Overwrite it?</p>") |
1509 "<p>The file <b>{0}</b> already exists.</p>" |
|
1510 "<p>Overwrite it?</p>") |
1452 .format(targetfile), |
1511 .format(targetfile), |
1453 icon=E5MessageBox.Warning) |
1512 icon=E5MessageBox.Warning) |
1454 if not res: |
1513 if not res: |
1455 continue # don't overwrite, carry on with next file |
1514 continue # don't overwrite, carry on |
|
1515 # with next file |
1456 |
1516 |
1457 shutil.copy(file, target) |
1517 shutil.copy(file, target) |
1458 except EnvironmentError: |
1518 except EnvironmentError: |
1459 continue |
1519 continue |
1460 self.appendFile(targetfile) |
1520 self.appendFile(targetfile) |
1916 self.menuCheckAct.setEnabled(True) |
1987 self.menuCheckAct.setEnabled(True) |
1917 self.menuShowAct.setEnabled(True) |
1988 self.menuShowAct.setEnabled(True) |
1918 self.menuDiagramAct.setEnabled(True) |
1989 self.menuDiagramAct.setEnabled(True) |
1919 self.menuApidocAct.setEnabled(True) |
1990 self.menuApidocAct.setEnabled(True) |
1920 self.menuPackagersAct.setEnabled(True) |
1991 self.menuPackagersAct.setEnabled(True) |
1921 self.pluginGrp.setEnabled(self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
1992 self.pluginGrp.setEnabled( |
|
1993 self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
1922 self.addLanguageAct.setEnabled( |
1994 self.addLanguageAct.setEnabled( |
1923 len(self.pdata["TRANSLATIONPATTERN"]) > 0 and \ |
1995 len(self.pdata["TRANSLATIONPATTERN"]) > 0 and \ |
1924 self.pdata["TRANSLATIONPATTERN"][0] != '') |
1996 self.pdata["TRANSLATIONPATTERN"][0] != '') |
1925 |
1997 |
1926 self.projectAboutToBeCreated.emit() |
1998 self.projectAboutToBeCreated.emit() |
1927 |
1999 |
1928 hash = str(QCryptographicHash.hash( |
2000 hash = str(QCryptographicHash.hash( |
1929 QByteArray(self.ppath.encode("utf-8")), QCryptographicHash.Sha1).toHex(), |
2001 QByteArray(self.ppath.encode("utf-8")), |
|
2002 QCryptographicHash.Sha1).toHex(), |
1930 encoding="utf-8") |
2003 encoding="utf-8") |
1931 self.pdata["HASH"] = [hash] |
2004 self.pdata["HASH"] = [hash] |
1932 |
2005 |
1933 # create the project directory if it doesn't exist already |
2006 # create the project directory if it doesn't exist already |
1934 if not os.path.isdir(self.ppath): |
2007 if not os.path.isdir(self.ppath): |
1935 try: |
2008 try: |
1936 os.makedirs(self.ppath) |
2009 os.makedirs(self.ppath) |
1937 except EnvironmentError: |
2010 except EnvironmentError: |
1938 E5MessageBox.critical(self.ui, |
2011 E5MessageBox.critical(self.ui, |
1939 self.trUtf8("Create project directory"), |
2012 self.trUtf8("Create project directory"), |
1940 self.trUtf8("<p>The project directory <b>{0}</b> could not" |
2013 self.trUtf8( |
|
2014 "<p>The project directory <b>{0}</b> could not" |
1941 " be created.</p>") |
2015 " be created.</p>") |
1942 .format(self.ppath)) |
2016 .format(self.ppath)) |
1943 self.vcs = self.initVCS() |
2017 self.vcs = self.initVCS() |
1944 return |
2018 return |
1945 # create an empty __init__.py file to make it a Python package |
2019 # create an empty __init__.py file to make it a Python package |
1946 # (only for Python and Python3) |
2020 # (only for Python and Python3) |
1947 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
2021 if self.pdata["PROGLANGUAGE"][0] in \ |
|
2022 ["Python", "Python2", "Python3"]: |
1948 fn = os.path.join(self.ppath, "__init__.py") |
2023 fn = os.path.join(self.ppath, "__init__.py") |
1949 f = open(fn, "w", encoding="utf-8") |
2024 f = open(fn, "w", encoding="utf-8") |
1950 f.close() |
2025 f.close() |
1951 self.appendFile(fn, True) |
2026 self.appendFile(fn, True) |
1952 # create an empty main script file, if a name was given |
2027 # create an empty main script file, if a name was given |
1953 if len(self.pdata["MAINSCRIPT"]) and self.pdata["MAINSCRIPT"][0]: |
2028 if len(self.pdata["MAINSCRIPT"]) and \ |
|
2029 self.pdata["MAINSCRIPT"][0]: |
1954 if not os.path.isabs(self.pdata["MAINSCRIPT"][0]): |
2030 if not os.path.isabs(self.pdata["MAINSCRIPT"][0]): |
1955 ms = os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0]) |
2031 ms = os.path.join( |
|
2032 self.ppath, self.pdata["MAINSCRIPT"][0]) |
1956 else: |
2033 else: |
1957 ms = self.pdata["MAINSCRIPT"][0] |
2034 ms = self.pdata["MAINSCRIPT"][0] |
1958 f = open(ms, "w") |
2035 f = open(ms, "w") |
1959 f.close() |
2036 f.close() |
1960 self.appendFile(ms, True) |
2037 self.appendFile(ms, True) |
2069 self.pdata["VCS"] = ['None'] |
2151 self.pdata["VCS"] = ['None'] |
2070 self.saveProject() |
2152 self.saveProject() |
2071 break |
2153 break |
2072 |
2154 |
2073 # put the project under VCS control |
2155 # put the project under VCS control |
2074 if self.vcs is None and self.vcsSoftwareAvailable() and self.vcsRequested: |
2156 if self.vcs is None and self.vcsSoftwareAvailable() and \ |
|
2157 self.vcsRequested: |
2075 vcsSystemsDict = e5App().getObject("PluginManager")\ |
2158 vcsSystemsDict = e5App().getObject("PluginManager")\ |
2076 .getPluginDisplayStrings("version_control") |
2159 .getPluginDisplayStrings("version_control") |
2077 vcsSystemsDisplay = [self.trUtf8("None")] |
2160 vcsSystemsDisplay = [self.trUtf8("None")] |
2078 keys = sorted(vcsSystemsDict.keys()) |
2161 keys = sorted(vcsSystemsDict.keys()) |
2079 for key in keys: |
2162 for key in keys: |
2080 vcsSystemsDisplay.append(vcsSystemsDict[key]) |
2163 vcsSystemsDisplay.append(vcsSystemsDict[key]) |
2081 vcsSelected, ok = QInputDialog.getItem( |
2164 vcsSelected, ok = QInputDialog.getItem( |
2082 None, |
2165 None, |
2083 self.trUtf8("New Project"), |
2166 self.trUtf8("New Project"), |
2084 self.trUtf8("Select version control system for the project"), |
2167 self.trUtf8( |
|
2168 "Select version control system for the project"), |
2085 vcsSystemsDisplay, |
2169 vcsSystemsDisplay, |
2086 0, False) |
2170 0, False) |
2087 if ok and vcsSelected != self.trUtf8("None"): |
2171 if ok and vcsSelected != self.trUtf8("None"): |
2088 for vcsSystem, vcsSystemDisplay in list(vcsSystemsDict.items()): |
2172 for vcsSystem, vcsSystemDisplay in vcsSystemsDict.items(): |
2089 if vcsSystemDisplay == vcsSelected: |
2173 if vcsSystemDisplay == vcsSelected: |
2090 break |
2174 break |
2091 else: |
2175 else: |
2092 vcsSystem = "None" |
2176 vcsSystem = "None" |
2093 self.pdata["VCS"] = [vcsSystem] |
2177 self.pdata["VCS"] = [vcsSystem] |
2166 # the first entry determines the mainscript name |
2252 # the first entry determines the mainscript name |
2167 mainscriptname = os.path.splitext(mainscript)[0] or \ |
2253 mainscriptname = os.path.splitext(mainscript)[0] or \ |
2168 os.path.basename(tslist[0]).split('_')[0] |
2254 os.path.basename(tslist[0]).split('_')[0] |
2169 self.pdata["TRANSLATIONPATTERN"] = \ |
2255 self.pdata["TRANSLATIONPATTERN"] = \ |
2170 [os.path.join(os.path.dirname(tslist[0]), |
2256 [os.path.join(os.path.dirname(tslist[0]), |
2171 "{0}_%language%{1}".format(os.path.basename(tslist[0]).split('_')[0], |
2257 "{0}_%language%{1}".format( |
|
2258 os.path.basename(tslist[0]).split('_')[0], |
2172 os.path.splitext(tslist[0])[1]))] |
2259 os.path.splitext(tslist[0])[1]))] |
2173 else: |
2260 else: |
2174 pattern, ok = QInputDialog.getText( |
2261 pattern, ok = QInputDialog.getText( |
2175 None, |
2262 None, |
2176 self.trUtf8("Translation Pattern"), |
2263 self.trUtf8("Translation Pattern"), |
2177 self.trUtf8("Enter the path pattern for translation files " |
2264 self.trUtf8( |
2178 "(use '%language%' in place of the language code):"), |
2265 "Enter the path pattern for translation files " |
|
2266 "(use '%language%' in place of the language code):"), |
2179 QLineEdit.Normal, |
2267 QLineEdit.Normal, |
2180 tslist[0]) |
2268 tslist[0]) |
2181 if pattern: |
2269 if pattern: |
2182 self.pdata["TRANSLATIONPATTERN"] = [pattern] |
2270 self.pdata["TRANSLATIONPATTERN"] = [pattern] |
2183 if self.pdata["TRANSLATIONPATTERN"]: |
2271 if self.pdata["TRANSLATIONPATTERN"]: |
2184 self.pdata["TRANSLATIONPATTERN"][0] = \ |
2272 self.pdata["TRANSLATIONPATTERN"][0] = \ |
2185 self.getRelativePath(self.pdata["TRANSLATIONPATTERN"][0]) |
2273 self.getRelativePath(self.pdata["TRANSLATIONPATTERN"][0]) |
2186 pattern = self.pdata["TRANSLATIONPATTERN"][0].replace("%language%", "*") |
2274 pattern = self.pdata["TRANSLATIONPATTERN"][0]\ |
|
2275 .replace("%language%", "*") |
2187 for ts in tslist: |
2276 for ts in tslist: |
2188 if fnmatch.fnmatch(ts, pattern): |
2277 if fnmatch.fnmatch(ts, pattern): |
2189 self.pdata["TRANSLATIONS"].append(ts) |
2278 self.pdata["TRANSLATIONS"].append(ts) |
2190 self.projectLanguageAdded.emit(ts) |
2279 self.projectLanguageAdded.emit(ts) |
2191 if self.pdata["TRANSLATIONSBINPATH"]: |
2280 if self.pdata["TRANSLATIONSBINPATH"]: |
2192 tpd = os.path.join(self.ppath, |
2281 tpd = os.path.join(self.ppath, |
2193 self.pdata["TRANSLATIONSBINPATH"][0]) |
2282 self.pdata["TRANSLATIONSBINPATH"][0]) |
2194 pattern = os.path.basename(self.pdata["TRANSLATIONPATTERN"][0])\ |
2283 pattern = os.path.basename( |
|
2284 self.pdata["TRANSLATIONPATTERN"][0])\ |
2195 .replace("%language%", "*") |
2285 .replace("%language%", "*") |
2196 pattern = self.__binaryTranslationFile(pattern) |
2286 pattern = self.__binaryTranslationFile(pattern) |
2197 qmlist = Utilities.direntries(tpd, True, pattern) |
2287 qmlist = Utilities.direntries(tpd, True, pattern) |
2198 for qm in qmlist: |
2288 for qm in qmlist: |
2199 self.pdata["TRANSLATIONS"].append(qm) |
2289 self.pdata["TRANSLATIONS"].append(qm) |
2200 self.projectLanguageAdded.emit(qm) |
2290 self.projectLanguageAdded.emit(qm) |
2201 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
2291 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
2202 len(self.pdata["MAINSCRIPT"][0]) == 0: |
2292 len(self.pdata["MAINSCRIPT"][0]) == 0: |
2203 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
2293 if self.pdata["PROGLANGUAGE"][0] in \ |
2204 self.pdata["MAINSCRIPT"] = ['{0}.py'.format(mainscriptname)] |
2294 ["Python", "Python2", "Python3"]: |
|
2295 self.pdata["MAINSCRIPT"] = [ |
|
2296 '{0}.py'.format(mainscriptname)] |
2205 elif self.pdata["PROGLANGUAGE"][0] == "Ruby": |
2297 elif self.pdata["PROGLANGUAGE"][0] == "Ruby": |
2206 self.pdata["MAINSCRIPT"] = ['{0}.rb'.format(mainscriptname)] |
2298 self.pdata["MAINSCRIPT"] = [ |
|
2299 '{0}.rb'.format(mainscriptname)] |
2207 self.setDirty(True) |
2300 self.setDirty(True) |
2208 QApplication.restoreOverrideCursor() |
2301 QApplication.restoreOverrideCursor() |
2209 |
2302 |
2210 def __showProperties(self): |
2303 def __showProperties(self): |
2211 """ |
2304 """ |
2238 os.makedirs(tp) |
2331 os.makedirs(tp) |
2239 if tp != self.ppath and tp not in self.subdirs: |
2332 if tp != self.ppath and tp not in self.subdirs: |
2240 self.subdirs.append(tp) |
2333 self.subdirs.append(tp) |
2241 |
2334 |
2242 if self.pdata["TRANSLATIONSBINPATH"]: |
2335 if self.pdata["TRANSLATIONSBINPATH"]: |
2243 tp = os.path.join(self.ppath, self.pdata["TRANSLATIONSBINPATH"][0]) |
2336 tp = os.path.join( |
|
2337 self.ppath, self.pdata["TRANSLATIONSBINPATH"][0]) |
2244 if not os.path.isdir(tp): |
2338 if not os.path.isdir(tp): |
2245 os.makedirs(tp) |
2339 os.makedirs(tp) |
2246 if tp != self.ppath and tp not in self.subdirs: |
2340 if tp != self.ppath and tp not in self.subdirs: |
2247 self.subdirs.append(tp) |
2341 self.subdirs.append(tp) |
2248 |
2342 |
2249 self.pluginGrp.setEnabled(self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
2343 self.pluginGrp.setEnabled( |
|
2344 self.pdata["PROJECTTYPE"][0] == "E4Plugin") |
2250 |
2345 |
2251 self.__model.projectPropertiesChanged() |
2346 self.__model.projectPropertiesChanged() |
2252 self.projectPropertiesChanged.emit() |
2347 self.projectPropertiesChanged.emit() |
2253 |
2348 |
2254 def __showUserProperties(self): |
2349 def __showUserProperties(self): |
2255 """ |
2350 """ |
2256 Private slot to display the user specific properties dialog. |
2351 Private slot to display the user specific properties dialog. |
2257 """ |
2352 """ |
2258 vcsSystem = self.pdata["VCS"] and self.pdata["VCS"][0] or None |
2353 vcsSystem = self.pdata["VCS"] and self.pdata["VCS"][0] or None |
2259 vcsSystemOverride = \ |
2354 vcsSystemOverride = self.pudata["VCSOVERRIDE"] and \ |
2260 self.pudata["VCSOVERRIDE"] and self.pudata["VCSOVERRIDE"][0] or None |
2355 self.pudata["VCSOVERRIDE"][0] or None |
2261 |
2356 |
2262 from .UserPropertiesDialog import UserPropertiesDialog |
2357 from .UserPropertiesDialog import UserPropertiesDialog |
2263 dlg = UserPropertiesDialog(self) |
2358 dlg = UserPropertiesDialog(self) |
2264 if dlg.exec_() == QDialog.Accepted: |
2359 if dlg.exec_() == QDialog.Accepted: |
2265 dlg.storeData() |
2360 dlg.storeData() |
2388 self.vcs = self.initVCS() |
2487 self.vcs = self.initVCS() |
2389 if self.vcs is None and self.isDirty() == oldState: |
2488 if self.vcs is None and self.isDirty() == oldState: |
2390 # check, if project is version controlled |
2489 # check, if project is version controlled |
2391 pluginManager = e5App().getObject("PluginManager") |
2490 pluginManager = e5App().getObject("PluginManager") |
2392 for indicator, vcsData in \ |
2491 for indicator, vcsData in \ |
2393 list(pluginManager.getVcsSystemIndicators().items()): |
2492 pluginManager.getVcsSystemIndicators().items(): |
2394 if os.path.exists(os.path.join(self.ppath, indicator)): |
2493 if os.path.exists( |
|
2494 os.path.join(self.ppath, indicator)): |
2395 if len(vcsData) > 1: |
2495 if len(vcsData) > 1: |
2396 vcsList = [] |
2496 vcsList = [] |
2397 for vcsSystemStr, vcsSystemDisplay in vcsData: |
2497 for vcsSystemStr, vcsSystemDisplay in \ |
|
2498 vcsData: |
2398 vcsList.append(vcsSystemDisplay) |
2499 vcsList.append(vcsSystemDisplay) |
2399 QApplication.restoreOverrideCursor() |
2500 QApplication.restoreOverrideCursor() |
2400 res, vcs_ok = QInputDialog.getItem( |
2501 res, vcs_ok = QInputDialog.getItem( |
2401 None, |
2502 None, |
2402 self.trUtf8("New Project"), |
2503 self.trUtf8("New Project"), |
2403 self.trUtf8("Select Version Control System"), |
2504 self.trUtf8( |
|
2505 "Select Version Control System"), |
2404 vcsList, |
2506 vcsList, |
2405 0, False) |
2507 0, False) |
2406 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
2508 QApplication.setOverrideCursor( |
|
2509 QCursor(Qt.WaitCursor)) |
2407 QApplication.processEvents() |
2510 QApplication.processEvents() |
2408 if vcs_ok: |
2511 if vcs_ok: |
2409 for vcsSystemStr, vcsSystemDisplay in vcsData: |
2512 for vcsSystemStr, vcsSystemDisplay in \ |
|
2513 vcsData: |
2410 if res == vcsSystemDisplay: |
2514 if res == vcsSystemDisplay: |
2411 vcsSystem = vcsSystemStr |
2515 vcsSystem = vcsSystemStr |
2412 break |
2516 break |
2413 else: |
2517 else: |
2414 vcsSystem = "None" |
2518 vcsSystem = "None" |
2459 |
2565 |
2460 if restoreSession: |
2566 if restoreSession: |
2461 # open the main script |
2567 # open the main script |
2462 if len(self.pdata["MAINSCRIPT"]) == 1: |
2568 if len(self.pdata["MAINSCRIPT"]) == 1: |
2463 self.sourceFile.emit( |
2569 self.sourceFile.emit( |
2464 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
2570 os.path.join( |
|
2571 self.ppath, self.pdata["MAINSCRIPT"][0])) |
2465 |
2572 |
2466 # open a project session file being quiet about errors |
2573 # open a project session file being quiet about errors |
2467 if reopen: |
2574 if reopen: |
2468 self.__readSession(quiet=True, indicator="_tmp") |
2575 self.__readSession(quiet=True, indicator="_tmp") |
2469 elif Preferences.getProject("AutoLoadSession"): |
2576 elif Preferences.getProject("AutoLoadSession"): |
2470 self.__readSession(quiet=True) |
2577 self.__readSession(quiet=True) |
2471 |
2578 |
2472 # open a project debugger properties file being quiet about errors |
2579 # open a project debugger properties file being quiet |
|
2580 # about errors |
2473 if Preferences.getProject("AutoLoadDbgProperties"): |
2581 if Preferences.getProject("AutoLoadDbgProperties"): |
2474 self.__readDebugProperties(True) |
2582 self.__readDebugProperties(True) |
2475 |
2583 |
2476 # start the VCS monitor thread |
2584 # start the VCS monitor thread |
2477 if self.vcs is not None: |
2585 if self.vcs is not None: |
2734 filesWithSyntaxErrors += 1 |
2843 filesWithSyntaxErrors += 1 |
2735 |
2844 |
2736 if reportSyntaxErrors and filesWithSyntaxErrors > 0: |
2845 if reportSyntaxErrors and filesWithSyntaxErrors > 0: |
2737 E5MessageBox.critical(self.ui, |
2846 E5MessageBox.critical(self.ui, |
2738 self.trUtf8("Syntax errors detected"), |
2847 self.trUtf8("Syntax errors detected"), |
2739 self.trUtf8("""The project contains %n file(s) with syntax errors.""", |
2848 self.trUtf8( |
|
2849 """The project contains %n file(s) with syntax errors.""", |
2740 "", filesWithSyntaxErrors) |
2850 "", filesWithSyntaxErrors) |
2741 ) |
2851 ) |
2742 return False |
2852 return False |
2743 else: |
2853 else: |
2744 return success |
2854 return success |
2745 |
2855 |
2746 def getMainScript(self, normalized=False): |
2856 def getMainScript(self, normalized=False): |
2747 """ |
2857 """ |
2748 Public method to return the main script filename. |
2858 Public method to return the main script filename. |
2749 |
2859 |
2750 @param normalized flag indicating a normalized filename is wanted (boolean) |
2860 @param normalized flag indicating a normalized filename is wanted |
|
2861 (boolean) |
2751 @return filename of the projects main script (string) |
2862 @return filename of the projects main script (string) |
2752 """ |
2863 """ |
2753 if len(self.pdata["MAINSCRIPT"]): |
2864 if len(self.pdata["MAINSCRIPT"]): |
2754 if normalized: |
2865 if normalized: |
2755 return os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0]) |
2866 return os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0]) |
3042 |
3160 |
3043 return False |
3161 return False |
3044 |
3162 |
3045 def isProjectSource(self, fn): |
3163 def isProjectSource(self, fn): |
3046 """ |
3164 """ |
3047 Public method used to check, if the passed in filename belongs to the project |
3165 Public method used to check, if the passed in filename belongs to the |
3048 sources. |
3166 project sources. |
3049 |
3167 |
3050 @param fn filename to be checked (string) |
3168 @param fn filename to be checked (string) |
3051 @return flag indicating membership (boolean) |
3169 @return flag indicating membership (boolean) |
3052 """ |
3170 """ |
3053 return self.__checkProjectFileGroup(fn, "SOURCES") |
3171 return self.__checkProjectFileGroup(fn, "SOURCES") |
3054 |
3172 |
3055 def isProjectForm(self, fn): |
3173 def isProjectForm(self, fn): |
3056 """ |
3174 """ |
3057 Public method used to check, if the passed in filename belongs to the project |
3175 Public method used to check, if the passed in filename belongs to the |
3058 forms. |
3176 project forms. |
3059 |
3177 |
3060 @param fn filename to be checked (string) |
3178 @param fn filename to be checked (string) |
3061 @return flag indicating membership (boolean) |
3179 @return flag indicating membership (boolean) |
3062 """ |
3180 """ |
3063 return self.__checkProjectFileGroup(fn, "FORMS") |
3181 return self.__checkProjectFileGroup(fn, "FORMS") |
3064 |
3182 |
3065 def isProjectInterface(self, fn): |
3183 def isProjectInterface(self, fn): |
3066 """ |
3184 """ |
3067 Public method used to check, if the passed in filename belongs to the project |
3185 Public method used to check, if the passed in filename belongs to the |
3068 interfaces. |
3186 project interfaces. |
3069 |
3187 |
3070 @param fn filename to be checked (string) |
3188 @param fn filename to be checked (string) |
3071 @return flag indicating membership (boolean) |
3189 @return flag indicating membership (boolean) |
3072 """ |
3190 """ |
3073 return self.__checkProjectFileGroup(fn, "INTERFACES") |
3191 return self.__checkProjectFileGroup(fn, "INTERFACES") |
3074 |
3192 |
3075 def isProjectResource(self, fn): |
3193 def isProjectResource(self, fn): |
3076 """ |
3194 """ |
3077 Public method used to check, if the passed in filename belongs to the project |
3195 Public method used to check, if the passed in filename belongs to the |
3078 resources. |
3196 project resources. |
3079 |
3197 |
3080 @param fn filename to be checked (string) |
3198 @param fn filename to be checked (string) |
3081 @return flag indicating membership (boolean) |
3199 @return flag indicating membership (boolean) |
3082 """ |
3200 """ |
3083 return self.__checkProjectFileGroup(fn, "RESOURCES") |
3201 return self.__checkProjectFileGroup(fn, "RESOURCES") |
3152 |
3271 |
3153 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), |
3272 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), |
3154 UI.PixmapCache.getIcon("fileMisc.png"), |
3273 UI.PixmapCache.getIcon("fileMisc.png"), |
3155 self.trUtf8('Add &files...'), 0, 0, |
3274 self.trUtf8('Add &files...'), 0, 0, |
3156 self.actGrp2, 'project_add_file') |
3275 self.actGrp2, 'project_add_file') |
3157 self.addFilesAct.setStatusTip(self.trUtf8('Add files to the current project')) |
3276 self.addFilesAct.setStatusTip(self.trUtf8( |
|
3277 'Add files to the current project')) |
3158 self.addFilesAct.setWhatsThis(self.trUtf8( |
3278 self.addFilesAct.setWhatsThis(self.trUtf8( |
3159 """<b>Add files...</b>""" |
3279 """<b>Add files...</b>""" |
3160 """<p>This opens a dialog for adding files""" |
3280 """<p>This opens a dialog for adding files""" |
3161 """ to the current project. The place to add is""" |
3281 """ to the current project. The place to add is""" |
3162 """ determined by the file extension.</p>""" |
3282 """ determined by the file extension.</p>""" |
3163 )) |
3283 )) |
3164 self.addFilesAct.triggered[()].connect(self.addFiles) |
3284 self.addFilesAct.triggered[()].connect(self.addFiles) |
3165 self.actions.append(self.addFilesAct) |
3285 self.actions.append(self.addFilesAct) |
3166 |
3286 |
3167 self.addDirectoryAct = E5Action(self.trUtf8('Add directory to project'), |
3287 self.addDirectoryAct = E5Action( |
3168 UI.PixmapCache.getIcon("dirOpen.png"), |
3288 self.trUtf8('Add directory to project'), |
3169 self.trUtf8('Add directory...'), 0, 0, |
3289 UI.PixmapCache.getIcon("dirOpen.png"), |
3170 self.actGrp2, 'project_add_directory') |
3290 self.trUtf8('Add directory...'), 0, 0, |
|
3291 self.actGrp2, 'project_add_directory') |
3171 self.addDirectoryAct.setStatusTip( |
3292 self.addDirectoryAct.setStatusTip( |
3172 self.trUtf8('Add a directory to the current project')) |
3293 self.trUtf8('Add a directory to the current project')) |
3173 self.addDirectoryAct.setWhatsThis(self.trUtf8( |
3294 self.addDirectoryAct.setWhatsThis(self.trUtf8( |
3174 """<b>Add directory...</b>""" |
3295 """<b>Add directory...</b>""" |
3175 """<p>This opens a dialog for adding a directory""" |
3296 """<p>This opens a dialog for adding a directory""" |
3176 """ to the current project.</p>""" |
3297 """ to the current project.</p>""" |
3177 )) |
3298 )) |
3178 self.addDirectoryAct.triggered[()].connect(self.addDirectory) |
3299 self.addDirectoryAct.triggered[()].connect(self.addDirectory) |
3179 self.actions.append(self.addDirectoryAct) |
3300 self.actions.append(self.addDirectoryAct) |
3180 |
3301 |
3181 self.addLanguageAct = E5Action(self.trUtf8('Add translation to project'), |
3302 self.addLanguageAct = E5Action( |
3182 UI.PixmapCache.getIcon("linguist4.png"), |
3303 self.trUtf8('Add translation to project'), |
3183 self.trUtf8('Add &translation...'), 0, 0, |
3304 UI.PixmapCache.getIcon("linguist4.png"), |
3184 self.actGrp2, 'project_add_translation') |
3305 self.trUtf8('Add &translation...'), 0, 0, |
|
3306 self.actGrp2, 'project_add_translation') |
3185 self.addLanguageAct.setStatusTip( |
3307 self.addLanguageAct.setStatusTip( |
3186 self.trUtf8('Add a translation to the current project')) |
3308 self.trUtf8('Add a translation to the current project')) |
3187 self.addLanguageAct.setWhatsThis(self.trUtf8( |
3309 self.addLanguageAct.setWhatsThis(self.trUtf8( |
3188 """<b>Add translation...</b>""" |
3310 """<b>Add translation...</b>""" |
3189 """<p>This opens a dialog for add a translation""" |
3311 """<p>This opens a dialog for add a translation""" |
3193 self.actions.append(self.addLanguageAct) |
3315 self.actions.append(self.addLanguageAct) |
3194 |
3316 |
3195 act = E5Action(self.trUtf8('Search new files'), |
3317 act = E5Action(self.trUtf8('Search new files'), |
3196 self.trUtf8('Searc&h new files...'), 0, 0, |
3318 self.trUtf8('Searc&h new files...'), 0, 0, |
3197 self.actGrp2, 'project_search_new_files') |
3319 self.actGrp2, 'project_search_new_files') |
3198 act.setStatusTip(self.trUtf8('Search new files in the project directory.')) |
3320 act.setStatusTip(self.trUtf8( |
|
3321 'Search new files in the project directory.')) |
3199 act.setWhatsThis(self.trUtf8( |
3322 act.setWhatsThis(self.trUtf8( |
3200 """<b>Search new files...</b>""" |
3323 """<b>Search new files...</b>""" |
3201 """<p>This searches for new files (sources, *.ui, *.idl) in the project""" |
3324 """<p>This searches for new files (sources, *.ui, *.idl) in""" |
3202 """ directory and registered subdirectories.</p>""" |
3325 """ the project directory and registered subdirectories.</p>""" |
3203 )) |
3326 )) |
3204 act.triggered[()].connect(self.__searchNewFiles) |
3327 act.triggered[()].connect(self.__searchNewFiles) |
3205 self.actions.append(act) |
3328 self.actions.append(act) |
3206 |
3329 |
3207 self.propsAct = E5Action(self.trUtf8('Project properties'), |
3330 self.propsAct = E5Action(self.trUtf8('Project properties'), |
3208 UI.PixmapCache.getIcon("projectProps.png"), |
3331 UI.PixmapCache.getIcon("projectProps.png"), |
3209 self.trUtf8('&Properties...'), 0, 0, self, 'project_properties') |
3332 self.trUtf8('&Properties...'), 0, 0, self, |
|
3333 'project_properties') |
3210 self.propsAct.setStatusTip(self.trUtf8('Show the project properties')) |
3334 self.propsAct.setStatusTip(self.trUtf8('Show the project properties')) |
3211 self.propsAct.setWhatsThis(self.trUtf8( |
3335 self.propsAct.setWhatsThis(self.trUtf8( |
3212 """<b>Properties...</b>""" |
3336 """<b>Properties...</b>""" |
3213 """<p>This shows a dialog to edit the project properties.</p>""" |
3337 """<p>This shows a dialog to edit the project properties.</p>""" |
3214 )) |
3338 )) |
3215 self.propsAct.triggered[()].connect(self.__showProperties) |
3339 self.propsAct.triggered[()].connect(self.__showProperties) |
3216 self.actions.append(self.propsAct) |
3340 self.actions.append(self.propsAct) |
3217 |
3341 |
3218 self.userPropsAct = E5Action(self.trUtf8('User project properties'), |
3342 self.userPropsAct = E5Action(self.trUtf8('User project properties'), |
3219 UI.PixmapCache.getIcon("projectUserProps.png"), |
3343 UI.PixmapCache.getIcon("projectUserProps.png"), |
3220 self.trUtf8('&User Properties...'), 0, 0, self, 'project_user_properties') |
3344 self.trUtf8('&User Properties...'), 0, 0, self, |
|
3345 'project_user_properties') |
3221 self.userPropsAct.setStatusTip(self.trUtf8( |
3346 self.userPropsAct.setStatusTip(self.trUtf8( |
3222 'Show the user specific project properties')) |
3347 'Show the user specific project properties')) |
3223 self.userPropsAct.setWhatsThis(self.trUtf8( |
3348 self.userPropsAct.setWhatsThis(self.trUtf8( |
3224 """<b>User Properties...</b>""" |
3349 """<b>User Properties...</b>""" |
3225 """<p>This shows a dialog to edit the user specific project properties.</p>""" |
3350 """<p>This shows a dialog to edit the user specific project""" |
|
3351 """ properties.</p>""" |
3226 )) |
3352 )) |
3227 self.userPropsAct.triggered[()].connect(self.__showUserProperties) |
3353 self.userPropsAct.triggered[()].connect(self.__showUserProperties) |
3228 self.actions.append(self.userPropsAct) |
3354 self.actions.append(self.userPropsAct) |
3229 |
3355 |
3230 self.filetypesAct = E5Action(self.trUtf8('Filetype Associations'), |
3356 self.filetypesAct = E5Action(self.trUtf8('Filetype Associations'), |
3232 self, 'project_filetype_associatios') |
3358 self, 'project_filetype_associatios') |
3233 self.filetypesAct.setStatusTip( |
3359 self.filetypesAct.setStatusTip( |
3234 self.trUtf8('Show the project filetype associations')) |
3360 self.trUtf8('Show the project filetype associations')) |
3235 self.filetypesAct.setWhatsThis(self.trUtf8( |
3361 self.filetypesAct.setWhatsThis(self.trUtf8( |
3236 """<b>Filetype Associations...</b>""" |
3362 """<b>Filetype Associations...</b>""" |
3237 """<p>This shows a dialog to edit the filetype associations of the project.""" |
3363 """<p>This shows a dialog to edit the filetype associations of""" |
3238 """ These associations determine the type (source, form, interface""" |
3364 """ the project. These associations determine the type""" |
3239 """ or others) with a filename pattern. They are used when adding a file""" |
3365 """ (source, form, interface or others) with a filename""" |
3240 """ to the project and when performing a search for new files.</p>""" |
3366 """ pattern. They are used when adding a file to the project""" |
|
3367 """ and when performing a search for new files.</p>""" |
3241 )) |
3368 )) |
3242 self.filetypesAct.triggered[()].connect(self.__showFiletypeAssociations) |
3369 self.filetypesAct.triggered[()].connect( |
|
3370 self.__showFiletypeAssociations) |
3243 self.actions.append(self.filetypesAct) |
3371 self.actions.append(self.filetypesAct) |
3244 |
3372 |
3245 self.lexersAct = E5Action(self.trUtf8('Lexer Associations'), |
3373 self.lexersAct = E5Action(self.trUtf8('Lexer Associations'), |
3246 self.trUtf8('Lexer Associations...'), 0, 0, |
3374 self.trUtf8('Lexer Associations...'), 0, 0, |
3247 self, 'project_lexer_associatios') |
3375 self, 'project_lexer_associatios') |
3248 self.lexersAct.setStatusTip( |
3376 self.lexersAct.setStatusTip(self.trUtf8( |
3249 self.trUtf8('Show the project lexer associations (overriding defaults)')) |
3377 'Show the project lexer associations (overriding defaults)')) |
3250 self.lexersAct.setWhatsThis(self.trUtf8( |
3378 self.lexersAct.setWhatsThis(self.trUtf8( |
3251 """<b>Lexer Associations...</b>""" |
3379 """<b>Lexer Associations...</b>""" |
3252 """<p>This shows a dialog to edit the lexer associations of the project.""" |
3380 """<p>This shows a dialog to edit the lexer associations of""" |
3253 """ These associations override the global lexer associations. Lexers""" |
3381 """ the project. These associations override the global lexer""" |
3254 """ are used to highlight the editor text.</p>""" |
3382 """ associations. Lexers are used to highlight the editor""" |
|
3383 """ text.</p>""" |
3255 )) |
3384 )) |
3256 self.lexersAct.triggered[()].connect(self.__showLexerAssociations) |
3385 self.lexersAct.triggered[()].connect(self.__showLexerAssociations) |
3257 self.actions.append(self.lexersAct) |
3386 self.actions.append(self.lexersAct) |
3258 |
3387 |
3259 self.dbgActGrp = createActionGroup(self) |
3388 self.dbgActGrp = createActionGroup(self) |
3400 self.codeProfileAct.triggered[()].connect(self.__showProfileData) |
3531 self.codeProfileAct.triggered[()].connect(self.__showProfileData) |
3401 self.actions.append(self.codeProfileAct) |
3532 self.actions.append(self.codeProfileAct) |
3402 |
3533 |
3403 self.graphicsGrp = createActionGroup(self) |
3534 self.graphicsGrp = createActionGroup(self) |
3404 |
3535 |
3405 self.applicationDiagramAct = E5Action(self.trUtf8('Application Diagram'), |
3536 self.applicationDiagramAct = E5Action( |
3406 self.trUtf8('&Application Diagram...'), 0, 0, |
3537 self.trUtf8('Application Diagram'), |
3407 self.graphicsGrp, 'project_application_diagram') |
3538 self.trUtf8('&Application Diagram...'), 0, 0, |
|
3539 self.graphicsGrp, 'project_application_diagram') |
3408 self.applicationDiagramAct.setStatusTip( |
3540 self.applicationDiagramAct.setStatusTip( |
3409 self.trUtf8('Show a diagram of the project.')) |
3541 self.trUtf8('Show a diagram of the project.')) |
3410 self.applicationDiagramAct.setWhatsThis(self.trUtf8( |
3542 self.applicationDiagramAct.setWhatsThis(self.trUtf8( |
3411 """<b>Application Diagram...</b>""" |
3543 """<b>Application Diagram...</b>""" |
3412 """<p>This shows a diagram of the project.</p>""" |
3544 """<p>This shows a diagram of the project.</p>""" |
3413 )) |
3545 )) |
3414 self.applicationDiagramAct.triggered[()].connect(self.handleApplicationDiagram) |
3546 self.applicationDiagramAct.triggered[()].connect( |
|
3547 self.handleApplicationDiagram) |
3415 self.actions.append(self.applicationDiagramAct) |
3548 self.actions.append(self.applicationDiagramAct) |
3416 |
3549 |
3417 self.loadDiagramAct = E5Action(self.trUtf8('Load Diagram'), |
3550 self.loadDiagramAct = E5Action(self.trUtf8('Load Diagram'), |
3418 self.trUtf8('&Load Diagram...'), 0, 0, |
3551 self.trUtf8('&Load Diagram...'), 0, 0, |
3419 self.graphicsGrp, 'project_load_diagram') |
3552 self.graphicsGrp, 'project_load_diagram') |
3448 self.pluginGrp, 'project_plugin_archive') |
3582 self.pluginGrp, 'project_plugin_archive') |
3449 self.pluginArchiveAct.setStatusTip( |
3583 self.pluginArchiveAct.setStatusTip( |
3450 self.trUtf8('Create an eric5 plugin archive file.')) |
3584 self.trUtf8('Create an eric5 plugin archive file.')) |
3451 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3585 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3452 """<b>Create Plugin Archive</b>""" |
3586 """<b>Create Plugin Archive</b>""" |
3453 """<p>This creates an eric5 plugin archive file using the list of files """ |
3587 """<p>This creates an eric5 plugin archive file using the list""" |
3454 """given in the PKGLIST file. The archive name is built from the main """ |
3588 """ of files given in the PKGLIST file. The archive name is""" |
3455 """script name.</p>""" |
3589 """ built from the main script name.</p>""" |
3456 )) |
3590 )) |
3457 self.pluginArchiveAct.triggered[()].connect(self.__pluginCreateArchive) |
3591 self.pluginArchiveAct.triggered[()].connect(self.__pluginCreateArchive) |
3458 self.actions.append(self.pluginArchiveAct) |
3592 self.actions.append(self.pluginArchiveAct) |
3459 |
3593 |
3460 self.pluginSArchiveAct = E5Action(self.trUtf8('Create Plugin Archive (Snapshot)'), |
3594 self.pluginSArchiveAct = E5Action( |
3461 UI.PixmapCache.getIcon("pluginArchiveSnapshot.png"), |
3595 self.trUtf8('Create Plugin Archive (Snapshot)'), |
3462 self.trUtf8('Create Plugin Archive (&Snapshot)'), 0, 0, |
3596 UI.PixmapCache.getIcon("pluginArchiveSnapshot.png"), |
3463 self.pluginGrp, 'project_plugin_sarchive') |
3597 self.trUtf8('Create Plugin Archive (&Snapshot)'), 0, 0, |
3464 self.pluginSArchiveAct.setStatusTip( |
3598 self.pluginGrp, 'project_plugin_sarchive') |
3465 self.trUtf8('Create an eric5 plugin archive file (snapshot release).')) |
3599 self.pluginSArchiveAct.setStatusTip(self.trUtf8( |
|
3600 'Create an eric5 plugin archive file (snapshot release).')) |
3466 self.pluginSArchiveAct.setWhatsThis(self.trUtf8( |
3601 self.pluginSArchiveAct.setWhatsThis(self.trUtf8( |
3467 """<b>Create Plugin Archive (Snapshot)</b>""" |
3602 """<b>Create Plugin Archive (Snapshot)</b>""" |
3468 """<p>This creates an eric5 plugin archive file using the list of files """ |
3603 """<p>This creates an eric5 plugin archive file using the list""" |
3469 """given in the PKGLIST file. The archive name is built from the main """ |
3604 """ of files given in the PKGLIST file. The archive name is""" |
3470 """script name. The version entry of the main script is modified to """ |
3605 """ built from the main script name. The version entry of the""" |
3471 """reflect a snapshot release.</p>""" |
3606 """ main script is modified to reflect a snapshot release.</p>""" |
3472 )) |
3607 )) |
3473 self.pluginSArchiveAct.triggered[()].connect(self.__pluginCreateSnapshotArchive) |
3608 self.pluginSArchiveAct.triggered[()].connect( |
|
3609 self.__pluginCreateSnapshotArchive) |
3474 self.actions.append(self.pluginSArchiveAct) |
3610 self.actions.append(self.pluginSArchiveAct) |
3475 |
3611 |
3476 self.closeAct.setEnabled(False) |
3612 self.closeAct.setEnabled(False) |
3477 self.saveAct.setEnabled(False) |
3613 self.saveAct.setEnabled(False) |
3478 self.saveasAct.setEnabled(False) |
3614 self.saveasAct.setEnabled(False) |
3752 dirs.append(d) |
3892 dirs.append(d) |
3753 continue |
3893 continue |
3754 |
3894 |
3755 filetype = "" |
3895 filetype = "" |
3756 bfn = os.path.basename(fn) |
3896 bfn = os.path.basename(fn) |
3757 for pattern in reversed(sorted(self.pdata["FILETYPES"].keys())): |
3897 for pattern in reversed( |
|
3898 sorted(self.pdata["FILETYPES"].keys())): |
3758 if fnmatch.fnmatch(bfn, pattern): |
3899 if fnmatch.fnmatch(bfn, pattern): |
3759 filetype = self.pdata["FILETYPES"][pattern] |
3900 filetype = self.pdata["FILETYPES"][pattern] |
3760 break |
3901 break |
3761 |
3902 |
3762 if (filetype == "SOURCES" and fn not in self.pdata["SOURCES"]) or \ |
3903 if (filetype == "SOURCES" and |
3763 (filetype == "FORMS" and fn not in self.pdata["FORMS"]) or \ |
3904 fn not in self.pdata["SOURCES"]) or \ |
3764 (filetype == "INTERFACES" and fn not in self.pdata["INTERFACES"]) or \ |
3905 (filetype == "FORMS" and |
3765 (filetype == "RESOURCES" and fn not in self.pdata["RESOURCES"]) or \ |
3906 fn not in self.pdata["FORMS"]) or \ |
|
3907 (filetype == "INTERFACES" and |
|
3908 fn not in self.pdata["INTERFACES"]) or \ |
|
3909 (filetype == "RESOURCES" and |
|
3910 fn not in self.pdata["RESOURCES"]) or \ |
3766 (filetype == "OTHERS" and fn not in self.pdata["OTHERS"]): |
3911 (filetype == "OTHERS" and fn not in self.pdata["OTHERS"]): |
3767 if autoInclude and AI: |
3912 if autoInclude and AI: |
3768 self.appendFile(ns) |
3913 self.appendFile(ns) |
3769 else: |
3914 else: |
3770 newFiles.append(ns) |
3915 newFiles.append(ns) |
3771 elif filetype == "TRANSLATIONS" and fn not in self.pdata["TRANSLATIONS"]: |
3916 elif filetype == "TRANSLATIONS" and \ |
3772 if fnmatch.fnmatch(ns, pattern) or fnmatch.fnmatch(ns, binpattern): |
3917 fn not in self.pdata["TRANSLATIONS"]: |
|
3918 if fnmatch.fnmatch(ns, pattern) or \ |
|
3919 fnmatch.fnmatch(ns, binpattern): |
3773 if autoInclude and AI: |
3920 if autoInclude and AI: |
3774 self.appendFile(ns) |
3921 self.appendFile(ns) |
3775 else: |
3922 else: |
3776 newFiles.append(ns) |
3923 newFiles.append(ns) |
3777 |
3924 |
3913 if override: |
4063 if override: |
3914 # override failed, revert to original |
4064 # override failed, revert to original |
3915 QApplication.restoreOverrideCursor() |
4065 QApplication.restoreOverrideCursor() |
3916 E5MessageBox.critical(self.ui, |
4066 E5MessageBox.critical(self.ui, |
3917 self.trUtf8("Version Control System"), |
4067 self.trUtf8("Version Control System"), |
3918 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found." |
4068 self.trUtf8( |
3919 "<br/>Reverting override.</p><p>{1}</p>")\ |
4069 "<p>The selected VCS <b>{0}</b> could not be" |
|
4070 " found. <br/>Reverting override.</p><p>{1}</p>") |
3920 .format(vcsSystem, msg)) |
4071 .format(vcsSystem, msg)) |
3921 self.pudata["VCSOVERRIDE"] = [] |
4072 self.pudata["VCSOVERRIDE"] = [] |
3922 return self.initVCS(nooverride=True) |
4073 return self.initVCS(nooverride=True) |
3923 |
4074 |
3924 QApplication.restoreOverrideCursor() |
4075 QApplication.restoreOverrideCursor() |
3925 E5MessageBox.critical(self.ui, |
4076 E5MessageBox.critical(self.ui, |
3926 self.trUtf8("Version Control System"), |
4077 self.trUtf8("Version Control System"), |
3927 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found.<br/>" |
4078 self.trUtf8( |
3928 "Disabling version control.</p><p>{1}</p>")\ |
4079 "<p>The selected VCS <b>{0}</b> could not be" |
3929 .format(vcsSystem, msg)) |
4080 " found.<br/>Disabling version control.</p>" |
|
4081 "<p>{1}</p>").format(vcsSystem, msg)) |
3930 vcs = None |
4082 vcs = None |
3931 if forProject: |
4083 if forProject: |
3932 self.pdata["VCS"][0] = 'None' |
4084 self.pdata["VCS"][0] = 'None' |
3933 self.setDirty(True) |
4085 self.setDirty(True) |
3934 else: |
4086 else: |
4304 if self.pdata["EOL"][0] == 0: |
4458 if self.pdata["EOL"][0] == 0: |
4305 newline = None |
4459 newline = None |
4306 else: |
4460 else: |
4307 newline = self.getEolString() |
4461 newline = self.getEolString() |
4308 pkglistFile = open(pkglist, "w", encoding="utf-8", newline=newline) |
4462 pkglistFile = open(pkglist, "w", encoding="utf-8", newline=newline) |
4309 pkglistFile.write("\n".join([Utilities.fromNativeSeparators(f) for f in lst])) |
4463 pkglistFile.write( |
|
4464 "\n".join([Utilities.fromNativeSeparators(f) for f in lst])) |
4310 pkglistFile.write("\n") # ensure the file ends with an empty line |
4465 pkglistFile.write("\n") # ensure the file ends with an empty line |
4311 pkglistFile.close() |
4466 pkglistFile.close() |
4312 except IOError as why: |
4467 except IOError as why: |
4313 E5MessageBox.critical(self.ui, |
4468 E5MessageBox.critical(self.ui, |
4314 self.trUtf8("Create Package List"), |
4469 self.trUtf8("Create Package List"), |
4315 self.trUtf8("""<p>The file <b>PKGLIST</b> could not be created.</p>""" |
4470 self.trUtf8( |
4316 """<p>Reason: {0}</p>""").format(str(why))) |
4471 """<p>The file <b>PKGLIST</b> could not be created.</p>""" |
|
4472 """<p>Reason: {0}</p>""").format(str(why))) |
4317 return |
4473 return |
4318 |
4474 |
4319 if not "PKGLIST" in self.pdata["OTHERS"]: |
4475 if not "PKGLIST" in self.pdata["OTHERS"]: |
4320 self.appendFile("PKGLIST") |
4476 self.appendFile("PKGLIST") |
4321 |
4477 |
4335 |
4491 |
4336 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
4492 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
4337 len(self.pdata["MAINSCRIPT"][0]) == 0: |
4493 len(self.pdata["MAINSCRIPT"][0]) == 0: |
4338 E5MessageBox.critical(self.ui, |
4494 E5MessageBox.critical(self.ui, |
4339 self.trUtf8("Create Plugin Archive"), |
4495 self.trUtf8("Create Plugin Archive"), |
4340 self.trUtf8("""The project does not have a main script defined. """ |
4496 self.trUtf8( |
4341 """Aborting...""")) |
4497 """The project does not have a main script defined. """ |
|
4498 """Aborting...""")) |
4342 return |
4499 return |
4343 |
4500 |
4344 try: |
4501 try: |
4345 pkglistFile = open(pkglist, "r", encoding="utf-8") |
4502 pkglistFile = open(pkglist, "r", encoding="utf-8") |
4346 names = pkglistFile.read() |
4503 names = pkglistFile.read() |
4347 pkglistFile.close() |
4504 pkglistFile.close() |
4348 names = sorted(names.splitlines()) |
4505 names = sorted(names.splitlines()) |
4349 except IOError as why: |
4506 except IOError as why: |
4350 E5MessageBox.critical(self.ui, |
4507 E5MessageBox.critical(self.ui, |
4351 self.trUtf8("Create Plugin Archive"), |
4508 self.trUtf8("Create Plugin Archive"), |
4352 self.trUtf8("""<p>The file <b>PKGLIST</b> could not be read.</p>""" |
4509 self.trUtf8( |
4353 """<p>Reason: {0}</p>""").format(str(why))) |
4510 """<p>The file <b>PKGLIST</b> could not be read.</p>""" |
|
4511 """<p>Reason: {0}</p>""").format(str(why))) |
4354 return |
4512 return |
4355 |
4513 |
4356 archive = \ |
4514 archive = os.path.join( |
4357 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0].replace(".py", ".zip")) |
4515 self.ppath, self.pdata["MAINSCRIPT"][0].replace(".py", ".zip")) |
4358 try: |
4516 try: |
4359 archiveFile = zipfile.ZipFile(archive, "w") |
4517 archiveFile = zipfile.ZipFile(archive, "w") |
4360 except IOError as why: |
4518 except IOError as why: |
4361 E5MessageBox.critical(self.ui, |
4519 E5MessageBox.critical(self.ui, |
4362 self.trUtf8("Create Plugin Archive"), |
4520 self.trUtf8("Create Plugin Archive"), |
4363 self.trUtf8("""<p>The eric5 plugin archive file <b>{0}</b> could """ |
4521 self.trUtf8( |
4364 """not be created.</p>""" |
4522 """<p>The eric5 plugin archive file <b>{0}</b> could """ |
4365 """<p>Reason: {1}</p>""").format(archive, str(why))) |
4523 """not be created.</p>""" |
|
4524 """<p>Reason: {1}</p>""").format(archive, str(why))) |
4366 return |
4525 return |
4367 |
4526 |
4368 for name in names: |
4527 for name in names: |
4369 if name: |
4528 if name: |
4370 try: |
4529 try: |
4371 self.__createZipDirEntries(os.path.split(name)[0], archiveFile) |
4530 self.__createZipDirEntries( |
|
4531 os.path.split(name)[0], archiveFile) |
4372 if snapshot and name == self.pdata["MAINSCRIPT"][0]: |
4532 if snapshot and name == self.pdata["MAINSCRIPT"][0]: |
4373 snapshotSource, version = self.__createSnapshotSource( |
4533 snapshotSource, version = self.__createSnapshotSource( |
4374 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
4534 os.path.join(self.ppath, |
|
4535 self.pdata["MAINSCRIPT"][0])) |
4375 archiveFile.writestr(name, snapshotSource) |
4536 archiveFile.writestr(name, snapshotSource) |
4376 else: |
4537 else: |
4377 archiveFile.write(os.path.join(self.ppath, name), name) |
4538 archiveFile.write(os.path.join(self.ppath, name), name) |
4378 if name == self.pdata["MAINSCRIPT"][0]: |
4539 if name == self.pdata["MAINSCRIPT"][0]: |
4379 version = self.__pluginExtractVersion( |
4540 version = self.__pluginExtractVersion( |
4380 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
4541 os.path.join(self.ppath, |
|
4542 self.pdata["MAINSCRIPT"][0])) |
4381 except OSError as why: |
4543 except OSError as why: |
4382 E5MessageBox.critical(self.ui, |
4544 E5MessageBox.critical(self.ui, |
4383 self.trUtf8("Create Plugin Archive"), |
4545 self.trUtf8("Create Plugin Archive"), |
4384 self.trUtf8("""<p>The file <b>{0}</b> could not be stored """ |
4546 self.trUtf8( |
4385 """in the archive. Ignoring it.</p>""" |
4547 """<p>The file <b>{0}</b> could not be stored """ |
4386 """<p>Reason: {1}</p>""")\ |
4548 """in the archive. Ignoring it.</p>""" |
4387 .format(os.path.join(self.ppath, name), str(why))) |
4549 """<p>Reason: {1}</p>""")\ |
|
4550 .format(os.path.join(self.ppath, name), str(why))) |
4388 archiveFile.writestr("VERSION", version.encode("utf-8")) |
4551 archiveFile.writestr("VERSION", version.encode("utf-8")) |
4389 archiveFile.close() |
4552 archiveFile.close() |
4390 |
4553 |
4391 if not archive in self.pdata["OTHERS"]: |
4554 if not archive in self.pdata["OTHERS"]: |
4392 self.appendFile(archive) |
4555 self.appendFile(archive) |
4393 |
4556 |
4394 if self.ui.notificationsEnabled(): |
4557 if self.ui.notificationsEnabled(): |
4395 self.ui.showNotification(UI.PixmapCache.getPixmap("pluginArchive48.png"), |
4558 self.ui.showNotification( |
|
4559 UI.PixmapCache.getPixmap("pluginArchive48.png"), |
4396 self.trUtf8("Create Plugin Archive"), |
4560 self.trUtf8("Create Plugin Archive"), |
4397 self.trUtf8("""<p>The eric5 plugin archive file <b>{0}</b> was """ |
4561 self.trUtf8( |
4398 """created successfully.</p>""")\ |
4562 """<p>The eric5 plugin archive file <b>{0}</b> was """ |
|
4563 """created successfully.</p>""")\ |
4399 .format(os.path.basename(archive))) |
4564 .format(os.path.basename(archive))) |
4400 else: |
4565 else: |
4401 E5MessageBox.information(self.ui, |
4566 E5MessageBox.information(self.ui, |
4402 self.trUtf8("Create Plugin Archive"), |
4567 self.trUtf8("Create Plugin Archive"), |
4403 self.trUtf8("""<p>The eric5 plugin archive file <b>{0}</b> was """ |
4568 self.trUtf8( |
4404 """created successfully.</p>""").format(archive)) |
4569 """<p>The eric5 plugin archive file <b>{0}</b> was """ |
|
4570 """created successfully.</p>""").format(archive)) |
4405 |
4571 |
4406 def __pluginCreateSnapshotArchive(self): |
4572 def __pluginCreateSnapshotArchive(self): |
4407 """ |
4573 """ |
4408 Private slot to create an eric5 plugin archive snapshot release. |
4574 Private slot to create an eric5 plugin archive snapshot release. |
4409 """ |
4575 """ |
4443 except (IOError, UnicodeError) as why: |
4609 except (IOError, UnicodeError) as why: |
4444 E5MessageBox.critical(self.ui, |
4610 E5MessageBox.critical(self.ui, |
4445 self.trUtf8("Create Plugin Archive"), |
4611 self.trUtf8("Create Plugin Archive"), |
4446 self.trUtf8("""<p>The plugin file <b>{0}</b> could """ |
4612 self.trUtf8("""<p>The plugin file <b>{0}</b> could """ |
4447 """not be read.</p>""" |
4613 """not be read.</p>""" |
4448 """<p>Reason: {1}</p>""").format(filename, str(why))) |
4614 """<p>Reason: {1}</p>""") |
|
4615 .format(filename, str(why))) |
4449 return b"", "" |
4616 return b"", "" |
4450 |
4617 |
4451 lineno = 0 |
4618 lineno = 0 |
4452 while lineno < len(sourcelines): |
4619 while lineno < len(sourcelines): |
4453 if sourcelines[lineno].startswith("version = "): |
4620 if sourcelines[lineno].startswith("version = "): |
4454 # found the line to modify |
4621 # found the line to modify |
4455 datestr = time.strftime("%Y%m%d") |
4622 datestr = time.strftime("%Y%m%d") |
4456 lineend = sourcelines[lineno].replace(sourcelines[lineno].rstrip(), "") |
4623 lineend = sourcelines[lineno]\ |
4457 sversion = "{0}-snapshot-{1}".format( |
4624 .replace(sourcelines[lineno].rstrip(), "") |
4458 sourcelines[lineno].replace("version = ", "").strip()[1:-1], |
4625 sversion = "{0}-snapshot-{1}".format(sourcelines[lineno]\ |
|
4626 .replace("version = ", "").strip()[1:-1], |
4459 datestr) |
4627 datestr) |
4460 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4628 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4461 sourcelines[lineno].rstrip(), datestr, lineend) |
4629 sourcelines[lineno].rstrip(), datestr, lineend) |
4462 break |
4630 break |
4463 |
4631 |