⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editor.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 2 页
字号:
        dispatcher.send(signal='EditorChange', sender=self,
                        editor=window.editor)
        window.SetFocus()
        event.Skip()


class EditorShellNotebookFrame(EditorNotebookFrame):
    """Frame containing a notebook containing EditorShellNotebooks."""

    def __init__(self, parent=None, id=-1, title='PyAlaModeTest',
                 pos=wx.DefaultPosition, size=(600, 400), 
                 style=wx.DEFAULT_FRAME_STYLE,
                 filename=None, singlefile=False):
        """Create EditorShellNotebookFrame instance."""
        self._singlefile = singlefile
        EditorNotebookFrame.__init__(self, parent, id, title, pos,
                                     size, style, filename)

    def _setup(self):
        """Setup prior to first buffer creation.

        Called automatically by base class during init."""
        if not self._singlefile:
            self.notebook = EditorNotebook(parent=self)

    def OnAbout(self, event):
        """Display an About window."""
        title = 'About PyAlaModePlus'
        text = 'Another fine, flaky program.'
        dialog = wx.MessageDialog(self, text, title,
                                  wx.OK | wx.ICON_INFORMATION)
        dialog.ShowModal()
        dialog.Destroy()

    def bufferCreate(self, filename=None):
        """Create new buffer."""
        if self._singlefile:
            self.bufferDestroy()
            notebook = EditorShellNotebook(parent=self,
                                           filename=filename)
            self.notebook = notebook
        else:
            notebook = EditorShellNotebook(parent=self.notebook,
                                           filename=filename)
        self.setEditor(notebook.editor)
        if not self._singlefile:
            self.notebook.AddPage(page=notebook, text=self.buffer.name,
                                  select=True)
        self.editor.setFocus()

    def bufferDestroy(self):
        """Destroy the current buffer."""
        if self.buffer:
            self.editor = None
            del self.buffers[self.buffer.id]
            self.buffer = None  # Do this before DeletePage().
        if self._singlefile:
            self.notebook.Destroy()
            self.notebook = None
        else:
            selection = self.notebook.GetSelection()
##             print "Destroy Selection:", selection
            self.notebook.DeletePage(selection)

    def bufferNew(self):
        """Create new buffer."""
        if self._singlefile and self.bufferHasChanged():
            cancel = self.bufferSuggestSave()
            if cancel:
                return cancel
        self.bufferCreate()
        cancel = False
        return cancel

    def bufferOpen(self):
        """Open file in buffer."""
        if self._singlefile and self.bufferHasChanged():
            cancel = self.bufferSuggestSave()
            if cancel:
                return cancel
        filedir = ''
        if self.buffer and self.buffer.doc.filedir:
            filedir = self.buffer.doc.filedir
        if self._singlefile:
            result = openSingle(directory=filedir)
            if result.path:
                self.bufferCreate(result.path)
        else:
            result = openMultiple(directory=filedir)
            for path in result.paths:
                self.bufferCreate(path)
        cancel = False
        return cancel


class EditorShellNotebook(wx.Notebook):
    """A notebook containing an editor page and a shell page."""

    def __init__(self, parent, filename=None):
        """Create EditorShellNotebook instance."""
        wx.Notebook.__init__(self, parent, id=-1)
        usePanels = True
        if usePanels:
            editorparent = editorpanel = wx.Panel(self, -1)
            shellparent = shellpanel = wx.Panel(self, -1)
        else:
            editorparent = self
            shellparent = self
        self.buffer = Buffer()
        self.editor = Editor(parent=editorparent)
        self.buffer.addEditor(self.editor)
        self.buffer.open(filename)
        self.shell = Shell(parent=shellparent, locals=self.buffer.interp.locals,
                           style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
        self.buffer.interp.locals.clear()
        if usePanels:
            self.AddPage(page=editorpanel, text='Editor', select=True)
            self.AddPage(page=shellpanel, text='Shell')
            # Setup sizers
            editorsizer = wx.BoxSizer(wx.VERTICAL)
            editorsizer.Add(self.editor.window, 1, wx.EXPAND)
            editorpanel.SetSizer(editorsizer)
            editorpanel.SetAutoLayout(True)
            shellsizer = wx.BoxSizer(wx.VERTICAL)
            shellsizer.Add(self.shell, 1, wx.EXPAND)
            shellpanel.SetSizer(shellsizer)
            shellpanel.SetAutoLayout(True)
        else:
            self.AddPage(page=self.editor.window, text='Editor', select=True)
            self.AddPage(page=self.shell, text='Shell')
        self.editor.setFocus()
        self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged, id=self.GetId())

    def OnPageChanged(self, event):
        """Page changed event handler."""
        selection = event.GetSelection()
        if selection == 0:
            self.editor.setFocus()
        else:
            self.shell.SetFocus()
        event.Skip()

    def SetFocus(self):
        wx.Notebook.SetFocus(self)
        selection = self.GetSelection()
        if selection == 0:
            self.editor.setFocus()
        else:
            self.shell.SetFocus()


