Project/Project.py

changeset 945
8cd4d08fa9f6
parent 882
34b86be88bf0
child 1003
b81a77ac656a
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
61 61
62 from E5Gui.E5Action import E5Action, createActionGroup 62 from E5Gui.E5Action import E5Action, createActionGroup
63 63
64 import Preferences 64 import Preferences
65 import Utilities 65 import Utilities
66
66 67
67 class Project(QObject): 68 class Project(QObject):
68 """ 69 """
69 Class implementing the project management functionality. 70 Class implementing the project management functionality.
70 71
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 """
319 self.ppath = "" # name of the project directory 320 self.ppath = "" # name of the project directory
320 self.ppathRe = None 321 self.ppathRe = None
321 self.translationsRoot = "" # the translations prefix 322 self.translationsRoot = "" # the translations prefix
322 self.name = "" 323 self.name = ""
323 self.opened = False 324 self.opened = False
324 self.subdirs = [""] # record the project dir as a relative path (i.e. empty path) 325 self.subdirs = [""] # record the project dir as a relative path (i.e. empty path)
325 self.otherssubdirs = [] 326 self.otherssubdirs = []
326 self.vcs = None 327 self.vcs = None
327 self.dbgCmdline = '' 328 self.dbgCmdline = ''
328 self.dbgWd = '' 329 self.dbgWd = ''
329 self.dbgEnv = '' 330 self.dbgEnv = ''
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)
1062 """ 1063 """
1063 qmFile = "" 1064 qmFile = ""
1064 try: 1065 try:
1065 if self.__binaryTranslationsCallbacks[self.pdata["PROJECTTYPE"][0]] \ 1066 if self.__binaryTranslationsCallbacks[self.pdata["PROJECTTYPE"][0]] \
1066 is not None: 1067 is not None:
1067 qmFile = self.__binaryTranslationsCallbacks\ 1068 qmFile = self.__binaryTranslationsCallbacks[
1068 [self.pdata["PROJECTTYPE"][0]](langFile) 1069 self.pdata["PROJECTTYPE"][0]](langFile)
1069 except KeyError: 1070 except KeyError:
1070 qmFile = langFile.replace('.ts', '.qm') 1071 qmFile = langFile.replace('.ts', '.qm')
1071 if qmFile == langFile: 1072 if qmFile == langFile:
1072 qmFile = "" 1073 qmFile = ""
1073 return qmFile 1074 return qmFile
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)
2578 ) 2579 )
2579 return False 2580 return False
2580 else: 2581 else:
2581 return success 2582 return success
2582 2583
2583 def getMainScript(self, normalized = False): 2584 def getMainScript(self, normalized=False):
2584 """ 2585 """
2585 Public method to return the main script filename. 2586 Public method to return the main script filename.
2586 2587
2587 @param normalized flag indicating a normalized filename is wanted (boolean) 2588 @param normalized flag indicating a normalized filename is wanted (boolean)
2588 @return filename of the projects main script (string) 2589 @return filename of the projects main script (string)
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)
3634 vcs = VCS.factory(vcsSystem) 3635 vcs = VCS.factory(vcsSystem)
3635 except ImportError: 3636 except ImportError:
3636 if override: 3637 if override:
3637 # override failed, revert to original 3638 # override failed, revert to original
3638 self.pudata["VCSOVERRIDE"] = [] 3639 self.pudata["VCSOVERRIDE"] = []
3639 return self.initVCS(nooverride = True) 3640 return self.initVCS(nooverride=True)
3640 3641
3641 if vcs: 3642 if vcs:
3642 vcsExists, msg = vcs.vcsExists() 3643 vcsExists, msg = vcs.vcsExists()
3643 if not vcsExists: 3644 if not vcsExists:
3644 if override: 3645 if override:
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"),
4003 return 4004 return
4004 4005
4005 if not "PKGLIST" in self.pdata["OTHERS"]: 4006 if not "PKGLIST" in self.pdata["OTHERS"]:
4006 self.appendFile("PKGLIST") 4007 self.appendFile("PKGLIST")
4007 4008
4008 def __pluginCreateArchive(self, snapshot = False): 4009 def __pluginCreateArchive(self, snapshot=False):
4009 """ 4010 """
4010 Private slot to create an eric5 plugin archive. 4011 Private slot to create an eric5 plugin archive.
4011 4012
4012 @param snapshot flag indicating a snapshot archive (boolean) 4013 @param snapshot flag indicating a snapshot archive (boolean)
4013 """ 4014 """
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

eric ide

mercurial