Beispiel #1
0
class APIs(QObject):
    """
    Class implementing an API storage entity.
    
    @signal apiPreparationFinished() emitted after the API preparation has
        finished
    @signal apiPreparationCancelled() emitted after the API preparation has
        been cancelled
    @signal apiPreparationStarted() emitted after the API preparation has
        started
    """
    apiPreparationFinished = pyqtSignal()
    apiPreparationCancelled = pyqtSignal()
    apiPreparationStarted = pyqtSignal()
    
    def __init__(self, language, forPreparation=False, parent=None):
        """
        Constructor
        
        @param language language of the APIs object (string)
        @param forPreparation flag indicating this object is just needed
            for a preparation process (boolean)
        @param parent reference to the parent object (QObject)
        """
        super(APIs, self).__init__(parent)
        self.setObjectName("APIs_{0}".format(language))
        
        self.__inPreparation = False
        self.__language = language
        self.__forPreparation = forPreparation
        self.__lexer = Lexers.getLexer(self.__language)
        self.__apifiles = Preferences.getEditorAPI(self.__language)
        self.__apifiles.sort()
        if self.__lexer is None:
            self.__apis = None
        else:
            self.__apis = QsciAPIs(self.__lexer)
            self.__apis.apiPreparationFinished.connect(
                self.__apiPreparationFinished)
            self.__apis.apiPreparationCancelled.connect(
                self.__apiPreparationCancelled)
            self.__apis.apiPreparationStarted.connect(
                self.__apiPreparationStarted)
            self.__loadAPIs()
        
    def __loadAPIs(self):
        """
        Private method to load the APIs.
        """
        if self.__apis.isPrepared():
            # load a prepared API file
            if not self.__forPreparation and \
                    Preferences.getEditor("AutoPrepareAPIs"):
                self.prepareAPIs()
            self.__apis.loadPrepared()
        else:
            # load the raw files and prepare the API file
            if not self.__forPreparation and \
                    Preferences.getEditor("AutoPrepareAPIs"):
                self.prepareAPIs(ondemand=True)
    
    def reloadAPIs(self):
        """
        Public method to reload the API information.
        """
        if not self.__forPreparation and \
                Preferences.getEditor("AutoPrepareAPIs"):
            self.prepareAPIs()
        self.__loadAPIs()
    
    def getQsciAPIs(self):
        """
        Public method to get a reference to QsciAPIs object.
        
        @return reference to the QsciAPIs object (QsciAPIs)
        """
        if not self.__forPreparation and \
                Preferences.getEditor("AutoPrepareAPIs"):
            self.prepareAPIs()
        return self.__apis
    
    def isEmpty(self):
        """
        Public method to check, if the object has API files configured.
        
        @return flag indicating no API files have been configured (boolean)
        """
        return len(self.__apifiles) == 0
    
    def __apiPreparationFinished(self):
        """
        Private method called to save an API, after it has been prepared.
        """
        self.__apis.savePrepared()
        self.__inPreparation = False
        self.apiPreparationFinished.emit()
    
    def __apiPreparationCancelled(self):
        """
        Private method called, after the API preparation process has been
        cancelled.
        """
        self.__inPreparation = False
        self.apiPreparationCancelled.emit()
    
    def __apiPreparationStarted(self):
        """
        Private method called, when the API preparation process started.
        """
        self.__inPreparation = True
        self.apiPreparationStarted.emit()
    
    def prepareAPIs(self, ondemand=False, rawList=None):
        """
        Public method to prepare the APIs if necessary.
        
        @keyparam ondemand flag indicating a requested preparation (boolean)
        @keyparam rawList list of raw API files (list of strings)
        """
        if self.__apis is None or self.__inPreparation:
            return
        
        needsPreparation = False
        if ondemand:
            needsPreparation = True
        else:
            # check, if a new preparation is necessary
            preparedAPIs = self.__defaultPreparedName()
            if preparedAPIs:
                preparedAPIsInfo = QFileInfo(preparedAPIs)
                if not preparedAPIsInfo.exists():
                    needsPreparation = True
                else:
                    preparedAPIsTime = preparedAPIsInfo.lastModified()
                    apifiles = sorted(
                        Preferences.getEditorAPI(self.__language))
                    if self.__apifiles != apifiles:
                        needsPreparation = True
                    for apifile in apifiles:
                        if QFileInfo(apifile).lastModified() > \
                                preparedAPIsTime:
                            needsPreparation = True
                            break
        
        if needsPreparation:
            # do the preparation
            self.__apis.clear()
            if rawList:
                apifiles = rawList
            else:
                apifiles = Preferences.getEditorAPI(self.__language)
            for apifile in apifiles:
                self.__apis.load(apifile)
            self.__apis.prepare()
            self.__apifiles = apifiles
    
    def cancelPreparation(self):
        """
        Public slot to cancel the APIs preparation.
        """
        self.__apis and self.__apis.cancelPreparation()
    
    def installedAPIFiles(self):
        """
        Public method to get a list of installed API files.
        
        @return list of installed API files (list of strings)
        """
        if self.__apis is not None:
            if Globals.isWindowsPlatform():
                qsciPath = os.path.join(
                    Globals.getPyQt5ModulesDirectory(), "qsci")
                if os.path.exists(qsciPath):
                    # it's the installer
                    if self.__lexer.lexerName() is not None:
                        apidir = os.path.join(qsciPath, "api",
                                              self.__lexer.lexerName())
                        fnames = []
                        filist = QDir(apidir).entryInfoList(
                            ["*.api"], QDir.Files, QDir.IgnoreCase)
                        for fi in filist:
                            fnames.append(fi.absoluteFilePath())
                        return fnames
                    else:
                        return []
            
            return self.__apis.installedAPIFiles()
        else:
            return []
    
    def __defaultPreparedName(self):
        """
        Private method returning the default name of a prepared API file.
        
        @return complete filename for the Prepared APIs file (string)
        """
        if self.__apis is not None:
            return self.__apis.defaultPreparedName()
        else:
            return ""