class Editor:
    """Editor having an EditWindow."""

    def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
        """Create Editor instance."""
        self.window = EditWindow(self, parent, id, pos, size, style)
        self.id = self.window.GetId()
        self.buffer = None
        # Assign handlers for keyboard events.
        self.window.Bind(wx.EVT_CHAR, self.OnChar)
        self.window.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

    def _setBuffer(self, buffer, text):
        """Set the editor to a buffer.  Private callback called by buffer."""
        self.buffer = buffer
        self.autoCompleteKeys = buffer.interp.getAutoCompleteKeys()
        self.clearAll()
        self.setText(text)
        self.emptyUndoBuffer()
        self.setSavePoint()

    def destroy(self):
        """Destroy all editor objects."""
        self.window.Destroy()

    def clearAll(self):
        self.window.ClearAll()

    def emptyUndoBuffer(self):
        self.window.EmptyUndoBuffer()

    def getStatus(self):
        """Return (filepath, line, column) status tuple."""
        if self.window:
            pos = self.window.GetCurrentPos()
            line = self.window.LineFromPosition(pos) + 1
            col = self.window.GetColumn(pos)
            if self.buffer:
                name = self.buffer.doc.filepath or self.buffer.name
            else:
                name = ''
            status = (name, line, col)
            return status
        else:
            return ('', 0, 0)

    def getText(self):
        """Return contents of editor."""
        return self.window.GetText()

    def hasChanged(self):
        """Return True if contents have changed."""
        return self.window.GetModify()

    def setFocus(self):
        """Set the input focus to the editor window."""
        self.window.SetFocus()

    def setSavePoint(self):
        self.window.SetSavePoint()

    def setText(self, text):
        """Set contents of editor."""
        self.window.SetText(text)

    def OnChar(self, event):
        """Keypress event handler.
        
        Only receives an event if OnKeyDown calls event.Skip() for the
        corresponding event."""

        key = event.KeyCode()
        if key in self.autoCompleteKeys:
            # Usually the dot (period) key activates auto completion.
            if self.window.AutoCompActive(): 
                self.window.AutoCompCancel()
            self.window.ReplaceSelection('')
            self.window.AddText(chr(key))
            text, pos = self.window.GetCurLine()
            text = text[:pos]
            if self.window.autoComplete: 
                self.autoCompleteShow(text)
        elif key == ord('('):
            # The left paren activates a call tip and cancels an
            # active auto completion.
            if self.window.AutoCompActive(): 
                self.window.AutoCompCancel()
            self.window.ReplaceSelection('')
            self.window.AddText('(')
            text, pos = self.window.GetCurLine()
            text = text[:pos]
            self.autoCallTipShow(text)
        else:
            # Allow the normal event handling to take place.
            event.Skip()

    def OnKeyDown(self, event):
        """Key down event handler."""

        key = event.KeyCode()
        # If the auto-complete window is up let it do its thing.
        if self.window.AutoCompActive():
            event.Skip()
            return
        controlDown = event.ControlDown()
        altDown = event.AltDown()
        shiftDown = event.ShiftDown()
        # Let Ctrl-Alt-* get handled normally.
        if controlDown and altDown:
            event.Skip()
        # Increase font size.
        elif controlDown and key in (ord(']'),):
            dispatcher.send(signal='FontIncrease')
        # Decrease font size.
        elif controlDown and key in (ord('['),):
            dispatcher.send(signal='FontDecrease')
        # Default font size.
        elif controlDown and key in (ord('='),):
            dispatcher.send(signal='FontDefault')
        else:
            event.Skip()

    def autoCompleteShow(self, command):
        """Display auto-completion popup list."""
        list = self.buffer.interp.getAutoCompleteList(command, 
                    includeMagic=self.window.autoCompleteIncludeMagic, 
                    includeSingle=self.window.autoCompleteIncludeSingle, 
                    includeDouble=self.window.autoCompleteIncludeDouble)
        if list:
            options = ' '.join(list)
            offset = 0
            self.window.AutoCompShow(offset, options)

    def autoCallTipShow(self, command):
        """Display argument spec and docstring in a popup window."""
        if self.window.CallTipActive():
            self.window.CallTipCancel()
        (name, argspec, tip) = self.buffer.interp.getCallTip(command)
        if tip:
            dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip)
        if not self.window.autoCallTip:
            return
        if argspec:
            startpos = self.window.GetCurrentPos()
            self.window.AddText(argspec + ')')
            endpos = self.window.GetCurrentPos()
            self.window.SetSelection(endpos, startpos)
        if tip:
            curpos = self.window.GetCurrentPos()
            size = len(name)
            tippos = curpos - (size + 1)
            fallback = curpos - self.window.GetColumn(curpos)
            # In case there isn't enough room, only go back to the
            # fallback.
            tippos = max(tippos, fallback)
            self.window.CallTipShow(tippos, tip)
            self.window.CallTipSetHighlight(0, size)


