Ejemplo n.º 1
0
class InputDockWidget(QDockWidget):

    def __init__(self, *args):
        QDockWidget.__init__(self, *args)
        self.setupUi(self)
        self.setWindowIcon(QIcon(':/icons/qtsixa.png'))
        self.color = QColor(Qt.lightGray)
        self.setMinimumWidth(350)
        self.setContentsMargins(0, 0, 0, 0)
        self.adjustSize()

    def setupUi(self, QtSixAMainW):
        QtSixAMainW.setObjectName(_fromUtf8('QtSixAMainW'))
        QtSixAMainW.resize(935, 513)
        triggers = TiggersView(self)
        triggers.show()
        bumpers = BumpersView(self)
        bumpers.show()
        face = FaceButtonsView(self)
        face.show()
        dpad = DpadView(self)
        dpad.show()
        select = StartSelectView(self)
        select.show()
        sixaxis = SixAxisView(self)
        sixaxis.show()
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(triggers)
        hbox.addWidget(bumpers)
        hbox.addWidget(dpad)
        hbox.addWidget(face)
        hbox.addWidget(select)
        hbox.addWidget(sixaxis)
        vbox = QVBoxLayout()
        vbox.addStretch(1)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.progress = QProgressBar(self)
        self.progress.setGeometry(20, 2, 50, 20)
        self.progress.setTextVisible(False)
        self.progress.setOrientation(Qt.Vertical)
        self.progress.setValue(80)
        self.progress.move(60,28)
        self.progress.show()
        print self.style().objectName()
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))

    def paintEvent(self, event = None):
        pass
Ejemplo n.º 2
0
class NotUsedAnalysisProgress(QDialog):
    " Progress of the not used analysis "

    Functions = 0
    Classes = 1
    Globals = 2

    def __init__(self, what, sourceModel, parent=None):
        QDialog.__init__(self, parent)

        if what not in [self.Functions, self.Classes, self.Globals]:
            raise Exception( "Unsupported unused analysis type: " + \
                             str( what ) )

        self.__cancelRequest = False
        self.__inProgress = False

        self.__what = what  # what is in source model
        self.__srcModel = sourceModel  # source model of globals or
        # functions or classes

        # Avoid pylint complains
        self.__progressBar = None
        self.__infoLabel = None
        self.__foundLabel = None
        self.__found = 0  # Number of found

        self.__createLayout()
        self.setWindowTitle(self.__formTitle())
        QTimer.singleShot(0, self.__process)
        return

    def keyPressEvent(self, event):
        " Processes the ESC key specifically "
        if event.key() == Qt.Key_Escape:
            self.__onClose()
        else:
            QDialog.keyPressEvent(self, event)
        return

    def __formTitle(self):
        " Forms the progress dialog title "
        title = "Unused "
        if self.__what == self.Functions:
            title += 'function'
        elif self.__what == self.Classes:
            title += 'class'
        else:
            title += 'globlal variable'
        return title + " analysis"

    def __formInfoLabel(self, name):
        " Forms the info label "
        if self.__what == self.Functions:
            return 'Function: ' + name
        if self.__what == self.Classes:
            return 'Class: ' + name
        return 'Globlal variable: ' + name

    def __whatAsString(self):
        " Provides 'what' as string "
        if self.__what == self.Functions:
            return 'function'
        if self.__what == self.Classes:
            return 'class'
        return 'global variable'

    def __updateFoundLabel(self):
        " Updates the found label "
        text = "Found: " + str(self.__found) + " candidate"
        if self.__found != 1:
            text += "s"
        self.__foundLabel.setText(text)
        return

    def __createLayout(self):
        """ Creates the dialog layout """

        self.resize(450, 20)
        self.setSizeGripEnabled(True)

        verticalLayout = QVBoxLayout(self)

        # Note label
        noteLabel = QLabel( "<b>Note</b>: the analysis is " \
                            "suggestive and not precise. " \
                            "Use the results with caution.\n", self )
        verticalLayout.addWidget(noteLabel)

        # Info label
        self.__infoLabel = QLabel(self)
        verticalLayout.addWidget(self.__infoLabel)

        # Progress bar
        self.__progressBar = QProgressBar(self)
        self.__progressBar.setValue(0)
        self.__progressBar.setOrientation(Qt.Horizontal)
        verticalLayout.addWidget(self.__progressBar)

        # Found label
        self.__foundLabel = QLabel(self)
        verticalLayout.addWidget(self.__foundLabel)

        # Buttons
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Close)
        verticalLayout.addWidget(buttonBox)

        buttonBox.rejected.connect(self.__onClose)
        return

    def __onClose(self):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __process(self):
        " Analysis process "

        self.__inProgress = True

        mainWindow = GlobalData().mainWindow
        editorsManager = mainWindow.editorsManagerWidget.editorsManager
        modified = editorsManager.getModifiedList(
            True)  # True - only project files
        if modified:
            modNames = [modItem[0] for modItem in modified]
            label = "File"
            if len(modified) >= 2:
                label += "s"
            label += ": "
            logging.warning( "The analisys is performed for the content of saved files. " \
                             "The unsaved modifications will not be taken into account. " \
                             + label + ", ".join( modNames ) )

        self.__updateFoundLabel()
        self.__progressBar.setRange(0,
                                    len(self.__srcModel.rootItem.childItems))
        QApplication.processEvents()
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        count = 0
        candidates = []
        for treeItem in self.__srcModel.rootItem.childItems:
            if self.__cancelRequest:
                break

            name = str(treeItem.data(0)).split('(')[0]
            path = os.path.realpath(treeItem.getPath())
            lineNumber = int(treeItem.data(2))
            absPosition = treeItem.sourceObj.absPosition

            count += 1
            self.__progressBar.setValue(count)
            self.__infoLabel.setText(self.__formInfoLabel(name))
            QApplication.processEvents()

            # Analyze the name
            found = False
            try:
                # True is for throwing exceptions
                locations = getOccurrences(path, absPosition, True)

                if len( locations ) == 1 and \
                   locations[ 0 ][ 1 ] == lineNumber:
                    found = True
                    index = getSearchItemIndex(candidates, path)
                    if index < 0:
                        widget = mainWindow.getWidgetForFileName(path)
                        if widget is None:
                            uuid = ""
                        else:
                            uuid = widget.getUUID()
                        newItem = ItemToSearchIn(path, uuid)
                        candidates.append(newItem)
                        index = len(candidates) - 1
                    candidates[index].addMatch(name, lineNumber)

            except Exception, exc:
                # There is nothing interesting with exceptions here.
                # It seems to me that rope throws them in case if the same item
                # is declared multiple times in a file. I also suspect that
                # exceptions may come up in case of syntactic errors.
                # So I just suppress them.
                pass

                #logging.warning( "Error detected while analysing " + \
                #                 self.__whatAsString() + " '" + name + \
                #                 "'. Message: " + str( exc ) )

            if found:
                self.__found += 1
                self.__updateFoundLabel()
            QApplication.processEvents()

        if self.__found == 0:
            # The analysis could be interrupted
            if not self.__cancelRequest:
                logging.info("No unused candidates found")
        else:
            mainWindow.displayFindInFiles("", candidates)

        QApplication.restoreOverrideCursor()
        self.__infoLabel.setText('Done')
        self.__inProgress = False

        self.accept()
        return
Ejemplo n.º 3
0
class LineCounterDialog( QDialog, object ):
    """ line counter dialog implementation """

    def __init__( self, fName = None, editor = None, parent = None ):

        QDialog.__init__( self, parent )

        self.__cancelRequest = False
        self.__inProgress = False
        if fName is not None:
            self.__fName = fName.strip()
        else:
            self.__fName = None
        self.__editor = editor
        self.__createLayout()
        self.setWindowTitle( "Line counter" )
        QTimer.singleShot( 0, self.__process )
        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 450, 220 )
        self.setSizeGripEnabled( True )

        self.verticalLayout = QVBoxLayout( self )

        # Info label
        self.infoLabel = FitPathLabel( self )
        #sizePolicy = QSizePolicy( QSizePolicy.Expanding,
        #                          QSizePolicy.Preferred )
        sizePolicy = QSizePolicy( QSizePolicy.Minimum,
                                  QSizePolicy.Preferred )
        sizePolicy.setHorizontalStretch( 0 )
        sizePolicy.setVerticalStretch( 0 )
        sizePolicy.setHeightForWidth(
                    self.infoLabel.sizePolicy().hasHeightForWidth() )
        self.infoLabel.setSizePolicy( sizePolicy )
        self.verticalLayout.addWidget( self.infoLabel )

        # Progress bar
        self.progressBar = QProgressBar( self )
        self.progressBar.setValue( 0 )
        self.progressBar.setOrientation( Qt.Horizontal )
        self.verticalLayout.addWidget( self.progressBar )

        # Result window
        self.resultEdit = QTextEdit( self )
        self.resultEdit.setTabChangesFocus( False )
        self.resultEdit.setAcceptRichText( False )
        self.resultEdit.setReadOnly( True )
        self.resultEdit.setFontFamily( GlobalData().skin.baseMonoFontFace )
        font = self.resultEdit.font()

        # Calculate the vertical size
        fontMetrics = QFontMetrics( font )
        rect = fontMetrics.boundingRect( "W" )
        # 6 lines, 5 line spacings, 2 frames
        self.resultEdit.setMinimumHeight( rect.height() * 7 + 4 * 5 +
                                          self.resultEdit.frameWidth() * 2 )
        self.verticalLayout.addWidget( self.resultEdit )

        # Buttons
        self.buttonBox = QDialogButtonBox( self )
        self.buttonBox.setOrientation( Qt.Horizontal )
        self.buttonBox.setStandardButtons( QDialogButtonBox.Close )
        self.verticalLayout.addWidget( self.buttonBox )

        self.buttonBox.rejected.connect( self.__onClose )
        return

    def __scanDir( self, path, files ):
        " Recursively builds a list of python files "

        if path in self.__scannedDirs:
            return

        self.__scannedDirs.append( path )
        for item in os.listdir( path ):
            if os.path.isdir( path + item ):
                nestedDir = os.path.realpath( path + item )
                if not nestedDir.endswith( os.path.sep ):
                    nestedDir += os.path.sep
                self.__scanDir( nestedDir, files )
            else:
                candidate = os.path.realpath( path + item )
                if candidate.endswith( ".py" ) or \
                   candidate.endswith( ".py3" ) or \
                   candidate.endswith( ".pyw" ):
                    if not candidate in files:
                        files.append( candidate )
        return

    def __onClose( self ):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __process( self ):
        " Accumulation process "

        self.__inProgress = True
        if self.__fName is not None:
            if os.path.exists( self.__fName ):
                if os.path.isdir( self.__fName ):
                    self.__fName = os.path.realpath( self.__fName )
                    if not self.__fName.endswith( os.path.sep ):
                        self.__fName += os.path.sep
                    files = []
                    self.__scannedDirs = []
                    QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) )
                    self.__scanDir( self.__fName, files )
                    QApplication.restoreOverrideCursor()
                else:
                    files = [ self.__fName ]
            else:
                files = []
        elif self.__editor is not None:
            files = [ "buffer" ]
        else:
            files = GlobalData().project.filesList
        self.progressBar.setRange( 0, len( files ) )

        accumulator = LinesCounter()
        current = LinesCounter()

        index = 1
        for fileName in files:

            if self.__cancelRequest:
                self.__inProgress = False
                self.close()
                return

            self.infoLabel.setPath( 'Processing: ' + fileName )

            processed = False
            if self.__editor is not None:
                current.getLinesInBuffer( self.__editor )
                processed = True
            else:
                if (fileName.endswith( '.py' ) or \
                    fileName.endswith( '.py3' ) or \
                    fileName.endswith( '.pyw' )) and \
                   os.path.exists( fileName ):
                    current.getLines( fileName )
                    processed = True

            if processed:
                accumulator.files += current.files
                accumulator.filesSize += current.filesSize
                accumulator.codeLines += current.codeLines
                accumulator.emptyLines += current.emptyLines
                accumulator.commentLines += current.commentLines
                accumulator.classes += current.classes

            self.progressBar.setValue( index )
            index += 1

            QApplication.processEvents()

        self.infoLabel.setPath( 'Done' )
        self.__inProgress = False

        # Update text in the text window
        nFiles = splitThousands( str( accumulator.files ) )
        filesSize = splitThousands( str( accumulator.filesSize ) )
        classes = splitThousands( str( accumulator.classes ) )
        codeLines = splitThousands( str( accumulator.codeLines ) )
        emptyLines = splitThousands( str( accumulator.emptyLines ) )
        commentLines = splitThousands( str( accumulator.commentLines ) )
        totalLines = splitThousands( str( accumulator.codeLines +
                                          accumulator.emptyLines +
                                          accumulator.commentLines ) )

        output = "Classes:                 " + classes + "\n" \
                 "Code lines:              " + codeLines + "\n" \
                 "Empty lines:             " + emptyLines + "\n" \
                 "Comment lines:           " + commentLines + "\n" \
                 "Total lines:             " + totalLines

        if self.__editor is None:
            output = "Number of python files:  " + nFiles + "\n" \
                     "Total files size:        " + filesSize + " bytes\n" + \
                     output
        else:
            output = "Number of characters:    " + filesSize + "\n" + \
                     output

        self.resultEdit.setText( output )
        return
