3057:10516539f238 | 3058:0a02c433f52d |
---|---|
293 type_ in self.__projectProgLanguages[progLanguage] | 293 type_ in self.__projectProgLanguages[progLanguage] |
294 else: | 294 else: |
295 return type_ in self.__projectTypes | 295 return type_ in self.__projectTypes |
296 | 296 |
297 def registerProjectType(self, type_, description, fileTypeCallback=None, | 297 def registerProjectType(self, type_, description, fileTypeCallback=None, |
298 binaryTranslationsCallback=None, lexerAssociationCallback=None, | 298 binaryTranslationsCallback=None, |
299 progLanguages=None): | 299 lexerAssociationCallback=None, progLanguages=None): |
300 """ | 300 """ |
301 Public method to register a project type. | 301 Public method to register a project type. |
302 | 302 |
303 @param type_ internal type designator to be registered (string) | 303 @param type_ internal type designator to be registered (string) |
304 @param description more verbose type name (display string) (string) | 304 @param description more verbose type name (display string) (string) |
314 project type (list of string) | 314 project type (list of string) |
315 """ | 315 """ |
316 if progLanguages: | 316 if progLanguages: |
317 for progLanguage in progLanguages: | 317 for progLanguage in progLanguages: |
318 if progLanguage not in self.__projectProgLanguages: | 318 if progLanguage not in self.__projectProgLanguages: |
319 E5MessageBox.critical(self.ui, | 319 E5MessageBox.critical( |
320 self.ui, | |
320 self.trUtf8("Registering Project Type"), | 321 self.trUtf8("Registering Project Type"), |
321 self.trUtf8( | 322 self.trUtf8( |
322 """<p>The Programming Language <b>{0}</b> is not""" | 323 """<p>The Programming Language <b>{0}</b> is not""" |
323 """ supported.</p>""")\ | 324 """ supported.</p>""")\ |
324 .format(progLanguage) | 325 .format(progLanguage) |
325 ) | 326 ) |
326 return | 327 return |
327 | 328 |
328 if type_ in self.__projectProgLanguages[progLanguage]: | 329 if type_ in self.__projectProgLanguages[progLanguage]: |
329 E5MessageBox.critical(self.ui, | 330 E5MessageBox.critical( |
331 self.ui, | |
330 self.trUtf8("Registering Project Type"), | 332 self.trUtf8("Registering Project Type"), |
331 self.trUtf8( | 333 self.trUtf8( |
332 """<p>The Project type <b>{0}</b> is already""" | 334 """<p>The Project type <b>{0}</b> is already""" |
333 """ registered with Programming Language""" | 335 """ registered with Programming Language""" |
334 """ <b>{1}</b>.</p>""")\ | 336 """ <b>{1}</b>.</p>""")\ |
335 .format(type_, progLanguage) | 337 .format(type_, progLanguage) |
336 ) | 338 ) |
337 return | 339 return |
338 | 340 |
339 if type_ in self.__projectTypes: | 341 if type_ in self.__projectTypes: |
340 E5MessageBox.critical(self.ui, | 342 E5MessageBox.critical( |
343 self.ui, | |
341 self.trUtf8("Registering Project Type"), | 344 self.trUtf8("Registering Project Type"), |
342 self.trUtf8("""<p>The Project type <b>{0}</b> is already""" | 345 self.trUtf8("""<p>The Project type <b>{0}</b> is already""" |
343 """ registered.</p>""").format(type_) | 346 """ registered.</p>""").format(type_) |
344 ) | 347 ) |
345 else: | 348 else: |
668 reader.readXML() | 671 reader.readXML() |
669 res = not reader.hasError() | 672 res = not reader.hasError() |
670 f.close() | 673 f.close() |
671 else: | 674 else: |
672 QApplication.restoreOverrideCursor() | 675 QApplication.restoreOverrideCursor() |
673 E5MessageBox.critical(self.ui, | 676 E5MessageBox.critical( |
677 self.ui, | |
674 self.trUtf8("Read project file"), | 678 self.trUtf8("Read project file"), |
675 self.trUtf8( | 679 self.trUtf8( |
676 "<p>The project file <b>{0}</b> could not be read.</p>")\ | 680 "<p>The project file <b>{0}</b> could not be read.</p>")\ |
677 .format(fn)) | 681 .format(fn)) |
678 return False | 682 return False |
767 from E5XML.ProjectWriter import ProjectWriter | 771 from E5XML.ProjectWriter import ProjectWriter |
768 ProjectWriter(f, os.path.splitext( | 772 ProjectWriter(f, os.path.splitext( |
769 os.path.basename(fn))[0]).writeXML() | 773 os.path.basename(fn))[0]).writeXML() |
770 res = True | 774 res = True |
771 else: | 775 else: |
772 E5MessageBox.critical(self.ui, | 776 E5MessageBox.critical( |
777 self.ui, | |
773 self.trUtf8("Save project file"), | 778 self.trUtf8("Save project file"), |
774 self.trUtf8( | 779 self.trUtf8( |
775 "<p>The project file <b>{0}</b> could not be" | 780 "<p>The project file <b>{0}</b> could not be" |
776 " written.</p>").format(fn)) | 781 " written.</p>").format(fn)) |
777 res = False | 782 res = False |
802 from E5XML.UserProjectReader import UserProjectReader | 807 from E5XML.UserProjectReader import UserProjectReader |
803 reader = UserProjectReader(f, self) | 808 reader = UserProjectReader(f, self) |
804 reader.readXML() | 809 reader.readXML() |
805 f.close() | 810 f.close() |
806 else: | 811 else: |
807 E5MessageBox.critical(self.ui, | 812 E5MessageBox.critical( |
813 self.ui, | |
808 self.trUtf8("Read user project properties"), | 814 self.trUtf8("Read user project properties"), |
809 self.trUtf8( | 815 self.trUtf8( |
810 "<p>The user specific project properties file" | 816 "<p>The user specific project properties file" |
811 " <b>{0}</b> could not be read.</p>").format(fn)) | 817 " <b>{0}</b> could not be read.</p>").format(fn)) |
812 | 818 |
825 from E5XML.UserProjectWriter import UserProjectWriter | 831 from E5XML.UserProjectWriter import UserProjectWriter |
826 UserProjectWriter( | 832 UserProjectWriter( |
827 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() | 833 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
828 f.close() | 834 f.close() |
829 else: | 835 else: |
830 E5MessageBox.critical(self.ui, | 836 E5MessageBox.critical( |
837 self.ui, | |
831 self.trUtf8("Save user project properties"), | 838 self.trUtf8("Save user project properties"), |
832 self.trUtf8( | 839 self.trUtf8( |
833 "<p>The user specific project properties file <b>{0}</b>" | 840 "<p>The user specific project properties file <b>{0}</b>" |
834 " could not be written.</p>").format(fn)) | 841 " could not be written.</p>").format(fn)) |
835 | 842 |
858 If this flag is true, no errors are reported. | 865 If this flag is true, no errors are reported. |
859 @keyparam indicator indicator string (string) | 866 @keyparam indicator indicator string (string) |
860 """ | 867 """ |
861 if self.pfile is None: | 868 if self.pfile is None: |
862 if not quiet: | 869 if not quiet: |
863 E5MessageBox.critical(self.ui, | 870 E5MessageBox.critical( |
871 self.ui, | |
864 self.trUtf8("Read project session"), | 872 self.trUtf8("Read project session"), |
865 self.trUtf8("Please save the project first.")) | 873 self.trUtf8("Please save the project first.")) |
866 return | 874 return |
867 | 875 |
868 fn, ext = os.path.splitext(os.path.basename(self.pfile)) | 876 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
875 reader = SessionReader(f, False) | 883 reader = SessionReader(f, False) |
876 reader.readXML(quiet=quiet) | 884 reader.readXML(quiet=quiet) |
877 f.close() | 885 f.close() |
878 else: | 886 else: |
879 if not quiet: | 887 if not quiet: |
880 E5MessageBox.critical(self.ui, | 888 E5MessageBox.critical( |
889 self.ui, | |
881 self.trUtf8("Read project session"), | 890 self.trUtf8("Read project session"), |
882 self.trUtf8( | 891 self.trUtf8( |
883 "<p>The project session file <b>{0}</b> could not be" | 892 "<p>The project session file <b>{0}</b> could not be" |
884 " read.</p>").format(fn)) | 893 " read.</p>").format(fn)) |
885 | 894 |
891 If this flag is true, no errors are reported. | 900 If this flag is true, no errors are reported. |
892 @keyparam indicator indicator string (string) | 901 @keyparam indicator indicator string (string) |
893 """ | 902 """ |
894 if self.pfile is None: | 903 if self.pfile is None: |
895 if not quiet: | 904 if not quiet: |
896 E5MessageBox.critical(self.ui, | 905 E5MessageBox.critical( |
906 self.ui, | |
897 self.trUtf8("Save project session"), | 907 self.trUtf8("Save project session"), |
898 self.trUtf8("Please save the project first.")) | 908 self.trUtf8("Please save the project first.")) |
899 return | 909 return |
900 | 910 |
901 fn, ext = os.path.splitext(os.path.basename(self.pfile)) | 911 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
908 SessionWriter( | 918 SessionWriter( |
909 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() | 919 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
910 f.close() | 920 f.close() |
911 else: | 921 else: |
912 if not quiet: | 922 if not quiet: |
913 E5MessageBox.critical(self.ui, | 923 E5MessageBox.critical( |
924 self.ui, | |
914 self.trUtf8("Save project session"), | 925 self.trUtf8("Save project session"), |
915 self.trUtf8( | 926 self.trUtf8( |
916 "<p>The project session file <b>{0}</b> could not be" | 927 "<p>The project session file <b>{0}</b> could not be" |
917 " written.</p>").format(fn)) | 928 " written.</p>").format(fn)) |
918 | 929 |
919 def __deleteSession(self): | 930 def __deleteSession(self): |
920 """ | 931 """ |
921 Private method to delete the session file. | 932 Private method to delete the session file. |
922 """ | 933 """ |
923 if self.pfile is None: | 934 if self.pfile is None: |
924 E5MessageBox.critical(self.ui, | 935 E5MessageBox.critical( |
936 self.ui, | |
925 self.trUtf8("Delete project session"), | 937 self.trUtf8("Delete project session"), |
926 self.trUtf8("Please save the project first.")) | 938 self.trUtf8("Please save the project first.")) |
927 return | 939 return |
928 | 940 |
929 fname, ext = os.path.splitext(os.path.basename(self.pfile)) | 941 fname, ext = os.path.splitext(os.path.basename(self.pfile)) |
932 self.getProjectManagementDir(), "{0}.e4s".format(fname))]: | 944 self.getProjectManagementDir(), "{0}.e4s".format(fname))]: |
933 if os.path.exists(fn): | 945 if os.path.exists(fn): |
934 try: | 946 try: |
935 os.remove(fn) | 947 os.remove(fn) |
936 except OSError: | 948 except OSError: |
937 E5MessageBox.critical(self.ui, | 949 E5MessageBox.critical( |
950 self.ui, | |
938 self.trUtf8("Delete project session"), | 951 self.trUtf8("Delete project session"), |
939 self.trUtf8( | 952 self.trUtf8( |
940 "<p>The project session file <b>{0}</b> could" | 953 "<p>The project session file <b>{0}</b> could" |
941 " not be deleted.</p>").format(fn)) | 954 " not be deleted.</p>").format(fn)) |
942 | 955 |
943 def __readTasks(self): | 956 def __readTasks(self): |
944 """ | 957 """ |
945 Private method to read in the project tasks file (.e4t). | 958 Private method to read in the project tasks file (.e4t). |
946 """ | 959 """ |
947 if self.pfile is None: | 960 if self.pfile is None: |
948 E5MessageBox.critical(self.ui, | 961 E5MessageBox.critical( |
962 self.ui, | |
949 self.trUtf8("Read tasks"), | 963 self.trUtf8("Read tasks"), |
950 self.trUtf8("Please save the project first.")) | 964 self.trUtf8("Please save the project first.")) |
951 return | 965 return |
952 | 966 |
953 fn, ext = os.path.splitext(os.path.basename(self.pfile)) | 967 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
959 from E5XML.TasksReader import TasksReader | 973 from E5XML.TasksReader import TasksReader |
960 reader = TasksReader(f, True) | 974 reader = TasksReader(f, True) |
961 reader.readXML() | 975 reader.readXML() |
962 f.close() | 976 f.close() |
963 else: | 977 else: |
964 E5MessageBox.critical(self.ui, | 978 E5MessageBox.critical( |
979 self.ui, | |
965 self.trUtf8("Read tasks"), | 980 self.trUtf8("Read tasks"), |
966 self.trUtf8( | 981 self.trUtf8( |
967 "<p>The tasks file <b>{0}</b> could not be read.</p>")\ | 982 "<p>The tasks file <b>{0}</b> could not be read.</p>")\ |
968 .format(fn)) | 983 .format(fn)) |
969 | 984 |
978 | 993 |
979 fn = os.path.join(self.getProjectManagementDir(), '{0}.e4t'.format(fn)) | 994 fn = os.path.join(self.getProjectManagementDir(), '{0}.e4t'.format(fn)) |
980 f = QFile(fn) | 995 f = QFile(fn) |
981 ok = f.open(QIODevice.WriteOnly) | 996 ok = f.open(QIODevice.WriteOnly) |
982 if not ok: | 997 if not ok: |
983 E5MessageBox.critical(self.ui, | 998 E5MessageBox.critical( |
999 self.ui, | |
984 self.trUtf8("Save tasks"), | 1000 self.trUtf8("Save tasks"), |
985 self.trUtf8( | 1001 self.trUtf8( |
986 "<p>The tasks file <b>{0}</b> could not be written.</p>") | 1002 "<p>The tasks file <b>{0}</b> could not be written.</p>") |
987 .format(fn)) | 1003 .format(fn)) |
988 return | 1004 return |
1016 @param quiet flag indicating quiet operations. | 1032 @param quiet flag indicating quiet operations. |
1017 If this flag is true, no errors are reported. | 1033 If this flag is true, no errors are reported. |
1018 """ | 1034 """ |
1019 if self.pfile is None: | 1035 if self.pfile is None: |
1020 if not quiet: | 1036 if not quiet: |
1021 E5MessageBox.critical(self.ui, | 1037 E5MessageBox.critical( |
1038 self.ui, | |
1022 self.trUtf8("Read debugger properties"), | 1039 self.trUtf8("Read debugger properties"), |
1023 self.trUtf8("Please save the project first.")) | 1040 self.trUtf8("Please save the project first.")) |
1024 return | 1041 return |
1025 | 1042 |
1026 fn, ext = os.path.splitext(os.path.basename(self.pfile)) | 1043 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
1032 reader = DebuggerPropertiesReader(f, self) | 1049 reader = DebuggerPropertiesReader(f, self) |
1033 reader.readXML(quiet=quiet) | 1050 reader.readXML(quiet=quiet) |
1034 f.close() | 1051 f.close() |
1035 else: | 1052 else: |
1036 if not quiet: | 1053 if not quiet: |
1037 E5MessageBox.critical(self.ui, | 1054 E5MessageBox.critical( |
1055 self.ui, | |
1038 self.trUtf8("Read debugger properties"), | 1056 self.trUtf8("Read debugger properties"), |
1039 self.trUtf8( | 1057 self.trUtf8( |
1040 "<p>The project debugger properties file <b>{0}</b>" | 1058 "<p>The project debugger properties file <b>{0}</b>" |
1041 " could not be read.</p>").format(fn)) | 1059 " could not be read.</p>").format(fn)) |
1042 | 1060 |
1047 @param quiet flag indicating quiet operations. | 1065 @param quiet flag indicating quiet operations. |
1048 If this flag is true, no errors are reported. | 1066 If this flag is true, no errors are reported. |
1049 """ | 1067 """ |
1050 if self.pfile is None: | 1068 if self.pfile is None: |
1051 if not quiet: | 1069 if not quiet: |
1052 E5MessageBox.critical(self.ui, | 1070 E5MessageBox.critical( |
1071 self.ui, | |
1053 self.trUtf8("Save debugger properties"), | 1072 self.trUtf8("Save debugger properties"), |
1054 self.trUtf8("Please save the project first.")) | 1073 self.trUtf8("Please save the project first.")) |
1055 return | 1074 return |
1056 | 1075 |
1057 fn, ext = os.path.splitext(os.path.basename(self.pfile)) | 1076 fn, ext = os.path.splitext(os.path.basename(self.pfile)) |
1063 DebuggerPropertiesWriter( | 1082 DebuggerPropertiesWriter( |
1064 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() | 1083 f, os.path.splitext(os.path.basename(fn))[0]).writeXML() |
1065 f.close() | 1084 f.close() |
1066 else: | 1085 else: |
1067 if not quiet: | 1086 if not quiet: |
1068 E5MessageBox.critical(self.ui, | 1087 E5MessageBox.critical( |
1088 self.ui, | |
1069 self.trUtf8("Save debugger properties"), | 1089 self.trUtf8("Save debugger properties"), |
1070 self.trUtf8( | 1090 self.trUtf8( |
1071 "<p>The project debugger properties file <b>{0}</b>" | 1091 "<p>The project debugger properties file <b>{0}</b>" |
1072 " could not be written.</p>").format(fn)) | 1092 " could not be written.</p>").format(fn)) |
1073 | 1093 |
1074 def __deleteDebugProperties(self): | 1094 def __deleteDebugProperties(self): |
1075 """ | 1095 """ |
1076 Private method to delete the project debugger properties file (.e4d). | 1096 Private method to delete the project debugger properties file (.e4d). |
1077 """ | 1097 """ |
1078 if self.pfile is None: | 1098 if self.pfile is None: |
1079 E5MessageBox.critical(self.ui, | 1099 E5MessageBox.critical( |
1100 self.ui, | |
1080 self.trUtf8("Delete debugger properties"), | 1101 self.trUtf8("Delete debugger properties"), |
1081 self.trUtf8("Please save the project first.")) | 1102 self.trUtf8("Please save the project first.")) |
1082 return | 1103 return |
1083 | 1104 |
1084 fname, ext = os.path.splitext(os.path.basename(self.pfile)) | 1105 fname, ext = os.path.splitext(os.path.basename(self.pfile)) |
1087 "{0}.e4d".format(fname))]: | 1108 "{0}.e4d".format(fname))]: |
1088 if os.path.exists(fn): | 1109 if os.path.exists(fn): |
1089 try: | 1110 try: |
1090 os.remove(fn) | 1111 os.remove(fn) |
1091 except OSError: | 1112 except OSError: |
1092 E5MessageBox.critical(self.ui, | 1113 E5MessageBox.critical( |
1114 self.ui, | |
1093 self.trUtf8("Delete debugger properties"), | 1115 self.trUtf8("Delete debugger properties"), |
1094 self.trUtf8( | 1116 self.trUtf8( |
1095 "<p>The project debugger properties file" | 1117 "<p>The project debugger properties file" |
1096 " <b>{0}</b> could not be deleted.</p>") | 1118 " <b>{0}</b> could not be deleted.</p>") |
1097 .format(fn)) | 1119 .format(fn)) |
1182 """ | 1204 """ |
1183 Public slot used to add a language to the project. | 1205 Public slot used to add a language to the project. |
1184 """ | 1206 """ |
1185 if len(self.pdata["TRANSLATIONPATTERN"]) == 0 or \ | 1207 if len(self.pdata["TRANSLATIONPATTERN"]) == 0 or \ |
1186 self.pdata["TRANSLATIONPATTERN"][0] == '': | 1208 self.pdata["TRANSLATIONPATTERN"][0] == '': |
1187 E5MessageBox.critical(self.ui, | 1209 E5MessageBox.critical( |
1210 self.ui, | |
1188 self.trUtf8("Add Language"), | 1211 self.trUtf8("Add Language"), |
1189 self.trUtf8( | 1212 self.trUtf8( |
1190 "You have to specify a translation pattern first.")) | 1213 "You have to specify a translation pattern first.")) |
1191 return | 1214 return |
1192 | 1215 |
1255 if qmFile: | 1278 if qmFile: |
1256 try: | 1279 try: |
1257 if self.pdata["TRANSLATIONSBINPATH"]: | 1280 if self.pdata["TRANSLATIONSBINPATH"]: |
1258 qmFile = self.getRelativePath( | 1281 qmFile = self.getRelativePath( |
1259 os.path.join(self.pdata["TRANSLATIONSBINPATH"][0], | 1282 os.path.join(self.pdata["TRANSLATIONSBINPATH"][0], |
1260 os.path.basename(qmFile))) | 1283 os.path.basename(qmFile))) |
1261 self.pdata["TRANSLATIONS"].remove(qmFile) | 1284 self.pdata["TRANSLATIONS"].remove(qmFile) |
1262 self.__model.removeItem(qmFile) | 1285 self.__model.removeItem(qmFile) |
1263 except ValueError: | 1286 except ValueError: |
1264 pass | 1287 pass |
1265 self.setDirty(True) | 1288 self.setDirty(True) |
1276 try: | 1299 try: |
1277 fn = os.path.join(self.ppath, langFile) | 1300 fn = os.path.join(self.ppath, langFile) |
1278 if os.path.exists(fn): | 1301 if os.path.exists(fn): |
1279 os.remove(fn) | 1302 os.remove(fn) |
1280 except IOError: | 1303 except IOError: |
1281 E5MessageBox.critical(self.ui, | 1304 E5MessageBox.critical( |
1305 self.ui, | |
1282 self.trUtf8("Delete translation"), | 1306 self.trUtf8("Delete translation"), |
1283 self.trUtf8( | 1307 self.trUtf8( |
1284 "<p>The selected translation file <b>{0}</b> could not be" | 1308 "<p>The selected translation file <b>{0}</b> could not be" |
1285 " deleted.</p>").format(langFile)) | 1309 " deleted.</p>").format(langFile)) |
1286 return | 1310 return |
1291 if qmFile: | 1315 if qmFile: |
1292 try: | 1316 try: |
1293 if self.pdata["TRANSLATIONSBINPATH"]: | 1317 if self.pdata["TRANSLATIONSBINPATH"]: |
1294 qmFile = self.getRelativePath( | 1318 qmFile = self.getRelativePath( |
1295 os.path.join(self.pdata["TRANSLATIONSBINPATH"][0], | 1319 os.path.join(self.pdata["TRANSLATIONSBINPATH"][0], |
1296 os.path.basename(qmFile))) | 1320 os.path.basename(qmFile))) |
1297 fn = os.path.join(self.ppath, qmFile) | 1321 fn = os.path.join(self.ppath, qmFile) |
1298 if os.path.exists(fn): | 1322 if os.path.exists(fn): |
1299 os.remove(fn) | 1323 os.remove(fn) |
1300 except IOError: | 1324 except IOError: |
1301 E5MessageBox.critical(self.ui, | 1325 E5MessageBox.critical( |
1326 self.ui, | |
1302 self.trUtf8("Delete translation"), | 1327 self.trUtf8("Delete translation"), |
1303 self.trUtf8( | 1328 self.trUtf8( |
1304 "<p>The selected translation file <b>{0}</b> could" | 1329 "<p>The selected translation file <b>{0}</b> could" |
1305 " not be deleted.</p>").format(qmFile)) | 1330 " not be deleted.</p>").format(qmFile)) |
1306 return | 1331 return |
1420 try: | 1445 try: |
1421 if not os.path.isdir(target): | 1446 if not os.path.isdir(target): |
1422 os.makedirs(target) | 1447 os.makedirs(target) |
1423 | 1448 |
1424 if os.path.exists(targetfile): | 1449 if os.path.exists(targetfile): |
1425 res = E5MessageBox.yesNo(self.ui, | 1450 res = E5MessageBox.yesNo( |
1451 self.ui, | |
1426 self.trUtf8("Add file"), | 1452 self.trUtf8("Add file"), |
1427 self.trUtf8( | 1453 self.trUtf8( |
1428 "<p>The file <b>{0}</b> already" | 1454 "<p>The file <b>{0}</b> already" |
1429 " exists.</p><p>Overwrite it?</p>") | 1455 " exists.</p><p>Overwrite it?</p>") |
1430 .format(targetfile), | 1456 .format(targetfile), |
1432 if not res: | 1458 if not res: |
1433 return # don't overwrite | 1459 return # don't overwrite |
1434 | 1460 |
1435 shutil.copy(fn, target) | 1461 shutil.copy(fn, target) |
1436 except IOError as why: | 1462 except IOError as why: |
1437 E5MessageBox.critical(self.ui, | 1463 E5MessageBox.critical( |
1464 self.ui, | |
1438 self.trUtf8("Add file"), | 1465 self.trUtf8("Add file"), |
1439 self.trUtf8( | 1466 self.trUtf8( |
1440 "<p>The selected file <b>{0}</b> could" | 1467 "<p>The selected file <b>{0}</b> could" |
1441 " not be added to <b>{1}</b>.</p>" | 1468 " not be added to <b>{1}</b>.</p>" |
1442 "<p>Reason: {2}</p>") | 1469 "<p>Reason: {2}</p>") |
1443 .format(fn, target, str(why))) | 1470 .format(fn, target, str(why))) |
1444 continue | 1471 continue |
1445 | 1472 |
1446 self.appendFile(targetfile, isSource or filter == 'source') | 1473 self.appendFile(targetfile, isSource or filter == 'source') |
1447 else: | 1474 else: |
1448 E5MessageBox.critical(self.ui, | 1475 E5MessageBox.critical( |
1476 self.ui, | |
1449 self.trUtf8("Add file"), | 1477 self.trUtf8("Add file"), |
1450 self.trUtf8("The target directory must not be empty.")) | 1478 self.trUtf8("The target directory must not be empty.")) |
1451 | 1479 |
1452 def __addSingleDirectory(self, filetype, source, target, quiet=False): | 1480 def __addSingleDirectory(self, filetype, source, target, quiet=False): |
1453 """ | 1481 """ |
1473 sstring = "{0}{1}{2}".format(source, os.sep, pattern) | 1501 sstring = "{0}{1}{2}".format(source, os.sep, pattern) |
1474 files.extend(glob.glob(sstring)) | 1502 files.extend(glob.glob(sstring)) |
1475 | 1503 |
1476 if len(files) == 0: | 1504 if len(files) == 0: |
1477 if not quiet: | 1505 if not quiet: |
1478 E5MessageBox.information(self.ui, | 1506 E5MessageBox.information( |
1507 self.ui, | |
1479 self.trUtf8("Add directory"), | 1508 self.trUtf8("Add directory"), |
1480 self.trUtf8("<p>The source directory doesn't contain" | 1509 self.trUtf8( |
1510 "<p>The source directory doesn't contain" | |
1481 " any files belonging to the selected category.</p>")) | 1511 " any files belonging to the selected category.</p>")) |
1482 return | 1512 return |
1483 | 1513 |
1484 if not Utilities.samepath(target, source) and \ | 1514 if not Utilities.samepath(target, source) and \ |
1485 not os.path.isdir(target): | 1515 not os.path.isdir(target): |
1486 try: | 1516 try: |
1487 os.makedirs(target) | 1517 os.makedirs(target) |
1488 except IOError as why: | 1518 except IOError as why: |
1489 E5MessageBox.critical(self.ui, | 1519 E5MessageBox.critical( |
1520 self.ui, | |
1490 self.trUtf8("Add directory"), | 1521 self.trUtf8("Add directory"), |
1491 self.trUtf8( | 1522 self.trUtf8( |
1492 "<p>The target directory <b>{0}</b> could not be" | 1523 "<p>The target directory <b>{0}</b> could not be" |
1493 " created.</p><p>Reason: {1}</p>") | 1524 " created.</p><p>Reason: {1}</p>") |
1494 .format(target, str(why))) | 1525 .format(target, str(why))) |
1501 | 1532 |
1502 targetfile = os.path.join(target, os.path.basename(file)) | 1533 targetfile = os.path.join(target, os.path.basename(file)) |
1503 if not Utilities.samepath(target, source): | 1534 if not Utilities.samepath(target, source): |
1504 try: | 1535 try: |
1505 if os.path.exists(targetfile): | 1536 if os.path.exists(targetfile): |
1506 res = E5MessageBox.yesNo(self.ui, | 1537 res = E5MessageBox.yesNo( |
1538 self.ui, | |
1507 self.trUtf8("Add directory"), | 1539 self.trUtf8("Add directory"), |
1508 self.trUtf8( | 1540 self.trUtf8( |
1509 "<p>The file <b>{0}</b> already exists.</p>" | 1541 "<p>The file <b>{0}</b> already exists.</p>" |
1510 "<p>Overwrite it?</p>") | 1542 "<p>Overwrite it?</p>") |
1511 .format(targetfile), | 1543 .format(targetfile), |
1554 dlg = AddDirectoryDialog( | 1586 dlg = AddDirectoryDialog( |
1555 self, filter, self.parent(), startdir=startdir) | 1587 self, filter, self.parent(), startdir=startdir) |
1556 if dlg.exec_() == QDialog.Accepted: | 1588 if dlg.exec_() == QDialog.Accepted: |
1557 filetype, source, target, recursive = dlg.getData() | 1589 filetype, source, target, recursive = dlg.getData() |
1558 if target == '': | 1590 if target == '': |
1559 E5MessageBox.critical(self.ui, | 1591 E5MessageBox.critical( |
1592 self.ui, | |
1560 self.trUtf8("Add directory"), | 1593 self.trUtf8("Add directory"), |
1561 self.trUtf8("The target directory must not be empty.")) | 1594 self.trUtf8("The target directory must not be empty.")) |
1562 return | 1595 return |
1563 | 1596 |
1564 if filetype == 'OTHERS': | 1597 if filetype == 'OTHERS': |
1565 self.addToOthers(source) | 1598 self.addToOthers(source) |
1566 return | 1599 return |
1567 | 1600 |
1568 if source == '': | 1601 if source == '': |
1569 E5MessageBox.critical(self.ui, | 1602 E5MessageBox.critical( |
1603 self.ui, | |
1570 self.trUtf8("Add directory"), | 1604 self.trUtf8("Add directory"), |
1571 self.trUtf8("The source directory must not be empty.")) | 1605 self.trUtf8("The source directory must not be empty.")) |
1572 return | 1606 return |
1573 | 1607 |
1574 if recursive: | 1608 if recursive: |
1698 if not newfn: | 1732 if not newfn: |
1699 return False | 1733 return False |
1700 newfn = Utilities.toNativeSeparators(newfn) | 1734 newfn = Utilities.toNativeSeparators(newfn) |
1701 | 1735 |
1702 if os.path.exists(newfn): | 1736 if os.path.exists(newfn): |
1703 res = E5MessageBox.yesNo(self.ui, | 1737 res = E5MessageBox.yesNo( |
1738 self.ui, | |
1704 self.trUtf8("Rename File"), | 1739 self.trUtf8("Rename File"), |
1705 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" | 1740 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" |
1706 """ Overwrite it?</p>""") | 1741 """ Overwrite it?</p>""") |
1707 .format(newfn), | 1742 .format(newfn), |
1708 icon=E5MessageBox.Warning) | 1743 icon=E5MessageBox.Warning) |
1710 return False | 1745 return False |
1711 | 1746 |
1712 try: | 1747 try: |
1713 os.rename(oldfn, newfn) | 1748 os.rename(oldfn, newfn) |
1714 except OSError as msg: | 1749 except OSError as msg: |
1715 E5MessageBox.critical(self.ui, | 1750 E5MessageBox.critical( |
1751 self.ui, | |
1716 self.trUtf8("Rename File"), | 1752 self.trUtf8("Rename File"), |
1717 self.trUtf8( | 1753 self.trUtf8( |
1718 """<p>The file <b>{0}</b> could not be renamed.<br />""" | 1754 """<p>The file <b>{0}</b> could not be renamed.<br />""" |
1719 """Reason: {1}</p>""").format(oldfn, str(msg))) | 1755 """Reason: {1}</p>""").format(oldfn, str(msg))) |
1720 return False | 1756 return False |
1901 self.ppath, head, | 1937 self.ppath, head, |
1902 "__pycache__", "{0}.*{1}".format(tail, ext)) | 1938 "__pycache__", "{0}.*{1}".format(tail, ext)) |
1903 for f in glob.glob(pat): | 1939 for f in glob.glob(pat): |
1904 os.remove(f) | 1940 os.remove(f) |
1905 except EnvironmentError: | 1941 except EnvironmentError: |
1906 E5MessageBox.critical(self.ui, | 1942 E5MessageBox.critical( |
1943 self.ui, | |
1907 self.trUtf8("Delete file"), | 1944 self.trUtf8("Delete file"), |
1908 self.trUtf8( | 1945 self.trUtf8( |
1909 "<p>The selected file <b>{0}</b> could not be" | 1946 "<p>The selected file <b>{0}</b> could not be" |
1910 " deleted.</p>").format(fn)) | 1947 " deleted.</p>").format(fn)) |
1911 return False | 1948 return False |
1925 if not os.path.isabs(dn): | 1962 if not os.path.isabs(dn): |
1926 dn = os.path.join(self.ppath, dn) | 1963 dn = os.path.join(self.ppath, dn) |
1927 try: | 1964 try: |
1928 shutil.rmtree(dn, True) | 1965 shutil.rmtree(dn, True) |
1929 except EnvironmentError: | 1966 except EnvironmentError: |
1930 E5MessageBox.critical(self.ui, | 1967 E5MessageBox.critical( |
1968 self.ui, | |
1931 self.trUtf8("Delete directory"), | 1969 self.trUtf8("Delete directory"), |
1932 self.trUtf8("<p>The selected directory <b>{0}</b> could not be" | 1970 self.trUtf8( |
1971 "<p>The selected directory <b>{0}</b> could not be" | |
1933 " deleted.</p>").format(dn)) | 1972 " deleted.</p>").format(dn)) |
1934 return False | 1973 return False |
1935 | 1974 |
1936 self.removeDirectory(dn) | 1975 self.removeDirectory(dn) |
1937 return True | 1976 return True |
2006 # create the project directory if it doesn't exist already | 2045 # create the project directory if it doesn't exist already |
2007 if not os.path.isdir(self.ppath): | 2046 if not os.path.isdir(self.ppath): |
2008 try: | 2047 try: |
2009 os.makedirs(self.ppath) | 2048 os.makedirs(self.ppath) |
2010 except EnvironmentError: | 2049 except EnvironmentError: |
2011 E5MessageBox.critical(self.ui, | 2050 E5MessageBox.critical( |
2051 self.ui, | |
2012 self.trUtf8("Create project directory"), | 2052 self.trUtf8("Create project directory"), |
2013 self.trUtf8( | 2053 self.trUtf8( |
2014 "<p>The project directory <b>{0}</b> could not" | 2054 "<p>The project directory <b>{0}</b> could not" |
2015 " be created.</p>") | 2055 " be created.</p>") |
2016 .format(self.ppath)) | 2056 .format(self.ppath)) |
2063 if not os.path.exists(ms): | 2103 if not os.path.exists(ms): |
2064 try: | 2104 try: |
2065 f = open(ms, "w") | 2105 f = open(ms, "w") |
2066 f.close() | 2106 f.close() |
2067 except IOError as err: | 2107 except IOError as err: |
2068 E5MessageBox.critical(self.ui, | 2108 E5MessageBox.critical( |
2109 self.ui, | |
2069 self.trUtf8("Create main script"), | 2110 self.trUtf8("Create main script"), |
2070 self.trUtf8( | 2111 self.trUtf8( |
2071 "<p>The mainscript <b>{0}</b> could not" | 2112 "<p>The mainscript <b>{0}</b> could not" |
2072 " be created.<br/>Reason: {1}</p>") | 2113 " be created.<br/>Reason: {1}</p>") |
2073 .format(self.ppath, str(err))) | 2114 .format(self.ppath, str(err))) |
2074 self.appendFile(ms) | 2115 self.appendFile(ms) |
2075 except IndexError: | 2116 except IndexError: |
2076 ms = "" | 2117 ms = "" |
2077 | 2118 |
2078 # add existing files to the project | 2119 # add existing files to the project |
2079 res = E5MessageBox.yesNo(self.ui, | 2120 res = E5MessageBox.yesNo( |
2121 self.ui, | |
2080 self.trUtf8("New Project"), | 2122 self.trUtf8("New Project"), |
2081 self.trUtf8("""Add existing files to the project?"""), | 2123 self.trUtf8("""Add existing files to the project?"""), |
2082 yesDefault=True) | 2124 yesDefault=True) |
2083 if res: | 2125 if res: |
2084 self.newProjectAddFiles(ms) | 2126 self.newProjectAddFiles(ms) |
2123 self.pdata["VCS"] = [vcsSystem] | 2165 self.pdata["VCS"] = [vcsSystem] |
2124 self.vcs = self.initVCS() | 2166 self.vcs = self.initVCS() |
2125 self.setDirty(True) | 2167 self.setDirty(True) |
2126 if self.vcs is not None: | 2168 if self.vcs is not None: |
2127 # edit VCS command options | 2169 # edit VCS command options |
2128 vcores = E5MessageBox.yesNo(self.ui, | 2170 vcores = E5MessageBox.yesNo( |
2171 self.ui, | |
2129 self.trUtf8("New Project"), | 2172 self.trUtf8("New Project"), |
2130 self.trUtf8( | 2173 self.trUtf8( |
2131 """Would you like to edit the VCS""" | 2174 """Would you like to edit the VCS""" |
2132 """ command options?""")) | 2175 """ command options?""")) |
2133 if vcores: | 2176 if vcores: |
2136 codlg = vcsCommandOptionsDialog(self.vcs) | 2179 codlg = vcsCommandOptionsDialog(self.vcs) |
2137 if codlg.exec_() == QDialog.Accepted: | 2180 if codlg.exec_() == QDialog.Accepted: |
2138 self.vcs.vcsSetOptions(codlg.getOptions()) | 2181 self.vcs.vcsSetOptions(codlg.getOptions()) |
2139 # add project file to repository | 2182 # add project file to repository |
2140 if res == 0: | 2183 if res == 0: |
2141 apres = E5MessageBox.yesNo(self.ui, | 2184 apres = E5MessageBox.yesNo( |
2185 self.ui, | |
2142 self.trUtf8("New project"), | 2186 self.trUtf8("New project"), |
2143 self.trUtf8( | 2187 self.trUtf8( |
2144 "Shall the project file be added" | 2188 "Shall the project file be added" |
2145 " to the repository?"), | 2189 " to the repository?"), |
2146 yesDefault=True) | 2190 yesDefault=True) |
2186 self.pdata["VCS"] = ['None'] | 2230 self.pdata["VCS"] = ['None'] |
2187 self.vcs = self.initVCS() | 2231 self.vcs = self.initVCS() |
2188 self.setDirty(True) | 2232 self.setDirty(True) |
2189 if self.vcs is not None: | 2233 if self.vcs is not None: |
2190 # edit VCS command options | 2234 # edit VCS command options |
2191 vcores = E5MessageBox.yesNo(self.ui, | 2235 vcores = E5MessageBox.yesNo( |
2236 self.ui, | |
2192 self.trUtf8("New Project"), | 2237 self.trUtf8("New Project"), |
2193 self.trUtf8( | 2238 self.trUtf8( |
2194 """Would you like to edit the VCS command""" | 2239 """Would you like to edit the VCS command""" |
2195 """ options?""")) | 2240 """ options?""")) |
2196 if vcores: | 2241 if vcores: |
2644 if not ext: | 2689 if not ext: |
2645 ex = selectedFilter.split("(*")[1].split(")")[0] | 2690 ex = selectedFilter.split("(*")[1].split(")")[0] |
2646 if ex: | 2691 if ex: |
2647 fn += ex | 2692 fn += ex |
2648 if QFileInfo(fn).exists(): | 2693 if QFileInfo(fn).exists(): |
2649 res = E5MessageBox.yesNo(self.ui, | 2694 res = E5MessageBox.yesNo( |
2695 self.ui, | |
2650 self.trUtf8("Save File"), | 2696 self.trUtf8("Save File"), |
2651 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" | 2697 self.trUtf8("""<p>The file <b>{0}</b> already exists.""" |
2652 """ Overwrite it?</p>""").format(fn), | 2698 """ Overwrite it?</p>""").format(fn), |
2653 icon=E5MessageBox.Warning) | 2699 icon=E5MessageBox.Warning) |
2654 if not res: | 2700 if not res: |
2681 Public method to check dirty status and open a message window. | 2727 Public method to check dirty status and open a message window. |
2682 | 2728 |
2683 @return flag indicating whether this operation was successful (boolean) | 2729 @return flag indicating whether this operation was successful (boolean) |
2684 """ | 2730 """ |
2685 if self.isDirty(): | 2731 if self.isDirty(): |
2686 res = E5MessageBox.okToClearData(self.parent(), | 2732 res = E5MessageBox.okToClearData( |
2733 self.parent(), | |
2687 self.trUtf8("Close Project"), | 2734 self.trUtf8("Close Project"), |
2688 self.trUtf8("The current project has unsaved changes."), | 2735 self.trUtf8("The current project has unsaved changes."), |
2689 self.saveProject) | 2736 self.saveProject) |
2690 if res: | 2737 if res: |
2691 self.setDirty(False) | 2738 self.setDirty(False) |
2810 success &= vm.saveEditorEd(editor) | 2857 success &= vm.saveEditorEd(editor) |
2811 if reportSyntaxErrors and editor.hasSyntaxErrors(): | 2858 if reportSyntaxErrors and editor.hasSyntaxErrors(): |
2812 filesWithSyntaxErrors += 1 | 2859 filesWithSyntaxErrors += 1 |
2813 | 2860 |
2814 if reportSyntaxErrors and filesWithSyntaxErrors > 0: | 2861 if reportSyntaxErrors and filesWithSyntaxErrors > 0: |
2815 E5MessageBox.critical(self.ui, | 2862 E5MessageBox.critical( |
2863 self.ui, | |
2816 self.trUtf8("Syntax errors detected"), | 2864 self.trUtf8("Syntax errors detected"), |
2817 self.trUtf8( | 2865 self.trUtf8( |
2818 """The project contains %n file(s) with syntax errors.""", | 2866 """The project contains %n file(s) with syntax errors.""", |
2819 "", filesWithSyntaxErrors) | 2867 "", filesWithSyntaxErrors) |
2820 ) | 2868 ) |
2841 success &= editor.checkDirty() | 2889 success &= editor.checkDirty() |
2842 if reportSyntaxErrors and editor.hasSyntaxErrors(): | 2890 if reportSyntaxErrors and editor.hasSyntaxErrors(): |
2843 filesWithSyntaxErrors += 1 | 2891 filesWithSyntaxErrors += 1 |
2844 | 2892 |
2845 if reportSyntaxErrors and filesWithSyntaxErrors > 0: | 2893 if reportSyntaxErrors and filesWithSyntaxErrors > 0: |
2846 E5MessageBox.critical(self.ui, | 2894 E5MessageBox.critical( |
2895 self.ui, | |
2847 self.trUtf8("Syntax errors detected"), | 2896 self.trUtf8("Syntax errors detected"), |
2848 self.trUtf8( | 2897 self.trUtf8( |
2849 """The project contains %n file(s) with syntax errors.""", | 2898 """The project contains %n file(s) with syntax errors.""", |
2850 "", filesWithSyntaxErrors) | 2899 "", filesWithSyntaxErrors) |
2851 ) | 2900 ) |
3206 """ | 3255 """ |
3207 self.actions = [] | 3256 self.actions = [] |
3208 | 3257 |
3209 self.actGrp1 = createActionGroup(self) | 3258 self.actGrp1 = createActionGroup(self) |
3210 | 3259 |
3211 act = E5Action(self.trUtf8('New project'), | 3260 act = E5Action( |
3212 UI.PixmapCache.getIcon("projectNew.png"), | 3261 self.trUtf8('New project'), |
3213 self.trUtf8('&New...'), 0, 0, | 3262 UI.PixmapCache.getIcon("projectNew.png"), |
3214 self.actGrp1, 'project_new') | 3263 self.trUtf8('&New...'), 0, 0, |
3264 self.actGrp1, 'project_new') | |
3215 act.setStatusTip(self.trUtf8('Generate a new project')) | 3265 act.setStatusTip(self.trUtf8('Generate a new project')) |
3216 act.setWhatsThis(self.trUtf8( | 3266 act.setWhatsThis(self.trUtf8( |
3217 """<b>New...</b>""" | 3267 """<b>New...</b>""" |
3218 """<p>This opens a dialog for entering the info for a""" | 3268 """<p>This opens a dialog for entering the info for a""" |
3219 """ new project.</p>""" | 3269 """ new project.</p>""" |
3220 )) | 3270 )) |
3221 act.triggered[()].connect(self.createNewProject) | 3271 act.triggered[()].connect(self.createNewProject) |
3222 self.actions.append(act) | 3272 self.actions.append(act) |
3223 | 3273 |
3224 act = E5Action(self.trUtf8('Open project'), | 3274 act = E5Action( |
3225 UI.PixmapCache.getIcon("projectOpen.png"), | 3275 self.trUtf8('Open project'), |
3226 self.trUtf8('&Open...'), 0, 0, | 3276 UI.PixmapCache.getIcon("projectOpen.png"), |
3227 self.actGrp1, 'project_open') | 3277 self.trUtf8('&Open...'), 0, 0, |
3278 self.actGrp1, 'project_open') | |
3228 act.setStatusTip(self.trUtf8('Open an existing project')) | 3279 act.setStatusTip(self.trUtf8('Open an existing project')) |
3229 act.setWhatsThis(self.trUtf8( | 3280 act.setWhatsThis(self.trUtf8( |
3230 """<b>Open...</b>""" | 3281 """<b>Open...</b>""" |
3231 """<p>This opens an existing project.</p>""" | 3282 """<p>This opens an existing project.</p>""" |
3232 )) | 3283 )) |
3233 act.triggered[()].connect(self.openProject) | 3284 act.triggered[()].connect(self.openProject) |
3234 self.actions.append(act) | 3285 self.actions.append(act) |
3235 | 3286 |
3236 self.closeAct = E5Action(self.trUtf8('Close project'), | 3287 self.closeAct = E5Action( |
3237 UI.PixmapCache.getIcon("projectClose.png"), | 3288 self.trUtf8('Close project'), |
3238 self.trUtf8('&Close'), 0, 0, self, 'project_close') | 3289 UI.PixmapCache.getIcon("projectClose.png"), |
3290 self.trUtf8('&Close'), 0, 0, self, 'project_close') | |
3239 self.closeAct.setStatusTip(self.trUtf8('Close the current project')) | 3291 self.closeAct.setStatusTip(self.trUtf8('Close the current project')) |
3240 self.closeAct.setWhatsThis(self.trUtf8( | 3292 self.closeAct.setWhatsThis(self.trUtf8( |
3241 """<b>Close</b>""" | 3293 """<b>Close</b>""" |
3242 """<p>This closes the current project.</p>""" | 3294 """<p>This closes the current project.</p>""" |
3243 )) | 3295 )) |
3244 self.closeAct.triggered[()].connect(self.closeProject) | 3296 self.closeAct.triggered[()].connect(self.closeProject) |
3245 self.actions.append(self.closeAct) | 3297 self.actions.append(self.closeAct) |
3246 | 3298 |
3247 self.saveAct = E5Action(self.trUtf8('Save project'), | 3299 self.saveAct = E5Action( |
3248 UI.PixmapCache.getIcon("projectSave.png"), | 3300 self.trUtf8('Save project'), |
3249 self.trUtf8('&Save'), 0, 0, self, 'project_save') | 3301 UI.PixmapCache.getIcon("projectSave.png"), |
3302 self.trUtf8('&Save'), 0, 0, self, 'project_save') | |
3250 self.saveAct.setStatusTip(self.trUtf8('Save the current project')) | 3303 self.saveAct.setStatusTip(self.trUtf8('Save the current project')) |
3251 self.saveAct.setWhatsThis(self.trUtf8( | 3304 self.saveAct.setWhatsThis(self.trUtf8( |
3252 """<b>Save</b>""" | 3305 """<b>Save</b>""" |
3253 """<p>This saves the current project.</p>""" | 3306 """<p>This saves the current project.</p>""" |
3254 )) | 3307 )) |
3255 self.saveAct.triggered[()].connect(self.saveProject) | 3308 self.saveAct.triggered[()].connect(self.saveProject) |
3256 self.actions.append(self.saveAct) | 3309 self.actions.append(self.saveAct) |
3257 | 3310 |
3258 self.saveasAct = E5Action(self.trUtf8('Save project as'), | 3311 self.saveasAct = E5Action( |
3259 UI.PixmapCache.getIcon("projectSaveAs.png"), | 3312 self.trUtf8('Save project as'), |
3260 self.trUtf8('Save &as...'), 0, 0, self, 'project_save_as') | 3313 UI.PixmapCache.getIcon("projectSaveAs.png"), |
3314 self.trUtf8('Save &as...'), 0, 0, self, 'project_save_as') | |
3261 self.saveasAct.setStatusTip(self.trUtf8( | 3315 self.saveasAct.setStatusTip(self.trUtf8( |
3262 'Save the current project to a new file')) | 3316 'Save the current project to a new file')) |
3263 self.saveasAct.setWhatsThis(self.trUtf8( | 3317 self.saveasAct.setWhatsThis(self.trUtf8( |
3264 """<b>Save as</b>""" | 3318 """<b>Save as</b>""" |
3265 """<p>This saves the current project to a new file.</p>""" | 3319 """<p>This saves the current project to a new file.</p>""" |
3267 self.saveasAct.triggered[()].connect(self.saveProjectAs) | 3321 self.saveasAct.triggered[()].connect(self.saveProjectAs) |
3268 self.actions.append(self.saveasAct) | 3322 self.actions.append(self.saveasAct) |
3269 | 3323 |
3270 self.actGrp2 = createActionGroup(self) | 3324 self.actGrp2 = createActionGroup(self) |
3271 | 3325 |
3272 self.addFilesAct = E5Action(self.trUtf8('Add files to project'), | 3326 self.addFilesAct = E5Action( |
3273 UI.PixmapCache.getIcon("fileMisc.png"), | 3327 self.trUtf8('Add files to project'), |
3274 self.trUtf8('Add &files...'), 0, 0, | 3328 UI.PixmapCache.getIcon("fileMisc.png"), |
3275 self.actGrp2, 'project_add_file') | 3329 self.trUtf8('Add &files...'), 0, 0, |
3330 self.actGrp2, 'project_add_file') | |
3276 self.addFilesAct.setStatusTip(self.trUtf8( | 3331 self.addFilesAct.setStatusTip(self.trUtf8( |
3277 'Add files to the current project')) | 3332 'Add files to the current project')) |
3278 self.addFilesAct.setWhatsThis(self.trUtf8( | 3333 self.addFilesAct.setWhatsThis(self.trUtf8( |
3279 """<b>Add files...</b>""" | 3334 """<b>Add files...</b>""" |
3280 """<p>This opens a dialog for adding files""" | 3335 """<p>This opens a dialog for adding files""" |
3312 """ to the current project.</p>""" | 3367 """ to the current project.</p>""" |
3313 )) | 3368 )) |
3314 self.addLanguageAct.triggered[()].connect(self.addLanguage) | 3369 self.addLanguageAct.triggered[()].connect(self.addLanguage) |
3315 self.actions.append(self.addLanguageAct) | 3370 self.actions.append(self.addLanguageAct) |
3316 | 3371 |
3317 act = E5Action(self.trUtf8('Search new files'), | 3372 act = E5Action( |
3318 self.trUtf8('Searc&h new files...'), 0, 0, | 3373 self.trUtf8('Search new files'), |
3319 self.actGrp2, 'project_search_new_files') | 3374 self.trUtf8('Searc&h new files...'), 0, 0, |
3375 self.actGrp2, 'project_search_new_files') | |
3320 act.setStatusTip(self.trUtf8( | 3376 act.setStatusTip(self.trUtf8( |
3321 'Search new files in the project directory.')) | 3377 'Search new files in the project directory.')) |
3322 act.setWhatsThis(self.trUtf8( | 3378 act.setWhatsThis(self.trUtf8( |
3323 """<b>Search new files...</b>""" | 3379 """<b>Search new files...</b>""" |
3324 """<p>This searches for new files (sources, *.ui, *.idl) in""" | 3380 """<p>This searches for new files (sources, *.ui, *.idl) in""" |
3325 """ the project directory and registered subdirectories.</p>""" | 3381 """ the project directory and registered subdirectories.</p>""" |
3326 )) | 3382 )) |
3327 act.triggered[()].connect(self.__searchNewFiles) | 3383 act.triggered[()].connect(self.__searchNewFiles) |
3328 self.actions.append(act) | 3384 self.actions.append(act) |
3329 | 3385 |
3330 self.propsAct = E5Action(self.trUtf8('Project properties'), | 3386 self.propsAct = E5Action( |
3331 UI.PixmapCache.getIcon("projectProps.png"), | 3387 self.trUtf8('Project properties'), |
3332 self.trUtf8('&Properties...'), 0, 0, self, | 3388 UI.PixmapCache.getIcon("projectProps.png"), |
3333 'project_properties') | 3389 self.trUtf8('&Properties...'), 0, 0, self, |
3390 'project_properties') | |
3334 self.propsAct.setStatusTip(self.trUtf8('Show the project properties')) | 3391 self.propsAct.setStatusTip(self.trUtf8('Show the project properties')) |
3335 self.propsAct.setWhatsThis(self.trUtf8( | 3392 self.propsAct.setWhatsThis(self.trUtf8( |
3336 """<b>Properties...</b>""" | 3393 """<b>Properties...</b>""" |
3337 """<p>This shows a dialog to edit the project properties.</p>""" | 3394 """<p>This shows a dialog to edit the project properties.</p>""" |
3338 )) | 3395 )) |
3339 self.propsAct.triggered[()].connect(self.__showProperties) | 3396 self.propsAct.triggered[()].connect(self.__showProperties) |
3340 self.actions.append(self.propsAct) | 3397 self.actions.append(self.propsAct) |
3341 | 3398 |
3342 self.userPropsAct = E5Action(self.trUtf8('User project properties'), | 3399 self.userPropsAct = E5Action( |
3343 UI.PixmapCache.getIcon("projectUserProps.png"), | 3400 self.trUtf8('User project properties'), |
3344 self.trUtf8('&User Properties...'), 0, 0, self, | 3401 UI.PixmapCache.getIcon("projectUserProps.png"), |
3345 'project_user_properties') | 3402 self.trUtf8('&User Properties...'), 0, 0, self, |
3403 'project_user_properties') | |
3346 self.userPropsAct.setStatusTip(self.trUtf8( | 3404 self.userPropsAct.setStatusTip(self.trUtf8( |
3347 'Show the user specific project properties')) | 3405 'Show the user specific project properties')) |
3348 self.userPropsAct.setWhatsThis(self.trUtf8( | 3406 self.userPropsAct.setWhatsThis(self.trUtf8( |
3349 """<b>User Properties...</b>""" | 3407 """<b>User Properties...</b>""" |
3350 """<p>This shows a dialog to edit the user specific project""" | 3408 """<p>This shows a dialog to edit the user specific project""" |
3351 """ properties.</p>""" | 3409 """ properties.</p>""" |
3352 )) | 3410 )) |
3353 self.userPropsAct.triggered[()].connect(self.__showUserProperties) | 3411 self.userPropsAct.triggered[()].connect(self.__showUserProperties) |
3354 self.actions.append(self.userPropsAct) | 3412 self.actions.append(self.userPropsAct) |
3355 | 3413 |
3356 self.filetypesAct = E5Action(self.trUtf8('Filetype Associations'), | 3414 self.filetypesAct = E5Action( |
3357 self.trUtf8('Filetype Associations...'), 0, 0, | 3415 self.trUtf8('Filetype Associations'), |
3358 self, 'project_filetype_associatios') | 3416 self.trUtf8('Filetype Associations...'), 0, 0, |
3417 self, 'project_filetype_associatios') | |
3359 self.filetypesAct.setStatusTip( | 3418 self.filetypesAct.setStatusTip( |
3360 self.trUtf8('Show the project filetype associations')) | 3419 self.trUtf8('Show the project filetype associations')) |
3361 self.filetypesAct.setWhatsThis(self.trUtf8( | 3420 self.filetypesAct.setWhatsThis(self.trUtf8( |
3362 """<b>Filetype Associations...</b>""" | 3421 """<b>Filetype Associations...</b>""" |
3363 """<p>This shows a dialog to edit the filetype associations of""" | 3422 """<p>This shows a dialog to edit the filetype associations of""" |
3368 )) | 3427 )) |
3369 self.filetypesAct.triggered[()].connect( | 3428 self.filetypesAct.triggered[()].connect( |
3370 self.__showFiletypeAssociations) | 3429 self.__showFiletypeAssociations) |
3371 self.actions.append(self.filetypesAct) | 3430 self.actions.append(self.filetypesAct) |
3372 | 3431 |
3373 self.lexersAct = E5Action(self.trUtf8('Lexer Associations'), | 3432 self.lexersAct = E5Action( |
3374 self.trUtf8('Lexer Associations...'), 0, 0, | 3433 self.trUtf8('Lexer Associations'), |
3375 self, 'project_lexer_associatios') | 3434 self.trUtf8('Lexer Associations...'), 0, 0, |
3435 self, 'project_lexer_associatios') | |
3376 self.lexersAct.setStatusTip(self.trUtf8( | 3436 self.lexersAct.setStatusTip(self.trUtf8( |
3377 'Show the project lexer associations (overriding defaults)')) | 3437 'Show the project lexer associations (overriding defaults)')) |
3378 self.lexersAct.setWhatsThis(self.trUtf8( | 3438 self.lexersAct.setWhatsThis(self.trUtf8( |
3379 """<b>Lexer Associations...</b>""" | 3439 """<b>Lexer Associations...</b>""" |
3380 """<p>This shows a dialog to edit the lexer associations of""" | 3440 """<p>This shows a dialog to edit the lexer associations of""" |
3385 self.lexersAct.triggered[()].connect(self.__showLexerAssociations) | 3445 self.lexersAct.triggered[()].connect(self.__showLexerAssociations) |
3386 self.actions.append(self.lexersAct) | 3446 self.actions.append(self.lexersAct) |
3387 | 3447 |
3388 self.dbgActGrp = createActionGroup(self) | 3448 self.dbgActGrp = createActionGroup(self) |
3389 | 3449 |
3390 act = E5Action(self.trUtf8('Debugger Properties'), | 3450 act = E5Action( |
3391 self.trUtf8('Debugger &Properties...'), 0, 0, | 3451 self.trUtf8('Debugger Properties'), |
3392 self.dbgActGrp, 'project_debugger_properties') | 3452 self.trUtf8('Debugger &Properties...'), 0, 0, |
3453 self.dbgActGrp, 'project_debugger_properties') | |
3393 act.setStatusTip(self.trUtf8('Show the debugger properties')) | 3454 act.setStatusTip(self.trUtf8('Show the debugger properties')) |
3394 act.setWhatsThis(self.trUtf8( | 3455 act.setWhatsThis(self.trUtf8( |
3395 """<b>Debugger Properties...</b>""" | 3456 """<b>Debugger Properties...</b>""" |
3396 """<p>This shows a dialog to edit project specific debugger""" | 3457 """<p>This shows a dialog to edit project specific debugger""" |
3397 """ settings.</p>""" | 3458 """ settings.</p>""" |
3398 )) | 3459 )) |
3399 act.triggered[()].connect(self.__showDebugProperties) | 3460 act.triggered[()].connect(self.__showDebugProperties) |
3400 self.actions.append(act) | 3461 self.actions.append(act) |
3401 | 3462 |
3402 act = E5Action(self.trUtf8('Load'), | 3463 act = E5Action( |
3403 self.trUtf8('&Load'), 0, 0, | 3464 self.trUtf8('Load'), |
3404 self.dbgActGrp, 'project_debugger_properties_load') | 3465 self.trUtf8('&Load'), 0, 0, |
3466 self.dbgActGrp, 'project_debugger_properties_load') | |
3405 act.setStatusTip(self.trUtf8('Load the debugger properties')) | 3467 act.setStatusTip(self.trUtf8('Load the debugger properties')) |
3406 act.setWhatsThis(self.trUtf8( | 3468 act.setWhatsThis(self.trUtf8( |
3407 """<b>Load Debugger Properties</b>""" | 3469 """<b>Load Debugger Properties</b>""" |
3408 """<p>This loads the project specific debugger settings.</p>""" | 3470 """<p>This loads the project specific debugger settings.</p>""" |
3409 )) | 3471 )) |
3410 act.triggered[()].connect(self.__readDebugProperties) | 3472 act.triggered[()].connect(self.__readDebugProperties) |
3411 self.actions.append(act) | 3473 self.actions.append(act) |
3412 | 3474 |
3413 act = E5Action(self.trUtf8('Save'), | 3475 act = E5Action( |
3414 self.trUtf8('&Save'), 0, 0, | 3476 self.trUtf8('Save'), |
3415 self.dbgActGrp, 'project_debugger_properties_save') | 3477 self.trUtf8('&Save'), 0, 0, |
3478 self.dbgActGrp, 'project_debugger_properties_save') | |
3416 act.setStatusTip(self.trUtf8('Save the debugger properties')) | 3479 act.setStatusTip(self.trUtf8('Save the debugger properties')) |
3417 act.setWhatsThis(self.trUtf8( | 3480 act.setWhatsThis(self.trUtf8( |
3418 """<b>Save Debugger Properties</b>""" | 3481 """<b>Save Debugger Properties</b>""" |
3419 """<p>This saves the project specific debugger settings.</p>""" | 3482 """<p>This saves the project specific debugger settings.</p>""" |
3420 )) | 3483 )) |
3421 act.triggered[()].connect(self.__writeDebugProperties) | 3484 act.triggered[()].connect(self.__writeDebugProperties) |
3422 self.actions.append(act) | 3485 self.actions.append(act) |
3423 | 3486 |
3424 act = E5Action(self.trUtf8('Delete'), | 3487 act = E5Action( |
3425 self.trUtf8('&Delete'), 0, 0, | 3488 self.trUtf8('Delete'), |
3426 self.dbgActGrp, 'project_debugger_properties_delete') | 3489 self.trUtf8('&Delete'), 0, 0, |
3490 self.dbgActGrp, 'project_debugger_properties_delete') | |
3427 act.setStatusTip(self.trUtf8('Delete the debugger properties')) | 3491 act.setStatusTip(self.trUtf8('Delete the debugger properties')) |
3428 act.setWhatsThis(self.trUtf8( | 3492 act.setWhatsThis(self.trUtf8( |
3429 """<b>Delete Debugger Properties</b>""" | 3493 """<b>Delete Debugger Properties</b>""" |
3430 """<p>This deletes the file containing the project specific""" | 3494 """<p>This deletes the file containing the project specific""" |
3431 """ debugger settings.</p>""" | 3495 """ debugger settings.</p>""" |
3432 )) | 3496 )) |
3433 act.triggered[()].connect(self.__deleteDebugProperties) | 3497 act.triggered[()].connect(self.__deleteDebugProperties) |
3434 self.actions.append(act) | 3498 self.actions.append(act) |
3435 | 3499 |
3436 act = E5Action(self.trUtf8('Reset'), | 3500 act = E5Action( |
3437 self.trUtf8('&Reset'), 0, 0, | 3501 self.trUtf8('Reset'), |
3438 self.dbgActGrp, 'project_debugger_properties_resets') | 3502 self.trUtf8('&Reset'), 0, 0, |
3503 self.dbgActGrp, 'project_debugger_properties_resets') | |
3439 act.setStatusTip(self.trUtf8('Reset the debugger properties')) | 3504 act.setStatusTip(self.trUtf8('Reset the debugger properties')) |
3440 act.setWhatsThis(self.trUtf8( | 3505 act.setWhatsThis(self.trUtf8( |
3441 """<b>Reset Debugger Properties</b>""" | 3506 """<b>Reset Debugger Properties</b>""" |
3442 """<p>This resets the project specific debugger settings.</p>""" | 3507 """<p>This resets the project specific debugger settings.</p>""" |
3443 )) | 3508 )) |
3444 act.triggered[()].connect(self.__initDebugProperties) | 3509 act.triggered[()].connect(self.__initDebugProperties) |
3445 self.actions.append(act) | 3510 self.actions.append(act) |
3446 | 3511 |
3447 self.sessActGrp = createActionGroup(self) | 3512 self.sessActGrp = createActionGroup(self) |
3448 | 3513 |
3449 act = E5Action(self.trUtf8('Load session'), | 3514 act = E5Action( |
3450 self.trUtf8('Load session'), 0, 0, | 3515 self.trUtf8('Load session'), |
3451 self.sessActGrp, 'project_load_session') | 3516 self.trUtf8('Load session'), 0, 0, |
3517 self.sessActGrp, 'project_load_session') | |
3452 act.setStatusTip(self.trUtf8('Load the projects session file.')) | 3518 act.setStatusTip(self.trUtf8('Load the projects session file.')) |
3453 act.setWhatsThis(self.trUtf8( | 3519 act.setWhatsThis(self.trUtf8( |
3454 """<b>Load session</b>""" | 3520 """<b>Load session</b>""" |
3455 """<p>This loads the projects session file. The session consists""" | 3521 """<p>This loads the projects session file. The session consists""" |
3456 """ of the following data.<br>""" | 3522 """ of the following data.<br>""" |
3461 """- the exception reporting flag</p>""" | 3527 """- the exception reporting flag</p>""" |
3462 )) | 3528 )) |
3463 act.triggered[()].connect(self.__readSession) | 3529 act.triggered[()].connect(self.__readSession) |
3464 self.actions.append(act) | 3530 self.actions.append(act) |
3465 | 3531 |
3466 act = E5Action(self.trUtf8('Save session'), | 3532 act = E5Action( |
3467 self.trUtf8('Save session'), 0, 0, | 3533 self.trUtf8('Save session'), |
3468 self.sessActGrp, 'project_save_session') | 3534 self.trUtf8('Save session'), 0, 0, |
3535 self.sessActGrp, 'project_save_session') | |
3469 act.setStatusTip(self.trUtf8('Save the projects session file.')) | 3536 act.setStatusTip(self.trUtf8('Save the projects session file.')) |
3470 act.setWhatsThis(self.trUtf8( | 3537 act.setWhatsThis(self.trUtf8( |
3471 """<b>Save session</b>""" | 3538 """<b>Save session</b>""" |
3472 """<p>This saves the projects session file. The session consists""" | 3539 """<p>This saves the projects session file. The session consists""" |
3473 """ of the following data.<br>""" | 3540 """ of the following data.<br>""" |
3478 """- the exception reporting flag</p>""" | 3545 """- the exception reporting flag</p>""" |
3479 )) | 3546 )) |
3480 act.triggered[()].connect(self.__writeSession) | 3547 act.triggered[()].connect(self.__writeSession) |
3481 self.actions.append(act) | 3548 self.actions.append(act) |
3482 | 3549 |
3483 act = E5Action(self.trUtf8('Delete session'), | 3550 act = E5Action( |
3484 self.trUtf8('Delete session'), 0, 0, | 3551 self.trUtf8('Delete session'), |
3485 self.sessActGrp, 'project_delete_session') | 3552 self.trUtf8('Delete session'), 0, 0, |
3553 self.sessActGrp, 'project_delete_session') | |
3486 act.setStatusTip(self.trUtf8('Delete the projects session file.')) | 3554 act.setStatusTip(self.trUtf8('Delete the projects session file.')) |
3487 act.setWhatsThis(self.trUtf8( | 3555 act.setWhatsThis(self.trUtf8( |
3488 """<b>Delete session</b>""" | 3556 """<b>Delete session</b>""" |
3489 """<p>This deletes the projects session file</p>""" | 3557 """<p>This deletes the projects session file</p>""" |
3490 )) | 3558 )) |
3491 act.triggered[()].connect(self.__deleteSession) | 3559 act.triggered[()].connect(self.__deleteSession) |
3492 self.actions.append(act) | 3560 self.actions.append(act) |
3493 | 3561 |
3494 self.chkGrp = createActionGroup(self) | 3562 self.chkGrp = createActionGroup(self) |
3495 | 3563 |
3496 self.codeMetricsAct = E5Action(self.trUtf8('Code Metrics'), | 3564 self.codeMetricsAct = E5Action( |
3497 self.trUtf8('&Code Metrics...'), 0, 0, | 3565 self.trUtf8('Code Metrics'), |
3498 self.chkGrp, 'project_code_metrics') | 3566 self.trUtf8('&Code Metrics...'), 0, 0, |
3567 self.chkGrp, 'project_code_metrics') | |
3499 self.codeMetricsAct.setStatusTip( | 3568 self.codeMetricsAct.setStatusTip( |
3500 self.trUtf8('Show some code metrics for the project.')) | 3569 self.trUtf8('Show some code metrics for the project.')) |
3501 self.codeMetricsAct.setWhatsThis(self.trUtf8( | 3570 self.codeMetricsAct.setWhatsThis(self.trUtf8( |
3502 """<b>Code Metrics...</b>""" | 3571 """<b>Code Metrics...</b>""" |
3503 """<p>This shows some code metrics for all Python files in""" | 3572 """<p>This shows some code metrics for all Python files in""" |
3504 """ the project.</p>""" | 3573 """ the project.</p>""" |
3505 )) | 3574 )) |
3506 self.codeMetricsAct.triggered[()].connect(self.__showCodeMetrics) | 3575 self.codeMetricsAct.triggered[()].connect(self.__showCodeMetrics) |
3507 self.actions.append(self.codeMetricsAct) | 3576 self.actions.append(self.codeMetricsAct) |
3508 | 3577 |
3509 self.codeCoverageAct = E5Action(self.trUtf8('Python Code Coverage'), | 3578 self.codeCoverageAct = E5Action( |
3510 self.trUtf8('Code Co&verage...'), 0, 0, | 3579 self.trUtf8('Python Code Coverage'), |
3511 self.chkGrp, 'project_code_coverage') | 3580 self.trUtf8('Code Co&verage...'), 0, 0, |
3581 self.chkGrp, 'project_code_coverage') | |
3512 self.codeCoverageAct.setStatusTip( | 3582 self.codeCoverageAct.setStatusTip( |
3513 self.trUtf8('Show code coverage information for the project.')) | 3583 self.trUtf8('Show code coverage information for the project.')) |
3514 self.codeCoverageAct.setWhatsThis(self.trUtf8( | 3584 self.codeCoverageAct.setWhatsThis(self.trUtf8( |
3515 """<b>Code Coverage...</b>""" | 3585 """<b>Code Coverage...</b>""" |
3516 """<p>This shows the code coverage information for all Python""" | 3586 """<p>This shows the code coverage information for all Python""" |
3517 """ files in the project.</p>""" | 3587 """ files in the project.</p>""" |
3518 )) | 3588 )) |
3519 self.codeCoverageAct.triggered[()].connect(self.__showCodeCoverage) | 3589 self.codeCoverageAct.triggered[()].connect(self.__showCodeCoverage) |
3520 self.actions.append(self.codeCoverageAct) | 3590 self.actions.append(self.codeCoverageAct) |
3521 | 3591 |
3522 self.codeProfileAct = E5Action(self.trUtf8('Profile Data'), | 3592 self.codeProfileAct = E5Action( |
3523 self.trUtf8('&Profile Data...'), 0, 0, | 3593 self.trUtf8('Profile Data'), |
3524 self.chkGrp, 'project_profile_data') | 3594 self.trUtf8('&Profile Data...'), 0, 0, |
3595 self.chkGrp, 'project_profile_data') | |
3525 self.codeProfileAct.setStatusTip( | 3596 self.codeProfileAct.setStatusTip( |
3526 self.trUtf8('Show profiling data for the project.')) | 3597 self.trUtf8('Show profiling data for the project.')) |
3527 self.codeProfileAct.setWhatsThis(self.trUtf8( | 3598 self.codeProfileAct.setWhatsThis(self.trUtf8( |
3528 """<b>Profile Data...</b>""" | 3599 """<b>Profile Data...</b>""" |
3529 """<p>This shows the profiling data for the project.</p>""" | 3600 """<p>This shows the profiling data for the project.</p>""" |
3545 )) | 3616 )) |
3546 self.applicationDiagramAct.triggered[()].connect( | 3617 self.applicationDiagramAct.triggered[()].connect( |
3547 self.handleApplicationDiagram) | 3618 self.handleApplicationDiagram) |
3548 self.actions.append(self.applicationDiagramAct) | 3619 self.actions.append(self.applicationDiagramAct) |
3549 | 3620 |
3550 self.loadDiagramAct = E5Action(self.trUtf8('Load Diagram'), | 3621 self.loadDiagramAct = E5Action( |
3551 self.trUtf8('&Load Diagram...'), 0, 0, | 3622 self.trUtf8('Load Diagram'), |
3552 self.graphicsGrp, 'project_load_diagram') | 3623 self.trUtf8('&Load Diagram...'), 0, 0, |
3624 self.graphicsGrp, 'project_load_diagram') | |
3553 self.loadDiagramAct.setStatusTip( | 3625 self.loadDiagramAct.setStatusTip( |
3554 self.trUtf8('Load a diagram from file.')) | 3626 self.trUtf8('Load a diagram from file.')) |
3555 self.loadDiagramAct.setWhatsThis(self.trUtf8( | 3627 self.loadDiagramAct.setWhatsThis(self.trUtf8( |
3556 """<b>Load Diagram...</b>""" | 3628 """<b>Load Diagram...</b>""" |
3557 """<p>This loads a diagram from file.</p>""" | 3629 """<p>This loads a diagram from file.</p>""" |
3559 self.loadDiagramAct.triggered[()].connect(self.__loadDiagram) | 3631 self.loadDiagramAct.triggered[()].connect(self.__loadDiagram) |
3560 self.actions.append(self.loadDiagramAct) | 3632 self.actions.append(self.loadDiagramAct) |
3561 | 3633 |
3562 self.pluginGrp = createActionGroup(self) | 3634 self.pluginGrp = createActionGroup(self) |
3563 | 3635 |
3564 self.pluginPkgListAct = E5Action(self.trUtf8('Create Package List'), | 3636 self.pluginPkgListAct = E5Action( |
3565 UI.PixmapCache.getIcon("pluginArchiveList.png"), | 3637 self.trUtf8('Create Package List'), |
3566 self.trUtf8('Create &Package List'), 0, 0, | 3638 UI.PixmapCache.getIcon("pluginArchiveList.png"), |
3567 self.pluginGrp, 'project_plugin_pkglist') | 3639 self.trUtf8('Create &Package List'), 0, 0, |
3640 self.pluginGrp, 'project_plugin_pkglist') | |
3568 self.pluginPkgListAct.setStatusTip( | 3641 self.pluginPkgListAct.setStatusTip( |
3569 self.trUtf8('Create an initial PKGLIST file for an eric5 plugin.')) | 3642 self.trUtf8('Create an initial PKGLIST file for an eric5 plugin.')) |
3570 self.pluginPkgListAct.setWhatsThis(self.trUtf8( | 3643 self.pluginPkgListAct.setWhatsThis(self.trUtf8( |
3571 """<b>Create Package List</b>""" | 3644 """<b>Create Package List</b>""" |
3572 """<p>This creates an initial list of files to include in an""" | 3645 """<p>This creates an initial list of files to include in an""" |
3574 """ file.</p>""" | 3647 """ file.</p>""" |
3575 )) | 3648 )) |
3576 self.pluginPkgListAct.triggered[()].connect(self.__pluginCreatePkgList) | 3649 self.pluginPkgListAct.triggered[()].connect(self.__pluginCreatePkgList) |
3577 self.actions.append(self.pluginPkgListAct) | 3650 self.actions.append(self.pluginPkgListAct) |
3578 | 3651 |
3579 self.pluginArchiveAct = E5Action(self.trUtf8('Create Plugin Archive'), | 3652 self.pluginArchiveAct = E5Action( |
3580 UI.PixmapCache.getIcon("pluginArchive.png"), | 3653 self.trUtf8('Create Plugin Archive'), |
3581 self.trUtf8('Create Plugin &Archive'), 0, 0, | 3654 UI.PixmapCache.getIcon("pluginArchive.png"), |
3582 self.pluginGrp, 'project_plugin_archive') | 3655 self.trUtf8('Create Plugin &Archive'), 0, 0, |
3656 self.pluginGrp, 'project_plugin_archive') | |
3583 self.pluginArchiveAct.setStatusTip( | 3657 self.pluginArchiveAct.setStatusTip( |
3584 self.trUtf8('Create an eric5 plugin archive file.')) | 3658 self.trUtf8('Create an eric5 plugin archive file.')) |
3585 self.pluginArchiveAct.setWhatsThis(self.trUtf8( | 3659 self.pluginArchiveAct.setWhatsThis(self.trUtf8( |
3586 """<b>Create Plugin Archive</b>""" | 3660 """<b>Create Plugin Archive</b>""" |
3587 """<p>This creates an eric5 plugin archive file using the list""" | 3661 """<p>This creates an eric5 plugin archive file using the list""" |
3800 if idx < 10: | 3874 if idx < 10: |
3801 formatStr = '&{0:d}. {1}' | 3875 formatStr = '&{0:d}. {1}' |
3802 else: | 3876 else: |
3803 formatStr = '{0:d}. {1}' | 3877 formatStr = '{0:d}. {1}' |
3804 act = self.recentMenu.addAction( | 3878 act = self.recentMenu.addAction( |
3805 formatStr.format(idx, | 3879 formatStr.format( |
3880 idx, | |
3806 Utilities.compactPath(rp, self.ui.maxMenuFilePathLen))) | 3881 Utilities.compactPath(rp, self.ui.maxMenuFilePathLen))) |
3807 act.setData(rp) | 3882 act.setData(rp) |
3808 act.setEnabled(QFileInfo(rp).exists()) | 3883 act.setEnabled(QFileInfo(rp).exists()) |
3809 idx += 1 | 3884 idx += 1 |
3810 | 3885 |
3927 return | 4002 return |
3928 | 4003 |
3929 # if newfiles is empty, put up message box informing user nothing found | 4004 # if newfiles is empty, put up message box informing user nothing found |
3930 if not newFiles: | 4005 if not newFiles: |
3931 if onUserDemand: | 4006 if onUserDemand: |
3932 E5MessageBox.information(self.ui, | 4007 E5MessageBox.information( |
4008 self.ui, | |
3933 self.trUtf8("Search New Files"), | 4009 self.trUtf8("Search New Files"), |
3934 self.trUtf8("There were no new files found to be added.")) | 4010 self.trUtf8("There were no new files found to be added.")) |
3935 return | 4011 return |
3936 | 4012 |
3937 # autoInclude is not set, show a dialog | 4013 # autoInclude is not set, show a dialog |
4061 vcsExists, msg = vcs.vcsExists() | 4137 vcsExists, msg = vcs.vcsExists() |
4062 if not vcsExists: | 4138 if not vcsExists: |
4063 if override: | 4139 if override: |
4064 # override failed, revert to original | 4140 # override failed, revert to original |
4065 QApplication.restoreOverrideCursor() | 4141 QApplication.restoreOverrideCursor() |
4066 E5MessageBox.critical(self.ui, | 4142 E5MessageBox.critical( |
4143 self.ui, | |
4067 self.trUtf8("Version Control System"), | 4144 self.trUtf8("Version Control System"), |
4068 self.trUtf8( | 4145 self.trUtf8( |
4069 "<p>The selected VCS <b>{0}</b> could not be" | 4146 "<p>The selected VCS <b>{0}</b> could not be" |
4070 " found. <br/>Reverting override.</p><p>{1}</p>") | 4147 " found. <br/>Reverting override.</p><p>{1}</p>") |
4071 .format(vcsSystem, msg)) | 4148 .format(vcsSystem, msg)) |
4072 self.pudata["VCSOVERRIDE"] = [] | 4149 self.pudata["VCSOVERRIDE"] = [] |
4073 return self.initVCS(nooverride=True) | 4150 return self.initVCS(nooverride=True) |
4074 | 4151 |
4075 QApplication.restoreOverrideCursor() | 4152 QApplication.restoreOverrideCursor() |
4076 E5MessageBox.critical(self.ui, | 4153 E5MessageBox.critical( |
4154 self.ui, | |
4077 self.trUtf8("Version Control System"), | 4155 self.trUtf8("Version Control System"), |
4078 self.trUtf8( | 4156 self.trUtf8( |
4079 "<p>The selected VCS <b>{0}</b> could not be" | 4157 "<p>The selected VCS <b>{0}</b> could not be" |
4080 " found.<br/>Disabling version control.</p>" | 4158 " found.<br/>Disabling version control.</p>" |
4081 "<p>{1}</p>").format(vcsSystem, msg)) | 4159 "<p>{1}</p>").format(vcsSystem, msg)) |
4173 | 4251 |
4174 def __showCodeMetrics(self): | 4252 def __showCodeMetrics(self): |
4175 """ | 4253 """ |
4176 Private slot used to calculate some code metrics for the project files. | 4254 Private slot used to calculate some code metrics for the project files. |
4177 """ | 4255 """ |
4178 files = [os.path.join(self.ppath, file) \ | 4256 files = [os.path.join(self.ppath, file) |
4179 for file in self.pdata["SOURCES"] if file.endswith(".py")] | 4257 for file in self.pdata["SOURCES"] if file.endswith(".py")] |
4180 from DataViews.CodeMetricsDialog import CodeMetricsDialog | 4258 from DataViews.CodeMetricsDialog import CodeMetricsDialog |
4181 self.codemetrics = CodeMetricsDialog() | 4259 self.codemetrics = CodeMetricsDialog() |
4182 self.codemetrics.show() | 4260 self.codemetrics.show() |
4183 self.codemetrics.prepare(files, self) | 4261 self.codemetrics.prepare(files, self) |
4184 | 4262 |
4187 Private slot used to show the code coverage information for the | 4265 Private slot used to show the code coverage information for the |
4188 project files. | 4266 project files. |
4189 """ | 4267 """ |
4190 fn = self.getMainScript(True) | 4268 fn = self.getMainScript(True) |
4191 if fn is None: | 4269 if fn is None: |
4192 E5MessageBox.critical(self.ui, | 4270 E5MessageBox.critical( |
4271 self.ui, | |
4193 self.trUtf8("Coverage Data"), | 4272 self.trUtf8("Coverage Data"), |
4194 self.trUtf8("There is no main script defined for the" | 4273 self.trUtf8( |
4274 "There is no main script defined for the" | |
4195 " current project. Aborting")) | 4275 " current project. Aborting")) |
4196 return | 4276 return |
4197 | 4277 |
4198 tfn = Utilities.getTestFileName(fn) | 4278 tfn = Utilities.getTestFileName(fn) |
4199 basename = os.path.splitext(fn)[0] | 4279 basename = os.path.splitext(fn)[0] |
4221 else: | 4301 else: |
4222 fn = files[0] | 4302 fn = files[0] |
4223 else: | 4303 else: |
4224 return | 4304 return |
4225 | 4305 |
4226 files = [os.path.join(self.ppath, file) \ | 4306 files = [os.path.join(self.ppath, file) |
4227 for file in self.pdata["SOURCES"] if file.endswith(".py")] | 4307 for file in self.pdata["SOURCES"] if file.endswith(".py")] |
4228 from DataViews.PyCoverageDialog import PyCoverageDialog | 4308 from DataViews.PyCoverageDialog import PyCoverageDialog |
4229 self.codecoverage = PyCoverageDialog() | 4309 self.codecoverage = PyCoverageDialog() |
4230 self.codecoverage.show() | 4310 self.codecoverage.show() |
4231 self.codecoverage.start(fn, files) | 4311 self.codecoverage.start(fn, files) |
4232 | 4312 |
4234 """ | 4314 """ |
4235 Private slot used to show the profiling information for the project. | 4315 Private slot used to show the profiling information for the project. |
4236 """ | 4316 """ |
4237 fn = self.getMainScript(True) | 4317 fn = self.getMainScript(True) |
4238 if fn is None: | 4318 if fn is None: |
4239 E5MessageBox.critical(self.ui, | 4319 E5MessageBox.critical( |
4320 self.ui, | |
4240 self.trUtf8("Profile Data"), | 4321 self.trUtf8("Profile Data"), |
4241 self.trUtf8("There is no main script defined for the" | 4322 self.trUtf8( |
4323 "There is no main script defined for the" | |
4242 " current project. Aborting")) | 4324 " current project. Aborting")) |
4243 return | 4325 return |
4244 | 4326 |
4245 tfn = Utilities.getTestFileName(fn) | 4327 tfn = Utilities.getTestFileName(fn) |
4246 basename = os.path.splitext(fn)[0] | 4328 basename = os.path.splitext(fn)[0] |
4309 | 4391 |
4310 def handleApplicationDiagram(self): | 4392 def handleApplicationDiagram(self): |
4311 """ | 4393 """ |
4312 Private method to handle the application diagram context menu action. | 4394 Private method to handle the application diagram context menu action. |
4313 """ | 4395 """ |
4314 res = E5MessageBox.yesNo(self.ui, | 4396 res = E5MessageBox.yesNo( |
4397 self.ui, | |
4315 self.trUtf8("Application Diagram"), | 4398 self.trUtf8("Application Diagram"), |
4316 self.trUtf8("""Include module names?"""), | 4399 self.trUtf8("""Include module names?"""), |
4317 yesDefault=True) | 4400 yesDefault=True) |
4318 | 4401 |
4319 from Graphics.UMLDialog import UMLDialog | 4402 from Graphics.UMLDialog import UMLDialog |
4426 """ | 4509 """ |
4427 Private slot to create a PKGLIST file needed for archive file creation. | 4510 Private slot to create a PKGLIST file needed for archive file creation. |
4428 """ | 4511 """ |
4429 pkglist = os.path.join(self.ppath, "PKGLIST") | 4512 pkglist = os.path.join(self.ppath, "PKGLIST") |
4430 if os.path.exists(pkglist): | 4513 if os.path.exists(pkglist): |
4431 res = E5MessageBox.yesNo(self.ui, | 4514 res = E5MessageBox.yesNo( |
4515 self.ui, | |
4432 self.trUtf8("Create Package List"), | 4516 self.trUtf8("Create Package List"), |
4433 self.trUtf8("<p>The file <b>PKGLIST</b> already" | 4517 self.trUtf8( |
4518 "<p>The file <b>PKGLIST</b> already" | |
4434 " exists.</p><p>Overwrite it?</p>"), | 4519 " exists.</p><p>Overwrite it?</p>"), |
4435 icon=E5MessageBox.Warning) | 4520 icon=E5MessageBox.Warning) |
4436 if not res: | 4521 if not res: |
4437 return # don't overwrite | 4522 return # don't overwrite |
4438 | 4523 |
4442 "INTERFACES", "OTHERS"]: | 4527 "INTERFACES", "OTHERS"]: |
4443 lst_.extend(self.pdata[key]) | 4528 lst_.extend(self.pdata[key]) |
4444 lst = [] | 4529 lst = [] |
4445 for entry in lst_: | 4530 for entry in lst_: |
4446 if os.path.isdir(self.getAbsolutePath(entry)): | 4531 if os.path.isdir(self.getAbsolutePath(entry)): |
4447 lst.extend([self.getRelativePath(p) for p in | 4532 lst.extend( |
4448 Utilities.direntries(self.getAbsolutePath(entry), True)]) | 4533 [self.getRelativePath(p) for p in |
4534 Utilities.direntries(self.getAbsolutePath(entry), True)]) | |
4449 continue | 4535 continue |
4450 else: | 4536 else: |
4451 lst.append(entry) | 4537 lst.append(entry) |
4452 lst.sort() | 4538 lst.sort() |
4453 if "PKGLIST" in lst: | 4539 if "PKGLIST" in lst: |
4463 pkglistFile.write( | 4549 pkglistFile.write( |
4464 "\n".join([Utilities.fromNativeSeparators(f) for f in lst])) | 4550 "\n".join([Utilities.fromNativeSeparators(f) for f in lst])) |
4465 pkglistFile.write("\n") # ensure the file ends with an empty line | 4551 pkglistFile.write("\n") # ensure the file ends with an empty line |
4466 pkglistFile.close() | 4552 pkglistFile.close() |
4467 except IOError as why: | 4553 except IOError as why: |
4468 E5MessageBox.critical(self.ui, | 4554 E5MessageBox.critical( |
4555 self.ui, | |
4469 self.trUtf8("Create Package List"), | 4556 self.trUtf8("Create Package List"), |
4470 self.trUtf8( | 4557 self.trUtf8( |
4471 """<p>The file <b>PKGLIST</b> could not be created.</p>""" | 4558 """<p>The file <b>PKGLIST</b> could not be created.</p>""" |
4472 """<p>Reason: {0}</p>""").format(str(why))) | 4559 """<p>Reason: {0}</p>""").format(str(why))) |
4473 return | 4560 return |
4481 | 4568 |
4482 @param snapshot flag indicating a snapshot archive (boolean) | 4569 @param snapshot flag indicating a snapshot archive (boolean) |
4483 """ | 4570 """ |
4484 pkglist = os.path.join(self.ppath, "PKGLIST") | 4571 pkglist = os.path.join(self.ppath, "PKGLIST") |
4485 if not os.path.exists(pkglist): | 4572 if not os.path.exists(pkglist): |
4486 E5MessageBox.critical(self.ui, | 4573 E5MessageBox.critical( |
4574 self.ui, | |
4487 self.trUtf8("Create Plugin Archive"), | 4575 self.trUtf8("Create Plugin Archive"), |
4488 self.trUtf8("""<p>The file <b>PKGLIST</b> does not exist. """ | 4576 self.trUtf8("""<p>The file <b>PKGLIST</b> does not exist. """ |
4489 """Aborting...</p>""")) | 4577 """Aborting...</p>""")) |
4490 return | 4578 return |
4491 | 4579 |
4492 if len(self.pdata["MAINSCRIPT"]) == 0 or \ | 4580 if len(self.pdata["MAINSCRIPT"]) == 0 or \ |
4493 len(self.pdata["MAINSCRIPT"][0]) == 0: | 4581 len(self.pdata["MAINSCRIPT"][0]) == 0: |
4494 E5MessageBox.critical(self.ui, | 4582 E5MessageBox.critical( |
4583 self.ui, | |
4495 self.trUtf8("Create Plugin Archive"), | 4584 self.trUtf8("Create Plugin Archive"), |
4496 self.trUtf8( | 4585 self.trUtf8( |
4497 """The project does not have a main script defined. """ | 4586 """The project does not have a main script defined. """ |
4498 """Aborting...""")) | 4587 """Aborting...""")) |
4499 return | 4588 return |
4502 pkglistFile = open(pkglist, "r", encoding="utf-8") | 4591 pkglistFile = open(pkglist, "r", encoding="utf-8") |
4503 names = pkglistFile.read() | 4592 names = pkglistFile.read() |
4504 pkglistFile.close() | 4593 pkglistFile.close() |
4505 names = sorted(names.splitlines()) | 4594 names = sorted(names.splitlines()) |
4506 except IOError as why: | 4595 except IOError as why: |
4507 E5MessageBox.critical(self.ui, | 4596 E5MessageBox.critical( |
4597 self.ui, | |
4508 self.trUtf8("Create Plugin Archive"), | 4598 self.trUtf8("Create Plugin Archive"), |
4509 self.trUtf8( | 4599 self.trUtf8( |
4510 """<p>The file <b>PKGLIST</b> could not be read.</p>""" | 4600 """<p>The file <b>PKGLIST</b> could not be read.</p>""" |
4511 """<p>Reason: {0}</p>""").format(str(why))) | 4601 """<p>Reason: {0}</p>""").format(str(why))) |
4512 return | 4602 return |
4514 archive = os.path.join( | 4604 archive = os.path.join( |
4515 self.ppath, self.pdata["MAINSCRIPT"][0].replace(".py", ".zip")) | 4605 self.ppath, self.pdata["MAINSCRIPT"][0].replace(".py", ".zip")) |
4516 try: | 4606 try: |
4517 archiveFile = zipfile.ZipFile(archive, "w") | 4607 archiveFile = zipfile.ZipFile(archive, "w") |
4518 except IOError as why: | 4608 except IOError as why: |
4519 E5MessageBox.critical(self.ui, | 4609 E5MessageBox.critical( |
4610 self.ui, | |
4520 self.trUtf8("Create Plugin Archive"), | 4611 self.trUtf8("Create Plugin Archive"), |
4521 self.trUtf8( | 4612 self.trUtf8( |
4522 """<p>The eric5 plugin archive file <b>{0}</b> could """ | 4613 """<p>The eric5 plugin archive file <b>{0}</b> could """ |
4523 """not be created.</p>""" | 4614 """not be created.</p>""" |
4524 """<p>Reason: {1}</p>""").format(archive, str(why))) | 4615 """<p>Reason: {1}</p>""").format(archive, str(why))) |
4539 if name == self.pdata["MAINSCRIPT"][0]: | 4630 if name == self.pdata["MAINSCRIPT"][0]: |
4540 version = self.__pluginExtractVersion( | 4631 version = self.__pluginExtractVersion( |
4541 os.path.join(self.ppath, | 4632 os.path.join(self.ppath, |
4542 self.pdata["MAINSCRIPT"][0])) | 4633 self.pdata["MAINSCRIPT"][0])) |
4543 except OSError as why: | 4634 except OSError as why: |
4544 E5MessageBox.critical(self.ui, | 4635 E5MessageBox.critical( |
4636 self.ui, | |
4545 self.trUtf8("Create Plugin Archive"), | 4637 self.trUtf8("Create Plugin Archive"), |
4546 self.trUtf8( | 4638 self.trUtf8( |
4547 """<p>The file <b>{0}</b> could not be stored """ | 4639 """<p>The file <b>{0}</b> could not be stored """ |
4548 """in the archive. Ignoring it.</p>""" | 4640 """in the archive. Ignoring it.</p>""" |
4549 """<p>Reason: {1}</p>""")\ | 4641 """<p>Reason: {1}</p>""")\ |
4561 self.trUtf8( | 4653 self.trUtf8( |
4562 """<p>The eric5 plugin archive file <b>{0}</b> was """ | 4654 """<p>The eric5 plugin archive file <b>{0}</b> was """ |
4563 """created successfully.</p>""")\ | 4655 """created successfully.</p>""")\ |
4564 .format(os.path.basename(archive))) | 4656 .format(os.path.basename(archive))) |
4565 else: | 4657 else: |
4566 E5MessageBox.information(self.ui, | 4658 E5MessageBox.information( |
4659 self.ui, | |
4567 self.trUtf8("Create Plugin Archive"), | 4660 self.trUtf8("Create Plugin Archive"), |
4568 self.trUtf8( | 4661 self.trUtf8( |
4569 """<p>The eric5 plugin archive file <b>{0}</b> was """ | 4662 """<p>The eric5 plugin archive file <b>{0}</b> was """ |
4570 """created successfully.</p>""").format(archive)) | 4663 """created successfully.</p>""").format(archive)) |
4571 | 4664 |
4605 """ | 4698 """ |
4606 try: | 4699 try: |
4607 sourcelines, encoding = Utilities.readEncodedFile(filename) | 4700 sourcelines, encoding = Utilities.readEncodedFile(filename) |
4608 sourcelines = sourcelines.splitlines(True) | 4701 sourcelines = sourcelines.splitlines(True) |
4609 except (IOError, UnicodeError) as why: | 4702 except (IOError, UnicodeError) as why: |
4610 E5MessageBox.critical(self.ui, | 4703 E5MessageBox.critical( |
4704 self.ui, | |
4611 self.trUtf8("Create Plugin Archive"), | 4705 self.trUtf8("Create Plugin Archive"), |
4612 self.trUtf8("""<p>The plugin file <b>{0}</b> could """ | 4706 self.trUtf8("""<p>The plugin file <b>{0}</b> could """ |
4613 """not be read.</p>""" | 4707 """not be read.</p>""" |
4614 """<p>Reason: {1}</p>""") | 4708 """<p>Reason: {1}</p>""") |
4615 .format(filename, str(why))) | 4709 .format(filename, str(why))) |
4620 if sourcelines[lineno].startswith("version = "): | 4714 if sourcelines[lineno].startswith("version = "): |
4621 # found the line to modify | 4715 # found the line to modify |
4622 datestr = time.strftime("%Y%m%d") | 4716 datestr = time.strftime("%Y%m%d") |
4623 lineend = sourcelines[lineno]\ | 4717 lineend = sourcelines[lineno]\ |
4624 .replace(sourcelines[lineno].rstrip(), "") | 4718 .replace(sourcelines[lineno].rstrip(), "") |
4625 sversion = "{0}-snapshot-{1}".format(sourcelines[lineno]\ | 4719 sversion = "{0}-snapshot-{1}".format( |
4626 .replace("version = ", "").strip()[1:-1], | 4720 sourcelines[lineno].replace("version = ", "") |
4721 .strip()[1:-1], | |
4627 datestr) | 4722 datestr) |
4628 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( | 4723 sourcelines[lineno] = '{0} + "-snapshot-{1}"{2}'.format( |
4629 sourcelines[lineno].rstrip(), datestr, lineend) | 4724 sourcelines[lineno].rstrip(), datestr, lineend) |
4630 break | 4725 break |
4631 | 4726 |
4644 version = "0.0.0" | 4739 version = "0.0.0" |
4645 try: | 4740 try: |
4646 sourcelines = Utilities.readEncodedFile(filename)[0] | 4741 sourcelines = Utilities.readEncodedFile(filename)[0] |
4647 sourcelines = sourcelines.splitlines(True) | 4742 sourcelines = sourcelines.splitlines(True) |
4648 except (IOError, UnicodeError) as why: | 4743 except (IOError, UnicodeError) as why: |
4649 E5MessageBox.critical(self.ui, | 4744 E5MessageBox.critical( |
4745 self.ui, | |
4650 self.trUtf8("Create Plugin Archive"), | 4746 self.trUtf8("Create Plugin Archive"), |
4651 self.trUtf8( | 4747 self.trUtf8( |
4652 """<p>The plugin file <b>{0}</b> could """ | 4748 """<p>The plugin file <b>{0}</b> could """ |
4653 """not be read.</p> <p>Reason: {1}</p>""") | 4749 """not be read.</p> <p>Reason: {1}</p>""") |
4654 .format(filename, str(why))) | 4750 .format(filename, str(why))) |