Esempio n. 1
0
 def __init__(self, parent=None):
     TextTabWidget.__init__(self, parent)
     self.setHTML(self.__getContent())
     self.setFileName("")
     self.setShortName("Welcome")
     GlobalData().project.sigProjectChanged.connect(self.__onProjectChanged)
Esempio n. 2
0
 def onFileUpdated( self, fileName, uuid ):
     " Triggered when the file is updated "
     self.clViewer.onFileUpdated( fileName )
     self.findNotUsedButton.setEnabled( GlobalData().project.isLoaded() and \
                                        self.getItemCount() > 0 )
     return
Esempio n. 3
0
 def __getBrokenHeaderBackground(self):
     " Returns thr broken header background color as a string useful for CSS "
     return self.__toCSSColor(
         GlobalData().skin.outdatedOutlineColor.getRgb())
Esempio n. 4
0
 def clearSearchIndicators(self):
     """Hides the search indicator"""
     self.resetHighlight()
     GlobalData().mainWindow.clearStatusBarMessage()
Esempio n. 5
0
 def __filterItemAdded( self ):
     " The filter item has been added "
     project = GlobalData().project
     if project.fileName != "":
         project.setFindClassHistory( self.filterEdit.getItems() )
     return
Esempio n. 6
0
def exceptionHook(excType, excValue, tracebackObj):
    """Catches unhandled exceptions"""
    globalData = GlobalData()

    # Keyboard interrupt is a special case
    if issubclass(excType, KeyboardInterrupt):
        if globalData.application is not None:
            globalData.application.quit()
        return

    error = '%s: %s' % (excType.__name__, excValue)
    stackTraceString = ''.join(
        traceback.format_exception(excType, excValue, tracebackObj))

    # Save the traceback to a file explicitly together with a log window
    # content.
    excptFileName = SETTINGS_DIR + 'unhandledexceptions.log'
    try:
        savedOK = True
        with open(excptFileName, 'a', encoding=DEFAULT_ENCODING) as diskfile:
            diskfile.write('------ Unhandled exception report at ' +
                           str(datetime.datetime.now()) + '\n')
            diskfile.write('Traceback:\n')
            diskfile.write(stackTraceString)

            diskfile.write('Log window:\n')
            if globalData.mainWindow is not None:
                # i.e. the log window is available, save its content too
                logWindowContent = globalData.mainWindow.getLogViewerContent()
                logWindowContent = logWindowContent.strip()
                if logWindowContent:
                    diskfile.write(logWindowContent)
                    diskfile.write('\n')
                else:
                    diskfile.write('Nothing is there\n')
            else:
                diskfile.write('Has not been created yet\n')
            diskfile.write('------\n\n')
    except:
        savedOK = False

    # This output will be to a console if the application has not started yet
    # or to a log window otherwise.
    logging.error('Unhandled exception is caught\n%s', stackTraceString)

    # Display the message as a QT modal dialog box if the application
    # has started
    if globalData.application is not None:
        message = "<html><body>"
        if savedOK:
            message += "Stack trace and log window content saved in " + \
                       excptFileName + ".<br>"
        else:
            message += "Failed to save stack trace and log window " \
                       "content in " + excptFileName + ".<br>"

        lines = stackTraceString.split('\n')
        if len(lines) > 32:
            message += "First 32 lines of the stack trace " \
                       "(the rest is truncated):" \
                       "<pre>" + "\n".join(lines[:32]) + "<pre>"
        else:
            message += "Stack trace:" + \
                       "<pre>" + stackTraceString + "</pre>"
        message += "</body></html>"
        QMessageBox.critical(None, "Unhandled exception: " + error, message)
        globalData.application.exit(1)
Esempio n. 7
0
 def __findWhereUsed(self):
     """Find where used context menu handler"""
     if self.__contextItem is not None:
         GlobalData().mainWindow.findWhereUsed(self.__contextItem.getPath(),
                                               self.__contextItem.sourceObj)