Ejemplo n.º 4
0
class ImportsDiagramProgress( QDialog ):
    " Progress of the diagram generator "

    def __init__( self, what, options, path = "", buf = "", parent = None ):
        QDialog.__init__( self, parent )
        self.__cancelRequest = False
        self.__inProgress = False

        self.__what = what
        self.__options = options
        self.__path = path          # could be a dir or a file
        self.__buf = buf            # content in case of a modified file

        # Working process data
        self.__participantFiles = []    # Collected list of files
        self.__projectImportDirs = []
        self.__projectImportsCache = {} # utils.settings -> /full/path/to.py
        self.__dirsToImportsCache = {}  # /dir/path -> { my.mod: path.py, ... }

        self.dataModel = ImportDiagramModel()
        self.scene = QGraphicsScene()

        # Avoid pylint complains
        self.progressBar = None
        self.infoLabel = None

        self.__createLayout()
        self.setWindowTitle( 'Imports/dependencies diagram generator' )
        QTimer.singleShot( 0, self.__process )
        return

    def keyPressEvent( self, event ):
        " Processes the ESC key specifically "
        if event.key() == Qt.Key_Escape:
            self.__onClose()
        else:
            QDialog.keyPressEvent( self, event )
        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 450, 20 )
        self.setSizeGripEnabled( True )

        verticalLayout = QVBoxLayout( self )

        # Info label
        self.infoLabel = QLabel( self )
        verticalLayout.addWidget( self.infoLabel )

        # Progress bar
        self.progressBar = QProgressBar( self )
        self.progressBar.setValue( 0 )
        self.progressBar.setOrientation( Qt.Horizontal )
        verticalLayout.addWidget( self.progressBar )

        # Buttons
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Close )
        verticalLayout.addWidget( buttonBox )

        buttonBox.rejected.connect( self.__onClose )
        return

    def __onClose( self ):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __buildParticipants( self ):
        " Builds a list of participating files and dirs "
        if self.__what in [ ImportsDiagramDialog.SingleBuffer,
                            ImportsDiagramDialog.SingleFile ]:
            # File exists but could be modified
            self.__path = os.path.realpath( self.__path )
            self.__participantFiles.append( self.__path )
            return

        if self.__what == ImportsDiagramDialog.ProjectFiles:
            self.__scanProjectDirs()
            return

        # This is a recursive directory
        self.__path = os.path.realpath( self.__path )
        self.__scanDirForPythonFiles( self.__path + os.path.sep )
        return

    def __scanDirForPythonFiles( self, path ):
        " Scans the directory for the python files recursively "
        for item in os.listdir( path ):
            if item in [ ".svn",  ".cvs" ]:
                continue
            if os.path.isdir( path + item ):
                self.__scanDirForPythonFiles( path + item + os.path.sep )
                continue
            if item.endswith( ".py" ) or item.endswith( ".py3" ):
                fName = os.path.realpath( path + item )
                # If it was a link, the target could be non-python
                if fName.endswith( ".py" ) or fName.endswith( ".py3" ):
                    self.__participantFiles.append( fName )
        return

    def __scanProjectDirs( self ):
        " Populates participant lists from the project files "
        for fName in GlobalData().project.filesList:
            if fName.endswith( ".py" ) or fName.endswith( ".py3" ):
                self.__participantFiles.append( fName )
        return

    def isProjectImport( self, importString ):
        " Checks if it is a project import string and provides a path if so "
        if importString in self.__projectImportsCache:
            return self.__projectImportsCache[ importString ]

        subpath = importString.replace( '.', os.path.sep )
        candidates = [ subpath + ".py", subpath + ".py3",
                       subpath + os.path.sep + "__init__.py",
                       subpath + os.path.sep + "__init__.py3" ]
        for path in self.__projectImportDirs:
            for item in candidates:
                fName = path + os.path.sep + item
                if os.path.isfile( fName ):
                    self.__projectImportsCache[ importString ] = fName
                    return fName
        return None

    def isLocalImport( self, dirName, importString ):
        " Checks if it is local dir import string and provides a path if so "
        dirFound = False
        if dirName in self.__dirsToImportsCache:
            dirFound = True
            importsDict = self.__dirsToImportsCache[ dirName ]
            if importString in importsDict:
                return importsDict[ importString ]

        subpath = importString.replace( '.', os.path.sep )
        candidates = [ subpath + ".py", subpath + ".py3",
                       subpath + os.path.sep + "__init__.py",
                       subpath + os.path.sep + "__init__.py3" ]
        for item in candidates:
            fName = dirName + os.path.sep + item
            if os.path.isfile( fName ):
                # Found on the FS. Add to the dictionary
                if dirFound:
                    importsDict[ importString ] = fName
                else:
                    self.__dirsToImportsCache[ dirName ] = { importString: fName }
                return fName
        return None

    def isSystemWideImport( self, importString ):
        " Provides a path to the system wide import or None "
        # Systemwide modules may not have a path if it is a
        # built-in module, or to have a path to an .so library
        try:
            path = getSystemWideModules()[ importString ]
            if path is None:
                return True, None
            if path.endswith( ".py" ):
                return True, path
            if path.endswith( ".py3" ):
                return True, path
            return True, None
        except:
            return False, None

    def __addBoxInfo( self, box, info ):
        " Adds information to the given box if so configured "
        if info.docstring is not None:
            box.docstring = info.docstring.text

        if self.__options.includeClasses:
            for klass in info.classes:
                box.classes.append( klass )

        if self.__options.includeFuncs:
            for func in info.functions:
                box.funcs.append( func )

        if self.__options.includeGlobs:
            for glob in info.globals:
                box.globs.append( glob )

        if self.__options.includeConnText:
            for imp in info.imports:
                box.imports.append( imp )

        return

    def __addDocstringBox( self, info, fName, modBoxName ):
        " Adds a docstring box if needed "
        if self.__options.includeDocs:
            if info.docstring is not None:
                docBox = DgmDocstring()
                docBox.docstring = info.docstring
                docBox.refFile = fName

                # Add the box and its connection
                docBoxName = self.dataModel.addDocstringBox( docBox )

                conn = DgmConnection()
                conn.kind = DgmConnection.ModuleDoc
                conn.source = modBoxName
                conn.target = docBoxName
                self.dataModel.addConnection( conn )

                # Add rank for better layout
                rank = DgmRank()
                rank.firstObj = modBoxName
                rank.secondObj = docBoxName
                self.dataModel.addRank( rank )
        return

    def __getSytemWideImportDocstring( self, path ):
        " Provides the system wide module docstring "
        if not path.endswith( '.py' ) and not path.endswith( '.py3' ):
            return ""

        try:
            info = GlobalData().briefModinfoCache.get( path )
            if info.docstring is not None:
                return info.docstring.text
            return ""
        except:
            return ""

    @staticmethod
    def __getModuleTitle( fName ):
        " Extracts a module name out of the file name "
        baseTitle = os.path.basename( fName ).split( '.' )[ 0 ]
        if baseTitle != "__init__":
            return baseTitle

        # __init__ is not very descriptive. Add a top level dir.
        dirName = os.path.dirname( fName )
        topDir = os.path.basename( dirName )
        return topDir + "(" + baseTitle + ")"

    def __addSingleFileToDataModel( self, info, fName ):
        " Adds a single file to the data model "
        if fName.endswith( "__init__.py" ) or \
           fName.endswith( "__init__.py3" ):
            if not info.classes and not info.functions and \
               not info.globals and not info.imports:
                # Skip dummy init files
                return

        modBox = DgmModule()
        modBox.refFile = fName

        modBox.kind = DgmModule.ModuleOfInterest
        modBox.title = self.__getModuleTitle( fName )

        self.__addBoxInfo( modBox, info )
        modBoxName = self.dataModel.addModule( modBox )
        self.__addDocstringBox( info, fName, modBoxName )

        # Add what is imported
        isProjectFile = GlobalData().project.isProjectFile( fName )
        for item in info.imports:
            impBox = DgmModule()

            importPath = None
            systemWideImportPath = None
            if isProjectFile:
                importPath = self.isProjectImport( item.name )
            if importPath is None:
                importPath = self.isLocalImport( os.path.dirname( fName ), item.name )

            if importPath is not None:
                impBox.kind = DgmModule.OtherProjectModule
                impBox.title = os.path.basename( importPath ).split( '.' )[ 0 ]
                impBox.refFile = importPath
                otherInfo = GlobalData().briefModinfoCache.get( importPath )

                # It's a local or project import
                self.__addBoxInfo( impBox, otherInfo )

            else:
                impBox.kind = DgmModule.UnknownModule
                impBox.title = item.name

                found, systemWideImportPath = self.isSystemWideImport( item.name )
                if found:
                    if systemWideImportPath is not None:
                        impBox.kind = DgmModule.SystemWideModule
                        impBox.refFile = systemWideImportPath
                        impBox.docstring = \
                            self.__getSytemWideImportDocstring( \
                                            systemWideImportPath )
                    else:
                        impBox.kind = DgmModule.BuiltInModule

            impBoxName = self.dataModel.addModule( impBox )

            impConn = DgmConnection()
            impConn.kind = DgmConnection.ModuleDependency
            impConn.source = modBoxName
            impConn.target = impBoxName

            if self.__options.includeConnText:
                for impWhat in item.what:
                    if impWhat.name != "":
                        impConn.labels.append( impWhat )
            self.dataModel.addConnection( impConn )

        return

    def __process( self ):
        " Accumulation process "

        # Intermediate working data
        self.__participantFiles = []
        self.__projectImportDirs = []
        self.__projectImportsCache = {}

        self.dataModel.clear()
        self.__inProgress = True

        try:
            self.infoLabel.setText( 'Building the list of files to analyze...' )
            QApplication.processEvents()

            # Build the list of participating python files
            self.__buildParticipants()
            self.__projectImportDirs = \
                        GlobalData().project.getImportDirsAsAbsolutePaths()


            QApplication.processEvents()
            if self.__cancelRequest == True:
                QApplication.restoreOverrideCursor()
                self.close()
                return

            self.progressBar.setRange( 0, len( self.__participantFiles ) )
            index = 1

            # Now, parse the files and build the diagram data model
            if self.__what == ImportsDiagramDialog.SingleBuffer:
                info = getBriefModuleInfoFromMemory( str( self.__buf ) )
                self.__addSingleFileToDataModel( info, self.__path )
            else:
                infoSrc = GlobalData().briefModinfoCache
                for fName in self.__participantFiles:
                    self.progressBar.setValue( index )
                    self.infoLabel.setText( 'Analyzing ' + fName + "..." )
                    QApplication.processEvents()
                    if self.__cancelRequest == True:
                        QApplication.restoreOverrideCursor()
                        self.dataModel.clear()
                        self.close()
                        return
                    info = infoSrc.get( fName )
                    self.__addSingleFileToDataModel( info, fName )
                    index += 1

            # The import caches and other working data are not needed anymore
            self.__participantFiles = None
            self.__projectImportDirs = None
            self.__projectImportsCache = None


            # Generating the graphviz layout
            self.infoLabel.setText( 'Generating layout using graphviz...' )
            QApplication.processEvents()

            graph = getGraphFromDescriptionData( self.dataModel.toGraphviz() )
            graph.normalize( self.physicalDpiX(), self.physicalDpiY() )
            QApplication.processEvents()
            if self.__cancelRequest == True:
                QApplication.restoreOverrideCursor()
                self.dataModel.clear()
                self.close()
                return

            # Generate graphics scene
            self.infoLabel.setText( 'Generating graphics scene...' )
            QApplication.processEvents()
            self.__buildGraphicsScene( graph )

            # Clear the data model
            self.dataModel = None
        except Exception, exc:
            QApplication.restoreOverrideCursor()
            logging.error( str( exc ) )
            self.__inProgress = False
            self.__onClose()
            return

        QApplication.restoreOverrideCursor()
        self.infoLabel.setText( 'Done' )
        QApplication.processEvents()
        self.__inProgress = False

        self.accept()
        return
