Esempio n. 1
0
    def setupViews(self):
        self.tableViews = {
            'left': self.fileHistoryLeft,
            'right': self.fileHistoryRight
        }
        # viewers are Scintilla editors
        self.viewers = {}
        # block are diff-block displayers
        self.block = {}
        self.diffblock = blockmatcher.BlockMatch(self.frame)
        lay = QHBoxLayout(self.frame)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)

        try:
            contents = open(self.repo.wjoin(self.filename), "rb").read(1024)
            lexer = lexers.get_lexer(self.filename, contents, self)
        except Exception:
            lexer = None

        for side, idx in (('left', 0), ('right', 3)):
            sci = Scintilla(self.frame)
            sci.verticalScrollBar().setFocusPolicy(Qt.StrongFocus)
            sci.setFocusProxy(sci.verticalScrollBar())
            sci.verticalScrollBar().installEventFilter(self)

            sci.setContextMenuPolicy(Qt.CustomContextMenu)
            sci.customContextMenuRequested.connect(
                functools.partial(self.fileViewMenuRequest, sci))

            sci.setFrameShape(QFrame.NoFrame)
            sci.setMarginLineNumbers(1, True)
            sci.SendScintilla(sci.SCI_SETSELEOLFILLED, True)

            sci.setLexer(lexer)
            if lexer is None:
                sci.setFont(qtlib.getfont('fontdiff').font())

            sci.setReadOnly(True)
            sci.setUtf8(True)
            lay.addWidget(sci)

            # hide margin 0 (markers)
            sci.SendScintilla(sci.SCI_SETMARGINTYPEN, 0, 0)
            sci.SendScintilla(sci.SCI_SETMARGINWIDTHN, 0, 0)
            # setup margin 1 for line numbers only
            sci.SendScintilla(sci.SCI_SETMARGINTYPEN, 1, 1)
            sci.SendScintilla(sci.SCI_SETMARGINWIDTHN, 1, 20)
            sci.SendScintilla(sci.SCI_SETMARGINMASKN, 1, 0)

            # define markers for colorize zones of diff
            self.markerplus = sci.markerDefine(QsciScintilla.Background)
            sci.SendScintilla(sci.SCI_MARKERSETBACK, self.markerplus, 0xB0FFA0)
            self.markerminus = sci.markerDefine(QsciScintilla.Background)
            sci.SendScintilla(sci.SCI_MARKERSETBACK, self.markerminus,
                              0xA0A0FF)
            self.markertriangle = sci.markerDefine(QsciScintilla.Background)
            sci.SendScintilla(sci.SCI_MARKERSETBACK, self.markertriangle,
                              0xFFA0A0)

            self.viewers[side] = sci
            blk = blockmatcher.BlockList(self.frame)
            blk.linkScrollBar(sci.verticalScrollBar())
            self.diffblock.linkScrollBar(sci.verticalScrollBar(), side)
            lay.insertWidget(idx, blk)
            self.block[side] = blk
        lay.insertWidget(2, self.diffblock)

        for side in sides:
            table = getattr(self, 'tableView_revisions_%s' % side)
            table.setTabKeyNavigation(False)
            #table.installEventFilter(self)
            table.revisionSelected.connect(self.onRevisionSelected)
            table.revisionActivated.connect(self.onRevisionActivated)

            self.viewers[side].verticalScrollBar().valueChanged.connect(
                lambda value, side=side: self.sbar_changed(
                    value, side, 'vertical'))
            self.viewers[side].horizontalScrollBar().valueChanged.connect(
                lambda value, side=side: self.sbar_changed(
                    value, side, 'horizontal'))

        self.setTabOrder(table, self.viewers['left'])
        self.setTabOrder(self.viewers['left'], self.viewers['right'])

        # timer used to fill viewers with diff block markers during GUI idle time
        self.timer = QTimer()
        self.timer.setSingleShot(False)
        self.timer.timeout.connect(self.idle_fill_files)