Esempio n. 8
0
class BrowserModelBase(QAbstractItemModel):
    " Class implementing the file system browser model "

    def __init__(self, headerData, parent=None):
        QAbstractItemModel.__init__(self, parent)

        self.rootItem = TreeViewItem(None, headerData)
        self.globalData = GlobalData()
        self.projectTopLevelDirs = []
        self.showTooltips = True
        return

    def setTooltips(self, switchOn):
        " Sets the tooltip mode: to show or not to show them "
        self.showTooltips = switchOn
        return

    def columnCount(self, parent=QModelIndex()):
        " Provides the number of columns "
        if parent.isValid():
            return parent.internalPointer().columnCount()
        return self.rootItem.columnCount()

    def updateRootData(self, column, value):
        " Updates the root entry, i.e. header "
        self.rootItem.setData(column, value)
        self.headerDataChanged.emit(Qt.Horizontal, column, column)
        return

    def data(self, index, role):
        " Provides data of an item "
        if not index.isValid():
            return QVariant()

        column = index.column()
        if role == Qt.DisplayRole:
            item = index.internalPointer()
            if column < item.columnCount():
                return QVariant(item.data(column))
            if column == item.columnCount() and \
               column < self.columnCount( self.parent( index ) ):
                # This is for the case when an item under a multi-column
                # parent doesn't have a value for all the columns
                return QVariant("")
        elif role == Qt.DecorationRole:
            if column == 0:
                return QVariant(index.internalPointer().getIcon())
        elif role == Qt.ToolTipRole:
            item = index.internalPointer()
            if column == 1 and item.path is not None:
                return QVariant(item.path)
            if self.showTooltips and column == 0 and item.toolTip != "":
                return QVariant(item.toolTip)
        return QVariant()

    def flags(self, index):
        " Provides the item flags "
        if not index.isValid():
            return Qt.ItemIsEnabled
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        " Provides the header data "
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            if section >= self.rootItem.columnCount():
                return QVariant("")
            return self.rootItem.data(section)
        return QVariant()

    def index(self, row, column, parent=QModelIndex()):
        " Creates an index "

        # The model/view framework considers negative values out-of-bounds,
        # however in python they work when indexing into lists. So make sure
        # we return an invalid index for out-of-bounds row/col
        if row < 0 or column < 0 or \
           row >= self.rowCount( parent ) or \
           column >= self.columnCount( parent ):
            return QModelIndex()

        if parent.isValid():
            parentItem = parent.internalPointer()
        else:
            parentItem = self.rootItem

        try:
            if not parentItem.populated:
                self.populateItem(parentItem)
            childItem = parentItem.child(row)
        except IndexError:
            return QModelIndex()

        if childItem:
            return self.createIndex(row, column, childItem)
        return QModelIndex()

    def buildIndex(self, rowPath):
        " Builds index for the path (path is like [ 1, 2, 1, 16 ]) "
        result = QModelIndex()
        for row in rowPath:
            result = self.index(row, 0, result)
        return result

    def parent(self, index):
        " Provides the index of the parent object "

        if not index.isValid():
            return QModelIndex()

        childItem = index.internalPointer()
        parentItem = childItem.parent()

        if parentItem == self.rootItem:
            return QModelIndex()

        return self.createIndex(parentItem.row(), 0, parentItem)

    def totalRowCount(self):
        " Provides the total number of rows "
        return self.rootItem.childCount()

    def rowCount(self, parent=QModelIndex()):
        " Provides the number of rows "

        # Only the first column should have children
        if parent.column() > 0:
            return 0

        if not parent.isValid():
            return self.rootItem.childCount()

        parentItem = parent.internalPointer()
        if not parentItem.populated:  # lazy population
            self.populateItem(parentItem)
        return parentItem.childCount()

    def hasChildren(self, parent=QModelIndex()):
        " Returns True if the parent has children "
        # Only the first column should have children
        if parent.column() > 0:
            return False
        if not parent.isValid():
            return self.rootItem.childCount() > 0

        if parent.internalPointer().lazyPopulation:
            return True
        return parent.internalPointer().childCount() > 0

    def clear(self):
        " Clears the model "
        self.rootItem.removeChildren()
        self.reset()
        return

    def item(self, index):
        " Provides a reference to an item "
        if not index.isValid():
            return None
        return index.internalPointer()

    @staticmethod
    def _addItem(itm, parentItem):
        " Adds an item "
        parentItem.appendChild(itm)
        return

    def addItem(self, itm, parent=QModelIndex()):
        " Adds an item "

        if not parent.isValid():
            parentItem = self.rootItem
        else:
            parentItem = parent.internalPointer()

        cnt = parentItem.childCount()
        self.beginInsertRows(parent, cnt, cnt)
        self._addItem(itm, parentItem)
        self.endInsertRows()
        return

    def populateItem(self, parentItem, repopulate=False):
        " Populates an item's subtree "

        if parentItem.itemType == DirectoryItemType:
            self.populateDirectoryItem(parentItem, repopulate)
        elif parentItem.itemType == SysPathItemType:
            self.populateSysPathItem(parentItem, repopulate)
        elif parentItem.itemType == FileItemType:
            self.populateFileItem(parentItem, repopulate)
        elif parentItem.itemType == GlobalsItemType:
            self.populateGlobalsItem(parentItem, repopulate)
        elif parentItem.itemType == ImportsItemType:
            self.populateImportsItem(parentItem, repopulate)
        elif parentItem.itemType == FunctionsItemType:
            self.populateFunctionsItem(parentItem, repopulate)
        elif parentItem.itemType == ClassesItemType:
            self.populateClassesItem(parentItem, repopulate)
        elif parentItem.itemType == ClassItemType:
            self.populateClassItem(parentItem, repopulate)
        elif parentItem.itemType == StaticAttributesItemType:
            self.populateStaticAttributesItem(parentItem, repopulate)
        elif parentItem.itemType == InstanceAttributesItemType:
            self.populateInstanceAttributesItem(parentItem, repopulate)
        elif parentItem.itemType == FunctionItemType:
            self.populateFunctionItem(parentItem, repopulate)
        elif parentItem.itemType == ImportItemType:
            self.populateImportItem(parentItem, repopulate)
        parentItem.populated = True
        return

    def populateDirectoryItem(self, parentItem, repopulate=False):
        " Populates a directory item's subtree "

        path = parentItem.getPath()
        if not os.path.exists(path):
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            items = os.listdir(path)
        except Exception, exc:
            QApplication.restoreOverrideCursor()
            logging.error("Cannot populate directory. " + str(exc))
            return

        excludes = ['.svn', '.cvs', '.hg', '.git']
        items = [itm for itm in items if itm not in excludes]
        if parentItem.needVCSStatus:
            # That's the project browser. Filter out what not needed.
            excludeFunctor = GlobalData().project.shouldExclude
            items = [itm for itm in items if not excludeFunctor(itm)]

        pathsToRequest = []
        if items:
            infoSrc = self.globalData.briefModinfoCache

            if repopulate:
                self.beginInsertRows(
                    self.createIndex(parentItem.row(), 0, parentItem), 0,
                    len(items) - 1)
            path = os.path.realpath(path) + os.path.sep
            for item in items:
                fullPath = path + item
                if os.path.isdir(fullPath):
                    node = TreeViewDirectoryItem(parentItem, fullPath, False)
                    if parentItem.needVCSStatus:
                        pathsToRequest.append(fullPath + os.path.sep)
                else:
                    node = TreeViewFileItem(parentItem, fullPath)
                    if parentItem.needVCSStatus:
                        pathsToRequest.append(fullPath)
                    if node.fileType in [PythonFileType, Python3FileType]:
                        modInfo = infoSrc.get(fullPath)
                        node.toolTip = ""
                        if modInfo.docstring is not None:
                            node.toolTip = modInfo.docstring.text

                        if modInfo.isOK == False:
                            # Substitute icon and change the tooltip
                            node.icon = PixmapCache().getIcon(
                                'filepythonbroken.png')
                            if node.toolTip != "":
                                node.toolTip += "\n\n"
                            node.toolTip += "Parsing errors:\n" + \
                                            "\n".join( modInfo.lexerErrors + \
                                                       modInfo.errors )
                            node.parsingErrors = True

                        if modInfo.encoding is None and \
                           not modInfo.imports and \
                           not modInfo.globals and \
                           not modInfo.functions and \
                           not modInfo.classes:
                            node.populated = True
                            node.lazyPopulation = False

                node.needVCSStatus = parentItem.needVCSStatus
                self._addItem(node, parentItem)

            if repopulate:
                self.endInsertRows()

        parentItem.populated = True

        # Request statuses of the populated items. The request must be sent
        # after the items are added, otherwise the status received by the model
        # before the items are populated thus not updated properly.
        for path in pathsToRequest:
            GlobalData().mainWindow.vcsManager.requestStatus(path)
        QApplication.restoreOverrideCursor()
        return