Beispiel #2
0
class APIs(QObject):
    """
    Class implementing an API storage entity.
    
    @signal apiPreparationFinished() emitted after the API preparation has
        finished
    @signal apiPreparationCancelled() emitted after the API preparation has
        been cancelled
    @signal apiPreparationStarted() emitted after the API preparation has
        started
    """
    apiPreparationFinished = pyqtSignal()
    apiPreparationCancelled = pyqtSignal()
    apiPreparationStarted = pyqtSignal()

    def __init__(self,
                 language,
                 projectType="",
                 forPreparation=False,
                 parent=None):
        """
        Constructor
        
        @param language language of the APIs object
        @type str
        @param projectType type of the project
        @type str
        @param forPreparation flag indicating this object is just needed
            for a preparation process
        @type bool
        @param parent reference to the parent object
        @type QObject
        """
        super(APIs, self).__init__(parent)
        if projectType:
            self.setObjectName("APIs_{0}_{1}".format(language, projectType))
        else:
            self.setObjectName("APIs_{0}".format(language))

        self.__inPreparation = False
        self.__language = language
        self.__projectType = projectType
        self.__forPreparation = forPreparation
        self.__lexer = Lexers.getLexer(self.__language)
        self.__apifiles = Preferences.getEditorAPI(self.__language,
                                                   self.__projectType)
        self.__apifiles.sort()
        if self.__lexer is None:
            self.__apis = None
        else:
            self.__apis = QsciAPIs(self.__lexer)
            self.__apis.apiPreparationFinished.connect(
                self.__apiPreparationFinished)
            self.__apis.apiPreparationCancelled.connect(
                self.__apiPreparationCancelled)
            self.__apis.apiPreparationStarted.connect(
                self.__apiPreparationStarted)
            self.__loadAPIs()

    def __loadAPIs(self):
        """
        Private method to load the APIs.
        """
        if self.__apis.isPrepared():
            # load a prepared API file
            if (not self.__forPreparation
                    and Preferences.getEditor("AutoPrepareAPIs")):
                self.prepareAPIs()
            self.__apis.loadPrepared(self.__preparedName())
        else:
            # load the raw files and prepare the API file
            if (not self.__forPreparation
                    and Preferences.getEditor("AutoPrepareAPIs")):
                self.prepareAPIs(ondemand=True)

    def reloadAPIs(self):
        """
        Public method to reload the API information.
        """
        if (not self.__forPreparation
                and Preferences.getEditor("AutoPrepareAPIs")):
            self.prepareAPIs()
        self.__loadAPIs()

    def getQsciAPIs(self):
        """
        Public method to get a reference to QsciAPIs object.
        
        @return reference to the QsciAPIs object (QsciAPIs)
        """
        if (not self.__forPreparation
                and Preferences.getEditor("AutoPrepareAPIs")):
            self.prepareAPIs()
        return self.__apis

    def isEmpty(self):
        """
        Public method to check, if the object has API files configured.
        
        @return flag indicating no API files have been configured (boolean)
        """
        return len(self.__apifiles) == 0

    def __apiPreparationFinished(self):
        """
        Private method called to save an API, after it has been prepared.
        """
        self.__apis.savePrepared(self.__preparedName())
        self.__inPreparation = False
        self.apiPreparationFinished.emit()

    def __apiPreparationCancelled(self):
        """
        Private method called, after the API preparation process has been
        cancelled.
        """
        self.__inPreparation = False
        self.apiPreparationCancelled.emit()

    def __apiPreparationStarted(self):
        """
        Private method called, when the API preparation process started.
        """
        self.__inPreparation = True
        self.apiPreparationStarted.emit()

    def prepareAPIs(self, ondemand=False, rawList=None):
        """
        Public method to prepare the APIs if necessary.
        
        @keyparam ondemand flag indicating a requested preparation (boolean)
        @keyparam rawList list of raw API files (list of strings)
        """
        if self.__apis is None or self.__inPreparation:
            return

        needsPreparation = False
        if ondemand:
            needsPreparation = True
        else:
            # check, if a new preparation is necessary
            preparedAPIs = self.__preparedName()
            if preparedAPIs:
                preparedAPIsInfo = QFileInfo(preparedAPIs)
                if not preparedAPIsInfo.exists():
                    needsPreparation = True
                else:
                    preparedAPIsTime = preparedAPIsInfo.lastModified()
                    apifiles = sorted(
                        Preferences.getEditorAPI(self.__language,
                                                 self.__projectType))
                    if self.__apifiles != apifiles:
                        needsPreparation = True
                    for apifile in apifiles:
                        if (QFileInfo(apifile).lastModified() >
                                preparedAPIsTime):
                            needsPreparation = True
                            break

        if needsPreparation:
            # do the preparation
            self.__apis.clear()
            if rawList:
                apifiles = rawList
            else:
                apifiles = Preferences.getEditorAPI(self.__language,
                                                    self.__projectType)
            for apifile in apifiles:
                self.__apis.load(apifile)
            self.__apis.prepare()
            self.__apifiles = apifiles

    def cancelPreparation(self):
        """
        Public slot to cancel the APIs preparation.
        """
        self.__apis and self.__apis.cancelPreparation()

    def installedAPIFiles(self):
        """
        Public method to get a list of installed API files.
        
        @return list of installed API files (list of strings)
        """
        if self.__apis is not None:
            if Globals.isWindowsPlatform():
                qsciPath = os.path.join(Globals.getPyQt5ModulesDirectory(),
                                        "qsci")
                if os.path.exists(qsciPath):
                    # it's the installer
                    if self.__lexer.lexerName() is not None:
                        apidir = os.path.join(qsciPath, "api",
                                              self.__lexer.lexerName())
                        fnames = []
                        filist = QDir(apidir).entryInfoList(["*.api"],
                                                            QDir.Files,
                                                            QDir.IgnoreCase)
                        for fi in filist:
                            fnames.append(fi.absoluteFilePath())
                        return fnames
                    else:
                        return []

            return self.__apis.installedAPIFiles()
        else:
            return []

    def __preparedName(self):
        """
        Private method returning the default name of a prepared API file.
        
        @return complete filename for the Prepared APIs file (string)
        """
        apisDir = os.path.join(Globals.getConfigDir(), "APIs")
        if self.__apis is not None:
            if self.__projectType:
                filename = "{0}_{1}.pap".format(self.__language,
                                                self.__projectType)
            else:
                filename = "{0}.pap".format(self.__language)
            return os.path.join(apisDir, filename)
        else:
            return ""