Esempio n. 2
0
    def displayFile(self, filename=None, status=None):
        if isinstance(filename, (unicode, QString)):
            filename = hglib.fromunicode(filename)
            status = hglib.fromunicode(status)
        if filename and self._filename == filename:
            # Get the last visible line to restore it after reloading the editor
            lastCursorPosition = self.sci.getCursorPosition()
            lastScrollPosition = self.sci.firstVisibleLine()
        else:
            lastCursorPosition = (0, 0)
            lastScrollPosition = 0
        self._filename, self._status = filename, status

        self.clearMarkup()
        self._diffs = []
        if filename is None:
            self.restrictModes(False, False, False)
            return

        if self._ctx2:
            ctx2 = self._ctx2
        elif self._parent == 0 or len(self._ctx.parents()) == 1:
            ctx2 = self._ctx.p1()
        else:
            ctx2 = self._ctx.p2()
        fd = filedata.FileData(self._ctx, ctx2, filename, status)

        if fd.elabel:
            self.extralabel.setText(fd.elabel)
            self.extralabel.show()
        else:
            self.extralabel.hide()
        self.filenamelabel.setText(fd.flabel)

        if not fd.isValid():
            self.sci.setText(fd.error)
            self.sci.setLexer(None)
            self.sci.setFont(qtlib.getfont("fontlog").font())
            self.sci.setMarginWidth(1, 0)
            self.blk.setVisible(False)
            self.restrictModes(False, False, False)
            return

        candiff = bool(fd.diff)
        canfile = bool(fd.contents or fd.ucontents)
        canann = bool(fd.contents) and type(self._ctx.rev()) is int

        if not candiff or not canfile:
            self.restrictModes(candiff, canfile, canann)
        else:
            self.actionDiffMode.setEnabled(True)
            self.actionFileMode.setEnabled(True)
            self.actionAnnMode.setEnabled(True)
            if self._lostMode:
                self._mode = self._lostMode
                if self._lostMode == DiffMode:
                    self.actionDiffMode.trigger()
                elif self._lostMode == FileMode:
                    self.actionFileMode.trigger()
                elif self._lostMode == AnnMode:
                    self.actionAnnMode.trigger()
                self._lostMode = None
                self.blk.setVisible(self._mode != DiffMode)
                self.sci.setAnnotationEnabled(self._mode == AnnMode)

        if self._mode == DiffMode:
            self.sci.setMarginWidth(1, 0)
            lexer = lexers.get_diff_lexer(self)
            self.sci.setLexer(lexer)
            if lexer is None:
                self.sci.setFont(qtlib.getfont("fontlog").font())
            # trim first three lines, for example:
            # diff -r f6bfc41af6d7 -r c1b18806486d tortoisehg/hgqt/thgrepo.py
            # --- a/tortoisehg/hgqt/thgrepo.py
            # +++ b/tortoisehg/hgqt/thgrepo.py
            if fd.diff:
                out = fd.diff.split("\n", 3)
                if len(out) == 4:
                    self.sci.setText(hglib.tounicode(out[3]))
                else:
                    # there was an error or rename without diffs
                    self.sci.setText(hglib.tounicode(fd.diff))
        elif fd.ucontents:
            # subrepo summary and perhaps other data
            self.sci.setText(fd.ucontents)
            self.sci.setLexer(None)
            self.sci.setFont(qtlib.getfont("fontlog").font())
            self.sci.setMarginWidth(1, 0)
            self.blk.setVisible(False)
            return
        elif fd.contents:
            lexer = lexers.get_lexer(filename, fd.contents, self)
            self.sci.setLexer(lexer)
            if lexer is None:
                self.sci.setFont(qtlib.getfont("fontlog").font())
            self.sci.setText(hglib.tounicode(fd.contents))
            self.blk.setVisible(True)
            self.sci._updatemarginwidth()
            if self._mode == AnnMode:
                self.sci._updateannotation(self._ctx, filename)
        else:
            return

        # Recover the last cursor/scroll position
        self.sci.setCursorPosition(*lastCursorPosition)
        # Make sure that lastScrollPosition never exceeds the amount of
        # lines on the editor
        lastScrollPosition = min(lastScrollPosition, self.sci.lines() - 1)
        self.sci.verticalScrollBar().setValue(lastScrollPosition)

        self.highlightText(*self._lastSearch)
        uf = hglib.tounicode(filename)
        uc = hglib.tounicode(fd.contents) or ""
        self.fileDisplayed.emit(uf, uc)

        if self._mode != DiffMode:
            self.blk.setVisible(True)
            self.blk.syncPageStep()

        if fd.contents and fd.olddata:
            if self.timer.isActive():
                self.timer.stop()
            self._fd = fd
            self.timer.start()
        self.actionNextDiff.setEnabled(bool(self._diffs))
        self.actionPrevDiff.setEnabled(bool(self._diffs))

        lexer = self.sci.lexer()

        if lexer:
            font = self.sci.lexer().font(0)
        else:
            font = self.sci.font()

        fm = QFontMetrics(font)
        self.maxWidth = fm.maxWidth()
        lines = unicode(self.sci.text()).splitlines()
        if lines:
            # assume that the longest line has the largest width;
            # fm.width() is too slow to apply to each line.
            try:
                longestline = max(lines, key=len)
            except TypeError:  # Python<2.5 has no key support
                longestline = max((len(l), l) for l in lines)[1]
            self.maxWidth += fm.width(longestline)
        self.updateScrollBar()