Esempio n. 9
0
    def __init__(self,
                 scriptName,
                 params,
                 reportTime,
                 dataFile,
                 stats,
                 parent=None):
        QWidget.__init__(self, parent)

        self.__table = ProfilerTreeWidget(self)
        self.__table.sigEscapePressed.connect(self.__onEsc)

        self.__script = scriptName
        self.__stats = stats
        project = GlobalData().project
        if project.isLoaded():
            self.__projectPrefix = os.path.dirname(project.fileName)
        else:
            self.__projectPrefix = os.path.dirname(scriptName)
        if not self.__projectPrefix.endswith(os.path.sep):
            self.__projectPrefix += os.path.sep

        self.__table.setAlternatingRowColors(True)
        self.__table.setRootIsDecorated(False)
        self.__table.setItemsExpandable(False)
        self.__table.setSortingEnabled(True)
        self.__table.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__table.setUniformRowHeights(True)
        self.__table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.__table.setSelectionBehavior(QAbstractItemView.SelectRows)

        headerLabels = [
            "", "Calls", "Total time", "Per call", "Cum. time", "Per call",
            "File name:line", "Function", "Callers", "Callees"
        ]
        self.__table.setHeaderLabels(headerLabels)

        headerItem = self.__table.headerItem()
        headerItem.setToolTip(0, "Indication if it is an outside function")
        headerItem.setToolTip(
            1, "Actual number of calls/primitive calls "
            "(not induced via recursion)")
        headerItem.setToolTip(
            2, "Total time spent in function "
            "(excluding time made in calls "
            "to sub-functions)")
        headerItem.setToolTip(
            3, "Total time divided by number "
            "of actual calls")
        headerItem.setToolTip(
            4, "Total time spent in function and all "
            "subfunctions (from invocation till exit)")
        headerItem.setToolTip(
            5, "Cumulative time divided by number "
            "of primitive calls")
        headerItem.setToolTip(6, "Function location")
        headerItem.setToolTip(7, "Function name")
        headerItem.setToolTip(8, "Function callers")
        headerItem.setToolTip(9, "Function callees")

        self.__table.itemActivated.connect(self.__activated)

        totalCalls = self.__stats.total_calls
        # The calls were not induced via recursion
        totalPrimitiveCalls = self.__stats.prim_calls
        totalTime = self.__stats.total_tt

        txt = "<b>Script:</b> " + self.__script + " " + \
              params['arguments'] + "<br/>" \
              "<b>Run at:</b> " + reportTime + "<br/>" + \
              str(totalCalls) + " function calls (" + \
              str(totalPrimitiveCalls) + " primitive calls) in " + \
              FLOAT_FORMAT % totalTime + " CPU seconds"
        summary = HeaderFitLabel(self)
        summary.setText(txt)
        summary.setToolTip(txt)
        summary.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        summary.setMinimumWidth(10)

        vLayout = QVBoxLayout()
        vLayout.setContentsMargins(0, 0, 0, 0)
        vLayout.setSpacing(0)
        vLayout.addWidget(summary)
        vLayout.addWidget(self.__table)

        self.setLayout(vLayout)
        self.__createContextMenu()

        self.__populate(totalTime)