Ejemplo n.º 5
0
class FindInFilesDialog(QDialog, object):
    """ find in files dialog implementation """

    inProject = 0
    inDirectory = 1
    inOpenFiles = 2

    def __init__(self, where, what="", dirPath="", filters=[], parent=None):

        QDialog.__init__(self, parent)

        mainWindow = GlobalData().mainWindow
        self.editorsManager = mainWindow.editorsManagerWidget.editorsManager

        self.__cancelRequest = False
        self.__inProgress = False
        self.searchRegexp = None
        self.searchResults = []

        # Avoid pylint complains
        self.findCombo = None
        self.caseCheckBox = None
        self.wordCheckBox = None
        self.regexpCheckBox = None
        self.projectRButton = None
        self.openFilesRButton = None
        self.dirRButton = None
        self.dirEditCombo = None
        self.dirSelectButton = None
        self.filterCombo = None
        self.fileLabel = None
        self.progressBar = None
        self.findButton = None

        self.__createLayout()
        self.setWindowTitle("Find in files")

        # Restore the combo box values
        project = GlobalData().project
        if project.fileName != "":
            self.findFilesWhat = project.findFilesWhat
            self.findFilesDirs = project.findFilesDirs
            self.findFilesMasks = project.findFilesMasks
        else:
            settings = Settings()
            self.findFilesWhat = settings.findFilesWhat
            self.findFilesDirs = settings.findFilesDirs
            self.findFilesMasks = settings.findFilesMasks
        self.findCombo.addItems(self.findFilesWhat)
        self.findCombo.setEditText("")
        self.dirEditCombo.addItems(self.findFilesDirs)
        self.dirEditCombo.setEditText("")
        self.filterCombo.addItems(self.findFilesMasks)
        self.filterCombo.setEditText("")

        if where == self.inProject:
            self.setSearchInProject(what, filters)
        elif where == self.inDirectory:
            self.setSearchInDirectory(what, dirPath, filters)
        else:
            self.setSearchInOpenFiles(what, filters)

        return

    def __createLayout(self):
        """ Creates the dialog layout """

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

        verticalLayout = QVBoxLayout(self)
        gridLayout = QGridLayout()

        # Combo box for the text to search
        findLabel = QLabel(self)
        findLabel.setText("Find text:")
        self.findCombo = QComboBox(self)
        self.__tuneCombo(self.findCombo)
        self.findCombo.lineEdit().setToolTip(
            "Regular expression to search for")
        self.findCombo.editTextChanged.connect(self.__someTextChanged)

        gridLayout.addWidget(findLabel, 0, 0, 1, 1)
        gridLayout.addWidget(self.findCombo, 0, 1, 1, 1)
        verticalLayout.addLayout(gridLayout)

        # Check boxes
        horizontalCBLayout = QHBoxLayout()
        self.caseCheckBox = QCheckBox(self)
        self.caseCheckBox.setText("Match &case")
        horizontalCBLayout.addWidget(self.caseCheckBox)
        self.wordCheckBox = QCheckBox(self)
        self.wordCheckBox.setText("Match whole &word")
        horizontalCBLayout.addWidget(self.wordCheckBox)
        self.regexpCheckBox = QCheckBox(self)
        self.regexpCheckBox.setText("Regular &expression")
        horizontalCBLayout.addWidget(self.regexpCheckBox)

        verticalLayout.addLayout(horizontalCBLayout)

        # Files groupbox
        filesGroupbox = QGroupBox(self)
        filesGroupbox.setTitle("Find in")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            filesGroupbox.sizePolicy().hasHeightForWidth())
        filesGroupbox.setSizePolicy(sizePolicy)

        gridLayoutFG = QGridLayout(filesGroupbox)
        self.projectRButton = QRadioButton(filesGroupbox)
        self.projectRButton.setText("&Project")
        gridLayoutFG.addWidget(self.projectRButton, 0, 0)
        self.projectRButton.clicked.connect(self.__projectClicked)

        self.openFilesRButton = QRadioButton(filesGroupbox)
        self.openFilesRButton.setText("&Opened files only")
        gridLayoutFG.addWidget(self.openFilesRButton, 1, 0)
        self.openFilesRButton.clicked.connect(self.__openFilesOnlyClicked)

        self.dirRButton = QRadioButton(filesGroupbox)
        self.dirRButton.setText("&Directory tree")
        gridLayoutFG.addWidget(self.dirRButton, 2, 0)
        self.dirRButton.clicked.connect(self.__dirClicked)

        self.dirEditCombo = QComboBox(filesGroupbox)
        self.__tuneCombo(self.dirEditCombo)
        self.dirEditCombo.lineEdit().setToolTip("Directory to search in")
        gridLayoutFG.addWidget(self.dirEditCombo, 2, 1)
        self.dirEditCombo.editTextChanged.connect(self.__someTextChanged)

        self.dirSelectButton = QPushButton(filesGroupbox)
        self.dirSelectButton.setText("...")
        gridLayoutFG.addWidget(self.dirSelectButton, 2, 2)
        self.dirSelectButton.clicked.connect(self.__selectDirClicked)

        filterLabel = QLabel(filesGroupbox)
        filterLabel.setText("Files filter:")
        gridLayoutFG.addWidget(filterLabel, 3, 0)
        self.filterCombo = QComboBox(filesGroupbox)
        self.__tuneCombo(self.filterCombo)
        self.filterCombo.lineEdit().setToolTip("File names regular expression")
        gridLayoutFG.addWidget(self.filterCombo, 3, 1)
        self.filterCombo.editTextChanged.connect(self.__someTextChanged)

        verticalLayout.addWidget(filesGroupbox)

        # File label
        self.fileLabel = FitPathLabel(self)
        self.fileLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        verticalLayout.addWidget(self.fileLabel)

        # Progress bar
        self.progressBar = QProgressBar(self)
        self.progressBar.setValue(0)
        self.progressBar.setOrientation(Qt.Horizontal)
        verticalLayout.addWidget(self.progressBar)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Cancel)
        self.findButton = buttonBox.addButton("Find",
                                              QDialogButtonBox.AcceptRole)
        self.findButton.setDefault(True)
        self.findButton.clicked.connect(self.__process)
        verticalLayout.addWidget(buttonBox)

        buttonBox.rejected.connect(self.__onClose)
        return

    @staticmethod
    def __tuneCombo(comboBox):
        " Sets the common settings for a combo box "
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth( \
                            comboBox.sizePolicy().hasHeightForWidth() )
        comboBox.setSizePolicy(sizePolicy)
        comboBox.setEditable(True)
        comboBox.setInsertPolicy(QComboBox.InsertAtTop)
        comboBox.setAutoCompletion(False)
        comboBox.setDuplicatesEnabled(False)
        return

    def __onClose(self):
        " Triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def setSearchInProject(self, what="", filters=[]):
        " Set search ready for the whole project "

        if GlobalData().project.fileName == "":
            # No project loaded, fallback to opened files
            self.setSearchInOpenFiles(what, filters)
            return

        # Select the project radio button
        self.projectRButton.setEnabled(True)
        self.projectRButton.setChecked(True)
        self.dirEditCombo.setEnabled(False)
        self.dirSelectButton.setEnabled(False)

        openedFiles = self.editorsManager.getTextEditors()
        self.openFilesRButton.setEnabled(len(openedFiles) != 0)

        self.setFilters(filters)

        self.findCombo.setEditText(what)
        self.findCombo.lineEdit().selectAll()
        self.findCombo.setFocus()

        # Check searchability
        self.__testSearchability()
        return

    def setSearchInOpenFiles(self, what="", filters=[]):
        " Sets search ready for the opened files "

        openedFiles = self.editorsManager.getTextEditors()
        if len(openedFiles) == 0:
            # No opened files, fallback to search in dir
            self.setSearchInDirectory(what, "", filters)
            return

        # Select the radio buttons
        self.projectRButton.setEnabled(GlobalData().project.fileName != "")
        self.openFilesRButton.setEnabled(True)
        self.openFilesRButton.setChecked(True)
        self.dirEditCombo.setEnabled(False)
        self.dirSelectButton.setEnabled(False)

        self.setFilters(filters)

        self.findCombo.setEditText(what)
        self.findCombo.lineEdit().selectAll()
        self.findCombo.setFocus()

        # Check searchability
        self.__testSearchability()
        return

    def setSearchInDirectory(self, what="", dirPath="", filters=[]):
        " Sets search ready for the given directory "

        # Select radio buttons
        self.projectRButton.setEnabled(GlobalData().project.fileName != "")
        openedFiles = self.editorsManager.getTextEditors()
        self.openFilesRButton.setEnabled(len(openedFiles) != 0)
        self.dirRButton.setEnabled(True)
        self.dirRButton.setChecked(True)
        self.dirEditCombo.setEnabled(True)
        self.dirSelectButton.setEnabled(True)
        self.dirEditCombo.setEditText(dirPath)

        self.setFilters(filters)

        self.findCombo.setEditText(what)
        self.findCombo.lineEdit().selectAll()
        self.findCombo.setFocus()

        # Check searchability
        self.__testSearchability()
        return

    def setFilters(self, filters):
        " Sets up the filters "

        # Set filters if provided
        if filters:
            self.filterCombo.setEditText(";".join(filters))
        else:
            self.filterCombo.setEditText("")
        return

    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 os.path.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:
            filterRe = re.compile(filtersText, re.IGNORECASE)
        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 = filterRe.match(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 = filterRe.match(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, filterRe, 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")
        return

    @staticmethod
    def __matchInDir(path, filterRe, startTime):
        " Provides the 'match' and 'too long' statuses "
        matched = False
        tooLong = False
        for item in os.listdir(path):
            if time.time() - startTime > 0.1:
                tooLong = True
                return matched, tooLong
            if os.path.isdir(path + item):
                dname = path + item + sep
                matched, tooLong = FindInFilesDialog.__matchInDir(
                    dname, filterRe, startTime)
                if matched or tooLong:
                    return matched, tooLong
                continue
            if filterRe.match(path + item):
                matched = True
                return matched, tooLong
        return matched, tooLong

    def __projectClicked(self):
        " project radio button clicked "
        self.dirEditCombo.setEnabled(False)
        self.dirSelectButton.setEnabled(False)
        self.__testSearchability()
        return

    def __openFilesOnlyClicked(self):
        " open files only radio button clicked "
        self.dirEditCombo.setEnabled(False)
        self.dirSelectButton.setEnabled(False)
        self.__testSearchability()
        return

    def __dirClicked(self):
        " dir radio button clicked "
        self.dirEditCombo.setEnabled(True)
        self.dirSelectButton.setEnabled(True)
        self.dirEditCombo.setFocus()
        self.__testSearchability()
        return

    def __someTextChanged(self, text):
        " Text to search, filter or dir name has been changed "
        self.__testSearchability()
        return

    def __selectDirClicked(self):
        " The user selects a directory "
        dirName = QFileDialog.getExistingDirectory(
            self, "Select directory to search in",
            self.dirEditCombo.currentText(),
            QFileDialog.Options(QFileDialog.ShowDirsOnly))

        if dirName:
            self.dirEditCombo.setEditText(os.path.normpath(dirName))
        self.__testSearchability()
        return

    def __projectFiles(self, filterRe):
        " Project files list respecting the mask "
        mainWindow = GlobalData().mainWindow
        files = []
        for fname in GlobalData().project.filesList:
            if fname.endswith(sep):
                continue
            if filterRe is None or filterRe.match(fname):
                widget = mainWindow.getWidgetForFileName(fname)
                if widget is None:
                    # Do not check for broken symlinks
                    if isFileSearchable(fname, False):
                        files.append(ItemToSearchIn(fname, ""))
                else:
                    if widget.getType() in \
                                [ MainWindowTabWidgetBase.PlainTextEditor ]:
                        files.append(ItemToSearchIn(fname, widget.getUUID()))
            QApplication.processEvents()
            if self.__cancelRequest:
                raise Exception("Cancel request")
        return files

    def __openedFiles(self, filterRe):
        " Currently opened editor buffers "

        files = []
        openedFiles = self.editorsManager.getTextEditors()
        for record in openedFiles:
            uuid = record[0]
            fname = record[1]
            if filterRe is None or filterRe.match(fname):
                files.append(ItemToSearchIn(fname, uuid))
            QApplication.processEvents()
            if self.__cancelRequest:
                raise Exception("Cancel request")
        return files

    def __dirFiles(self, path, filterRe, files):
        " Files recursively for the dir "
        for item in os.listdir(path):
            QApplication.processEvents()
            if self.__cancelRequest:
                raise Exception("Cancel request")
            if os.path.isdir(path + item):
                if item in [".svn", ".cvs"]:
                    # It does not make sense to search in revision control dirs
                    continue
                anotherDir, isLoop = resolveLink(path + item)
                if not isLoop:
                    self.__dirFiles(anotherDir + sep, filterRe, files)
                continue
            if not os.path.isfile(path + item):
                continue
            realItem, isLoop = resolveLink(path + item)
            if isLoop:
                continue
            if filterRe is None or filterRe.match(realItem):
                found = False
                for itm in files:
                    if itm.fileName == realItem:
                        found = True
                        break
                if not found:
                    mainWindow = GlobalData().mainWindow
                    widget = mainWindow.getWidgetForFileName(realItem)
                    if widget is None:
                        if isFileSearchable(realItem):
                            files.append(ItemToSearchIn(realItem, ""))
                    else:
                        if widget.getType() in \
                                    [ MainWindowTabWidgetBase.PlainTextEditor ]:
                            files.append(
                                ItemToSearchIn(realItem, widget.getUUID()))
        return

    def __buildFilesList(self):
        " Builds the list of files to search in "
        filtersText = self.filterCombo.currentText().strip()
        if filtersText != "":
            filterRe = re.compile(filtersText, re.IGNORECASE)
        else:
            filterRe = None

        if self.projectRButton.isChecked():
            return self.__projectFiles(filterRe)

        if self.openFilesRButton.isChecked():
            return self.__openedFiles(filterRe)

        dirname = os.path.realpath(self.dirEditCombo.currentText().strip())
        files = []
        self.__dirFiles(dirname + sep, filterRe, files)
        return files

    def __process(self):
        " Search process "

        # Add entries to the combo box if required
        regexpText = self.findCombo.currentText()
        if regexpText in self.findFilesWhat:
            self.findFilesWhat.remove(regexpText)
        self.findFilesWhat.insert(0, regexpText)
        if len(self.findFilesWhat) > 32:
            self.findFilesWhat = self.findFilesWhat[:32]
        self.findCombo.clear()
        self.findCombo.addItems(self.findFilesWhat)

        filtersText = self.filterCombo.currentText().strip()
        if filtersText in self.findFilesMasks:
            self.findFilesMasks.remove(filtersText)
        self.findFilesMasks.insert(0, filtersText)
        if len(self.findFilesMasks) > 32:
            self.findFilesMasks = self.findFilesMasks[:32]
        self.filterCombo.clear()
        self.filterCombo.addItems(self.findFilesMasks)

        if self.dirRButton.isChecked():
            dirText = self.dirEditCombo.currentText().strip()
            if dirText in self.findFilesDirs:
                self.findFilesDirs.remove(dirText)
            self.findFilesDirs.insert(0, dirText)
            if len(self.findFilesDirs) > 32:
                self.findFilesDirs = self.findFilesDirs[:32]
            self.dirEditCombo.clear()
            self.dirEditCombo.addItems(self.findFilesDirs)

        # Save the combo values for further usage
        if GlobalData().project.fileName != "":
            GlobalData().project.setFindInFilesHistory(self.findFilesWhat,
                                                       self.findFilesDirs,
                                                       self.findFilesMasks)
        else:
            Settings().findFilesWhat = self.findFilesWhat
            Settings().findFilesDirs = self.findFilesDirs
            Settings().findFilesMasks = self.findFilesMasks

        self.__inProgress = True
        numberOfMatches = 0
        self.searchResults = []
        self.searchRegexp = None

        # Form the regexp to search
        if not self.regexpCheckBox.isChecked():
            regexpText = re.escape(regexpText)
        if self.wordCheckBox.isChecked():
            regexpText = "\\b%s\\b" % regexpText
        flags = re.UNICODE | re.LOCALE
        if not self.caseCheckBox.isChecked():
            flags |= re.IGNORECASE

        try:
            self.searchRegexp = re.compile(regexpText, flags)
        except:
            logging.error("Invalid search expression")
            self.close()
            return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.fileLabel.setPath('Building list of files to search in...')
        QApplication.processEvents()
        try:
            files = self.__buildFilesList()
        except Exception, exc:
            if "Cancel request" in str(exc):
                QApplication.restoreOverrideCursor()
                self.close()
                return
            else:
                QApplication.restoreOverrideCursor()
                logging.error(str(exc))
                self.close()
                return
        QApplication.restoreOverrideCursor()
        QApplication.processEvents()

        if len(files) == 0:
            self.fileLabel.setPath('No files to search in')
            return

        self.progressBar.setRange(0, len(files))

        index = 1
        for item in files:

            if self.__cancelRequest:
                self.__inProgress = False
                self.close()
                return

            self.fileLabel.setPath( 'Matches: ' + str( numberOfMatches ) + \
                                    ' Processing: ' + item.fileName )

            item.search(self.searchRegexp)
            found = len(item.matches)
            if found > 0:
                numberOfMatches += found
                self.searchResults.append(item)

            self.progressBar.setValue(index)
            index += 1

            QApplication.processEvents()

        if numberOfMatches == 0:
            if len(files) == 1:
                self.fileLabel.setPath("No matches in 1 file.")
            else:
                self.fileLabel.setPath( "No matches in " + \
                                        str( len( files ) ) + " files." )
            self.__inProgress = False
        else:
            self.close()
        return
Ejemplo n.º 6
0
class ErrorLabel(QWidget):
    WARNING, ERROR = range(2)

    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.ticks = 5
        self.elapsedTicks = 0
        self.lastSeverity = None
        self.icon_label = QLabel()
        self.icon_label.setGeometry(0, 0, 48, 48)
        self.message_edit = QTextEdit()
        self.message_edit.setReadOnly(True)
        self.message_edit.setFrameStyle(QFrame.NoFrame)
        palette = self.message_edit.palette()
        palette.setBrush(QPalette.Base, QBrush())
        self.message_edit.setPalette(palette)
        self.time_bar = QProgressBar()
        self.time_bar.setOrientation(Qt.Vertical)
        self.time_bar.setMaximum(self.ticks)
        self.time_bar.setTextVisible(False)
        self.pauseButton = QPushButton(QIcon(QPixmap(":/icons/images/pause.png")), "")
        self.pauseButton.setFixedSize(32, 32)
        self.connect(self.pauseButton, SIGNAL('clicked()'), self.stopTimer)
        self.stopButton = QPushButton(QIcon(QPixmap(":/icons/images/stop.png")), "")
        self.stopButton.setFixedSize(32, 32)
        self.connect(self.stopButton, SIGNAL('clicked()'), self.closeWidget)
        self.layout = QGridLayout(self)
        self.layout.addWidget(self.time_bar, 0, 0, 2, 1)
        self.layout.addWidget(self.icon_label, 0, 1, 2, 1)
        self.layout.addWidget(self.message_edit, 0, 2, 2, 1)
        self.layout.addWidget(self.pauseButton, 0, 3)
        self.layout.addWidget(self.stopButton, 1, 3)
        self.layout.setColumnStretch(2, 1)
        self.setAutoFillBackground(True)
        self.timer = QTimer()
        self.connect(self.timer, SIGNAL("timeout()"), self.decrementTime)

    def stopTimer(self):
        self.timer.stop()
        self.pauseButton.setEnabled(False)

    def closeWidget(self):
        self.timer.stop()
        QWidget.hide(self)

    @pyqtSlot()
    def decrementTime(self):
        if self.elapsedTicks == self.ticks:
            self.hide()
            self.timer.stop()
        else:
            self.elapsedTicks += 1
            self.time_bar.setValue(self.ticks - self.elapsedTicks)

    def updatePosition(self):
        self.setGeometry(0, self.parent().height() - self.height(), self.width(), self.height())

    def setSize(self, w, h):
        self.setGeometry(0, self.parent().height() - h, w, h)

    def setErrorMessage(self, msg):
        self.lastSeverity = self.ERROR
        self.icon_label.setPixmap(QApplication.style().standardIcon(QStyle.SP_MessageBoxCritical).pixmap(48, 48))
        self._setMessage(msg)

    def setWarningMessage(self, msg):
        self.lastSeverity = self.WARNING
        self.icon_label.setPixmap(QApplication.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48))
        self._setMessage(msg)

    def _setMessage(self, msg):
        self.message_edit.setText(msg)
        self.updatePosition()
        self.elapsedTicks = 0
        self.time_bar.setValue(self.ticks)
        self.timer.start(1000)
        self.pauseButton.setEnabled(True)
        self.show()
Ejemplo n.º 7
0
class ViewDataTools(QMainWindow):
    def __init__(self, parent=None):
        super(ViewDataTools, self).__init__(parent)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # DATATOOLS WINDOWS:
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        self.setWindowTitle(ui_strings.DATATOOLS_TITLE)
        self._width = 680
        self._height = 560
        self._left_margin = 10
        self.resize(self._width, self._height)
        size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)
        size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(size_policy)
        self.setMinimumSize(QtCore.QSize(self._width, self._height))
        self.setMaximumSize(QtCore.QSize(self._width, self._height))
        self.setWindowIcon(QIcon(resources.ICON_LOGO))

        # central widget
        self.central_widget = QWidget(self)

        # DataTools description
        self.lbl_description = QLabel(self.central_widget)
        self.lbl_description.setGeometry(QtCore.QRect(0, 0, self._width, 30))
        self.lbl_description.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_description.setText(ui_strings.DATATOOLS_DESCRIPTION)

        # group input files
        self.group_input_file = QGroupBox(self.central_widget)
        self.group_input_file.setGeometry(QtCore.QRect(self._left_margin, 30, 660, 80))
        self.group_input_file.setTitle(ui_strings.DATATOOLS_GROUP_INPUT)

        # frame input files
        self.frame_inputs = QFrame(self.group_input_file)
        self.frame_inputs.setGeometry(QtCore.QRect(self._left_margin, 0, 270, 80))
        self.frame_inputs.setFrameShape(QFrame.StyledPanel)
        self.frame_inputs.setFrameShadow(QFrame.Raised)

        # label input type
        self.lbl_input_type = QLabel(self.frame_inputs)
        self.lbl_input_type.setGeometry(QtCore.QRect(20, 20, 60, 15))
        self.lbl_input_type.setText(ui_strings.DATATOOLS_INPUT_TYPE)

        # button xls
        self.btn_xls = QToolButton(self.frame_inputs)
        self.btn_xls.setGeometry(QtCore.QRect(20, 35, 35, 35))
        icon_xls = QIcon()
        icon_xls.addPixmap(QPixmap(resources.ICON_XLS), QIcon.Normal, QIcon.Off)
        self.btn_xls.setIcon(icon_xls)
        self.btn_xls.setIconSize(QtCore.QSize(24, 24))
        self.btn_xls.setCheckable(True)
        self.btn_xls.setAutoExclusive(True)
        self.btn_xls.setObjectName("xls_button")

        # button csv
        self.btn_csv = QToolButton(self.frame_inputs)
        self.btn_csv.setGeometry(QtCore.QRect(60, 35, 35, 35))
        icon_csv = QIcon()
        icon_csv.addPixmap(QPixmap(resources.ICON_CSV), QIcon.Normal, QIcon.Off)
        self.btn_csv.setIcon(icon_csv)
        self.btn_csv.setIconSize(QtCore.QSize(24, 24))
        self.btn_csv.setCheckable(True)
        self.btn_csv.setAutoExclusive(True)
        self.btn_csv.setObjectName("csv_button")

        # checkbox csv with headers
        self.chk_csv_headers = QCheckBox(ui_strings.DATATOOLS_WITH_HEADERS, self.frame_inputs)
        self.chk_csv_headers.setGeometry(QtCore.QRect(100, 45, 110, 15))
        self.chk_csv_headers.setEnabled(False)

        # TextEdit + PushButton (FindFolder)
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # lbl sheet name
        self.lbl_file_path = QLabel(self.group_input_file)
        self.lbl_file_path.setGeometry(QtCore.QRect(250, 20, 120, 15))
        self.lbl_file_path.setText(ui_strings.DATATOOLS_SELECT_FILE)

        self.txt_file = QLineEdit(self.group_input_file)
        self.txt_file.setGeometry(QtCore.QRect(250, 35, 160, 20))
        self.txt_file.setReadOnly(True)

        self.btn_path = QPushButton(self.group_input_file)
        self.btn_path.setGeometry(QtCore.QRect(410, 34, 50, 22))
        self.btn_path.setText(ui_strings.DATATOOLS_SELECT_BUTTON)
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        # lbl sheet name
        self.lbl_sheet_name = QLabel(self.group_input_file)
        self.lbl_sheet_name.setGeometry(QtCore.QRect(500, 20, 120, 15))
        self.lbl_sheet_name.setText(ui_strings.DATATOOLS_SHEET_NAME)

        # Combobox select sheet - initially does not contain values
        self.cbo_sheet = QComboBox(self.group_input_file)
        self.cbo_sheet.setGeometry(QtCore.QRect(500, 35, 130, 20))

        # data grid to visualize error messages
        self.tbl_errors = QTableWidget(self.central_widget)
        self.tbl_errors.setGeometry(QtCore.QRect(self._left_margin, 420, 660, 100))

        # data grid to visualize those records with errors.
        self.tbl_uploaded_data = QTableWidget(self.central_widget)
        self.tbl_uploaded_data.setGeometry(QtCore.QRect(self._left_margin, 120, 500, 220))

        # group run options
        self.group_run_options = QGroupBox(self.central_widget)
        self.group_run_options.setGeometry(QtCore.QRect(520, 120, 150, 220))
        self.group_run_options.setTitle(ui_strings.DATATOOLS_GROUP_RUN)

        # Errors summary:
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # group summary errors
        self.group_errors = QGroupBox(self.central_widget)
        self.group_errors.setGeometry(QtCore.QRect(self._left_margin, 350, 660, 60))
        self.group_errors.setTitle(ui_strings.DATATOOLS_HEADER_ERRORS)

        # lbl records
        self.lbl_records = QLabel(self.group_errors)
        self.lbl_records.setGeometry(QtCore.QRect(165, 15, 80, 15))
        self.lbl_records.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_records.setText(ui_strings.DATATOOLS_RECORDS)

        self.txt_records = QLineEdit(self.group_errors)
        self.txt_records.setGeometry(QtCore.QRect(165, 30, 80, 20))
        self.txt_records.setAlignment(QtCore.Qt.AlignCenter)
        self.txt_records.setReadOnly(True)

        # lbl errors
        self.lbl_errors = QLabel(self.group_errors)
        self.lbl_errors.setGeometry(QtCore.QRect(275, 15, 80, 15))
        self.lbl_errors.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_errors.setText(ui_strings.DATATOOLS_ERRORS)

        self.txt_errors = QLineEdit(self.group_errors)
        self.txt_errors.setGeometry(QtCore.QRect(275, 30, 80, 20))
        self.txt_errors.setAlignment(QtCore.Qt.AlignCenter)
        self.txt_errors.setReadOnly(True)

        # lbl time
        self.lbl_time = QLabel(self.group_errors)
        self.lbl_time.setGeometry(QtCore.QRect(385, 15, 80, 15))
        self.lbl_time.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_time.setText(ui_strings.DATATOOLS_TIME)

        self.txt_time = QLineEdit(self.group_errors)
        self.txt_time.setGeometry(QtCore.QRect(385, 30, 80, 20))
        self.txt_time.setAlignment(QtCore.Qt.AlignCenter)
        self.txt_time.setReadOnly(True)

        # history button
        self.btn_history = QToolButton(self.group_errors)
        self.btn_history.setGeometry(QtCore.QRect(500, 25, 100, 25))
        icon_history = QIcon()
        icon_history.addPixmap(QPixmap(resources.ICON_HISTORY), QIcon.Normal, QIcon.Off)
        self.btn_history.setIcon(icon_history)
        self.btn_history.setIconSize(QtCore.QSize(20, 20))
        self.btn_history.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        self.btn_history.setText(ui_strings.DATATOOLS_HISTORY)
        self.btn_history.setCheckable(True)
        self.btn_history.setAutoExclusive(True)
        self.btn_history.setObjectName("history_button")
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        # btn data uploader
        self.btn_data_uploader = QPushButton(ui_strings.DATATOOLS_DATA_UPLOADER, self.group_run_options)
        self.btn_data_uploader.setGeometry(QtCore.QRect(10, 120, 90, 25))
        self.btn_data_uploader.setCheckable(True)
        self.btn_data_uploader.setAutoExclusive(True)
        self.btn_data_uploader.setFlat(False)

        # btn data testing
        self.btn_data_testing = QPushButton(ui_strings.DATATOOLS_DATA_TESTING, self.group_run_options)
        self.btn_data_testing.setEnabled(False)
        self.btn_data_testing.setGeometry(QtCore.QRect(10, 150, 90, 25))
        self.btn_data_testing.setCheckable(True)
        self.btn_data_testing.setAutoExclusive(True)

        # btn data to database
        self.btn_data_db = QPushButton(ui_strings.DATATOOLS_DATA_DB, self.group_run_options)
        self.btn_data_db.setEnabled(False)
        self.btn_data_db.setGeometry(QtCore.QRect(10, 179, 91, 23))
        self.btn_data_db.setCheckable(True)
        self.btn_data_db.setAutoExclusive(True)

        # frame run options
        self.frame_run = QFrame(self.group_run_options)
        self.frame_run.setGeometry(QtCore.QRect(10, 30, 130, 80))
        self.frame_run.setFrameShape(QFrame.StyledPanel)
        self.frame_run.setFrameShadow(QFrame.Raised)

        # option process until first error
        self.rbtn_process_error = QRadioButton(ui_strings.DATATOOLS_PROCESS_ERROR, self.frame_run)
        self.rbtn_process_error.setGeometry(QtCore.QRect(0, 0, 150, 20))

        # option process all data
        self.rbtn_process_all = QRadioButton(ui_strings.DATATOOLS_PROCESS_ALL, self.frame_run)
        self.rbtn_process_all.setGeometry(QtCore.QRect(0, 20, 150, 30))

        # checkbox to filter by records with errors.
        #self.chk_filter_errors = QCheckBox(ui_strings.DATATOOLS_FILTER_ERRORS, self.frame_run)
        #self.chk_filter_errors.setGeometry(QtCore.QRect(0, 50, 100, 15))
        #self.chk_filter_errors.setEnabled(False)

        # icons -> pass - error: Initially are empty labels
        # if not started -> ICON_MINI_WAIT
        # if error -> ICON_DELETE
        # if pass -> ICON_CHECK

        # state icon data uploader
        self.lbl_state_du = QLabel(self.group_run_options)
        self.lbl_state_du.setGeometry(QtCore.QRect(110, 120, 20, 20))
        self.lbl_state_du.setPixmap(QPixmap(resources.ICON_MINI_WAIT))
        self.lbl_state_du.setScaledContents(True)

        # state icon data to database
        self.lbl_state_dt = QLabel(self.group_run_options)
        self.lbl_state_dt.setGeometry(QtCore.QRect(110, 150, 20, 20))
        self.lbl_state_dt.setPixmap(QPixmap(resources.ICON_MINI_WAIT))
        self.lbl_state_dt.setScaledContents(True)

         # state icon data testing
        self.lbl_state_db = QLabel(self.group_run_options)
        self.lbl_state_db.setGeometry(QtCore.QRect(110, 180, 20, 20))
        self.lbl_state_db.setPixmap(QPixmap(resources.ICON_MINI_WAIT))
        self.lbl_state_db.setScaledContents(True)

        # progress bar
        self.progress_bar = QProgressBar(self.central_widget)
        self.progress_bar.setGeometry(QtCore.QRect(self._left_margin, 530, 660, 15))
        self.progress_bar.setMaximum(100)
        self.progress_bar.setProperty("value", 0)
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setOrientation(QtCore.Qt.Horizontal)
        self.progress_bar.setInvertedAppearance(False)
        self.progress_bar.setTextDirection(QProgressBar.TopToBottom)

        self.setCentralWidget(self.central_widget)
