Logo Search packages:      
Sourcecode: qct version File versions  Download package

changeselect.py

#!/usr/bin/env python
# Change Selection Dialog
#
# Copyright 2007 Steve Borho
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qctlib.ui_select import Ui_ChangeDialog
from qctlib.utils import formatPatchRichText
from qctlib.patches import iter_patched, hunk_from_header
import difflib

patchColors = {
    'std': 'black',
    'new': '#009600',
    'remove': '#C80000',
    'head': '#C800C8'}

00022 class ChangeDialog(QDialog):
    '''QCT commit tool GUI logic'''
00024     def __init__(self, changefile, origfile):
        '''Initialize the dialog window, calculate diff hunks'''
        QDialog.__init__(self)

        self.changefile = changefile
        self.origfile = origfile
        self.accepted = False
        self.ui = Ui_ChangeDialog()
        self.ui.setupUi(self)
        self.ui.buttonBox.setStandardButtons(QDialogButtonBox.Cancel)
        settings = QSettings('vcs', 'qct')
        settings.beginGroup('changetool')
        if settings.contains('size'):
            self.resize(settings.value('size').toSize())
            self.move(settings.value('pos').toPoint())
        settings.endGroup()

        # Calculate unified diffs, split into hunks
        self.hunklist = []
        hunk = None
        self.origtext = open(origfile, 'rb').readlines()
        changetext = open(changefile, 'rb').readlines()
        for line in difflib.unified_diff(self.origtext, changetext):
            if line.startswith('@@'):
                if hunk: self.hunklist.append(hunk)
                hunk = [line]
            elif hunk:
                hunk.append(line)
        if hunk: self.hunklist.append(hunk)

        self.curhunk = 0
        self.showhunk()

    def showhunk(self):
        text = ''.join(self.hunklist[self.curhunk])
        h = formatPatchRichText(text, patchColors)
        self.ui.textEdit.setHtml(h)

00062     def on_keepButton_pressed(self):
        '''User has pushed the keep button'''
        self.curhunk += 1
        if self.curhunk < len(self.hunklist):
            self.showhunk()
        else:
            self.ui.keepButton.setEnabled(False)
            self.ui.shelveButton.setEnabled(False)
            self.ui.buttonBox.setStandardButtons( \
                    QDialogButtonBox.Cancel | QDialogButtonBox.Ok)

    def on_shelveButton_pressed(self):
        del self.hunklist[self.curhunk]
        if self.curhunk < len(self.hunklist):
            self.showhunk()
        else:
            self.ui.keepButton.setEnabled(False)
            self.ui.shelveButton.setEnabled(False)
            self.ui.buttonBox.setStandardButtons( \
                    QDialogButtonBox.Cancel | QDialogButtonBox.Ok)

00083     def reject(self):
        '''User has pushed the cancel button'''
        self.close()

00087     def closeEvent(self, e = None):
        '''Dialog is closing, save persistent state'''
        settings = QSettings('vcs', 'qct')
        settings.beginGroup('changetool')
        settings.setValue("size", QVariant(self.size()))
        settings.setValue("pos", QVariant(self.pos()))
        settings.endGroup()
        settings.sync()
        if e is not None:
            e.accept()

00098     def accept(self):
        '''User has pushed the accept button'''
        # Make sure at least one hunk was selected
        if not self.hunklist:
            self.close()
            return

        # Determine lines we expect from iter_patched to replace
        lasthunk = self.hunklist[-1]
        lasth = hunk_from_header(lasthunk[0])
                
        # Apply selected hunks to origfile
        try:
            patchlines = ['--- orig\n', '+++ changed\n']
            for p in self.hunklist:
                patchlines += p
            replace = []
            for line in iter_patched(self.origtext, patchlines):
                replace.append(line)
            if replace:
                self.origtext[0:lasth.orig_pos + lasth.orig_range - 1] = replace
            f = open(self.origfile, 'wb')
            f.writelines(self.origtext)
            f.close()
            self.accepted = True
        except Exception, e:
            print str(e)
        finally:
            self.close()

# Test operation by running directly
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    try:
        (changefile, origfile) = sys.argv[1:3]
    except ValueError:
        print sys.argv[0], 'changed-file orig-file'
        sys.exit(1)
    dialog = ChangeDialog(changefile, origfile)
    dialog.show()
    app.exec_()
    if dialog.accepted:
        sys.exit(0)
    else:
        print 'changes not selected'
        sys.exit(1)

Generated by  Doxygen 1.6.0   Back to index