Esempio n. 10
0
 def onFileUpdated(self, fileName, uuid):
     """Triggered when the file is updated"""
     del uuid    # unused argument
     self.funcViewer.onFileUpdated(fileName)
     self.findNotUsedButton.setEnabled(GlobalData().project.isLoaded() and
                                       self.getItemCount() > 0)
Esempio n. 11
0
    def analyzeFile(self, path, pylintrc="", importDirs=[], workingDir=""):
        " run pylint for a certain file or files list "

        self.retCode = -1
        self.errorMessages = []
        self.tables = []
        self.similarities = []
        self.dependencies = None
        self.statementsAnalysed = 0
        self.score = 0.0
        self.previousScore = 0.0

        self.__currentSection = []

        if pylintrc != "" and not os.path.exists(pylintrc):
            # This is a buffer with an rc content
            tempDirName = tempfile.mkdtemp()
            if not tempDirName.endswith(os.path.sep):
                tempDirName += os.path.sep
            tempFileName = tempDirName + "temp_pylint.rc"

            temporaryStorage = open(tempFileName, "w")
            temporaryStorage.write(str(pylintrc))
            temporaryStorage.close()

        if type(path) == type("a"):
            path = path.split()

        # Run pylint with a parseable output and with messages types
        try:

            rcArg = []
            if pylintrc:
                if os.path.exists(pylintrc):
                    rcArg = ["--rcfile=" + pylintrc]
                else:
                    rcArg = ["--rcfile=" + tempFileName]

            initHook = ["--init-hook"]
            code = ""
            if importDirs:
                code = "import sys"
                for dirName in importDirs:
                    code += ";sys.path.insert(0,'" + dirName + "')"

            # Dirty hack to support CGI files pylinting
            if code:
                code += ";\n"
            code += "try: from logilab.common import modutils;" \
                    "modutils.PY_SOURCE_EXTS=('py','cgi');\nexcept: pass"

            initHook.append(code)

            if GlobalData().pylintVersion < StrictVersion("1.0.0"):
                formatArg = ['-f', 'parseable', '-i', 'y']
            else:
                formatArg = [
                    '--msg-template="{path}:{line}: [{msg_id}, {obj}] {msg}"'
                ]

            skipTillRecognised = False
            # print "Command line: pylint: " + " ".join( formatArg + initHook + rcArg + path )
            # print "Dir: " + workingDir
            output = self.__run(['pylint'] + formatArg + initHook + rcArg +
                                path, workingDir).split('\n')
            for index in xrange(len(output)):
                line = output[index]
                if skipTillRecognised:
                    lineType, shouldSkip = self.__detectLineType(output, index)
                    if lineType == self.Unknown:
                        continue
                    skipTillRecognised = shouldSkip
                else:
                    lineType, skipTillRecognised = self.__detectLineType(
                        output, index)

                if verbose:
                    print str(lineType) + " -> " + line
                if lineType == self.Header:
                    continue
                if lineType == self.Message:
                    self.errorMessages.append(
                        ErrorMessage(output, index, workingDir))
                    continue

                if lineType == self.Unknown:
                    self.__currentSection.append(line)
                    continue

                # Here: beginning of a section or beginning of a similarity
                # message
                self.__parseCurrentSection(path)
                self.__currentSection.append(line)

            # Final section parsing
            self.__parseCurrentSection(path)

        except Exception:
            if pylintrc != "" and not os.path.exists(pylintrc):
                os.unlink(tempFileName)
                os.rmdir(tempDirName)
            raise

        if pylintrc != "" and not os.path.exists(pylintrc):
            os.unlink(tempFileName)
            os.rmdir(tempDirName)
        return
