diff options
author | Thierry N <thierryn1 at hispeed dot ch> | 2009-09-08 22:28:09 +0200 |
---|---|---|
committer | Thierry N <thierryn1 at hispeed dot ch> | 2009-09-08 22:28:09 +0200 |
commit | ce887287150321c034a68ddabbe343e648ab6995 (patch) | |
tree | c45360b5eee9c0696d297b4c32a514da84b02e5b /extra/wxpython/editra-ebmlib.diff | |
parent | ba1b7f0dcee05091cc619ce58b6811e90472ba77 (diff) | |
download | nutyx-extra-ce887287150321c034a68ddabbe343e648ab6995.tar.gz nutyx-extra-ce887287150321c034a68ddabbe343e648ab6995.tar.bz2 nutyx-extra-ce887287150321c034a68ddabbe343e648ab6995.tar.xz nutyx-extra-ce887287150321c034a68ddabbe343e648ab6995.zip |
Ajout de wxpython#2.8.9.2-1
Diffstat (limited to 'extra/wxpython/editra-ebmlib.diff')
-rw-r--r-- | extra/wxpython/editra-ebmlib.diff | 1417 |
1 files changed, 1417 insertions, 0 deletions
diff --git a/extra/wxpython/editra-ebmlib.diff b/extra/wxpython/editra-ebmlib.diff new file mode 100644 index 000000000..7b4c90471 --- /dev/null +++ b/extra/wxpython/editra-ebmlib.diff @@ -0,0 +1,1417 @@ +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/setup.py wxPython-src-2.8.10.1/wxPython/setup.py +--- wxPython-src-2.8.10.1-orig/wxPython/setup.py 2009-06-06 14:43:00.000000000 -0400 ++++ wxPython-src-2.8.10.1/wxPython/setup.py 2009-06-06 14:43:55.000000000 -0400 +@@ -882,6 +882,7 @@ + 'wx.tools.Editra', + 'wx.tools.Editra.src', + 'wx.tools.Editra.src.autocomp', ++ 'wx.tools.Editra.src.ebmlib', + 'wx.tools.Editra.src.eclib', + 'wx.tools.Editra.src.extern', + 'wx.tools.Editra.src.syntax', +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/__init__.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/__init__.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/__init__.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/__init__.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,33 @@ ++############################################################################### ++# Name: __init__.py # ++# Purpose: Editra Buisness Model Library # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__cvsid__ = "$Id: __init__.py 60840 2009-05-31 16:00:50Z CJP $" ++__revision__ = "$Revision: 60840 $" ++ ++#-----------------------------------------------------------------------------# ++ ++# Text Utils ++from searcheng import * ++from fchecker import * ++from fileutil import * ++from fileimpl import * ++ ++from backupmgr import * ++ ++# Storage Classes ++from histcache import * ++from clipboard import * ++ ++# Misc ++from miscutil import * +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/backupmgr.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/backupmgr.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/backupmgr.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/backupmgr.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,160 @@ ++############################################################################### ++# Name: backupmgr.py # ++# Purpose: File Backup Manager # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: FileBackupMgr ++ ++Helper class for managing and creating backups of files. ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__cvsid__ = "$Id: backupmgr.py 60581 2009-05-10 02:56:00Z CJP $" ++__revision__ = "$Revision: 60581 $" ++ ++__all__ = [ 'FileBackupMgr', ] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++import os ++import shutil ++ ++# Local Imports ++import fileutil ++import fchecker ++ ++#-----------------------------------------------------------------------------# ++ ++class FileBackupMgr(object): ++ """File backup creator and manager""" ++ def __init__(self, header=None, template=u"%s~"): ++ """Create a BackupManager ++ @keyword header: header to id backups with (Text files only!!) ++ @keyword template: template string for naming backup file with ++ ++ """ ++ object.__init__(self) ++ ++ # Attributes ++ self.checker = fchecker.FileTypeChecker() ++ self.header = header # Backup id header ++ self.template = template # Filename template ++ ++ def _CheckHeader(self, fname): ++ """Check if the backup file has a header that matches the ++ header used to identify backup files. ++ @param fname: name of file to check ++ @return: bool (True if header is ok, False otherwise) ++ ++ """ ++ isok = False ++ try: ++ handle = open(fname) ++ line = handle.readline() ++ isok = line.startswith(self.header) ++ except: ++ isok = False ++ finally: ++ handle.close() ++ return isok ++ ++ def GetBackupFilename(self, fname): ++ """Get the unique name for the files backup copy ++ @param fname: string (file path) ++ @return: string ++ ++ """ ++ rname = self.template % fname ++ if self.header is not None and \ ++ not self.checker.IsBinary(fname) and \ ++ os.path.exists(rname): ++ # Make sure that the template backup name does not match ++ # an existing file that is not a backup file. ++ while not self._CheckHeader(rname): ++ rname = self.template % rname ++ ++ return rname ++ ++ def GetBackupWriter(self, fileobj): ++ """Create a backup filewriter method to backup a files contents ++ with. ++ @param fileobj: object implementing fileimpl.FileObjectImpl interface ++ @return: callable(text) to create backup with ++ ++ """ ++ nfile = fileobj.Clone() ++ fname = self.GetBackupFilename(nfile.GetPath()) ++ nfile.SetPath(fname) ++ # Write the header if it is enabled ++ if self.header is not None and not self.checker.IsBinary(fname): ++ nfile.Write(self.header + os.linesep) ++ return nfile.Write ++ ++ def HasBackup(self, fname): ++ """Check if a given file has a backup file available or not ++ @param fname: string (file path) ++ ++ """ ++ backup = self.GetBackupFilename(fname) ++ return os.path.exists(backup) ++ ++ def IsBackupNewer(self, fname): ++ """Is the backup of this file newer than the saved version ++ of the file? ++ @param fname: string (file path) ++ @return: bool ++ ++ """ ++ backup = self.GetBackupFilename(fname) ++ if os.path.exists(fname) and os.path.exists(backup): ++ mod1 = fileutil.GetFileModTime(backup) ++ mod2 = fileutil.GetFileModTime(fname) ++ return mod1 > mod2 ++ else: ++ return False ++ ++ def MakeBackupCopy(self, fname): ++ """Create a backup copy of the given filename ++ @param fname: string (file path) ++ @return: bool (True == Success) ++ ++ """ ++ backup = self.GetBackupFilename(fname) ++ try: ++ if os.path.exists(backup): ++ os.remove(backup) ++ ++ shutil.copy2(fname, backup) ++ except: ++ return False ++ else: ++ return True ++ ++ def MakeBackupCopyAsync(self, fname): ++ """Do the backup asyncronously ++ @param fname: string (file path) ++ @todo: Not implemented yet ++ ++ """ ++ raise NotImplementedError("TODO: implement once threadpool is finished") ++ ++ def SetBackupFileTemplate(self, tstr): ++ """Set the filename template for generating the backupfile name ++ @param tstr: template string i.e) %s~ ++ ++ """ ++ assert tstr.count("%s") == 1, "Format statment must only have one arg" ++ self.template = tstr ++ ++ def SetHeader(self, header): ++ """Set the header string for identifying a file as a backup ++ @param header: string (single line only) ++ ++ """ ++ assert '\n' not in header, "Header must only be a single line" ++ self.header = header +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/clipboard.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/clipboard.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/clipboard.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/clipboard.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,135 @@ ++############################################################################### ++# Name: histcache.py # ++# Purpose: History Cache # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: Clipboard ++ ++Clipboard helper class ++ ++""" ++ ++__author__ = "Hasan Aljudy" ++__cvsid__ = "$Id: clipboard.py 60681 2009-05-17 10:41:42Z CJP $" ++__revision__ = "$Revision: 60681 $" ++ ++__all__ = [ 'Clipboard',] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++import wx ++ ++#-----------------------------------------------------------------------------# ++ ++class Clipboard(object): ++ """Multiple clipboards as named registers (as per vim) ++ ++ " is an alias for system clipboard and is also the default clipboard. ++ ++ @note: The only way to access multiple clipboards right now is through ++ Normal mode when Vi(m) emulation is enabled. ++ ++ """ ++ NAMES = list(u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_') ++ registers = {} ++ current = u'"' ++ ++ @classmethod ++ def Switch(cls, reg): ++ """Switch to register ++ @param reg: char ++ ++ """ ++ if reg in cls.NAMES or reg == u'"': ++ cls.current = reg ++ else: ++ raise Exception(u"Switched to invalid register name") ++ ++ @classmethod ++ def NextFree(cls, reg): ++ """Switch to the next free register. If current register is free, no ++ switching happens. ++ ++ A free register is one that's either unused or has no content ++ ++ @param reg: char ++ @note: This is not used yet. ++ ++ """ ++ if cls.Get() == u'': ++ return ++ ++ for name in cls.NAMES: ++ if cls.registers.get(name, u'') == u'': ++ cls.Switch(name) ++ break ++ ++ @classmethod ++ def AllUsed(cls): ++ """Get a dictionary mapping all used clipboards (plus the system ++ clipboard) to their content. ++ ++ @note: This is not used yet. ++ ++ """ ++ cmd_map = { u'"': cls.SystemGet() } ++ for name in cls.NAMES: ++ if cls.registers.get(name, u''): ++ cmd_map[name] = cls.registers[name] ++ return cmd_map ++ ++ @classmethod ++ def Get(cls): ++ """Get the content of the current register. Used for pasting""" ++ if cls.current == u'"': ++ return cls.SystemGet() ++ else: ++ return cls.registers.get( cls.current, u'' ) ++ ++ @classmethod ++ def Set(cls, text): ++ """Set the content of the current register ++ @param text: string ++ ++ """ ++ if cls.current == u'"': ++ return cls.SystemSet(text) ++ else: ++ cls.registers[cls.current] = text ++ ++ @classmethod ++ def SystemGet(cls): ++ """Get text from the system clipboard ++ @return: string ++ ++ """ ++ text = None ++ if wx.TheClipboard.Open(): ++ if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)): ++ text = wx.TextDataObject() ++ wx.TheClipboard.GetData(text) ++ ++ wx.TheClipboard.Close() ++ ++ if text is not None: ++ return text.GetText() ++ else: ++ return u'' ++ ++ @classmethod ++ def SystemSet(cls, text): ++ """Set text into the system clipboard ++ @param text: string ++ @return: bool ++ ++ """ ++ ok = False ++ if wx.TheClipboard.Open(): ++ wx.TheClipboard.SetData(wx.TextDataObject(text)) ++ wx.TheClipboard.Close() ++ ok = True ++ return ok +\ No newline at end of file +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/fchecker.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/fchecker.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/fchecker.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/fchecker.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,82 @@ ++############################################################################### ++# Name: fchecker.py # ++# Purpose: Filetype checker object. # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: FileTypeChecker ++ ++Helper class for checking what kind of a content a file contains. ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__cvsid__ = "$Id: fchecker.py 60505 2009-05-03 19:18:21Z CJP $" ++__revision__ = "$Revision: 60505 $" ++ ++__all__ = [ 'FileTypeChecker', ] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++import os ++ ++#-----------------------------------------------------------------------------# ++ ++class FileTypeChecker(object): ++ """File type checker and recognizer""" ++ TXTCHARS = ''.join(map(chr, [7, 8, 9, 10, 12, 13, 27] + range(0x20, 0x100))) ++ ALLBYTES = ''.join(map(chr, range(256))) ++ ++ def __init__(self, preread=4096): ++ """Create the FileTypeChecker ++ @keyword preread: number of bytes to read for checking file type ++ ++ """ ++ object.__init__(self) ++ ++ # Attributes ++ self._preread = preread ++ ++ @staticmethod ++ def _GetHandle(fname): ++ """Get a file handle for reading ++ @param fname: filename ++ @return: file object or None ++ ++ """ ++ try: ++ handle = open(fname, 'rb') ++ except: ++ handle = None ++ return handle ++ ++ def IsBinary(self, fname): ++ """Is the file made up of binary data ++ @param fname: filename to check ++ @return: bool ++ ++ """ ++ handle = self._GetHandle(fname) ++ if handle is not None: ++ bytes = handle.read(self._preread) ++ handle.close() ++ nontext = bytes.translate(FileTypeChecker.ALLBYTES, ++ FileTypeChecker.TXTCHARS) ++ return bool(nontext) ++ else: ++ return False ++ ++ def IsReadableText(self, fname): ++ """Is the given path readable as text. Will return True if the ++ file is accessable by current user and is plain text. ++ @param fname: filename ++ @return: bool ++ ++ """ ++ f_ok = False ++ if os.access(fname, os.R_OK): ++ f_ok = not self.IsBinary(fname) ++ return f_ok +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/fileimpl.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/fileimpl.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/fileimpl.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/fileimpl.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,215 @@ ++############################################################################### ++# Name: Cody Precord # ++# Purpose: File Object Interface Implementation # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# License: wxWindows License # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: FileObjectImpl ++ ++Implementation of a file object interface class. Objects and methods inside ++of this library expect a file object that derives from this interface. ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__svnid__ = "$Id: fileimpl.py 60582 2009-05-10 04:24:30Z CJP $" ++__revision__ = "$Revision: 60582 $" ++ ++#--------------------------------------------------------------------------# ++# Imports ++import os ++ ++# Editra Buisness Model Imports ++import fileutil ++ ++#--------------------------------------------------------------------------# ++ ++class FileObjectImpl(object): ++ """File Object Interface implementation base class""" ++ def __init__(self, path=u'', modtime=0): ++ object.__init__(self) ++ ++ # Attributes ++ self._path = path ++ self._modtime = modtime ++ ++ self._handle = None ++ self.open = False ++ ++ self.last_err = None ++ ++ def ClearLastError(self): ++ """Reset the error marker on this file""" ++ del self.last_err ++ self.last_err = None ++ ++ def Clone(self): ++ """Clone the file object ++ @return: FileObject ++ ++ """ ++ fileobj = FileObjectImpl(self._path, self._modtime) ++ fileobj.SetLastError(self.last_err) ++ return fileobj ++ ++ def Close(self): ++ """Close the file handle ++ @note: this is normally done automatically after a read/write operation ++ ++ """ ++ try: ++ self._handle.close() ++ except: ++ pass ++ ++ self.open = False ++ ++ def DoOpen(self, mode): ++ """Opens and creates the internal file object ++ @param mode: mode to open file in ++ @return: True if opened, False if not ++ @postcondition: self._handle is set to the open handle ++ ++ """ ++ if not len(self._path): ++ return False ++ ++ try: ++ file_h = open(self._path, mode) ++ except (IOError, OSError), msg: ++ self.last_err = msg ++ return False ++ else: ++ self._handle = file_h ++ self.open = True ++ return True ++ ++ def GetExtension(self): ++ """Get the files extension if it has one else simply return the ++ filename minus the path. ++ @return: string file extension (no dot) ++ ++ """ ++ fname = os.path.split(self._path) ++ return fname[-1].split(os.extsep)[-1].lower() ++ ++ def GetHandle(self): ++ """Get this files handle""" ++ return self._handle ++ ++ def GetLastError(self): ++ """Return the last error that occured when using this file ++ @return: err traceback or None ++ ++ """ ++ return unicode(self.last_err).replace("u'", "'") ++ ++ def GetModtime(self): ++ """Get the timestamp of this files last modification""" ++ return self._modtime ++ ++ def GetPath(self): ++ """Get the path of the file ++ @return: string ++ ++ """ ++ return self._path ++ ++ def GetSize(self): ++ """Get the size of the file ++ @return: int ++ ++ """ ++ if self._path: ++ return fileutil.GetFileSize(self._path) ++ else: ++ return 0 ++ ++ @property ++ def Handle(self): ++ """Raw file handle property""" ++ return self._handle ++ ++ def IsOpen(self): ++ """Check if file is open or not ++ @return: bool ++ ++ """ ++ return self.open ++ ++ def IsReadOnly(self): ++ """Is the file Read Only ++ @return: bool ++ ++ """ ++ if os.path.exists(self._path): ++ return not os.access(self._path, os.R_OK|os.W_OK) ++ else: ++ return False ++ ++ @property ++ def Modtime(self): ++ """File modification time propery""" ++ return self.GetModtime() ++ ++ @property ++ def ReadOnly(self): ++ """Is the file read only?""" ++ return self.IsReadOnly() ++ ++ def ResetAll(self): ++ """Reset all file attributes""" ++ self._handle = None ++ self.open = False ++ self._path = u'' ++ self._modtime = 0 ++ self.last_err = None ++ ++ def SetLastError(self, err): ++ """Set the last error ++ @param err: exception object / msg ++ ++ """ ++ self.last_err = err ++ ++ def SetPath(self, path): ++ """Set the path of the file ++ @param path: absolute path to file ++ ++ """ ++ self._path = path ++ ++ def SetModTime(self, mtime): ++ """Set the modtime of this file ++ @param mtime: long int to set modtime to ++ ++ """ ++ self._modtime = mtime ++ ++ #--- SHould be overridden by subclass ---# ++ ++ def Read(self): ++ """Open/Read the file ++ @return: string (file contents) ++ ++ """ ++ txt = u'' ++ if self.DoOpen('rb'): ++ try: ++ txt = self._handle.read() ++ except: ++ pass ++ ++ return txt ++ ++ def Write(self, value): ++ """Open/Write the value to disk ++ @param value: string ++ ++ """ ++ if self.DoOpen('wb'): ++ self._handle.write(value) ++ self._handle.close() +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/fileutil.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/fileutil.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/fileutil.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/fileutil.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,180 @@ ++############################################################################### ++# Name: fileutil.py # ++# Purpose: File Management Utilities. # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: File Utilities ++ ++Utility functions for managing and working with files. ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__svnid__ = "$Id: fileutil.py 60523 2009-05-05 18:49:31Z CJP $" ++__revision__ = "$Revision: 60523 $" ++ ++__all__ = [ 'GetFileModTime', 'GetFileSize', 'GetUniqueName', 'MakeNewFile', ++ 'MakeNewFolder', 'GetFileExtension', 'GetFileName', 'GetPathName', ++ 'ResolveRealPath', 'IsLink' ] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++import os ++import platform ++import stat ++ ++UNIX = WIN = False ++if platform.system().lower() in ['windows', 'microsoft']: ++ WIN = True ++ try: ++ # Check for if win32 extensions are available ++ import win32com.client as win32client ++ except ImportError: ++ win32client = None ++else: ++ UNIX = True ++ ++#-----------------------------------------------------------------------------# ++ ++def GetFileExtension(file_str): ++ """Gets last atom at end of string as extension if ++ no extension whole string is returned ++ @param file_str: path or file name to get extension from ++ ++ """ ++ return file_str.split('.')[-1] ++ ++def GetFileModTime(file_name): ++ """Returns the time that the given file was last modified on ++ @param file_name: path of file to get mtime of ++ ++ """ ++ try: ++ mod_time = os.path.getmtime(file_name) ++ except (OSError, EnvironmentError): ++ mod_time = 0 ++ return mod_time ++ ++def GetFileName(path): ++ """Gets last atom on end of string as filename ++ @param path: full path to get filename from ++ ++ """ ++ return os.path.split(path)[-1] ++ ++def GetFileSize(path): ++ """Get the size of the file at a given path ++ @param path: Path to file ++ @return: long ++ ++ """ ++ try: ++ return os.stat(path)[stat.ST_SIZE] ++ except: ++ return 0 ++ ++def GetPathName(path): ++ """Gets the path minus filename ++ @param path: full path to get base of ++ ++ """ ++ return os.path.split(path)[0] ++ ++def IsLink(path): ++ """Is the file a link ++ @return: bool ++ ++ """ ++ if WIN: ++ return path.endswith(".lnk") or os.path.islink(path) ++ else: ++ return os.path.islink(path) ++ ++def ResolveRealPath(link): ++ """Return the real path of the link file ++ @param link: path of link file ++ @return: string ++ ++ """ ++ assert IsLink(link), "ResolveRealPath expects a link file!" ++ realpath = link ++ if WIN and win32client is not None: ++ shell = win32client.Dispatch("WScript.Shell") ++ shortcut = shell.CreateShortCut(link) ++ realpath = shortcut.Targetpath ++ else: ++ realpath = os.path.realpath(link) ++ return realpath ++ ++#-----------------------------------------------------------------------------# ++ ++def GetUniqueName(path, name): ++ """Make a file name that will be unique in case a file of the ++ same name already exists at that path. ++ @param path: Root path to folder of files destination ++ @param name: desired file name base ++ @return: string ++ ++ """ ++ tmpname = os.path.join(path, name) ++ if os.path.exists(tmpname): ++ if '.' not in name: ++ ext = '' ++ fbase = name ++ else: ++ ext = '.' + name.split('.')[-1] ++ fbase = name[:-1 * len(ext)] ++ ++ inc = len([x for x in os.listdir(path) if x.startswith(fbase)]) ++ tmpname = os.path.join(path, "%s-%d%s" % (fbase, inc, ext)) ++ while os.path.exists(tmpname): ++ inc = inc + 1 ++ tmpname = os.path.join(path, "%s-%d%s" % (fbase, inc, ext)) ++ ++ return tmpname ++ ++ ++#-----------------------------------------------------------------------------# ++ ++def MakeNewFile(path, name): ++ """Make a new file at the given path with the given name. ++ If the file already exists, the given name will be changed to ++ a unique name in the form of name + -NUMBER + .extension ++ @param path: path to directory to create file in ++ @param name: desired name of file ++ @return: Tuple of (success?, Path of new file OR Error message) ++ ++ """ ++ if not os.path.isdir(path): ++ path = os.path.dirname(path) ++ fname = GetUniqueName(path, name) ++ ++ try: ++ open(fname, 'w').close() ++ except (IOError, OSError), msg: ++ return (False, str(msg)) ++ ++ return (True, fname) ++ ++def MakeNewFolder(path, name): ++ """Make a new folder at the given path with the given name. ++ If the folder already exists, the given name will be changed to ++ a unique name in the form of name + -NUMBER. ++ @param path: path to create folder on ++ @param name: desired name for folder ++ @return: Tuple of (success?, new dirname OR Error message) ++ ++ """ ++ if not os.path.isdir(path): ++ path = os.path.dirname(path) ++ folder = GetUniqueName(path, name) ++ try: ++ os.mkdir(folder) ++ except (OSError, IOError), msg: ++ return (False, str(msg)) ++ ++ return (True, folder) +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/histcache.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/histcache.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/histcache.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/histcache.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,131 @@ ++############################################################################### ++# Name: histcache.py # ++# Purpose: History Cache # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: HistoryCache ++ ++History cache that acts as a stack for managing a history list o ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__cvsid__ = "$Id: histcache.py 60613 2009-05-13 02:27:21Z CJP $" ++__revision__ = "$Revision: 60613 $" ++ ++__all__ = [ 'HistoryCache', 'HIST_CACHE_UNLIMITED'] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++ ++#-----------------------------------------------------------------------------# ++# Globals ++HIST_CACHE_UNLIMITED = -1 ++ ++#-----------------------------------------------------------------------------# ++ ++class HistoryCache(object): ++ def __init__(self, max_size=HIST_CACHE_UNLIMITED): ++ object.__init__(self) ++ ++ # Attributes ++ self._list = list() ++ self.cpos = -1 ++ self.max_size = max_size ++ ++ def _Resize(self): ++ """Adjust cache size based on max size setting""" ++ if self.max_size != HIST_CACHE_UNLIMITED: ++ lsize = len(self._list) ++ if lsize: ++ adj = self.max_size - lsize ++ if adj < 0: ++ self._list.pop(0) ++ self.cpos = len(self._list) - 1 ++ ++ def Clear(self): ++ """Clear the history cache""" ++ del self._list ++ self._list = list() ++ self.cpos = -1 ++ ++ def GetSize(self): ++ """Get the current size of the cache ++ @return: int (number of items in the cache) ++ ++ """ ++ return len(self._list) ++ ++ def GetMaxSize(self): ++ """Get the max size of the cache ++ @return: int ++ ++ """ ++ return self.max_size ++ ++ def GetNextItem(self): ++ """Get the next item in the history cache, moving the ++ current postion towards the end of the cache. ++ @return: object or None if at end of list ++ ++ """ ++ item = None ++ if self.cpos < len(self._list) - 1: ++ self.cpos += 1 ++ item = self._list[self.cpos] ++ return item ++ ++ def GetPreviousItem(self): ++ """Get the previous item in the history cache, moving the ++ current postion towards the begining of the cache. ++ @return: object or None if at start of list ++ ++ """ ++ item = None ++ if self.cpos >= 0: ++ item = self._list[self.cpos] ++ self.cpos -= 1 ++ return item ++ ++ def HasPrevious(self): ++ """Are there more items to the left of the current position ++ @return: bool ++ ++ """ ++ more = self.cpos >= 0 ++ return more ++ ++ def HasNext(self): ++ """Are there more items to the right of the current position ++ @return: bool ++ ++ """ ++ if self.cpos == -1 and len(self._list): ++ more = True ++ else: ++ more = self.cpos >= 0 and self.cpos < len(self._list) ++ return more ++ ++ def PutItem(self, item): ++ """Put an item on the top of the cache ++ @param item: object ++ ++ """ ++ if self.cpos != len(self._list) - 1: ++ self._list = self._list[:self.cpos] ++ self._list.append(item) ++ self.cpos += 1 ++ self._Resize() ++ ++ def SetMaxSize(self, max_size): ++ """Set the maximum size of the cache ++ @param max_size: int (HIST_CACHE_UNLIMITED for unlimited size) ++ ++ """ ++ assert max_size > 0 or max_size == 1, "Invalid max size" ++ self.max_size = max_size ++ self._Resize() +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/miscutil.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/miscutil.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/miscutil.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/miscutil.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,33 @@ ++############################################################################### ++# Name: miscutil.py # ++# Purpose: Various helper functions. # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: MiscUtil ++ ++Various helper functions ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__cvsid__ = "$Id: miscutil.py 60840 2009-05-31 16:00:50Z CJP $" ++__revision__ = "$Revision: 60840 $" ++ ++__all__ = [ 'MinMax', ] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++ ++#-----------------------------------------------------------------------------# ++ ++def MinMax(arg1, arg2): ++ """Return an ordered tuple of the minumum and maximum value ++ of the two args. ++ @return: tuple ++ ++ """ ++ return min(arg1, arg2), max(arg1, arg2) +diff -Naur wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/searcheng.py wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/searcheng.py +--- wxPython-src-2.8.10.1-orig/wxPython/wx/tools/Editra/src/ebmlib/searcheng.py 1969-12-31 19:00:00.000000000 -0500 ++++ wxPython-src-2.8.10.1/wxPython/wx/tools/Editra/src/ebmlib/searcheng.py 2009-06-06 03:48:10.000000000 -0400 +@@ -0,0 +1,400 @@ ++############################################################################### ++# Name: searcheng.py # ++# Purpose: Text search engine and utilities # ++# Author: Cody Precord <cprecord@editra.org> # ++# Copyright: (c) 2009 Cody Precord <staff@editra.org> # ++# Licence: wxWindows Licence # ++############################################################################### ++ ++""" ++Editra Buisness Model Library: SearchEngine ++ ++Text Search Engine for finding text and grepping files ++ ++""" ++ ++__author__ = "Cody Precord <cprecord@editra.org>" ++__cvsid__ = "$Id: searcheng.py 60680 2009-05-17 20:31:58Z CJP $" ++__revision__ = "$Revision: 60680 $" ++ ++__all__ = [ 'SearchEngine', ] ++ ++#-----------------------------------------------------------------------------# ++# Imports ++import os ++import re ++import fnmatch ++import types ++from StringIO import StringIO ++ ++# Local imports ++import fchecker ++ ++#-----------------------------------------------------------------------------# ++ ++class SearchEngine(object): ++ """Text Search Engine ++ All Search* methods are iterable generators ++ All Find* methods do a complete search and return the match collection ++ @summary: Text Search Engine ++ @todo: Add file filter support ++ ++ """ ++ def __init__(self, query, regex=True, down=True, ++ matchcase=True, wholeword=False): ++ """Initialize a search engine object ++ @param query: search string ++ @keyword regex: Is a regex search ++ @keyword down: Search down or up ++ @keyword matchcase: Match case ++ @keyword wholeword: Match whole word ++ ++ """ ++ object.__init__(self) ++ ++ # Attributes ++ self._isregex = regex ++ self._next = down ++ self._matchcase = matchcase ++ self._wholeword = wholeword ++ self._unicode = False ++ self._query = query ++ self._regex = u'' ++ self._pool = u'' ++ self._lmatch = None # Last match object ++ self._filters = None # File Filters ++ self._formatter = lambda f, l, m: u"%s %d: %s" % (f, l+1, m) ++ self._CompileRegex() ++ ++ def _CompileRegex(self): ++ """Prepare and compile the regex object based on the current state ++ and settings of the engine. ++ @postcondition: the engines regular expression is created ++ ++ """ ++ tmp = self._query ++ if not self._isregex: ++ tmp = re.escape(tmp) ++ ++ if self._wholeword: ++ tmp = "\\b%s\\b" % tmp ++ ++ flags = re.MULTILINE ++ ++ if not self._matchcase: ++ flags |= re.IGNORECASE ++ ++ if self._unicode: ++ flags |= re.UNICODE ++ ++ try: ++ self._regex = re.compile(tmp, flags) ++ except: ++ self._regex = None ++ ++ def ClearPool(self): ++ """Clear the search pool""" ++ del self._pool ++ self._pool = u"" ++ ++ def Find(self, spos=0): ++ """Find the next match based on the state of the search engine ++ @keyword spos: search start position ++ @return: tuple (match start pos, match end pos) or None if no match ++ @note: L{SetSearchPool} has been called to set search string ++ ++ """ ++ if self._regex is None: ++ return None ++ ++ if self._next: ++ return self.FindNext(spos) ++ else: ++ if spos == 0: ++ spos = -1 ++ return self.FindPrev(spos) ++ ++ def FindAll(self): ++ """Find all the matches in the current context ++ @return: list of tuples [(start1, end1), (start2, end2), ] ++ ++ """ ++ if self._regex is None: ++ return list() ++ ++ matches = [match for match in self._regex.finditer(self._pool)] ++ return matches ++ ++ def FindAllLines(self): ++ """Find all the matches in the current context ++ @return: list of strings ++ ++ """ ++ rlist = list() ++ if self._regex is None: ++ return rlist ++ ++ for lnum, line in enumerate(StringIO(self._pool)): ++ if self._regex.search(line) is not None: ++ rlist.append(self._formatter(u"Untitled", lnum, line)) ++ ++ return rlist ++ ++ def FindNext(self, spos=0): ++ """Find the next match of the query starting at spos ++ @keyword spos: search start position in string ++ @return: tuple (match start pos, match end pos) or None if no match ++ @note: L{SetSearchPool} has been called to set the string to search in. ++ ++ """ ++ if self._regex is None: ++ return None ++ ++ if spos < len(self._pool): ++ match = self._regex.search(self._pool[spos:]) ++ if match is not None: ++ self._lmatch = match ++ return match.span() ++ return None ++ ++ def FindPrev(self, spos=-1): ++ """Find the previous match of the query starting at spos ++ @keyword spos: search start position in string ++ @return: tuple (match start pos, match end pos) ++ ++ """ ++ if self._regex is None: ++ return None ++ ++ if spos+1 < len(self._pool): ++ matches = [match for match in ++ self._regex.finditer(self._pool[:spos])] ++ if len(matches): ++ lmatch = matches[-1] ++ self._lmatch = lmatch ++ return (lmatch.start(), lmatch.end()) ++ return None ++ ++ def GetLastMatch(self): ++ """Get the last found match object from the previous L{FindNext} or ++ L{FindPrev} action. ++ @return: match object or None ++ ++ """ ++ return self._lmatch ++ ++ def GetOptionsString(self): ++ """Get a string describing the search engines options""" ++ rstring = u"\"%s\" [ " % self._query ++ for desc, attr in (("regex: %s", self._isregex), ++ ("match case: %s", self._matchcase), ++ ("whole word: %s", self._wholeword)): ++ if attr: ++ rstring += (desc % u"on; ") ++ else: ++ rstring += (desc % u"off; ") ++ rstring += u"]" ++ ++ return rstring ++ ++ def GetQuery(self): ++ """Get the raw query string used by the search engine ++ @return: string ++ ++ """ ++ return self._query ++ ++ def GetQueryObject(self): ++ """Get the regex object used for the search. Will return None if ++ there was an error in creating the object. ++ @return: pattern object ++ ++ """ ++ return self._regex ++ ++ def GetSearchPool(self): ++ """Get the search pool string for this L{SearchEngine}. ++ @return: string ++ ++ """ ++ return self._pool ++ ++ def IsMatchCase(self): ++ """Is the engine set to a case sensitive search ++ @return: bool ++ ++ """ ++ return self._matchcase ++ ++ def IsRegEx(self): ++ """Is the engine searching with the query as a regular expression ++ @return: bool ++ ++ """ ++ return self._isregex ++ ++ def IsWholeWord(self): ++ """Is the engine set to search for wholeword matches ++ @return: bool ++ ++ """ ++ return self._wholeword ++ ++ def SearchInBuffer(self, sbuffer): ++ """Search in the buffer ++ @param sbuffer: buffer like object ++ @todo: implement ++ ++ """ ++ raise NotImplementedError ++ ++ def SearchInDirectory(self, directory, recursive=True): ++ """Search in all the files found in the given directory ++ @param directory: directory path ++ @keyword recursive: search recursivly ++ ++ """ ++ if self._regex is None: ++ return ++ ++ # Get all files in the directories ++ paths = [os.path.join(directory, fname) ++ for fname in os.listdir(directory) if not fname.startswith('.')] ++ ++ # Filter out files that don't match the current filter(s) ++ if self._filters is not None and len(self._filters): ++ filtered = list() ++ for fname in paths: ++ if os.path.isdir(fname): ++ filtered.append(fname) ++ continue ++ ++ for pat in self._filters: ++ if fnmatch.fnmatch(fname, pat): ++ filtered.append(fname) ++ paths = filtered ++ ++ # Begin searching in the paths ++ for path in paths: ++ if recursive and os.path.isdir(path): ++ # Recursive call to decend into directories ++ for match in self.SearchInDirectory(path, recursive): ++ yield match ++ else: ++ for match in self.SearchInFile(path): ++ yield match ++ return ++ ++ def SearchInFile(self, fname): ++ """Search in a file for all lines with matches of the set query and ++ yield the results as they are found. ++ @param fname: filename ++ @todo: unicode handling ++ ++ """ ++ if self._regex is None: ++ return ++ ++ checker = fchecker.FileTypeChecker() ++ if checker.IsReadableText(fname): ++ try: ++ fobj = open(fname, 'rb') ++ except (IOError, OSError): ++ return ++ else: ++ # Special token to signify start of a search ++ yield (None, fname) ++ ++ for lnum, line in enumerate(fobj): ++ if self._regex.search(line) is not None: ++ yield self._formatter(fname, lnum, line) ++ fobj.close() ++ return ++ ++ def SearchInFiles(self, flist): ++ """Search in a list of files and yield results as they are found. ++ @param flist: list of file names ++ ++ """ ++ if self._regex is None: ++ return ++ ++ for fname in flist: ++ for match in self.SearchInFile(fname): ++ yield match ++ return ++ ++ def SearchInString(self, sstring, startpos=0): ++ """Search in a string ++ @param sstring: string to search in ++ @keyword startpos: search start position ++ ++ """ ++ raise NotImplementedError ++ ++ def SetFileFilters(self, filters): ++ """Set the file filters to specify what type of files to search in ++ the filter should be a list of wild card patterns to match. ++ @param filters: list of strings ['*.py', '*.pyw'] ++ ++ """ ++ self._filters = filters ++ ++ def SetFlags(self, isregex=None, matchcase=None, wholeword=None, down=None): ++ """Set the search engine flags. Leaving the parameter set to None ++ will not change the flag. Setting it to non None will change the value. ++ @keyword isregex: is regex search ++ @keyword matchcase: matchcase search ++ @keyword wholeword: wholeword search ++ @keyword down: search down or up ++ ++ """ ++ for attr, val in (('_isregex', isregex), ('_matchcase', matchcase), ++ ('_wholeword', wholeword), ('_next', down)): ++ if val is not None: ++ setattr(self, attr, val) ++ self._CompileRegex() ++ ++ def SetMatchCase(self, case=True): ++ """Set whether the engine will use case sensative searches ++ @keyword case: bool ++ ++ """ ++ self._matchcase = case ++ self._CompileRegex() ++ ++ def SetResultFormatter(self, funct): ++ """Set the result formatter function ++ @param funct: callable(filename, linenum, matchstr) ++ ++ """ ++ assert callable(funct) ++ self._formatter = funct ++ ++ def SetSearchPool(self, pool): ++ """Set the search pool used by the Find methods ++ @param pool: string to search in ++ ++ """ ++ del self._pool ++ self._pool = pool ++ if isinstance(self._pool, types.UnicodeType): ++ self._unicode = True ++ self._CompileRegex() ++ ++ def SetQuery(self, query): ++ """Set the search query ++ @param query: string ++ ++ """ ++ self._query = query ++ self._CompileRegex() ++ ++ def SetUseRegex(self, use=True): ++ """Set whether the engine is using regular expresion searches or ++ not. ++ @keyword use: bool ++ ++ """ ++ self._isregex = use ++ self._CompileRegex() |