StyledTextCtrls.py :  » IDE » Boa-Constructor » boa-constructor-0.6.1 » Views » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » Boa Constructor 
Boa Constructor » boa constructor 0.6.1 » Views » StyledTextCtrls.py
#-----------------------------------------------------------------------------
# Name:        StyledTextCtrls.py
# Purpose:     Mixin classes to extend wx.stc.StyledTextCtrl
#
# Author:      Riaan Booysen
#
# Created:     2000/04/26
# RCS-ID:      $Id: StyledTextCtrls.py,v 1.39 2007/07/02 15:01:16 riaan Exp $
# Copyright:   (c) 1999 - 2007 Riaan Booysen
# Licence:     GPL
#-----------------------------------------------------------------------------

import os, re, keyword, string

import wx
import wx.stc

eols = {  wx.stc.STC_EOL_CRLF : '\r\n',
          wx.stc.STC_EOL_CR   : '\r',
          wx.stc.STC_EOL_LF   : '\n'}

import Preferences
from Utils import _

import methodparse
import STCStyleEditor

# from PythonWin from IDLE :)
_is_block_opener = re.compile(r':\s*(#.*)?$').search
_is_block_closer = re.compile(r'''
    \s*
    ( return
    | break
    | continue
    | raise
    | pass
    )
    \b
''', re.VERBOSE).match


def ver_tot(ma, mi, re):
    return ma*10000+mi*100+re

word_delim  = string.letters + string.digits + '_'
object_delim = word_delim + '.'

#---Utility mixins--------------------------------------------------------------

class FoldingStyledTextCtrlMix:
    def __init__(self, wId, margin):
        self.__fold_margin = margin
        if Preferences.edSTCFolding:
            self.SetProperty('fold', '1')
        self.SetMarginType(margin, wx.stc.STC_MARGIN_SYMBOL)
        self.SetMarginMask(margin, wx.stc.STC_MASK_FOLDERS)
        self.SetMarginSensitive(margin, True)
        self.SetMarginWidth(margin, Preferences.STCFoldingMarginWidth)

        markIdnt, markBorder, markCenter = Preferences.STCFoldingClose
        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, 
              markIdnt, markBorder, markCenter)
        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, 
              wx.stc.STC_MARK_EMPTY, markBorder, markCenter)

        markIdnt, markBorder, markCenter = Preferences.STCFoldingOpen
        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, 
              markIdnt, markBorder, markCenter)
        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, 
              wx.stc.STC_MARK_EMPTY, markBorder, markCenter)

        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, 
              wx.stc.STC_MARK_BACKGROUND, "white", "black")
        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB, 
              wx.stc.STC_MARK_BACKGROUND, "white", "black")
        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL, 
              wx.stc.STC_MARK_BACKGROUND, "white", "black")

    def OnMarginClick(self, evt):
        # fold and unfold as needed
        if evt.GetMargin() == self.__fold_margin:
            if evt.GetShift() and evt.GetControl():
                self.FoldAll()
            else:
                lineClicked = self.LineFromPosition(evt.GetPosition())
                if self.GetFoldLevel(lineClicked) & wx.stc.STC_FOLDLEVELHEADERFLAG:
                    if evt.GetShift():
                        self.SetFoldExpanded(lineClicked, True)
                        self.Expand(lineClicked, True, True, 1)
                    elif evt.GetControl():
                        if self.GetFoldExpanded(lineClicked):
                            self.SetFoldExpanded(lineClicked, False)
                            self.Expand(lineClicked, False, True, 0)
                        else:
                            self.SetFoldExpanded(lineClicked, True)
                            self.Expand(lineClicked, True, True, 100)
                    else:
                        self.ToggleFold(lineClicked)


    def FoldAll(self, expanding=None):
        lineCount = self.GetLineCount()

        if expanding is None:
            expanding = True
    
            # find out if we are folding or unfolding
            for lineNum in range(lineCount):
                if self.GetFoldLevel(lineNum) & wx.stc.STC_FOLDLEVELHEADERFLAG:
                    expanding = not self.GetFoldExpanded(lineNum)
                    break

        lineNum = 0
        while lineNum < lineCount:
            level = self.GetFoldLevel(lineNum)
            if level & wx.stc.STC_FOLDLEVELHEADERFLAG and \
               (level & wx.stc.STC_FOLDLEVELNUMBERMASK) == wx.stc.STC_FOLDLEVELBASE:

                if expanding:
                    self.SetFoldExpanded(lineNum, True)
                    lineNum = self.Expand(lineNum, True)
                    lineNum = lineNum - 1
                else:
                    lastChild = self.GetLastChild(lineNum, -1)
                    self.SetFoldExpanded(lineNum, False)
                    if lastChild > lineNum:
                        self.HideLines(lineNum+1, lastChild)

            lineNum = lineNum + 1

    def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
        lastChild = self.GetLastChild(line, level)
        line = line + 1
        while line <= lastChild:
            if force:
                if visLevels > 0:
                    self.ShowLines(line, line)
                else:
                    self.HideLines(line, line)
            else:
                if doExpand:
                    self.ShowLines(line, line)

            if level == -1:
                level = self.GetFoldLevel(line)

            if level & wx.stc.STC_FOLDLEVELHEADERFLAG:
                if force:
                    if visLevels > 1:
                        self.SetFoldExpanded(line, True)
                    else:
                        self.SetFoldExpanded(line, False)
                    line = self.Expand(line, doExpand, force, visLevels-1)

                else:
                    if doExpand and self.GetFoldExpanded(line):
                        line = self.Expand(line, True, force, visLevels-1)
                    else:
                        line = self.Expand(line, False, force, visLevels-1)
            else:
                line = line + 1;

        return line