Esempio n. 3
0
    def setupViews(self):
        self.tableViews = {'left': self.fileHistoryLeft,
                           'right': self.fileHistoryRight}
        # viewers are Scintilla editors
        self.viewers = {}
        # block are diff-block displayers
        self.block = {}
        self.diffblock = blockmatcher.BlockMatch(self.frame)
        lay = QHBoxLayout(self.frame)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)

        try:
            contents = open(self.repo.wjoin(self.filename), "rb").read(1024)
            lexer = lexers.get_lexer(self.filename, contents, self)
        except Exception:
            lexer = None

        for side, idx  in (('left', 0), ('right', 3)):
            sci = Scintilla(self.frame)
            sci.verticalScrollBar().setFocusPolicy(Qt.StrongFocus)
            sci.setFocusProxy(sci.verticalScrollBar())
            sci.verticalScrollBar().installEventFilter(self)

            sci.setContextMenuPolicy(Qt.CustomContextMenu)
            sci.customContextMenuRequested.connect(
                functools.partial(self.fileViewMenuRequest, sci))

            sci.setFrameShape(QFrame.NoFrame)
            sci.setMarginLineNumbers(1, True)
            sci.SendScintilla(sci.SCI_SETSELEOLFILLED, True)

            sci.setLexer(lexer)
            if lexer is None:
                sci.setFont(qtlib.getfont('fontdiff').font())

            sci.setReadOnly(True)
            sci.setUtf8(True)
            lay.addWidget(sci)

            # hide margin 0 (markers)
            sci.SendScintilla(sci.SCI_SETMARGINTYPEN, 0, 0)
            sci.SendScintilla(sci.SCI_SETMARGINWIDTHN, 0, 0)
            # setup margin 1 for line numbers only
            sci.SendScintilla(sci.SCI_SETMARGINTYPEN, 1, 1)
            sci.SendScintilla(sci.SCI_SETMARGINWIDTHN, 1, 20)
            sci.SendScintilla(sci.SCI_SETMARGINMASKN, 1, 0)

            # define markers for colorize zones of diff
            self.markerplus = sci.markerDefine(QsciScintilla.Background)
            sci.SendScintilla(sci.SCI_MARKERSETBACK, self.markerplus, 0xB0FFA0)
            self.markerminus = sci.markerDefine(QsciScintilla.Background)
            sci.SendScintilla(sci.SCI_MARKERSETBACK, self.markerminus, 0xA0A0FF)
            self.markertriangle = sci.markerDefine(QsciScintilla.Background)
            sci.SendScintilla(sci.SCI_MARKERSETBACK, self.markertriangle, 0xFFA0A0)

            self.viewers[side] = sci
            blk = blockmatcher.BlockList(self.frame)
            blk.linkScrollBar(sci.verticalScrollBar())
            self.diffblock.linkScrollBar(sci.verticalScrollBar(), side)
            lay.insertWidget(idx, blk)
            self.block[side] = blk
        lay.insertWidget(2, self.diffblock)

        for side in sides:
            table = getattr(self, 'tableView_revisions_%s' % side)
            table.setTabKeyNavigation(False)
            #table.installEventFilter(self)
            table.revisionSelected.connect(self.onRevisionSelected)
            table.revisionActivated.connect(self.onRevisionActivated)

            self.viewers[side].verticalScrollBar().valueChanged.connect(
                    lambda value, side=side: self.sbar_changed(value, side, 'vertical'))
            self.viewers[side].horizontalScrollBar().valueChanged.connect(
                    lambda value, side=side: self.sbar_changed(value, side, 'horizontal'))

        self.setTabOrder(table, self.viewers['left'])
        self.setTabOrder(self.viewers['left'], self.viewers['right'])

        # timer used to fill viewers with diff block markers during GUI idle time
        self.timer = QTimer()
        self.timer.setSingleShot(False)
        self.timer.timeout.connect(self.idle_fill_files)