Esempio n. 12
0
 def __findNotUsed():
     """Runs the unused function analysis"""
     GlobalData().mainWindow.onNotUsedFunctions()
Esempio n. 13
0
 def _onAnchorClicked(self, link):
     """Handles a URL click"""
     fileName, anchorOrLine = self._resolveLink(link)
     if fileName:
         GlobalData().mainWindow.openFile(fileName, anchorOrLine)
Esempio n. 14
0
    def __createLayout(self, varName, varType, varValue, isGlobal):
        """ Creates the dialog layout """

        varTypeParts = varType.split()
        if varTypeParts[0].lower() in ["string", "unicode", "qstring"]:
            length = str(len(varValue))
            lines = str(len(varValue.splitlines()))
            varType = varType.split( "(" )[ 0 ].strip() + \
                      " (lines: " + lines + ", characters: " + length + ")"

        self.resize(600, 250)
        self.setSizeGripEnabled(True)

        # Top level layout
        layout = QVBoxLayout(self)

        gridLayout = QGridLayout()
        gridLayout.setSpacing(2)
        varScopeLabel = QLabel("Scope:")
        gridLayout.addWidget(varScopeLabel, 0, 0, Qt.AlignTop)
        if isGlobal:
            varScopeValue = FramedLabelWithDoubleClick("Global")
        else:
            varScopeValue = FramedLabelWithDoubleClick("Local")
        varScopeValue.setToolTip("Double click to copy")
        font = varScopeValue.font()
        font.setFamily(GlobalData().skin.baseMonoFontFace)
        varScopeValue.setFont(font)
        gridLayout.addWidget(varScopeValue, 0, 1)

        varNameLabel = QLabel("Name:")
        gridLayout.addWidget(varNameLabel, 1, 0, Qt.AlignTop)
        varNameValue = FramedLabelWithDoubleClick(varName)
        varNameValue.setToolTip("Double click to copy")
        varNameValue.setFont(font)
        gridLayout.addWidget(varNameValue, 1, 1)
        varTypeLabel = QLabel("Type:")
        gridLayout.addWidget(varTypeLabel, 2, 0, Qt.AlignTop)
        varTypeValue = FramedLabelWithDoubleClick(varType)
        varTypeValue.setToolTip("Double click to copy")
        varTypeValue.setFont(font)
        gridLayout.addWidget(varTypeValue, 2, 1)
        varValueLabel = QLabel("Value:")
        gridLayout.addWidget(varValueLabel, 3, 0, Qt.AlignTop)
        varValueValue = QTextEdit()
        varValueValue.setReadOnly(True)
        varValueValue.setFontFamily(GlobalData().skin.baseMonoFontFace)
        # varValueValue.setLineWrapMode( QTextEdit.NoWrap )
        varValueValue.setAcceptRichText(False)
        varValueValue.setPlainText(varValue)
        gridLayout.addWidget(varValueValue, 3, 1)
        layout.addLayout(gridLayout)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.__OKButton = buttonBox.button(QDialogButtonBox.Ok)
        self.__OKButton.setDefault(True)
        buttonBox.accepted.connect(self.close)
        buttonBox.rejected.connect(self.close)
        layout.addWidget(buttonBox)

        varValueValue.setFocus()
        return