def idWord(line, piv, lineStart, leftDelim=word_delim, rightDelim=word_delim):
    if piv >= len(line):
        return 0, 0
    pivL = pivR = piv
    # Look left
    for pivL in range(piv, -1, -1):
        if not line[pivL] in leftDelim:
            pivL = pivL + 1
            break
    # Look right
    for pivR in range(piv + 1, len(line)):
        if not line[pivR] in rightDelim:
            break
    else:
        pivR = pivR+1

    return pivL + lineStart, pivR - pivL

class BrowseStyledTextCtrlMix:
    """ This class is to be mix-in with a wxStyledTextCtrl to add
        functionality for browsing the code.
    """
    def __init__(self, indicator=0):
        self.handCrs = 1
        self.stndCrs = 0

        self.IndicatorSetStyle(indicator, wx.stc.STC_INDIC_PLAIN)
        self.IndicatorSetForeground(indicator, wx.BLUE)
        self._indicator = indicator
        self.styleStart = 0
        self.styleLength = 0
        self.ctrlDown = False
        self.Bind(wx.EVT_MOTION, self.OnBrowseMotion)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnBrowseClick)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)

    def doClearBrwsLn(self):
        self.styleStart, self.styleLength = \
            self.clearUnderline(self.styleStart, self.styleLength)

    def BrowseClick(self, word, line, lineNo, start, style):
        """Called when a link is clicked.
           Override to use, return True if click is swallowed """
        return False

    def StyleVeto(self, style):
        return False

    # XXX Setting the cursor irrevocably changes the cursor for the whole STC
    def underlineWord(self, start, length):
        #self.SetCursor(self.handCrs)
        self.SetLexer(wx.stc.STC_LEX_NULL)

        self.StartStyling(start, wx.stc.STC_INDICS_MASK)
        self.SetStyling(length, wx.stc.STC_INDIC0_MASK)
        return start, length

    def clearUnderline(self, start, length):
        #self.SetCursor(self.stndCrs)

        self.StartStyling(start, wx.stc.STC_INDICS_MASK)
        self.SetStyling(length, 0)
        self.SetLexer(wx.stc.STC_LEX_PYTHON)
        self.Refresh(False)
        return 0, 0

    def getBrowsableText(self, line, piv, lnStPs):
        return idWord(line, piv, lnStPs)

    def OnBrowseMotion(self, event):
        event.Skip()
        #check if words should be underlined
        if event.ControlDown():
            mp = event.GetPosition()
            pos = self.PositionFromPoint(wx.Point(mp.x, mp.y))

            stl = self.GetStyleAt(pos) & 31

            if self.StyleVeto(stl):
                if self.styleLength > 0:
                    self.styleStart, self.styleLength = \
                      self.clearUnderline(self.styleStart, self.styleLength)
                return

            lnNo = self.LineFromPosition(pos)
            lnStPs = self.PositionFromLine(lnNo)
            line = self.GetLine(lnNo)
            piv = pos - lnStPs
            start, length = self.getBrowsableText(line, piv, lnStPs)
            #mark new
            if length > 0 and self.styleStart != start:
                if self.styleLength > 0:
                    self.clearUnderline(self.styleStart, self.styleLength)
                self.styleStart,self.styleLength = \
                  self.underlineWord(start, length)
            #keep current
            elif self.styleStart == start: pass
            #delete previous
            elif self.styleLength > 0:
                self.styleStart, self.styleLength = \
                  self.clearUnderline(self.styleStart, self.styleLength)

        #clear any underlined words
        elif self.styleLength > 0:
            self.styleStart, self.styleLength = \
              self.clearUnderline(self.styleStart, self.styleLength)

    def getStyledWordElems(self, styleStart, styleLength):
        if styleLength > 0:
            lnNo = self.LineFromPosition(styleStart)
            lnStPs = self.PositionFromLine(lnNo)
            line = self.GetLine(lnNo)
            start = styleStart - lnStPs
            word = line[start:start+styleLength]
            return word, line, lnNo, start
        else:
            return '', 0, 0, 0

    def OnBrowseClick(self, event):
        word, line, lnNo, start = self.getStyledWordElems(self.styleStart, self.styleLength)
        if word:
            style = self.GetStyleAt(self.styleStart) & 31
            if self.BrowseClick(word, line, lnNo, start, style):
                return
        event.Skip()

    def OnKeyDown(self, event):
        if event.ControlDown(): self.ctrlDown = True
        event.Skip()

    def OnKeyUp(self, event):
        if self.ctrlDown and (not event.ControlDown()):
            self.ctrlDown = False
            if self.styleLength > 0:
                self.styleStart, self.styleLength = \
                  self.clearUnderline(self.styleStart, self.styleLength)
        event.Skip()

