示例#1
0
    def __init__(self, app):

        self._app = app
        self._info = {}
        self._enabled = False
        self.type = "system"
        self.enabled = Listeners()
示例#2
0
    def __init__(self, pref_dir=None):
        Pref.__init__(self)
        if pref_dir is None:
            self._pref_dir = get_user_pref_dir()
        else:
            self._pref_dir = pref_dir

        # listener
        self.changed = Listeners()
示例#3
0
 def __init__(self, app):
     
     self._app = app
     self._info = {}
     self._enabled = False
     self.type = "system"
     self.enabled = Listeners()
示例#4
0
    def __init__(self, rootdir=None):
        """rootdir -- Root directory of notebook"""

        NoteBookDir.__init__(self, rootdir, notebook=self)
        self.pref = NoteBookPreferences()
        if rootdir is not None:
            self._attr["title"] = os.path.basename(rootdir)
        else:
            self._attr["title"] = None
        self._dirty = set()
        self._trash = None

        self._attr["order"] = 0

        # init notebook attributes
        self._init_default_attr()

        # init trash
        if rootdir:
            self._trash_path = get_trash_dir(self.get_path())
        else:
            self._trash_path = None

        # listeners
        self.node_changed = Listeners()  # signature = (node, recurse)

        # add node types
        self._init_default_node_types()
示例#5
0
    def __init__(self, pref_dir=None):       
        Pref.__init__(self)
        if pref_dir is None:
            self._pref_dir = get_user_pref_dir()
        else:
            self._pref_dir = pref_dir

        # listener
        self.changed = Listeners()
        self.changed.add(self._on_changed)
示例#6
0
    def __init__(self, rootdir=None):
        """rootdir -- Root directory of notebook"""
        NoteBookDir.__init__(self, rootdir, notebook=self)
        self.pref = NoteBookPreferences()
        if rootdir is not None:
            self._attr["title"] = os.path.basename(rootdir)
        else:
            self._attr["title"] = None
        self._dirty = set()
        self._trash = None
        self._attr["order"] = 0

        # init notebook attributes
        self.notebook_attrs = {}
        for attr in g_default_attrs:
            self.notebook_attrs[attr.key] = attr
        
        if rootdir:
            self._trash_path = get_trash_dir(self.get_path())
        
        # listeners
        self.node_changed = Listeners()  # node, recurse
示例#7
0
class KeepNotePreferences (Pref):
    """Preference data structure for the KeepNote application"""
    
    def __init__(self, pref_dir=None):       
        Pref.__init__(self)
        if pref_dir is None:
            self._pref_dir = get_user_pref_dir()
        else:
            self._pref_dir = pref_dir

        # listener
        self.changed = Listeners()
        self.changed.add(self._on_changed)


    def get_pref_dir(self):
        """Returns preference directory"""
        return self._pref_dir


    def _on_changed(self):
        """Listener for preference changes"""
        self.write()
        
    
    #=========================================
    # Input/Output

    def read(self):
        """Read preferences from file"""

        # ensure preference file exists
        if not os.path.exists(get_user_pref_file(self._pref_dir)):
            # write default
            try:
                init_user_pref_dir(self._pref_dir)
                self.write()
            except Exception, e:
                raise KeepNotePreferenceError("Cannot initialize preferences", e)

        try:
            # read preferences xml
            tree = ET.ElementTree(
                file=get_user_pref_file(self._pref_dir))
            
            # parse xml
            # check tree structure matches current version
            root = tree.getroot()
            if root.tag == "keepnote":
                p = root.find("pref")
                if p is None:
                    # convert from old preference version
                    import keepnote.compat.pref as old
                    old_pref = old.KeepNotePreferences()
                    old_pref.read(get_user_pref_file(self._pref_dir))
                    data = old_pref._get_data()
                else:
                    # get data object from xml
                    d = p.find("dict")
                    if d is not None:
                        data = plist.load_etree(d)
                    else:
                        data = orderdict.OrderDict()

                # set data
                self._data.clear()
                self._data.update(data)
        except Exception, e:
            raise KeepNotePreferenceError("Cannot read preferences", e)