Esempio n. 15
0
    def main(self):
        """The codimension driver"""
        usageMessage = 'Usage: %prog [options] [project file | python files]'
        parser = OptionParser(usage=usageMessage, version='%prog ' + VER)

        parser.add_option(
            '--debug',
            action='store_true',
            dest='debug',
            default=False,
            help='switch on debug and info messages (default: Off)')
        parser.add_option(
            '--clean-start',
            action='store_true',
            dest='cleanStart',
            default=False,
            help='do not restore previous IDE state (default: Off)')

        self.__options, self.__args = parser.parse_args()
        self.setupLogging()

        # The default exception handler can be replaced
        sys.excepthook = exceptionHook

        # Create global data singleton.
        # It's unlikely to throw any exceptions.
        globalData = GlobalData()
        globalData.version = VER

        # Loading settings - they have to be loaded before the application is
        # created. This is because the skin name is saved there.
        settings = Settings()
        self.copySkin()

        # Load the skin
        globalData.skin = Skin()
        globalData.skin.load(SETTINGS_DIR + 'skins' + os.path.sep +
                             settings['skin'])

        self.__delayedWarnings += settings.validateZoom(
            globalData.skin.minTextZoom, globalData.skin.minCFlowZoom)

        # QT on UBUNTU has a bug - the main menu bar does not generate the
        # 'aboutToHide' signal (though 'aboutToShow' is generated properly. This
        # prevents codimension working properly so this hack below disables the
        # global menu bar for codimension and makes it working properly.
        os.environ['QT_X11_NO_NATIVE_MENUBAR'] = '1'

        # Create QT application
        codimensionApp = CodimensionApplication(sys.argv, settings['style'])
        globalData.application = codimensionApp

        logging.debug('Starting codimension v.%s', VER)

        try:
            # Process command line arguments
            self.__projectFile = self.processCommandLineArgs()
        except Exception as exc:
            logging.error(str(exc))
            parser.print_help()
            return 1

        # Show splash screen
        self.__splash = SplashScreen()

        screenSize = codimensionApp.desktop().screenGeometry()
        globalData.screenWidth = screenSize.width()
        globalData.screenHeight = screenSize.height()

        self.__splash.showMessage('Importing packages...')
        from ui.mainwindow import CodimensionMainWindow

        self.__splash.showMessage('Generating main window...')
        mainWindow = CodimensionMainWindow(self.__splash, settings)
        codimensionApp.setMainWindow(mainWindow)
        globalData.mainWindow = mainWindow
        codimensionApp.lastWindowClosed.connect(codimensionApp.quit)

        mainWindow.show()
        mainWindow.restoreWindowPosition()
        mainWindow.restoreSplitterSizes()

        # Launch the user interface
        QTimer.singleShot(1, self.launchUserInterface)

        # Run the application main cycle
        retVal = codimensionApp.exec_()
        return retVal
Esempio n. 16
0
 def __onDeadCode(self):
     """Triggered when vulture analysis is requested"""
     GlobalData().mainWindow.tabDeadCodeClicked()
Esempio n. 17
0
    def launchUserInterface(self):
        """UI launchpad"""
        globalData = GlobalData()

        self.__splash.showMessage('Loading plugins...')
        globalData.pluginManager.load()

        settings = Settings()
        mainWindow = globalData.mainWindow
        mainWindow.getToolbar().setVisible(settings['showMainToolBar'])

        needSignal = True
        if self.__options.cleanStart:
            # Codimension will not load anything.
            pass
        elif self.__projectFile:
            self.__splash.showMessage('Loading project...')
            globalData.project.loadProject(self.__projectFile)
            needSignal = False
        elif self.__args:
            # There are arguments and they are python files
            # The project should not be loaded but the files should
            # be opened
            for fName in self.__args:
                mainWindow.openFile(os.path.abspath(fName), -1)
        elif settings['projectLoaded']:
            if not settings['recentProjects']:
                # Some project was loaded but now it is not available.
                pass
            else:
                self.__splash.showMessage('Loading project...')
                if os.path.exists(settings['recentProjects'][0]):
                    globalData.project.loadProject(
                        settings['recentProjects'][0])
                    needSignal = False
                else:
                    self.__delayedWarnings.append(
                        'Cannot open the most recent project: ' +
                        settings['recentProjects'][0] +
                        '. Ignore and continue.')
        else:
            mainWindow.em.restoreTabs(settings.tabStatus)

        # Signal for triggering browsers layout
        if needSignal:
            globalData.project.sigProjectChanged.emit(
                CodimensionProject.CompleteProject)

        # The editors positions can be restored properly only when the editors have
        # actually been drawn. Otherwise the first visible line is unknown.
        # So, I load the project first and let object browsers initialize
        # themselves and then manually call the main window handler to restore the
        # editors. The last step is to connect the signal.
        mainWindow.onProjectChanged(CodimensionProject.CompleteProject)
        globalData.project.sigProjectChanged.connect(
            mainWindow.onProjectChanged)

        self.__splash.finish(globalData.mainWindow)
        self.__splash = None
        del self.__splash

        for message in self.__delayedWarnings:
            logging.warning(message)

        # Some startup time objects could be collected here. In my test runs
        # there were around 700 objects.
        gc.collect()