class CodeHelpStyledTextCtrlMix:
    def getCurrLineInfo(self):
        pos = self.GetCurrentPos()
        lnNo = self.GetCurrentLine()
        lnStPs = self.PositionFromLine(lnNo)
        return (pos, lnNo, lnStPs,
                self.GetCurLine()[0], pos - lnStPs - 1)

    def getFirstContinousBlock(self, docs):
        docs = docs.strip()
        res = []
        for line in docs.split('\n'):
            if line.strip():
                res.append(line)
            else:
                break
        return '\n'.join(res)


class AutoCompleteCodeHelpSTCMix(CodeHelpStyledTextCtrlMix):
    """ Mixin that assists with code completion

        Users should implement:
        def getCodeCompOptions(self, word, rootWord, matchWord, lnNo):
            return ['list', 'of', 'options']
    """

    def __init__(self):
        self.AutoCompSetIgnoreCase(True)
        self.AutoCompSetCancelAtStart(False)

    def codeCompCheck(self):
        pos, lnNo, lnStPs, line, piv = self.getCurrLineInfo()

        start, length = idWord(line, piv, lnStPs, object_delim, object_delim)
        startLine = start-lnStPs
        word = line[startLine:startLine+length]
        pivword = piv - startLine

        dot = word.rfind('.', 0, pivword+1)
        matchWord = word
        if dot != -1:
            rdot = word.find('.', pivword)
            if rdot != -1:
                matchWord = word[dot+1:rdot]
            else:
                matchWord = word[dot+1:]

            offset = pivword - dot
            rootWord = word[:dot]
        else:
            offset = pivword + 1
            rootWord = ''

        if not matchWord:
            offset = 0

        names = self.getCodeCompOptions(word, rootWord, matchWord, lnNo)

        # remove duplicates and sort
        unqNms = {}
        for name in names: unqNms[name] = None
        names = unqNms.keys()

        sortnames = [(name.upper(), name) for name in names]
        sortnames.sort()
        names = [n[1] for n in sortnames]

        # move _* names to the end of the list
        cnt = 0
        maxmoves = len(names)
        while cnt < maxmoves:
            if names[0] and names[0][0] == '_':
                names.append(names[0])
                del names[0]
                cnt = cnt + 1
            else:
                break

        if names:
            self.AutoCompShow(offset, ' '.join(names))
        #self.AutoCompSelect(matchWord)