示例#8
0
 def __init__(self, textbuffer):
     self.undo_stack = UndoStack(MAX_UNDOS)
     self._next_action = None
     self._buffer = textbuffer
     self.after_changed = Listeners()
示例#9
0
class UndoHandler(object):
    """TextBuffer Handler that provides undo/redo functionality"""
    def __init__(self, textbuffer):
        self.undo_stack = UndoStack(MAX_UNDOS)
        self._next_action = None
        self._buffer = textbuffer
        self.after_changed = Listeners()

    def on_insert_text(self, textbuffer, it, text, length):
        """Callback for text insert"""

        # NOTE: GTK does not give us a proper UTF string, so fix it
        text = unicode(text, "utf_8")
        length = len(text)

        # setup next action
        offset = it.get_offset()
        self._next_action = InsertAction(
            textbuffer,
            offset,
            text,
            length,
            cursor_insert=(offset == textbuffer.get_iter_at_mark(
                textbuffer.get_insert()).get_offset()))

    def on_delete_range(self, textbuffer, start, end):
        """Callback for delete range"""
        # setup next action
        self._next_action = DeleteAction(
            textbuffer, start.get_offset(), end.get_offset(),
            start.get_slice(end),
            textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_offset())

    def on_insert_pixbuf(self, textbuffer, it, pixbuf):
        """Callback for inserting a pixbuf"""
        pass

    def on_insert_child_anchor(self, textbuffer, it, anchor):
        """Callback for inserting a child anchor"""
        # setup next action
        self._next_action = InsertChildAction(textbuffer, it.get_offset(),
                                              anchor)

    def on_apply_tag(self, textbuffer, tag, start, end):
        """Callback for tag apply"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(),
                           end.get_offset(), True)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_remove_tag(self, textbuffer, tag, start, end):
        """Callback for tag remove"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(),
                           end.get_offset(), False)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_changed(self, textbuffer):
        """Callback for buffer change"""

        # process actions that have changed the buffer
        if not self._next_action:
            return

        textbuffer.begin_user_action()

        # add action to undo stack
        action = self._next_action
        self._next_action = None
        self.undo_stack.do(action.do, action.undo, False)

        # perfrom additional "clean-up" actions
        # note: only if undo/redo is not currently in progress
        if not self.undo_stack.is_in_progress():
            self.after_changed.notify(action)

        textbuffer.end_user_action()
示例#10
0
class KeepNotePreferences(Pref):
    """Preference data structure for the KeepNote application"""
    def __init__(self, pref_dir=None):
        Pref.__init__(self)
        if pref_dir is None:
            self._pref_dir = get_user_pref_dir()
        else:
            self._pref_dir = pref_dir

        # listener
        self.changed = Listeners()
        self.changed.add(self._on_changed)

    def get_pref_dir(self):
        """Returns preference directory"""
        return self._pref_dir

    def _on_changed(self):
        """Listener for preference changes"""
        self.write()

    #=========================================
    # Input/Output

    def read(self):
        """Read preferences from file"""

        # ensure preference file exists
        if not os.path.exists(get_user_pref_file(self._pref_dir)):
            # write default
            try:
                init_user_pref_dir(self._pref_dir)
                self.write()
            except Exception, e:
                raise KeepNotePreferenceError("Cannot initialize preferences",
                                              e)

        try:
            # read preferences xml
            tree = ET.ElementTree(file=get_user_pref_file(self._pref_dir))

            # parse xml
            # check tree structure matches current version
            root = tree.getroot()
            if root.tag == "keepnote":
                p = root.find("pref")
                if p is None:
                    # convert from old preference version
                    import keepnote.compat.pref as old
                    old_pref = old.KeepNotePreferences()
                    old_pref.read(get_user_pref_file(self._pref_dir))
                    data = old_pref._get_data()
                else:
                    # get data object from xml
                    d = p.find("dict")
                    if d is not None:
                        data = plist.load_etree(d)
                    else:
                        data = orderdict.OrderDict()

                # set data
                self._data.clear()
                self._data.update(data)
        except Exception, e:
            raise KeepNotePreferenceError("Cannot read preferences", e)