Esempio n. 18
0
 def onRunScript(action=None):
     """Runs the script"""
     del action  # unused argument
     GlobalData().mainWindow.onRunTab()
Esempio n. 19
0
 def __filterItemAdded(self):
     """The filter item has been added"""
     project = GlobalData().project
     if project.isLoaded():
         project.findFunctionHistory = self.filterEdit.getItems()
Esempio n. 20
0
 def onRunScriptDlg():
     """Shows the run parameters dialogue"""
     GlobalData().mainWindow.onRunTabDlg()
Esempio n. 21
0
    def __testSearchability(self):
        """Tests the searchability and sets the Find button status"""
        startTime = time.time()
        if self.findCombo.currentText().strip() == "":
            self.findButton.setEnabled(False)
            self.findButton.setToolTip("No text to search")
            return

        if self.dirRButton.isChecked():
            dirname = self.dirEditCombo.currentText().strip()
            if dirname == "":
                self.findButton.setEnabled(False)
                self.findButton.setToolTip("No directory path")
                return
            if not isdir(dirname):
                self.findButton.setEnabled(False)
                self.findButton.setToolTip("Path is not a directory")
                return

        # Now we need to match file names if there is a filter
        filtersText = self.filterCombo.currentText().strip()
        if filtersText == "":
            self.findButton.setEnabled(True)
            self.findButton.setToolTip("Find in files")
            return

        # Need to check the files match
        try:
            filters = self.__compileFilters()
        except:
            self.findButton.setEnabled(False)
            self.findButton.setToolTip("Incorrect files "
                                       "filter regular expression")
            return

        matched = False
        tooLong = False
        if self.projectRButton.isChecked():
            # Whole project
            for fname in GlobalData().project.filesList:
                if fname.endswith(sep):
                    continue
                matched = self.__filterMatch(filters, fname)
                if matched:
                    break
                # Check the time, it might took too long
                if time.time() - startTime > 0.1:
                    tooLong = True
                    break

        elif self.openFilesRButton.isChecked():
            # Opened files
            openedFiles = self.editorsManager.getTextEditors()
            for record in openedFiles:
                matched = self.__filterMatch(filters, record[1])
                if matched:
                    break
                # Check the time, it might took too long
                if time.time() - startTime > 0.1:
                    tooLong = True
                    break

        else:
            # Search in the dir
            if not dirname.endswith(sep):
                dirname += sep
            matched, tooLong = self.__matchInDir(dirname, filters, startTime)

        if matched:
            self.findButton.setEnabled(True)
            self.findButton.setToolTip("Find in files")
        else:
            if tooLong:
                self.findButton.setEnabled(True)
                self.findButton.setToolTip("Find in files")
            else:
                self.findButton.setEnabled(False)
                self.findButton.setToolTip("No files matched to search in")
Esempio n. 22
0
 def onProfileScript(action=None):
     """Profiles the script"""
     del action  # unused argument
     GlobalData().mainWindow.onProfileTab()
Esempio n. 23
0
 def __showStatusBarMessage(msg):
     """Shows a main window status bar message"""
     mainWindow = GlobalData().mainWindow
     mainWindow.showStatusBarMessage(msg, 8000)
Esempio n. 24
0
 def onProfileScriptDlg():
     """Shows the profile parameters dialogue"""
     GlobalData().mainWindow.onProfileTabDlg()
Esempio n. 25
0
 def __findNotUsed( self ):
     " Runs the unused class analysis "
     GlobalData().mainWindow.onNotUsedClasses()
     return
Esempio n. 26
0
 def onDebugScript(action=None):
     """Starts debugging"""
     del action  # unused argument
     GlobalData().mainWindow.onDebugTab()