class CallTipCodeHelpSTCMix(CodeHelpStyledTextCtrlMix):
    """ Mixin that assists with code completion

        Users should implement:
            def getTipValue(word, lnNo):
                return 'Tip'
    """
    def __init__(self):
        self.lastCallTip = ''
        self.lastTipHilite = (0, 0)

        self.CallTipSetBackground(Preferences.STCCallTipBackColour)

    def getTipValue(self, word, lnNo):
        return ''

    def callTipCheck(self):
        pos, lnNo, lnStPs, line, piv = self.getCurrLineInfo()

        bracket = methodparse.matchbracket(line[:piv+1], '(')
        if bracket == -1 and self.CallTipActive():
            self.CallTipCancel()
            return

        cursBrktOffset = piv - bracket

        start, length = idWord(line, bracket-1, lnStPs, object_delim, object_delim)
        startLine = start-lnStPs
        word = line[startLine:startLine+length]
        if word:
            tip = self.getTipValue(word, lnNo)
            if tip:
                # Minus offset of 1st bracket in the tip
                tipBrkt = tip.find('(')
                if tipBrkt != -1:
                    pos = pos - tipBrkt - 1
                else:
                    tipBrkt = 0

                # get the current parameter from source
                paramNo = len(methodparse.safesplitfields(\
                      line[bracket+1:piv+1]+'X', ','))
                if paramNo:
                    paramNo = paramNo - 1

                # get hilight & corresponding parameter from tip
                tipBrktEnd = tip.rfind(')')
                tip_param_str = tip[tipBrkt+1:tipBrktEnd]
                tip_params = methodparse.safesplitfields(\
                    tip_param_str, ',', ('(', '{'), (')', '}') )
                try:
                    hiliteStart = tipBrkt+1 + tip_param_str.find(tip_params[paramNo])
                except IndexError:
                    hilite = (0, 0)
                else:
                    hilite = (hiliteStart,
                              hiliteStart+len(tip_params[paramNo]))

                # don't update if active and unchanged
                if self.CallTipActive() and tip == self.lastCallTip and \
                      hilite == self.lastTipHilite:
                    return

                # close if active and changed
                if self.CallTipActive() and (tip != self.lastCallTip or \
                      hilite != self.lastTipHilite):
                    self.CallTipCancel()

                self.CallTipShow(pos - cursBrktOffset, tip)

                self.CallTipSetHighlight(hilite[0], hilite[1])
                self.lastCallTip = tip
                self.lastTipHilite = hilite

