Changeset 1260

Show
Ignore:
Timestamp:
04/16/08 17:24:18 (7 months ago)
Author:
rob
Message:

Refs #425: attemped to find start and end of multi-byte sequence before replacing the value. Still doesn't work for all cases

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/peppy/plugins/hexedit_mode.py

    r1259 r1260  
    377377            val=int(value,16) 
    378378            if val>=0 and val<256: 
    379                 c=chr(val) 
    380                 loc = self.getLoc(row,col) 
    381                 self.stc.SetSelection(loc,loc+1) 
    382                 self.stc.ReplaceSelection('') 
    383                 self.stc.AddStyledText(c+'\0') 
     379                bytes = chr(val) 
    384380            else: 
    385381                assert self.dprint('SetValue(%d, %d, "%s")=%d out of range.' % (row, col, value,val)) 
     
    387383            textcol = self.getTextCol(col) 
    388384            fmt = self.types[textcol] 
    389             assert self.dprint('SetValue(%d, %d, "%s") packing with fmt %s.' % (row, col, value, fmt)) 
     385            assert self.dprint('SetValue(%d, %d, %s (%s)) packing with fmt %s.' % (row, col, value, repr(value), fmt)) 
     386            fmt_char = fmt[-1] 
     387            if fmt_char == 'f' or fmt_char == 'd': 
     388                value = float(value) 
     389            elif fmt_char in ['bBhHiIlLqQ']: 
     390                value = int(value) 
     391            else: 
     392                value = str(value) 
    390393            bytes = struct.pack(fmt, value) 
    391394            assert self.dprint('bytes = %s' % repr(bytes)) 
    392             loc=self.getLoc(row,col) 
    393             self.stc.SetSelection(loc,loc+1) 
    394             self.stc.ReplaceSelection('') 
    395             styled='\0'.join(bytes)+'\0' 
    396             self.stc.AddStyledText(styled) 
     395             
     396        loc = self.getLoc(row, col) 
     397        locend = loc + len(bytes) 
     398         
     399        # FIXME: the set/replace selection can fail if we start or end in the 
     400        # middle of a multi-byte sequence.  To properly handle this, we'd 
     401        # have to search backwards and forwards to make sure that we aren't 
     402        # splitting a UTF-8 sequence 
     403        start = loc 
     404        valid = False 
     405        while not valid: 
     406            try: 
     407                self.stc.GotoPos(start) 
     408                valid = True 
     409            except wx._core.PyAssertionError: 
     410                self.dprint("Trying back one... start=%d" % start) 
     411                if start > 0: 
     412                    start -= 1 
     413        if start > 0: 
     414            self.stc.CmdKeyExecute(wx.stc.STC_CMD_CHARLEFTEXTEND) 
     415        start = self.stc.GetSelectionStart() 
     416        end = locend 
     417        valid = False 
     418        while not valid: 
     419            try: 
     420                self.stc.GotoPos(end) 
     421                valid = True 
     422            except wx._core.PyAssertionError: 
     423                self.dprint("Trying ahead one... end=%d" % end) 
     424                if end < self.stc.GetLength(): 
     425                    end += 1 
     426        self.stc.CmdKeyExecute(wx.stc.STC_CMD_CHARRIGHTEXTEND) 
     427        end = self.stc.GetSelectionEnd() 
     428        data = self.stc.GetStyledText(start, end) 
     429        self.stc.SetSelection(start, end) 
     430        self.stc.ReplaceSelection('') 
     431         
     432        styled = '\0'.join(bytes) + '\0' 
     433        gap1 = loc - start 
     434        gap2 = gap1 + locend - loc 
     435        replacement = data[:gap1 * 2] + styled + data[gap2 * 2:] 
     436        self.dprint("start=%d loc=%d locend=%d end=%d  data=%s styled=%s replace=%s" % (start, loc, locend, end, repr(data), repr(styled), repr(replacement))) 
     437        self.stc.AddStyledText(replacement) 
     438         
    397439        self.invalidateCacheRow(row) 
    398440