示例#11
0
 def __init__(self, textbuffer):
     self.undo_stack = UndoStack(MAX_UNDOS)
     self._next_action = None
     self._buffer = textbuffer
     self.after_changed = Listeners()
示例#12
0
class UndoHandler(object):
    """TextBuffer Handler that provides undo/redo functionality"""

    def __init__(self, textbuffer):
        self.undo_stack = UndoStack(MAX_UNDOS)
        self._next_action = None
        self._buffer = textbuffer
        self.after_changed = Listeners()

    def on_insert_text(self, textbuffer, it, text, length):
        """Callback for text insert"""

        # NOTE: GTK does not give us a proper UTF string, so fix it
        text = unicode(text, "utf_8")
        length = len(text)

        # setup next action
        offset = it.get_offset()
        self._next_action = InsertAction(
            textbuffer,
            offset,
            text,
            length,
            cursor_insert=(offset == textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_offset()),
        )

    def on_delete_range(self, textbuffer, start, end):
        """Callback for delete range"""
        # setup next action
        self._next_action = DeleteAction(
            textbuffer,
            start.get_offset(),
            end.get_offset(),
            start.get_slice(end),
            textbuffer.get_iter_at_mark(textbuffer.get_insert()).get_offset(),
        )

    def on_insert_pixbuf(self, textbuffer, it, pixbuf):
        """Callback for inserting a pixbuf"""
        pass

    def on_insert_child_anchor(self, textbuffer, it, anchor):
        """Callback for inserting a child anchor"""
        # setup next action
        self._next_action = InsertChildAction(textbuffer, it.get_offset(), anchor)

    def on_apply_tag(self, textbuffer, tag, start, end):
        """Callback for tag apply"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(), end.get_offset(), True)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_remove_tag(self, textbuffer, tag, start, end):
        """Callback for tag remove"""

        if not isinstance(tag, RichTextTag):
            # do not process tags that are not rich text
            # i.e. gtkspell tags (ignored by undo/redo)
            return

        action = TagAction(textbuffer, tag, start.get_offset(), end.get_offset(), False)
        self.undo_stack.do(action.do, action.undo, False)
        textbuffer.set_modified(True)

    def on_changed(self, textbuffer):
        """Callback for buffer change"""

        # process actions that have changed the buffer
        if not self._next_action:
            return

        textbuffer.begin_user_action()

        # add action to undo stack
        action = self._next_action
        self._next_action = None
        self.undo_stack.do(action.do, action.undo, False)

        # perfrom additional "clean-up" actions
        # note: only if undo/redo is not currently in progress
        if not self.undo_stack.is_in_progress():
            self.after_changed.notify(action)

        textbuffer.end_user_action()
示例#13
0
class Extension(object):
    """KeepNote Extension"""

    version = (1, 0)
    key = ""
    name = "untitled"
    author = "no author"
    website = "http://rasm.ods.org/keepnote"
    description = "base extension"
    visible = True

    def __init__(self, app):

        self._app = app
        self._enabled = False
        self.type = "system"
        self.enabled = Listeners()

    def enable(self, enable):
        """Enable/disable extension"""

        # check dependencies
        self.check_depends()

        # mark extension as enabled
        self._enabled = enable

        # notify listeners
        self.enabled.notify(enable)

        # return whether the extension is enabled
        return self._enabled

    def is_enabled(self):
        """Returns True if extension is enabled"""
        return self._enabled

    def check_depends(self):
        """Checks whether dependencies are met.  Throws exception on failure"""
        for dep in self.get_depends():
            if not self._app.dependency_satisfied(dep):
                raise DependencyError(self, dep)

    def get_depends(self):
        """
        Returns dependencies of extension

        Dependencies returned as a list of tuples (NAME, REL, EXTRA)

        NAME is a string identify an extension (or 'keepnote' itself).
        EXTRA is an object whose type depends on REL

        REL is a string representing a relation.  Options are:

          Version relations.  For each of these values for REL, the EXTRA
          field is interpreted as VERSION (see below):
            '>='   the version must be greater than or equal to
            '>'    the version must be greater than
            '=='   the version must be exactly equal to
            '<='   the version must less than or equal to
            '<'    the version must be less than
            '!='   the version must not be equal to

          Other relations.  
            'no'   the extension must not exist.  EXTRA is None.


        Possible values for EXTRA:

          VERSION   This is a tuple representing a version number.
            ex: the tuple (0, 6, 1) represents version 0.6.1


        All dependencies must be met to enable an extension.  A extension
        name can appear more than once if several relations are required
        (such as specifying a range of valid version numbers).

        """

        return [("keepnote", ">=", (0, 6, 1))]

    #===============================
    # filesystem paths

    def get_base_dir(self, exist=True):
        """Returns the directory containing the extensions code"""
        path = self._app.get_extension_base_dir(self.key)
        if exist and not os.path.exists(path):
            os.makedirs(path)
        return path

    def get_data_dir(self, exist=True):
        """Returns the directory for storing data specific to this extension"""
        path = self._app.get_extension_data_dir(self.key)
        if exist and not os.path.exists(path):
            os.makedirs(path)
        return path

    def get_data_file(self, filename, exist=True):
        """
        Returns a full path to  a file within the extension's data directory
        """
        return os.path.join(self.get_data_dir(exist), filename)
示例#14
0
 def get_listeners(self, key):
     listeners = self._listeners.get(key, None)
     if listeners is None:
         listeners = Listeners()
         self._listeners[key] = listeners
     return listeners
示例#15
0
class Extension (object):
    """KeepNote Extension"""

    version = (1, 0)
    key = ""
    name = "untitled"
    author = "no author"
    website = "http://keepnote.org"
    description = "base extension"
    visible = True


    def __init__(self, app):
        
        self._app = app
        self._info = {}
        self._enabled = False
        self.type = "system"
        self.enabled = Listeners()


    def read_info(self):
        """Populate extension info"""

        path = self.get_base_dir(False)
        self._info = read_extension_info(path)

        # populate info
        self.version = parse_extension_version(self._info["version"])
        self.name = self._info["name"]
        self.author = self._info["author"]
        self.website = self._info["website"]
        self.description = self._info["description"]

        
    def get_info(self, key):
        return self._info.get(key, None)
        

    def enable(self, enable):
        """Enable/disable extension"""

        # check dependencies
        self.check_depends()
        
        # mark extension as enabled
        self._enabled = enable
        
        # notify listeners
        self.enabled.notify(enable)
        
        # return whether the extension is enabled
        return self._enabled


    def is_enabled(self):
        """Returns True if extension is enabled"""
        return self._enabled


    def check_depends(self):
        """Checks whether dependencies are met.  Throws exception on failure"""
        for dep in self.get_depends():
            if not self._app.dependency_satisfied(dep):
                raise DependencyError(self, dep)


    def get_depends(self):
        """
        Returns dependencies of extension

        Dependencies returned as a list of tuples (NAME, REL, EXTRA)

        NAME is a string identify an extension (or 'keepnote' itself).
        EXTRA is an object whose type depends on REL

        REL is a string representing a relation.  Options are:

          Version relations.  For each of these values for REL, the EXTRA
          field is interpreted as VERSION (see below):
            '>='   the version must be greater than or equal to
            '>'    the version must be greater than
            '=='   the version must be exactly equal to
            '<='   the version must less than or equal to
            '<'    the version must be less than
            '!='   the version must not be equal to

          Other relations.  
            'no'   the extension must not exist.  EXTRA is None.


        Possible values for EXTRA:

          VERSION   This is a tuple representing a version number.
            ex: the tuple (0, 6, 1) represents version 0.6.1


        All dependencies must be met to enable an extension.  A extension
        name can appear more than once if several relations are required
        (such as specifying a range of valid version numbers).

        """

        return [("keepnote", ">=", (0, 6, 1))]

    #===============================
    # filesystem paths

    def get_base_dir(self, exist=True):
        """
        Returns the directory containing the extension's code

        If 'exists' is True, create directory if it does not exists.
        """
        path = self._app.get_extension_base_dir(self.key)
        if exist and not os.path.exists(path):
            os.makedirs(path)
        return path


    def get_data_dir(self, exist=True):
        """
        Returns the directory for storing data specific to this extension

        If 'exists' is True, create directory if it does not exists.
        """
        path = self._app.get_extension_data_dir(self.key)
        if exist and not os.path.exists(path):
            os.makedirs(path)
        return path

    def get_data_file(self, filename, exist=True):
        """
        Returns a full path to a file within the extension's data directory

        If 'exists' is True, create directory if it does not exists.
        """
        return os.path.join(self.get_data_dir(exist), filename)
示例#16
0
class KeepNotePreferences(Pref):
    """Preference data structure for the KeepNote application"""
    def __init__(self, pref_dir=None):
        Pref.__init__(self)
        if pref_dir is None:
            self._pref_dir = get_user_pref_dir()
        else:
            self._pref_dir = pref_dir

        # listener
        self.changed = Listeners()
        # self.changed.add(self._on_changed)

    def get_pref_dir(self):
        """Returns preference directory"""
        return self._pref_dir

    # def _on_changed(self):
    #    """Listener for preference changes"""
    #    self.write()

    # =========================================
    # Input/Output

    def read(self):
        """Read preferences from file"""

        # ensure preference file exists
        if not os.path.exists(get_user_pref_file(self._pref_dir)):
            # write default
            try:
                init_user_pref_dir(self._pref_dir)
                self.write()
            except Exception as e:
                raise KeepNotePreferenceError("Cannot initialize preferences",
                                              e)

        try:
            # read preferences xml
            tree = ElementTree.ElementTree(
                file=get_user_pref_file(self._pref_dir))

            # parse xml
            # check tree structure matches current version
            root = tree.getroot()
            if root.tag == "keepnote":
                p = root.find("pref")
                if p is None:
                    # convert from old preference version
                    import keepnote.compat.pref as old
                    old_pref = old.KeepNotePreferences()
                    old_pref.read(get_user_pref_file(self._pref_dir))
                    data = old_pref._get_data()
                else:
                    # get data object from xml
                    d = p.find("dict")
                    if d is not None:
                        data = plist.load_etree(d)
                    else:
                        data = orderdict.OrderDict()

                # set data
                self._data.clear()
                self._data.update(data)
        except Exception as e:
            raise KeepNotePreferenceError("Cannot read preferences", e)

        # notify listeners
        self.changed.notify()

    def write(self):
        """Write preferences to file"""

        try:
            if not os.path.exists(self._pref_dir):
                init_user_pref_dir(self._pref_dir)

            out = safefile.open(get_user_pref_file(self._pref_dir),
                                "w",
                                codec="utf-8")
            out.write(u'<?xml version="1.0" encoding="UTF-8"?>\n'
                      u'<keepnote>\n'
                      u'<pref>\n')
            plist.dump(self._data, out, indent=4, depth=4)
            out.write(u'</pref>\n' u'</keepnote>\n')

            out.close()

        except (IOError, OSError) as e:
            log_error(e, sys.exc_info()[2])
            raise NoteBookError(_("Cannot save preferences"), e)