class DebuggingViewSTCMix:
    def __init__(self, debugMarkers):

        (self.brkPtMrk, self.tmpBrkPtMrk, self.disabledBrkPtMrk,
         self.stepPosMrk) = debugMarkers

        # XXX properly allocate the marker
        self.stepPosBackMrk = self.stepPosMrk + 1

        # Initialize breakpoints from file and running debugger
        # XXX Remote breakpoints should be stored in a local pickle
        filename = self.model.filename

        from Debugger.Breakpoint import bplist
        self.breaks = bplist.getFileBreakpoints(filename)
        self.tryLoadBreakpoints()

    def setupDebuggingMargin(self, symbolMrg):
        self.SetMarginType(symbolMrg, wx.stc.STC_MARGIN_SYMBOL)
        self.SetMarginWidth(symbolMrg, Preferences.STCSymbolMarginWidth)
        self.SetMarginSensitive(symbolMrg, True)

        markIdnt, markBorder, markCenter = Preferences.STCBreakpointMarker
        self.MarkerDefine(self.brkPtMrk, markIdnt, markBorder, markCenter)

        markIdnt, markBorder, markCenter = Preferences.STCLinePointer
        self.MarkerDefine(self.stepPosMrk, markIdnt, markBorder, markCenter)

        markIdnt, markBorder, markCenter = Preferences.STCTmpBreakpointMarker
        self.MarkerDefine(self.tmpBrkPtMrk, markIdnt, markBorder, markCenter)

        markIdnt, markBorder, markCenter = Preferences.STCDisabledBreakpointMarker
        self.MarkerDefine(self.disabledBrkPtMrk, markIdnt, markBorder, markCenter)

        try:
            wx.stc.STC_MARK_BACKGROUND
        except:
            self.MarkerDefine(self.stepPosBackMrk, wx.stc.STC_MARK_EMPTY,
                              wx.Colour(255, 255, 255), wx.Colour(128, 128, 255))
        else:
            self.MarkerDefine(self.stepPosBackMrk, wx.stc.STC_MARK_BACKGROUND,
                              wx.Colour(255, 255, 255), wx.Colour(220, 220, 255))


    def setInitialBreakpoints(self):
        # Adds markers where the breakpoints are located.
        for mrk in (self.tmpBrkPtMrk, self.disabledBrkPtMrk, self.brkPtMrk):
            self.MarkerDeleteAll(mrk)
        for brk in self.breaks.listBreakpoints():
            self.setBreakMarker(brk)

    def setBreakMarker(self, brk):
        if brk['temporary']: mrk = self.tmpBrkPtMrk
        elif not brk['enabled']: mrk = self.disabledBrkPtMrk
        else: mrk = self.brkPtMrk
        lineno = brk['lineno'] - 1
        currMrk = self.MarkerGet(lineno) & (1 << mrk)
        if currMrk:
            self.MarkerDelete(lineno, mrk)
        self.MarkerAdd(lineno, mrk)

    def deleteBreakMarkers(self, lineNo):
        self.MarkerDelete(lineNo - 1, self.brkPtMrk)
        self.MarkerDelete(lineNo - 1, self.tmpBrkPtMrk)
        self.MarkerDelete(lineNo - 1, self.disabledBrkPtMrk)

    def deleteBreakPoint(self, lineNo):
        self.breaks.deleteBreakpoints(lineNo)
        debugger = self.model.editor.debugger
        if debugger:
            # Try to apply to the running debugger.
            debugger.deleteBreakpoints(self.model.filename, lineNo)
        self.deleteBreakMarkers(lineNo)

    def addBreakPoint(self, lineNo, temp=0, notify_debugger=1):
        filename = self.model.filename

        self.breaks.addBreakpoint(lineNo, temp)
        if notify_debugger:
            debugger = self.model.editor.debugger
            if debugger:
                # Try to apply to the running debugger.
                debugger.setBreakpoint(filename, lineNo, temp)
        if temp: mrk = self.tmpBrkPtMrk
        else: mrk = self.brkPtMrk
        self.MarkerAdd(lineNo - 1, mrk)

    def moveBreakpoint(self, bpt, delta):
        # remove
        index = (bpt.file, bpt.line)

        if index not in bpt.bplist.keys():
            return

        bpt.bplist[index].remove(bpt)
        if not bpt.bplist[index]:
            del bpt.bplist[index]

        del self.breaks[bpt.line]

        bpt.line = bpt.line + delta

        # re-add
        index = (bpt.file, bpt.line)
        if bpt.bplist.has_key(index):
            bpt.bplist[index].append(bpt)
        else:
            bpt.bplist[index] = [bpt]

        self.breaks[bpt.line] = bpt

    def tryLoadBreakpoints(self):
        import pickle
        fn = self.getBreakpointFilename()

        if fn:
            rval = self.breaks.loadBreakpoints(fn)
            if rval:
                self.setInitialBreakpoints()
        else:
            rval = None
        return rval

    def saveBreakpoints(self):
        # XXX This is not yet called automatically on saving a module,
        # should it be ?
        fn = self.getBreakpointFilename()
        if fn:
            self.breaks.saveBreakpoints(fn)

    def clearStepPos(self, lineNo):
        if lineNo < 0:
            lineNo = 0
        self.MarkerDelete(lineNo, self.stepPosMrk)
        self.MarkerDelete(lineNo, self.stepPosBackMrk)

    def setStepPos(self, lineNo):
        if lineNo < 0:
            lineNo = 0
        self.MarkerDeleteAll(self.stepPosMrk)
        self.MarkerAdd(lineNo, self.stepPosMrk)
        self.MarkerDeleteAll(self.stepPosBackMrk)
        self.MarkerAdd(lineNo, self.stepPosBackMrk)

        if self.breaks.hasBreakpoint(lineNo + 1):
            # Be sure all the breakpoints for this file are displayed.
            self.setInitialBreakpoints()
        self.MarkerDelete(lineNo, self.tmpBrkPtMrk)

    def getBreakpointFilename(self):
        try:
            return os.path.splitext(self.model.assertLocalFile())[0]+'.brk'
        except AssertionError:
            return ''

    def adjustBreakpoints(self, linesAdded, modType, evtPos):
        line = self.LineFromPosition(evtPos)#event.GetPosition())

        endline = self.GetLineCount()
        if self.breaks.hasBreakpoint(
              min(line, endline), max(line, endline)):

            changed = self.breaks.adjustBreakpoints(line, linesAdded)
            debugger = self.model.editor.debugger
            if debugger:
                # XXX also check that module has been imported
                # XXX this should apply; with or without breakpoint
                if debugger.running and \
                      not modType & wx.stc.STC_PERFORMED_UNDO:
                    wx.LogWarning(_('Adding or removing lines from the '
                                    'debugger will cause the source and the '
                                    'debugger to be out of sync.'
                                    '\nPlease undo this action.'))

                debugger.adjustBreakpoints(self.model.filename, line,
                      linesAdded)
            else:
                # bdb must still be updated
                import bdb

                bpList = bdb.Breakpoint.bplist
                filename = self.model.filename #canonic form, same as url form I think
                setBreaks = []

                # store reference and remove from (fn, ln) refed dict.
                for bpFile, bpLine in bpList.keys():
                    if bpFile == filename and bpLine > line:
                        setBreaks.append(bpList[bpFile, bpLine])
                        del bpList[bpFile, bpLine]

                # put old break at new place and renumber
                for brks in setBreaks:
                    for brk in brks:
                        brk.line = brk.line + linesAdded
                        # merge in moved breaks
                        if bpList.has_key((filename, brk.line)):
                            bpList[filename, brk.line].append(brk)
                        else:
                            bplist[filename, brk.line] = [brk]

    def OnSaveBreakPoints(self, event):
        self.saveBreakpoints()

    def OnLoadBreakPoints(self, event):
        self.tryLoadBreakpoints()

    def OnSetBreakPoint(self, event):
        line = self.LineFromPosition(self.GetCurrentPos()) + 1
        if self.breaks.hasBreakpoint(line):
            self.deleteBreakPoint(line)
        else:
            self.addBreakPoint(line)

    def OnMarginClick(self, event):
        lineClicked = self.LineFromPosition(event.GetPosition()) + 1
        if self.breaks.hasBreakpoint(lineClicked):
            self.deleteBreakPoint(lineClicked)
        else:
            self.addBreakPoint(lineClicked)