Ejemplo n.º 8
0
class NotUsedAnalysisProgress( QDialog ):
    " Progress of the not used analysis "

    Functions = 0
    Classes   = 1
    Globals   = 2

    def __init__( self, what, sourceModel, parent = None ):
        QDialog.__init__( self, parent )

        if what not in [ self.Functions, self.Classes, self.Globals ]:
            raise Exception( "Unsupported unused analysis type: " + \
                             str( what ) )

        self.__cancelRequest = False
        self.__inProgress = False

        self.__what = what              # what is in source model
        self.__srcModel = sourceModel   # source model of globals or
                                        # functions or classes

        # Avoid pylint complains
        self.__progressBar = None
        self.__infoLabel = None
        self.__foundLabel = None
        self.__found = 0        # Number of found

        self.__createLayout()
        self.setWindowTitle( self.__formTitle() )
        QTimer.singleShot( 0, self.__process )
        return

    def keyPressEvent( self, event ):
        " Processes the ESC key specifically "
        if event.key() == Qt.Key_Escape:
            self.__onClose()
        else:
            QDialog.keyPressEvent( self, event )
        return

    def __formTitle( self ):
        " Forms the progress dialog title "
        title = "Unused "
        if self.__what == self.Functions:
            title += 'function'
        elif self.__what == self.Classes:
            title += 'class'
        else:
            title += 'globlal variable'
        return title + " analysis"

    def __formInfoLabel( self, name ):
        " Forms the info label "
        if self.__what == self.Functions:
            return 'Function: ' + name
        if self.__what == self.Classes:
            return 'Class: ' + name
        return 'Globlal variable: ' + name

    def __whatAsString( self ):
        " Provides 'what' as string "
        if self.__what == self.Functions:
            return 'function'
        if self.__what == self.Classes:
            return 'class'
        return 'global variable'

    def __updateFoundLabel( self ):
        " Updates the found label "
        text = "Found: " + str( self.__found ) + " candidate"
        if self.__found != 1:
            text += "s"
        self.__foundLabel.setText( text )
        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 450, 20 )
        self.setSizeGripEnabled( True )

        verticalLayout = QVBoxLayout( self )

        # Note label
        noteLabel = QLabel( "<b>Note</b>: the analysis is " \
                            "suggestive and not precise. " \
                            "Use the results with caution.\n", self )
        verticalLayout.addWidget( noteLabel )

        # Info label
        self.__infoLabel = QLabel( self )
        verticalLayout.addWidget( self.__infoLabel )

        # Progress bar
        self.__progressBar = QProgressBar( self )
        self.__progressBar.setValue( 0 )
        self.__progressBar.setOrientation( Qt.Horizontal )
        verticalLayout.addWidget( self.__progressBar )

        # Found label
        self.__foundLabel = QLabel( self )
        verticalLayout.addWidget( self.__foundLabel )

        # Buttons
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Close )
        verticalLayout.addWidget( buttonBox )

        buttonBox.rejected.connect( self.__onClose )
        return

    def __onClose( self ):
        " triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def __process( self ):
        " Analysis process "

        self.__inProgress = True

        mainWindow = GlobalData().mainWindow
        editorsManager = mainWindow.editorsManagerWidget.editorsManager
        modified = editorsManager.getModifiedList( True ) # True - only project files
        if modified:
            modNames = [ modItem[ 0 ] for modItem in modified ]
            label = "File"
            if len( modified ) >= 2:
                label += "s"
            label += ": "
            logging.warning( "The analisys is performed for the content of saved files. " \
                             "The unsaved modifications will not be taken into account. " \
                             + label + ", ".join( modNames ) )

        self.__updateFoundLabel()
        self.__progressBar.setRange( 0,
                                   len( self.__srcModel.rootItem.childItems ) )
        QApplication.processEvents()
        QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) )

        count = 0
        candidates = []
        for treeItem in self.__srcModel.rootItem.childItems:
            if self.__cancelRequest:
                break

            name = str( treeItem.data( 0 ) ).split( '(' )[ 0 ]
            path = os.path.realpath( treeItem.getPath() )
            lineNumber = int( treeItem.data( 2 ) )
            absPosition = treeItem.sourceObj.absPosition

            count += 1
            self.__progressBar.setValue( count )
            self.__infoLabel.setText( self.__formInfoLabel( name ) )
            QApplication.processEvents()

            # Analyze the name
            found = False
            try:
                # True is for throwing exceptions
                locations = getOccurrences( path, absPosition, True )

                if len( locations ) == 1 and \
                   locations[ 0 ][ 1 ] == lineNumber:
                    found = True
                    index = getSearchItemIndex( candidates, path )
                    if index < 0:
                        widget = mainWindow.getWidgetForFileName( path )
                        if widget is None:
                            uuid = ""
                        else:
                            uuid = widget.getUUID()
                        newItem = ItemToSearchIn( path, uuid )
                        candidates.append( newItem )
                        index = len( candidates ) - 1
                    candidates[ index ].addMatch( name, lineNumber )

            except Exception, exc:
                # There is nothing interesting with exceptions here.
                # It seems to me that rope throws them in case if the same item
                # is declared multiple times in a file. I also suspect that
                # exceptions may come up in case of syntactic errors.
                # So I just suppress them.
                pass

                #logging.warning( "Error detected while analysing " + \
                #                 self.__whatAsString() + " '" + name + \
                #                 "'. Message: " + str( exc ) )

            if found:
                self.__found += 1
                self.__updateFoundLabel()
            QApplication.processEvents()

        if self.__found == 0:
            # The analysis could be interrupted
            if not self.__cancelRequest:
                logging.info( "No unused candidates found" )
        else:
            mainWindow.displayFindInFiles( "", candidates )

        QApplication.restoreOverrideCursor()
        self.__infoLabel.setText( 'Done' )
        self.__inProgress = False

        self.accept()
        return