Esempio n. 4
0
    def displayFile(self, filename=None, status=None):
        if isinstance(filename, (unicode, QString)):
            filename = hglib.fromunicode(filename)
            status = hglib.fromunicode(status)
        if filename and self._filename == filename:
            # Get the last visible line to restore it after reloading the editor
            lastCursorPosition = self.sci.getCursorPosition()
            lastScrollPosition = self.sci.firstVisibleLine()
        else:
            lastCursorPosition = (0, 0)
            lastScrollPosition = 0
        self._filename, self._status = filename, status

        self.clearMarkup()
        self._diffs = []
        if filename is None:
            self.restrictModes(False, False, False)
            return

        if self._ctx2:
            ctx2 = self._ctx2
        elif self._parent == 0 or len(self._ctx.parents()) == 1:
            ctx2 = self._ctx.p1()
        else:
            ctx2 = self._ctx.p2()
        fd = filedata.FileData(self._ctx, ctx2, filename, status)

        if fd.elabel:
            self.extralabel.setText(fd.elabel)
            self.extralabel.show()
        else:
            self.extralabel.hide()
        self.filenamelabel.setText(fd.flabel)

        if not fd.isValid():
            self.sci.setText(fd.error)
            self.sci.setLexer(None)
            self.sci.setFont(qtlib.getfont('fontlog').font())
            self.sci.setMarginWidth(1, 0)
            self.blk.setVisible(False)
            self.restrictModes(False, False, False)
            return

        candiff = bool(fd.diff)
        canfile = bool(fd.contents or fd.ucontents)
        canann = bool(fd.contents) and type(self._ctx.rev()) is int

        if not candiff or not canfile:
            self.restrictModes(candiff, canfile, canann)
        else:
            self.actionDiffMode.setEnabled(True)
            self.actionFileMode.setEnabled(True)
            self.actionAnnMode.setEnabled(True)
            if self._lostMode:
                self._mode = self._lostMode
                if self._lostMode == DiffMode:
                    self.actionDiffMode.trigger()
                elif self._lostMode == FileMode:
                    self.actionFileMode.trigger()
                elif self._lostMode == AnnMode:
                    self.actionAnnMode.trigger()
                self._lostMode = None
                self.blk.setVisible(self._mode != DiffMode)
                self.sci.setAnnotationEnabled(self._mode == AnnMode)

        if self._mode == DiffMode:
            self.sci.setMarginWidth(1, 0)
            lexer = lexers.get_diff_lexer(self)
            self.sci.setLexer(lexer)
            if lexer is None:
                self.sci.setFont(qtlib.getfont('fontlog').font())
            # trim first three lines, for example:
            # diff -r f6bfc41af6d7 -r c1b18806486d tortoisehg/hgqt/thgrepo.py
            # --- a/tortoisehg/hgqt/thgrepo.py
            # +++ b/tortoisehg/hgqt/thgrepo.py
            if fd.diff:
                out = fd.diff.split('\n', 3)
                if len(out) == 4:
                    self.sci.setText(hglib.tounicode(out[3]))
                else:
                    # there was an error or rename without diffs
                    self.sci.setText(hglib.tounicode(fd.diff))
        elif fd.ucontents:
            # subrepo summary and perhaps other data
            self.sci.setText(fd.ucontents)
            self.sci.setLexer(None)
            self.sci.setFont(qtlib.getfont('fontlog').font())
            self.sci.setMarginWidth(1, 0)
            self.blk.setVisible(False)
            return
        elif fd.contents:
            lexer = lexers.get_lexer(filename, fd.contents, self)
            self.sci.setLexer(lexer)
            if lexer is None:
                self.sci.setFont(qtlib.getfont('fontlog').font())
            self.sci.setText(hglib.tounicode(fd.contents))
            self.blk.setVisible(True)
            self.sci._updatemarginwidth()
            if self._mode == AnnMode:
                self.sci._updateannotation(self._ctx, filename)
        else:
            return

        # Recover the last cursor/scroll position
        self.sci.setCursorPosition(*lastCursorPosition)
        # Make sure that lastScrollPosition never exceeds the amount of
        # lines on the editor
        lastScrollPosition = min(lastScrollPosition, self.sci.lines() - 1)
        self.sci.verticalScrollBar().setValue(lastScrollPosition)

        self.highlightText(*self._lastSearch)
        uf = hglib.tounicode(filename)
        uc = hglib.tounicode(fd.contents) or ''
        self.fileDisplayed.emit(uf, uc)

        if self._mode != DiffMode:
            self.blk.setVisible(True)
            self.blk.syncPageStep()

        if fd.contents and fd.olddata:
            if self.timer.isActive():
                self.timer.stop()
            self._fd = fd
            self.timer.start()
        self.actionNextDiff.setEnabled(bool(self._diffs))
        self.actionPrevDiff.setEnabled(bool(self._diffs))

        lexer = self.sci.lexer()

        if lexer:
            font = self.sci.lexer().font(0)
        else:
            font = self.sci.font()

        fm = QFontMetrics(font)
        self.maxWidth = fm.maxWidth()
        lines = unicode(self.sci.text()).splitlines()
        if lines:
            # assume that the longest line has the largest width;
            # fm.width() is too slow to apply to each line.
            try:
                longestline = max(lines, key=len)
            except TypeError:  # Python<2.5 has no key support
                longestline = max((len(l), l) for l in lines)[1]
            self.maxWidth += fm.width(longestline)
        self.updateScrollBar()