#---Language mixins-------------------------------------------------------------
class LanguageSTCMix:
    def __init__(self, wId, marginNumWidth, language, config):
        self.language = language
        (cfg, self.commonDefs, self.styleIdNames, self.styles, psgn, psg, olsgn,
              olsg, ds, self.lexer, self.keywords, bi) = \
              self.getSTCStyles(config, language)

        #self.SetEOLMode(wx.stc.STC_EOL_LF)
        #self.eol = '\n'
        self.SetBufferedDraw(Preferences.STCBufferedDraw)
        self.SetCaretPeriod(Preferences.STCCaretPeriod)

        self.SetViewWhiteSpace(Preferences.STCViewWhiteSpace)
        self.SetViewEOL(Preferences.STCViewEOL)

        self.SetIndent(Preferences.STCIndent)
        self.SetUseTabs(Preferences.STCUseTabs)
        self.SetTabWidth(Preferences.STCTabWidth)
        self.SetCaretPeriod(Preferences.STCCaretPeriod)
        #if Preferences.STCCaretPolicy:
        #    self.SetCaretPolicy(Preferences.STCCaretPolicy,
        #                        Preferences.STCCaretPolicySlop)

        self.SetEdgeMode(Preferences.STCEdgeMode)
        self.SetEdgeColumn(Preferences.STCEdgeColumnWidth)

        if marginNumWidth:
            self.SetMargins(1, 1)
            self.SetMarginType(marginNumWidth[0], wx.stc.STC_MARGIN_NUMBER)
            self.SetMarginWidth(marginNumWidth[0], marginNumWidth[1])

        self.Bind(wx.stc.EVT_STC_UPDATEUI, self.OnUpdateUI, id=wId)

    def setStyles(self, commonOverride=None):
        commonDefs = {}
        commonDefs.update(self.commonDefs)
        if commonOverride is not None:
            commonDefs.update(commonOverride)

        STCStyleEditor.setSTCStyles(self, self.styles, self.styleIdNames,
              commonDefs, self.language, self.lexer, self.keywords)

    def getSTCStyles(self, config, language):
        """ Override to set values directly """
        return STCStyleEditor.initFromConfig(config, language)


    keymap={'euro': {226: chr(124), 69: chr(128), 81: chr(64), 77: chr(181),
                     48: chr(125), 337: chr(126), 50: chr(178), 51: chr(179),
                     55: chr(123), 56: chr(91), 57: chr(93), 219: chr(92),
                    },
            'swiss-german': {192: chr(93), 226: chr(92), 50: chr(64),
                             51: chr(35), 55: chr(124), 186: chr(91),
                             219: chr(96), 220: chr(123), 221: chr(126),
                             223: chr(125),
                            },
            'italian': {192: chr(64), 337: chr(93), 186: chr(91), 219: chr(123),
                        221: chr(125), 222: chr(35),
                       },
            'france': {226: chr(54), 48: chr(64), 337: chr(125), 50: chr(126),
                       51: chr(35), 52: chr(123), 53: chr(91), 54: chr(124),
                       55: chr(96), 56: chr(92), 219: chr(93),
                      },
           }
    def handleSpecialEuropeanKeys(self, event, countryKeymap='euro'):
        key = event.GetKeyCode()
        keymap = self.keymap[countryKeymap]
        if event.AltDown() and event.ControlDown() and keymap.has_key(key):
            currPos = self.GetCurrentPos()
            self.InsertText(currPos, keymap[key])
            self.SetCurrentPos(self.GetCurrentPos()+1)
            self.SetSelectionStart(self.GetCurrentPos())


