99 @type bool |
107 @type bool |
100 @param projectType type of the project |
108 @param projectType type of the project |
101 @type str |
109 @type str |
102 """ |
110 """ |
103 QThread.__init__(self) |
111 QThread.__init__(self) |
104 |
112 |
105 self.setTerminationEnabled(True) |
113 self.setTerminationEnabled(True) |
106 |
114 |
107 # Get the AC word separators for all of the languages that the editor |
115 # Get the AC word separators for all of the languages that the editor |
108 # supports. This has to be before we create a new thread, because |
116 # supports. This has to be before we create a new thread, because |
109 # access to GUI elements is not allowed from non-GUI threads. |
117 # access to GUI elements is not allowed from non-GUI threads. |
110 self.__wseps = {} |
118 self.__wseps = {} |
111 for lang in QScintilla.Lexers.getSupportedLanguages(): |
119 for lang in QScintilla.Lexers.getSupportedLanguages(): |
112 lexer = QScintilla.Lexers.getLexer(lang) |
120 lexer = QScintilla.Lexers.getLexer(lang) |
113 if lexer is not None: |
121 if lexer is not None: |
114 self.__wseps[lang] = lexer.autoCompletionWordSeparators() |
122 self.__wseps[lang] = lexer.autoCompletionWordSeparators() |
115 |
123 |
116 self.__proxy = proxy |
124 self.__proxy = proxy |
117 self.__language = language |
125 self.__language = language |
118 self.__projectType = projectType |
126 self.__projectType = projectType |
119 self.__apiFiles = apiFiles[:] |
127 self.__apiFiles = apiFiles[:] |
120 self.__aborted = False |
128 self.__aborted = False |
121 self.__projectPath = projectPath |
129 self.__projectPath = projectPath |
122 self.__refresh = refresh |
130 self.__refresh = refresh |
123 |
131 |
124 self.__databaseName = dbName |
132 self.__databaseName = dbName |
125 |
133 |
126 if self.__projectType: |
134 if self.__projectType: |
127 self.__connectionName = "{0}_{1}_{2}".format( |
135 self.__connectionName = "{0}_{1}_{2}".format( |
128 self.__language, self.__projectType, id(self)) |
136 self.__language, self.__projectType, id(self) |
129 else: |
137 ) |
130 self.__connectionName = "{0}_{1}".format( |
138 else: |
131 self.__language, id(self)) |
139 self.__connectionName = "{0}_{1}".format(self.__language, id(self)) |
132 |
140 |
133 def __autoCompletionWordSeparators(self, language): |
141 def __autoCompletionWordSeparators(self, language): |
134 """ |
142 """ |
135 Private method to get the word separator characters for a language. |
143 Private method to get the word separator characters for a language. |
136 |
144 |
137 @param language language of the APIs object |
145 @param language language of the APIs object |
138 @type str |
146 @type str |
139 @return word separator characters |
147 @return word separator characters |
140 @rtype list of str |
148 @rtype list of str |
141 """ |
149 """ |
142 if language: |
150 if language: |
143 return self.__wseps.get(language, None) |
151 return self.__wseps.get(language, None) |
144 else: |
152 else: |
145 return self.__proxy.autoCompletionWordSeparators() |
153 return self.__proxy.autoCompletionWordSeparators() |
146 |
154 |
147 def abort(self): |
155 def abort(self): |
148 """ |
156 """ |
149 Public method to ask the thread to stop. |
157 Public method to ask the thread to stop. |
150 """ |
158 """ |
151 self.__aborted = True |
159 self.__aborted = True |
152 |
160 |
153 def __loadApiFileIfNewer(self, apiFile): |
161 def __loadApiFileIfNewer(self, apiFile): |
154 """ |
162 """ |
155 Private method to load an API file, if it is newer than the one read |
163 Private method to load an API file, if it is newer than the one read |
156 into the database. |
164 into the database. |
157 |
165 |
158 @param apiFile filename of the raw API file |
166 @param apiFile filename of the raw API file |
159 @type str |
167 @type str |
160 """ |
168 """ |
161 db = QSqlDatabase.database(self.__connectionName) |
169 db = QSqlDatabase.database(self.__connectionName) |
162 db.transaction() |
170 db.transaction() |
165 query.prepare(self.file_loaded_stmt) |
173 query.prepare(self.file_loaded_stmt) |
166 query.bindValue(":file", apiFile) |
174 query.bindValue(":file", apiFile) |
167 query.exec() |
175 query.exec() |
168 loadTime = ( |
176 loadTime = ( |
169 QDateTime.fromString(query.value(0), Qt.DateFormat.ISODate) |
177 QDateTime.fromString(query.value(0), Qt.DateFormat.ISODate) |
170 if query.next() and query.isValid() else |
178 if query.next() and query.isValid() |
|
179 else |
171 # __IGNORE_WARNING_M513__ |
180 # __IGNORE_WARNING_M513__ |
172 QDateTime(1970, 1, 1, 0, 0) |
181 QDateTime(1970, 1, 1, 0, 0) |
173 ) |
182 ) |
174 query.finish() |
183 query.finish() |
175 del query |
184 del query |
176 finally: |
185 finally: |
177 db.commit() |
186 db.commit() |
178 if self.__projectPath: |
187 if self.__projectPath: |
179 modTime = ( |
188 modTime = QFileInfo( |
180 QFileInfo(os.path.join(self.__projectPath, apiFile)) |
189 os.path.join(self.__projectPath, apiFile) |
181 .lastModified() |
190 ).lastModified() |
182 ) |
|
183 else: |
191 else: |
184 modTime = QFileInfo(apiFile).lastModified() |
192 modTime = QFileInfo(apiFile).lastModified() |
185 basesFile = os.path.splitext(apiFile)[0] + ".bas" |
193 basesFile = os.path.splitext(apiFile)[0] + ".bas" |
186 if os.path.exists(basesFile): |
194 if os.path.exists(basesFile): |
187 modTimeBases = QFileInfo(basesFile).lastModified() |
195 modTimeBases = QFileInfo(basesFile).lastModified() |
188 if modTimeBases > modTime: |
196 if modTimeBases > modTime: |
189 modTime = modTimeBases |
197 modTime = modTimeBases |
190 if loadTime < modTime: |
198 if loadTime < modTime: |
191 self.processing.emit(WorkerStatusFile, apiFile) |
199 self.processing.emit(WorkerStatusFile, apiFile) |
192 self.__loadApiFile(apiFile) |
200 self.__loadApiFile(apiFile) |
193 |
201 |
194 def __classesAttributesApi(self, module): |
202 def __classesAttributesApi(self, module): |
195 """ |
203 """ |
196 Private method to generate class api section for class attributes. |
204 Private method to generate class api section for class attributes. |
197 |
205 |
198 @param module module object to get the info from |
206 @param module module object to get the info from |
199 @type Module |
207 @type Module |
200 @return API information |
208 @return API information |
201 @rtype list of str |
209 @rtype list of str |
202 """ |
210 """ |
203 api = [] |
211 api = [] |
204 modulePath = module.name.split('.') |
212 modulePath = module.name.split(".") |
205 moduleName = "{0}.".format('.'.join(modulePath)) |
213 moduleName = "{0}.".format(".".join(modulePath)) |
206 |
214 |
207 for className in sorted(module.classes.keys()): |
215 for className in sorted(module.classes.keys()): |
208 _class = module.classes[className] |
216 _class = module.classes[className] |
209 classNameStr = "{0}{1}.".format(moduleName, className) |
217 classNameStr = "{0}{1}.".format(moduleName, className) |
210 for variable in sorted(_class.attributes.keys()): |
218 for variable in sorted(_class.attributes.keys()): |
211 if not _class.attributes[variable].isPrivate(): |
219 if not _class.attributes[variable].isPrivate(): |
212 from QScintilla.Editor import Editor |
220 from QScintilla.Editor import Editor |
|
221 |
213 if _class.attributes[variable].isPublic(): |
222 if _class.attributes[variable].isPublic(): |
214 iconId = Editor.AttributeID |
223 iconId = Editor.AttributeID |
215 elif _class.attributes[variable].isProtected(): |
224 elif _class.attributes[variable].isProtected(): |
216 iconId = Editor.AttributeProtectedID |
225 iconId = Editor.AttributeProtectedID |
217 else: |
226 else: |
218 iconId = Editor.AttributePrivateID |
227 iconId = Editor.AttributePrivateID |
219 api.append('{0}{1}?{2:d}'.format(classNameStr, variable, |
228 api.append("{0}{1}?{2:d}".format(classNameStr, variable, iconId)) |
220 iconId)) |
|
221 return api |
229 return api |
222 |
230 |
223 def __loadApiFile(self, apiFile): |
231 def __loadApiFile(self, apiFile): |
224 """ |
232 """ |
225 Private method to read a raw API file into the database. |
233 Private method to read a raw API file into the database. |
226 |
234 |
227 @param apiFile filename of the raw API file |
235 @param apiFile filename of the raw API file |
228 @type str |
236 @type str |
229 """ |
237 """ |
230 apis = [] |
238 apis = [] |
231 bases = [] |
239 bases = [] |
232 |
240 |
233 if self.__language == ApisNameProject: |
241 if self.__language == ApisNameProject: |
234 with contextlib.suppress(OSError, ImportError): |
242 with contextlib.suppress(OSError, ImportError): |
235 module = Utilities.ModuleParser.readModule( |
243 module = Utilities.ModuleParser.readModule( |
236 os.path.join(self.__projectPath, apiFile), |
244 os.path.join(self.__projectPath, apiFile), |
237 basename=self.__projectPath + os.sep, |
245 basename=self.__projectPath + os.sep, |
238 caching=False) |
246 caching=False, |
|
247 ) |
239 language = module.getType() |
248 language = module.getType() |
240 if language: |
249 if language: |
241 from DocumentationTools.APIGenerator import APIGenerator |
250 from DocumentationTools.APIGenerator import APIGenerator |
|
251 |
242 apiGenerator = APIGenerator(module) |
252 apiGenerator = APIGenerator(module) |
243 apis = apiGenerator.genAPI(True, "", True) |
253 apis = apiGenerator.genAPI(True, "", True) |
244 if os.path.basename(apiFile).startswith("Ui_"): |
254 if os.path.basename(apiFile).startswith("Ui_"): |
245 # it is a forms source file, extract public attributes |
255 # it is a forms source file, extract public attributes |
246 # as well |
256 # as well |
247 apis.extend(self.__classesAttributesApi(module)) |
257 apis.extend(self.__classesAttributesApi(module)) |
248 |
258 |
249 basesDict = apiGenerator.genBases(True) |
259 basesDict = apiGenerator.genBases(True) |
250 for baseEntry in basesDict: |
260 for baseEntry in basesDict: |
251 if basesDict[baseEntry]: |
261 if basesDict[baseEntry]: |
252 bases.append("{0} {1}\n".format( |
262 bases.append( |
253 baseEntry, " ".join( |
263 "{0} {1}\n".format( |
254 sorted(basesDict[baseEntry])))) |
264 baseEntry, " ".join(sorted(basesDict[baseEntry])) |
|
265 ) |
|
266 ) |
255 else: |
267 else: |
256 with contextlib.suppress(OSError, UnicodeError): |
268 with contextlib.suppress(OSError, UnicodeError): |
257 apis = Utilities.readEncodedFile(apiFile)[0].splitlines(True) |
269 apis = Utilities.readEncodedFile(apiFile)[0].splitlines(True) |
258 with contextlib.suppress(OSError, UnicodeError): |
270 with contextlib.suppress(OSError, UnicodeError): |
259 basesFile = os.path.splitext(apiFile)[0] + ".bas" |
271 basesFile = os.path.splitext(apiFile)[0] + ".bas" |
260 if os.path.exists(basesFile): |
272 if os.path.exists(basesFile): |
261 bases = ( |
273 bases = Utilities.readEncodedFile(basesFile)[0].splitlines(True) |
262 Utilities.readEncodedFile(basesFile)[0] |
|
263 .splitlines(True) |
|
264 ) |
|
265 language = None |
274 language = None |
266 |
275 |
267 if len(apis) > 0: |
276 if len(apis) > 0: |
268 self.__storeApis(apis, bases, apiFile, language) |
277 self.__storeApis(apis, bases, apiFile, language) |
269 else: |
278 else: |
270 # just store file info to avoid rereading it every time |
279 # just store file info to avoid rereading it every time |
271 self.__storeFileInfoOnly(apiFile) |
280 self.__storeFileInfoOnly(apiFile) |
272 |
281 |
273 def __storeFileInfoOnly(self, apiFile): |
282 def __storeFileInfoOnly(self, apiFile): |
274 """ |
283 """ |
275 Private method to store file info only. |
284 Private method to store file info only. |
276 |
285 |
277 Doing this avoids rereading the file whenever the API is initialized |
286 Doing this avoids rereading the file whenever the API is initialized |
278 in case the given file doesn't contain API data. |
287 in case the given file doesn't contain API data. |
279 |
288 |
280 @param apiFile file name of the API file |
289 @param apiFile file name of the API file |
281 @type str |
290 @type str |
282 """ |
291 """ |
283 db = QSqlDatabase.database(self.__connectionName) |
292 db = QSqlDatabase.database(self.__connectionName) |
284 db.transaction() |
293 db.transaction() |
475 db.commit() |
484 db.commit() |
476 |
485 |
477 def __getApiFiles(self): |
486 def __getApiFiles(self): |
478 """ |
487 """ |
479 Private method to get a list of API files loaded into the database. |
488 Private method to get a list of API files loaded into the database. |
480 |
489 |
481 @return list of API filenames |
490 @return list of API filenames |
482 @rtype list of str |
491 @rtype list of str |
483 """ |
492 """ |
484 apiFiles = [] |
493 apiFiles = [] |
485 |
494 |
486 db = QSqlDatabase.database(self.__connectionName) |
495 db = QSqlDatabase.database(self.__connectionName) |
487 db.transaction() |
496 db.transaction() |
488 try: |
497 try: |
489 query = QSqlQuery(db) |
498 query = QSqlQuery(db) |
490 query.exec(self.api_files_stmt) |
499 query.exec(self.api_files_stmt) |
491 while query.next(): # __IGNORE_WARNING_M513__ |
500 while query.next(): # __IGNORE_WARNING_M513__ |
492 apiFiles.append(query.value(0)) |
501 apiFiles.append(query.value(0)) |
493 finally: |
502 finally: |
494 query.finish() |
503 query.finish() |
495 del query |
504 del query |
496 db.commit() |
505 db.commit() |
497 |
506 |
498 return apiFiles |
507 return apiFiles |
499 |
508 |
500 def run(self): |
509 def run(self): |
501 """ |
510 """ |
502 Public method to perform the threads work. |
511 Public method to perform the threads work. |
503 """ |
512 """ |
504 self.processing.emit(WorkerStatusStarted, "") |
513 self.processing.emit(WorkerStatusStarted, "") |
505 |
514 |
506 if QSqlDatabase.contains(self.__connectionName): |
515 if QSqlDatabase.contains(self.__connectionName): |
507 QSqlDatabase.removeDatabase(self.__connectionName) |
516 QSqlDatabase.removeDatabase(self.__connectionName) |
508 |
517 |
509 db = QSqlDatabase.addDatabase("QSQLITE", self.__connectionName) |
518 db = QSqlDatabase.addDatabase("QSQLITE", self.__connectionName) |
510 db.setDatabaseName(self.__databaseName) |
519 db.setDatabaseName(self.__databaseName) |
511 db.open() |
520 db.open() |
512 |
521 |
513 if db.isValid() and db.isOpen(): |
522 if db.isValid() and db.isOpen(): |
514 # step 1: remove API files not wanted any longer |
523 # step 1: remove API files not wanted any longer |
515 if not self.__refresh: |
524 if not self.__refresh: |
516 loadedApiFiles = self.__getApiFiles() |
525 loadedApiFiles = self.__getApiFiles() |
517 for apiFile in loadedApiFiles: |
526 for apiFile in loadedApiFiles: |
518 if not self.__aborted and apiFile not in self.__apiFiles: |
527 if not self.__aborted and apiFile not in self.__apiFiles: |
519 self.__deleteApiFile(apiFile) |
528 self.__deleteApiFile(apiFile) |
520 |
529 |
521 # step 2: (re-)load api files |
530 # step 2: (re-)load api files |
522 for apiFile in self.__apiFiles: |
531 for apiFile in self.__apiFiles: |
523 if not self.__aborted: |
532 if not self.__aborted: |
524 self.__loadApiFileIfNewer(apiFile) |
533 self.__loadApiFileIfNewer(apiFile) |
525 |
534 |
526 db.close() |
535 db.close() |
527 |
536 |
528 if self.__aborted: |
537 if self.__aborted: |
529 self.processing.emit(WorkerStatusAborted, "") |
538 self.processing.emit(WorkerStatusAborted, "") |
530 else: |
539 else: |
531 self.processing.emit(WorkerStatusFinished, "") |
540 self.processing.emit(WorkerStatusFinished, "") |
532 |
541 |
533 |
542 |
534 class DbAPIs(QObject): |
543 class DbAPIs(QObject): |
535 """ |
544 """ |
536 Class implementing an API storage entity. |
545 Class implementing an API storage entity. |
537 |
546 |
538 @signal apiPreparationStatus(language, status, file) emitted to indicate |
547 @signal apiPreparationStatus(language, status, file) emitted to indicate |
539 the API preparation status for a language |
548 the API preparation status for a language |
540 """ |
549 """ |
|
550 |
541 apiPreparationStatus = pyqtSignal(str, int, str) |
551 apiPreparationStatus = pyqtSignal(str, int, str) |
542 |
552 |
543 DB_VERSION = 4 |
553 DB_VERSION = 4 |
544 |
554 |
545 create_mgmt_stmt = """ |
555 create_mgmt_stmt = """ |
546 CREATE TABLE mgmt |
556 CREATE TABLE mgmt |
547 (format INTEGER) |
557 (format INTEGER) |
548 """ |
558 """ |
549 drop_mgmt_stmt = """DROP TABLE IF EXISTS mgmt""" |
559 drop_mgmt_stmt = """DROP TABLE IF EXISTS mgmt""" |
550 |
560 |
551 create_api_stmt = """ |
561 create_api_stmt = """ |
552 CREATE TABLE api |
562 CREATE TABLE api |
553 (acWord TEXT, |
563 (acWord TEXT, |
554 context TEXT, |
564 context TEXT, |
555 fullContext TEXT, |
565 fullContext TEXT, |
654 QObject.__init__(self, parent) |
664 QObject.__init__(self, parent) |
655 if projectType: |
665 if projectType: |
656 self.setObjectName("DbAPIs_{0}_{1}".format(language, projectType)) |
666 self.setObjectName("DbAPIs_{0}_{1}".format(language, projectType)) |
657 else: |
667 else: |
658 self.setObjectName("DbAPIs_{0}".format(language)) |
668 self.setObjectName("DbAPIs_{0}".format(language)) |
659 |
669 |
660 self.__inPreparation = False |
670 self.__inPreparation = False |
661 self.__worker = None |
671 self.__worker = None |
662 self.__workerQueue = [] |
672 self.__workerQueue = [] |
663 self.__opened = False |
673 self.__opened = False |
664 |
674 |
665 self.__projectType = projectType |
675 self.__projectType = projectType |
666 self.__language = language |
676 self.__language = language |
667 |
677 |
668 if self.__projectType: |
678 if self.__projectType: |
669 self.__connectionName = "{0}_{1}".format( |
679 self.__connectionName = "{0}_{1}".format( |
670 self.__language, self.__projectType) |
680 self.__language, self.__projectType |
|
681 ) |
671 else: |
682 else: |
672 self.__connectionName = self.__language |
683 self.__connectionName = self.__language |
673 |
684 |
674 if self.__language == ApisNameProject: |
685 if self.__language == ApisNameProject: |
675 self.__initAsProject() |
686 self.__initAsProject() |
676 else: |
687 else: |
677 self.__initAsLanguage() |
688 self.__initAsLanguage() |
678 |
689 |
679 def __initAsProject(self): |
690 def __initAsProject(self): |
680 """ |
691 """ |
681 Private method to initialize as a project API object. |
692 Private method to initialize as a project API object. |
682 """ |
693 """ |
683 self.__lexer = None |
694 self.__lexer = None |
684 |
695 |
685 self.__project = ericApp().getObject("Project") |
696 self.__project = ericApp().getObject("Project") |
686 self.__project.projectOpened.connect(self.__projectOpened) |
697 self.__project.projectOpened.connect(self.__projectOpened) |
687 self.__project.newProject.connect(self.__projectOpened) |
698 self.__project.newProject.connect(self.__projectOpened) |
688 self.__project.projectClosed.connect(self.__projectClosed) |
699 self.__project.projectClosed.connect(self.__projectClosed) |
689 self.__project.projectFormCompiled.connect(self.__projectFormCompiled) |
700 self.__project.projectFormCompiled.connect(self.__projectFormCompiled) |
690 self.__project.projectChanged.connect(self.__projectChanged) |
701 self.__project.projectChanged.connect(self.__projectChanged) |
691 |
702 |
692 if self.__project.isOpen(): |
703 if self.__project.isOpen(): |
693 self.__projectOpened() |
704 self.__projectOpened() |
694 |
705 |
695 def __initAsLanguage(self): |
706 def __initAsLanguage(self): |
696 """ |
707 """ |
697 Private method to initialize as a language API object. |
708 Private method to initialize as a language API object. |
698 """ |
709 """ |
699 if self.__language == "Python3": |
710 if self.__language == "Python3": |
701 else: |
712 else: |
702 self.__discardFirst = [] |
713 self.__discardFirst = [] |
703 self.__lexer = QScintilla.Lexers.getLexer(self.__language) |
714 self.__lexer = QScintilla.Lexers.getLexer(self.__language) |
704 try: |
715 try: |
705 self.__apifiles = Preferences.getEditorAPI( |
716 self.__apifiles = Preferences.getEditorAPI( |
706 self.__language, projectType=self.__projectType) |
717 self.__language, projectType=self.__projectType |
|
718 ) |
707 except TypeError: |
719 except TypeError: |
708 # older interface |
720 # older interface |
709 self.__apifiles = Preferences.getEditorAPI(self.__language) |
721 self.__apifiles = Preferences.getEditorAPI(self.__language) |
710 self.__apifiles.sort() |
722 self.__apifiles.sort() |
711 if self.__lexer is not None: |
723 if self.__lexer is not None: |
712 self.__openAPIs() |
724 self.__openAPIs() |
713 |
725 |
714 def _apiDbName(self): |
726 def _apiDbName(self): |
715 """ |
727 """ |
716 Protected method to determine the name of the database file. |
728 Protected method to determine the name of the database file. |
717 |
729 |
718 @return name of the database file |
730 @return name of the database file |
719 @rtype str |
731 @rtype str |
720 """ |
732 """ |
721 if self.__language == ApisNameProject: |
733 if self.__language == ApisNameProject: |
722 return os.path.join(self.__project.getProjectManagementDir(), |
734 return os.path.join( |
723 "project-apis.db") |
735 self.__project.getProjectManagementDir(), "project-apis.db" |
|
736 ) |
724 else: |
737 else: |
725 apisDir = os.path.join(Globals.getConfigDir(), "APIs") |
738 apisDir = os.path.join(Globals.getConfigDir(), "APIs") |
726 if not os.path.exists(apisDir): |
739 if not os.path.exists(apisDir): |
727 os.makedirs(apisDir) |
740 os.makedirs(apisDir) |
728 if self.__projectType: |
741 if self.__projectType: |
729 filename = "{0}_{1}-api.db".format(self.__language, |
742 filename = "{0}_{1}-api.db".format(self.__language, self.__projectType) |
730 self.__projectType) |
|
731 else: |
743 else: |
732 filename = "{0}-api.db".format(self.__language) |
744 filename = "{0}-api.db".format(self.__language) |
733 return os.path.join(apisDir, filename) |
745 return os.path.join(apisDir, filename) |
734 |
746 |
735 def close(self): |
747 def close(self): |
736 """ |
748 """ |
737 Public method to close the database. |
749 Public method to close the database. |
738 """ |
750 """ |
739 self.__workerQueue = [] |
751 self.__workerQueue = [] |
740 if self.__worker is not None: |
752 if self.__worker is not None: |
741 self.__worker.abort() |
753 self.__worker.abort() |
742 if self.__worker is not None: |
754 if self.__worker is not None: |
743 self.__worker.wait(5000) |
755 self.__worker.wait(5000) |
744 if ( |
756 if self.__worker is not None and not self.__worker.isFinished(): |
745 self.__worker is not None and |
|
746 not self.__worker.isFinished() |
|
747 ): |
|
748 self.__worker.terminate() |
757 self.__worker.terminate() |
749 if self.__worker is not None: |
758 if self.__worker is not None: |
750 self.__worker.wait(5000) |
759 self.__worker.wait(5000) |
751 |
760 |
752 if QSqlDatabase and QSqlDatabase.database( |
761 if QSqlDatabase and QSqlDatabase.database(self.__connectionName).isOpen(): |
753 self.__connectionName).isOpen(): |
|
754 QSqlDatabase.database(self.__connectionName).close() |
762 QSqlDatabase.database(self.__connectionName).close() |
755 QSqlDatabase.removeDatabase(self.__connectionName) |
763 QSqlDatabase.removeDatabase(self.__connectionName) |
756 |
764 |
757 self.__opened = False |
765 self.__opened = False |
758 |
766 |
759 def __openApiDb(self): |
767 def __openApiDb(self): |
760 """ |
768 """ |
761 Private method to open the API database. |
769 Private method to open the API database. |
762 |
770 |
763 @return flag indicating the database status |
771 @return flag indicating the database status |
764 @rtype bool |
772 @rtype bool |
765 """ |
773 """ |
766 db = QSqlDatabase.database(self.__connectionName, False) |
774 db = QSqlDatabase.database(self.__connectionName, False) |
767 if not db.isValid(): |
775 if not db.isValid(): |
768 # the database connection is a new one |
776 # the database connection is a new one |
769 db = QSqlDatabase.addDatabase("QSQLITE", self.__connectionName) |
777 db = QSqlDatabase.addDatabase("QSQLITE", self.__connectionName) |
770 dbName = self._apiDbName() |
778 dbName = self._apiDbName() |
771 if ( |
779 if self.__language == ApisNameProject and not os.path.exists( |
772 self.__language == ApisNameProject and |
780 self.__project.getProjectManagementDir() |
773 not os.path.exists(self.__project.getProjectManagementDir()) |
|
774 ): |
781 ): |
775 opened = False |
782 opened = False |
776 else: |
783 else: |
777 db.setDatabaseName(dbName) |
784 db.setDatabaseName(dbName) |
778 opened = db.open() |
785 opened = db.open() |
779 if not opened: |
786 if not opened: |
780 QSqlDatabase.removeDatabase(self.__connectionName) |
787 QSqlDatabase.removeDatabase(self.__connectionName) |
781 else: |
788 else: |
782 opened = True |
789 opened = True |
783 return opened |
790 return opened |
784 |
791 |
785 def __createApiDB(self): |
792 def __createApiDB(self): |
786 """ |
793 """ |
787 Private method to create an API database. |
794 Private method to create an API database. |
788 """ |
795 """ |
789 db = QSqlDatabase.database(self.__connectionName) |
796 db = QSqlDatabase.database(self.__connectionName) |
885 key 'context' contains the context and |
892 key 'context' contains the context and |
886 key 'pictureId' contains the ID of the icon to be shown) |
893 key 'pictureId' contains the ID of the icon to be shown) |
887 @rtype list of dict |
894 @rtype list of dict |
888 """ |
895 """ |
889 completions = [] |
896 completions = [] |
890 |
897 |
891 db = QSqlDatabase.database(self.__connectionName) |
898 db = QSqlDatabase.database(self.__connectionName) |
892 if db.isOpen() and not self.__inPreparation: |
899 if db.isOpen() and not self.__inPreparation: |
893 db.transaction() |
900 db.transaction() |
894 try: |
901 try: |
895 query = None |
902 query = None |
896 |
903 |
897 if start is not None and context is not None: |
904 if start is not None and context is not None: |
898 query = QSqlQuery(db) |
905 query = QSqlQuery(db) |
899 query.prepare(self.ac_context_word_stmt) |
906 query.prepare(self.ac_context_word_stmt) |
900 query.bindValue(":acWord", start + '*') |
907 query.bindValue(":acWord", start + "*") |
901 query.bindValue(":context", context) |
908 query.bindValue(":context", context) |
902 elif start is not None: |
909 elif start is not None: |
903 query = QSqlQuery(db) |
910 query = QSqlQuery(db) |
904 query.prepare(self.ac_stmt) |
911 query.prepare(self.ac_stmt) |
905 query.bindValue(":acWord", start + '*') |
912 query.bindValue(":acWord", start + "*") |
906 elif context is not None: |
913 elif context is not None: |
907 query = QSqlQuery(db) |
914 query = QSqlQuery(db) |
908 query.prepare(self.ac_context_stmt) |
915 query.prepare(self.ac_context_stmt) |
909 query.bindValue(":context", context) |
916 query.bindValue(":context", context) |
910 |
917 |
911 if query is not None: |
918 if query is not None: |
912 query.exec() |
919 query.exec() |
913 while query.next(): # __IGNORE_WARNING_M513__ |
920 while query.next(): # __IGNORE_WARNING_M513__ |
914 completions.append({"completion": query.value(0), |
921 completions.append( |
915 "context": query.value(1), |
922 { |
916 "pictureId": query.value(2)}) |
923 "completion": query.value(0), |
|
924 "context": query.value(1), |
|
925 "pictureId": query.value(2), |
|
926 } |
|
927 ) |
917 query.finish() |
928 query.finish() |
918 del query |
929 del query |
919 finally: |
930 finally: |
920 db.commit() |
931 db.commit() |
921 |
932 |
922 if followHierarchy: |
933 if followHierarchy: |
923 query = QSqlQuery(db) |
934 query = QSqlQuery(db) |
924 query.prepare(self.bases_stmt) |
935 query.prepare(self.bases_stmt) |
925 query.bindValue(":class", context) |
936 query.bindValue(":class", context) |
926 query.exec() |
937 query.exec() |
927 if query.next(): # __IGNORE_WARNING_M513__ |
938 if query.next(): # __IGNORE_WARNING_M513__ |
928 bases = query.value(0).split() |
939 bases = query.value(0).split() |
929 else: |
940 else: |
930 bases = [] |
941 bases = [] |
931 for base in bases: |
942 for base in bases: |
932 completions.extend(self.getCompletions(start, base, |
943 completions.extend( |
933 followHierarchy=True)) |
944 self.getCompletions(start, base, followHierarchy=True) |
|
945 ) |
934 query.finish() |
946 query.finish() |
935 del query |
947 del query |
936 |
948 |
937 return completions |
949 return completions |
938 |
950 |
939 def getCalltips(self, acWord, commas, context=None, fullContext=None, |
951 def getCalltips( |
940 showContext=True, followHierarchy=False): |
952 self, |
|
953 acWord, |
|
954 commas, |
|
955 context=None, |
|
956 fullContext=None, |
|
957 showContext=True, |
|
958 followHierarchy=False, |
|
959 ): |
941 """ |
960 """ |
942 Public method to determine the calltips. |
961 Public method to determine the calltips. |
943 |
962 |
944 @param acWord function to get calltips for |
963 @param acWord function to get calltips for |
945 @type str |
964 @type str |
946 @param commas minimum number of commas contained in the calltip |
965 @param commas minimum number of commas contained in the calltip |
947 @type int |
966 @type int |
948 @param context string giving the context (e.g. classname) |
967 @param context string giving the context (e.g. classname) |
988 for discard in self.__discardFirst: |
1007 for discard in self.__discardFirst: |
989 sig = sig.replace(discard, "", 1) |
1008 sig = sig.replace(discard, "", 1) |
990 sig = sig.strip(", \t\r\n") |
1009 sig = sig.strip(", \t\r\n") |
991 if self.__enoughCommas(sig, commas): |
1010 if self.__enoughCommas(sig, commas): |
992 if showContext: |
1011 if showContext: |
993 calltips.append("{0}{1}{2}{3}".format( |
1012 calltips.append( |
994 fullCtx, |
1013 "{0}{1}{2}{3}".format( |
995 contextSeparator if fullCtx else "", |
1014 fullCtx, |
996 word, sig)) |
1015 contextSeparator if fullCtx else "", |
|
1016 word, |
|
1017 sig, |
|
1018 ) |
|
1019 ) |
997 else: |
1020 else: |
998 calltips.append("{0}{1}".format(word, sig)) |
1021 calltips.append("{0}{1}".format(word, sig)) |
999 query.finish() |
1022 query.finish() |
1000 del query |
1023 del query |
1001 finally: |
1024 finally: |
1002 db.commit() |
1025 db.commit() |
1003 |
1026 |
1004 if followHierarchy: |
1027 if followHierarchy: |
1005 query = QSqlQuery(db) |
1028 query = QSqlQuery(db) |
1006 query.prepare(self.bases_stmt) |
1029 query.prepare(self.bases_stmt) |
1007 query.bindValue(":class", context) |
1030 query.bindValue(":class", context) |
1008 query.exec() |
1031 query.exec() |
1009 if query.next(): # __IGNORE_WARNING_M513__ |
1032 if query.next(): # __IGNORE_WARNING_M513__ |
1010 bases = query.value(0).split() |
1033 bases = query.value(0).split() |
1011 else: |
1034 else: |
1012 bases = [] |
1035 bases = [] |
1013 for base in bases: |
1036 for base in bases: |
1014 calltips.extend(self.getCalltips( |
1037 calltips.extend( |
1015 acWord, commas, context=base, showContext=showContext, |
1038 self.getCalltips( |
1016 followHierarchy=True)) |
1039 acWord, |
|
1040 commas, |
|
1041 context=base, |
|
1042 showContext=showContext, |
|
1043 followHierarchy=True, |
|
1044 ) |
|
1045 ) |
1017 query.finish() |
1046 query.finish() |
1018 del query |
1047 del query |
1019 |
1048 |
1020 if context and len(calltips) == 0 and not followHierarchy: |
1049 if context and len(calltips) == 0 and not followHierarchy: |
1021 # nothing found, try without a context |
1050 # nothing found, try without a context |
1022 calltips = self.getCalltips( |
1051 calltips = self.getCalltips(acWord, commas, showContext=showContext) |
1023 acWord, commas, showContext=showContext) |
1052 |
1024 |
|
1025 return calltips |
1053 return calltips |
1026 |
1054 |
1027 def __enoughCommas(self, s, commas): |
1055 def __enoughCommas(self, s, commas): |
1028 """ |
1056 """ |
1029 Private method to determine, if the given string contains enough |
1057 Private method to determine, if the given string contains enough |
1030 commas. |
1058 commas. |
1031 |
1059 |
1032 @param s string to check |
1060 @param s string to check |
1033 @type str |
1061 @type str |
1034 @param commas number of commas to check for |
1062 @param commas number of commas to check for |
1035 @type int |
1063 @type int |
1036 @return flag indicating, that there are enough commas |
1064 @return flag indicating, that there are enough commas |
1037 @rtype bool |
1065 @rtype bool |
1038 """ |
1066 """ |
1039 end = s.find(')') |
1067 end = s.find(")") |
1040 |
1068 |
1041 if end < 0: |
1069 if end < 0: |
1042 return False |
1070 return False |
1043 |
1071 |
1044 w = s[:end] |
1072 w = s[:end] |
1045 return w.count(',') >= commas |
1073 return w.count(",") >= commas |
1046 |
1074 |
1047 def __openAPIs(self): |
1075 def __openAPIs(self): |
1048 """ |
1076 """ |
1049 Private method to open the API database. |
1077 Private method to open the API database. |
1050 """ |
1078 """ |
1051 self.__opened = self.__openApiDb() |
1079 self.__opened = self.__openApiDb() |
1052 if self.__opened: |
1080 if self.__opened: |
1053 if not self.__isPrepared(): |
1081 if not self.__isPrepared(): |
1054 self.__createApiDB() |
1082 self.__createApiDB() |
1055 |
1083 |
1056 # prepare the database if neccessary |
1084 # prepare the database if neccessary |
1057 self.prepareAPIs() |
1085 self.prepareAPIs() |
1058 |
1086 |
1059 def __getProjectFormSources(self, normalized=False): |
1087 def __getProjectFormSources(self, normalized=False): |
1060 """ |
1088 """ |
1061 Private method to get the source files for the project forms. |
1089 Private method to get the source files for the project forms. |
1062 |
1090 |
1063 @param normalized flag indicating a normalized filename is wanted |
1091 @param normalized flag indicating a normalized filename is wanted |
1064 @type bool |
1092 @type bool |
1065 @return list of project form sources |
1093 @return list of project form sources |
1066 @rtype list of str |
1094 @rtype list of str |
1067 """ |
1095 """ |
1068 if self.__project.getProjectLanguage() in ( |
1096 if self.__project.getProjectLanguage() in ("Python3", "MicroPython", "Cython"): |
1069 "Python3", "MicroPython", "Cython" |
|
1070 ): |
|
1071 sourceExt = ".py" |
1097 sourceExt = ".py" |
1072 elif self.__project.getProjectLanguage() == "Ruby": |
1098 elif self.__project.getProjectLanguage() == "Ruby": |
1073 sourceExt = ".rb" |
1099 sourceExt = ".rb" |
1074 else: |
1100 else: |
1075 return [] |
1101 return [] |
1076 |
1102 |
1077 formsSources = [] |
1103 formsSources = [] |
1078 forms = self.__project.getProjectFiles("FORMS") |
1104 forms = self.__project.getProjectFiles("FORMS") |
1079 for fn in forms: |
1105 for fn in forms: |
1080 ofn = os.path.splitext(fn)[0] |
1106 ofn = os.path.splitext(fn)[0] |
1081 dirname, filename = os.path.split(ofn) |
1107 dirname, filename = os.path.split(ofn) |
1082 formSource = os.path.join(dirname, "Ui_" + filename + sourceExt) |
1108 formSource = os.path.join(dirname, "Ui_" + filename + sourceExt) |
1083 if normalized: |
1109 if normalized: |
1084 formSource = os.path.join( |
1110 formSource = os.path.join(self.__project.getProjectPath(), formSource) |
1085 self.__project.getProjectPath(), formSource) |
|
1086 formsSources.append(formSource) |
1111 formsSources.append(formSource) |
1087 return formsSources |
1112 return formsSources |
1088 |
1113 |
1089 def prepareAPIs(self, rawList=None): |
1114 def prepareAPIs(self, rawList=None): |
1090 """ |
1115 """ |
1091 Public method to prepare the APIs if neccessary. |
1116 Public method to prepare the APIs if neccessary. |
1092 |
1117 |
1093 @param rawList list of raw API files |
1118 @param rawList list of raw API files |
1094 @type list of str |
1119 @type list of str |
1095 """ |
1120 """ |
1096 if self.__inPreparation: |
1121 if self.__inPreparation: |
1097 return |
1122 return |
1098 |
1123 |
1099 projectPath = "" |
1124 projectPath = "" |
1100 if rawList: |
1125 if rawList: |
1101 apiFiles = rawList[:] |
1126 apiFiles = rawList[:] |
1102 elif self.__language == ApisNameProject: |
1127 elif self.__language == ApisNameProject: |
1103 apiFiles = self.__project.getSources()[:] |
1128 apiFiles = self.__project.getSources()[:] |
1104 apiFiles.extend( |
1129 apiFiles.extend( |
1105 [f for f in self.__getProjectFormSources() if |
1130 [f for f in self.__getProjectFormSources() if f not in apiFiles] |
1106 f not in apiFiles]) |
1131 ) |
1107 projectPath = self.__project.getProjectPath() |
1132 projectPath = self.__project.getProjectPath() |
1108 projectType = "" |
1133 projectType = "" |
1109 else: |
1134 else: |
1110 apiFiles = Preferences.getEditorAPI( |
1135 apiFiles = Preferences.getEditorAPI( |
1111 self.__language, projectType=self.__projectType) |
1136 self.__language, projectType=self.__projectType |
|
1137 ) |
1112 projectType = self.__projectType |
1138 projectType = self.__projectType |
1113 self.__worker = DbAPIsWorker(self, self.__language, apiFiles, |
1139 self.__worker = DbAPIsWorker( |
1114 self._apiDbName(), projectPath, |
1140 self, |
1115 projectType=projectType) |
1141 self.__language, |
|
1142 apiFiles, |
|
1143 self._apiDbName(), |
|
1144 projectPath, |
|
1145 projectType=projectType, |
|
1146 ) |
1116 self.__worker.processing.connect( |
1147 self.__worker.processing.connect( |
1117 self.__processingStatus, Qt.ConnectionType.QueuedConnection) |
1148 self.__processingStatus, Qt.ConnectionType.QueuedConnection |
|
1149 ) |
1118 self.__worker.start() |
1150 self.__worker.start() |
1119 |
1151 |
1120 def __processQueue(self): |
1152 def __processQueue(self): |
1121 """ |
1153 """ |
1122 Private slot to process the queue of files to load. |
1154 Private slot to process the queue of files to load. |
1123 """ |
1155 """ |
1124 if self.__worker is not None and self.__worker.isFinished(): |
1156 if self.__worker is not None and self.__worker.isFinished(): |
1125 self.__worker.deleteLater() |
1157 self.__worker.deleteLater() |
1126 self.__worker = None |
1158 self.__worker = None |
1127 |
1159 |
1128 if self.__worker is None and len(self.__workerQueue) > 0: |
1160 if self.__worker is None and len(self.__workerQueue) > 0: |
1129 apiFiles = [self.__workerQueue.pop(0)] |
1161 apiFiles = [self.__workerQueue.pop(0)] |
1130 if self.__language == ApisNameProject: |
1162 if self.__language == ApisNameProject: |
1131 projectPath = self.__project.getProjectPath() |
1163 projectPath = self.__project.getProjectPath() |
1132 apiFiles = [apiFiles[0].replace(projectPath + os.sep, "")] |
1164 apiFiles = [apiFiles[0].replace(projectPath + os.sep, "")] |
1133 projectType = "" |
1165 projectType = "" |
1134 else: |
1166 else: |
1135 projectPath = "" |
1167 projectPath = "" |
1136 projectType = self.__projectType |
1168 projectType = self.__projectType |
1137 self.__worker = DbAPIsWorker(self, self.__language, apiFiles, |
1169 self.__worker = DbAPIsWorker( |
1138 self._apiDbName(), projectPath, |
1170 self, |
1139 projectType=projectType, refresh=True) |
1171 self.__language, |
|
1172 apiFiles, |
|
1173 self._apiDbName(), |
|
1174 projectPath, |
|
1175 projectType=projectType, |
|
1176 refresh=True, |
|
1177 ) |
1140 self.__worker.processing.connect( |
1178 self.__worker.processing.connect( |
1141 self.__processingStatus, Qt.ConnectionType.QueuedConnection) |
1179 self.__processingStatus, Qt.ConnectionType.QueuedConnection |
|
1180 ) |
1142 self.__worker.start() |
1181 self.__worker.start() |
1143 |
1182 |
1144 def getLexer(self): |
1183 def getLexer(self): |
1145 """ |
1184 """ |
1146 Public method to return a reference to our lexer object. |
1185 Public method to return a reference to our lexer object. |
1147 |
1186 |
1148 @return reference to the lexer object |
1187 @return reference to the lexer object |
1149 @rtype Lexer |
1188 @rtype Lexer |
1150 """ |
1189 """ |
1151 return self.__lexer |
1190 return self.__lexer |
1152 |
1191 |
1153 def autoCompletionWordSeparators(self): |
1192 def autoCompletionWordSeparators(self): |
1154 """ |
1193 """ |
1155 Public method to get the word separator characters. |
1194 Public method to get the word separator characters. |
1156 |
1195 |
1157 @return word separator characters |
1196 @return word separator characters |
1158 @rtype list of str |
1197 @rtype list of str |
1159 """ |
1198 """ |
1160 if self.__lexer: |
1199 if self.__lexer: |
1161 return self.__lexer.autoCompletionWordSeparators() |
1200 return self.__lexer.autoCompletionWordSeparators() |
1162 return None |
1201 return None |
1163 |
1202 |
1164 def __processingStatus(self, status, filename): |
1203 def __processingStatus(self, status, filename): |
1165 """ |
1204 """ |
1166 Private slot handling the processing signal of the API preparation |
1205 Private slot handling the processing signal of the API preparation |
1167 thread. |
1206 thread. |
1168 |
1207 |
1169 @param status preparation status (one of WorkerStatus...) |
1208 @param status preparation status (one of WorkerStatus...) |
1170 @type int |
1209 @type int |
1171 @param filename name of the file being processed |
1210 @param filename name of the file being processed |
1172 @type str |
1211 @type str |
1173 """ |
1212 """ |
1174 if status == WorkerStatusStarted: |
1213 if status == WorkerStatusStarted: |
1175 self.__inPreparation = True |
1214 self.__inPreparation = True |
1176 self.apiPreparationStatus.emit( |
1215 self.apiPreparationStatus.emit(self.__language, WorkerStatusStarted, "") |
1177 self.__language, WorkerStatusStarted, "") |
|
1178 elif status == WorkerStatusFinished: |
1216 elif status == WorkerStatusFinished: |
1179 self.__inPreparation = False |
1217 self.__inPreparation = False |
1180 self.apiPreparationStatus.emit( |
1218 self.apiPreparationStatus.emit(self.__language, WorkerStatusFinished, "") |
1181 self.__language, WorkerStatusFinished, "") |
|
1182 QTimer.singleShot(0, self.__processQueue) |
1219 QTimer.singleShot(0, self.__processQueue) |
1183 elif status == WorkerStatusAborted: |
1220 elif status == WorkerStatusAborted: |
1184 self.__inPreparation = False |
1221 self.__inPreparation = False |
1185 self.apiPreparationStatus.emit( |
1222 self.apiPreparationStatus.emit(self.__language, WorkerStatusAborted, "") |
1186 self.__language, WorkerStatusAborted, "") |
|
1187 QTimer.singleShot(0, self.__processQueue) |
1223 QTimer.singleShot(0, self.__processQueue) |
1188 elif status == WorkerStatusFile: |
1224 elif status == WorkerStatusFile: |
1189 self.apiPreparationStatus.emit( |
1225 self.apiPreparationStatus.emit(self.__language, WorkerStatusFile, filename) |
1190 self.__language, WorkerStatusFile, filename) |
1226 |
1191 |
|
1192 ######################################################## |
1227 ######################################################## |
1193 ## project related stuff below |
1228 ## project related stuff below |
1194 ######################################################## |
1229 ######################################################## |
1195 |
1230 |
1196 def __projectOpened(self): |
1231 def __projectOpened(self): |
1197 """ |
1232 """ |
1198 Private slot to perform actions after a project has been opened. |
1233 Private slot to perform actions after a project has been opened. |
1199 """ |
1234 """ |
1200 if self.__project.getProjectLanguage() in ( |
1235 if self.__project.getProjectLanguage() in ("Python3", "MicroPython", "Cython"): |
1201 "Python3", "MicroPython", "Cython" |
|
1202 ): |
|
1203 self.__discardFirst = ["self", "cls"] |
1236 self.__discardFirst = ["self", "cls"] |
1204 else: |
1237 else: |
1205 self.__discardFirst = [] |
1238 self.__discardFirst = [] |
1206 self.__lexer = QScintilla.Lexers.getLexer( |
1239 self.__lexer = QScintilla.Lexers.getLexer(self.__project.getProjectLanguage()) |
1207 self.__project.getProjectLanguage()) |
|
1208 self.__openAPIs() |
1240 self.__openAPIs() |
1209 |
1241 |
1210 def __projectClosed(self): |
1242 def __projectClosed(self): |
1211 """ |
1243 """ |
1212 Private slot to perform actions after a project has been closed. |
1244 Private slot to perform actions after a project has been closed. |
1213 """ |
1245 """ |
1214 self.close() |
1246 self.close() |
1215 |
1247 |
1216 def __projectFormCompiled(self, filename): |
1248 def __projectFormCompiled(self, filename): |
1217 """ |
1249 """ |
1218 Private slot to handle the projectFormCompiled signal. |
1250 Private slot to handle the projectFormCompiled signal. |
1219 |
1251 |
1220 @param filename name of the form file that was compiled |
1252 @param filename name of the form file that was compiled |
1221 @type str |
1253 @type str |
1222 """ |
1254 """ |
1223 self.__workerQueue.append(filename) |
1255 self.__workerQueue.append(filename) |
1224 self.__processQueue() |
1256 self.__processQueue() |
1225 |
1257 |
1226 def __projectChanged(self): |
1258 def __projectChanged(self): |
1227 """ |
1259 """ |
1228 Private slot to handle the projectChanged signal. |
1260 Private slot to handle the projectChanged signal. |
1229 """ |
1261 """ |
1230 if self.__opened: |
1262 if self.__opened: |
1231 self.__projectClosed() |
1263 self.__projectClosed() |
1232 self.__projectOpened() |
1264 self.__projectOpened() |
1233 |
1265 |
1234 def editorSaved(self, filename): |
1266 def editorSaved(self, filename): |
1235 """ |
1267 """ |
1236 Public slot to handle the editorSaved signal. |
1268 Public slot to handle the editorSaved signal. |
1237 |
1269 |
1238 @param filename name of the file that was saved |
1270 @param filename name of the file that was saved |
1239 @type str |
1271 @type str |
1240 """ |
1272 """ |
1241 if self.__project.isProjectSource(filename): |
1273 if self.__project.isProjectSource(filename): |
1242 self.__workerQueue.append(filename) |
1274 self.__workerQueue.append(filename) |
1289 """ |
1322 """ |
1290 try: |
1323 try: |
1291 return self.__apis[(language, projectType)] |
1324 return self.__apis[(language, projectType)] |
1292 except KeyError: |
1325 except KeyError: |
1293 if ( |
1326 if ( |
1294 language in QScintilla.Lexers.getSupportedApiLanguages() or |
1327 language in QScintilla.Lexers.getSupportedApiLanguages() |
1295 language == ApisNameProject |
1328 or language == ApisNameProject |
1296 ): |
1329 ): |
1297 # create the api object |
1330 # create the api object |
1298 api = DbAPIs(language, projectType=projectType) |
1331 api = DbAPIs(language, projectType=projectType) |
1299 api.apiPreparationStatus.connect(self.__apiPreparationStatus) |
1332 api.apiPreparationStatus.connect(self.__apiPreparationStatus) |
1300 self.__apis[(language, projectType)] = api |
1333 self.__apis[(language, projectType)] = api |
1301 return self.__apis[(language, projectType)] |
1334 return self.__apis[(language, projectType)] |
1302 else: |
1335 else: |
1303 return None |
1336 return None |
1304 |
1337 |
1305 def deactivate(self): |
1338 def deactivate(self): |
1306 """ |
1339 """ |
1307 Public method to perform actions upon deactivation. |
1340 Public method to perform actions upon deactivation. |
1308 """ |
1341 """ |
1309 for apiLang in self.__apis: |
1342 for apiLang in self.__apis: |
1310 self.__apis[apiLang].close() |
1343 self.__apis[apiLang].close() |
1311 self.__apis[apiLang].deleteLater() |
1344 self.__apis[apiLang].deleteLater() |
1312 self.__apis[apiLang] = None |
1345 self.__apis[apiLang] = None |
1313 |
1346 |
1314 def __showMessage(self, msg): |
1347 def __showMessage(self, msg): |
1315 """ |
1348 """ |
1316 Private message to show a message in the main windows status bar. |
1349 Private message to show a message in the main windows status bar. |
1317 |
1350 |
1318 @param msg message to be shown |
1351 @param msg message to be shown |
1319 @type str |
1352 @type str |
1320 """ |
1353 """ |
1321 if msg: |
1354 if msg: |
1322 self.__mw.statusBar().showMessage(msg, 2000) |
1355 self.__mw.statusBar().showMessage(msg, 2000) |
1323 |
1356 |
1324 def __apiPreparationStatus(self, language, status, filename): |
1357 def __apiPreparationStatus(self, language, status, filename): |
1325 """ |
1358 """ |
1326 Private slot handling the preparation status signal of an API object. |
1359 Private slot handling the preparation status signal of an API object. |
1327 |
1360 |
1328 @param language language of the API |
1361 @param language language of the API |
1329 @type str |
1362 @type str |
1330 @param status preparation status (one of WorkerStatus...) |
1363 @param status preparation status (one of WorkerStatus...) |
1331 @type int |
1364 @type int |
1332 @param filename name of the file being processed |
1365 @param filename name of the file being processed |
1333 @type str |
1366 @type str |
1334 """ |
1367 """ |
1335 if language == ApisNameProject: |
1368 if language == ApisNameProject: |
1336 language = self.tr("Project") |
1369 language = self.tr("Project") |
1337 |
1370 |
1338 if status == WorkerStatusStarted: |
1371 if status == WorkerStatusStarted: |
1339 self.__showMessage(self.tr( |
1372 self.__showMessage( |
1340 "Preparation of '{0}' APIs started.").format(language)) |
1373 self.tr("Preparation of '{0}' APIs started.").format(language) |
|
1374 ) |
1341 elif status == WorkerStatusFile: |
1375 elif status == WorkerStatusFile: |
1342 self.__showMessage(self.tr( |
1376 self.__showMessage( |
1343 "'{0}' APIs: Processing '{1}'").format( |
1377 self.tr("'{0}' APIs: Processing '{1}'").format( |
1344 language, os.path.basename(filename))) |
1378 language, os.path.basename(filename) |
|
1379 ) |
|
1380 ) |
1345 elif status == WorkerStatusFinished: |
1381 elif status == WorkerStatusFinished: |
1346 self.__showMessage(self.tr( |
1382 self.__showMessage( |
1347 "Preparation of '{0}' APIs finished.").format(language)) |
1383 self.tr("Preparation of '{0}' APIs finished.").format(language) |
|
1384 ) |
1348 elif status == WorkerStatusAborted: |
1385 elif status == WorkerStatusAborted: |
1349 self.__showMessage(self.tr( |
1386 self.__showMessage( |
1350 "Preparation of '{0}' APIs cancelled.").format(language)) |
1387 self.tr("Preparation of '{0}' APIs cancelled.").format(language) |
|
1388 ) |
|
1389 |
1351 |
1390 |
1352 # |
1391 # |
1353 # eflag: noqa = M523, M834, S608 |
1392 # eflag: noqa = M523, M834, S608 |