class EditWindow(editwindow.EditWindow):
    """EditWindow based on StyledTextCtrl."""

    def __init__(self, editor, parent, id=-1, pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
        """Create EditWindow instance."""
        editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
        self.editor = editor


class DialogResults:
    """DialogResults class."""

    def __init__(self, returned):
        """Create wrapper for results returned by dialog."""
        self.returned = returned
        self.positive = returned in (wx.ID_OK, wx.ID_YES)
        self.text = self._asString()
        

    def __repr__(self):
        return str(self.__dict__)

    def _asString(self):
        returned = self.returned
        if returned == wx.ID_OK:
            return "Ok"
        elif returned == wx.ID_CANCEL:
            return "Cancel"
        elif returned == wx.ID_YES:
            return "Yes"
        elif returned == wx.ID_NO:
            return "No"


def fileDialog(parent=None, title='Open', directory='', filename='',
               wildcard='All Files (*.*)|*.*',
               style=wx.OPEN | wx.MULTIPLE):
    """File dialog wrapper function."""
    dialog = wx.FileDialog(parent, title, directory, filename,
                           wildcard, style)
    result = DialogResults(dialog.ShowModal())
    if result.positive:
        result.paths = dialog.GetPaths()
    else:
        result.paths = []
    dialog.Destroy()
    return result


def openSingle(parent=None, title='Open', directory='', filename='',
               wildcard='All Files (*.*)|*.*', style=wx.OPEN):
    """File dialog wrapper function."""
    dialog = wx.FileDialog(parent, title, directory, filename,
                           wildcard, style)
    result = DialogResults(dialog.ShowModal())
    if result.positive:
        result.path = dialog.GetPath()
    else:
        result.path = None
    dialog.Destroy()
    return result


def openMultiple(parent=None, title='Open', directory='', filename='',
                 wildcard='All Files (*.*)|*.*',
                 style=wx.OPEN | wx.MULTIPLE):
    """File dialog wrapper function."""
    return fileDialog(parent, title, directory, filename, wildcard, style)


def saveSingle(parent=None, title='Save', directory='', filename='',
               wildcard='All Files (*.*)|*.*',
               style=wx.SAVE | wx.OVERWRITE_PROMPT):
    """File dialog wrapper function."""
    dialog = wx.FileDialog(parent, title, directory, filename,
                           wildcard, style)
    result = DialogResults(dialog.ShowModal())
    if result.positive:
        result.path = dialog.GetPath()
    else:
        result.path = None
    dialog.Destroy()
    return result


def directory(parent=None, message='Choose a directory', path='', style=0,
              pos=wx.DefaultPosition, size=wx.DefaultSize):
    """Dir dialog wrapper function."""
    dialog = wx.DirDialog(parent, message, path, style, pos, size)
    result = DialogResults(dialog.ShowModal())
    if result.positive:
        result.path = dialog.GetPath()
    else:
        result.path = None
    dialog.Destroy()
    return result


def messageDialog(parent=None, message='', title='Message box',
                  style=wx.YES_NO | wx.CANCEL | wx.CENTRE | wx.ICON_QUESTION,
                  pos=wx.DefaultPosition):
    """Message dialog wrapper function."""
    dialog = wx.MessageDialog(parent, message, title, style, pos)
    result = DialogResults(dialog.ShowModal())
    dialog.Destroy()
    return result

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -