class SVNPluginLogDialog( QDialog ): " SVN plugin log dialog " NODIFF = '<html><body bgcolor="#ffffe6"></body></html>' def __init__( self, plugin, client, path, logInfo, parent = None ): QDialog.__init__( self, parent ) self.__plugin = plugin self.__client = client self.__path = path self.__logInfo = logInfo self.__lhsSelected = None self.__rhsSelected = None self.__createLayout() self.setWindowTitle( "SVN Log" ) lastIndex = len( self.__logInfo ) - 1 index = 0 for log in self.__logInfo: newItem = LogItem( log ) self.__logView.addTopLevelItem( newItem ) if index != lastIndex: rev = log.revision.number nextRev = self.__logInfo[ index + 1 ].revision.number diffButton = self.__createDiffButton( log.revision, self.__logInfo[ index + 1 ].revision ) if rev is not None and nextRev is not None: diffButton.setToolTip( "Click to see diff to the older revision (r." + str( rev ) + " to r." + str( nextRev ) + ")" ) else: diffButton.setEnabled( False ) diffButton.setToolTip( "Could not determine current or previous revision" ) else: diffButton = self.__createDiffButton( None, None ) diffButton.setEnabled( False ) diffButton.setToolTip( "Diff to previous revision is not avalable for the first revision" ) self.__logView.setItemWidget( newItem, DIFFTONEXT_COL, diffButton ) index += 1 self.__resizeLogView() self.__sortLogView() self.__logView.setFocus() return def __createDiffButton( self, rev, prevRev ): " Creates a diff button for a path " button = DiffButton() button.rev = rev button.prevRev = prevRev self.connect( button, SIGNAL( 'CustomClick' ), self.onDiffBetween ) return button def __resizeLogView( self ): " Resizes the plugins table " self.__logView.header().setStretchLastSection( True ) self.__logView.header().resizeSections( QHeaderView.ResizeToContents ) self.__logView.header().resizeSection( SELECT_COL, 28 ) self.__logView.header().setResizeMode( SELECT_COL, QHeaderView.Fixed ) self.__logView.header().resizeSection( DIFFTONEXT_COL, 24 ) self.__logView.header().setResizeMode( DIFFTONEXT_COL, QHeaderView.Fixed ) return def __sortLogView( self ): " Sorts the log table " self.__logView.sortItems( self.__logView.sortColumn(), self.__logView.header().sortIndicatorOrder() ) return def __createLayout( self ): " Creates the dialog layout " self.resize( 640, 480 ) self.setSizeGripEnabled( True ) vboxLayout = QVBoxLayout( self ) # Revisions to compare compareGroupbox = QGroupBox( self ) compareGroupbox.setTitle( "Revisions to compare" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( compareGroupbox.sizePolicy().hasHeightForWidth() ) compareGroupbox.setSizePolicy( sizePolicy ) revisionLayout = QHBoxLayout( compareGroupbox ) self.__lhsRevisionLabel = QLabel() self.__lhsRevisionLabel.setFrameStyle( QFrame.StyledPanel ) self.__lhsResetButton = QToolButton() self.__lhsResetButton.setIcon( PixmapCache().getIcon( pluginHomeDir + 'svnclearrev.png' ) ) self.__lhsResetButton.setFocusPolicy( Qt.NoFocus ) self.__lhsResetButton.setEnabled( False ) self.__lhsResetButton.setToolTip( "Reset revision to compare" ) self.__lhsResetButton.clicked.connect( self.__onLHSReset ) self.__rhsRevisionLabel = QLabel() self.__rhsRevisionLabel.setFrameStyle( QFrame.StyledPanel ) self.__rhsResetButton = QToolButton() self.__rhsResetButton.setIcon( PixmapCache().getIcon( pluginHomeDir + 'svnclearrev.png' ) ) self.__rhsResetButton.setFocusPolicy( Qt.NoFocus ) self.__rhsResetButton.setEnabled( False ) self.__rhsResetButton.setToolTip( "Reset revision to compare" ) self.__rhsResetButton.clicked.connect( self.__onRHSReset ) lhsLayout = QHBoxLayout() lhsLayout.addWidget( self.__lhsRevisionLabel ) lhsLayout.addWidget( self.__lhsResetButton ) rhsLayout = QHBoxLayout() rhsLayout.addWidget( self.__rhsRevisionLabel ) rhsLayout.addWidget( self.__rhsResetButton ) bothLayout = QVBoxLayout() bothLayout.addLayout( lhsLayout ) bothLayout.addLayout( rhsLayout ) revisionLayout.addLayout( bothLayout ) self.__diffButton = QToolButton() self.__diffButton.setText( "Diff" ) self.__diffButton.setFocusPolicy( Qt.NoFocus ) self.__diffButton.setEnabled( False ) self.__diffButton.clicked.connect( self.__onDiff ) revisionLayout.addWidget( self.__diffButton ) vboxLayout.addWidget( compareGroupbox ) # Log table logHeaderFrame = QFrame() logHeaderFrame.setFrameStyle( QFrame.StyledPanel ) logHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( logHeaderFrame ) logHeaderFrame.setFixedHeight( 24 ) logHeaderLayout = QHBoxLayout() logHeaderLayout.setContentsMargins( 3, 0, 0, 0 ) logHeaderLayout.addWidget( QLabel( "Subversion log of " + self.__path ) ) logHeaderFrame.setLayout( logHeaderLayout ) vboxLayout.addWidget( logHeaderFrame ) self.__logView = QTreeWidget() self.__logView.setAlternatingRowColors( True ) self.__logView.setRootIsDecorated( False ) self.__logView.setItemsExpandable( False ) self.__logView.setSortingEnabled( True ) self.__logView.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) self.__logViewHeader = QTreeWidgetItem( [ "", "", "Revision", "Date", "Author", "Message" ] ) self.__logView.setHeaderItem( self.__logViewHeader ) self.__logView.header().setSortIndicator( REVISION_COL, Qt.AscendingOrder ) self.__logView.itemChanged.connect( self.__onLogViewChanged ) vboxLayout.addWidget( self.__logView ) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle( QFrame.StyledPanel ) diffHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( diffHeaderFrame ) diffHeaderFrame.setFixedHeight( 24 ) diffLabel = QLabel( "Diff" ) diffExpandingSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise( True ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideDiffButton.setFixedSize( 20, 20 ) self.__showHideDiffButton.setToolTip( "Show diff" ) self.__showHideDiffButton.setFocusPolicy( Qt.NoFocus ) self.__showHideDiffButton.clicked.connect( self.__onShowHideDiff ) diffLayout = QHBoxLayout() diffLayout.setContentsMargins( 3, 0, 0, 0 ) diffLayout.addWidget( diffLabel ) diffLayout.addSpacerItem( diffExpandingSpacer ) diffLayout.addWidget( self.__showHideDiffButton ) diffHeaderFrame.setLayout( diffLayout ) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML( self.NODIFF ) self.__diffViewer.setVisible( False ) vboxLayout.addWidget( diffHeaderFrame ) vboxLayout.addWidget( self.__diffViewer ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Ok ) buttonBox.button( QDialogButtonBox.Ok ).setDefault( True ) buttonBox.accepted.connect( self.close ) vboxLayout.addWidget( buttonBox ) return @staticmethod def __setLightPalette( frame ): " Creates a lighter paletter for the widget background " palette = frame.palette() background = palette.color( QPalette.Background ) background.setRgb( min( background.red() + 30, 255 ), min( background.green() + 30, 255 ), min( background.blue() + 30, 255 ) ) palette.setColor( QPalette.Background, background ) frame.setPalette( palette ) return def __onShowHideDiff( self ): " On/off the diff section " if self.__diffViewer.isVisible(): self.__diffViewer.setVisible( False ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideDiffButton.setToolTip( "Show diff" ) else: self.__diffViewer.setVisible( True ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'more.png' ) ) self.__showHideDiffButton.setToolTip( "Hide diff" ) return def onDiffBetween( self, rev, prevRev ): " Called when diff is requested between revisions " if not rev or not prevRev: return QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) ) try: lhsContent = self.__client.cat( self.__path, prevRev ) rhsContent = self.__client.cat( self.__path, rev ) except Exception, exc: QApplication.restoreOverrideCursor() logging.error( str( exc ) ) return except:
def __createLayout( self ): " Creates the dialog layout " self.resize( 640, 480 ) self.setSizeGripEnabled( True ) vboxLayout = QVBoxLayout( self ) # Revisions to compare compareGroupbox = QGroupBox( self ) compareGroupbox.setTitle( "Revisions to compare" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( compareGroupbox.sizePolicy().hasHeightForWidth() ) compareGroupbox.setSizePolicy( sizePolicy ) revisionLayout = QHBoxLayout( compareGroupbox ) self.__lhsRevisionLabel = QLabel() self.__lhsRevisionLabel.setFrameStyle( QFrame.StyledPanel ) self.__lhsResetButton = QToolButton() self.__lhsResetButton.setIcon( PixmapCache().getIcon( pluginHomeDir + 'svnclearrev.png' ) ) self.__lhsResetButton.setFocusPolicy( Qt.NoFocus ) self.__lhsResetButton.setEnabled( False ) self.__lhsResetButton.setToolTip( "Reset revision to compare" ) self.__lhsResetButton.clicked.connect( self.__onLHSReset ) self.__rhsRevisionLabel = QLabel() self.__rhsRevisionLabel.setFrameStyle( QFrame.StyledPanel ) self.__rhsResetButton = QToolButton() self.__rhsResetButton.setIcon( PixmapCache().getIcon( pluginHomeDir + 'svnclearrev.png' ) ) self.__rhsResetButton.setFocusPolicy( Qt.NoFocus ) self.__rhsResetButton.setEnabled( False ) self.__rhsResetButton.setToolTip( "Reset revision to compare" ) self.__rhsResetButton.clicked.connect( self.__onRHSReset ) lhsLayout = QHBoxLayout() lhsLayout.addWidget( self.__lhsRevisionLabel ) lhsLayout.addWidget( self.__lhsResetButton ) rhsLayout = QHBoxLayout() rhsLayout.addWidget( self.__rhsRevisionLabel ) rhsLayout.addWidget( self.__rhsResetButton ) bothLayout = QVBoxLayout() bothLayout.addLayout( lhsLayout ) bothLayout.addLayout( rhsLayout ) revisionLayout.addLayout( bothLayout ) self.__diffButton = QToolButton() self.__diffButton.setText( "Diff" ) self.__diffButton.setFocusPolicy( Qt.NoFocus ) self.__diffButton.setEnabled( False ) self.__diffButton.clicked.connect( self.__onDiff ) revisionLayout.addWidget( self.__diffButton ) vboxLayout.addWidget( compareGroupbox ) # Log table logHeaderFrame = QFrame() logHeaderFrame.setFrameStyle( QFrame.StyledPanel ) logHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( logHeaderFrame ) logHeaderFrame.setFixedHeight( 24 ) logHeaderLayout = QHBoxLayout() logHeaderLayout.setContentsMargins( 3, 0, 0, 0 ) logHeaderLayout.addWidget( QLabel( "Subversion log of " + self.__path ) ) logHeaderFrame.setLayout( logHeaderLayout ) vboxLayout.addWidget( logHeaderFrame ) self.__logView = QTreeWidget() self.__logView.setAlternatingRowColors( True ) self.__logView.setRootIsDecorated( False ) self.__logView.setItemsExpandable( False ) self.__logView.setSortingEnabled( True ) self.__logView.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) self.__logViewHeader = QTreeWidgetItem( [ "", "", "Revision", "Date", "Author", "Message" ] ) self.__logView.setHeaderItem( self.__logViewHeader ) self.__logView.header().setSortIndicator( REVISION_COL, Qt.AscendingOrder ) self.__logView.itemChanged.connect( self.__onLogViewChanged ) vboxLayout.addWidget( self.__logView ) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle( QFrame.StyledPanel ) diffHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( diffHeaderFrame ) diffHeaderFrame.setFixedHeight( 24 ) diffLabel = QLabel( "Diff" ) diffExpandingSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise( True ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideDiffButton.setFixedSize( 20, 20 ) self.__showHideDiffButton.setToolTip( "Show diff" ) self.__showHideDiffButton.setFocusPolicy( Qt.NoFocus ) self.__showHideDiffButton.clicked.connect( self.__onShowHideDiff ) diffLayout = QHBoxLayout() diffLayout.setContentsMargins( 3, 0, 0, 0 ) diffLayout.addWidget( diffLabel ) diffLayout.addSpacerItem( diffExpandingSpacer ) diffLayout.addWidget( self.__showHideDiffButton ) diffHeaderFrame.setLayout( diffLayout ) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML( self.NODIFF ) self.__diffViewer.setVisible( False ) vboxLayout.addWidget( diffHeaderFrame ) vboxLayout.addWidget( self.__diffViewer ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Ok ) buttonBox.button( QDialogButtonBox.Ok ).setDefault( True ) buttonBox.accepted.connect( self.close ) vboxLayout.addWidget( buttonBox ) return
def __createLayout(self, pathsToCommit, pathsToIgnore): " Creates the dialog layout " self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Paths to commit part commitHeaderFrame = QFrame() commitHeaderFrame.setFrameStyle(QFrame.StyledPanel) commitHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(commitHeaderFrame) commitHeaderFrame.setFixedHeight(24) expandingCommitSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__selectAllButton = QToolButton() self.__selectAllButton.setAutoRaise(True) self.__selectAllButton.setIcon( PixmapCache().getIcon(pluginHomeDir + 'svnselectall.png')) self.__selectAllButton.setFixedSize(20, 20) self.__selectAllButton.setToolTip("Select all") self.__selectAllButton.setFocusPolicy(Qt.NoFocus) self.__selectAllButton.clicked.connect(self.__onSelectAll) commitHeaderLayout = QHBoxLayout() commitHeaderLayout.setContentsMargins(3, 0, 0, 0) commitHeaderLayout.addWidget( QLabel("Paths to commit (total: " + str(len(pathsToCommit)) + ")")) commitHeaderLayout.addSpacerItem(expandingCommitSpacer) commitHeaderLayout.addWidget(self.__selectAllButton) commitHeaderFrame.setLayout(commitHeaderLayout) vboxLayout.addWidget(commitHeaderFrame) self.__pathToCommitView = QTreeWidget() self.__configTable(self.__pathToCommitView) self.__pathToCommitHeader = QTreeWidgetItem(["", "Path", "Status", ""]) self.__pathToCommitView.setHeaderItem(self.__pathToCommitHeader) self.__pathToCommitView.header().setSortIndicator( PATH_COL, Qt.AscendingOrder) self.__pathToCommitView.itemChanged.connect(self.__onCommitPathChanged) vboxLayout.addWidget(self.__pathToCommitView) # Paths to ignore part headerFrame = QFrame() headerFrame.setFrameStyle(QFrame.StyledPanel) headerFrame.setAutoFillBackground(True) self.__setLightPalette(headerFrame) headerFrame.setFixedHeight(24) ignoreLabel = QLabel("Ignored paths (total: " + str(len(pathsToIgnore)) + ")") expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideIgnoredButton = QToolButton() self.__showHideIgnoredButton.setAutoRaise(True) self.__showHideIgnoredButton.setIcon(PixmapCache().getIcon('less.png')) self.__showHideIgnoredButton.setFixedSize(20, 20) self.__showHideIgnoredButton.setToolTip("Show ignored path list") self.__showHideIgnoredButton.setFocusPolicy(Qt.NoFocus) self.__showHideIgnoredButton.clicked.connect(self.__onShowHideIgnored) ignoredHeaderLayout = QHBoxLayout() ignoredHeaderLayout.setContentsMargins(3, 0, 0, 0) ignoredHeaderLayout.addWidget(ignoreLabel) ignoredHeaderLayout.addSpacerItem(expandingSpacer) ignoredHeaderLayout.addWidget(self.__showHideIgnoredButton) headerFrame.setLayout(ignoredHeaderLayout) vboxLayout.addWidget(headerFrame) self.__pathToIgnoreView = QTreeWidget() self.__configTable(self.__pathToIgnoreView) self.__pathToIgnoreView.setVisible(False) pathToIgnoreHeader = QTreeWidgetItem(["Path", "Status"]) self.__pathToIgnoreView.setHeaderItem(pathToIgnoreHeader) self.__pathToIgnoreView.header().setSortIndicator(0, Qt.AscendingOrder) vboxLayout.addWidget(self.__pathToIgnoreView) # Message part vboxLayout.addWidget(QLabel("Message")) self.__message = QTextEdit() self.__message.setAcceptRichText(False) metrics = QFontMetrics(self.__message.font()) rect = metrics.boundingRect("X") self.__message.setFixedHeight(rect.height() * 4 + 5) vboxLayout.addWidget(self.__message) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(PixmapCache().getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.__OKButton = buttonBox.button(QDialogButtonBox.Ok) self.__OKButton.setText("Commit") buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) buttonBox.accepted.connect(self.userAccept) buttonBox.rejected.connect(self.close) vboxLayout.addWidget(buttonBox) return
class SVNPluginCommitDialog(QDialog): " SVN Plugin commit dialog " NODIFF = '<html><body bgcolor="#ffffe6"></body></html>' 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 __resizeCommitPaths(self): " Resizes the plugins table " self.__pathToCommitView.header().setStretchLastSection(False) self.__pathToCommitView.header().resizeSections( QHeaderView.ResizeToContents) self.__pathToCommitView.header().resizeSection(CHECK_COL, 28) self.__pathToCommitView.header().setResizeMode(CHECK_COL, QHeaderView.Fixed) # By some reasons, to have PATH_COL visually adjustable the only STATUS_COL # must be set to be stretchable, so there is a comment below. # self.__pathToCommitView.header().setResizeMode( PATH_COL, QHeaderView.Stretch ) self.__pathToCommitView.header().setResizeMode(STATUS_COL, QHeaderView.Stretch) self.__pathToCommitView.header().resizeSection(DIFF_COL, 24) self.__pathToCommitView.header().setResizeMode(DIFF_COL, QHeaderView.Fixed) return def __sortCommitPaths(self): " Sorts the commit paths table " self.__pathToCommitView.sortItems( self.__pathToCommitView.sortColumn(), self.__pathToCommitView.header().sortIndicatorOrder()) return def __createDiffButton(self): " Creates a diff button for a path " button = DiffButton() self.connect(button, SIGNAL('CustomClick'), self.onDiff) return button @staticmethod def __setLightPalette(frame): " Creates a lighter paletter for the widget background " palette = frame.palette() background = palette.color(QPalette.Background) background.setRgb(min(background.red() + 30, 255), min(background.green() + 30, 255), min(background.blue() + 30, 255)) palette.setColor(QPalette.Background, background) frame.setPalette(palette) return @staticmethod def __configTable(table): " Sets common properties for a table " table.setAlternatingRowColors(True) table.setRootIsDecorated(False) table.setItemsExpandable(False) table.setSortingEnabled(True) table.setItemDelegate(NoOutlineHeightDelegate(4)) table.setUniformRowHeights(True) return def __createLayout(self, pathsToCommit, pathsToIgnore): " Creates the dialog layout " self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Paths to commit part commitHeaderFrame = QFrame() commitHeaderFrame.setFrameStyle(QFrame.StyledPanel) commitHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(commitHeaderFrame) commitHeaderFrame.setFixedHeight(24) expandingCommitSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__selectAllButton = QToolButton() self.__selectAllButton.setAutoRaise(True) self.__selectAllButton.setIcon( PixmapCache().getIcon(pluginHomeDir + 'svnselectall.png')) self.__selectAllButton.setFixedSize(20, 20) self.__selectAllButton.setToolTip("Select all") self.__selectAllButton.setFocusPolicy(Qt.NoFocus) self.__selectAllButton.clicked.connect(self.__onSelectAll) commitHeaderLayout = QHBoxLayout() commitHeaderLayout.setContentsMargins(3, 0, 0, 0) commitHeaderLayout.addWidget( QLabel("Paths to commit (total: " + str(len(pathsToCommit)) + ")")) commitHeaderLayout.addSpacerItem(expandingCommitSpacer) commitHeaderLayout.addWidget(self.__selectAllButton) commitHeaderFrame.setLayout(commitHeaderLayout) vboxLayout.addWidget(commitHeaderFrame) self.__pathToCommitView = QTreeWidget() self.__configTable(self.__pathToCommitView) self.__pathToCommitHeader = QTreeWidgetItem(["", "Path", "Status", ""]) self.__pathToCommitView.setHeaderItem(self.__pathToCommitHeader) self.__pathToCommitView.header().setSortIndicator( PATH_COL, Qt.AscendingOrder) self.__pathToCommitView.itemChanged.connect(self.__onCommitPathChanged) vboxLayout.addWidget(self.__pathToCommitView) # Paths to ignore part headerFrame = QFrame() headerFrame.setFrameStyle(QFrame.StyledPanel) headerFrame.setAutoFillBackground(True) self.__setLightPalette(headerFrame) headerFrame.setFixedHeight(24) ignoreLabel = QLabel("Ignored paths (total: " + str(len(pathsToIgnore)) + ")") expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideIgnoredButton = QToolButton() self.__showHideIgnoredButton.setAutoRaise(True) self.__showHideIgnoredButton.setIcon(PixmapCache().getIcon('less.png')) self.__showHideIgnoredButton.setFixedSize(20, 20) self.__showHideIgnoredButton.setToolTip("Show ignored path list") self.__showHideIgnoredButton.setFocusPolicy(Qt.NoFocus) self.__showHideIgnoredButton.clicked.connect(self.__onShowHideIgnored) ignoredHeaderLayout = QHBoxLayout() ignoredHeaderLayout.setContentsMargins(3, 0, 0, 0) ignoredHeaderLayout.addWidget(ignoreLabel) ignoredHeaderLayout.addSpacerItem(expandingSpacer) ignoredHeaderLayout.addWidget(self.__showHideIgnoredButton) headerFrame.setLayout(ignoredHeaderLayout) vboxLayout.addWidget(headerFrame) self.__pathToIgnoreView = QTreeWidget() self.__configTable(self.__pathToIgnoreView) self.__pathToIgnoreView.setVisible(False) pathToIgnoreHeader = QTreeWidgetItem(["Path", "Status"]) self.__pathToIgnoreView.setHeaderItem(pathToIgnoreHeader) self.__pathToIgnoreView.header().setSortIndicator(0, Qt.AscendingOrder) vboxLayout.addWidget(self.__pathToIgnoreView) # Message part vboxLayout.addWidget(QLabel("Message")) self.__message = QTextEdit() self.__message.setAcceptRichText(False) metrics = QFontMetrics(self.__message.font()) rect = metrics.boundingRect("X") self.__message.setFixedHeight(rect.height() * 4 + 5) vboxLayout.addWidget(self.__message) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(PixmapCache().getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.__OKButton = buttonBox.button(QDialogButtonBox.Ok) self.__OKButton.setText("Commit") buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) buttonBox.accepted.connect(self.userAccept) buttonBox.rejected.connect(self.close) vboxLayout.addWidget(buttonBox) return def __onShowHideDiff(self): if self.__diffViewer.isVisible(): self.__diffViewer.setVisible(False) self.__showHideDiffButton.setIcon( PixmapCache().getIcon('less.png')) self.__showHideDiffButton.setToolTip("Show diff") else: self.__diffViewer.setVisible(True) self.__showHideDiffButton.setIcon( PixmapCache().getIcon('more.png')) self.__showHideDiffButton.setToolTip("Hide diff") return def __onShowHideIgnored(self): if self.__pathToIgnoreView.isVisible(): self.__pathToIgnoreView.setVisible(False) self.__showHideIgnoredButton.setIcon( PixmapCache().getIcon('less.png')) self.__showHideIgnoredButton.setToolTip("Show ignored path list") else: self.__pathToIgnoreView.setVisible(True) self.__showHideIgnoredButton.setIcon( PixmapCache().getIcon('more.png')) self.__showHideIgnoredButton.setToolTip("Hide ignored path list") return def userAccept(self): " Triggered when the user clicks OK " # Collect the list of checked paths self.commitMessage = self.__message.toPlainText().strip() self.commitPaths = [] index = 0 while index < self.__pathToCommitView.topLevelItemCount(): item = self.__pathToCommitView.topLevelItem(index) if item.checkState(0) == Qt.Checked: path = str(item.text(1)) if os.path.isdir( path ) and not os.path.islink( path ) and \ not path.endswith( os.path.sep ): path += os.path.sep self.commitPaths.append(path) index += 1 self.accept() return def __getCheckedCount(self): " Provides the number of selected items in the commit paths section " index = 0 checkedCount = 0 while index < self.__pathToCommitView.topLevelItemCount(): item = self.__pathToCommitView.topLevelItem(index) if item.checkState(0) == Qt.Checked: checkedCount += 1 index += 1 return checkedCount def __updateSelectAllStatus(self): " Updates the select all status button " total = self.__pathToCommitView.topLevelItemCount() if total == 0 or total == self.__getCheckedCount(): self.__selectAllButton.setEnabled(False) else: self.__selectAllButton.setEnabled(True) return def __updateOKStatus(self): " Updates the OK button status " self.__OKButton.setEnabled(self.__getCheckedCount() > 0) return def __onCommitPathChanged(self, item, column): " Triggered when an item is changed " self.__updateSelectAllStatus() self.__updateOKStatus() return def __onSelectAll(self): " Triggered when select all button is clicked " index = 0 while index < self.__pathToCommitView.topLevelItemCount(): item = self.__pathToCommitView.topLevelItem(index) item.setCheckState(0, Qt.Checked) index += 1 self.__updateSelectAllStatus() self.__updateOKStatus() return def onDiff(self, path, status): " Triggered when diff for the path is called " if not path: return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: # Status is one of the following: # IND_ADDED, IND_DELETED, IND_MERGED, IND_MODIFIED_LR, IND_MODIFIED_L, IND_CONFLICTED repositoryContent = "" localContent = "" if status != IND_ADDED: client = self.__plugin.getSVNClient( self.__plugin.getSettings()) repositoryContent = client.cat(path) if status != IND_DELETED: with open(path) as f: localContent = f.read() diff = difflib.unified_diff(repositoryContent.splitlines(), localContent.splitlines()) nodiffMessage = path + " has no difference to the " \ "repository at revision HEAD" if diff is None: QApplication.restoreOverrideCursor() logging.info(nodiffMessage) return # There are changes, so replace the text and tell about the changes diffAsText = '\n'.join(list(diff)) if diffAsText.strip() == '': QApplication.restoreOverrideCursor() logging.info(nodiffMessage) return source = "+++ local " + os.path.basename(path) diffAsText = diffAsText.replace("+++ ", source, 1) diffAsText = diffAsText.replace("--- ", "--- repository at revision HEAD", 1) self.__diffViewer.setHTML( parse_from_memory(diffAsText, False, True)) if not self.__diffViewer.isVisible(): self.__onShowHideDiff() except Exception, exc: logging.error(str(exc)) except:
def __createLayout(self): " Creates the dialog layout " self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Revisions to compare compareGroupbox = QGroupBox(self) compareGroupbox.setTitle("Revisions to compare") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( compareGroupbox.sizePolicy().hasHeightForWidth()) compareGroupbox.setSizePolicy(sizePolicy) revisionLayout = QHBoxLayout(compareGroupbox) self.__lhsRevisionLabel = QLabel() self.__lhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__lhsResetButton = QToolButton() self.__lhsResetButton.setIcon(PixmapCache().getIcon(pluginHomeDir + 'svnclearrev.png')) self.__lhsResetButton.setFocusPolicy(Qt.NoFocus) self.__lhsResetButton.setEnabled(False) self.__lhsResetButton.setToolTip("Reset revision to compare") self.__lhsResetButton.clicked.connect(self.__onLHSReset) self.__rhsRevisionLabel = QLabel() self.__rhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__rhsResetButton = QToolButton() self.__rhsResetButton.setIcon(PixmapCache().getIcon(pluginHomeDir + 'svnclearrev.png')) self.__rhsResetButton.setFocusPolicy(Qt.NoFocus) self.__rhsResetButton.setEnabled(False) self.__rhsResetButton.setToolTip("Reset revision to compare") self.__rhsResetButton.clicked.connect(self.__onRHSReset) lhsLayout = QHBoxLayout() lhsLayout.addWidget(self.__lhsRevisionLabel) lhsLayout.addWidget(self.__lhsResetButton) rhsLayout = QHBoxLayout() rhsLayout.addWidget(self.__rhsRevisionLabel) rhsLayout.addWidget(self.__rhsResetButton) bothLayout = QVBoxLayout() bothLayout.addLayout(lhsLayout) bothLayout.addLayout(rhsLayout) revisionLayout.addLayout(bothLayout) self.__diffButton = QToolButton() self.__diffButton.setText("Diff") self.__diffButton.setFocusPolicy(Qt.NoFocus) self.__diffButton.setEnabled(False) self.__diffButton.clicked.connect(self.__onDiff) revisionLayout.addWidget(self.__diffButton) vboxLayout.addWidget(compareGroupbox) # Log table logHeaderFrame = QFrame() logHeaderFrame.setFrameStyle(QFrame.StyledPanel) logHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(logHeaderFrame) logHeaderFrame.setFixedHeight(24) logHeaderLayout = QHBoxLayout() logHeaderLayout.setContentsMargins(3, 0, 0, 0) logHeaderLayout.addWidget(QLabel("Subversion log of " + self.__path)) logHeaderFrame.setLayout(logHeaderLayout) vboxLayout.addWidget(logHeaderFrame) self.__logView = QTreeWidget() self.__logView.setAlternatingRowColors(True) self.__logView.setRootIsDecorated(False) self.__logView.setItemsExpandable(False) self.__logView.setSortingEnabled(True) self.__logView.setItemDelegate(NoOutlineHeightDelegate(4)) self.__logViewHeader = QTreeWidgetItem( ["", "", "Revision", "Date", "Author", "Message"]) self.__logView.setHeaderItem(self.__logViewHeader) self.__logView.header().setSortIndicator(REVISION_COL, Qt.AscendingOrder) self.__logView.itemChanged.connect(self.__onLogViewChanged) vboxLayout.addWidget(self.__logView) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(PixmapCache().getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok) buttonBox.button(QDialogButtonBox.Ok).setDefault(True) buttonBox.accepted.connect(self.close) vboxLayout.addWidget(buttonBox) return
class SVNPluginLogDialog(QDialog): " SVN plugin log dialog " NODIFF = '<html><body bgcolor="#ffffe6"></body></html>' def __init__(self, plugin, client, path, logInfo, parent=None): QDialog.__init__(self, parent) self.__plugin = plugin self.__client = client self.__path = path self.__logInfo = logInfo self.__lhsSelected = None self.__rhsSelected = None self.__createLayout() self.setWindowTitle("SVN Log") lastIndex = len(self.__logInfo) - 1 index = 0 for log in self.__logInfo: newItem = LogItem(log) self.__logView.addTopLevelItem(newItem) if index != lastIndex: rev = log.revision.number nextRev = self.__logInfo[index + 1].revision.number diffButton = self.__createDiffButton( log.revision, self.__logInfo[index + 1].revision) if rev is not None and nextRev is not None: diffButton.setToolTip( "Click to see diff to the older revision (r." + str(rev) + " to r." + str(nextRev) + ")") else: diffButton.setEnabled(False) diffButton.setToolTip( "Could not determine current or previous revision") else: diffButton = self.__createDiffButton(None, None) diffButton.setEnabled(False) diffButton.setToolTip( "Diff to previous revision is not avalable for the first revision" ) self.__logView.setItemWidget(newItem, DIFFTONEXT_COL, diffButton) index += 1 self.__resizeLogView() self.__sortLogView() self.__logView.setFocus() return def __createDiffButton(self, rev, prevRev): " Creates a diff button for a path " button = DiffButton() button.rev = rev button.prevRev = prevRev self.connect(button, SIGNAL('CustomClick'), self.onDiffBetween) return button def __resizeLogView(self): " Resizes the plugins table " self.__logView.header().setStretchLastSection(True) self.__logView.header().resizeSections(QHeaderView.ResizeToContents) self.__logView.header().resizeSection(SELECT_COL, 28) self.__logView.header().setResizeMode(SELECT_COL, QHeaderView.Fixed) self.__logView.header().resizeSection(DIFFTONEXT_COL, 24) self.__logView.header().setResizeMode(DIFFTONEXT_COL, QHeaderView.Fixed) return def __sortLogView(self): " Sorts the log table " self.__logView.sortItems(self.__logView.sortColumn(), self.__logView.header().sortIndicatorOrder()) return def __createLayout(self): " Creates the dialog layout " self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Revisions to compare compareGroupbox = QGroupBox(self) compareGroupbox.setTitle("Revisions to compare") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( compareGroupbox.sizePolicy().hasHeightForWidth()) compareGroupbox.setSizePolicy(sizePolicy) revisionLayout = QHBoxLayout(compareGroupbox) self.__lhsRevisionLabel = QLabel() self.__lhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__lhsResetButton = QToolButton() self.__lhsResetButton.setIcon(PixmapCache().getIcon(pluginHomeDir + 'svnclearrev.png')) self.__lhsResetButton.setFocusPolicy(Qt.NoFocus) self.__lhsResetButton.setEnabled(False) self.__lhsResetButton.setToolTip("Reset revision to compare") self.__lhsResetButton.clicked.connect(self.__onLHSReset) self.__rhsRevisionLabel = QLabel() self.__rhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__rhsResetButton = QToolButton() self.__rhsResetButton.setIcon(PixmapCache().getIcon(pluginHomeDir + 'svnclearrev.png')) self.__rhsResetButton.setFocusPolicy(Qt.NoFocus) self.__rhsResetButton.setEnabled(False) self.__rhsResetButton.setToolTip("Reset revision to compare") self.__rhsResetButton.clicked.connect(self.__onRHSReset) lhsLayout = QHBoxLayout() lhsLayout.addWidget(self.__lhsRevisionLabel) lhsLayout.addWidget(self.__lhsResetButton) rhsLayout = QHBoxLayout() rhsLayout.addWidget(self.__rhsRevisionLabel) rhsLayout.addWidget(self.__rhsResetButton) bothLayout = QVBoxLayout() bothLayout.addLayout(lhsLayout) bothLayout.addLayout(rhsLayout) revisionLayout.addLayout(bothLayout) self.__diffButton = QToolButton() self.__diffButton.setText("Diff") self.__diffButton.setFocusPolicy(Qt.NoFocus) self.__diffButton.setEnabled(False) self.__diffButton.clicked.connect(self.__onDiff) revisionLayout.addWidget(self.__diffButton) vboxLayout.addWidget(compareGroupbox) # Log table logHeaderFrame = QFrame() logHeaderFrame.setFrameStyle(QFrame.StyledPanel) logHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(logHeaderFrame) logHeaderFrame.setFixedHeight(24) logHeaderLayout = QHBoxLayout() logHeaderLayout.setContentsMargins(3, 0, 0, 0) logHeaderLayout.addWidget(QLabel("Subversion log of " + self.__path)) logHeaderFrame.setLayout(logHeaderLayout) vboxLayout.addWidget(logHeaderFrame) self.__logView = QTreeWidget() self.__logView.setAlternatingRowColors(True) self.__logView.setRootIsDecorated(False) self.__logView.setItemsExpandable(False) self.__logView.setSortingEnabled(True) self.__logView.setItemDelegate(NoOutlineHeightDelegate(4)) self.__logViewHeader = QTreeWidgetItem( ["", "", "Revision", "Date", "Author", "Message"]) self.__logView.setHeaderItem(self.__logViewHeader) self.__logView.header().setSortIndicator(REVISION_COL, Qt.AscendingOrder) self.__logView.itemChanged.connect(self.__onLogViewChanged) vboxLayout.addWidget(self.__logView) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(PixmapCache().getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok) buttonBox.button(QDialogButtonBox.Ok).setDefault(True) buttonBox.accepted.connect(self.close) vboxLayout.addWidget(buttonBox) return @staticmethod def __setLightPalette(frame): " Creates a lighter paletter for the widget background " palette = frame.palette() background = palette.color(QPalette.Background) background.setRgb(min(background.red() + 30, 255), min(background.green() + 30, 255), min(background.blue() + 30, 255)) palette.setColor(QPalette.Background, background) frame.setPalette(palette) return def __onShowHideDiff(self): " On/off the diff section " if self.__diffViewer.isVisible(): self.__diffViewer.setVisible(False) self.__showHideDiffButton.setIcon( PixmapCache().getIcon('less.png')) self.__showHideDiffButton.setToolTip("Show diff") else: self.__diffViewer.setVisible(True) self.__showHideDiffButton.setIcon( PixmapCache().getIcon('more.png')) self.__showHideDiffButton.setToolTip("Hide diff") return def onDiffBetween(self, rev, prevRev): " Called when diff is requested between revisions " if not rev or not prevRev: return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: lhsContent = self.__client.cat(self.__path, prevRev) rhsContent = self.__client.cat(self.__path, rev) except Exception, exc: QApplication.restoreOverrideCursor() logging.error(str(exc)) return except:
class SVNPluginLogDialog(QDialog): """SVN plugin log dialog""" NODIFF = '<html><body bgcolor="#ffffe6"></body></html>' def __init__(self, plugin, client, path, logInfo, parent=None): QDialog.__init__(self, parent) self.__plugin = plugin self.__client = client self.__path = path self.__logInfo = logInfo self.__lhsSelected = None self.__rhsSelected = None self.__createLayout() self.setWindowTitle("SVN Log") lastIndex = len(self.__logInfo) - 1 index = 0 for log in self.__logInfo: newItem = LogItem(log) self.__logView.addTopLevelItem(newItem) if index != lastIndex: rev = log.revision.number nextRev = self.__logInfo[index + 1].revision.number diffButton = self.__createDiffButton( log.revision, self.__logInfo[index + 1].revision) if rev is not None and nextRev is not None: diffButton.setToolTip( "Click to see diff to the older revision (r." + str(rev) + " to r." + str(nextRev) + ")") else: diffButton.setEnabled(False) diffButton.setToolTip( "Could not determine current or previous revision") else: diffButton = self.__createDiffButton(None, None) diffButton.setEnabled(False) diffButton.setToolTip( "Diff to previous revision is not avalable for the first revision" ) self.__logView.setItemWidget(newItem, DIFFTONEXT_COL, diffButton) index += 1 self.__resizeLogView() self.__sortLogView() self.__logView.setFocus() def __createDiffButton(self, rev, prevRev): """Creates a diff button for a path""" button = DiffButton() button.rev = rev button.prevRev = prevRev self.connect(button, SIGNAL('CustomClick'), self.onDiffBetween) return button def __resizeLogView(self): """Resizes the plugins table""" self.__logView.header().setStretchLastSection(True) self.__logView.header().resizeSections(QHeaderView.ResizeToContents) self.__logView.header().resizeSection(SELECT_COL, 28) self.__logView.header().setResizeMode(SELECT_COL, QHeaderView.Fixed) self.__logView.header().resizeSection(DIFFTONEXT_COL, 24) self.__logView.header().setResizeMode(DIFFTONEXT_COL, QHeaderView.Fixed) def __sortLogView(self): """Sorts the log table""" self.__logView.sortItems(self.__logView.sortColumn(), self.__logView.header().sortIndicatorOrder()) def __createLayout(self): """Creates the dialog layout""" self.resize(640, 480) self.setSizeGripEnabled(True) vboxLayout = QVBoxLayout(self) # Revisions to compare compareGroupbox = QGroupBox(self) compareGroupbox.setTitle("Revisions to compare") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( compareGroupbox.sizePolicy().hasHeightForWidth()) compareGroupbox.setSizePolicy(sizePolicy) revisionLayout = QHBoxLayout(compareGroupbox) self.__lhsRevisionLabel = QLabel() self.__lhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__lhsResetButton = QToolButton() self.__lhsResetButton.setIcon( getIcon(pluginHomeDir + 'svnclearrev.png')) self.__lhsResetButton.setFocusPolicy(Qt.NoFocus) self.__lhsResetButton.setEnabled(False) self.__lhsResetButton.setToolTip("Reset revision to compare") self.__lhsResetButton.clicked.connect(self.__onLHSReset) self.__rhsRevisionLabel = QLabel() self.__rhsRevisionLabel.setFrameStyle(QFrame.StyledPanel) self.__rhsResetButton = QToolButton() self.__rhsResetButton.setIcon( getIcon(pluginHomeDir + 'svnclearrev.png')) self.__rhsResetButton.setFocusPolicy(Qt.NoFocus) self.__rhsResetButton.setEnabled(False) self.__rhsResetButton.setToolTip("Reset revision to compare") self.__rhsResetButton.clicked.connect(self.__onRHSReset) lhsLayout = QHBoxLayout() lhsLayout.addWidget(self.__lhsRevisionLabel) lhsLayout.addWidget(self.__lhsResetButton) rhsLayout = QHBoxLayout() rhsLayout.addWidget(self.__rhsRevisionLabel) rhsLayout.addWidget(self.__rhsResetButton) bothLayout = QVBoxLayout() bothLayout.addLayout(lhsLayout) bothLayout.addLayout(rhsLayout) revisionLayout.addLayout(bothLayout) self.__diffButton = QToolButton() self.__diffButton.setText("Diff") self.__diffButton.setFocusPolicy(Qt.NoFocus) self.__diffButton.setEnabled(False) self.__diffButton.clicked.connect(self.__onDiff) revisionLayout.addWidget(self.__diffButton) vboxLayout.addWidget(compareGroupbox) # Log table logHeaderFrame = QFrame() logHeaderFrame.setFrameStyle(QFrame.StyledPanel) logHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(logHeaderFrame) logHeaderFrame.setFixedHeight(24) logHeaderLayout = QHBoxLayout() logHeaderLayout.setContentsMargins(3, 0, 0, 0) logHeaderLayout.addWidget(QLabel("Subversion log of " + self.__path)) logHeaderFrame.setLayout(logHeaderLayout) vboxLayout.addWidget(logHeaderFrame) self.__logView = QTreeWidget() self.__logView.setAlternatingRowColors(True) self.__logView.setRootIsDecorated(False) self.__logView.setItemsExpandable(False) self.__logView.setSortingEnabled(True) self.__logView.setItemDelegate(NoOutlineHeightDelegate(4)) self.__logViewHeader = QTreeWidgetItem( ["", "", "Revision", "Date", "Author", "Message"]) self.__logView.setHeaderItem(self.__logViewHeader) self.__logView.header().setSortIndicator(REVISION_COL, Qt.AscendingOrder) self.__logView.itemChanged.connect(self.__onLogViewChanged) vboxLayout.addWidget(self.__logView) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle(QFrame.StyledPanel) diffHeaderFrame.setAutoFillBackground(True) self.__setLightPalette(diffHeaderFrame) diffHeaderFrame.setFixedHeight(24) diffLabel = QLabel("Diff") diffExpandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise(True) self.__showHideDiffButton.setIcon(getIcon('less.png')) self.__showHideDiffButton.setFixedSize(20, 20) self.__showHideDiffButton.setToolTip("Show diff") self.__showHideDiffButton.setFocusPolicy(Qt.NoFocus) self.__showHideDiffButton.clicked.connect(self.__onShowHideDiff) diffLayout = QHBoxLayout() diffLayout.setContentsMargins(3, 0, 0, 0) diffLayout.addWidget(diffLabel) diffLayout.addSpacerItem(diffExpandingSpacer) diffLayout.addWidget(self.__showHideDiffButton) diffHeaderFrame.setLayout(diffLayout) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML(self.NODIFF) self.__diffViewer.setVisible(False) vboxLayout.addWidget(diffHeaderFrame) vboxLayout.addWidget(self.__diffViewer) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Ok) buttonBox.button(QDialogButtonBox.Ok).setDefault(True) buttonBox.accepted.connect(self.close) vboxLayout.addWidget(buttonBox) @staticmethod def __setLightPalette(frame): """Creates a lighter palette for the widget background""" palette = frame.palette() background = palette.color(QPalette.Background) background.setRgb(min(background.red() + 30, 255), min(background.green() + 30, 255), min(background.blue() + 30, 255)) palette.setColor(QPalette.Background, background) frame.setPalette(palette) def __onShowHideDiff(self): """On/off the diff section""" if self.__diffViewer.isVisible(): self.__diffViewer.setVisible(False) self.__showHideDiffButton.setIcon(getIcon('less.png')) self.__showHideDiffButton.setToolTip("Show diff") else: self.__diffViewer.setVisible(True) self.__showHideDiffButton.setIcon(getIcon('more.png')) self.__showHideDiffButton.setToolTip("Hide diff") def onDiffBetween(self, rev, prevRev): """Called when diff is requested between revisions""" if not rev or not prevRev: return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: lhsContent = self.__client.cat(self.__path, prevRev) rhsContent = self.__client.cat(self.__path, rev) except Exception as exc: QApplication.restoreOverrideCursor() logging.error(str(exc)) return except: QApplication.restoreOverrideCursor() logging.error("Unknown error while retrieving " + self.__path + " content from the repository.") return QApplication.restoreOverrideCursor() diff = difflib.unified_diff(lhsContent.splitlines(), rhsContent.splitlines()) nodiffMessage = self.__path + " has no difference from revision " + \ str(prevRev.number) + " to revision " + str(rev.number) if diff is None: logging.info(nodiffMessage) return # There are changes, so replace the text and tell about the changes diffAsText = '\n'.join(list(diff)) if diffAsText.strip() == '': logging.info(nodiffMessage) return lhs = "--- revision " + str(prevRev.number) diffAsText = diffAsText.replace("--- ", lhs, 1) rhs = "+++ revision " + str(rev.number) diffAsText = diffAsText.replace("+++ ", rhs, 1) self.__diffViewer.setHTML(parse_from_memory(diffAsText, False, True)) if not self.__diffViewer.isVisible(): self.__onShowHideDiff() def __onDiff(self): """Show diff between revisions""" self.onDiffBetween(self.__rhsSelected.revision, self.__lhsSelected.revision) def __onLogViewChanged(self, item, column): """Revision selected for diff""" if item.checkState(SELECT_COL) == Qt.Checked: # An item has been selected if self.__lhsSelected is None: self.__lhsSelected = item.logInfo self.__normalizeSelected() return if self.__rhsSelected is None: self.__rhsSelected = item.logInfo self.__normalizeSelected() return # Both of the places have been occupied. Pick the one to update. if item.logInfo.date > self.__rhsSelected.date: self.__rhsSelected = item.logInfo else: self.__lhsSelected = item.logInfo self.__normalizeSelected() else: # An item has been de-selected if self.__lhsSelected is not None: if self.__lhsSelected.revision.number == item.logInfo.revision.number: self.__lhsSelected = None elif self.__rhsSelected is not None: if self.__rhsSelected.revision.number == item.logInfo.revision.number: self.__rhsSelected = None self.__normalizeSelected() return def __onLHSReset(self): """Revision removed from diff""" if self.__lhsSelected is not None: self.__deselectRevision(self.__lhsSelected.revision.number) self.__lhsSelected = None self.__lhsRevisionLabel.setText("") self.__diffButton.setEnabled(False) self.__lhsResetButton.setEnabled(False) def __onRHSReset(self): """Revision removed from diff""" if self.__rhsSelected is not None: self.__deselectRevision(self.__rhsSelected.revision.number) self.__rhsSelected = None self.__rhsRevisionLabel.setText("") self.__diffButton.setEnabled(False) self.__rhsResetButton.setEnabled(False) def __deselectRevision(self, revNumber): """Deselects a revision in the list""" index = 0 while index < self.__logView.topLevelItemCount(): item = self.__logView.topLevelItem(index) if item.logInfo.revision.number == revNumber: item.setCheckState(SELECT_COL, Qt.Unchecked) break index += 1 def __normalizeSelected(self): """Puts the earliest revision first""" if self.__lhsSelected is not None and self.__rhsSelected is not None: # It might be necessary to exchange the versions if self.__rhsSelected.date < self.__lhsSelected.date: temp = self.__rhsSelected self.__rhsSelected = self.__lhsSelected self.__lhsSelected = temp self.__diffButton.setEnabled(True) else: self.__diffButton.setEnabled(False) if self.__lhsSelected is None: self.__lhsRevisionLabel.setText("") self.__lhsRevisionLabel.setToolTip("") self.__lhsResetButton.setEnabled(False) else: self.__lhsRevisionLabel.setText( str(self.__lhsSelected.revision.number) + " (" + timestampToString(self.__lhsSelected.date) + ")") self.__lhsRevisionLabel.setToolTip(str(self.__lhsSelected.message)) self.__lhsResetButton.setEnabled(True) if self.__rhsSelected is None: self.__rhsRevisionLabel.setText("") self.__rhsRevisionLabel.setToolTip("") self.__rhsResetButton.setEnabled(False) else: self.__rhsRevisionLabel.setText( str(self.__rhsSelected.revision.number) + " (" + timestampToString(self.__rhsSelected.date) + ")") self.__rhsRevisionLabel.setToolTip(str(self.__rhsSelected.message)) self.__rhsResetButton.setEnabled(True)
class SVNPluginCommitDialog( QDialog ): " SVN Plugin commit dialog " NODIFF = '<html><body bgcolor="#ffffe6"></body></html>' 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 __resizeCommitPaths( self ): " Resizes the plugins table " self.__pathToCommitView.header().setStretchLastSection( False ) self.__pathToCommitView.header().resizeSections( QHeaderView.ResizeToContents ) self.__pathToCommitView.header().resizeSection( CHECK_COL, 28 ) self.__pathToCommitView.header().setResizeMode( CHECK_COL, QHeaderView.Fixed ) # By some reasons, to have PATH_COL visually adjustable the only STATUS_COL # must be set to be stretchable, so there is a comment below. # self.__pathToCommitView.header().setResizeMode( PATH_COL, QHeaderView.Stretch ) self.__pathToCommitView.header().setResizeMode( STATUS_COL, QHeaderView.Stretch ) self.__pathToCommitView.header().resizeSection( DIFF_COL, 24 ) self.__pathToCommitView.header().setResizeMode( DIFF_COL, QHeaderView.Fixed ) return def __sortCommitPaths( self ): " Sorts the commit paths table " self.__pathToCommitView.sortItems( self.__pathToCommitView.sortColumn(), self.__pathToCommitView.header().sortIndicatorOrder() ) return def __createDiffButton( self ): " Creates a diff button for a path " button = DiffButton() self.connect( button, SIGNAL( 'CustomClick' ), self.onDiff ) return button @staticmethod def __setLightPalette( frame ): " Creates a lighter paletter for the widget background " palette = frame.palette() background = palette.color( QPalette.Background ) background.setRgb( min( background.red() + 30, 255 ), min( background.green() + 30, 255 ), min( background.blue() + 30, 255 ) ) palette.setColor( QPalette.Background, background ) frame.setPalette( palette ) return @staticmethod def __configTable( table ): " Sets common properties for a table " table.setAlternatingRowColors( True ) table.setRootIsDecorated( False ) table.setItemsExpandable( False ) table.setSortingEnabled( True ) table.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) table.setUniformRowHeights( True ) return def __createLayout( self, pathsToCommit, pathsToIgnore ): " Creates the dialog layout " self.resize( 640, 480 ) self.setSizeGripEnabled( True ) vboxLayout = QVBoxLayout( self ) # Paths to commit part commitHeaderFrame = QFrame() commitHeaderFrame.setFrameStyle( QFrame.StyledPanel ) commitHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( commitHeaderFrame ) commitHeaderFrame.setFixedHeight( 24 ) expandingCommitSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__selectAllButton = QToolButton() self.__selectAllButton.setAutoRaise( True ) self.__selectAllButton.setIcon( PixmapCache().getIcon( pluginHomeDir + 'svnselectall.png' ) ) self.__selectAllButton.setFixedSize( 20, 20 ) self.__selectAllButton.setToolTip( "Select all" ) self.__selectAllButton.setFocusPolicy( Qt.NoFocus ) self.__selectAllButton.clicked.connect( self.__onSelectAll ) commitHeaderLayout = QHBoxLayout() commitHeaderLayout.setContentsMargins( 3, 0, 0, 0 ) commitHeaderLayout.addWidget( QLabel( "Paths to commit (total: " + str( len( pathsToCommit ) ) + ")" ) ) commitHeaderLayout.addSpacerItem( expandingCommitSpacer ) commitHeaderLayout.addWidget( self.__selectAllButton ) commitHeaderFrame.setLayout( commitHeaderLayout ) vboxLayout.addWidget( commitHeaderFrame ) self.__pathToCommitView = QTreeWidget() self.__configTable( self.__pathToCommitView ) self.__pathToCommitHeader = QTreeWidgetItem( [ "", "Path", "Status", "" ] ) self.__pathToCommitView.setHeaderItem( self.__pathToCommitHeader ) self.__pathToCommitView.header().setSortIndicator( PATH_COL, Qt.AscendingOrder ) self.__pathToCommitView.itemChanged.connect( self.__onCommitPathChanged ) vboxLayout.addWidget( self.__pathToCommitView ) # Paths to ignore part headerFrame = QFrame() headerFrame.setFrameStyle( QFrame.StyledPanel ) headerFrame.setAutoFillBackground( True ) self.__setLightPalette( headerFrame ) headerFrame.setFixedHeight( 24 ) ignoreLabel = QLabel( "Ignored paths (total: " + str( len( pathsToIgnore ) ) + ")" ) expandingSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__showHideIgnoredButton = QToolButton() self.__showHideIgnoredButton.setAutoRaise( True ) self.__showHideIgnoredButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideIgnoredButton.setFixedSize( 20, 20 ) self.__showHideIgnoredButton.setToolTip( "Show ignored path list" ) self.__showHideIgnoredButton.setFocusPolicy( Qt.NoFocus ) self.__showHideIgnoredButton.clicked.connect( self.__onShowHideIgnored ) ignoredHeaderLayout = QHBoxLayout() ignoredHeaderLayout.setContentsMargins( 3, 0, 0, 0 ) ignoredHeaderLayout.addWidget( ignoreLabel ) ignoredHeaderLayout.addSpacerItem( expandingSpacer ) ignoredHeaderLayout.addWidget( self.__showHideIgnoredButton ) headerFrame.setLayout( ignoredHeaderLayout ) vboxLayout.addWidget( headerFrame ) self.__pathToIgnoreView = QTreeWidget() self.__configTable( self.__pathToIgnoreView ) self.__pathToIgnoreView.setVisible( False ) pathToIgnoreHeader = QTreeWidgetItem( [ "Path", "Status" ] ) self.__pathToIgnoreView.setHeaderItem( pathToIgnoreHeader ) self.__pathToIgnoreView.header().setSortIndicator( 0, Qt.AscendingOrder ) vboxLayout.addWidget( self.__pathToIgnoreView ) # Message part vboxLayout.addWidget( QLabel( "Message" ) ) self.__message = QTextEdit() self.__message.setAcceptRichText( False ) metrics = QFontMetrics( self.__message.font() ) rect = metrics.boundingRect( "X" ) self.__message.setFixedHeight( rect.height() * 4 + 5 ) vboxLayout.addWidget( self.__message ) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle( QFrame.StyledPanel ) diffHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( diffHeaderFrame ) diffHeaderFrame.setFixedHeight( 24 ) diffLabel = QLabel( "Diff" ) diffExpandingSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise( True ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideDiffButton.setFixedSize( 20, 20 ) self.__showHideDiffButton.setToolTip( "Show diff" ) self.__showHideDiffButton.setFocusPolicy( Qt.NoFocus ) self.__showHideDiffButton.clicked.connect( self.__onShowHideDiff ) diffLayout = QHBoxLayout() diffLayout.setContentsMargins( 3, 0, 0, 0 ) diffLayout.addWidget( diffLabel ) diffLayout.addSpacerItem( diffExpandingSpacer ) diffLayout.addWidget( self.__showHideDiffButton ) diffHeaderFrame.setLayout( diffLayout ) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML( self.NODIFF ) self.__diffViewer.setVisible( False ) vboxLayout.addWidget( diffHeaderFrame ) vboxLayout.addWidget( self.__diffViewer ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) self.__OKButton = buttonBox.button( QDialogButtonBox.Ok ) self.__OKButton.setText( "Commit" ) buttonBox.button( QDialogButtonBox.Cancel ).setDefault( True ) buttonBox.accepted.connect( self.userAccept ) buttonBox.rejected.connect( self.close ) vboxLayout.addWidget( buttonBox ) return def __onShowHideDiff( self ): if self.__diffViewer.isVisible(): self.__diffViewer.setVisible( False ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideDiffButton.setToolTip( "Show diff" ) else: self.__diffViewer.setVisible( True ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'more.png' ) ) self.__showHideDiffButton.setToolTip( "Hide diff" ) return def __onShowHideIgnored( self ): if self.__pathToIgnoreView.isVisible(): self.__pathToIgnoreView.setVisible( False ) self.__showHideIgnoredButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideIgnoredButton.setToolTip( "Show ignored path list" ) else: self.__pathToIgnoreView.setVisible( True ) self.__showHideIgnoredButton.setIcon( PixmapCache().getIcon( 'more.png' ) ) self.__showHideIgnoredButton.setToolTip( "Hide ignored path list" ) return def userAccept( self ): " Triggered when the user clicks OK " # Collect the list of checked paths self.commitMessage = self.__message.toPlainText().strip() self.commitPaths = [] index = 0 while index < self.__pathToCommitView.topLevelItemCount(): item = self.__pathToCommitView.topLevelItem( index ) if item.checkState( 0 ) == Qt.Checked: path = str( item.text( 1 ) ) if os.path.isdir( path ) and not os.path.islink( path ) and \ not path.endswith( os.path.sep ): path += os.path.sep self.commitPaths.append( path ) index += 1 self.accept() return def __getCheckedCount( self ): " Provides the number of selected items in the commit paths section " index = 0 checkedCount = 0 while index < self.__pathToCommitView.topLevelItemCount(): item = self.__pathToCommitView.topLevelItem( index ) if item.checkState( 0 ) == Qt.Checked: checkedCount += 1 index += 1 return checkedCount def __updateSelectAllStatus( self ): " Updates the select all status button " total = self.__pathToCommitView.topLevelItemCount() if total == 0 or total == self.__getCheckedCount(): self.__selectAllButton.setEnabled( False ) else: self.__selectAllButton.setEnabled( True ) return def __updateOKStatus( self ): " Updates the OK button status " self.__OKButton.setEnabled( self.__getCheckedCount() > 0 ) return def __onCommitPathChanged( self, item, column ): " Triggered when an item is changed " self.__updateSelectAllStatus() self.__updateOKStatus() return def __onSelectAll( self ): " Triggered when select all button is clicked " index = 0 while index < self.__pathToCommitView.topLevelItemCount(): item = self.__pathToCommitView.topLevelItem( index ) item.setCheckState( 0, Qt.Checked ) index += 1 self.__updateSelectAllStatus() self.__updateOKStatus() return def onDiff( self, path, status ): " Triggered when diff for the path is called " if not path: return QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) ) try: # Status is one of the following: # IND_ADDED, IND_DELETED, IND_MERGED, IND_MODIFIED_LR, IND_MODIFIED_L, IND_CONFLICTED repositoryContent = "" localContent = "" if status != IND_ADDED: client = self.__plugin.getSVNClient( self.__plugin.getSettings() ) repositoryContent = client.cat( path ) if status != IND_DELETED: with open( path ) as f: localContent = f.read() diff = difflib.unified_diff( repositoryContent.splitlines(), localContent.splitlines() ) nodiffMessage = path + " has no difference to the " \ "repository at revision HEAD" if diff is None: QApplication.restoreOverrideCursor() logging.info( nodiffMessage ) return # There are changes, so replace the text and tell about the changes diffAsText = '\n'.join( list( diff ) ) if diffAsText.strip() == '': QApplication.restoreOverrideCursor() logging.info( nodiffMessage ) return source = "+++ local " + os.path.basename( path ) diffAsText = diffAsText.replace( "+++ ", source, 1 ) diffAsText = diffAsText.replace( "--- ", "--- repository at revision HEAD", 1 ) self.__diffViewer.setHTML( parse_from_memory( diffAsText, False, True ) ) if not self.__diffViewer.isVisible(): self.__onShowHideDiff() except Exception, exc: logging.error( str( exc ) ) except:
def __createLayout( self, pathsToCommit, pathsToIgnore ): " Creates the dialog layout " self.resize( 640, 480 ) self.setSizeGripEnabled( True ) vboxLayout = QVBoxLayout( self ) # Paths to commit part commitHeaderFrame = QFrame() commitHeaderFrame.setFrameStyle( QFrame.StyledPanel ) commitHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( commitHeaderFrame ) commitHeaderFrame.setFixedHeight( 24 ) expandingCommitSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__selectAllButton = QToolButton() self.__selectAllButton.setAutoRaise( True ) self.__selectAllButton.setIcon( PixmapCache().getIcon( pluginHomeDir + 'svnselectall.png' ) ) self.__selectAllButton.setFixedSize( 20, 20 ) self.__selectAllButton.setToolTip( "Select all" ) self.__selectAllButton.setFocusPolicy( Qt.NoFocus ) self.__selectAllButton.clicked.connect( self.__onSelectAll ) commitHeaderLayout = QHBoxLayout() commitHeaderLayout.setContentsMargins( 3, 0, 0, 0 ) commitHeaderLayout.addWidget( QLabel( "Paths to commit (total: " + str( len( pathsToCommit ) ) + ")" ) ) commitHeaderLayout.addSpacerItem( expandingCommitSpacer ) commitHeaderLayout.addWidget( self.__selectAllButton ) commitHeaderFrame.setLayout( commitHeaderLayout ) vboxLayout.addWidget( commitHeaderFrame ) self.__pathToCommitView = QTreeWidget() self.__configTable( self.__pathToCommitView ) self.__pathToCommitHeader = QTreeWidgetItem( [ "", "Path", "Status", "" ] ) self.__pathToCommitView.setHeaderItem( self.__pathToCommitHeader ) self.__pathToCommitView.header().setSortIndicator( PATH_COL, Qt.AscendingOrder ) self.__pathToCommitView.itemChanged.connect( self.__onCommitPathChanged ) vboxLayout.addWidget( self.__pathToCommitView ) # Paths to ignore part headerFrame = QFrame() headerFrame.setFrameStyle( QFrame.StyledPanel ) headerFrame.setAutoFillBackground( True ) self.__setLightPalette( headerFrame ) headerFrame.setFixedHeight( 24 ) ignoreLabel = QLabel( "Ignored paths (total: " + str( len( pathsToIgnore ) ) + ")" ) expandingSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__showHideIgnoredButton = QToolButton() self.__showHideIgnoredButton.setAutoRaise( True ) self.__showHideIgnoredButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideIgnoredButton.setFixedSize( 20, 20 ) self.__showHideIgnoredButton.setToolTip( "Show ignored path list" ) self.__showHideIgnoredButton.setFocusPolicy( Qt.NoFocus ) self.__showHideIgnoredButton.clicked.connect( self.__onShowHideIgnored ) ignoredHeaderLayout = QHBoxLayout() ignoredHeaderLayout.setContentsMargins( 3, 0, 0, 0 ) ignoredHeaderLayout.addWidget( ignoreLabel ) ignoredHeaderLayout.addSpacerItem( expandingSpacer ) ignoredHeaderLayout.addWidget( self.__showHideIgnoredButton ) headerFrame.setLayout( ignoredHeaderLayout ) vboxLayout.addWidget( headerFrame ) self.__pathToIgnoreView = QTreeWidget() self.__configTable( self.__pathToIgnoreView ) self.__pathToIgnoreView.setVisible( False ) pathToIgnoreHeader = QTreeWidgetItem( [ "Path", "Status" ] ) self.__pathToIgnoreView.setHeaderItem( pathToIgnoreHeader ) self.__pathToIgnoreView.header().setSortIndicator( 0, Qt.AscendingOrder ) vboxLayout.addWidget( self.__pathToIgnoreView ) # Message part vboxLayout.addWidget( QLabel( "Message" ) ) self.__message = QTextEdit() self.__message.setAcceptRichText( False ) metrics = QFontMetrics( self.__message.font() ) rect = metrics.boundingRect( "X" ) self.__message.setFixedHeight( rect.height() * 4 + 5 ) vboxLayout.addWidget( self.__message ) # Diff part diffHeaderFrame = QFrame() diffHeaderFrame.setFrameStyle( QFrame.StyledPanel ) diffHeaderFrame.setAutoFillBackground( True ) self.__setLightPalette( diffHeaderFrame ) diffHeaderFrame.setFixedHeight( 24 ) diffLabel = QLabel( "Diff" ) diffExpandingSpacer = QSpacerItem( 10, 10, QSizePolicy.Expanding ) self.__showHideDiffButton = QToolButton() self.__showHideDiffButton.setAutoRaise( True ) self.__showHideDiffButton.setIcon( PixmapCache().getIcon( 'less.png' ) ) self.__showHideDiffButton.setFixedSize( 20, 20 ) self.__showHideDiffButton.setToolTip( "Show diff" ) self.__showHideDiffButton.setFocusPolicy( Qt.NoFocus ) self.__showHideDiffButton.clicked.connect( self.__onShowHideDiff ) diffLayout = QHBoxLayout() diffLayout.setContentsMargins( 3, 0, 0, 0 ) diffLayout.addWidget( diffLabel ) diffLayout.addSpacerItem( diffExpandingSpacer ) diffLayout.addWidget( self.__showHideDiffButton ) diffHeaderFrame.setLayout( diffLayout ) self.__diffViewer = DiffTabWidget() self.__diffViewer.setHTML( self.NODIFF ) self.__diffViewer.setVisible( False ) vboxLayout.addWidget( diffHeaderFrame ) vboxLayout.addWidget( self.__diffViewer ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) self.__OKButton = buttonBox.button( QDialogButtonBox.Ok ) self.__OKButton.setText( "Commit" ) buttonBox.button( QDialogButtonBox.Cancel ).setDefault( True ) buttonBox.accepted.connect( self.userAccept ) buttonBox.rejected.connect( self.close ) vboxLayout.addWidget( buttonBox ) return