Source

codeaide / codeaide / base.py

import re

from PyQt4.QtCore import (
    Qt, QString, SIGNAL, QVariant, QThread, QLine, QSize, QRect, QTimer,
    QAbstractListModel, QModelIndex)
from PyQt4.QtGui import (
    QApplication, QWidget, QHBoxLayout, QToolTip,
    QTextBlockUserData, QPlainTextEdit, QCompleter, QTextCursor, 
    QColor, QBrush, QPainter, QPen, QPalette, QTextEdit, QTextFormat)



def command(func):
    """
    decorator to declare a method as an editor command
    """
    func.is_command = True
    return func



def class_members(cls):
    names = dir(cls)
    if hasattr(cls,'__bases__'):
        for base in cls.__bases__:
            names.extend(class_members(base))
    return list(set(names))


def members(obj):
    names = dir(obj)
    cls = getattr(obj, "__class__")
    names.extend(class_members(cls))
    return list(set(names))

    

class ModeBase(object):

    keyboard_hooks = {
        }
    paint_hook = None
    resize_hook = None
    state = 0
    name = None
    requires = []


    
    @classmethod
    def find(cls, mode):
        for subcls in cls.__subclasses__():
            if isinstance(mode, basestring):
                if subcls.__name__ == mode:
                    return subcls
            else:
                if subcls is mode:
                    return subcls
            found = subcls.find(mode)
            if found:
                return found


    def __init__(self, textedit, *args, **kwargs):
        for required_mode in self.requires:
            textedit.install(required_mode)
        self.textedit = textedit
        self.init(*args, **kwargs)
        self.install_hooks()


    def init(self):
        pass


    def install_hooks(self):
        self.install_keyboard_hooks()
        self.install_paint_hook()
        self.install_resize_hook()


    def install_keyboard_hooks(self):
        import functools
        for key, callback in self.keyboard_hooks.items():
            if isinstance(key, tuple):
                key, modifiers = key
            else:
                modifiers = -1
            h = self.textedit.keyboard_hooks.setdefault(self.state, {})
            bound_method = functools.partial(callback, self)
            h.setdefault((key, int(modifiers)), []).append(bound_method)


    def install_paint_hook(self):
        callback = self.paint_hook
        if callback:
            bound_method = callback
            #bound_method = \
            #    lambda *args, **kwargs: callback(self, *args, **kwargs)
            h = self.textedit.paint_hooks
            h.setdefault(self.state, []).append(bound_method)

        
    def install_resize_hook(self):
        callback = self.resize_hook
        if callback:
            bound_method = callback
            h = self.textedit.resize_hooks
            h.setdefault(self.state, []).append(bound_method)