Beispiel #3
0
 def _setup_editor(self):
     # set default editor settings
     self.editor.setFont(DEFAULT_FONT)
     self.editor.setMarginsFont(LINENO_FONT)
     self.editor.setBraceMatching(QsciScintilla.SloppyBraceMatch)
     self.editor.setCaretLineVisible(True)
     self.editor.setCaretForegroundColor(QColor('#000000'))
     self.editor.setCaretLineBackgroundColor(QColor('#c4e8fd'))
     self.editor.setAutoIndent(True)
     self.editor.setTabIndents(True)
     # tab width
     self.editor.setTabWidth(4)
     #  line numbers (margin 0)
     self.editor.setMarginLineNumbers(0, True)
     self.editor.setMarginWidth(0, '00000')
     # hide symbol margin
     self.editor.setMarginWidth(1, 0)
     # folding
     self.editor.setFolding(1)
     # indentation guides
     self.editor.setIndentationGuides(True)
     # wrap mode
     wrap_lines = False
     self.editor.setWrapMode(wrap_lines)
     if wrap_lines:
         # remove horizontal scrollBar
         self.editor.SendScintilla(SCI.SCI_SETHSCROLLBAR, 0, 0)
     lexer = QsciLexerPython(self)
     # apply default settings to lexer
     lexer.setDefaultFont(DEFAULT_FONT)
     lexer.setFont(DEFAULT_FONT)
     # margins
     lexer.setPaper(MARGIN_BGCOLOR, SCI.STYLE_LINENUMBER)
     lexer.setColor(MARGIN_COLOR, SCI.STYLE_LINENUMBER)
     lexer.setFont(DEFAULT_FONT, SCI.STYLE_LINENUMBER)
     # assign the lexer
     self.editor.setLexer(lexer)
     self.editor.SendScintilla(SCI.SCI_COLOURISE, 0, -1)
     # margins
     self.editor.setMarginsBackgroundColor(MARGIN_BGCOLOR)
     self.editor.setMarginsForegroundColor(MARGIN_COLOR)
     self.editor.setMarginsFont(LINENO_FONT)
     # folding
     self.editor.setFolding(FOLDING)
     self.editor.SendScintilla(SCI.SCI_SETMARGINWIDTHN, FOLD_MARGIN_NUM,
                               FOLD_MARGIN_WIDTH)
     # set fold margin colors
     self.editor.SendScintilla(SCI.SCI_SETFOLDMARGINCOLOUR, True,
                               Main._color_to_bgr_int(FOLD_MARGIN_COLOR))
     self.editor.SendScintilla(SCI.SCI_SETFOLDMARGINHICOLOUR, True,
                               Main._color_to_bgr_int(FOLD_MARGIN_HICOLOR))
     # create and configure the breakpoint column
     self.editor.setMarginWidth(self.__symbol_margin_num, 17)
     self.editor.markerDefine(BREAKPOINT_SYMBOL,
                              self.__breakpoint_marker_num)
     self.editor.setMarginMarkerMask(self.__symbol_margin_num,
                                     self.__breakpoint_marker_mask)
     self.editor.setMarkerBackgroundColor(BREAKPOINT_COLOR,
                                          self.__breakpoint_marker_num)
     # make breakpoint margin clickable
     self.editor.setMarginSensitivity(self.__symbol_margin_num, True)
     # add new callback for breakpoints
     self.editor.marginClicked.connect(self._slot_margin_clicked)
     # setup active line marker
     self.editor.markerDefine(ACTIVE_LINE_SYMBOL,
                              self.__active_line_marker_num)
     self.editor.setMarkerForegroundColor(ACTIVE_LINE_COLOR,
                                          self.__active_line_marker_num)
     self.editor.setMarkerBackgroundColor(ACTIVE_LINE_COLOR,
                                          self.__active_line_marker_num)
     # connect signals
     self.editor.textChanged.connect(self._slot_text_changed)
     self.editor.modificationChanged.connect(
         self._slot_editor_modification_changed)
     self.editor.SCN_URIDROPPED.connect(self._slot_file_dropped)
     self.editor.copyAvailable.connect(self.actionCut.setEnabled)
     self.editor.copyAvailable.connect(self.actionCopy.setEnabled)
     self.editor.selectionChanged.connect(
         lambda: self.actionDelete.setEnabled(self.editor.hasSelectedText()
                                              ))
     self.editor.selectionChanged.connect(
         lambda: self.actionSelectAll.setEnabled(self.editor.
                                                 hasSelectedText()))
     # autocomplete
     if API_FILE is not None:
         apis = QsciAPIs(self.editor.lexer())
         apis.loadPrepared(API_FILE)
     self.editor.setAutoCompletionThreshold(3)
     # The source is any installed APIs.
     self.editor.setAutoCompletionSource(QsciScintilla.AcsAPIs)