87 OTHERS project data area |
88 OTHERS project data area |
88 @signal projectAboutToBeCreated() emitted just before the project will be created |
89 @signal projectAboutToBeCreated() emitted just before the project will be created |
89 @signal newProjectHooks() emitted after a new project was generated but before |
90 @signal newProjectHooks() emitted after a new project was generated but before |
90 the newProject() signal is sent |
91 the newProject() signal is sent |
91 @signal newProject() emitted after a new project was generated |
92 @signal newProject() emitted after a new project was generated |
92 @signal sourceFile(str) emitted after a project file was read to |
93 @signal sourceFile(str) emitted after a project file was read to |
93 open the main script |
94 open the main script |
94 @signal projectOpenedHooks() emitted after a project file was read but before the |
95 @signal projectOpenedHooks() emitted after a project file was read but before the |
95 projectOpened() signal is sent |
96 projectOpened() signal is sent |
96 @signal projectOpened() emitted after a project file was read |
97 @signal projectOpened() emitted after a project file was read |
97 @signal projectClosedHooks() emitted after a project file was closed but before the |
98 @signal projectClosedHooks() emitted after a project file was closed but before the |
146 showMenu = pyqtSignal(str, QMenu) |
147 showMenu = pyqtSignal(str, QMenu) |
147 lexerAssociationsChanged = pyqtSignal() |
148 lexerAssociationsChanged = pyqtSignal() |
148 |
149 |
149 keynames = [ |
150 keynames = [ |
150 "PROGLANGUAGE", "MIXEDLANGUAGE", "PROJECTTYPE", |
151 "PROGLANGUAGE", "MIXEDLANGUAGE", "PROJECTTYPE", |
151 "SPELLLANGUAGE", "SPELLWORDS", "SPELLEXCLUDES", |
152 "SPELLLANGUAGE", "SPELLWORDS", "SPELLEXCLUDES", |
152 "DESCRIPTION", "VERSION", "HASH", |
153 "DESCRIPTION", "VERSION", "HASH", |
153 "AUTHOR", "EMAIL", |
154 "AUTHOR", "EMAIL", |
154 "SOURCES", "FORMS", "RESOURCES", |
155 "SOURCES", "FORMS", "RESOURCES", |
155 "TRANSLATIONS", "TRANSLATIONPATTERN", "TRANSLATIONSBINPATH", |
156 "TRANSLATIONS", "TRANSLATIONPATTERN", "TRANSLATIONSBINPATH", |
156 "TRANSLATIONEXCEPTIONS", |
157 "TRANSLATIONEXCEPTIONS", |
157 "MAINSCRIPT", "EOL", |
158 "MAINSCRIPT", "EOL", |
158 "VCS", "VCSOPTIONS", "VCSOTHERDATA", |
159 "VCS", "VCSOPTIONS", "VCSOTHERDATA", |
159 "OTHERS", "INTERFACES", |
160 "OTHERS", "INTERFACES", |
160 "FILETYPES", "LEXERASSOCS", |
161 "FILETYPES", "LEXERASSOCS", |
161 "PROJECTTYPESPECIFICDATA", |
162 "PROJECTTYPESPECIFICDATA", |
162 "DOCUMENTATIONPARMS", |
163 "DOCUMENTATIONPARMS", |
163 "PACKAGERSPARMS", |
164 "PACKAGERSPARMS", |
164 "CHECKERSPARMS", |
165 "CHECKERSPARMS", |
165 "OTHERTOOLSPARMS", |
166 "OTHERTOOLSPARMS", |
166 ] |
167 ] |
167 |
168 |
168 dbgKeynames = [ |
169 dbgKeynames = [ |
169 "INTERPRETER", "DEBUGCLIENT", |
170 "INTERPRETER", "DEBUGCLIENT", |
170 "ENVIRONMENTOVERRIDE", "ENVIRONMENTSTRING", |
171 "ENVIRONMENTOVERRIDE", "ENVIRONMENTSTRING", |
178 "VCSOVERRIDE", "VCSSTATUSMONITORINTERVAL", |
179 "VCSOVERRIDE", "VCSSTATUSMONITORINTERVAL", |
179 ] |
180 ] |
180 |
181 |
181 eols = [os.linesep, "\n", "\r", "\r\n"] |
182 eols = [os.linesep, "\n", "\r", "\r\n"] |
182 |
183 |
183 def __init__(self, parent = None, filename = None): |
184 def __init__(self, parent=None, filename=None): |
184 """ |
185 """ |
185 Constructor |
186 Constructor |
186 |
187 |
187 @param parent parent widget (usually the ui object) (QWidget) |
188 @param parent parent widget (usually the ui object) (QWidget) |
188 @param filename optional filename of a project file to open (string) |
189 @param filename optional filename of a project file to open (string) |
190 QObject.__init__(self, parent) |
191 QObject.__init__(self, parent) |
191 |
192 |
192 self.ui = parent |
193 self.ui = parent |
193 |
194 |
194 self.sourceExtensions = { |
195 self.sourceExtensions = { |
195 "Python2" : Preferences.getPython("PythonExtensions"), |
196 "Python2": Preferences.getPython("PythonExtensions"), |
196 "Python3" : Preferences.getPython("Python3Extensions"), |
197 "Python3": Preferences.getPython("Python3Extensions"), |
197 "Ruby" : ['.rb'], |
198 "Ruby": ['.rb'], |
198 "Mixed" : ['.py', '.ptl', '.rb'] |
199 "Mixed": ['.py', '.ptl', '.rb'] |
199 } |
200 } |
200 |
201 |
201 self.dbgFilters = { |
202 self.dbgFilters = { |
202 "Python2" : self.trUtf8( |
203 "Python2": self.trUtf8( |
203 "Python2 Files (*.py2);;" |
204 "Python2 Files (*.py2);;" |
204 "Python2 GUI Files (*.pyw2);;"), |
205 "Python2 GUI Files (*.pyw2);;"), |
205 "Python3" : self.trUtf8( |
206 "Python3": self.trUtf8( |
206 "Python3 Files (*.py *.py3);;" |
207 "Python3 Files (*.py *.py3);;" |
207 "Python3 GUI Files (*.pyw *.pyw3);;"), |
208 "Python3 GUI Files (*.pyw *.pyw3);;"), |
208 "Ruby" : self.trUtf8("Ruby Files (*.rb);;"), |
209 "Ruby": self.trUtf8("Ruby Files (*.rb);;"), |
209 } |
210 } |
210 |
211 |
211 self.vcsMenu = None |
212 self.vcsMenu = None |
212 |
213 |
213 self.__initProjectTypes() |
214 self.__initProjectTypes() |
222 else: |
223 else: |
223 self.vcs = self.initVCS() |
224 self.vcs = self.initVCS() |
224 |
225 |
225 self.__model = ProjectBrowserModel(self) |
226 self.__model = ProjectBrowserModel(self) |
226 |
227 |
227 self.codemetrics = None |
228 self.codemetrics = None |
228 self.codecoverage = None |
229 self.codecoverage = None |
229 self.profiledata = None |
230 self.profiledata = None |
230 self.applicationDiagram = None |
231 self.applicationDiagram = None |
231 |
232 |
232 def __initProjectTypes(self): |
233 def __initProjectTypes(self): |
233 """ |
234 """ |
234 Private method to initialize the list of supported project types. |
235 Private method to initialize the list of supported project types. |
264 |
265 |
265 @param type_ internal type designator to be unregistered (string) |
266 @param type_ internal type designator to be unregistered (string) |
266 """ |
267 """ |
267 return type_ in self.__projectTypes |
268 return type_ in self.__projectTypes |
268 |
269 |
269 def registerProjectType(self, type_, description, fileTypeCallback = None, |
270 def registerProjectType(self, type_, description, fileTypeCallback=None, |
270 binaryTranslationsCallback = None, lexerAssociationCallback = None): |
271 binaryTranslationsCallback=None, lexerAssociationCallback=None): |
271 """ |
272 """ |
272 Public method to register a project type. |
273 Public method to register a project type. |
273 |
274 |
274 @param type_ internal type designator to be registered (string) |
275 @param type_ internal type designator to be registered (string) |
275 @param description more verbose type name (display string) (string) |
276 @param description more verbose type name (display string) (string) |
276 @keyparam fileTypeCallback reference to a method returning a dictionary |
277 @keyparam fileTypeCallback reference to a method returning a dictionary |
277 of filetype associations. |
278 of filetype associations. |
278 @keyparam binaryTranslationsCallback reference to a method returning the |
279 @keyparam binaryTranslationsCallback reference to a method returning the |
279 name of the binary translation file given the name of the raw |
280 name of the binary translation file given the name of the raw |
280 translation file |
281 translation file |
281 @keyparam lexerAssociationCallback reference to a method returning the |
282 @keyparam lexerAssociationCallback reference to a method returning the |
282 lexer type to be used for syntax highlighting given the name of |
283 lexer type to be used for syntax highlighting given the name of |
283 a file |
284 a file |
284 """ |
285 """ |
372 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, DOCUMENTATIONPARMS |
373 PROJECTTYPESPECIFICDATA, CHECKERSPARMS, PACKAGERSPARMS, DOCUMENTATIONPARMS |
373 or OTHERTOOLSPARMS) |
374 or OTHERTOOLSPARMS) |
374 @param key key of the data entry to get (string). |
375 @param key key of the data entry to get (string). |
375 @return a copy of the requested data or None |
376 @return a copy of the requested data or None |
376 """ |
377 """ |
377 if category in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
378 if category in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
378 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"] and \ |
379 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"] and \ |
379 key in self.pdata[category]: |
380 key in self.pdata[category]: |
380 return copy.deepcopy(self.pdata[category][key]) |
381 return copy.deepcopy(self.pdata[category][key]) |
381 else: |
382 else: |
382 return None |
383 return None |
390 or OTHERTOOLSPARMS) |
391 or OTHERTOOLSPARMS) |
391 @param key key of the data entry to get (string). |
392 @param key key of the data entry to get (string). |
392 @param data data to be stored |
393 @param data data to be stored |
393 @return flag indicating success (boolean) |
394 @return flag indicating success (boolean) |
394 """ |
395 """ |
395 if category not in ["PROJECTTYPESPECIFICDATA","CHECKERSPARMS", "PACKAGERSPARMS", |
396 if category not in ["PROJECTTYPESPECIFICDATA", "CHECKERSPARMS", "PACKAGERSPARMS", |
396 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"]: |
397 "DOCUMENTATIONPARMS", "OTHERTOOLSPARMS"]: |
397 return False |
398 return False |
398 |
399 |
399 # test for changes of data and save them in the project |
400 # test for changes of data and save them in the project |
400 # 1. there were none, now there are |
401 # 1. there were none, now there are |
428 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" |
429 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" |
429 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" |
430 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" |
430 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "E4Plugin", "PySide"]: |
431 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "E4Plugin", "PySide"]: |
431 self.pdata["FILETYPES"]["*.ui"] = "FORMS" |
432 self.pdata["FILETYPES"]["*.ui"] = "FORMS" |
432 self.pdata["FILETYPES"]["*.ui.h"] = "FORMS" |
433 self.pdata["FILETYPES"]["*.ui.h"] = "FORMS" |
433 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
434 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
434 "PySide", "PySideC"]: |
435 "PySide", "PySideC"]: |
435 self.pdata["FILETYPES"]["*.qrc"] = "RESOURCES" |
436 self.pdata["FILETYPES"]["*.qrc"] = "RESOURCES" |
436 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
437 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
437 "PySide", "PySideC"]: |
438 "PySide", "PySideC"]: |
438 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
439 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
439 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
440 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
440 try: |
441 try: |
441 if self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]] is not None: |
442 if self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"][0]] is not None: |
447 |
448 |
448 def updateFileTypes(self): |
449 def updateFileTypes(self): |
449 """ |
450 """ |
450 Public method to update the filetype associations with new default values. |
451 Public method to update the filetype associations with new default values. |
451 """ |
452 """ |
452 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
453 if self.pdata["PROJECTTYPE"][0] in ["Qt4", "Qt4C", "E4Plugin", |
453 "PySide", "PySideC"]: |
454 "PySide", "PySideC"]: |
454 if "*.ts" not in self.pdata["FILETYPES"]: |
455 if "*.ts" not in self.pdata["FILETYPES"]: |
455 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
456 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" |
456 if "*.qm" not in self.pdata["FILETYPES"]: |
457 if "*.qm" not in self.pdata["FILETYPES"]: |
457 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
458 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" |
552 """ |
553 """ |
553 return self.opened |
554 return self.opened |
554 |
555 |
555 def __checkFilesExist(self, index): |
556 def __checkFilesExist(self, index): |
556 """ |
557 """ |
557 Private method to check, if the files in a list exist. |
558 Private method to check, if the files in a list exist. |
558 |
559 |
559 The files in the indicated list are checked for existance in the |
560 The files in the indicated list are checked for existance in the |
560 filesystem. Non existant files are removed from the list and the |
561 filesystem. Non existant files are removed from the list and the |
561 dirty state of the project is changed accordingly. |
562 dirty state of the project is changed accordingly. |
562 |
563 |
577 def __makePpathRe(self): |
578 def __makePpathRe(self): |
578 """ |
579 """ |
579 Private method to generate a regular expression for the project path. |
580 Private method to generate a regular expression for the project path. |
580 """ |
581 """ |
581 ppathRe = (self.ppath + os.sep)\ |
582 ppathRe = (self.ppath + os.sep)\ |
582 .replace("\\","@@")\ |
583 .replace("\\", "@@")\ |
583 .replace("/","@@")\ |
584 .replace("/", "@@")\ |
584 .replace("@@",r"[\\/]") |
585 .replace("@@", r"[\\/]") |
585 if Utilities.isWindowsPlatform(): |
586 if Utilities.isWindowsPlatform(): |
586 self.ppathRe = re.compile(ppathRe, re.IGNORECASE) |
587 self.ppathRe = re.compile(ppathRe, re.IGNORECASE) |
587 else: |
588 else: |
588 self.ppathRe = re.compile(ppathRe) |
589 self.ppathRe = re.compile(ppathRe) |
589 |
590 |
656 |
657 |
657 # create hash value, if it doesn't have one |
658 # create hash value, if it doesn't have one |
658 if not self.pdata["HASH"][0]: |
659 if not self.pdata["HASH"][0]: |
659 hash = str(QCryptographicHash.hash( |
660 hash = str(QCryptographicHash.hash( |
660 QByteArray(self.ppath), QCryptographicHash.Sha1).toHex(), |
661 QByteArray(self.ppath), QCryptographicHash.Sha1).toHex(), |
661 encoding = "utf-8") |
662 encoding="utf-8") |
662 self.pdata["HASH"] = [hash] |
663 self.pdata["HASH"] = [hash] |
663 self.setDirty(True) |
664 self.setDirty(True) |
664 |
665 |
665 return res |
666 return res |
666 |
667 |
667 def __writeProject(self, fn = None): |
668 def __writeProject(self, fn=None): |
668 """ |
669 """ |
669 Private method to save the project infos to a project file. |
670 Private method to save the project infos to a project file. |
670 |
671 |
671 @param fn optional filename of the project file to be written (string). |
672 @param fn optional filename of the project file to be written (string). |
672 If fn is None, the filename stored in the project object |
673 If fn is None, the filename stored in the project object |
744 E5MessageBox.critical(self.ui, |
745 E5MessageBox.critical(self.ui, |
745 self.trUtf8("Save user project properties"), |
746 self.trUtf8("Save user project properties"), |
746 self.trUtf8("<p>The user specific project properties file <b>{0}</b>" |
747 self.trUtf8("<p>The user specific project properties file <b>{0}</b>" |
747 " could not be written.</p>").format(fn)) |
748 " could not be written.</p>").format(fn)) |
748 |
749 |
749 def __readSession(self, quiet = False, indicator = ""): |
750 def __readSession(self, quiet=False, indicator=""): |
750 """ |
751 """ |
751 Private method to read in the project session file (.e4s) |
752 Private method to read in the project session file (.e4s) |
752 |
753 |
753 @param quiet flag indicating quiet operations. |
754 @param quiet flag indicating quiet operations. |
754 If this flag is true, no errors are reported. |
755 If this flag is true, no errors are reported. |
760 self.trUtf8("Read project session"), |
761 self.trUtf8("Read project session"), |
761 self.trUtf8("Please save the project first.")) |
762 self.trUtf8("Please save the project first.")) |
762 return |
763 return |
763 |
764 |
764 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
765 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
765 fn = os.path.join(self.getProjectManagementDir(), |
766 fn = os.path.join(self.getProjectManagementDir(), |
766 '{0}{1}.e4s'.format(fn, indicator)) |
767 '{0}{1}.e4s'.format(fn, indicator)) |
767 |
768 |
768 f = QFile(fn) |
769 f = QFile(fn) |
769 if f.open(QIODevice.ReadOnly): |
770 if f.open(QIODevice.ReadOnly): |
770 reader = SessionReader(f, False) |
771 reader = SessionReader(f, False) |
771 reader.readXML(quiet = quiet) |
772 reader.readXML(quiet=quiet) |
772 f.close() |
773 f.close() |
773 else: |
774 else: |
774 if not quiet: |
775 if not quiet: |
775 E5MessageBox.critical(self.ui, |
776 E5MessageBox.critical(self.ui, |
776 self.trUtf8("Read project session"), |
777 self.trUtf8("Read project session"), |
777 self.trUtf8("<p>The project session file <b>{0}</b> could not be" |
778 self.trUtf8("<p>The project session file <b>{0}</b> could not be" |
778 " read.</p>").format(fn)) |
779 " read.</p>").format(fn)) |
779 |
780 |
780 def __writeSession(self, quiet = False, indicator = ""): |
781 def __writeSession(self, quiet=False, indicator=""): |
781 """ |
782 """ |
782 Private method to write the session data to an XML file (.e4s). |
783 Private method to write the session data to an XML file (.e4s). |
783 |
784 |
784 @param quiet flag indicating quiet operations. |
785 @param quiet flag indicating quiet operations. |
785 If this flag is true, no errors are reported. |
786 If this flag is true, no errors are reported. |
791 self.trUtf8("Save project session"), |
792 self.trUtf8("Save project session"), |
792 self.trUtf8("Please save the project first.")) |
793 self.trUtf8("Please save the project first.")) |
793 return |
794 return |
794 |
795 |
795 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
796 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
796 fn = os.path.join(self.getProjectManagementDir(), |
797 fn = os.path.join(self.getProjectManagementDir(), |
797 '{0}{1}.e4s'.format(fn, indicator)) |
798 '{0}{1}.e4s'.format(fn, indicator)) |
798 |
799 |
799 f = QFile(fn) |
800 f = QFile(fn) |
800 if f.open(QIODevice.WriteOnly): |
801 if f.open(QIODevice.WriteOnly): |
801 SessionWriter(f, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
802 SessionWriter(f, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
875 return |
876 return |
876 |
877 |
877 TasksWriter(f, True, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
878 TasksWriter(f, True, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
878 f.close() |
879 f.close() |
879 |
880 |
880 def __readDebugProperties(self, quiet = False): |
881 def __readDebugProperties(self, quiet=False): |
881 """ |
882 """ |
882 Private method to read in the project debugger properties file (.e4d) |
883 Private method to read in the project debugger properties file (.e4d) |
883 |
884 |
884 @param quiet flag indicating quiet operations. |
885 @param quiet flag indicating quiet operations. |
885 If this flag is true, no errors are reported. |
886 If this flag is true, no errors are reported. |
895 fn = os.path.join(self.getProjectManagementDir(), '{0}.e4d'.format(fn)) |
896 fn = os.path.join(self.getProjectManagementDir(), '{0}.e4d'.format(fn)) |
896 |
897 |
897 f = QFile(fn) |
898 f = QFile(fn) |
898 if f.open(QIODevice.ReadOnly): |
899 if f.open(QIODevice.ReadOnly): |
899 reader = DebuggerPropertiesReader(f, self) |
900 reader = DebuggerPropertiesReader(f, self) |
900 reader.readXML(quiet = quiet) |
901 reader.readXML(quiet=quiet) |
901 f.close() |
902 f.close() |
902 else: |
903 else: |
903 if not quiet: |
904 if not quiet: |
904 E5MessageBox.critical(self.ui, |
905 E5MessageBox.critical(self.ui, |
905 self.trUtf8("Read debugger properties"), |
906 self.trUtf8("Read debugger properties"), |
906 self.trUtf8("<p>The project debugger properties file <b>{0}</b> could" |
907 self.trUtf8("<p>The project debugger properties file <b>{0}</b> could" |
907 " not be read.</p>").format(fn)) |
908 " not be read.</p>").format(fn)) |
908 |
909 |
909 def __writeDebugProperties(self, quiet = False): |
910 def __writeDebugProperties(self, quiet=False): |
910 """ |
911 """ |
911 Private method to write the project debugger properties file (.e4d) |
912 Private method to write the project debugger properties file (.e4d) |
912 |
913 |
913 @param quiet flag indicating quiet operations. |
914 @param quiet flag indicating quiet operations. |
914 If this flag is true, no errors are reported. |
915 If this flag is true, no errors are reported. |
998 @param key key of the property (string) |
999 @param key key of the property (string) |
999 @return value of the property |
1000 @return value of the property |
1000 """ |
1001 """ |
1001 return self.debugProperties[key] |
1002 return self.debugProperties[key] |
1002 |
1003 |
1003 def setDbgInfo(self, argv, wd, env, excReporting, excList, excIgnoreList, |
1004 def setDbgInfo(self, argv, wd, env, excReporting, excList, excIgnoreList, |
1004 autoClearShell, tracePython = None, autoContinue = None): |
1005 autoClearShell, tracePython=None, autoContinue=None): |
1005 """ |
1006 """ |
1006 Public method to set the debugging information. |
1007 Public method to set the debugging information. |
1007 |
1008 |
1008 @param argv command line arguments to be used (string) |
1009 @param argv command line arguments to be used (string) |
1009 @param wd working directory (string) |
1010 @param wd working directory (string) |
1151 self.trUtf8("Delete translation"), |
1152 self.trUtf8("Delete translation"), |
1152 self.trUtf8("<p>The selected translation file <b>{0}</b> could not be" |
1153 self.trUtf8("<p>The selected translation file <b>{0}</b> could not be" |
1153 " deleted.</p>").format(qmFile)) |
1154 " deleted.</p>").format(qmFile)) |
1154 return |
1155 return |
1155 |
1156 |
1156 def appendFile(self, fn, isSourceFile = False, updateModel = True): |
1157 def appendFile(self, fn, isSourceFile=False, updateModel=True): |
1157 """ |
1158 """ |
1158 Public method to append a file to the project. |
1159 Public method to append a file to the project. |
1159 |
1160 |
1160 @param fn filename to be added to the project (string) |
1161 @param fn filename to be added to the project (string) |
1161 @param isSourceFile flag indicating that this is a source file |
1162 @param isSourceFile flag indicating that this is a source file |
1242 self.otherssubdirs.append(newdir) |
1243 self.otherssubdirs.append(newdir) |
1243 |
1244 |
1244 if dirty: |
1245 if dirty: |
1245 self.setDirty(True) |
1246 self.setDirty(True) |
1246 |
1247 |
1247 def addFiles(self, filter = None, startdir = None): |
1248 def addFiles(self, filter=None, startdir=None): |
1248 """ |
1249 """ |
1249 Public slot used to add files to the project. |
1250 Public slot used to add files to the project. |
1250 |
1251 |
1251 @param filter filter to be used by the add file dialog |
1252 @param filter filter to be used by the add file dialog |
1252 (string out of source, form, resource, interface, others) |
1253 (string out of source, form, resource, interface, others) |
1253 @param startdir start directory for the selection dialog |
1254 @param startdir start directory for the selection dialog |
1254 """ |
1255 """ |
1255 if startdir is None: |
1256 if startdir is None: |
1256 startdir = self.ppath |
1257 startdir = self.ppath |
1257 dlg = AddFileDialog(self, self.parent(), filter, startdir = startdir) |
1258 dlg = AddFileDialog(self, self.parent(), filter, startdir=startdir) |
1258 if dlg.exec_() == QDialog.Accepted: |
1259 if dlg.exec_() == QDialog.Accepted: |
1259 fnames, target, isSource = dlg.getData() |
1260 fnames, target, isSource = dlg.getData() |
1260 if target != '': |
1261 if target != '': |
1261 for fn in fnames: |
1262 for fn in fnames: |
1262 targetfile = os.path.join(target, os.path.basename(fn)) |
1263 targetfile = os.path.join(target, os.path.basename(fn)) |
1269 res = E5MessageBox.yesNo(self.ui, |
1270 res = E5MessageBox.yesNo(self.ui, |
1270 self.trUtf8("Add file"), |
1271 self.trUtf8("Add file"), |
1271 self.trUtf8("<p>The file <b>{0}</b> already" |
1272 self.trUtf8("<p>The file <b>{0}</b> already" |
1272 " exists.</p><p>Overwrite it?</p>") |
1273 " exists.</p><p>Overwrite it?</p>") |
1273 .format(targetfile), |
1274 .format(targetfile), |
1274 icon = E5MessageBox.Warning) |
1275 icon=E5MessageBox.Warning) |
1275 if not res: |
1276 if not res: |
1276 return # don't overwrite |
1277 return # don't overwrite |
1277 |
1278 |
1278 shutil.copy(fn, target) |
1279 shutil.copy(fn, target) |
1279 except IOError as why: |
1280 except IOError as why: |
1288 else: |
1289 else: |
1289 E5MessageBox.critical(self.ui, |
1290 E5MessageBox.critical(self.ui, |
1290 self.trUtf8("Add file"), |
1291 self.trUtf8("Add file"), |
1291 self.trUtf8("The target directory must not be empty.")) |
1292 self.trUtf8("The target directory must not be empty.")) |
1292 |
1293 |
1293 def __addSingleDirectory(self, filetype, source, target, quiet = False): |
1294 def __addSingleDirectory(self, filetype, source, target, quiet=False): |
1294 """ |
1295 """ |
1295 Private method used to add all files of a single directory to the project. |
1296 Private method used to add all files of a single directory to the project. |
1296 |
1297 |
1297 @param filetype type of files to add (string) |
1298 @param filetype type of files to add (string) |
1298 @param source source directory (string) |
1299 @param source source directory (string) |
1344 res = E5MessageBox.yesNo(self.ui, |
1345 res = E5MessageBox.yesNo(self.ui, |
1345 self.trUtf8("Add directory"), |
1346 self.trUtf8("Add directory"), |
1346 self.trUtf8("<p>The file <b>{0}</b> already exists.</p>" |
1347 self.trUtf8("<p>The file <b>{0}</b> already exists.</p>" |
1347 "<p>Overwrite it?</p>") |
1348 "<p>Overwrite it?</p>") |
1348 .format(targetfile), |
1349 .format(targetfile), |
1349 icon = E5MessageBox.Warning) |
1350 icon=E5MessageBox.Warning) |
1350 if not res: |
1351 if not res: |
1351 continue # don't overwrite, carry on with next file |
1352 continue # don't overwrite, carry on with next file |
1352 |
1353 |
1353 shutil.copy(file, target) |
1354 shutil.copy(file, target) |
1354 except EnvironmentError: |
1355 except EnvironmentError: |
1374 ns = os.path.join(source, name) |
1375 ns = os.path.join(source, name) |
1375 if os.path.isdir(ns): |
1376 if os.path.isdir(ns): |
1376 nt = os.path.join(target, name) |
1377 nt = os.path.join(target, name) |
1377 self.__addRecursiveDirectory(filetype, ns, nt) |
1378 self.__addRecursiveDirectory(filetype, ns, nt) |
1378 |
1379 |
1379 def addDirectory(self, filter = None, startdir = None): |
1380 def addDirectory(self, filter=None, startdir=None): |
1380 """ |
1381 """ |
1381 Public method used to add all files of a directory to the project. |
1382 Public method used to add all files of a directory to the project. |
1382 |
1383 |
1383 @param filter filter to be used by the add directory dialog |
1384 @param filter filter to be used by the add directory dialog |
1384 (string out of source, form, resource, interface, others) |
1385 (string out of source, form, resource, interface, others) |
1385 @param startdir start directory for the selection dialog (string) |
1386 @param startdir start directory for the selection dialog (string) |
1386 """ |
1387 """ |
1387 if startdir is None: |
1388 if startdir is None: |
1388 startdir = self.ppath |
1389 startdir = self.ppath |
1389 dlg = AddDirectoryDialog(self, filter, self.parent(), startdir = startdir) |
1390 dlg = AddDirectoryDialog(self, filter, self.parent(), startdir=startdir) |
1390 if dlg.exec_() == QDialog.Accepted: |
1391 if dlg.exec_() == QDialog.Accepted: |
1391 filetype, source, target, recursive = dlg.getData() |
1392 filetype, source, target, recursive = dlg.getData() |
1392 if target == '': |
1393 if target == '': |
1393 E5MessageBox.critical(self.ui, |
1394 E5MessageBox.critical(self.ui, |
1394 self.trUtf8("Add directory"), |
1395 self.trUtf8("Add directory"), |
1506 |
1507 |
1507 fn = self.getRelativePath(newfn) |
1508 fn = self.getRelativePath(newfn) |
1508 self.pdata["MAINSCRIPT"] = [fn] |
1509 self.pdata["MAINSCRIPT"] = [fn] |
1509 self.setDirty(True) |
1510 self.setDirty(True) |
1510 |
1511 |
1511 def renameFile(self, oldfn, newfn = None): |
1512 def renameFile(self, oldfn, newfn=None): |
1512 """ |
1513 """ |
1513 Public slot to rename a file of the project. |
1514 Public slot to rename a file of the project. |
1514 |
1515 |
1515 @param oldfn old filename of the file (string) |
1516 @param oldfn old filename of the file (string) |
1516 @param newfn new filename of the file (string) |
1517 @param newfn new filename of the file (string) |
1534 res = E5MessageBox.yesNo(self.ui, |
1535 res = E5MessageBox.yesNo(self.ui, |
1535 self.trUtf8("Rename File"), |
1536 self.trUtf8("Rename File"), |
1536 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" |
1537 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" |
1537 """ Overwrite it?</p>""") |
1538 """ Overwrite it?</p>""") |
1538 .format(newfn), |
1539 .format(newfn), |
1539 icon = E5MessageBox.Warning) |
1540 icon=E5MessageBox.Warning) |
1540 if not res: |
1541 if not res: |
1541 return False |
1542 return False |
1542 |
1543 |
1543 try: |
1544 try: |
1544 os.rename(oldfn, newfn) |
1545 os.rename(oldfn, newfn) |
1557 fn in self.pdata["OTHERS"]: |
1558 fn in self.pdata["OTHERS"]: |
1558 self.renameFileInPdata(oldfn, newfn, isSourceFile) |
1559 self.renameFileInPdata(oldfn, newfn, isSourceFile) |
1559 |
1560 |
1560 return True |
1561 return True |
1561 |
1562 |
1562 def renameFileInPdata(self, oldname, newname, isSourceFile = False): |
1563 def renameFileInPdata(self, oldname, newname, isSourceFile=False): |
1563 """ |
1564 """ |
1564 Public method to rename a file in the pdata structure. |
1565 Public method to rename a file in the pdata structure. |
1565 |
1566 |
1566 @param oldname old filename (string) |
1567 @param oldname old filename (string) |
1567 @param newname new filename (string) |
1568 @param newname new filename (string) |
1639 del typeStrings[0] |
1640 del typeStrings[0] |
1640 self.__model.removeItem(olddn) |
1641 self.__model.removeItem(olddn) |
1641 self.__model.addNewItem(typeString, newdn, typeStrings) |
1642 self.__model.addNewItem(typeString, newdn, typeStrings) |
1642 self.directoryRemoved.emit(olddn) |
1643 self.directoryRemoved.emit(olddn) |
1643 |
1644 |
1644 def removeFile(self, fn, updateModel = True): |
1645 def removeFile(self, fn, updateModel=True): |
1645 """ |
1646 """ |
1646 Public slot to remove a file from the project. |
1647 Public slot to remove a file from the project. |
1647 |
1648 |
1648 The file is not deleted from the project directory. |
1649 The file is not deleted from the project directory. |
1649 |
1650 |
1808 |
1809 |
1809 self.projectAboutToBeCreated.emit() |
1810 self.projectAboutToBeCreated.emit() |
1810 |
1811 |
1811 hash = str(QCryptographicHash.hash( |
1812 hash = str(QCryptographicHash.hash( |
1812 QByteArray(self.ppath), QCryptographicHash.Sha1).toHex(), |
1813 QByteArray(self.ppath), QCryptographicHash.Sha1).toHex(), |
1813 encoding = "utf-8") |
1814 encoding="utf-8") |
1814 self.pdata["HASH"] = [hash] |
1815 self.pdata["HASH"] = [hash] |
1815 |
1816 |
1816 # create the project directory if it doesn't exist already |
1817 # create the project directory if it doesn't exist already |
1817 if not os.path.isdir(self.ppath): |
1818 if not os.path.isdir(self.ppath): |
1818 try: |
1819 try: |
1827 return |
1828 return |
1828 # create an empty __init__.py file to make it a Python package |
1829 # create an empty __init__.py file to make it a Python package |
1829 # (only for Python and Python3) |
1830 # (only for Python and Python3) |
1830 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
1831 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
1831 fn = os.path.join(self.ppath, "__init__.py") |
1832 fn = os.path.join(self.ppath, "__init__.py") |
1832 f = open(fn, "w", encoding = "utf-8") |
1833 f = open(fn, "w", encoding="utf-8") |
1833 f.close() |
1834 f.close() |
1834 self.appendFile(fn, True) |
1835 self.appendFile(fn, True) |
1835 # create an empty main script file, if a name was given |
1836 # create an empty main script file, if a name was given |
1836 if len(self.pdata["MAINSCRIPT"]) and self.pdata["MAINSCRIPT"][0]: |
1837 if len(self.pdata["MAINSCRIPT"]) and self.pdata["MAINSCRIPT"][0]: |
1837 if not os.path.isabs(self.pdata["MAINSCRIPT"][0]): |
1838 if not os.path.isabs(self.pdata["MAINSCRIPT"][0]): |
1874 |
1875 |
1875 # add existing files to the project |
1876 # add existing files to the project |
1876 res = E5MessageBox.yesNo(self.ui, |
1877 res = E5MessageBox.yesNo(self.ui, |
1877 self.trUtf8("New Project"), |
1878 self.trUtf8("New Project"), |
1878 self.trUtf8("""Add existing files to the project?"""), |
1879 self.trUtf8("""Add existing files to the project?"""), |
1879 yesDefault = True) |
1880 yesDefault=True) |
1880 if res: |
1881 if res: |
1881 self.newProjectAddFiles(ms) |
1882 self.newProjectAddFiles(ms) |
1882 # create an empty __init__.py file to make it a Python package |
1883 # create an empty __init__.py file to make it a Python package |
1883 # if none exists (only for Python and Python3) |
1884 # if none exists (only for Python and Python3) |
1884 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
1885 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
1885 fn = os.path.join(self.ppath, "__init__.py") |
1886 fn = os.path.join(self.ppath, "__init__.py") |
1886 if not os.path.exists(fn): |
1887 if not os.path.exists(fn): |
1887 f = open(fn, "w", encoding = "utf-8") |
1888 f = open(fn, "w", encoding="utf-8") |
1888 f.close() |
1889 f.close() |
1889 self.appendFile(fn, True) |
1890 self.appendFile(fn, True) |
1890 self.saveProject() |
1891 self.saveProject() |
1891 |
1892 |
1892 # check, if the existing project directory is already under |
1893 # check, if the existing project directory is already under |
1933 if res == 0: |
1934 if res == 0: |
1934 apres = E5MessageBox.yesNo(self.ui, |
1935 apres = E5MessageBox.yesNo(self.ui, |
1935 self.trUtf8("New project"), |
1936 self.trUtf8("New project"), |
1936 self.trUtf8("Shall the project file be added" |
1937 self.trUtf8("Shall the project file be added" |
1937 " to the repository?"), |
1938 " to the repository?"), |
1938 yesDefault = True) |
1939 yesDefault=True) |
1939 if apres: |
1940 if apres: |
1940 self.saveProject() |
1941 self.saveProject() |
1941 self.vcs.vcsAdd(self.pfile) |
1942 self.vcs.vcsAdd(self.pfile) |
1942 else: |
1943 else: |
1943 self.pdata["VCS"] = ['None'] |
1944 self.pdata["VCS"] = ['None'] |
2040 if '_' in os.path.basename(tslist[0]): |
2041 if '_' in os.path.basename(tslist[0]): |
2041 # the first entry determines the mainscript name |
2042 # the first entry determines the mainscript name |
2042 mainscriptname = os.path.splitext(mainscript)[0] or \ |
2043 mainscriptname = os.path.splitext(mainscript)[0] or \ |
2043 os.path.basename(tslist[0]).split('_')[0] |
2044 os.path.basename(tslist[0]).split('_')[0] |
2044 self.pdata["TRANSLATIONPATTERN"] = \ |
2045 self.pdata["TRANSLATIONPATTERN"] = \ |
2045 [os.path.join(os.path.dirname(tslist[0]), |
2046 [os.path.join(os.path.dirname(tslist[0]), |
2046 "{0}_%language%{1}".format(os.path.basename(tslist[0]).split('_')[0], |
2047 "{0}_%language%{1}".format(os.path.basename(tslist[0]).split('_')[0], |
2047 os.path.splitext(tslist[0])[1]))] |
2048 os.path.splitext(tslist[0])[1]))] |
2048 else: |
2049 else: |
2049 pattern, ok = QInputDialog.getText( |
2050 pattern, ok = QInputDialog.getText( |
2050 None, |
2051 None, |
2051 self.trUtf8("Translation Pattern"), |
2052 self.trUtf8("Translation Pattern"), |
2052 self.trUtf8("Enter the path pattern for translation files " |
2053 self.trUtf8("Enter the path pattern for translation files " |
2053 "(use '%language%' in place of the language code):"), |
2054 "(use '%language%' in place of the language code):"), |
2054 QLineEdit.Normal, |
2055 QLineEdit.Normal, |
2055 tslist[0]) |
2056 tslist[0]) |
2056 if not pattern.isEmpty: |
2057 if not pattern.isEmpty: |
2057 self.pdata["TRANSLATIONPATTERN"] = [pattern] |
2058 self.pdata["TRANSLATIONPATTERN"] = [pattern] |
2058 self.pdata["TRANSLATIONPATTERN"][0] = \ |
2059 self.pdata["TRANSLATIONPATTERN"][0] = \ |
2059 self.getRelativePath(self.pdata["TRANSLATIONPATTERN"][0]) |
2060 self.getRelativePath(self.pdata["TRANSLATIONPATTERN"][0]) |
2067 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
2068 if self.pdata["PROGLANGUAGE"][0] in ["Python", "Python2", "Python3"]: |
2068 self.pdata["MAINSCRIPT"] = ['{0}.py'.format(mainscriptname)] |
2069 self.pdata["MAINSCRIPT"] = ['{0}.py'.format(mainscriptname)] |
2069 elif self.pdata["PROGLANGUAGE"][0] == "Ruby": |
2070 elif self.pdata["PROGLANGUAGE"][0] == "Ruby": |
2070 self.pdata["MAINSCRIPT"] = ['{0}.rb'.format(mainscriptname)] |
2071 self.pdata["MAINSCRIPT"] = ['{0}.rb'.format(mainscriptname)] |
2071 if self.pdata["TRANSLATIONSBINPATH"]: |
2072 if self.pdata["TRANSLATIONSBINPATH"]: |
2072 tpd = os.path.join(self.ppath, |
2073 tpd = os.path.join(self.ppath, |
2073 self.pdata["TRANSLATIONSBINPATH"][0]) |
2074 self.pdata["TRANSLATIONSBINPATH"][0]) |
2074 pattern = os.path.splitext( |
2075 pattern = os.path.splitext( |
2075 os.path.basename(self.pdata["TRANSLATIONPATTERN"][0])) |
2076 os.path.basename(self.pdata["TRANSLATIONPATTERN"][0])) |
2076 pattern = self.__binaryTranslationFile(pattern) |
2077 pattern = self.__binaryTranslationFile(pattern) |
2077 qmlist = Utilities.direntries(tpd, True, pattern) |
2078 qmlist = Utilities.direntries(tpd, True, pattern) |
2206 pass |
2207 pass |
2207 |
2208 |
2208 # return empty string to signal to use the global setting |
2209 # return empty string to signal to use the global setting |
2209 return "" |
2210 return "" |
2210 |
2211 |
2211 def openProject(self, fn = None, restoreSession = True, reopen = False): |
2212 def openProject(self, fn=None, restoreSession=True, reopen=False): |
2212 """ |
2213 """ |
2213 Public slot to open a project. |
2214 Public slot to open a project. |
2214 |
2215 |
2215 @param fn optional filename of the project file to be read |
2216 @param fn optional filename of the project file to be read |
2216 @param restoreSession flag indicating to restore the project |
2217 @param restoreSession flag indicating to restore the project |
2329 self.sourceFile.emit( |
2330 self.sourceFile.emit( |
2330 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
2331 os.path.join(self.ppath, self.pdata["MAINSCRIPT"][0])) |
2331 |
2332 |
2332 # open a project session file being quiet about errors |
2333 # open a project session file being quiet about errors |
2333 if reopen: |
2334 if reopen: |
2334 self.__readSession(quiet = True, indicator = "_tmp") |
2335 self.__readSession(quiet=True, indicator="_tmp") |
2335 elif Preferences.getProject("AutoLoadSession"): |
2336 elif Preferences.getProject("AutoLoadSession"): |
2336 self.__readSession(quiet = True) |
2337 self.__readSession(quiet=True) |
2337 |
2338 |
2338 # open a project debugger properties file being quiet about errors |
2339 # open a project debugger properties file being quiet about errors |
2339 if Preferences.getProject("AutoLoadDbgProperties"): |
2340 if Preferences.getProject("AutoLoadDbgProperties"): |
2340 self.__readDebugProperties(True) |
2341 self.__readDebugProperties(True) |
2341 |
2342 |
2352 def reopenProject(self): |
2353 def reopenProject(self): |
2353 """ |
2354 """ |
2354 Public slot to reopen the current project. |
2355 Public slot to reopen the current project. |
2355 """ |
2356 """ |
2356 projectFile = self.pfile |
2357 projectFile = self.pfile |
2357 res = self.closeProject(reopen = True) |
2358 res = self.closeProject(reopen=True) |
2358 if res: |
2359 if res: |
2359 self.openProject(projectFile, reopen = True) |
2360 self.openProject(projectFile, reopen=True) |
2360 |
2361 |
2361 def saveProject(self): |
2362 def saveProject(self): |
2362 """ |
2363 """ |
2363 Public slot to save the current project. |
2364 Public slot to save the current project. |
2364 |
2365 |
2399 if QFileInfo(fn).exists(): |
2400 if QFileInfo(fn).exists(): |
2400 res = E5MessageBox.yesNo(self.ui, |
2401 res = E5MessageBox.yesNo(self.ui, |
2401 self.trUtf8("Save File"), |
2402 self.trUtf8("Save File"), |
2402 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" |
2403 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" |
2403 """ Overwrite it?</p>""").format(fn), |
2404 """ Overwrite it?</p>""").format(fn), |
2404 icon = E5MessageBox.Warning) |
2405 icon=E5MessageBox.Warning) |
2405 if not res: |
2406 if not res: |
2406 return False |
2407 return False |
2407 |
2408 |
2408 self.name = QFileInfo(fn).baseName() |
2409 self.name = QFileInfo(fn).baseName() |
2409 ok = self.__writeProject(fn) |
2410 ok = self.__writeProject(fn) |
2432 Public method to check dirty status and open a message window. |
2433 Public method to check dirty status and open a message window. |
2433 |
2434 |
2434 @return flag indicating whether this operation was successful (boolean) |
2435 @return flag indicating whether this operation was successful (boolean) |
2435 """ |
2436 """ |
2436 if self.isDirty(): |
2437 if self.isDirty(): |
2437 res = E5MessageBox.okToClearData(self.parent(), |
2438 res = E5MessageBox.okToClearData(self.parent(), |
2438 self.trUtf8("Close Project"), |
2439 self.trUtf8("Close Project"), |
2439 self.trUtf8("The current project has unsaved changes."), |
2440 self.trUtf8("The current project has unsaved changes."), |
2440 self.saveProject) |
2441 self.saveProject) |
2441 if res: |
2442 if res: |
2442 self.setDirty(False) |
2443 self.setDirty(False) |
2451 self.codemetrics and self.codemetrics.close() |
2452 self.codemetrics and self.codemetrics.close() |
2452 self.codecoverage and self.codecoverage.close() |
2453 self.codecoverage and self.codecoverage.close() |
2453 self.profiledata and self.profiledata.close() |
2454 self.profiledata and self.profiledata.close() |
2454 self.applicationDiagram and self.applicationDiagram.close() |
2455 self.applicationDiagram and self.applicationDiagram.close() |
2455 |
2456 |
2456 def closeProject(self, reopen = False, noSave = False): |
2457 def closeProject(self, reopen=False, noSave=False): |
2457 """ |
2458 """ |
2458 Public slot to close the current project. |
2459 Public slot to close the current project. |
2459 |
2460 |
2460 @keyparam reopen flag indicating a reopening of the project (boolean) |
2461 @keyparam reopen flag indicating a reopening of the project (boolean) |
2461 @keyparam noSave flag indicating to not perform save actions (boolean) |
2462 @keyparam noSave flag indicating to not perform save actions (boolean) |
2474 if not noSave: |
2475 if not noSave: |
2475 self.__writeUserProperties() |
2476 self.__writeUserProperties() |
2476 |
2477 |
2477 # save the project session file being quiet about error |
2478 # save the project session file being quiet about error |
2478 if reopen: |
2479 if reopen: |
2479 self.__writeSession(quiet = True, indicator = "_tmp") |
2480 self.__writeSession(quiet=True, indicator="_tmp") |
2480 elif Preferences.getProject("AutoSaveSession") and not noSave: |
2481 elif Preferences.getProject("AutoSaveSession") and not noSave: |
2481 self.__writeSession(quiet = True) |
2482 self.__writeSession(quiet=True) |
2482 |
2483 |
2483 # save the project debugger properties file being quiet about error |
2484 # save the project debugger properties file being quiet about error |
2484 if Preferences.getProject("AutoSaveDbgProperties") and \ |
2485 if Preferences.getProject("AutoSaveDbgProperties") and \ |
2485 self.isDebugPropertiesLoaded() and \ |
2486 self.isDebugPropertiesLoaded() and \ |
2486 not noSave: |
2487 not noSave: |
2549 self.projectClosedHooks.emit() |
2550 self.projectClosedHooks.emit() |
2550 self.projectClosed.emit() |
2551 self.projectClosed.emit() |
2551 |
2552 |
2552 return True |
2553 return True |
2553 |
2554 |
2554 def saveAllScripts(self, reportSyntaxErrors = False): |
2555 def saveAllScripts(self, reportSyntaxErrors=False): |
2555 """ |
2556 """ |
2556 Public method to save all scripts belonging to the project. |
2557 Public method to save all scripts belonging to the project. |
2557 |
2558 |
2558 @keyparam reportSyntaxErrors flag indicating special reporting |
2559 @keyparam reportSyntaxErrors flag indicating special reporting |
2559 for syntax errors (boolean) |
2560 for syntax errors (boolean) |
2593 else: |
2594 else: |
2594 return self.pdata["MAINSCRIPT"] |
2595 return self.pdata["MAINSCRIPT"] |
2595 else: |
2596 else: |
2596 return None |
2597 return None |
2597 |
2598 |
2598 def getSources(self, normalized = False): |
2599 def getSources(self, normalized=False): |
2599 """ |
2600 """ |
2600 Public method to return the source script files. |
2601 Public method to return the source script files. |
2601 |
2602 |
2602 @param normalized flag indicating a normalized filename is wanted (boolean) |
2603 @param normalized flag indicating a normalized filename is wanted (boolean) |
2603 @return list of the projects scripts (list of string) |
2604 @return list of the projects scripts (list of string) |
2736 """ |
2737 """ |
2737 return Utilities.fromNativeSeparators(self.getRelativePath(path)) |
2738 return Utilities.fromNativeSeparators(self.getRelativePath(path)) |
2738 |
2739 |
2739 def getAbsoluteUniversalPath(self, fn): |
2740 def getAbsoluteUniversalPath(self, fn): |
2740 """ |
2741 """ |
2741 Public method to convert a project relative file path with universal |
2742 Public method to convert a project relative file path with universal |
2742 separators to an absolute file path. |
2743 separators to an absolute file path. |
2743 |
2744 |
2744 @param fn file or directory name to convert (string) |
2745 @param fn file or directory name to convert (string) |
2745 @return absolute path (string) |
2746 @return absolute path (string) |
2746 """ |
2747 """ |
2843 self.actGrp1 = createActionGroup(self) |
2844 self.actGrp1 = createActionGroup(self) |
2844 |
2845 |
2845 act = E5Action(self.trUtf8('New project'), |
2846 act = E5Action(self.trUtf8('New project'), |
2846 UI.PixmapCache.getIcon("projectNew.png"), |
2847 UI.PixmapCache.getIcon("projectNew.png"), |
2847 self.trUtf8('&New...'), 0, 0, |
2848 self.trUtf8('&New...'), 0, 0, |
2848 self.actGrp1,'project_new') |
2849 self.actGrp1, 'project_new') |
2849 act.setStatusTip(self.trUtf8('Generate a new project')) |
2850 act.setStatusTip(self.trUtf8('Generate a new project')) |
2850 act.setWhatsThis(self.trUtf8( |
2851 act.setWhatsThis(self.trUtf8( |
2851 """<b>New...</b>""" |
2852 """<b>New...</b>""" |
2852 """<p>This opens a dialog for entering the info for a""" |
2853 """<p>This opens a dialog for entering the info for a""" |
2853 """ new project.</p>""" |
2854 """ new project.</p>""" |
2856 self.actions.append(act) |
2857 self.actions.append(act) |
2857 |
2858 |
2858 act = E5Action(self.trUtf8('Open project'), |
2859 act = E5Action(self.trUtf8('Open project'), |
2859 UI.PixmapCache.getIcon("projectOpen.png"), |
2860 UI.PixmapCache.getIcon("projectOpen.png"), |
2860 self.trUtf8('&Open...'), 0, 0, |
2861 self.trUtf8('&Open...'), 0, 0, |
2861 self.actGrp1,'project_open') |
2862 self.actGrp1, 'project_open') |
2862 act.setStatusTip(self.trUtf8('Open an existing project')) |
2863 act.setStatusTip(self.trUtf8('Open an existing project')) |
2863 act.setWhatsThis(self.trUtf8( |
2864 act.setWhatsThis(self.trUtf8( |
2864 """<b>Open...</b>""" |
2865 """<b>Open...</b>""" |
2865 """<p>This opens an existing project.</p>""" |
2866 """<p>This opens an existing project.</p>""" |
2866 )) |
2867 )) |
2903 self.actGrp2 = createActionGroup(self) |
2904 self.actGrp2 = createActionGroup(self) |
2904 |
2905 |
2905 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), |
2906 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), |
2906 UI.PixmapCache.getIcon("fileMisc.png"), |
2907 UI.PixmapCache.getIcon("fileMisc.png"), |
2907 self.trUtf8('Add &files...'), 0, 0, |
2908 self.trUtf8('Add &files...'), 0, 0, |
2908 self.actGrp2,'project_add_file') |
2909 self.actGrp2, 'project_add_file') |
2909 self.addFilesAct.setStatusTip(self.trUtf8('Add files to the current project')) |
2910 self.addFilesAct.setStatusTip(self.trUtf8('Add files to the current project')) |
2910 self.addFilesAct.setWhatsThis(self.trUtf8( |
2911 self.addFilesAct.setWhatsThis(self.trUtf8( |
2911 """<b>Add files...</b>""" |
2912 """<b>Add files...</b>""" |
2912 """<p>This opens a dialog for adding files""" |
2913 """<p>This opens a dialog for adding files""" |
2913 """ to the current project. The place to add is""" |
2914 """ to the current project. The place to add is""" |
2917 self.actions.append(self.addFilesAct) |
2918 self.actions.append(self.addFilesAct) |
2918 |
2919 |
2919 self.addDirectoryAct = E5Action(self.trUtf8('Add directory to project'), |
2920 self.addDirectoryAct = E5Action(self.trUtf8('Add directory to project'), |
2920 UI.PixmapCache.getIcon("dirOpen.png"), |
2921 UI.PixmapCache.getIcon("dirOpen.png"), |
2921 self.trUtf8('Add directory...'), 0, 0, |
2922 self.trUtf8('Add directory...'), 0, 0, |
2922 self.actGrp2,'project_add_directory') |
2923 self.actGrp2, 'project_add_directory') |
2923 self.addDirectoryAct.setStatusTip( |
2924 self.addDirectoryAct.setStatusTip( |
2924 self.trUtf8('Add a directory to the current project')) |
2925 self.trUtf8('Add a directory to the current project')) |
2925 self.addDirectoryAct.setWhatsThis(self.trUtf8( |
2926 self.addDirectoryAct.setWhatsThis(self.trUtf8( |
2926 """<b>Add directory...</b>""" |
2927 """<b>Add directory...</b>""" |
2927 """<p>This opens a dialog for adding a directory""" |
2928 """<p>This opens a dialog for adding a directory""" |
2931 self.actions.append(self.addDirectoryAct) |
2932 self.actions.append(self.addDirectoryAct) |
2932 |
2933 |
2933 self.addLanguageAct = E5Action(self.trUtf8('Add translation to project'), |
2934 self.addLanguageAct = E5Action(self.trUtf8('Add translation to project'), |
2934 UI.PixmapCache.getIcon("linguist4.png"), |
2935 UI.PixmapCache.getIcon("linguist4.png"), |
2935 self.trUtf8('Add &translation...'), 0, 0, |
2936 self.trUtf8('Add &translation...'), 0, 0, |
2936 self.actGrp2,'project_add_translation') |
2937 self.actGrp2, 'project_add_translation') |
2937 self.addLanguageAct.setStatusTip( |
2938 self.addLanguageAct.setStatusTip( |
2938 self.trUtf8('Add a translation to the current project')) |
2939 self.trUtf8('Add a translation to the current project')) |
2939 self.addLanguageAct.setWhatsThis(self.trUtf8( |
2940 self.addLanguageAct.setWhatsThis(self.trUtf8( |
2940 """<b>Add translation...</b>""" |
2941 """<b>Add translation...</b>""" |
2941 """<p>This opens a dialog for add a translation""" |
2942 """<p>This opens a dialog for add a translation""" |
2944 self.addLanguageAct.triggered[()].connect(self.addLanguage) |
2945 self.addLanguageAct.triggered[()].connect(self.addLanguage) |
2945 self.actions.append(self.addLanguageAct) |
2946 self.actions.append(self.addLanguageAct) |
2946 |
2947 |
2947 act = E5Action(self.trUtf8('Search new files'), |
2948 act = E5Action(self.trUtf8('Search new files'), |
2948 self.trUtf8('Searc&h new files...'), 0, 0, |
2949 self.trUtf8('Searc&h new files...'), 0, 0, |
2949 self.actGrp2,'project_search_new_files') |
2950 self.actGrp2, 'project_search_new_files') |
2950 act.setStatusTip(self.trUtf8('Search new files in the project directory.')) |
2951 act.setStatusTip(self.trUtf8('Search new files in the project directory.')) |
2951 act.setWhatsThis(self.trUtf8( |
2952 act.setWhatsThis(self.trUtf8( |
2952 """<b>Search new files...</b>""" |
2953 """<b>Search new files...</b>""" |
2953 """<p>This searches for new files (sources, *.ui, *.idl) in the project""" |
2954 """<p>This searches for new files (sources, *.ui, *.idl) in the project""" |
2954 """ directory and registered subdirectories.</p>""" |
2955 """ directory and registered subdirectories.</p>""" |
3115 |
3116 |
3116 self.chkGrp = createActionGroup(self) |
3117 self.chkGrp = createActionGroup(self) |
3117 |
3118 |
3118 self.codeMetricsAct = E5Action(self.trUtf8('Code Metrics'), |
3119 self.codeMetricsAct = E5Action(self.trUtf8('Code Metrics'), |
3119 self.trUtf8('&Code Metrics...'), 0, 0, |
3120 self.trUtf8('&Code Metrics...'), 0, 0, |
3120 self.chkGrp,'project_code_metrics') |
3121 self.chkGrp, 'project_code_metrics') |
3121 self.codeMetricsAct.setStatusTip( |
3122 self.codeMetricsAct.setStatusTip( |
3122 self.trUtf8('Show some code metrics for the project.')) |
3123 self.trUtf8('Show some code metrics for the project.')) |
3123 self.codeMetricsAct.setWhatsThis(self.trUtf8( |
3124 self.codeMetricsAct.setWhatsThis(self.trUtf8( |
3124 """<b>Code Metrics...</b>""" |
3125 """<b>Code Metrics...</b>""" |
3125 """<p>This shows some code metrics for all Python files in the project.</p>""" |
3126 """<p>This shows some code metrics for all Python files in the project.</p>""" |
3127 self.codeMetricsAct.triggered[()].connect(self.__showCodeMetrics) |
3128 self.codeMetricsAct.triggered[()].connect(self.__showCodeMetrics) |
3128 self.actions.append(self.codeMetricsAct) |
3129 self.actions.append(self.codeMetricsAct) |
3129 |
3130 |
3130 self.codeCoverageAct = E5Action(self.trUtf8('Python Code Coverage'), |
3131 self.codeCoverageAct = E5Action(self.trUtf8('Python Code Coverage'), |
3131 self.trUtf8('Code Co&verage...'), 0, 0, |
3132 self.trUtf8('Code Co&verage...'), 0, 0, |
3132 self.chkGrp,'project_code_coverage') |
3133 self.chkGrp, 'project_code_coverage') |
3133 self.codeCoverageAct.setStatusTip( |
3134 self.codeCoverageAct.setStatusTip( |
3134 self.trUtf8('Show code coverage information for the project.')) |
3135 self.trUtf8('Show code coverage information for the project.')) |
3135 self.codeCoverageAct.setWhatsThis(self.trUtf8( |
3136 self.codeCoverageAct.setWhatsThis(self.trUtf8( |
3136 """<b>Code Coverage...</b>""" |
3137 """<b>Code Coverage...</b>""" |
3137 """<p>This shows the code coverage information for all Python files""" |
3138 """<p>This shows the code coverage information for all Python files""" |
3140 self.codeCoverageAct.triggered[()].connect(self.__showCodeCoverage) |
3141 self.codeCoverageAct.triggered[()].connect(self.__showCodeCoverage) |
3141 self.actions.append(self.codeCoverageAct) |
3142 self.actions.append(self.codeCoverageAct) |
3142 |
3143 |
3143 self.codeProfileAct = E5Action(self.trUtf8('Profile Data'), |
3144 self.codeProfileAct = E5Action(self.trUtf8('Profile Data'), |
3144 self.trUtf8('&Profile Data...'), 0, 0, |
3145 self.trUtf8('&Profile Data...'), 0, 0, |
3145 self.chkGrp,'project_profile_data') |
3146 self.chkGrp, 'project_profile_data') |
3146 self.codeProfileAct.setStatusTip( |
3147 self.codeProfileAct.setStatusTip( |
3147 self.trUtf8('Show profiling data for the project.')) |
3148 self.trUtf8('Show profiling data for the project.')) |
3148 self.codeProfileAct.setWhatsThis(self.trUtf8( |
3149 self.codeProfileAct.setWhatsThis(self.trUtf8( |
3149 """<b>Profile Data...</b>""" |
3150 """<b>Profile Data...</b>""" |
3150 """<p>This shows the profiling data for the project.</p>""" |
3151 """<p>This shows the profiling data for the project.</p>""" |
3152 self.codeProfileAct.triggered[()].connect(self.__showProfileData) |
3153 self.codeProfileAct.triggered[()].connect(self.__showProfileData) |
3153 self.actions.append(self.codeProfileAct) |
3154 self.actions.append(self.codeProfileAct) |
3154 |
3155 |
3155 self.applicationDiagramAct = E5Action(self.trUtf8('Application Diagram'), |
3156 self.applicationDiagramAct = E5Action(self.trUtf8('Application Diagram'), |
3156 self.trUtf8('&Application Diagram...'), 0, 0, |
3157 self.trUtf8('&Application Diagram...'), 0, 0, |
3157 self.chkGrp,'project_application_diagram') |
3158 self.chkGrp, 'project_application_diagram') |
3158 self.applicationDiagramAct.setStatusTip( |
3159 self.applicationDiagramAct.setStatusTip( |
3159 self.trUtf8('Show a diagram of the project.')) |
3160 self.trUtf8('Show a diagram of the project.')) |
3160 self.applicationDiagramAct.setWhatsThis(self.trUtf8( |
3161 self.applicationDiagramAct.setWhatsThis(self.trUtf8( |
3161 """<b>Application Diagram...</b>""" |
3162 """<b>Application Diagram...</b>""" |
3162 """<p>This shows a diagram of the project.</p>""" |
3163 """<p>This shows a diagram of the project.</p>""" |
3167 self.pluginGrp = createActionGroup(self) |
3168 self.pluginGrp = createActionGroup(self) |
3168 |
3169 |
3169 self.pluginPkgListAct = E5Action(self.trUtf8('Create Package List'), |
3170 self.pluginPkgListAct = E5Action(self.trUtf8('Create Package List'), |
3170 UI.PixmapCache.getIcon("pluginArchiveList.png"), |
3171 UI.PixmapCache.getIcon("pluginArchiveList.png"), |
3171 self.trUtf8('Create &Package List'), 0, 0, |
3172 self.trUtf8('Create &Package List'), 0, 0, |
3172 self.pluginGrp,'project_plugin_pkglist') |
3173 self.pluginGrp, 'project_plugin_pkglist') |
3173 self.pluginPkgListAct.setStatusTip( |
3174 self.pluginPkgListAct.setStatusTip( |
3174 self.trUtf8('Create an initial PKGLIST file for an eric5 plugin.')) |
3175 self.trUtf8('Create an initial PKGLIST file for an eric5 plugin.')) |
3175 self.pluginPkgListAct.setWhatsThis(self.trUtf8( |
3176 self.pluginPkgListAct.setWhatsThis(self.trUtf8( |
3176 """<b>Create Package List</b>""" |
3177 """<b>Create Package List</b>""" |
3177 """<p>This creates an initial list of files to include in an eric5 """ |
3178 """<p>This creates an initial list of files to include in an eric5 """ |
3181 self.actions.append(self.pluginPkgListAct) |
3182 self.actions.append(self.pluginPkgListAct) |
3182 |
3183 |
3183 self.pluginArchiveAct = E5Action(self.trUtf8('Create Plugin Archive'), |
3184 self.pluginArchiveAct = E5Action(self.trUtf8('Create Plugin Archive'), |
3184 UI.PixmapCache.getIcon("pluginArchive.png"), |
3185 UI.PixmapCache.getIcon("pluginArchive.png"), |
3185 self.trUtf8('Create Plugin &Archive'), 0, 0, |
3186 self.trUtf8('Create Plugin &Archive'), 0, 0, |
3186 self.pluginGrp,'project_plugin_archive') |
3187 self.pluginGrp, 'project_plugin_archive') |
3187 self.pluginArchiveAct.setStatusTip( |
3188 self.pluginArchiveAct.setStatusTip( |
3188 self.trUtf8('Create an eric5 plugin archive file.')) |
3189 self.trUtf8('Create an eric5 plugin archive file.')) |
3189 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3190 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3190 """<b>Create Plugin Archive</b>""" |
3191 """<b>Create Plugin Archive</b>""" |
3191 """<p>This creates an eric5 plugin archive file using the list of files """ |
3192 """<p>This creates an eric5 plugin archive file using the list of files """ |
3196 self.actions.append(self.pluginArchiveAct) |
3197 self.actions.append(self.pluginArchiveAct) |
3197 |
3198 |
3198 self.pluginSArchiveAct = E5Action(self.trUtf8('Create Plugin Archive (Snapshot)'), |
3199 self.pluginSArchiveAct = E5Action(self.trUtf8('Create Plugin Archive (Snapshot)'), |
3199 UI.PixmapCache.getIcon("pluginArchiveSnapshot.png"), |
3200 UI.PixmapCache.getIcon("pluginArchiveSnapshot.png"), |
3200 self.trUtf8('Create Plugin Archive (&Snapshot)'), 0, 0, |
3201 self.trUtf8('Create Plugin Archive (&Snapshot)'), 0, 0, |
3201 self.pluginGrp,'project_plugin_sarchive') |
3202 self.pluginGrp, 'project_plugin_sarchive') |
3202 self.pluginSArchiveAct.setStatusTip( |
3203 self.pluginSArchiveAct.setStatusTip( |
3203 self.trUtf8('Create an eric5 plugin archive file (snapshot release).')) |
3204 self.trUtf8('Create an eric5 plugin archive file (snapshot release).')) |
3204 self.pluginSArchiveAct.setWhatsThis(self.trUtf8( |
3205 self.pluginSArchiveAct.setWhatsThis(self.trUtf8( |
3205 """<b>Create Plugin Archive (Snapshot)</b>""" |
3206 """<b>Create Plugin Archive (Snapshot)</b>""" |
3206 """<p>This creates an eric5 plugin archive file using the list of files """ |
3207 """<p>This creates an eric5 plugin archive file using the list of files """ |
3244 self.debuggerMenu = QMenu(self.trUtf8('Debugger'), menu) |
3245 self.debuggerMenu = QMenu(self.trUtf8('Debugger'), menu) |
3245 self.packagersMenu = QMenu(self.trUtf8('Pac&kagers'), menu) |
3246 self.packagersMenu = QMenu(self.trUtf8('Pac&kagers'), menu) |
3246 self.packagersMenu.setTearOffEnabled(True) |
3247 self.packagersMenu.setTearOffEnabled(True) |
3247 |
3248 |
3248 self.__menus = { |
3249 self.__menus = { |
3249 "Main" : menu, |
3250 "Main": menu, |
3250 "Recent" : self.recentMenu, |
3251 "Recent": self.recentMenu, |
3251 "VCS" : self.vcsMenu, |
3252 "VCS": self.vcsMenu, |
3252 "Checks" : self.checksMenu, |
3253 "Checks": self.checksMenu, |
3253 "Show" : self.menuShow, |
3254 "Show": self.menuShow, |
3254 "Graphics" : self.graphicsMenu, |
3255 "Graphics": self.graphicsMenu, |
3255 "Session" : self.sessionMenu, |
3256 "Session": self.sessionMenu, |
3256 "Apidoc" : self.apidocMenu, |
3257 "Apidoc": self.apidocMenu, |
3257 "Debugger" : self.debuggerMenu, |
3258 "Debugger": self.debuggerMenu, |
3258 "Packagers" : self.packagersMenu, |
3259 "Packagers": self.packagersMenu, |
3259 } |
3260 } |
3260 |
3261 |
3261 # connect the aboutToShow signals |
3262 # connect the aboutToShow signals |
3262 self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) |
3263 self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) |
3263 self.recentMenu.triggered.connect(self.__openRecent) |
3264 self.recentMenu.triggered.connect(self.__openRecent) |
3396 if idx < 10: |
3397 if idx < 10: |
3397 formatStr = '&{0:d}. {1}' |
3398 formatStr = '&{0:d}. {1}' |
3398 else: |
3399 else: |
3399 formatStr = '{0:d}. {1}' |
3400 formatStr = '{0:d}. {1}' |
3400 act = self.recentMenu.addAction( |
3401 act = self.recentMenu.addAction( |
3401 formatStr.format(idx, |
3402 formatStr.format(idx, |
3402 Utilities.compactPath(rp, self.ui.maxMenuFilePathLen))) |
3403 Utilities.compactPath(rp, self.ui.maxMenuFilePathLen))) |
3403 act.setData(rp) |
3404 act.setData(rp) |
3404 act.setEnabled(QFileInfo(rp).exists()) |
3405 act.setEnabled(QFileInfo(rp).exists()) |
3405 idx += 1 |
3406 idx += 1 |
3406 |
3407 |
3427 """ |
3428 """ |
3428 Private slot used to handle the search new files action. |
3429 Private slot used to handle the search new files action. |
3429 """ |
3430 """ |
3430 self.__doSearchNewFiles(False, True) |
3431 self.__doSearchNewFiles(False, True) |
3431 |
3432 |
3432 def __doSearchNewFiles(self, AI = True, onUserDemand = False): |
3433 def __doSearchNewFiles(self, AI=True, onUserDemand=False): |
3433 """ |
3434 """ |
3434 Private method to search for new files in the project directory. |
3435 Private method to search for new files in the project directory. |
3435 |
3436 |
3436 If new files were found, it shows a dialog listing these files and |
3437 If new files were found, it shows a dialog listing these files and |
3437 gives the user the opportunity to select the ones he wants to |
3438 gives the user the opportunity to select the ones he wants to |
3438 include. If 'Automatic Inclusion' is enabled, the new files are |
3439 include. If 'Automatic Inclusion' is enabled, the new files are |
3439 automatically added to the project. |
3440 automatically added to the project. |
3440 |
3441 |
3441 @param AI flag indicating whether the automatic inclusion should |
3442 @param AI flag indicating whether the automatic inclusion should |
3442 be honoured (boolean) |
3443 be honoured (boolean) |
3443 @param onUserDemand flag indicating whether this method was |
3444 @param onUserDemand flag indicating whether this method was |
3444 requested by the user via a menu action (boolean) |
3445 requested by the user via a menu action (boolean) |
3445 """ |
3446 """ |
3446 autoInclude = Preferences.getProject("AutoIncludeNewFiles") |
3447 autoInclude = Preferences.getProject("AutoIncludeNewFiles") |
3447 recursiveSearch = Preferences.getProject("SearchNewFilesRecursively") |
3448 recursiveSearch = Preferences.getProject("SearchNewFilesRecursively") |
3448 newFiles = [] |
3449 newFiles = [] |
3533 elif res == 2: |
3534 elif res == 2: |
3534 files = dlg.getSelection() |
3535 files = dlg.getSelection() |
3535 for file in files: |
3536 for file in files: |
3536 self.appendFile(file) |
3537 self.appendFile(file) |
3537 |
3538 |
3538 def othersAdded(self, fn, updateModel = True): |
3539 def othersAdded(self, fn, updateModel=True): |
3539 """ |
3540 """ |
3540 Public slot to be called, if something was added to the OTHERS project data area. |
3541 Public slot to be called, if something was added to the OTHERS project data area. |
3541 |
3542 |
3542 @param fn filename or directory name added (string) |
3543 @param fn filename or directory name added (string) |
3543 @param updateModel flag indicating an update of the model is requested (boolean) |
3544 @param updateModel flag indicating an update of the model is requested (boolean) |
3601 |
3602 |
3602 ############################################################## |
3603 ############################################################## |
3603 ## Below is the VCS interface |
3604 ## Below is the VCS interface |
3604 ############################################################## |
3605 ############################################################## |
3605 |
3606 |
3606 def initVCS(self, vcsSystem = None, nooverride = False): |
3607 def initVCS(self, vcsSystem=None, nooverride=False): |
3607 """ |
3608 """ |
3608 Public method used to instantiate a vcs system. |
3609 Public method used to instantiate a vcs system. |
3609 |
3610 |
3610 @param vcsSystem type of VCS to be used (string) |
3611 @param vcsSystem type of VCS to be used (string) |
3611 @param nooverride flag indicating to ignore an override request (boolean) |
3612 @param nooverride flag indicating to ignore an override request (boolean) |
3648 self.trUtf8("Version Control System"), |
3649 self.trUtf8("Version Control System"), |
3649 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found." |
3650 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found." |
3650 "<br/>Reverting override.</p><p>{1}</p>")\ |
3651 "<br/>Reverting override.</p><p>{1}</p>")\ |
3651 .format(vcsSystem, msg)) |
3652 .format(vcsSystem, msg)) |
3652 self.pudata["VCSOVERRIDE"] = [] |
3653 self.pudata["VCSOVERRIDE"] = [] |
3653 return self.initVCS(nooverride = True) |
3654 return self.initVCS(nooverride=True) |
3654 |
3655 |
3655 QApplication.restoreOverrideCursor() |
3656 QApplication.restoreOverrideCursor() |
3656 E5MessageBox.critical(self.ui, |
3657 E5MessageBox.critical(self.ui, |
3657 self.trUtf8("Version Control System"), |
3658 self.trUtf8("Version Control System"), |
3658 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found.<br/>" |
3659 self.trUtf8("<p>The selected VCS <b>{0}</b> could not be found.<br/>" |
3866 Private method to handle the application diagram context menu action. |
3867 Private method to handle the application diagram context menu action. |
3867 """ |
3868 """ |
3868 res = E5MessageBox.yesNo(self.ui, |
3869 res = E5MessageBox.yesNo(self.ui, |
3869 self.trUtf8("Application Diagram"), |
3870 self.trUtf8("Application Diagram"), |
3870 self.trUtf8("""Include module names?"""), |
3871 self.trUtf8("""Include module names?"""), |
3871 yesDefault = True) |
3872 yesDefault=True) |
3872 |
3873 |
3873 self.applicationDiagram = ApplicationDiagram(self, self.parent(), |
3874 self.applicationDiagram = ApplicationDiagram(self, self.parent(), |
3874 noModules = not res) |
3875 noModules=not res) |
3875 self.applicationDiagram.show() |
3876 self.applicationDiagram.show() |
3876 |
3877 |
3877 ######################################################################### |
3878 ######################################################################### |
3878 ## Below is the interface to the VCS monitor thread |
3879 ## Below is the interface to the VCS monitor thread |
3879 ######################################################################### |
3880 ######################################################################### |
3971 if os.path.exists(pkglist): |
3972 if os.path.exists(pkglist): |
3972 res = E5MessageBox.yesNo(self.ui, |
3973 res = E5MessageBox.yesNo(self.ui, |
3973 self.trUtf8("Create Package List"), |
3974 self.trUtf8("Create Package List"), |
3974 self.trUtf8("<p>The file <b>PKGLIST</b> already" |
3975 self.trUtf8("<p>The file <b>PKGLIST</b> already" |
3975 " exists.</p><p>Overwrite it?</p>"), |
3976 " exists.</p><p>Overwrite it?</p>"), |
3976 icon = E5MessageBox.Warning) |
3977 icon=E5MessageBox.Warning) |
3977 if not res: |
3978 if not res: |
3978 return # don't overwrite |
3979 return # don't overwrite |
3979 |
3980 |
3980 # build the list of entries |
3981 # build the list of entries |
3981 lst = [] |
3982 lst = [] |
3990 try: |
3991 try: |
3991 if self.pdata["EOL"][0] == 0: |
3992 if self.pdata["EOL"][0] == 0: |
3992 newline = None |
3993 newline = None |
3993 else: |
3994 else: |
3994 newline = self.getEolString() |
3995 newline = self.getEolString() |
3995 pkglistFile = open(pkglist, "w", encoding = "utf-8", newline = newline) |
3996 pkglistFile = open(pkglist, "w", encoding="utf-8", newline=newline) |
3996 pkglistFile.write("\n".join(lst)) |
3997 pkglistFile.write("\n".join(lst)) |
3997 pkglistFile.close() |
3998 pkglistFile.close() |
3998 except IOError as why: |
3999 except IOError as why: |
3999 E5MessageBox.critical(self.ui, |
4000 E5MessageBox.critical(self.ui, |
4000 self.trUtf8("Create Package List"), |
4001 self.trUtf8("Create Package List"), |
4026 self.trUtf8("""The project does not have a main script defined. """ |
4027 self.trUtf8("""The project does not have a main script defined. """ |
4027 """Aborting...""")) |
4028 """Aborting...""")) |
4028 return |
4029 return |
4029 |
4030 |
4030 try: |
4031 try: |
4031 pkglistFile = open(pkglist, "r", encoding = "utf-8") |
4032 pkglistFile = open(pkglist, "r", encoding="utf-8") |
4032 names = pkglistFile.read() |
4033 names = pkglistFile.read() |
4033 pkglistFile.close() |
4034 pkglistFile.close() |
4034 names = sorted(names.splitlines()) |
4035 names = sorted(names.splitlines()) |
4035 except IOError as why: |
4036 except IOError as why: |
4036 E5MessageBox.critical(self.ui, |
4037 E5MessageBox.critical(self.ui, |
4134 if sourcelines[lineno].startswith("version = "): |
4135 if sourcelines[lineno].startswith("version = "): |
4135 # found the line to modify |
4136 # found the line to modify |
4136 datestr = time.strftime("%Y%m%d") |
4137 datestr = time.strftime("%Y%m%d") |
4137 lineend = sourcelines[lineno].replace(sourcelines[lineno].rstrip(), "") |
4138 lineend = sourcelines[lineno].replace(sourcelines[lineno].rstrip(), "") |
4138 sversion = "{0}-snapshot-{1}".format( |
4139 sversion = "{0}-snapshot-{1}".format( |
4139 sourcelines[lineno].replace("version = ", "").strip()[1:-1], |
4140 sourcelines[lineno].replace("version = ", "").strip()[1:-1], |
4140 datestr) |
4141 datestr) |
4141 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4142 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4142 sourcelines[lineno].rstrip(), datestr, lineend) |
4143 sourcelines[lineno].rstrip(), datestr, lineend) |
4143 break |
4144 break |
4144 |
4145 |