def onFSChanged( self, items ): " Triggered when filesystem has changes " addedPythonFiles = [] deletedPythonFiles = [] for path in items: path = str( path ) if path.endswith( os.path.sep ): continue # dirs are out of interest if path.startswith( '+' ): path = path[ 1: ] if detectFileType( path ) not in [ PythonFileType, Python3FileType ]: continue addedPythonFiles.append( path ) else: path = path[ 1: ] if detectFileType( path ) not in [ PythonFileType, Python3FileType ]: continue deletedPythonFiles.append( path ) if addedPythonFiles or deletedPythonFiles: if self.__model.onFSChanged( addedPythonFiles, deletedPythonFiles ): # Need resort and counter updates self.layoutDisplay() self.updateCounter() self.model().setFilterRegExp( "" ) self.emit( SIGNAL( 'modelFilesChanged' ) ) return
def updateLinkStatus(self, path): " Called to update the status to/from broken link " if not self.isLink: return self.fileType = detectFileType(path) self.icon = getFileIcon(self.fileType) if self.fileType == BrokenSymlinkFileType: self.toolTip = self.__brokenLinkTooltip(path) return self.toolTip = self.__linkTooltip(path) self.icon = PixmapCache().getIcon('filelink.png') self.fileType = detectFileType(os.path.realpath(path)) return
def updateLinkStatus( self, path ): " Called to update the status to/from broken link " if not self.isLink: return self.fileType = detectFileType( path ) self.icon = getFileIcon( self.fileType ) if self.fileType == BrokenSymlinkFileType: self.toolTip = self.__brokenLinkTooltip( path ) return self.toolTip = self.__linkTooltip( path ) self.icon = PixmapCache().getIcon( 'filelink.png' ) self.fileType = detectFileType( os.path.realpath( path ) ) return
def onFileUpdated(self, fileName, uuid): " Triggered when the file is updated " fileType = detectFileType(fileName) if fileType in [PythonFileType, Python3FileType]: path = os.path.realpath(fileName) info = GlobalData().briefModinfoCache.get(path) if info.isOK: icon = PixmapCache().getIcon("filepython.png") else: icon = PixmapCache().getIcon("filepythonbroken.png") # For all root items for treeItem in self.model().sourceModel().rootItem.childItems: self.__walkTreeAndUpdate(treeItem, path, fileType, icon, info) elif fileType == CodimensionProjectFileType: path = os.path.realpath(fileName) # For all root items for treeItem in self.model().sourceModel().rootItem.childItems: self.__walkTreeAndUpdate(treeItem, path, fileType, None, None) elif fileName.endswith(".cgi"): path = os.path.realpath(fileName) icon = getFileIcon(fileType) # For all root items for treeItem in self.model().sourceModel().rootItem.childItems: self.__walkTreeAndUpdate(treeItem, path, fileType, icon, None) return
def __scanDir( prefix, path, infoLabel = None ): " Recursive scan for modules " if infoLabel is not None: infoLabel.setText( "Scanning " + path + "..." ) QApplication.processEvents() result = [] for item in os.listdir( path ): if item in [ ".svn", ".cvs" ]: continue if os.path.isdir( path + item ): result += __scanDir( prefix + item + ".", path + item + os.path.sep, infoLabel ) continue fileType = detectFileType( path + item ) if fileType not in [ PythonFileType, Python3FileType ]: continue if item.startswith( '__init__.' ): if prefix != "": result.append( prefix[ : -1 ] ) continue nameParts = item.split( '.' ) result.append( prefix + nameParts[ 0 ] ) return result
def __onSavedBufferAs( self, fileName, uuid ): " Triggered when a file is saved with a new name " if uuid in self.__outlineBrowsers: baseName = os.path.basename( fileName ) if detectFileType( fileName ) not in [ PythonFileType, Python3FileType ]: # It's not a python file anymore if uuid == self.__currentUUID: self.__outlineBrowsers[ uuid ].browser.hide() self.__noneLabel.show() self.__currentUUID = None del self.__outlineBrowsers[ uuid ] self.showParsingErrorsButton.setEnabled( False ) self.findButton.setEnabled( False ) return # Still python file with a different name browser = self.__outlineBrowsers[ uuid ].browser self.__outlineBrowsers[ uuid ].shortFileName = baseName if self.__outlineBrowsers[ uuid ].changed: title = self.__modifiedFormat % baseName else: title = baseName browser.model().sourceModel().updateRootData( 0, title ) return
def onFileUpdated(self, fileName, uuid): " Triggered when the file is updated " fileType = detectFileType(fileName) if fileType in [PythonFileType, Python3FileType]: path = os.path.realpath(fileName) info = GlobalData().briefModinfoCache.get(path) if info.isOK: icon = PixmapCache().getIcon('filepython.png') else: icon = PixmapCache().getIcon('filepythonbroken.png') # For all root items for treeItem in self.model().sourceModel().rootItem.childItems: self.__walkTreeAndUpdate(treeItem, path, fileType, icon, info) elif fileType == CodimensionProjectFileType: path = os.path.realpath(fileName) # For all root items for treeItem in self.model().sourceModel().rootItem.childItems: self.__walkTreeAndUpdate(treeItem, path, fileType, None, None) elif fileName.endswith(".cgi"): path = os.path.realpath(fileName) icon = getFileIcon(fileType) # For all root items for treeItem in self.model().sourceModel().rootItem.childItems: self.__walkTreeAndUpdate(treeItem, path, fileType, icon, None) return
def showReport(self, regexp, results): " Shows the find in files results " self.__clear() self.__noneLabel.hide() self.__reportRegexp = regexp self.__reportResults = results # Add the complete information totalMatched = 0 for item in results: matched = len(item.matches) totalMatched += matched if matched == 1: matchText = " (1 match)" else: matchText = " (" + str(matched) + " matches)" columns = [item.fileName, matchText] fileItem = MatchTableFileItem(columns, item.bufferUUID) fileItem.setIcon(0, getFileIcon(detectFileType(item.fileName))) if item.tooltip != "": fileItem.setToolTip(0, item.tooltip) self.__resultsTree.addTopLevelItem(fileItem) # Matches for match in item.matches: columns = [str(match.line), match.text] matchItem = MatchTableItem(columns, match.tooltip) fileItem.addChild(matchItem) fileItem.setExpanded(True) # Update the header with the total number of matches headerLabels = [ "File name / line (total files: " + str(len(results)) + ")", "Text (total matches: " + str(totalMatched) + ")" ] self.__resultsTree.setHeaderLabels(headerLabels) # Resizing the table self.__resultsTree.header().resizeSections( QHeaderView.ResizeToContents) # Show the complete information self.__resultsTree.show() self.__resultsTree.buildCache() self.__reportShown = True self.__updateButtonsStatus() # Connect the buffer change signal if not connected yet if not self.__bufferChangeconnected: self.__bufferChangeconnected = True mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.bufferModified.connect( self.__resultsTree.onBufferModified) return
def __init__( self, parent, path ): path = str( path ) TreeViewItem.__init__( self, parent, os.path.basename( path ) ) self.itemType = FileItemType self.parsingErrors = False # Used for python files only self.isLink = False self.fileType = detectFileType( path ) self.icon = getFileIcon( self.fileType ) if self.fileType == BrokenSymlinkFileType: self.isLink = True self.toolTip = self.__brokenLinkTooltip( path ) return if os.path.islink( path ): self.isLink = True self.toolTip = self.__linkTooltip( path ) self.icon = PixmapCache().getIcon( 'filelink.png' ) self.fileType = detectFileType( os.path.realpath( path ) ) return # Fine corrections for some file types if self.fileType in [ PythonFileType, Python3FileType ]: self.populated = False self.lazyPopulation = True return if self.fileType == LinguistFileType: if path.endswith( '.ts' ): self.icon = PixmapCache().getIcon( 'filelinguist.png' ) return if self.fileType == CodimensionProjectFileType: # Get the project properties try: self.toolTip = getProjectFileTooltip( path ) except: # cannot get project properties self.toolTip = 'Broken project file' return return
def __init__(self, parent, path): path = str(path) TreeViewItem.__init__(self, parent, os.path.basename(path)) self.itemType = FileItemType self.parsingErrors = False # Used for python files only self.isLink = False self.fileType = detectFileType(path) self.icon = getFileIcon(self.fileType) if self.fileType == BrokenSymlinkFileType: self.isLink = True self.toolTip = self.__brokenLinkTooltip(path) return if os.path.islink(path): self.isLink = True self.toolTip = self.__linkTooltip(path) self.icon = PixmapCache().getIcon('filelink.png') self.fileType = detectFileType(os.path.realpath(path)) return # Fine corrections for some file types if self.fileType in [PythonFileType, Python3FileType]: self.populated = False self.lazyPopulation = True return if self.fileType == LinguistFileType: if path.endswith('.ts'): self.icon = PixmapCache().getIcon('filelinguist.png') return if self.fileType == CodimensionProjectFileType: # Get the project properties try: self.toolTip = getProjectFileTooltip(path) except: # cannot get project properties self.toolTip = 'Broken project file' return return
def onFileContextMenuAboutToShow(self): " Called when the plugin file context menu is about to show " path = str(self.fileParentMenu.menuAction().data().toString()) pathStatus = self.getLocalStatus(path) debugMode = self.ide.mainWindow.debugMode if pathStatus == IND_ERROR: self.fileContextInfoAct.setEnabled(False) self.fileContextUpdateAct.setEnabled(False) self.fileContextAnnotateAct.setEnabled(False) self.fileContextLogAct.setEnabled(False) self.fileContextAddAct.setEnabled(False) self.fileContextCommitAct.setEnabled(False) self.fileContextDeleteAct.setEnabled(False) self.fileContextRevertAct.setEnabled(False) self.fileContextDiffAct.setEnabled(False) self.fileContextPropsAct.setEnabled(False) return if pathStatus == self.NOT_UNDER_VCS: self.fileContextInfoAct.setEnabled(False) self.fileContextUpdateAct.setEnabled(False) self.fileContextAnnotateAct.setEnabled(False) self.fileContextLogAct.setEnabled(False) self.fileContextCommitAct.setEnabled(False) self.fileContextDeleteAct.setEnabled(False) self.fileContextRevertAct.setEnabled(False) self.fileContextDiffAct.setEnabled(False) self.fileContextPropsAct.setEnabled(False) upperDirStatus = self.getLocalStatus(os.path.dirname(path)) if upperDirStatus == self.NOT_UNDER_VCS: self.fileContextAddAct.setEnabled(False) else: self.fileContextAddAct.setEnabled(upperDirStatus != IND_ERROR and not debugMode) return self.fileContextInfoAct.setEnabled(True) self.fileContextUpdateAct.setEnabled(not debugMode) self.fileContextAnnotateAct.setEnabled(True) self.fileContextLogAct.setEnabled(True) self.fileContextAddAct.setEnabled(False) self.fileContextPropsAct.setEnabled(not debugMode) self.fileContextCommitAct.setEnabled(pathStatus in [ IND_ADDED, IND_DELETED, IND_MERGED, IND_MODIFIED_LR, IND_MODIFIED_L, IND_REPLACED, IND_CONFLICTED ] and not debugMode) self.fileContextDeleteAct.setEnabled(pathStatus != IND_DELETED and not debugMode) self.fileContextRevertAct.setEnabled(pathStatus != IND_UPTODATE and not debugMode) # Diff makes sense only for text files fileType = detectFileType(path) self.fileContextDiffAct.setEnabled(isFileTypeSearchable(fileType)) return
def onFileContextMenuAboutToShow( self ): " Called when the plugin file context menu is about to show " path = str( self.fileParentMenu.menuAction().data().toString() ) pathStatus = self.getLocalStatus( path ) debugMode = self.ide.mainWindow.debugMode if pathStatus == IND_ERROR: self.fileContextInfoAct.setEnabled( False ) self.fileContextUpdateAct.setEnabled( False ) self.fileContextAnnotateAct.setEnabled( False ) self.fileContextLogAct.setEnabled( False ) self.fileContextAddAct.setEnabled( False ) self.fileContextCommitAct.setEnabled( False ) self.fileContextDeleteAct.setEnabled( False ) self.fileContextRevertAct.setEnabled( False ) self.fileContextDiffAct.setEnabled( False ) self.fileContextPropsAct.setEnabled( False ) return if pathStatus == self.NOT_UNDER_VCS: self.fileContextInfoAct.setEnabled( False ) self.fileContextUpdateAct.setEnabled( False ) self.fileContextAnnotateAct.setEnabled( False ) self.fileContextLogAct.setEnabled( False ) self.fileContextCommitAct.setEnabled( False ) self.fileContextDeleteAct.setEnabled( False ) self.fileContextRevertAct.setEnabled( False ) self.fileContextDiffAct.setEnabled( False ) self.fileContextPropsAct.setEnabled( False ) upperDirStatus = self.getLocalStatus( os.path.dirname( path ) ) if upperDirStatus == self.NOT_UNDER_VCS: self.fileContextAddAct.setEnabled( False ) else: self.fileContextAddAct.setEnabled( upperDirStatus != IND_ERROR and not debugMode ) return self.fileContextInfoAct.setEnabled( True ) self.fileContextUpdateAct.setEnabled( not debugMode ) self.fileContextAnnotateAct.setEnabled( True ) self.fileContextLogAct.setEnabled( True ) self.fileContextAddAct.setEnabled( False ) self.fileContextPropsAct.setEnabled( not debugMode ) self.fileContextCommitAct.setEnabled( pathStatus in [ IND_ADDED, IND_DELETED, IND_MERGED, IND_MODIFIED_LR, IND_MODIFIED_L, IND_REPLACED, IND_CONFLICTED ] and not debugMode ) self.fileContextDeleteAct.setEnabled( pathStatus != IND_DELETED and not debugMode ) self.fileContextRevertAct.setEnabled( pathStatus != IND_UPTODATE and not debugMode ) # Diff makes sense only for text files fileType = detectFileType( path ) self.fileContextDiffAct.setEnabled( isFileTypeSearchable( fileType ) ) return
def showReport(self, regexp, results): " Shows the find in files results " self.__clear() self.__noneLabel.hide() self.__reportRegexp = regexp self.__reportResults = results # Add the complete information totalMatched = 0 for item in results: matched = len(item.matches) totalMatched += matched if matched == 1: matchText = " (1 match)" else: matchText = " (" + str(matched) + " matches)" columns = [item.fileName, matchText] fileItem = MatchTableFileItem(columns, item.bufferUUID) fileItem.setIcon(0, getFileIcon(detectFileType(item.fileName))) if item.tooltip != "": fileItem.setToolTip(0, item.tooltip) self.__resultsTree.addTopLevelItem(fileItem) # Matches for match in item.matches: columns = [str(match.line), match.text] matchItem = MatchTableItem(columns, match.tooltip) fileItem.addChild(matchItem) fileItem.setExpanded(True) # Update the header with the total number of matches headerLabels = [ "File name / line (total files: " + str(len(results)) + ")", "Text (total matches: " + str(totalMatched) + ")", ] self.__resultsTree.setHeaderLabels(headerLabels) # Resizing the table self.__resultsTree.header().resizeSections(QHeaderView.ResizeToContents) # Show the complete information self.__resultsTree.show() self.__resultsTree.buildCache() self.__reportShown = True self.__updateButtonsStatus() # Connect the buffer change signal if not connected yet if not self.__bufferChangeconnected: self.__bufferChangeconnected = True mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager editorsManager.bufferModified.connect(self.__resultsTree.onBufferModified) return
def populateFileItem(self, parentItem, repopulate=False): " Populate a file item's subtree " path = parentItem.getPath() if not detectFileType(path) in [PythonFileType, Python3FileType]: return parentItem.populated = True modInfo = self.globalData.briefModinfoCache.get(path) # Count the number of rows to insert count = 0 if modInfo.encoding is not None: count += 1 if modInfo.imports: count += 1 if modInfo.globals: count += 1 if modInfo.functions: count += 1 if modInfo.classes: count += 1 if count == 0: return # Insert rows if repopulate: self.beginInsertRows( self.createIndex(parentItem.row(), 0, parentItem), 0, count - 1) if modInfo.encoding is not None: node = TreeViewCodingItem(parentItem, modInfo.encoding) self._addItem(node, parentItem) if modInfo.imports: node = TreeViewImportsItem(parentItem, modInfo) self._addItem(node, parentItem) if modInfo.globals: node = TreeViewGlobalsItem(parentItem, modInfo) self._addItem(node, parentItem) if modInfo.functions: node = TreeViewFunctionsItem(parentItem, modInfo) self._addItem(node, parentItem) if modInfo.classes: node = TreeViewClassesItem(parentItem, modInfo) self._addItem(node, parentItem) if repopulate: self.endInsertRows() return
def populateFileItem( self, parentItem, repopulate = False ): " Populate a file item's subtree " path = parentItem.getPath() if not detectFileType( path ) in [ PythonFileType, Python3FileType ]: return parentItem.populated = True modInfo = self.globalData.briefModinfoCache.get( path ) # Count the number of rows to insert count = 0 if modInfo.encoding is not None: count += 1 if modInfo.imports: count += 1 if modInfo.globals: count += 1 if modInfo.functions: count += 1 if modInfo.classes: count += 1 if count == 0: return # Insert rows if repopulate: self.beginInsertRows( self.createIndex( parentItem.row(), 0, parentItem ), 0, count - 1 ) if modInfo.encoding is not None: node = TreeViewCodingItem( parentItem, modInfo.encoding ) self._addItem( node, parentItem ) if modInfo.imports: node = TreeViewImportsItem( parentItem, modInfo ) self._addItem( node, parentItem ) if modInfo.globals: node = TreeViewGlobalsItem( parentItem, modInfo ) self._addItem( node, parentItem ) if modInfo.functions: node = TreeViewFunctionsItem( parentItem, modInfo ) self._addItem( node, parentItem ) if modInfo.classes: node = TreeViewClassesItem( parentItem, modInfo ) self._addItem( node, parentItem ) if repopulate: self.endInsertRows() return
def __onSavedBufferAs( self, fileName, uuid ): " Triggered when a file is saved with a new name " if uuid in self.__flakesResults: if detectFileType( fileName ) not in [ PythonFileType, Python3FileType ]: # It's not a python file anymore self.__currentUUID = None del self.__flakesResults[ uuid ] self.setFlakesNotAvailable( self.__uiLabel ) return
def processCommandLineArgs(args): " Checks what is in the command line " # I cannot import it at the top because the fileutils want # to use the pixmap cache which needs the application to be # created, so the import is deferred from utils.fileutils import CodimensionProjectFileType, PythonFileType, \ Python3FileType, detectFileType if len(args) == 0: return "" # Check that all the files exist fileType = PythonFileType for fName in args: if not os.path.exists(fName): raise Exception("Cannot open file: " + fName) if not os.path.isfile(fName): raise Exception("The " + fName + " is not a file") fileType = detectFileType(fName) if fileType not in [ PythonFileType, Python3FileType, CodimensionProjectFileType ]: raise Exception( "Unexpected file type (" + \ fName + ")" ) if len(args) == 1: if fileType == CodimensionProjectFileType: return args[0] return "" # There are many files, check that they are python only for fName in args: fileType = detectFileType(fName) if fileType == CodimensionProjectFileType: raise Exception("Codimension project file (" + fName + ") must not come " "together with python files") return ""
def __onSavedBufferAs(self, fileName, uuid): " Triggered when a file is saved with a new name " if uuid in self.__flakesResults: if detectFileType(fileName) not in [ PythonFileType, Python3FileType ]: # It's not a python file anymore self.__currentUUID = None del self.__flakesResults[uuid] self.setFlakesNotAvailable(self.__uiLabel) return
def processCommandLineArgs( args ): " Checks what is in the command line " # I cannot import it at the top because the fileutils want # to use the pixmap cache which needs the application to be # created, so the import is deferred from utils.fileutils import CodimensionProjectFileType, PythonFileType, \ Python3FileType, detectFileType if len( args ) == 0: return "" # Check that all the files exist fileType = PythonFileType for fName in args: if not os.path.exists( fName ): raise Exception( "Cannot open file: " + fName ) if not os.path.isfile( fName ): raise Exception( "The " + fName + " is not a file" ) fileType = detectFileType( fName ) if fileType not in [ PythonFileType, Python3FileType, CodimensionProjectFileType ]: raise Exception( "Unexpected file type (" + \ fName + ")" ) if len( args ) == 1: if fileType == CodimensionProjectFileType: return args[ 0 ] return "" # There are many files, check that they are python only for fName in args: fileType = detectFileType( fName ) if fileType == CodimensionProjectFileType: raise Exception( "Codimension project file (" + fName + ") must not come " "together with python files" ) return ""
def __populateFromProject( self ): " Populates find name dialog from the project files " mainWindow = GlobalData().mainWindow for fname in GlobalData().project.filesList: if detectFileType( fname ) in [ PythonFileType, Python3FileType ]: widget = mainWindow.getWidgetForFileName( fname ) if widget is None: info = GlobalData().briefModinfoCache.get( fname ) else: content = widget.getEditor().text() info = getBriefModuleInfoFromMemory( content ) self.__populateInfo( info, fname ) return
def __populateModel( self ): " Populates the project browser model " self.clear() project = self.globalData.project cache = self.globalData.briefModinfoCache for fname in project.filesList: if detectFileType( fname ) in [ PythonFileType, Python3FileType ]: info = cache.get( fname ) for func in info.functions: item = TreeViewFunctionItem( self.rootItem, func ) item.appendData( [ basename( fname ), func.line ] ) item.setPath( fname ) self.rootItem.appendChild( item ) return
def openItem(self, item): " Handles the case when an item is activated " if item.itemType in [ GlobalsItemType, ImportsItemType, FunctionsItemType, ClassesItemType, StaticAttributesItemType, InstanceAttributesItemType, DirectoryItemType, SysPathItemType, ]: return if item.itemType == FileItemType: if item.fileType == BrokenSymlinkFileType: return itemPath = item.getPath() if not os.path.exists(itemPath): logging.error("Cannot open " + itemPath) return if os.path.islink(itemPath): # Convert it to the real path and the decide what to do itemPath = os.path.realpath(itemPath) # The type may differ... itemFileType = detectFileType(itemPath) else: # The intermediate directory could be a link, so use the real # path itemPath = os.path.realpath(itemPath) itemFileType = item.fileType GlobalData().mainWindow.openFileByType(itemFileType, itemPath, -1) return if item.itemType in [ CodingItemType, ImportItemType, FunctionItemType, ClassItemType, DecoratorItemType, AttributeItemType, GlobalItemType, ImportWhatItemType, ]: GlobalData().mainWindow.openFile(os.path.realpath(item.getPath()), item.sourceObj.line) return
def __openFile( self ): " Handles 'open' file menu item " self.__fileContextItem.updateIconAndTooltip() fName = self.__fileContextItem.getFilename() if not self.__fileContextItem.isValid(): logging.warning( "Cannot open " + fName ) return fileType = detectFileType( fName ) if fileType == PixmapFileType: GlobalData().mainWindow.openPixmapFile( fName ) return GlobalData().mainWindow.openFile( fName, -1 ) return
def __openFile(self): " Handles 'open' file menu item " self.__fileContextItem.updateIconAndTooltip() fName = self.__fileContextItem.getFilename() if not self.__fileContextItem.isValid(): logging.warning("Cannot open " + fName) return fileType = detectFileType(fName) if fileType == PixmapFileType: GlobalData().mainWindow.openPixmapFile(fName) return GlobalData().mainWindow.openFile(fName, -1) return
def __init__(self, plugin, pathsToCommit, pathsToIgnore, parent=None): QDialog.__init__(self, parent) self.__plugin = plugin self.__createLayout(pathsToCommit, pathsToIgnore) self.setWindowTitle("SVN commit") # Fill the lists for item in pathsToCommit: newItem = QTreeWidgetItem(["", item[0], STATUS[item[1]]]) newItem.setCheckState(CHECK_COL, Qt.Checked) newItem.setToolTip(PATH_COL, item[0]) newItem.setToolTip(STATUS_COL, STATUS[item[1]]) self.__pathToCommitView.addTopLevelItem(newItem) diffButton = self.__createDiffButton() diffButton.path = item[0] diffButton.status = item[1] fileType = detectFileType(item[0]) if os.path.isdir( item[ 0 ] ) or item[ 1 ] in [ IND_REPLACED ] \ or not isFileTypeSearchable( fileType ): diffButton.setEnabled(False) diffButton.setToolTip("Diff is not available") else: diffButton.setEnabled(True) diffButton.setToolTip("Click to see diff") self.__pathToCommitView.setItemWidget(newItem, DIFF_COL, diffButton) self.__resizeCommitPaths() self.__sortCommitPaths() for item in pathsToIgnore: newItem = QTreeWidgetItem([item[0], STATUS[item[1]]]) newItem.setToolTip(0, item[0]) newItem.setToolTip(1, STATUS[item[1]]) self.__pathToIgnoreView.addTopLevelItem(newItem) self.__pathToIgnoreView.header().resizeSections( QHeaderView.ResizeToContents) self.__updateSelectAllStatus() self.__updateOKStatus() self.__message.setFocus() return
def onFileUpdated( self, fileName ): " Triggered when the file is updated " if not GlobalData().project.isProjectFile( fileName ): # Not a project file return if detectFileType( fileName ) not in [ PythonFileType, Python3FileType ]: return if self.__model.onFileUpdated( fileName ): # Need resort and counter updates self.layoutDisplay() self.updateCounter() self.model().setFilterRegExp( "" ) return
def __init__( self, plugin, pathsToCommit, pathsToIgnore, parent = None ): QDialog.__init__( self, parent ) self.__plugin = plugin self.__createLayout( pathsToCommit, pathsToIgnore ) self.setWindowTitle( "SVN commit" ) # Fill the lists for item in pathsToCommit: newItem = QTreeWidgetItem( [ "", item[ 0 ], STATUS[ item[ 1 ] ] ] ) newItem.setCheckState( CHECK_COL, Qt.Checked ) newItem.setToolTip( PATH_COL, item[ 0 ] ) newItem.setToolTip( STATUS_COL, STATUS[ item[ 1 ] ] ) self.__pathToCommitView.addTopLevelItem( newItem ) diffButton = self.__createDiffButton() diffButton.path = item[ 0 ] diffButton.status = item[ 1 ] fileType = detectFileType( item[ 0 ] ) if os.path.isdir( item[ 0 ] ) or item[ 1 ] in [ IND_REPLACED ] \ or not isFileTypeSearchable( fileType ): diffButton.setEnabled( False ) diffButton.setToolTip( "Diff is not available" ) else: diffButton.setEnabled( True ) diffButton.setToolTip( "Click to see diff" ) self.__pathToCommitView.setItemWidget( newItem, DIFF_COL, diffButton ) self.__resizeCommitPaths() self.__sortCommitPaths() for item in pathsToIgnore: newItem = QTreeWidgetItem( [ item[ 0 ], STATUS[ item[ 1 ] ] ] ) newItem.setToolTip( 0, item[ 0 ] ) newItem.setToolTip( 1, STATUS[ item[ 1 ] ] ) self.__pathToIgnoreView.addTopLevelItem( newItem ) self.__pathToIgnoreView.header().resizeSections( QHeaderView.ResizeToContents ) self.__updateSelectAllStatus() self.__updateOKStatus() self.__message.setFocus() return
def __init__( self, fileName, info = None, parent = None ): QDialog.__init__( self, parent ) if info is None: if not os.path.exists( fileName ): raise Exception( "Cannot open " + fileName ) if not detectFileType( fileName ) in [ PythonFileType, Python3FileType ]: raise Exception( "Unexpected file type (" + fileName + \ "). A python file is expected." ) self.__createLayout( fileName, info ) self.setWindowTitle( "Lexer/parser errors: " + \ os.path.basename( fileName ) ) self.show() return
def __init__(self, fileName, info=None, parent=None): QDialog.__init__(self, parent) if info is None: if not os.path.exists(fileName): raise Exception("Cannot open " + fileName) if not detectFileType(fileName) in [ PythonFileType, Python3FileType ]: raise Exception( "Unexpected file type (" + fileName + \ "). A python file is expected." ) self.__createLayout(fileName, info) self.setWindowTitle( "Lexer/parser errors: " + \ os.path.basename( fileName ) ) self.show() return
def __markOK( self ): " Mark the file as OK " self.__isValid = True fileName = self.getFilename() fileType = detectFileType( fileName ) if fileType in [ PythonFileType, Python3FileType ]: # The tooltip could be the file docstring info = GlobalData().briefModinfoCache.get( fileName ) if info.docstring is not None and Settings().recentTooltips: self.setToolTip( 1, info.docstring.text ) else: self.setToolTip( 1, "" ) if info.isOK: self.setIcon( 0, PixmapCache().getIcon( 'filepython.png' ) ) else: self.setIcon( 0, PixmapCache().getIcon( 'filepythonbroken.png' ) ) self.setToolTip( 0, "" ) elif fileType == CodimensionProjectFileType: # Get the project properties try: self.setToolTip( 0, "" ) tooltip = getProjectFileTooltip( fileName ) if Settings().recentTooltips: self.setToolTip( 1, tooltip ) else: self.setToolTip( 1, "" ) self.setText( 0, "" ) except: # cannot get project properties. Mark broken. self.__isValid = False self.setToolTip( 0, 'Broken project file' ) self.setToolTip( 1, 'Broken project file' ) self.setIcon( 0, getFileIcon( fileType ) ) else: # Get the other file type icon self.setIcon( 0, getFileIcon( fileType ) ) self.setToolTip( 2, self.getFilename() ) return
def __markOK(self): " Mark the file as OK " self.__isValid = True fileName = self.getFilename() fileType = detectFileType(fileName) if fileType in [PythonFileType, Python3FileType]: # The tooltip could be the file docstring info = GlobalData().briefModinfoCache.get(fileName) if info.docstring is not None and Settings().recentTooltips: self.setToolTip(1, info.docstring.text) else: self.setToolTip(1, "") if info.isOK: self.setIcon(0, getIcon('filepython.png')) else: self.setIcon(0, getIcon('filepythonbroken.png')) self.setToolTip(0, "") elif fileType == CodimensionProjectFileType: # Get the project properties try: self.setToolTip(0, "") tooltip = getProjectFileTooltip(fileName) if Settings().recentTooltips: self.setToolTip(1, tooltip) else: self.setToolTip(1, "") self.setText(0, "") except: # cannot get project properties. Mark broken. self.__isValid = False self.setToolTip(0, 'Broken project file') self.setToolTip(1, 'Broken project file') self.setIcon(0, getFileIcon(fileType)) else: # Get the other file type icon self.setIcon(0, getFileIcon(fileType)) self.setToolTip(2, self.getFilename()) return
def openItem(self, item): " Handles the case when an item is activated " if item.itemType in [ GlobalsItemType, ImportsItemType, FunctionsItemType, ClassesItemType, StaticAttributesItemType, InstanceAttributesItemType, DirectoryItemType, SysPathItemType ]: return if item.itemType == FileItemType: if item.fileType == BrokenSymlinkFileType: return itemPath = item.getPath() if not os.path.exists(itemPath): logging.error("Cannot open " + itemPath) return if os.path.islink(itemPath): # Convert it to the real path and the decide what to do itemPath = os.path.realpath(itemPath) # The type may differ... itemFileType = detectFileType(itemPath) else: # The intermediate directory could be a link, so use the real # path itemPath = os.path.realpath(itemPath) itemFileType = item.fileType GlobalData().mainWindow.openFileByType(itemFileType, itemPath, -1) return if item.itemType in [ CodingItemType, ImportItemType, FunctionItemType, ClassItemType, DecoratorItemType, AttributeItemType, GlobalItemType, ImportWhatItemType ]: GlobalData().mainWindow.openFile(os.path.realpath(item.getPath()), item.sourceObj.line) return
def __populateFromOpened(self): " Populates the name dialog from the opened files " mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager showTooltips = Settings().findFileTooltips for record in editorsManager.getTextEditors(): # uuid = record[ 0 ] fname = record[1] widget = record[2] fileType = detectFileType(fname) tooltip = "" if showTooltips and fileType in [PythonFileType, Python3FileType]: content = widget.getEditor().text() info = getBriefModuleInfoFromMemory(content) if info.docstring is not None: tooltip = info.docstring.text newItem = FileItem(self.rootItem, getFileIcon(fileType), fname, tooltip) self.rootItem.appendChild(newItem) self.count += 1 return
def __populateFromOpened( self ): " Populates the name dialog from the opened files " mainWindow = GlobalData().mainWindow editorsManager = mainWindow.editorsManagerWidget.editorsManager showTooltips = Settings().findFileTooltips for record in editorsManager.getTextEditors(): # uuid = record[ 0 ] fname = record[ 1 ] widget = record[ 2 ] fileType = detectFileType( fname ) tooltip = "" if showTooltips and fileType in [ PythonFileType, Python3FileType ]: content = widget.getEditor().text() info = getBriefModuleInfoFromMemory( content ) if info.docstring is not None: tooltip = info.docstring.text newItem = FileItem( self.rootItem, getFileIcon( fileType ), fname, tooltip ) self.rootItem.appendChild( newItem ) self.count += 1 return
def __populateFromProject(self): " Populates find name dialog from the project files " mainWindow = GlobalData().mainWindow showTooltips = Settings().findFileTooltips for fname in GlobalData().project.filesList: if fname.endswith(os.path.sep): continue fileType = detectFileType(fname) tooltip = "" if showTooltips and fileType in [PythonFileType, Python3FileType]: widget = mainWindow.getWidgetForFileName(fname) if widget is None: info = GlobalData().briefModinfoCache.get(fname) else: content = widget.getEditor().text() info = getBriefModuleInfoFromMemory(content) if info.docstring is not None: tooltip = info.docstring.text newItem = FileItem(self.rootItem, getFileIcon(fileType), fname, tooltip) self.rootItem.appendChild(newItem) self.count += 1 return
def __populateFromProject( self ): " Populates find name dialog from the project files " mainWindow = GlobalData().mainWindow showTooltips = Settings().findFileTooltips for fname in GlobalData().project.filesList: if fname.endswith( os.path.sep ): continue fileType = detectFileType( fname ) tooltip = "" if showTooltips and fileType in [ PythonFileType, Python3FileType ]: widget = mainWindow.getWidgetForFileName( fname ) if widget is None: info = GlobalData().briefModinfoCache.get( fname ) else: content = widget.getEditor().text() info = getBriefModuleInfoFromMemory( content ) if info.docstring is not None: tooltip = info.docstring.text newItem = FileItem( self.rootItem, getFileIcon( fileType ), fname, tooltip ) self.rootItem.appendChild( newItem ) self.count += 1 return
def onBufferContextMenuAboutToshow(self): " Called when the plugin buffer context menu is about to show " path = self.ide.currentEditorWidget.getFileName() debugMode = self.ide.mainWindow.debugMode if not os.path.isabs(path): self.bufContextInfoAct.setEnabled(False) self.bufContextUpdateAct.setEnabled(False) self.bufContextAnnotateAct.setEnabled(False) self.bufContextLogAct.setEnabled(False) self.bufContextAddAct.setEnabled(False) self.bufContextCommitAct.setEnabled(False) self.bufContextDeleteAct.setEnabled(False) self.bufContextRevertAct.setEnabled(False) self.bufContextDiffAct.setEnabled(False) self.bufContextPropsAct.setEnabled(False) return pathStatus = self.getLocalStatus(path) if pathStatus == IND_ERROR: self.bufContextInfoAct.setEnabled(False) self.bufContextUpdateAct.setEnabled(False) self.bufContextAnnotateAct.setEnabled(False) self.bufContextLogAct.setEnabled(False) self.bufContextAddAct.setEnabled(False) self.bufContextCommitAct.setEnabled(False) self.bufContextDeleteAct.setEnabled(False) self.bufContextRevertAct.setEnabled(False) self.bufContextDiffAct.setEnabled(False) self.bufContextPropsAct.setEnabled(False) return if pathStatus == self.NOT_UNDER_VCS: self.bufContextInfoAct.setEnabled(False) self.bufContextUpdateAct.setEnabled(False) self.bufContextAnnotateAct.setEnabled(False) self.bufContextLogAct.setEnabled(False) self.bufContextCommitAct.setEnabled(False) self.bufContextDeleteAct.setEnabled(False) self.bufContextRevertAct.setEnabled(False) self.bufContextDiffAct.setEnabled(False) self.bufContextPropsAct.setEnabled(False) upperDirStatus = self.getLocalStatus(os.path.dirname(path)) if upperDirStatus == self.NOT_UNDER_VCS: self.bufContextAddAct.setEnabled(False) else: self.bufContextAddAct.setEnabled(upperDirStatus != IND_ERROR and not debugMode) return self.bufContextInfoAct.setEnabled(True) self.bufContextUpdateAct.setEnabled(not debugMode) self.bufContextAddAct.setEnabled(False) self.bufContextPropsAct.setEnabled(not debugMode) self.bufContextDeleteAct.setEnabled(pathStatus != IND_DELETED and not debugMode) self.bufContextRevertAct.setEnabled(pathStatus != IND_UPTODATE and not debugMode) # Diff makes sense only for text files fileType = detectFileType(path) self.bufContextDiffAct.setEnabled(isFileTypeSearchable(fileType)) widgetType = self.ide.currentEditorWidget.getType() if widgetType in [ MainWindowTabWidgetBase.PlainTextEditor, MainWindowTabWidgetBase.PythonGraphicsEditor ]: self.bufContextAnnotateAct.setEnabled(True) self.bufContextLogAct.setEnabled(True) else: self.bufContextAnnotateAct.setEnabled(False) self.bufContextLogAct.setEnabled(False) # Set the Commit... menu item status if pathStatus not in [ IND_ADDED, IND_DELETED, IND_MERGED, IND_MODIFIED_LR, IND_MODIFIED_L, IND_REPLACED, IND_CONFLICTED ]: self.bufContextCommitAct.setEnabled(False) else: if widgetType in [ MainWindowTabWidgetBase.PlainTextEditor, MainWindowTabWidgetBase.PythonGraphicsEditor ]: self.bufContextCommitAct.setEnabled( not self.ide.currentEditorWidget.isModified() and not debugMode) else: self.bufContextCommitAct.setEnabled(False) return
def getFileType(self): " Provides the file type " if self.__fileType == UnknownFileType: if self.__shortName: self.__fileType = detectFileType(self.__shortName) return self.__fileType
def setShortName(self, name): " Sets the display name " self.__shortName = name self.__fileType = detectFileType(name) return
def getFileType( self ): " Provides the file type " if self.__fileType == UnknownFileType: if self.__shortName: self.__fileType = detectFileType( self.__shortName ) return self.__fileType
def setShortName( self, name ): " Sets the display name " self.__shortName = name self.__fileType = detectFileType( name ) return
def __createLayout(self, action, title, files): """ Creates the dialog layout """ self.resize(400, 300) self.setSizeGripEnabled(True) # Top level layout layout = QVBoxLayout(self) # Pixmap and the message topLayout = QHBoxLayout() pixmap = QLabel() pixmap.setPixmap(PixmapCache().getPixmap('warning.png')) topLayout.addWidget(pixmap) hSpacer = QWidget() hSpacer.setFixedSize(15, 15) topLayout.addWidget(hSpacer) message = QLabel( "All the project files must be " \ "saved before start debugging" ) message.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) message.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) message.setWordWrap(True) topLayout.addWidget(message) layout.addLayout(topLayout) vSpacer = QWidget() vSpacer.setFixedSize(15, 15) layout.addWidget(vSpacer) layout.addWidget(QLabel(title + ":")) filesList = QTreeWidget() filesList.setRootIsDecorated(False) filesList.setAlternatingRowColors(True) filesList.setUniformRowHeights(True) filesList.setItemsExpandable(False) filesList.setItemDelegate(NoOutlineHeightDelegate(4)) filesList.setSelectionMode(QAbstractItemView.NoSelection) filesList.setHeaderHidden(True) for item in files: fileName = item[0] fileItem = QTreeWidgetItem([fileName]) fileType = detectFileType(fileName) fileItem.setIcon(0, getFileIcon(fileType)) if fileType in [PythonFileType, Python3FileType]: infoSrc = GlobalData().briefModinfoCache info = infoSrc.get(fileName) if info.docstring is not None: fileItem.setToolTip(0, info.docstring.text) else: fileItem.setToolTip(0, "") filesList.addTopLevelItem(fileItem) layout.addWidget(filesList) # Buttons at the bottom buttonBox = QDialogButtonBox() buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Cancel) continueButton = buttonBox.addButton(action, QDialogButtonBox.ActionRole) continueButton.setDefault(True) layout.addWidget(buttonBox) continueButton.clicked.connect(self.accept) buttonBox.rejected.connect(self.close) continueButton.setFocus() return
def onBufferContextMenuAboutToshow( self ): " Called when the plugin buffer context menu is about to show " path = self.ide.currentEditorWidget.getFileName() debugMode = self.ide.mainWindow.debugMode if not os.path.isabs( path ): self.bufContextInfoAct.setEnabled( False ) self.bufContextUpdateAct.setEnabled( False ) self.bufContextAnnotateAct.setEnabled( False ) self.bufContextLogAct.setEnabled( False ) self.bufContextAddAct.setEnabled( False ) self.bufContextCommitAct.setEnabled( False ) self.bufContextDeleteAct.setEnabled( False ) self.bufContextRevertAct.setEnabled( False ) self.bufContextDiffAct.setEnabled( False ) self.bufContextPropsAct.setEnabled( False ) return pathStatus = self.getLocalStatus( path ) if pathStatus == IND_ERROR: self.bufContextInfoAct.setEnabled( False ) self.bufContextUpdateAct.setEnabled( False ) self.bufContextAnnotateAct.setEnabled( False ) self.bufContextLogAct.setEnabled( False ) self.bufContextAddAct.setEnabled( False ) self.bufContextCommitAct.setEnabled( False ) self.bufContextDeleteAct.setEnabled( False ) self.bufContextRevertAct.setEnabled( False ) self.bufContextDiffAct.setEnabled( False ) self.bufContextPropsAct.setEnabled( False ) return if pathStatus == self.NOT_UNDER_VCS: self.bufContextInfoAct.setEnabled( False ) self.bufContextUpdateAct.setEnabled( False ) self.bufContextAnnotateAct.setEnabled( False ) self.bufContextLogAct.setEnabled( False ) self.bufContextCommitAct.setEnabled( False ) self.bufContextDeleteAct.setEnabled( False ) self.bufContextRevertAct.setEnabled( False ) self.bufContextDiffAct.setEnabled( False ) self.bufContextPropsAct.setEnabled( False ) upperDirStatus = self.getLocalStatus( os.path.dirname( path ) ) if upperDirStatus == self.NOT_UNDER_VCS: self.bufContextAddAct.setEnabled( False ) else: self.bufContextAddAct.setEnabled( upperDirStatus != IND_ERROR and not debugMode ) return self.bufContextInfoAct.setEnabled( True ) self.bufContextUpdateAct.setEnabled( not debugMode ) self.bufContextAddAct.setEnabled( False ) self.bufContextPropsAct.setEnabled( not debugMode ) self.bufContextDeleteAct.setEnabled( pathStatus != IND_DELETED and not debugMode ) self.bufContextRevertAct.setEnabled( pathStatus != IND_UPTODATE and not debugMode ) # Diff makes sense only for text files fileType = detectFileType( path ) self.bufContextDiffAct.setEnabled( isFileTypeSearchable( fileType ) ) widgetType = self.ide.currentEditorWidget.getType() if widgetType in [ MainWindowTabWidgetBase.PlainTextEditor, MainWindowTabWidgetBase.PythonGraphicsEditor ]: self.bufContextAnnotateAct.setEnabled( True ) self.bufContextLogAct.setEnabled( True ) else: self.bufContextAnnotateAct.setEnabled( False ) self.bufContextLogAct.setEnabled( False ) # Set the Commit... menu item status if pathStatus not in [ IND_ADDED, IND_DELETED, IND_MERGED, IND_MODIFIED_LR, IND_MODIFIED_L, IND_REPLACED, IND_CONFLICTED ]: self.bufContextCommitAct.setEnabled( False ) else: if widgetType in [ MainWindowTabWidgetBase.PlainTextEditor, MainWindowTabWidgetBase.PythonGraphicsEditor ]: self.bufContextCommitAct.setEnabled( not self.ide.currentEditorWidget.isModified() and not debugMode ) else: self.bufContextCommitAct.setEnabled( False ) return
def __createLayout( self, action, title, files ): """ Creates the dialog layout """ self.resize( 400, 300 ) self.setSizeGripEnabled( True ) # Top level layout layout = QVBoxLayout( self ) # Pixmap and the message topLayout = QHBoxLayout() pixmap = QLabel() pixmap.setPixmap( PixmapCache().getPixmap( 'warning.png' ) ) topLayout.addWidget( pixmap ) hSpacer = QWidget() hSpacer.setFixedSize( 15, 15 ) topLayout.addWidget( hSpacer ) message = QLabel( "All the project files must be " \ "saved before start debugging" ) message.setAlignment( Qt.AlignHCenter | Qt.AlignVCenter ) message.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding ) message.setWordWrap( True ) topLayout.addWidget( message ) layout.addLayout( topLayout ) vSpacer = QWidget() vSpacer.setFixedSize( 15, 15 ) layout.addWidget( vSpacer ) layout.addWidget( QLabel( title + ":" ) ) filesList = QTreeWidget() filesList.setRootIsDecorated( False ) filesList.setAlternatingRowColors( True ) filesList.setUniformRowHeights( True ) filesList.setItemsExpandable( False ) filesList.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) filesList.setSelectionMode( QAbstractItemView.NoSelection ) filesList.setHeaderHidden( True ) for item in files: fileName = item[ 0 ] fileItem = QTreeWidgetItem( [ fileName ] ) fileType = detectFileType( fileName ) fileItem.setIcon( 0, getFileIcon( fileType ) ) if fileType in [ PythonFileType, Python3FileType ]: infoSrc = GlobalData().briefModinfoCache info = infoSrc.get( fileName ) if info.docstring is not None: fileItem.setToolTip( 0, info.docstring.text ) else: fileItem.setToolTip( 0, "" ) filesList.addTopLevelItem( fileItem ) layout.addWidget( filesList ) # Buttons at the bottom buttonBox = QDialogButtonBox() buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Cancel ) continueButton = buttonBox.addButton( action, QDialogButtonBox.ActionRole ) continueButton.setDefault( True ) layout.addWidget( buttonBox ) continueButton.clicked.connect( self.accept ) buttonBox.rejected.connect( self.close ) continueButton.setFocus() return