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(hglib.tounicode(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.read(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.getlexer(ui.ui(), 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
def setupViews(self): self.tableViews = {'left': self.tableView_revisions_left, 'right': self.tableView_revisions_right} # 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.getlexer(self.repo.ui, 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(self.fileViewMenuRequest) 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) l, r = (self.viewers[k].verticalScrollBar() for k in sides) l.valueChanged.connect(self.sbar_changed_left) r.valueChanged.connect(self.sbar_changed_right) l, r = (self.viewers[k].horizontalScrollBar() for k in sides) l.valueChanged.connect(r.setValue) r.valueChanged.connect(l.setValue) 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)
def setupViews(self): # 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.getlexer(self.repo.ui, self.filename, contents, self) except Exception: lexer = None for side, idx in (('left', 0), ('right', 3)): sci = _FileDiffScintilla(self.frame) sci.installEventFilter(self) sci.verticalScrollBar().setFocusPolicy(Qt.StrongFocus) sci.setFocusProxy(sci.verticalScrollBar()) sci.verticalScrollBar().installEventFilter(self) 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.setMarkerBackgroundColor(_colormap['+'], self.markerplus) self.markerminus = sci.markerDefine(QsciScintilla.Background) sci.setMarkerBackgroundColor(_colormap['-'], self.markerminus) self.markertriangle = sci.markerDefine(QsciScintilla.Background) sci.setMarkerBackgroundColor(_colormap['x'], self.markertriangle) self.markerplusline = sci.markerDefine(QsciScintilla.Invisible, _MARKERPLUSLINE) self.markerminusline = sci.markerDefine(QsciScintilla.Invisible, _MARKERMINUSLINE) self.markerplusunderline = sci.markerDefine(QsciScintilla.Invisible, _MARKERPLUSUNDERLINE) self.markerminusunderline = sci.markerDefine(QsciScintilla.Invisible, _MARKERMINUSUNDERLINE) 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 table in self._repoViews: table.setTabKeyNavigation(False) table.installEventFilter(self) table.columnsVisibilityChanged.connect(self._syncColumnsVisibility) table.revisionSelected.connect(self.onRevisionSelected) table.revisionActivated.connect(self.onRevisionActivated) l, r = (self.viewers[k].verticalScrollBar() for k in sides) l.valueChanged.connect(self.sbar_changed_left) r.valueChanged.connect(self.sbar_changed_right) l, r = (self.viewers[k].horizontalScrollBar() for k in sides) l.valueChanged.connect(r.setValue) r.valueChanged.connect(l.setValue) self.setTabOrder(table, self.viewers['left']) self.setTabOrder(self.viewers['left'], self.viewers['right']) # timer used to merge requests of syncPageStep on ResizeEvent self._delayedSyncPageStep = QTimer(self, interval=0, singleShot=True) self._delayedSyncPageStep.timeout.connect(self.diffblock.syncPageStep) # 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)
def __init__(self, ui, path, parent=None): 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._onMenuRequested) self.baseLineColor = editor.markerDefine(qsci.Background, -1) editor.setMarkerBackgroundColor(QColor('lightblue'), self.baseLineColor) self.layout().addWidget(editor, 3) searchbar = qscilib.SearchToolBar(self) 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.addActions(searchbar.editorActions()) 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) self.textencgroup = fileencoding.createActionGroup(self) self.textencgroup.triggered.connect(self._reloadFile) fileencoding.checkActionByName(self.textencgroup, fileencoding.contentencoding(ui)) 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') if not qscilib.readFile(editor, hglib.tounicode(path), self._textEncoding()): self.hide() QTimer.singleShot(0, self.reject) return earlybytes = hglib.fromunicode(editor.text(), 'replace')[:4096] lexer = lexers.getlexer(ui, path, earlybytes, self) editor.setLexer(lexer) if lexer is None: editor.setFont(qtlib.getfont('fontlog').font()) 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
def displayFile(self, filename=None, status=None, force=False): 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, self.changeselection, force=force) if fd.elabel: self.extralabel.setText(fd.elabel) self.extralabel.show() else: self.extralabel.hide() self.filenamelabel.setText(fd.flabel) uf = hglib.tounicode(filename) 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) self.newChunkList.emit(uf, None) forcedisplaymsg = filedata.forcedisplaymsg linkstart = fd.error.find(forcedisplaymsg) if linkstart >= 0: # add the link to force to view the data anyway self._setupForceViewIndicator() self.sci.fillIndicatorRange( 0, linkstart, 0, linkstart+len(forcedisplaymsg), self._forceviewindicator) 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.difflexer(self) self.sci.setLexer(lexer) if lexer is None: self.sci.setFont(qtlib.getfont('fontlog').font()) if fd.changes: self._showChangeSelectMargin(True) self.changes = fd.changes self.sci.setText(hglib.tounicode(fd.diff)) for chunk in self.changes.hunks: self.chunkatline[chunk.lineno] = chunk self.sci.markerAdd(chunk.lineno, self.inclmarker) elif fd.diff: # trim first three lines, for example: # diff -r f6bfc41af6d7 -r c1b18806486d tortoisehg/hgqt/mq.py # --- a/tortoisehg/hgqt/mq.py # +++ b/tortoisehg/hgqt/mq.py 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)) self.newChunkList.emit(uf, fd.changes) 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) self.newChunkList.emit(uf, None) return elif fd.contents: lexer = lexers.getlexer(self.repo.ui, 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) self.newChunkList.emit(uf, None) else: self.newChunkList.emit(uf, None) 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) uc = hglib.tounicode(fd.contents) or '' self.fileDisplayed.emit(uf, uc) if self._mode != DiffMode: self.blk.setVisible(True) self.blk.syncPageStep() self.blksearch.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()