Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
view.py833 linesDownload Raw Back to scintilla
1# A general purpose MFC CCtrlView view that uses Scintilla.2 3import array4import os5import re6import string7import struct8import sys9 10import __main__  # for attribute lookup11import afxres12import win32con13import win32ui14from pywin.mfc import dialog, docview15 16from . import IDLEenvironment  # IDLE emulation.17from . import bindings, control, keycodes, scintillacon18 19PRINTDLGORD = 153820IDC_PRINT_MAG_EDIT = 101021EM_FORMATRANGE = win32con.WM_USER + 5722 23wordbreaks = "._" + string.ascii_uppercase + string.ascii_lowercase + string.digits24 25patImport = re.compile("import (?P<name>.*)")26 27_event_commands = [28    # File menu29    "win32ui.ID_FILE_LOCATE",30    "win32ui.ID_FILE_CHECK",31    "afxres.ID_FILE_CLOSE",32    "afxres.ID_FILE_NEW",33    "afxres.ID_FILE_OPEN",34    "afxres.ID_FILE_SAVE",35    "afxres.ID_FILE_SAVE_AS",36    "win32ui.ID_FILE_SAVE_ALL",37    # Edit menu38    "afxres.ID_EDIT_UNDO",39    "afxres.ID_EDIT_REDO",40    "afxres.ID_EDIT_CUT",41    "afxres.ID_EDIT_COPY",42    "afxres.ID_EDIT_PASTE",43    "afxres.ID_EDIT_SELECT_ALL",44    "afxres.ID_EDIT_FIND",45    "afxres.ID_EDIT_REPEAT",46    "afxres.ID_EDIT_REPLACE",47    # View menu48    "win32ui.ID_VIEW_WHITESPACE",49    "win32ui.ID_VIEW_FIXED_FONT",50    "win32ui.ID_VIEW_BROWSE",51    "win32ui.ID_VIEW_INTERACTIVE",52    # Window menu53    "afxres.ID_WINDOW_ARRANGE",54    "afxres.ID_WINDOW_CASCADE",55    "afxres.ID_WINDOW_NEW",56    "afxres.ID_WINDOW_SPLIT",57    "afxres.ID_WINDOW_TILE_HORZ",58    "afxres.ID_WINDOW_TILE_VERT",59    # Others60    "afxres.ID_APP_EXIT",61    "afxres.ID_APP_ABOUT",62]63 64_extra_event_commands = [65    ("EditDelete", afxres.ID_EDIT_CLEAR),66    ("LocateModule", win32ui.ID_FILE_LOCATE),67    ("GotoLine", win32ui.ID_EDIT_GOTO_LINE),68    ("DbgBreakpointToggle", win32ui.IDC_DBG_ADD),69    ("DbgGo", win32ui.IDC_DBG_GO),70    ("DbgStepOver", win32ui.IDC_DBG_STEPOVER),71    ("DbgStep", win32ui.IDC_DBG_STEP),72    ("DbgStepOut", win32ui.IDC_DBG_STEPOUT),73    ("DbgBreakpointClearAll", win32ui.IDC_DBG_CLEAR),74    ("DbgClose", win32ui.IDC_DBG_CLOSE),75]76 77event_commands = []78 79 80def _CreateEvents():81    for name in _event_commands:82        val = eval(name)83        name_parts = name.split("_")[1:]84        name_parts = [p.capitalize() for p in name_parts]85        event = "".join(name_parts)86        event_commands.append((event, val))87    for name, id in _extra_event_commands:88        event_commands.append((name, id))89 90 91_CreateEvents()92del _event_commands93del _extra_event_commands94 95command_reflectors = [96    (win32ui.ID_EDIT_UNDO, win32con.WM_UNDO),97    (win32ui.ID_EDIT_REDO, scintillacon.SCI_REDO),98    (win32ui.ID_EDIT_CUT, win32con.WM_CUT),99    (win32ui.ID_EDIT_COPY, win32con.WM_COPY),100    (win32ui.ID_EDIT_PASTE, win32con.WM_PASTE),101    (win32ui.ID_EDIT_CLEAR, win32con.WM_CLEAR),102    (win32ui.ID_EDIT_SELECT_ALL, scintillacon.SCI_SELECTALL),103]104 105 106def DoBraceMatch(control):107    curPos = control.SCIGetCurrentPos()108    charBefore = " "109    if curPos:110        charBefore = control.SCIGetCharAt(curPos - 1)111    charAt = control.SCIGetCharAt(curPos)112    braceAtPos = braceOpposite = -1113    if charBefore in "[](){}":114        braceAtPos = curPos - 1115    if braceAtPos == -1:116        if charAt in "[](){}":117            braceAtPos = curPos118    if braceAtPos != -1:119        braceOpposite = control.SCIBraceMatch(braceAtPos, 0)120    if braceAtPos != -1 and braceOpposite == -1:121        control.SCIBraceBadHighlight(braceAtPos)122    else:123        # either clear them both or set them both.124        control.SCIBraceHighlight(braceAtPos, braceOpposite)125 126 127def _get_class_attributes(ob):128    # Recurse into base classes looking for attributes129    items = []130    try:131        items = items + dir(ob)132        for i in ob.__bases__:133            for item in _get_class_attributes(i):134                if item not in items:135                    items.append(item)136    except AttributeError:137        pass138    return items139 140 141# Supposed to look like an MFC CEditView, but142# also supports IDLE extensions and other source code generic features.143class CScintillaView(docview.CtrlView, control.CScintillaColorEditInterface):144    def __init__(self, doc):145        docview.CtrlView.__init__(146            self,147            doc,148            "Scintilla",149            win32con.WS_CHILD150            | win32con.WS_VSCROLL151            | win32con.WS_HSCROLL152            | win32con.WS_CLIPCHILDREN153            | win32con.WS_VISIBLE,154        )155        self._tabWidth = (156            8  # Mirror of what we send to Scintilla - never change this directly157        )158        self.bAutoCompleteAttributes = 1159        self.bShowCallTips = 1160        self.bMatchBraces = 0  # Editor option will default this to true later!161        self.bindings = bindings.BindingsManager(self)162 163        self.idle = IDLEenvironment.IDLEEditorWindow(self)164        self.idle.IDLEExtension("AutoExpand")165        # SendScintilla is called so frequently it is worth optimizing.166        self.SendScintilla = self._obj_.SendMessage167 168    def _MakeColorizer(self):169        ext = os.path.splitext(self.GetDocument().GetPathName())[1]170        from . import formatter171 172        return formatter.BuiltinPythonSourceFormatter(self, ext)173 174    # 	def SendScintilla(self, msg, w=0, l=0):175    # 		return self._obj_.SendMessage(msg, w, l)176 177    def SCISetTabWidth(self, width):178        # I need to remember the tab-width for the AutoIndent extension.  This may go.179        self._tabWidth = width180        control.CScintillaEditInterface.SCISetTabWidth(self, width)181 182    def GetTabWidth(self):183        return self._tabWidth184 185    def HookHandlers(self):186        # Create events for all the menu names.187        for name, val in event_commands:188            # 			handler = lambda id, code, tosend=val, parent=parent: parent.OnCommand(tosend, 0) and 0189            self.bindings.bind(name, None, cid=val)190 191        # Hook commands that do nothing other than send Scintilla messages.192        for command, reflection in command_reflectors:193            handler = (194                lambda id, code, ss=self.SendScintilla, tosend=reflection: ss(tosend)195                and 0196            )197            self.HookCommand(handler, command)198 199        self.HookCommand(self.OnCmdViewWS, win32ui.ID_VIEW_WHITESPACE)200        self.HookCommandUpdate(self.OnUpdateViewWS, win32ui.ID_VIEW_WHITESPACE)201        self.HookCommand(202            self.OnCmdViewIndentationGuides, win32ui.ID_VIEW_INDENTATIONGUIDES203        )204        self.HookCommandUpdate(205            self.OnUpdateViewIndentationGuides, win32ui.ID_VIEW_INDENTATIONGUIDES206        )207        self.HookCommand(self.OnCmdViewRightEdge, win32ui.ID_VIEW_RIGHT_EDGE)208        self.HookCommandUpdate(self.OnUpdateViewRightEdge, win32ui.ID_VIEW_RIGHT_EDGE)209        self.HookCommand(self.OnCmdViewEOL, win32ui.ID_VIEW_EOL)210        self.HookCommandUpdate(self.OnUpdateViewEOL, win32ui.ID_VIEW_EOL)211        self.HookCommand(self.OnCmdViewFixedFont, win32ui.ID_VIEW_FIXED_FONT)212        self.HookCommandUpdate(self.OnUpdateViewFixedFont, win32ui.ID_VIEW_FIXED_FONT)213        self.HookCommand(self.OnCmdFileLocate, win32ui.ID_FILE_LOCATE)214        self.HookCommand(self.OnCmdEditFind, win32ui.ID_EDIT_FIND)215        self.HookCommand(self.OnCmdEditRepeat, win32ui.ID_EDIT_REPEAT)216        self.HookCommand(self.OnCmdEditReplace, win32ui.ID_EDIT_REPLACE)217        self.HookCommand(self.OnCmdGotoLine, win32ui.ID_EDIT_GOTO_LINE)218        self.HookCommand(self.OnFilePrint, afxres.ID_FILE_PRINT)219        self.HookCommand(self.OnFilePrint, afxres.ID_FILE_PRINT_DIRECT)220        self.HookCommand(self.OnFilePrintPreview, win32ui.ID_FILE_PRINT_PREVIEW)221        # Key bindings.222        self.HookMessage(self.OnKeyDown, win32con.WM_KEYDOWN)223        self.HookMessage(self.OnKeyDown, win32con.WM_SYSKEYDOWN)224        # Hook wheeley mouse events225        # 		self.HookMessage(self.OnMouseWheel, win32con.WM_MOUSEWHEEL)226        self.HookFormatter()227 228    def OnInitialUpdate(self):229        doc = self.GetDocument()230 231        # Enable Unicode232        self.SendScintilla(scintillacon.SCI_SETCODEPAGE, scintillacon.SC_CP_UTF8, 0)233        self.SendScintilla(scintillacon.SCI_SETKEYSUNICODE, 1, 0)234 235        # Create margins236        self.SendScintilla(237            scintillacon.SCI_SETMARGINTYPEN, 1, scintillacon.SC_MARGIN_SYMBOL238        )239        self.SendScintilla(scintillacon.SCI_SETMARGINMASKN, 1, 0xF)240        self.SendScintilla(241            scintillacon.SCI_SETMARGINTYPEN, 2, scintillacon.SC_MARGIN_SYMBOL242        )243        self.SendScintilla(244            scintillacon.SCI_SETMARGINMASKN, 2, scintillacon.SC_MASK_FOLDERS245        )246        self.SendScintilla(scintillacon.SCI_SETMARGINSENSITIVEN, 2, 1)247 248        self.GetDocument().HookViewNotifications(249            self250        )  # is there an MFC way to grab this?251        self.HookHandlers()252 253        # Load the configuration information.254        self.OnWinIniChange(None)255 256        self.SetSel()257 258        self.GetDocument().FinalizeViewCreation(259            self260        )  # is there an MFC way to grab this?261 262    def _GetSubConfigNames(self):263        return None  # By default we use only sections without sub-sections.264 265    def OnWinIniChange(self, section=None):266        self.bindings.prepare_configure()267        try:268            self.DoConfigChange()269        finally:270            self.bindings.complete_configure()271 272    def DoConfigChange(self):273        # Bit of a hack I dont kow what to do about - these should be "editor options"274        from pywin.framework.editor import GetEditorOption275 276        self.bAutoCompleteAttributes = GetEditorOption("Autocomplete Attributes", 1)277        self.bShowCallTips = GetEditorOption("Show Call Tips", 1)278        # Update the key map and extension data.279        configManager.configure(self, self._GetSubConfigNames())280        if configManager.last_error:281            win32ui.MessageBox(configManager.last_error, "Configuration Error")282        self.bMatchBraces = GetEditorOption("Match Braces", 1)283        self.ApplyFormattingStyles(1)284 285    def OnDestroy(self, msg):286        self.bindings.close()287        self.bindings = None288        self.idle.close()289        self.idle = None290        control.CScintillaColorEditInterface.close(self)291        return docview.CtrlView.OnDestroy(self, msg)292 293    def OnMouseWheel(self, msg):294        zDelta = msg[2] >> 16295        vpos = self.GetScrollPos(win32con.SB_VERT)296        vpos = vpos - zDelta / 40  # 3 lines per notch297        self.SetScrollPos(win32con.SB_VERT, vpos)298        self.SendScintilla(299            win32con.WM_VSCROLL, (vpos << 16) | win32con.SB_THUMBPOSITION, 0300        )301 302    def OnBraceMatch(self, std, extra):303        if not self.bMatchBraces:304            return305        DoBraceMatch(self)306 307    def OnNeedShown(self, std, extra):308        notify = self.SCIUnpackNotifyMessage(extra)309        # OnNeedShown is called before an edit operation when310        # text is folded (as it is possible the text insertion will happen311        # in a folded region.)  As this happens _before_ the insert,312        # we ignore the length (if we are at EOF, pos + length may313        # actually be beyond the end of buffer)314        self.EnsureCharsVisible(notify.position)315 316    def EnsureCharsVisible(self, start, end=None):317        if end is None:318            end = start319        lineStart = self.LineFromChar(min(start, end))320        lineEnd = self.LineFromChar(max(start, end))321        while lineStart <= lineEnd:322            self.SCIEnsureVisible(lineStart)323            lineStart = lineStart + 1324 325    # Helper to add an event to a menu.326    def AppendMenu(self, menu, text="", event=None, flags=None, checked=0):327        if event is None:328            assert flags is not None, "No event or custom flags!"329            cmdid = 0330        else:331            cmdid = self.bindings.get_command_id(event)332            if cmdid is None:333                # No event of that name - no point displaying it.334                print(335                    'View.AppendMenu(): Unknown event "%s" specified for menu text "%s" - ignored'336                    % (event, text)337                )338                return339            keyname = configManager.get_key_binding(event, self._GetSubConfigNames())340            if keyname is not None:341                text = text + "\t" + keyname342        if flags is None:343            flags = win32con.MF_STRING | win32con.MF_ENABLED344        if checked:345            flags = flags | win32con.MF_CHECKED346        menu.AppendMenu(flags, cmdid, text)347 348    def OnKeyDown(self, msg):349        return self.bindings.fire_key_event(msg)350 351    def GotoEndOfFileEvent(self, event):352        self.SetSel(-1)353 354    def KeyDotEvent(self, event):355        ## Don't trigger autocomplete if any text is selected356        s, e = self.GetSel()357        if s != e:358            return 1359        self.SCIAddText(".")360        if self.bAutoCompleteAttributes:361            self._AutoComplete()362 363    # View Whitespace/EOL/Indentation UI.364 365    def OnCmdViewWS(self, cmd, code):  # Handle the menu command366        viewWS = self.SCIGetViewWS()367        self.SCISetViewWS(not viewWS)368 369    def OnUpdateViewWS(self, cmdui):  # Update the tick on the UI.370        cmdui.SetCheck(self.SCIGetViewWS())371        cmdui.Enable()372 373    def OnCmdViewIndentationGuides(self, cmd, code):  # Handle the menu command374        viewIG = self.SCIGetIndentationGuides()375        self.SCISetIndentationGuides(not viewIG)376 377    def OnUpdateViewIndentationGuides(self, cmdui):  # Update the tick on the UI.378        cmdui.SetCheck(self.SCIGetIndentationGuides())379        cmdui.Enable()380 381    def OnCmdViewRightEdge(self, cmd, code):  # Handle the menu command382        if self.SCIGetEdgeMode() == scintillacon.EDGE_NONE:383            mode = scintillacon.EDGE_BACKGROUND384        else:385            mode = scintillacon.EDGE_NONE386        self.SCISetEdgeMode(mode)387 388    def OnUpdateViewRightEdge(self, cmdui):  # Update the tick on the UI.389        cmdui.SetCheck(self.SCIGetEdgeMode() != scintillacon.EDGE_NONE)390        cmdui.Enable()391 392    def OnCmdViewEOL(self, cmd, code):  # Handle the menu command393        viewEOL = self.SCIGetViewEOL()394        self.SCISetViewEOL(not viewEOL)395 396    def OnUpdateViewEOL(self, cmdui):  # Update the tick on the UI.397        cmdui.SetCheck(self.SCIGetViewEOL())398        cmdui.Enable()399 400    def OnCmdViewFixedFont(self, cmd, code):  # Handle the menu command401        self._GetColorizer().bUseFixed = not self._GetColorizer().bUseFixed402        self.ApplyFormattingStyles(0)403        # Ensure the selection is visible!404        self.ScrollCaret()405 406    def OnUpdateViewFixedFont(self, cmdui):  # Update the tick on the UI.407        c = self._GetColorizer()408        if c is not None:409            cmdui.SetCheck(c.bUseFixed)410        cmdui.Enable(c is not None)411 412    def OnCmdEditFind(self, cmd, code):413        from . import find414 415        find.ShowFindDialog()416 417    def OnCmdEditRepeat(self, cmd, code):418        from . import find419 420        find.FindNext()421 422    def OnCmdEditReplace(self, cmd, code):423        from . import find424 425        find.ShowReplaceDialog()426 427    def OnCmdFileLocate(self, cmd, id):428        line = self.GetLine().strip()429        import pywin.framework.scriptutils430 431        m = patImport.match(line)432        if m:433            # Module name on this line - locate that!434            modName = m.group("name")435            fileName = pywin.framework.scriptutils.LocatePythonFile(modName)436            if fileName is None:437                win32ui.SetStatusText("Can't locate module %s" % modName)438                return 1  # Let the default get it.439            else:440                win32ui.GetApp().OpenDocumentFile(fileName)441        else:442            # Just to a "normal" locate - let the default handler get it.443            return 1444        return 0445 446    def OnCmdGotoLine(self, cmd, id):447        try:448            lineNo = int(input("Enter Line Number")) - 1449        except (ValueError, KeyboardInterrupt):450            return 0451        self.SCIEnsureVisible(lineNo)452        self.SCIGotoLine(lineNo)453        return 0454 455    def SaveTextFile(self, filename, encoding=None):456        doc = self.GetDocument()457        doc._SaveTextToFile(self, filename, encoding=encoding)458        doc.SetModifiedFlag(0)459        return 1460 461    def _AutoComplete(self):462        def list2dict(l):463            ret = {}464            for i in l:465                ret[i] = None466            return ret467 468        self.SCIAutoCCancel()  # Cancel old auto-complete lists.469        # First try and get an object without evaluating calls470        ob = self._GetObjectAtPos(bAllowCalls=0)471        # If that failed, try and process call or indexing to get the object.472        if ob is None:473            ob = self._GetObjectAtPos(bAllowCalls=1)474        items_dict = {}475        if ob is not None:476            try:  # Catch unexpected errors when fetching attribute names from the object477                # extra attributes of win32ui objects478                if hasattr(ob, "_obj_"):479                    try:480                        items_dict.update(list2dict(dir(ob._obj_)))481                    except AttributeError:482                        pass  # object has no __dict__483 484                # normal attributes485                try:486                    items_dict.update(list2dict(dir(ob)))487                except AttributeError:488                    pass  # object has no __dict__489                if hasattr(ob, "__class__"):490                    items_dict.update(list2dict(_get_class_attributes(ob.__class__)))491                # The object may be a COM object with typelib support - lets see if we can get its props.492                # (contributed by Stefan Migowsky)493                try:494                    # Get the automation attributes495                    items_dict.update(ob.__class__._prop_map_get_)496                    # See if there is an write only property497                    # could be optimized498                    items_dict.update(ob.__class__._prop_map_put_)499                    # append to the already evaluated list500                except AttributeError:501                    pass502                # The object might be a pure COM dynamic dispatch with typelib support - lets see if we can get its props.503                if hasattr(ob, "_oleobj_"):504                    try:505                        for iTI in range(0, ob._oleobj_.GetTypeInfoCount()):506                            typeInfo = ob._oleobj_.GetTypeInfo(iTI)507                            self._UpdateWithITypeInfo(items_dict, typeInfo)508                    except:509                        pass510            except:511                win32ui.SetStatusText(512                    "Error attempting to get object attributes - %s"513                    % (repr(sys.exc_info()[0]),)514                )515 516        # ensure all keys are strings.517        items = [str(k) for k in items_dict.keys()]518        # All names that start with "_" go!519        items = [k for k in items if not k.startswith("_")]520 521        if not items:522            # Heuristics a-la AutoExpand523            # The idea is to find other usages of the current binding524            # and assume, that it refers to the same object (or at least,525            # to an object of the same type)526            # Contributed by Vadim Chugunov [vadimch@yahoo.com]527            left, right = self._GetWordSplit()528            if left == "":  # Ignore standalone dots529                return None530            # We limit our search to the current class, if that531            # information is available532            minline, maxline, curclass = self._GetClassInfoFromBrowser()533            endpos = self.LineIndex(maxline)534            text = self.GetTextRange(self.LineIndex(minline), endpos)535            try:536                l = re.findall(r"\b" + left + "\.\w+", text)537            except re.error:538                # parens etc may make an invalid RE, but this code wouldnt539                # benefit even if the RE did work :-)540                l = []541            prefix = len(left) + 1542            unique = {}543            for li in l:544                unique[li[prefix:]] = 1545            # Assuming traditional usage of self...546            if curclass and left == "self":547                self._UpdateWithClassMethods(unique, curclass)548 549            items = [550                word for word in unique.keys() if word[:2] != "__" or word[-2:] != "__"551            ]552            # Ignore the word currently to the right of the dot - probably a red-herring.553            try:554                items.remove(right[1:])555            except ValueError:556                pass557        if items:558            items.sort()559            self.SCIAutoCSetAutoHide(0)560            self.SCIAutoCShow(items)561 562    def _UpdateWithITypeInfo(self, items_dict, typeInfo):563        import pythoncom564 565        typeInfos = [typeInfo]566        # suppress IDispatch and IUnknown methods567        inspectedIIDs = {pythoncom.IID_IDispatch: None}568 569        while len(typeInfos) > 0:570            typeInfo = typeInfos.pop()571            typeAttr = typeInfo.GetTypeAttr()572 573            if typeAttr.iid not in inspectedIIDs:574                inspectedIIDs[typeAttr.iid] = None575                for iFun in range(0, typeAttr.cFuncs):576                    funDesc = typeInfo.GetFuncDesc(iFun)577                    funName = typeInfo.GetNames(funDesc.memid)[0]578                    if funName not in items_dict:579                        items_dict[funName] = None580 581                # Inspect the type info of all implemented types582                # E.g. IShellDispatch5 implements IShellDispatch4 which implements IShellDispatch3 ...583                for iImplType in range(0, typeAttr.cImplTypes):584                    iRefType = typeInfo.GetRefTypeOfImplType(iImplType)585                    refTypeInfo = typeInfo.GetRefTypeInfo(iRefType)586                    typeInfos.append(refTypeInfo)587 588    # TODO: This is kinda slow. Probably need some kind of cache589    # here that is flushed upon file save590    # Or maybe we don't need the superclass methods at all ?591    def _UpdateWithClassMethods(self, dict, classinfo):592        if not hasattr(classinfo, "methods"):593            # No 'methods' - probably not what we think it is.594            return595        dict.update(classinfo.methods)596        for super in classinfo.super:597            if hasattr(super, "methods"):598                self._UpdateWithClassMethods(dict, super)599 600    # Find which class definition caret is currently in and return601    # indexes of the the first and the last lines of that class definition602    # Data is obtained from module browser (if enabled)603    def _GetClassInfoFromBrowser(self, pos=-1):604        minline = 0605        maxline = self.GetLineCount() - 1606        doc = self.GetParentFrame().GetActiveDocument()607        browser = None608        try:609            if doc is not None:610                browser = doc.GetAllViews()[1]611        except IndexError:612            pass613        if browser is None:614            return (minline, maxline, None)  # Current window has no browser615        if not browser.list:616            return (minline, maxline, None)  # Not initialized617        path = self.GetDocument().GetPathName()618        if not path:619            return (minline, maxline, None)  # No current path620 621        import pywin.framework.scriptutils622 623        curmodule, path = pywin.framework.scriptutils.GetPackageModuleName(path)624        try:625            clbrdata = browser.list.root.clbrdata626        except AttributeError:627            return (minline, maxline, None)  # No class data for this module.628        curline = self.LineFromChar(pos)629        curclass = None630        # Find out which class we are in631        for item in clbrdata.values():632            if item.module == curmodule:633                item_lineno = (634                    item.lineno - 1635                )  # Scintilla counts lines from 0, whereas pyclbr - from 1636                if minline < item_lineno <= curline:637                    minline = item_lineno638                    curclass = item639                if curline < item_lineno < maxline:640                    maxline = item_lineno641        return (minline, maxline, curclass)642 643    def _GetObjectAtPos(self, pos=-1, bAllowCalls=0):644        left, right = self._GetWordSplit(pos, bAllowCalls)645        if left:  # It is an attribute lookup646            # How is this for a hack!647            namespace = sys.modules.copy()648            namespace.update(__main__.__dict__)649            # Get the debugger's context.650            try:651                from pywin.framework import interact652 653                if interact.edit is not None and interact.edit.currentView is not None:654                    globs, locs = interact.edit.currentView.GetContext()[:2]655                    if globs:656                        namespace.update(globs)657                    if locs:658                        namespace.update(locs)659            except ImportError:660                pass661            try:662                return eval(left, namespace)663            except:664                pass665        return None666 667    def _GetWordSplit(self, pos=-1, bAllowCalls=0):668        if pos == -1:669            pos = self.GetSel()[0] - 1  # Character before current one670        limit = self.GetTextLength()671        before = []672        after = []673        index = pos - 1674        wordbreaks_use = wordbreaks675        if bAllowCalls:676            wordbreaks_use = wordbreaks_use + "()[]"677        while index >= 0:678            char = self.SCIGetCharAt(index)679            if char not in wordbreaks_use:680                break681            before.insert(0, char)682            index = index - 1683        index = pos684        while index <= limit:685            char = self.SCIGetCharAt(index)686            if char not in wordbreaks_use:687                break688            after.append(char)689            index = index + 1690        return "".join(before), "".join(after)691 692    def OnPrepareDC(self, dc, pInfo):693        # 		print "OnPrepareDC for page", pInfo.GetCurPage(), "of", pInfo.GetFromPage(), "to", pInfo.GetToPage(), ", starts=", self.starts694        if dc.IsPrinting():695            # Check if we are beyond the end.696            # (only do this when actually printing, else messes up print preview!)697            if not pInfo.GetPreview() and self.starts is not None:698                prevPage = pInfo.GetCurPage() - 1699                if prevPage > 0 and self.starts[prevPage] >= self.GetTextLength():700                    # All finished.701                    pInfo.SetContinuePrinting(0)702                    return703            dc.SetMapMode(win32con.MM_TEXT)704 705    def OnPreparePrinting(self, pInfo):706        flags = (707            win32ui.PD_USEDEVMODECOPIES | win32ui.PD_ALLPAGES | win32ui.PD_NOSELECTION708        )  # Dont support printing just a selection.709        # NOTE: Custom print dialogs are stopping the user's values from coming back :-(710        # 		self.prtDlg = PrintDialog(pInfo, PRINTDLGORD, flags)711        # 		pInfo.SetPrintDialog(self.prtDlg)712        pInfo.SetMinPage(1)713        # max page remains undefined for now.714        pInfo.SetFromPage(1)715        pInfo.SetToPage(1)716        ret = self.DoPreparePrinting(pInfo)717        return ret718 719    def OnBeginPrinting(self, dc, pInfo):720        self.starts = None721        return self._obj_.OnBeginPrinting(dc, pInfo)722 723    def CalculatePageRanges(self, dc, pInfo):724        # Calculate page ranges and max page725        self.starts = {0: 0}726        metrics = dc.GetTextMetrics()727        left, top, right, bottom = pInfo.GetDraw()728        # Leave space at the top for the header.729        rc = (left, top + int((9 * metrics["tmHeight"]) / 2), right, bottom)730        pageStart = 0731        maxPage = 0732        textLen = self.GetTextLength()733        while pageStart < textLen:734            pageStart = self.FormatRange(dc, pageStart, textLen, rc, 0)735            maxPage = maxPage + 1736            self.starts[maxPage] = pageStart737        # And a sentinal for one page past the end738        self.starts[maxPage + 1] = textLen739        # When actually printing, maxPage doesnt have any effect at this late state.740        # but is needed to make the Print Preview work correctly.741        pInfo.SetMaxPage(maxPage)742 743    def OnFilePrintPreview(self, *arg):744        self._obj_.OnFilePrintPreview()745 746    def OnFilePrint(self, *arg):747        self._obj_.OnFilePrint()748 749    def FormatRange(self, dc, pageStart, lengthDoc, rc, draw):750        """751        typedef struct _formatrange {752                HDC hdc;753                HDC hdcTarget;754                RECT rc;755                RECT rcPage;756                CHARRANGE chrg;} FORMATRANGE;757        """758        fmt = "PPIIIIIIIIll"759        hdcRender = dc.GetHandleOutput()760        hdcFormat = dc.GetHandleAttrib()761        fr = struct.pack(762            fmt,763            hdcRender,764            hdcFormat,765            rc[0],766            rc[1],767            rc[2],768            rc[3],769            rc[0],770            rc[1],771            rc[2],772            rc[3],773            pageStart,774            lengthDoc,775        )776        nextPageStart = self.SendScintilla(EM_FORMATRANGE, draw, fr)777        return nextPageStart778 779    def OnPrint(self, dc, pInfo):780        metrics = dc.GetTextMetrics()781        # 		print "dev", w, h, l, metrics['tmAscent'], metrics['tmDescent']782        if self.starts is None:783            self.CalculatePageRanges(dc, pInfo)784        pageNum = pInfo.GetCurPage() - 1785        # Setup the header of the page - docname on left, pagenum on right.786        doc = self.GetDocument()787        cxChar = metrics["tmAveCharWidth"]788        cyChar = metrics["tmHeight"]789        left, top, right, bottom = pInfo.GetDraw()790        dc.TextOut(0, 2 * cyChar, doc.GetTitle())791        pagenum_str = win32ui.LoadString(afxres.AFX_IDS_PRINTPAGENUM) % (pageNum + 1,)792        dc.SetTextAlign(win32con.TA_RIGHT)793        dc.TextOut(right, 2 * cyChar, pagenum_str)794        dc.SetTextAlign(win32con.TA_LEFT)795        top = top + int((7 * cyChar) / 2)796        dc.MoveTo(left, top)797        dc.LineTo(right, top)798        top = top + cyChar799        rc = (left, top, right, bottom)800        nextPageStart = self.FormatRange(801            dc, self.starts[pageNum], self.starts[pageNum + 1], rc, 1802        )803 804 805def LoadConfiguration():806    global configManager807    # Bit of a hack I dont kow what to do about?808    from .config import ConfigManager809 810    configName = rc = win32ui.GetProfileVal("Editor", "Keyboard Config", "default")811    configManager = ConfigManager(configName)812    if configManager.last_error:813        bTryDefault = 0814        msg = "Error loading configuration '%s'\n\n%s" % (815            configName,816            configManager.last_error,817        )818        if configName != "default":819            msg = msg + "\n\nThe default configuration will be loaded."820            bTryDefault = 1821        win32ui.MessageBox(msg)822        if bTryDefault:823            configManager = ConfigManager("default")824            if configManager.last_error:825                win32ui.MessageBox(826                    "Error loading configuration 'default'\n\n%s"827                    % (configManager.last_error)828                )829 830 831configManager = None832LoadConfiguration()833 
codekingpro/portable-devtools · Team Ai