Esempio n. 5
0
    def __init__(self, path, parent):
        super(RejectsDialog, self).__init__(parent)
        self.setWindowTitle(_('Merge rejected patch chunks into %s') %
                            hglib.tounicode(path))
        self.setWindowFlags(Qt.Window)
        self.path = path

        self.setLayout(QVBoxLayout())
        editor = qscilib.Scintilla()
        editor.setBraceMatching(qsci.SloppyBraceMatch)
        editor.setFolding(qsci.BoxedTreeFoldStyle)
        editor.installEventFilter(qscilib.KeyPressInterceptor(self))
        editor.setContextMenuPolicy(Qt.CustomContextMenu)
        editor.customContextMenuRequested.connect(self.menuRequested)
        self.baseLineColor = editor.markerDefine(qsci.Background, -1)
        editor.setMarkerBackgroundColor(QColor('lightblue'), self.baseLineColor)
        self.layout().addWidget(editor, 3)

        searchbar = qscilib.SearchToolBar(self, hidable=True)
        searchbar.searchRequested.connect(editor.find)
        searchbar.conditionChanged.connect(editor.highlightText)
        searchbar.hide()
        def showsearchbar():
            searchbar.show()
            searchbar.setFocus(Qt.OtherFocusReason)
        qtlib.newshortcutsforstdkey(QKeySequence.Find, self, showsearchbar)
        self.layout().addWidget(searchbar)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(2, 2, 2, 2)
        self.layout().addLayout(hbox, 1)
        self.chunklist = QListWidget(self)
        self.updating = True
        self.chunklist.currentRowChanged.connect(self.showChunk)
        hbox.addWidget(self.chunklist, 1)

        bvbox = QVBoxLayout()
        bvbox.setContentsMargins(2, 2, 2, 2)
        self.resolved = tb = QToolButton()
        tb.setIcon(qtlib.geticon('thg-success'))
        tb.setToolTip(_('Mark this chunk as resolved, goto next unresolved'))
        tb.pressed.connect(self.resolveCurrentChunk)
        self.unresolved = tb = QToolButton()
        tb.setIcon(qtlib.geticon('thg-warning'))
        tb.setToolTip(_('Mark this chunk as unresolved'))
        tb.pressed.connect(self.unresolveCurrentChunk)
        bvbox.addStretch(1)
        bvbox.addWidget(self.resolved, 0)
        bvbox.addWidget(self.unresolved, 0)
        bvbox.addStretch(1)
        hbox.addLayout(bvbox, 0)

        self.editor = editor
        self.rejectbrowser = RejectBrowser(self)
        hbox.addWidget(self.rejectbrowser, 5)

        BB = QDialogButtonBox
        bb = QDialogButtonBox(BB.Save|BB.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.layout().addWidget(bb)
        self.saveButton = bb.button(BB.Save)

        s = QSettings()
        self.restoreGeometry(s.value('rejects/geometry').toByteArray())
        self.editor.loadSettings(s, 'rejects/editor')
        self.rejectbrowser.loadSettings(s, 'rejects/rejbrowse')

        f = QFile(path)
        if not f.open(QIODevice.ReadOnly):
            qtlib.ErrorMsgBox(_('Unable to merge rejects'),
                              _("Can't read this file (maybe deleted)"))
            self.hide()
            QTimer.singleShot(0, self.reject)
            return
        earlybytes = f.readData(4096)
        if '\0' in earlybytes:
            qtlib.ErrorMsgBox(_('Unable to merge rejects'),
                              _('This appears to be a binary file'))
            self.hide()
            QTimer.singleShot(0, self.reject)
            return

        f.seek(0)
        editor.read(f)
        editor.setModified(False)
        lexer = lexers.get_lexer(path, earlybytes, self)
        editor.setLexer(lexer)
        editor.setMarginLineNumbers(1, True)
        editor.setMarginWidth(1, str(editor.lines())+'X')

        buf = cStringIO.StringIO()
        try:
            buf.write('diff -r aaaaaaaaaaaa -r bbbbbbbbbbb %s\n' % path)
            buf.write(open(path + '.rej', 'rb').read())
            buf.seek(0)
        except IOError, e:
            pass
Esempio n. 6
0
    def __init__(self, path, parent):
        super(RejectsDialog, self).__init__(parent)
        self.setWindowTitle(_("Merge rejected patch chunks into %s") % hglib.tounicode(path))
        self.setWindowFlags(Qt.Window)
        self.path = path

        self.setLayout(QVBoxLayout())
        editor = qscilib.Scintilla()
        editor.setBraceMatching(qsci.SloppyBraceMatch)
        editor.setFolding(qsci.BoxedTreeFoldStyle)
        editor.installEventFilter(qscilib.KeyPressInterceptor(self))
        editor.setContextMenuPolicy(Qt.CustomContextMenu)
        editor.customContextMenuRequested.connect(self.menuRequested)
        self.baseLineColor = editor.markerDefine(qsci.Background, -1)
        editor.setMarkerBackgroundColor(QColor("lightblue"), self.baseLineColor)
        self.layout().addWidget(editor, 3)

        searchbar = qscilib.SearchToolBar(self, hidable=True)
        searchbar.searchRequested.connect(editor.find)
        searchbar.conditionChanged.connect(editor.highlightText)
        searchbar.hide()

        def showsearchbar():
            searchbar.show()
            searchbar.setFocus(Qt.OtherFocusReason)

        qtlib.newshortcutsforstdkey(QKeySequence.Find, self, showsearchbar)
        self.layout().addWidget(searchbar)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(2, 2, 2, 2)
        self.layout().addLayout(hbox, 1)
        self.chunklist = QListWidget(self)
        self.updating = True
        self.chunklist.currentRowChanged.connect(self.showChunk)
        hbox.addWidget(self.chunklist, 1)

        bvbox = QVBoxLayout()
        bvbox.setContentsMargins(2, 2, 2, 2)
        self.resolved = tb = QToolButton()
        tb.setIcon(qtlib.geticon("thg-success"))
        tb.setToolTip(_("Mark this chunk as resolved, goto next unresolved"))
        tb.pressed.connect(self.resolveCurrentChunk)
        self.unresolved = tb = QToolButton()
        tb.setIcon(qtlib.geticon("thg-warning"))
        tb.setToolTip(_("Mark this chunk as unresolved"))
        tb.pressed.connect(self.unresolveCurrentChunk)
        bvbox.addStretch(1)
        bvbox.addWidget(self.resolved, 0)
        bvbox.addWidget(self.unresolved, 0)
        bvbox.addStretch(1)
        hbox.addLayout(bvbox, 0)

        self.editor = editor
        self.rejectbrowser = RejectBrowser(self)
        hbox.addWidget(self.rejectbrowser, 5)

        BB = QDialogButtonBox
        bb = QDialogButtonBox(BB.Save | BB.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.layout().addWidget(bb)
        self.saveButton = bb.button(BB.Save)

        s = QSettings()
        self.restoreGeometry(s.value("rejects/geometry").toByteArray())
        self.editor.loadSettings(s, "rejects/editor")
        self.rejectbrowser.loadSettings(s, "rejects/rejbrowse")

        f = QFile(path)
        if not f.open(QIODevice.ReadOnly):
            qtlib.ErrorMsgBox(_("Unable to merge rejects"), _("Can't read this file (maybe deleted)"))
            self.hide()
            QTimer.singleShot(0, self.reject)
            return
        earlybytes = f.readData(4096)
        if "\0" in earlybytes:
            qtlib.ErrorMsgBox(_("Unable to merge rejects"), _("This appears to be a binary file"))
            self.hide()
            QTimer.singleShot(0, self.reject)
            return

        f.seek(0)
        editor.read(f)
        editor.setModified(False)
        lexer = lexers.get_lexer(path, earlybytes, self)
        editor.setLexer(lexer)
        editor.setMarginLineNumbers(1, True)
        editor.setMarginWidth(1, str(editor.lines()) + "X")

        buf = cStringIO.StringIO()
        try:
            buf.write("diff -r aaaaaaaaaaaa -r bbbbbbbbbbb %s\n" % path)
            buf.write(open(path + ".rej", "rb").read())
            buf.seek(0)
        except IOError, e:
            pass