1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#-----------------------------------------------------------------------------
# Name: DiffView.py
# Purpose:
#
# Author: Riaan Booysen
#
# Created: 2000/17/07
# RCS-ID: $Id: DiffView.py,v 1.13 2004/08/16 13:07:09 riaan Exp $
# Copyright: (c) 2000 - 2004 Riaan Booysen
# Licence: GPL
#-----------------------------------------------------------------------------
import sys, linecache, traceback, shutil
from cStringIO import StringIO
from wxPython import wx
from wxPython.stc import *
from ExternalLib import ndiff
from EditorViews import EditorView, CloseableViewMix
from StyledTextCtrls import PythonStyledTextCtrlMix
import Preferences, Utils
uniqueFile1Mrk = 1
uniqueFile2Mrk = 2
newToBothMrk = 3
maskMarkSet = 1 << uniqueFile1Mrk | 1 << uniqueFile2Mrk | 1 << newToBothMrk
def ndiff_lcompare(a, b):
""" Copy of ndiff.fcompare, works on lines instread of files """
cruncher = ndiff.SequenceMatcher(ndiff.IS_LINE_JUNK, a, b)
for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
if tag == 'replace':
ndiff.fancy_replace(a, alo, ahi, b, blo, bhi)
elif tag == 'delete':
ndiff.dump('-', a, alo, ahi)
elif tag == 'insert':
ndiff.dump('+', b, blo, bhi)
elif tag == 'equal':
ndiff.dump(' ', a, alo, ahi)
else:
raise ValueError, 'unknown tag ' + `tag`
return 1
class DiffPSOut(Utils.PseudoFile):
def write(self, s):
## cp = self.output.GetCurrentPos()
## cl = self.output.GetLineFromPos(cp)
## mrk = self.output.MarkerGet(cl)
if s not in ('+', '-', ' ', '?'):
self.output.AddText(s)
elif s[0] == '+':
self.output.MarkerAdd(self.output.GetLineCount()-1, uniqueFile2Mrk)
elif s[0] == '-':
self.output.MarkerAdd(self.output.GetLineCount()-1, uniqueFile1Mrk)
elif s[0] == '?':
self.output.MarkerAdd(self.output.GetLineCount()-1, newToBothMrk)
class DiffView(EditorView):
def genCustomPage(self, page):
return self.report
class PythonSourceDiffView(wxStyledTextCtrl, EditorView, PythonStyledTextCtrlMix, CloseableViewMix):
viewName = 'Diff'
refreshBmp = 'Images/Editor/Refresh.png'
prevBmp = 'Images/Shared/Previous.png'
nextBmp = 'Images/Shared/Next.png'
def __init__(self, parent, model):
wxID_PYTHONSOURCEDIFFVIEW = wxNewId()
wxStyledTextCtrl.__init__(self, parent, wxID_PYTHONSOURCEDIFFVIEW,
style = wx.wxCLIP_CHILDREN | wx.wxSUNKEN_BORDER)
PythonStyledTextCtrlMix.__init__(self, wxID_PYTHONSOURCEDIFFVIEW, 0)
CloseableViewMix.__init__(self, 'diffs')
EditorView.__init__(self, model,
( ('Refresh', self.OnRefresh, self.refreshBmp, 'Refresh'), ) +
self.closingActionItems +
( ('-', None, '', ''),
('Previous difference', self.OnPrev, self.prevBmp, ''),
('Next difference', self.OnNext, self.nextBmp, ''),
('Apply all changes', self.OnApplyAllChanges, '-', '') ), -1)
self.SetMarginType(1, wxSTC_MARGIN_SYMBOL)
self.SetMarginWidth(1, 16)
markIdnt, markBorder, markCenter = Preferences.STCDiffRemovedMarker
self.MarkerDefine(uniqueFile1Mrk, markIdnt, markBorder, markCenter)
markIdnt, markBorder, markCenter = Preferences.STCDiffAddedMarker
self.MarkerDefine(uniqueFile2Mrk, markIdnt, markBorder, markCenter)
markIdnt, markBorder, markCenter = Preferences.STCDiffChangesMarker
self.MarkerDefine(newToBothMrk, markIdnt, markBorder, markCenter)
self.SetMarginSensitive(1, wx.true)
EVT_STC_MARGINCLICK(self, wxID_PYTHONSOURCEDIFFVIEW, self.OnMarginClick)
self.tabName = 'Diff'
self.diffWith = ''
self.currSearchLine = 1
## Install the handler for refreshs.
if wx.wxPlatform == '__WXGTK__' and Preferences.edUseCustomSTCPaintEvtHandler:
self.paint_handler = Utils.PaintEventHandler(self)
self.active = wx.true
self.lineIndex = []
def refreshCtrl(self):
from Explorers.Explorer import openEx
self.SetReadOnly(wx.false)
self.ClearAll()
if self.diffWith:
saveout = sys.stdout
try:
sys.stdout = DiffPSOut(self)
try:
src = StringIO(self.model.data).readlines()
# XXX could sometimes use data from file open in IDE ???
dst = StringIO(openEx(self.diffWith).load('rb')).readlines()
# self.model.editor.app.saveStdio = sys.stdout, sys.stderr
ndiff_lcompare(src, dst)
except:
(sys.last_type, sys.last_value,
sys.last_traceback) = sys.exc_info()
linecache.checkcache()
traceback.print_exc()
finally:
sys.stdout = saveout
self.SetReadOnly(wx.true)
def gotoLine(self, lineno, offset = -1):
self.GotoLine(lineno)
vl = self.GetFirstVisibleLine()
self.LineScroll(0, lineno - vl)
if offset != -1: self.SetCurrentPos(self.GetCurrentPos()+offset+1)
def OnUpdateUI(self, event):
if Preferences.braceHighLight:
PythonStyledTextCtrlMix.OnUpdateUI(self, event)
def OnRefresh(self, event):
self.refreshModel()
def OnMarginClick(self, event):
if event.GetMargin() == 1:
ln = self.LineFromPosition(event.GetPosition())
def OnPrev(self, event):
self.currSearchLine = self.MarkerPrevious(self.currSearchLine,
maskMarkSet) - 1
self.gotoLine(self.currSearchLine + 1)
def OnNext(self, event):
self.currSearchLine = self.MarkerNext(self.currSearchLine,
maskMarkSet) + 1
self.gotoLine(self.currSearchLine - 1)
def OnApplyAllChanges(self, event):
filename = self.model.assertLocalFile()
if self.diffWith and Utils.yesNoDialog(self, 'Are you sure?',
'Replace %s with %s?'% (filename, self.diffWith)):
shutil.copyfile(self.diffWith, filename)
# reload
self.model.load()
self.deleteFromNotebook('Source', self.tabName)
|