stcConfigPath = os.path.join(Preferences.rcPath, 'stc-styles.rc.cfg')

class PythonStyledTextCtrlMix(LanguageSTCMix):
    def __init__(self, wId, margin):
        LanguageSTCMix.__init__(self, wId, margin, 'python', stcConfigPath)

        # XXX add 'with'. here or in stc config?
        self.keywords += ' yield None True False'

        self.setStyles()

    def grayout(self, do):
        if not Preferences.grayoutSource: return
        if do: f = {'backcol': '#EEF2FF'}
        else: f = None
        self.setStyles(f)

    def OnUpdateUI(self, event):
        # check for matching braces
        braceAtCaret = -1
        braceOpposite = -1
        charBefore = None
        caretPos = self.GetCurrentPos()
        if caretPos > 0:
            try:
                charBefore = chr(self.GetCharAt(caretPos - 1))
            except ValueError:
                charBefore = ''
            styleBefore = self.GetStyleAt(caretPos - 1)

        # check before
        if charBefore and charBefore in "[]{}()" and styleBefore == 10:
            braceAtCaret = caretPos - 1

        # check after
        if braceAtCaret < 0:
            try:
                charAfter = chr(self.GetCharAt(caretPos))
            except ValueError:
                charAfter = ''
            styleAfter = self.GetStyleAt(caretPos)

            if charAfter and charAfter in "[]{}()" and styleAfter == 10:
                braceAtCaret = caretPos

        if braceAtCaret >= 0:
            braceOpposite = self.BraceMatch(braceAtCaret)

        if braceAtCaret != -1 and braceOpposite == -1:
            self.BraceBadLight(braceAtCaret)
        else:
            self.BraceHighlight(braceAtCaret, braceOpposite)
            # self.Refresh(False)

    def doAutoIndent(self, prevline, pos):
        stripprevline = prevline.strip()
        if stripprevline:
            indent = prevline[:prevline.find(stripprevline)]
        else:
            try:
                indent = prevline.strip('\r\n', 1)
            except TypeError:
                indent = prevline
                while indent and indent[-1] in ('\r', '\n'):
                    indent = indent[:-1]

        if self.GetUseTabs():
            indtBlock = '\t'
        else:
            # XXX Why did I do this?
            indtBlock = self.GetTabWidth()*' '

        if _is_block_opener(prevline):
            indent = indent + indtBlock
        elif _is_block_closer(prevline):
            indent = indent[:-1*len(indtBlock)]

        self.BeginUndoAction()
        try:
            self.InsertText(pos, indent)
            self.GotoPos(pos + len(indent))
        finally:
            self.EndUndoAction()

