document.py :  » Windows » pyExcelerator » pywin32-214 » pythonwin » pywin » scintilla » 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 » Windows » pyExcelerator 
pyExcelerator » pywin32 214 » pythonwin » pywin » scintilla » document.py
import win32ui
from pywin.mfc import docview
from pywin import default_scintilla_encoding
import scintillacon
import win32con
import string
import os
import codecs
import re

crlf_bytes = "\r\n".encode("ascii")
lf_bytes = "\n".encode("ascii")

# re from pep263 - but we use it both on bytes and strings.
re_encoding_bytes = re.compile("coding[:=]\s*([-\w.]+)".encode("ascii"))
re_encoding_text = re.compile("coding[:=]\s*([-\w.]+)")

ParentScintillaDocument=docview.Document
class CScintillaDocument(ParentScintillaDocument):
  "A SyntEdit document. "
  def __init__(self, *args):
    self.bom = None # the BOM, if any, read from the file.
    # the encoding we detected from the source.  Might have
    # detected via the BOM or an encoding decl.  Note that in
    # the latter case (ie, while self.bom is None), it can't be
    # trusted - the user may have edited the encoding decl between
    # open and save.
    self.source_encoding = None
    ParentScintillaDocument.__init__(self, *args)

  def DeleteContents(self):
    pass

  def OnOpenDocument(self, filename):
    # init data members
    #print "Opening", filename
    self.SetPathName(filename) # Must set this early!
    try:
      # load the text as binary we can get smart
      # about detecting any existing EOL conventions.
      f = open(filename, 'rb')
      try:
        self._LoadTextFromFile(f)
      finally:
        f.close()
    except IOError:
      win32ui.MessageBox("Could not load the file from %s" % filename)
      return 0

    return 1

  def SaveFile(self, fileName):
    view = self.GetFirstView()
    ok = view.SaveTextFile(fileName)
    if ok:
      view.SCISetSavePoint()
    return ok

  def ApplyFormattingStyles(self):
    self._ApplyOptionalToViews("ApplyFormattingStyles")

  # #####################
  # File related functions
  # Helper to transfer text from the MFC document to the control.
  def _LoadTextFromFile(self, f):
    # detect EOL mode - we don't support \r only - so find the
    # first '\n' and guess based on the char before.
    l = f.readline()
    l2 = f.readline()
    # If line ends with \r\n or has no line ending, use CRLF.
    if l.endswith(crlf_bytes) or not l.endswith(lf_bytes):
      eol_mode = scintillacon.SC_EOL_CRLF
    else:
      eol_mode = scintillacon.SC_EOL_LF

    # Detect the encoding - first look for a BOM, and if not found,
    # look for a pep263 encoding declaration.
    for bom, encoding in (
      (codecs.BOM_UTF8, "utf8"),
      (codecs.BOM_UTF16_LE, "utf_16_le"),
      (codecs.BOM_UTF16_BE, "utf_16_be"),
      ):
      if l.startswith(bom):
        self.bom = bom
        self.source_encoding = encoding
        l = l[len(bom):] # remove it.
        break
    else:
      # no bom detected - look for pep263 encoding decl.
      for look in (l, l2):
        # Note we are looking at raw bytes here: so
        # both the re itself uses bytes and the result
        # is bytes - but we need the result as a string.
        match = re_encoding_bytes.search(look)
        if match is not None:
          self.source_encoding = match.group(1).decode("ascii")
          break

    # reading by lines would be too slow?  Maybe we can use the
    # incremental encoders? For now just stick with loading the
    # entire file in memory.
    text = l + l2 + f.read()

    # Translate from source encoding to UTF-8 bytes for Scintilla
    source_encoding = self.source_encoding
    # If we don't know an encoding, just use latin-1 to treat
    # it as bytes...
    if source_encoding is None:
      source_encoding = 'latin1'
    # we could optimize this by avoiding utf8 to-ing and from-ing,
    # but then we would lose the ability to handle invalid utf8
    # (and even then, the use of encoding aliases makes this tricky)
    # To create an invalid utf8 file:
    # >>> open(filename, "wb").write(codecs.BOM_UTF8+"bad \xa9har\r\n")
    try:
      dec = text.decode(source_encoding)
    except UnicodeError:
      print "WARNING: Failed to decode bytes from %r encoding - treating as latin1" % source_encoding
      dec = text.decode('latin1')
    # and put it back as utf8 - this shouldn't fail.
    text = dec.encode(default_scintilla_encoding)

    view = self.GetFirstView()
    if view.IsWindow():
      # Turn off undo collection while loading 
      view.SendScintilla(scintillacon.SCI_SETUNDOCOLLECTION, 0, 0)
      # Make sure the control isnt read-only
      view.SetReadOnly(0)
      view.SendScintilla(scintillacon.SCI_CLEARALL)
      view.SendMessage(scintillacon.SCI_ADDTEXT, text)
      view.SendScintilla(scintillacon.SCI_SETUNDOCOLLECTION, 1, 0)
      view.SendScintilla(win32con.EM_EMPTYUNDOBUFFER, 0, 0)
      # set EOL mode
      view.SendScintilla(scintillacon.SCI_SETEOLMODE, eol_mode)

  def _SaveTextToFile(self, view, f):
    s = view.GetTextRange() # already decoded from scintilla's encoding
    source_encoding = None
    if self.bom:
      f.write(self.bom)
      source_encoding = self.source_encoding
    else:
      # no BOM - look for an encoding.
      bits = re.split("[\r\n]*", s, 3)
      for look in bits[:-1]:
        match = re_encoding_text.search(look)
        if match is not None:
          source_encoding = match.group(1)
          self.source_encoding = source_encoding
          break

    if source_encoding is None:
      source_encoding = 'latin1'

    f.write(s.encode(source_encoding))
    self.SetModifiedFlag(0)


  def FinalizeViewCreation(self, view):
    pass

  def HookViewNotifications(self, view):
    parent = view.GetParentFrame()
    parent.HookNotify(ViewNotifyDelegate(self, "OnBraceMatch"), scintillacon.SCN_CHECKBRACE)
    parent.HookNotify(ViewNotifyDelegate(self, "OnMarginClick"), scintillacon.SCN_MARGINCLICK)
    parent.HookNotify(ViewNotifyDelegate(self, "OnNeedShown"), scintillacon.SCN_NEEDSHOWN)

    parent.HookNotify(DocumentNotifyDelegate(self, "OnSavePointReached"), scintillacon.SCN_SAVEPOINTREACHED)
    parent.HookNotify(DocumentNotifyDelegate(self, "OnSavePointLeft"), scintillacon.SCN_SAVEPOINTLEFT)
    parent.HookNotify(DocumentNotifyDelegate(self, "OnModifyAttemptRO"), scintillacon.SCN_MODIFYATTEMPTRO)
    # Tell scintilla what characters should abort auto-complete.
    view.SCIAutoCStops(string.whitespace+"()[]:;+-/*=\\?'!#@$%^&,<>\"'|" )

    if view != self.GetFirstView():
      view.SCISetDocPointer(self.GetFirstView().SCIGetDocPointer())


  def OnSavePointReached(self, std, extra):
    self.SetModifiedFlag(0)

  def OnSavePointLeft(self, std, extra):
    self.SetModifiedFlag(1)

  def OnModifyAttemptRO(self, std, extra):
    self.MakeDocumentWritable()

  # All Marker functions are 1 based.
  def MarkerAdd( self, lineNo, marker ):
    self.GetEditorView().SCIMarkerAdd(lineNo-1, marker)

  def MarkerCheck(self, lineNo, marker ):
    v = self.GetEditorView()
    lineNo = lineNo - 1 # Make 0 based
    markerState = v.SCIMarkerGet(lineNo)
    return markerState & (1<<marker) != 0

  def MarkerToggle( self, lineNo, marker ):
    v = self.GetEditorView()
    if self.MarkerCheck(lineNo, marker):
      v.SCIMarkerDelete(lineNo-1, marker)
    else:
      v.SCIMarkerAdd(lineNo-1, marker)
  def MarkerDelete( self, lineNo, marker ):
    self.GetEditorView().SCIMarkerDelete(lineNo-1, marker)
  def MarkerDeleteAll( self, marker ):
    self.GetEditorView().SCIMarkerDeleteAll(marker)
  def MarkerGetNext(self, lineNo, marker):
    return self.GetEditorView().SCIMarkerNext( lineNo-1, 1 << marker )+1
  def MarkerAtLine(self, lineNo, marker):
    markerState = self.GetEditorView().SCIMarkerGet(lineNo-1)
    return markerState & (1<<marker)

  # Helper for reflecting functions to views.
  def _ApplyToViews(self, funcName, *args):
    for view in self.GetAllViews():
      func = getattr(view, funcName)
      func(*args)
  def _ApplyOptionalToViews(self, funcName, *args):
    for view in self.GetAllViews():
      func = getattr(view, funcName, None)
      if func is not None:
        func(*args)
  def GetEditorView(self):
    # Find the first frame with a view,
    # then ask it to give the editor view
    # as it knows which one is "active"
    try:
      frame_gev = self.GetFirstView().GetParentFrame().GetEditorView
    except AttributeError:
      return self.GetFirstView()
    return frame_gev()

# Delegate to the correct view, based on the control that sent it.
class ViewNotifyDelegate:
  def __init__(self, doc, name):
    self.doc = doc
    self.name = name
  def __call__(self, std, extra):
    (hwndFrom, idFrom, code) = std
    for v in self.doc.GetAllViews():
      if v.GetSafeHwnd() == hwndFrom:
        return getattr(v, self.name)(*(std, extra))

# Delegate to the document, but only from a single view (as each view sends it seperately)
class DocumentNotifyDelegate:
  def __init__(self, doc, name):
    self.doc = doc
    self.delegate = getattr(doc, name)
  def __call__(self, std, extra):
    (hwndFrom, idFrom, code) = std
    if hwndFrom == self.doc.GetEditorView().GetSafeHwnd():
        self.delegate(*(std, extra))
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.