Ejemplo n.º 9
0
class ViewDataTools(QMainWindow):
    def __init__(self, parent=None):
        super(ViewDataTools, self).__init__(parent)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # DATATOOLS WINDOWS:
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        self.setWindowTitle(ui_strings.DATATOOLS_TITLE)
        self._width = 680
        self._height = 560
        self._left_margin = 10
        self.resize(self._width, self._height)
        size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)
        size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(size_policy)
        self.setMinimumSize(QtCore.QSize(self._width, self._height))
        self.setMaximumSize(QtCore.QSize(self._width, self._height))
        self.setWindowIcon(QIcon(resources.ICON_LOGO))

        # central widget
        self.central_widget = QWidget(self)

        # DataTools description
        self.lbl_description = QLabel(self.central_widget)
        self.lbl_description.setGeometry(QtCore.QRect(0, 0, self._width, 30))
        self.lbl_description.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_description.setText(ui_strings.DATATOOLS_DESCRIPTION)

        # group input files
        self.group_input_file = QGroupBox(self.central_widget)
        self.group_input_file.setGeometry(
            QtCore.QRect(self._left_margin, 30, 660, 80))
        self.group_input_file.setTitle(ui_strings.DATATOOLS_GROUP_INPUT)

        # frame input files
        self.frame_inputs = QFrame(self.group_input_file)
        self.frame_inputs.setGeometry(
            QtCore.QRect(self._left_margin, 0, 270, 80))
        self.frame_inputs.setFrameShape(QFrame.StyledPanel)
        self.frame_inputs.setFrameShadow(QFrame.Raised)

        # label input type
        self.lbl_input_type = QLabel(self.frame_inputs)
        self.lbl_input_type.setGeometry(QtCore.QRect(20, 20, 60, 15))
        self.lbl_input_type.setText(ui_strings.DATATOOLS_INPUT_TYPE)

        # button xls
        self.btn_xls = QToolButton(self.frame_inputs)
        self.btn_xls.setGeometry(QtCore.QRect(20, 35, 35, 35))
        icon_xls = QIcon()
        icon_xls.addPixmap(QPixmap(resources.ICON_XLS), QIcon.Normal,
                           QIcon.Off)
        self.btn_xls.setIcon(icon_xls)
        self.btn_xls.setIconSize(QtCore.QSize(24, 24))
        self.btn_xls.setCheckable(True)
        self.btn_xls.setAutoExclusive(True)
        self.btn_xls.setObjectName("xls_button")

        # button csv
        self.btn_csv = QToolButton(self.frame_inputs)
        self.btn_csv.setGeometry(QtCore.QRect(60, 35, 35, 35))
        icon_csv = QIcon()
        icon_csv.addPixmap(QPixmap(resources.ICON_CSV), QIcon.Normal,
                           QIcon.Off)
        self.btn_csv.setIcon(icon_csv)
        self.btn_csv.setIconSize(QtCore.QSize(24, 24))
        self.btn_csv.setCheckable(True)
        self.btn_csv.setAutoExclusive(True)
        self.btn_csv.setObjectName("csv_button")

        # checkbox csv with headers
        self.chk_csv_headers = QCheckBox(ui_strings.DATATOOLS_WITH_HEADERS,
                                         self.frame_inputs)
        self.chk_csv_headers.setGeometry(QtCore.QRect(100, 45, 110, 15))
        self.chk_csv_headers.setEnabled(False)

        # TextEdit + PushButton (FindFolder)
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # lbl sheet name
        self.lbl_file_path = QLabel(self.group_input_file)
        self.lbl_file_path.setGeometry(QtCore.QRect(250, 20, 120, 15))
        self.lbl_file_path.setText(ui_strings.DATATOOLS_SELECT_FILE)

        self.txt_file = QLineEdit(self.group_input_file)
        self.txt_file.setGeometry(QtCore.QRect(250, 35, 160, 20))
        self.txt_file.setReadOnly(True)

        self.btn_path = QPushButton(self.group_input_file)
        self.btn_path.setGeometry(QtCore.QRect(410, 34, 50, 22))
        self.btn_path.setText(ui_strings.DATATOOLS_SELECT_BUTTON)
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        # lbl sheet name
        self.lbl_sheet_name = QLabel(self.group_input_file)
        self.lbl_sheet_name.setGeometry(QtCore.QRect(500, 20, 120, 15))
        self.lbl_sheet_name.setText(ui_strings.DATATOOLS_SHEET_NAME)

        # Combobox select sheet - initially does not contain values
        self.cbo_sheet = QComboBox(self.group_input_file)
        self.cbo_sheet.setGeometry(QtCore.QRect(500, 35, 130, 20))

        # data grid to visualize error messages
        self.tbl_errors = QTableWidget(self.central_widget)
        self.tbl_errors.setGeometry(
            QtCore.QRect(self._left_margin, 420, 660, 100))

        # data grid to visualize those records with errors.
        self.tbl_uploaded_data = QTableWidget(self.central_widget)
        self.tbl_uploaded_data.setGeometry(
            QtCore.QRect(self._left_margin, 120, 500, 220))

        # group run options
        self.group_run_options = QGroupBox(self.central_widget)
        self.group_run_options.setGeometry(QtCore.QRect(520, 120, 150, 220))
        self.group_run_options.setTitle(ui_strings.DATATOOLS_GROUP_RUN)

        # Errors summary:
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # group summary errors
        self.group_errors = QGroupBox(self.central_widget)
        self.group_errors.setGeometry(
            QtCore.QRect(self._left_margin, 350, 660, 60))
        self.group_errors.setTitle(ui_strings.DATATOOLS_HEADER_ERRORS)

        # lbl records
        self.lbl_records = QLabel(self.group_errors)
        self.lbl_records.setGeometry(QtCore.QRect(165, 15, 80, 15))
        self.lbl_records.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_records.setText(ui_strings.DATATOOLS_RECORDS)

        self.txt_records = QLineEdit(self.group_errors)
        self.txt_records.setGeometry(QtCore.QRect(165, 30, 80, 20))
        self.txt_records.setAlignment(QtCore.Qt.AlignCenter)
        self.txt_records.setReadOnly(True)

        # lbl errors
        self.lbl_errors = QLabel(self.group_errors)
        self.lbl_errors.setGeometry(QtCore.QRect(275, 15, 80, 15))
        self.lbl_errors.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_errors.setText(ui_strings.DATATOOLS_ERRORS)

        self.txt_errors = QLineEdit(self.group_errors)
        self.txt_errors.setGeometry(QtCore.QRect(275, 30, 80, 20))
        self.txt_errors.setAlignment(QtCore.Qt.AlignCenter)
        self.txt_errors.setReadOnly(True)

        # lbl time
        self.lbl_time = QLabel(self.group_errors)
        self.lbl_time.setGeometry(QtCore.QRect(385, 15, 80, 15))
        self.lbl_time.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_time.setText(ui_strings.DATATOOLS_TIME)

        self.txt_time = QLineEdit(self.group_errors)
        self.txt_time.setGeometry(QtCore.QRect(385, 30, 80, 20))
        self.txt_time.setAlignment(QtCore.Qt.AlignCenter)
        self.txt_time.setReadOnly(True)

        # history button
        self.btn_history = QToolButton(self.group_errors)
        self.btn_history.setGeometry(QtCore.QRect(500, 25, 100, 25))
        icon_history = QIcon()
        icon_history.addPixmap(QPixmap(resources.ICON_HISTORY), QIcon.Normal,
                               QIcon.Off)
        self.btn_history.setIcon(icon_history)
        self.btn_history.setIconSize(QtCore.QSize(20, 20))
        self.btn_history.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        self.btn_history.setText(ui_strings.DATATOOLS_HISTORY)
        self.btn_history.setCheckable(True)
        self.btn_history.setAutoExclusive(True)
        self.btn_history.setObjectName("history_button")
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        # btn data uploader
        self.btn_data_uploader = QPushButton(
            ui_strings.DATATOOLS_DATA_UPLOADER, self.group_run_options)
        self.btn_data_uploader.setGeometry(QtCore.QRect(10, 120, 90, 25))
        self.btn_data_uploader.setCheckable(True)
        self.btn_data_uploader.setAutoExclusive(True)
        self.btn_data_uploader.setFlat(False)

        # btn data testing
        self.btn_data_testing = QPushButton(ui_strings.DATATOOLS_DATA_TESTING,
                                            self.group_run_options)
        self.btn_data_testing.setEnabled(False)
        self.btn_data_testing.setGeometry(QtCore.QRect(10, 150, 90, 25))
        self.btn_data_testing.setCheckable(True)
        self.btn_data_testing.setAutoExclusive(True)

        # btn data to database
        self.btn_data_db = QPushButton(ui_strings.DATATOOLS_DATA_DB,
                                       self.group_run_options)
        self.btn_data_db.setEnabled(False)
        self.btn_data_db.setGeometry(QtCore.QRect(10, 179, 91, 23))
        self.btn_data_db.setCheckable(True)
        self.btn_data_db.setAutoExclusive(True)

        # frame run options
        self.frame_run = QFrame(self.group_run_options)
        self.frame_run.setGeometry(QtCore.QRect(10, 30, 130, 80))
        self.frame_run.setFrameShape(QFrame.StyledPanel)
        self.frame_run.setFrameShadow(QFrame.Raised)

        # option process until first error
        self.rbtn_process_error = QRadioButton(
            ui_strings.DATATOOLS_PROCESS_ERROR, self.frame_run)
        self.rbtn_process_error.setGeometry(QtCore.QRect(0, 0, 150, 20))

        # option process all data
        self.rbtn_process_all = QRadioButton(ui_strings.DATATOOLS_PROCESS_ALL,
                                             self.frame_run)
        self.rbtn_process_all.setGeometry(QtCore.QRect(0, 20, 150, 30))

        # checkbox to filter by records with errors.
        #self.chk_filter_errors = QCheckBox(ui_strings.DATATOOLS_FILTER_ERRORS, self.frame_run)
        #self.chk_filter_errors.setGeometry(QtCore.QRect(0, 50, 100, 15))
        #self.chk_filter_errors.setEnabled(False)

        # icons -> pass - error: Initially are empty labels
        # if not started -> ICON_MINI_WAIT
        # if error -> ICON_DELETE
        # if pass -> ICON_CHECK

        # state icon data uploader
        self.lbl_state_du = QLabel(self.group_run_options)
        self.lbl_state_du.setGeometry(QtCore.QRect(110, 120, 20, 20))
        self.lbl_state_du.setPixmap(QPixmap(resources.ICON_MINI_WAIT))
        self.lbl_state_du.setScaledContents(True)

        # state icon data to database
        self.lbl_state_dt = QLabel(self.group_run_options)
        self.lbl_state_dt.setGeometry(QtCore.QRect(110, 150, 20, 20))
        self.lbl_state_dt.setPixmap(QPixmap(resources.ICON_MINI_WAIT))
        self.lbl_state_dt.setScaledContents(True)

        # state icon data testing
        self.lbl_state_db = QLabel(self.group_run_options)
        self.lbl_state_db.setGeometry(QtCore.QRect(110, 180, 20, 20))
        self.lbl_state_db.setPixmap(QPixmap(resources.ICON_MINI_WAIT))
        self.lbl_state_db.setScaledContents(True)

        # progress bar
        self.progress_bar = QProgressBar(self.central_widget)
        self.progress_bar.setGeometry(
            QtCore.QRect(self._left_margin, 530, 660, 15))
        self.progress_bar.setMaximum(100)
        self.progress_bar.setProperty("value", 0)
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setOrientation(QtCore.Qt.Horizontal)
        self.progress_bar.setInvertedAppearance(False)
        self.progress_bar.setTextDirection(QProgressBar.TopToBottom)

        self.setCentralWidget(self.central_widget)
Ejemplo n.º 10
0
class MessageDialog(QWidget):
	def __init__(self, mailList, jobID = '', sec = 0, parent = None):
		QWidget.__init__(self, parent)
		self.prnt = parent
		self.jobID = jobID
		self.sec = sec
		self.frozen = False
		self.tr = self.prnt.prnt.tr
		self.setWindowTitle(self.tr._translate('M@il Checker : MailView Dialog'))
		self.setStyleSheet("QWidget {background: rgba(235,240,255,128);}")
		self.mailList = QLabel(mailList)
		self.layout = QVBoxLayout()
		self.buttonLayout = QHBoxLayout()
		
		self.ok = QPushButton(QIcon.fromTheme("dialog-ok"), "", self)
		self.cancel = QPushButton(QIcon.fromTheme("dialog-cancel"), "", self)
		self.freezMSG = QPushButton(QIcon.fromTheme("layer-visible-on"), '', self)
		self.freezMSG.setToolTip(self.tr._translate('Freez message'))
		self.ok.setMaximumHeight(15)
		self.freezMSG.setMaximumHeight(15)
		self.cancel.setMaximumHeight(15)
		self.ok.clicked.connect(self.accepted)
		self.freezMSG.clicked.connect(self.freez)
		self.cancel.clicked.connect(self.rejected)
		self.buttonLayout.addWidget(self.ok)
		self.buttonLayout.addWidget(self.freezMSG)
		self.buttonLayout.addWidget(self.cancel)

		self.layout.addWidget(self.mailList)
		if sec :
			self.lifetime = QProgressBar()
			self.lifetime.setOrientation(Qt.Horizontal)
			self.lifetime.setMinimum(0)
			self.lifetime.setMaximum(sec)
			self.lifetime.setValue(sec)
			self.lifetime.setMaximumHeight(7)
			self.layout.addWidget(self.lifetime)
			self.lifetimeID = self.startTimer(1000)
		self.layout.addItem(self.buttonLayout)

		self.setLayout(self.layout)
		self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		self.setMinimumWidth(100)

	def accepted(self):
		self.prnt.prnt.viewJob.emit(self.jobID)
		if self.prnt.prnt.SoundEnabled :
			self.prnt.prnt.sound.Accepted.play()
		self.close()

	def rejected(self, common = False):
		if self.prnt.prnt.SoundEnabled and not common :
			self.prnt.prnt.sound.Cleared.play()
		self.close()

	def freez(self, common = False):
		if self.sec : self.killTimer(self.lifetimeID)
		self.setStyleSheet("QWidget {background: rgba(100,175,255,25);}")
		self.frozen = True
		self.freezMSG.setEnabled(False)
		if self.prnt.prnt.SoundEnabled and not common :
			self.prnt.prnt.sound.Frozen.play()

	def timerEvent(self, ev):
		if ev.type()==QEvent.Timer :
			value = self.lifetime.value()
			#print ev.timerId(), value
			if value > self.lifetime.minimum() :
				self.lifetime.setValue(value-1)
			else :
				self.close()

	def isFrozen(self): return self.frozen

	def closeEvent(self, ev):
		if ev.type()==QEvent.Close :
			if self.sec : self.killTimer(self.lifetimeID)
			self.prnt.checkEmpty.emit(self.jobID)
			self.prnt.prnt.clearJob.emit(self.jobID)
			ev.accept()
		else : ev.ignore()
Ejemplo n.º 11
0
class FindInFilesDialog( QDialog, object ):
    """ find in files dialog implementation """

    inProject = 0
    inDirectory = 1
    inOpenFiles = 2

    def __init__( self, where, what = "",
                  dirPath = "", filters = [],
                  parent = None ):

        QDialog.__init__( self, parent )

        mainWindow = GlobalData().mainWindow
        self.editorsManager = mainWindow.editorsManagerWidget.editorsManager

        self.__cancelRequest = False
        self.__inProgress = False
        self.searchRegexp = None
        self.searchResults = []

        # Avoid pylint complains
        self.findCombo = None
        self.caseCheckBox = None
        self.wordCheckBox = None
        self.regexpCheckBox = None
        self.projectRButton = None
        self.openFilesRButton = None
        self.dirRButton = None
        self.dirEditCombo = None
        self.dirSelectButton = None
        self.filterCombo = None
        self.fileLabel = None
        self.progressBar = None
        self.findButton = None

        self.__createLayout()
        self.setWindowTitle( "Find in files" )

        # Restore the combo box values
        project = GlobalData().project
        if project.fileName != "":
            self.findFilesWhat = project.findFilesWhat
            self.findFilesDirs = project.findFilesDirs
            self.findFilesMasks = project.findFilesMasks
        else:
            settings = Settings()
            self.findFilesWhat = settings.findFilesWhat
            self.findFilesDirs = settings.findFilesDirs
            self.findFilesMasks = settings.findFilesMasks
        self.findCombo.addItems( self.findFilesWhat )
        self.findCombo.setEditText( "" )
        self.dirEditCombo.addItems( self.findFilesDirs )
        self.dirEditCombo.setEditText( "" )
        self.filterCombo.addItems( self.findFilesMasks )
        self.filterCombo.setEditText( "" )

        if where == self.inProject:
            self.setSearchInProject( what, filters )
        elif where == self.inDirectory:
            self.setSearchInDirectory( what, dirPath, filters )
        else:
            self.setSearchInOpenFiles( what, filters )

        return

    def __createLayout( self ):
        """ Creates the dialog layout """

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

        verticalLayout = QVBoxLayout( self )
        gridLayout = QGridLayout()

        # Combo box for the text to search
        findLabel = QLabel( self )
        findLabel.setText( "Find text:" )
        self.findCombo = QComboBox( self )
        self.__tuneCombo( self.findCombo )
        self.findCombo.lineEdit().setToolTip( "Regular expression to search for" )
        self.findCombo.editTextChanged.connect( self.__someTextChanged )

        gridLayout.addWidget( findLabel, 0, 0, 1, 1 )
        gridLayout.addWidget( self.findCombo, 0, 1, 1, 1 )
        verticalLayout.addLayout( gridLayout )

        # Check boxes
        horizontalCBLayout = QHBoxLayout()
        self.caseCheckBox = QCheckBox( self )
        self.caseCheckBox.setText( "Match &case" )
        horizontalCBLayout.addWidget( self.caseCheckBox )
        self.wordCheckBox = QCheckBox( self )
        self.wordCheckBox.setText( "Match whole &word" )
        horizontalCBLayout.addWidget( self.wordCheckBox )
        self.regexpCheckBox = QCheckBox( self )
        self.regexpCheckBox.setText( "Regular &expression" )
        horizontalCBLayout.addWidget( self.regexpCheckBox )

        verticalLayout.addLayout( horizontalCBLayout )

        # Files groupbox
        filesGroupbox = QGroupBox( self )
        filesGroupbox.setTitle( "Find in" )
        sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred )
        sizePolicy.setHorizontalStretch( 0 )
        sizePolicy.setVerticalStretch( 0 )
        sizePolicy.setHeightForWidth(
                        filesGroupbox.sizePolicy().hasHeightForWidth() )
        filesGroupbox.setSizePolicy( sizePolicy )

        gridLayoutFG = QGridLayout( filesGroupbox )
        self.projectRButton = QRadioButton( filesGroupbox )
        self.projectRButton.setText( "&Project" )
        gridLayoutFG.addWidget( self.projectRButton, 0, 0 )
        self.projectRButton.clicked.connect( self.__projectClicked )

        self.openFilesRButton = QRadioButton( filesGroupbox )
        self.openFilesRButton.setText( "&Opened files only" )
        gridLayoutFG.addWidget( self.openFilesRButton, 1, 0 )
        self.openFilesRButton.clicked.connect( self.__openFilesOnlyClicked )

        self.dirRButton = QRadioButton( filesGroupbox )
        self.dirRButton.setText( "&Directory tree" )
        gridLayoutFG.addWidget( self.dirRButton, 2, 0 )
        self.dirRButton.clicked.connect( self.__dirClicked )

        self.dirEditCombo = QComboBox( filesGroupbox )
        self.__tuneCombo( self.dirEditCombo )
        self.dirEditCombo.lineEdit().setToolTip( "Directory to search in" )
        gridLayoutFG.addWidget( self.dirEditCombo, 2, 1 )
        self.dirEditCombo.editTextChanged.connect( self.__someTextChanged )

        self.dirSelectButton = QPushButton( filesGroupbox )
        self.dirSelectButton.setText( "..." )
        gridLayoutFG.addWidget( self.dirSelectButton, 2, 2 )
        self.dirSelectButton.clicked.connect( self.__selectDirClicked )

        filterLabel = QLabel( filesGroupbox )
        filterLabel.setText( "Files filter:" )
        gridLayoutFG.addWidget( filterLabel, 3, 0 )
        self.filterCombo = QComboBox( filesGroupbox )
        self.__tuneCombo( self.filterCombo )
        self.filterCombo.lineEdit().setToolTip( "File names regular expression" )
        gridLayoutFG.addWidget( self.filterCombo, 3, 1 )
        self.filterCombo.editTextChanged.connect( self.__someTextChanged )

        verticalLayout.addWidget( filesGroupbox )

        # File label
        self.fileLabel = FitPathLabel( self )
        self.fileLabel.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed )
        verticalLayout.addWidget( self.fileLabel )

        # Progress bar
        self.progressBar = QProgressBar( self )
        self.progressBar.setValue( 0 )
        self.progressBar.setOrientation( Qt.Horizontal )
        verticalLayout.addWidget( self.progressBar )

        # Buttons at the bottom
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Cancel )
        self.findButton = buttonBox.addButton( "Find",
                                               QDialogButtonBox.AcceptRole )
        self.findButton.setDefault( True )
        self.findButton.clicked.connect( self.__process )
        verticalLayout.addWidget( buttonBox )

        buttonBox.rejected.connect( self.__onClose )
        return

    @staticmethod
    def __tuneCombo( comboBox ):
        " Sets the common settings for a combo box "
        sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed )
        sizePolicy.setHorizontalStretch( 0 )
        sizePolicy.setVerticalStretch( 0 )
        sizePolicy.setHeightForWidth( \
                            comboBox.sizePolicy().hasHeightForWidth() )
        comboBox.setSizePolicy( sizePolicy )
        comboBox.setEditable( True )
        comboBox.setInsertPolicy( QComboBox.InsertAtTop )
        comboBox.setAutoCompletion( False )
        comboBox.setDuplicatesEnabled( False )
        return

    def __onClose( self ):
        " Triggered when the close button is clicked "

        self.__cancelRequest = True
        if not self.__inProgress:
            self.close()
        return

    def setSearchInProject( self, what = "", filters = [] ):
        " Set search ready for the whole project "

        if GlobalData().project.fileName == "":
            # No project loaded, fallback to opened files
            self.setSearchInOpenFiles( what, filters )
            return

        # Select the project radio button
        self.projectRButton.setEnabled( True )
        self.projectRButton.setChecked( True )
        self.dirEditCombo.setEnabled( False )
        self.dirSelectButton.setEnabled( False )

        openedFiles = self.editorsManager.getTextEditors()
        self.openFilesRButton.setEnabled( len( openedFiles ) != 0 )

        self.setFilters( filters )

        self.findCombo.setEditText( what )
        self.findCombo.lineEdit().selectAll()
        self.findCombo.setFocus()

        # Check searchability
        self.__testSearchability()
        return


    def setSearchInOpenFiles( self, what = "", filters = [] ):
        " Sets search ready for the opened files "

        openedFiles = self.editorsManager.getTextEditors()
        if len( openedFiles ) == 0:
            # No opened files, fallback to search in dir
            self.setSearchInDirectory( what, "", filters )
            return

        # Select the radio buttons
        self.projectRButton.setEnabled( GlobalData().project.fileName != "" )
        self.openFilesRButton.setEnabled( True )
        self.openFilesRButton.setChecked( True )
        self.dirEditCombo.setEnabled( False )
        self.dirSelectButton.setEnabled( False )

        self.setFilters( filters )

        self.findCombo.setEditText( what )
        self.findCombo.lineEdit().selectAll()
        self.findCombo.setFocus()

        # Check searchability
        self.__testSearchability()
        return


    def setSearchInDirectory( self, what = "", dirPath = "", filters = [] ):
        " Sets search ready for the given directory "

        # Select radio buttons
        self.projectRButton.setEnabled( GlobalData().project.fileName != "" )
        openedFiles = self.editorsManager.getTextEditors()
        self.openFilesRButton.setEnabled( len( openedFiles ) != 0 )
        self.dirRButton.setEnabled( True )
        self.dirRButton.setChecked( True )
        self.dirEditCombo.setEnabled( True )
        self.dirSelectButton.setEnabled( True )
        self.dirEditCombo.setEditText( dirPath )

        self.setFilters( filters )

        self.findCombo.setEditText( what )
        self.findCombo.lineEdit().selectAll()
        self.findCombo.setFocus()

        # Check searchability
        self.__testSearchability()
        return


    def setFilters( self, filters ):
        " Sets up the filters "

        # Set filters if provided
        if filters:
            self.filterCombo.setEditText( ";".join( filters ) )
        else:
            self.filterCombo.setEditText( "" )
        return

    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 os.path.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:
            filterRe = re.compile( filtersText, re.IGNORECASE )
        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 = filterRe.match( 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 = filterRe.match( 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, filterRe, 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" )
        return

    @staticmethod
    def __matchInDir( path, filterRe, startTime ):
        " Provides the 'match' and 'too long' statuses "
        matched = False
        tooLong = False
        for item in os.listdir( path ):
            if time.time() - startTime > 0.1:
                tooLong = True
                return matched, tooLong
            if os.path.isdir( path + item ):
                dname = path + item + sep
                matched, tooLong = FindInFilesDialog.__matchInDir( dname,
                                                                   filterRe,
                                                                   startTime )
                if matched or tooLong:
                    return matched, tooLong
                continue
            if filterRe.match( path + item ):
                matched = True
                return matched, tooLong
        return matched, tooLong

    def __projectClicked( self ):
        " project radio button clicked "
        self.dirEditCombo.setEnabled( False )
        self.dirSelectButton.setEnabled( False )
        self.__testSearchability()
        return

    def __openFilesOnlyClicked( self ):
        " open files only radio button clicked "
        self.dirEditCombo.setEnabled( False )
        self.dirSelectButton.setEnabled( False )
        self.__testSearchability()
        return

    def __dirClicked( self ):
        " dir radio button clicked "
        self.dirEditCombo.setEnabled( True )
        self.dirSelectButton.setEnabled( True )
        self.dirEditCombo.setFocus()
        self.__testSearchability()
        return

    def __someTextChanged( self, text ):
        " Text to search, filter or dir name has been changed "
        self.__testSearchability()
        return

    def __selectDirClicked( self ):
        " The user selects a directory "
        dirName = QFileDialog.getExistingDirectory( self,
                    "Select directory to search in",
                    self.dirEditCombo.currentText(),
                    QFileDialog.Options( QFileDialog.ShowDirsOnly ) )

        if dirName:
            self.dirEditCombo.setEditText( os.path.normpath( dirName ) )
        self.__testSearchability()
        return


    def __projectFiles( self, filterRe ):
        " Project files list respecting the mask "
        mainWindow = GlobalData().mainWindow
        files = []
        for fname in GlobalData().project.filesList:
            if fname.endswith( sep ):
                continue
            if filterRe is None or filterRe.match( fname ):
                widget = mainWindow.getWidgetForFileName( fname )
                if widget is None:
                    # Do not check for broken symlinks
                    if isFileSearchable( fname, False ):
                        files.append( ItemToSearchIn( fname, "" ) )
                else:
                    if widget.getType() in \
                                [ MainWindowTabWidgetBase.PlainTextEditor ]:
                        files.append( ItemToSearchIn( fname,
                                                      widget.getUUID() ) )
            QApplication.processEvents()
            if self.__cancelRequest:
                raise Exception( "Cancel request" )
        return files

    def __openedFiles( self, filterRe ):
        " Currently opened editor buffers "

        files = []
        openedFiles = self.editorsManager.getTextEditors()
        for record in openedFiles:
            uuid = record[ 0 ]
            fname = record[ 1 ]
            if filterRe is None or filterRe.match( fname ):
                files.append( ItemToSearchIn( fname, uuid ) )
            QApplication.processEvents()
            if self.__cancelRequest:
                raise Exception( "Cancel request" )
        return files

    def __dirFiles( self, path, filterRe, files ):
        " Files recursively for the dir "
        for item in os.listdir( path ):
            QApplication.processEvents()
            if self.__cancelRequest:
                raise Exception( "Cancel request" )
            if os.path.isdir( path + item ):
                if item in [ ".svn", ".cvs" ]:
                    # It does not make sense to search in revision control dirs
                    continue
                anotherDir, isLoop = resolveLink( path + item )
                if not isLoop:
                    self.__dirFiles( anotherDir + sep,
                                     filterRe, files )
                continue
            if not os.path.isfile( path + item ):
                continue
            realItem, isLoop = resolveLink( path + item )
            if isLoop:
                continue
            if filterRe is None or filterRe.match( realItem ):
                found = False
                for itm in files:
                    if itm.fileName == realItem:
                        found = True
                        break
                if not found:
                    mainWindow = GlobalData().mainWindow
                    widget = mainWindow.getWidgetForFileName( realItem )
                    if widget is None:
                        if isFileSearchable( realItem ):
                            files.append( ItemToSearchIn( realItem, "" ) )
                    else:
                        if widget.getType() in \
                                    [ MainWindowTabWidgetBase.PlainTextEditor ]:
                            files.append( ItemToSearchIn( realItem,
                                                          widget.getUUID() ) )
        return


    def __buildFilesList( self ):
        " Builds the list of files to search in "
        filtersText = self.filterCombo.currentText().strip()
        if filtersText != "":
            filterRe = re.compile( filtersText, re.IGNORECASE )
        else:
            filterRe = None

        if self.projectRButton.isChecked():
            return self.__projectFiles( filterRe )

        if self.openFilesRButton.isChecked():
            return self.__openedFiles( filterRe )

        dirname = os.path.realpath( self.dirEditCombo.currentText().strip() )
        files = []
        self.__dirFiles( dirname + sep, filterRe, files )
        return files


    def __process( self ):
        " Search process "

        # Add entries to the combo box if required
        regexpText = self.findCombo.currentText()
        if regexpText in self.findFilesWhat:
            self.findFilesWhat.remove( regexpText )
        self.findFilesWhat.insert( 0, regexpText )
        if len( self.findFilesWhat ) > 32:
            self.findFilesWhat = self.findFilesWhat[ : 32 ]
        self.findCombo.clear()
        self.findCombo.addItems( self.findFilesWhat )

        filtersText = self.filterCombo.currentText().strip()
        if filtersText in self.findFilesMasks:
            self.findFilesMasks.remove( filtersText )
        self.findFilesMasks.insert( 0, filtersText )
        if len( self.findFilesMasks ) > 32:
            self.findFilesMasks = self.findFilesMasks[ : 32 ]
        self.filterCombo.clear()
        self.filterCombo.addItems( self.findFilesMasks )

        if self.dirRButton.isChecked():
            dirText = self.dirEditCombo.currentText().strip()
            if dirText in self.findFilesDirs:
                self.findFilesDirs.remove( dirText )
            self.findFilesDirs.insert( 0, dirText )
            if len( self.findFilesDirs ) > 32:
                self.findFilesDirs = self.findFilesDirs[ : 32 ]
            self.dirEditCombo.clear()
            self.dirEditCombo.addItems( self.findFilesDirs )

        # Save the combo values for further usage
        if GlobalData().project.fileName != "":
            GlobalData().project.setFindInFilesHistory( self.findFilesWhat,
                                                        self.findFilesDirs,
                                                        self.findFilesMasks )
        else:
            Settings().findFilesWhat = self.findFilesWhat
            Settings().findFilesDirs = self.findFilesDirs
            Settings().findFilesMasks = self.findFilesMasks


        self.__inProgress = True
        numberOfMatches = 0
        self.searchResults = []
        self.searchRegexp = None

        # Form the regexp to search
        if not self.regexpCheckBox.isChecked():
            regexpText = re.escape( regexpText )
        if self.wordCheckBox.isChecked():
            regexpText = "\\b%s\\b" % regexpText
        flags = re.UNICODE | re.LOCALE
        if not self.caseCheckBox.isChecked():
            flags |= re.IGNORECASE

        try:
            self.searchRegexp = re.compile( regexpText, flags )
        except:
            logging.error( "Invalid search expression" )
            self.close()
            return


        QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) )
        self.fileLabel.setPath( 'Building list of files to search in...' )
        QApplication.processEvents()
        try:
            files = self.__buildFilesList()
        except Exception, exc:
            if "Cancel request" in str( exc ):
                QApplication.restoreOverrideCursor()
                self.close()
                return
            else:
                QApplication.restoreOverrideCursor()
                logging.error( str( exc ) )
                self.close()
                return
        QApplication.restoreOverrideCursor()
        QApplication.processEvents()

        if len( files ) == 0:
            self.fileLabel.setPath( 'No files to search in' )
            return

        self.progressBar.setRange( 0, len( files ) )

        index = 1
        for item in files:

            if self.__cancelRequest:
                self.__inProgress = False
                self.close()
                return

            self.fileLabel.setPath( 'Matches: ' + str( numberOfMatches ) + \
                                    ' Processing: ' + item.fileName )

            item.search( self.searchRegexp )
            found = len( item.matches )
            if found > 0:
                numberOfMatches += found
                self.searchResults.append( item )

            self.progressBar.setValue( index )
            index += 1

            QApplication.processEvents()

        if numberOfMatches == 0:
            if len( files ) == 1:
                self.fileLabel.setPath( "No matches in 1 file." )
            else:
                self.fileLabel.setPath( "No matches in " + \
                                        str( len( files ) ) + " files." )
            self.__inProgress = False
        else:
            self.close()
        return