Esempio n. 27
0
 def modelFilesChanged( self ):
     " Triggered when the source model has a file or files added or deleted "
     self.findNotUsedButton.setEnabled( GlobalData().project.isLoaded() and \
                                        self.getItemCount() > 0 )
     return
Esempio n. 28
0
 def onDebugScriptDlg():
     """Shows the debug parameters dialogue"""
     GlobalData().mainWindow.onDebugTabDlg()
Esempio n. 29
0
def __getImportedObjects(moduleName, fileName):
    " Provides a list of objects to be imported from "
    buildSystemWideModulesList()

    modulePath = None
    moduleName = str(moduleName)
    if moduleName in __systemwideModules:
        modulePath = __systemwideModules[moduleName]
        if modulePath is None or moduleName in Settings().dirSafeModules:
            # it could be a built-in module
            return getImportNames(moduleName)
    else:
        # Not a system wide, try search in the project
        # or current directories
        if moduleName.startswith("."):
            # That's a relative import
            if not fileName:
                # File name must be known for a relative import
                return set()
            dotCount = 0
            while moduleName.startswith("."):
                dotCount += 1
                moduleName = moduleName[1:]
            # Strip as many paths as dots instruct
            baseDir = os.path.dirname(fileName)
            while dotCount > 1:
                baseDir = os.path.dirname(baseDir)
                dotCount -= 1
            specificModules = getProjectSpecificModules(baseDir, True)
        else:
            specificModules = getProjectSpecificModules(fileName)
        if moduleName in specificModules:
            modulePath = specificModules[moduleName]

    if modulePath is None:
        return set()

    binarySuffix = __isBinaryModule(modulePath)
    if binarySuffix is not None:
        try:
            modName = os.path.basename(modulePath)
            modObj = imp.load_module(modName, None, modulePath, binarySuffix)
            return set(dir(modObj))
        except:
            # Failed to load a binary module
            return set()

    # It's not a binary module, so parse it and make a list of objects.
    # Check first if the module is loaded into the editor
    mainWindow = GlobalData().mainWindow
    editorsManager = mainWindow.editorsManagerWidget.editorsManager
    widget = editorsManager.getWidgetForFileName(modulePath)
    if widget is None:
        # Not loaded, so parse it from a file
        info = getBriefModuleInfoFromFile(modulePath)
    else:
        # Parse it from memory because it could be changed
        editor = widget.getEditor()
        info = getBriefModuleInfoFromMemory(editor.text())

    return __getParsedModuleNames(info)
Esempio n. 30
0
    def __createLayout(self, parent):
        " Helper to create the viewer layout "

        # __textEdit list area
        self.__textEdit = QPlainTextEdit(parent)
        self.__textEdit.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.__textEdit.setFont(QFont(GlobalData().skin.baseMonoFontFace))
        self.__textEdit.setReadOnly(True)

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.__textEdit.setFontPointSize( 12.0 )

        # Buttons
        self.__selectAllButton = QAction(
            PixmapCache().getIcon('selectall.png'), 'Select all', self)
        self.__selectAllButton.triggered.connect(self.__textEdit.selectAll)
        self.__copyButton = QAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy to clipboard',
            self)
        self.__copyButton.triggered.connect(self.__textEdit.copy)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.__clearButton = QAction(PixmapCache().getIcon('trash.png'),
                                     'Clear all', self)
        self.__clearButton.triggered.connect(self.__clear)

        # Toolbar
        toolbar = QToolBar()
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.LeftToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)
        toolbar.addAction(self.__selectAllButton)
        toolbar.addAction(self.__copyButton)
        toolbar.addWidget(spacer)
        toolbar.addAction(self.__clearButton)

        self.__header = QLabel("Signature: none")
        self.__header.setFrameStyle(QFrame.StyledPanel)
        self.__header.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.__header.setAutoFillBackground(True)
        headerPalette = self.__header.palette()
        headerBackground = headerPalette.color(QPalette.Background)
        headerBackground.setRgb(min(headerBackground.red() + 30, 255),
                                min(headerBackground.green() + 30, 255),
                                min(headerBackground.blue() + 30, 255))
        headerPalette.setColor(QPalette.Background, headerBackground)
        self.__header.setPalette(headerPalette)
        verticalLayout = QVBoxLayout()
        verticalLayout.setContentsMargins(2, 2, 2, 2)
        verticalLayout.setSpacing(2)
        verticalLayout.addWidget(self.__header)
        verticalLayout.addWidget(self.__textEdit)

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(toolbar)
        layout.addLayout(verticalLayout)

        self.setLayout(layout)
        return