class TextSTCMix(LanguageSTCMix):
    def __init__(self, wId):
        LanguageSTCMix.__init__(self, wId, (), 'text', stcConfigPath)
        self.setStyles()

## 1 :
## 2 : diff
## 3 : +++/---
## 4 : @
## 5 : -
## 6 : +
class DiffSTCMix(LanguageSTCMix):
    def __init__(self, wId):
        LanguageSTCMix.__init__(self, wId, (), 'diff', stcConfigPath)
        self.setStyles()

from types import IntType,SliceType,StringType
class STCLinesList:
    def __init__(self, STC):
        self.__STC = STC

    def _rememberPos(self):
        self.__pos = self.GetCurrentPos()

    def __getitem__(self, key):
        if type(key) is IntType:
            # XXX last char is garbage
            if key < len(self):
                return self.__STC.GetLine(key)
            else:
                raise IndexError
        elif type(key) is SliceType:
            res = []
            for idx in range(key.start, key.stop):
                res.append(self[idx])
            return res
        else:
            raise TypeError, _('%s not supported') % `type(key)`

    def __setitem__(self, key, value):
        stc = self.__STC
        if type(key) is IntType:
            assert type(value) is StringType
            if key < len(self):
                stc.SetSelection(stc.PositionFromLine(key), stc.GetLineEndPosition(key))
                stc.ReplaceSelection(value)
            else:
                raise IndexError
        elif type(key) is SliceType:
            lines = eols[stc.GetEOLMode()].join(value)
            stc.SetSelection(stc.PositionFromLine(key.start),
                  stc.GetLineEndPosition(key.stop))
            stc.ReplaceSelection(lines)
        else:
            raise TypeError, _('%s not supported') % `type(key)`

    def __delitem__(self, key):
        stc = self.__STC
        if type(key) is IntType:
            stc.SetSelection(stc.PositionFromLine(key), stc.GetLineEndPosition(key)+1)
            stc.ReplaceSelection('')
        elif type(key) is SliceType:
            stc.SetSelection(stc.PositionFromLine(key.start),
                  stc.GetLineEndPosition(key.stop)+1)
            stc.ReplaceSelection('')
        else:
            raise TypeError, _('%s not supported') % `type(key)`

    def __getattr__(self, name):
        if name == 'current':
            return self.__STC.GetCurrentLine()
        if name == 'count':
            return self.__STC.GetLineCount()
        if name == 'size':
            return self.__STC.GetTextLength()
        # dubious
        if name == 'line':
            return self.__STC.GetCurLine()[0]
        # dubious
        if name == 'pos':
            return self.__STC.GetCurrentPos()

        raise AttributeError, name

    def __len__(self):
        return self.__STC.GetLineCount()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.