Introducing StyledText in Notes.

svn: r10410
This commit is contained in:
Zsolt Foldvari
2008-03-28 23:22:46 +00:00
parent 52ad89909c
commit 0542a9b78c
10 changed files with 879 additions and 804 deletions

View File

@@ -69,3 +69,8 @@ from gen.lib.srcmediatype import SourceMediaType
from gen.lib.eventroletype import EventRoleType
from gen.lib.markertype import MarkerType
from gen.lib.notetype import NoteType
from gen.lib.styledtexttagtype import StyledTextTagType
# Text
from gen.lib.styledtexttag import StyledTextTag
from gen.lib.styledtext import StyledText

View File

@@ -31,19 +31,26 @@ Base type for all gramps types.
#------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# _init_map function
#
#-------------------------------------------------------------------------
def _init_map(data, key_col, data_col, blacklist=None):
"""
Initialize the map, building a new map from the specified columns.
"""
"""Initialize the map, building a new map from the specified columns."""
if blacklist:
new_data = dict([ (item[key_col], item[data_col])
for item in data
if not item[0] in blacklist ])
new_data = dict([(item[key_col], item[data_col])
for item in data if not item[0] in blacklist])
else:
new_data = dict([ (item[key_col], item[data_col])
for item in data ])
new_data = dict([(item[key_col], item[data_col]) for item in data])
return new_data
#-------------------------------------------------------------------------
#
# GrampsTypeMeta class
#
#-------------------------------------------------------------------------
class GrampsTypeMeta(type):
"""Metaclass for L{GrampsType}.
@@ -55,15 +62,30 @@ class GrampsTypeMeta(type):
type.__init__(mcs, name, bases, namespace)
mcs.__class_init__(namespace)
#-------------------------------------------------------------------------
#
# GrampsType class
#
#-------------------------------------------------------------------------
class GrampsType(object):
"""Base class for all Gramps object types.
_DATAMAP is a 3-tuple like (index, localized_string, english_string)
_BLACKLIST is a list of indices to ignore (obsolete/retired entries)
(gramps policy is never to delete type values,
or reuse the name (TOKEN) of any specific type value)
@cvar _DATAMAP: 3-tuple like (index, localized_string, english_string).
@type _DATAMAP: list
@cvar _BLACKLIST: List of indices to ignore (obsolete/retired entries).
(gramps policy is never to delete type values, or reuse the name (TOKEN)
of any specific type value)
@type _BLACKLIST: list
@cvar POS_<x>: Position of <x> attribute in the serialized format of
an instance.
@type POS_<x>: int
@attention: The POS_<x> class variables reflect the serialized object, they
have to be updated in case the data structure or the L{serialize} method
changes!
"""
(POS_VALUE, POS_STRING) = range(2)
_CUSTOM = 0
_DEFAULT = 0
@@ -89,8 +111,8 @@ class GrampsType(object):
self.set(value)
def __set_tuple(self, value):
v,s = self._DEFAULT,u''
if len(value) > 0:
v, s = self._DEFAULT, u''
if value:
v = value[0]
if len(value) > 1:
s = value[1]
@@ -148,15 +170,11 @@ class GrampsType(object):
return self._I2EMAP[self.val]
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
"""Convert the object to a serialized tuple of data. """
return (self.val, self.string)
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
"""Convert a serialized tuple of data to an object."""
self.val, self.string = data
def __str__(self):
@@ -172,16 +190,12 @@ class GrampsType(object):
return self._I2SMAP
def get_standard_names(self):
"""
Return the list of localized names for all standard types.
"""
"""Return the list of localized names for all standard types."""
return [s for (i, s) in self._I2SMAP.items()
if (i != self._CUSTOM) and s.strip()]
def get_standard_xml(self):
"""
Return the list of XML (english) names for all standard types.
"""
"""Return the list of XML (english) names for all standard types."""
return [s for (i, s) in self._I2EMAP.items()
if (i != self._CUSTOM) and s.strip()]

View File

@@ -32,6 +32,7 @@ Note class for GRAMPS.
from gen.lib.primaryobj import BasicPrimaryObject
from gen.lib.notetype import NoteType
from gen.lib.markertype import MarkerType
from gen.lib.styledtext import StyledText
#-------------------------------------------------------------------------
#
@@ -39,118 +40,163 @@ from gen.lib.markertype import MarkerType
#
#-------------------------------------------------------------------------
class Note(BasicPrimaryObject):
"""
Introduction
============
The Note class defines a text note. The note may be preformatted
or 'flowed', which indicates that it text string is considered
to be in paragraphs, separated by newlines.
"""
"""Define a text note.
FLOWED = 0
FORMATTED = 1
Starting from GRAMPS 3.1 Note object stores the text in L{StyledText}
instance, thus it can have text formatting information.
def __init__(self, text = ""):
"""
Create a new Note object, initializing from the passed string.
"""
To get and set only the clear text of the note use the L{get} and L{set}
methods.
To get and set the formatted version of the Note's text use the
L{get_styledtext} and L{set_styledtext} methods.
The note may be 'preformatted' or 'flowed', which indicates that the
text string is considered to be in paragraphs, separated by newlines.
@cvar POS_<x>: Position of <x> attribute in the serialized format of
an instance.
@type POS_<x>: int
@attention: The POS_<x> class variables reflect the serialized object, they
have to be updated in case the data structure or the L{serialize} method
changes!
"""
(FLOWED, FORMATTED) = range(2)
(POS_HANDLE,
POS_ID,
POS_TEXT,
POS_FORMAT,
POS_TYPE,
POS_CHANGE,
POS_MARKER,
POS_PRIVATE,) = range(8)
def __init__(self, text=""):
"""Create a new Note object, initializing from the passed string."""
BasicPrimaryObject.__init__(self)
self.text = text
self.text = StyledText(text)
self.format = Note.FLOWED
self.type = NoteType()
def serialize(self):
"""Convert the object to a serialized tuple of data.
@returns: The serialized format of the instance.
@rtype: tuple
"""
Convert the object to a serialized tuple of data.
"""
return (self.handle, self.gramps_id, self.text, self.format,
return (self.handle, self.gramps_id, self.text.serialize(), self.format,
self.type.serialize(), self.change, self.marker.serialize(),
self.private)
def unserialize(self, data):
"""Convert a serialized tuple of data to an object.
@param data: The serialized format of a Note.
@type: data: tuple
"""
Convert a serialized tuple of data to an object.
"""
(self.handle, self.gramps_id, self.text, self.format,
(self.handle, self.gramps_id, the_text, self.format,
the_type, self.change, the_marker, self.private) = data
self.text = StyledText()
self.text.unserialize(the_text)
self.marker = MarkerType()
self.marker.unserialize(the_marker)
self.type = NoteType()
self.type.unserialize(the_type)
def get_text_data_list(self):
"""
Return the list of all textual attributes of the object.
"""Return the list of all textual attributes of the object.
@return: Returns the list of all textual attributes of the object.
@returns: The list of all textual attributes of the object.
@rtype: list
"""
return [self.text]
return [str(self.text)]
def set(self, text):
"""
Set the text associated with the note to the passed string.
"""Set the text associated with the note to the passed string.
@param text: Text string defining the note contents.
@param text: The I{clear} text defining the note contents.
@type text: str
"""
self.text = text
self.text = StyledText(text)
def get(self):
"""
Return the text string associated with the note.
"""Return the text string associated with the note.
@returns: Returns the text string defining the note contents.
@returns: The I{clear} text of the note contents.
@rtype: str
"""
text = self.text
return text
return str(self.text)
def append(self, text):
def set_styledtext(self, text):
"""Set the text associated with the note to the passed string.
@param text: The I{formatted} text defining the note contents.
@type text: L{StyledText}
"""
Append the specified text to the text associated with the note.
self.text = text
def get_styledtext(self):
"""Return the text string associated with the note.
@returns: The I{formatted} text of the note contents.
@rtype: L{StyledText}
"""
return self.text
def append(self, text):
"""Append the specified text to the text associated with the note.
@param text: Text string to be appended to the note.
@type text: str
@type text: str or L{StyledText}
"""
self.text = self.text + text
def set_format(self, format):
"""
Set the format of the note to the passed value.
"""Set the format of the note to the passed value.
The value can either indicate Flowed or Preformatted.
@param: format: The value can either indicate Flowed or Preformatted.
@type format: int
"""
self.format = format
def get_format(self):
"""
Return the format of the note.
"""Return the format of the note.
The value can either indicate Flowed or Preformatted.
@returns: 0 indicates Flowed, 1 indicates Preformated
@rtype: int
"""
return self.format
def set_type(self, the_type):
"""
Set descriptive type of the Note.
"""Set descriptive type of the Note.
@param the_type: descriptive type of the Note
@type the_type: str
"""
self.type.set(the_type)
def get_type(self):
"""
Get descriptive type of the Note.
"""Get descriptive type of the Note.
@returns: the descriptive type of the Note
@rtype: str
"""
return self.type

162
src/gen/lib/styledtext.py Normal file
View File

@@ -0,0 +1,162 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"Handling formatted ('rich text') strings"
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.lib.styledtexttag import StyledTextTag
#-------------------------------------------------------------------------
#
# StyledText class
#
#-------------------------------------------------------------------------
class StyledText(object):
"""Helper class to enable character based text formatting.
@ivar string: The clear text part.
@type string: str
@ivar tags: Text tags holding formatting information for the string.
@type tags: list of L{StyledTextTag}
@cvar POS_TEXT: Position of I{string} attribute in the serialized format of
an instance.
@type POS_TEXT: int
@cvar POS_TAGS: Position of I{tags} attribute in the serialized format of
an instance.
@type POS_TAGS: int
@attention: The POS_<x> class variables reflect the serialized object, they
have to be updated in case the data structure or the L{serialize} method
changes!
"""
##StyledText provides interface
##Provide interface for:
##- tag manipulation for editor access:
##. get_tags
##. set_tags
##- explicit formatting for reports; at the moment:
##. start_bold() - end_bold()
##. start_superscript() - end_superscript()
(POS_TEXT, POS_TAGS) = range(2)
def __init__(self, text="", tags=None):
"""Setup initial instance variable values."""
self._string = text
# TODO we might want to make simple sanity check first
if tags:
self._tags = tags
else:
self._tags = []
# special methods
def __str__(self): return self._string.__str__()
def __repr__(self): return self._string.__repr__()
def __add__(self, other):
if isinstance(other, StyledText):
# FIXME merging tags missing
return self.__class__("".join([self._string, other.string]))
elif isinstance(other, basestring):
# in this case tags remain the same, only text becomes longer
return self.__class__("".join([self._string, other]))
else:
return self.__class__("".join([self._string, str(other)]))
# string methods in alphabetical order:
def join(self, seq):
# FIXME handling tags missing
return self.__class__(self._string.join(seq))
def replace(self, old, new, maxsplit=-1):
# FIXME handling tags missing
return self.__class__(self._string.replace(old, new, maxsplit))
def split(self, sep=None, maxsplit=-1):
# FIXME handling tags missing
string_list = self._string.split(sep, maxsplit)
return [self.__class__(string) for string in string_list]
# other public methods
def serialize(self):
"""Convert the object to a serialized tuple of data.
@returns: Serialized format of the instance.
@returntype: tuple
"""
if self._tags:
the_tags = [tag.serialize() for tag in self._tags]
else:
the_tags = []
return (self._string, the_tags)
def unserialize(self, data):
"""Convert a serialized tuple of data to an object.
@param data: Serialized format of instance variables.
@type data: tuple
"""
(self._string, the_tags) = data
# I really wonder why this doesn't work... it does for all other types
#self._tags = [StyledTextTag().unserialize(tag) for tag in the_tags]
for tag in the_tags:
gtt = StyledTextTag()
gtt.unserialize(tag)
self._tags.append(gtt)
def get_tags(self):
"""Return the list of formatting tags.
@returns: The formatting tags applied on the text.
@returntype: list of 0 or more L{StyledTextTag} instances.
"""
return self._tags
##def set_tags(self, tags):
##"""Set all the formatting tags at once.
##@param tags: The formatting tags to be applied on the text.
##@type tags: list of 0 or more StyledTextTag instances.
##"""
### TODO we might want to make simple sanity check first
##self._tags = tags
if __name__ == '__main__':
GT = StyledText("asbcde")
print GT

View File

@@ -0,0 +1,73 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"Provide formatting tag definition for StyledText."
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.lib.styledtexttagtype import StyledTextTagType
#-------------------------------------------------------------------------
#
# StyledTextTag class
#
#-------------------------------------------------------------------------
class StyledTextTag():
"""Hold formatting information for StyledText.
@ivar name: Type or name of the tag instance. E.g. bold, etc.
@type name: L{gen.lib.StyledTextTagType} instace
@ivar value: Value of the tag. E.g. color hex string for font color, etc.
@type value: str or None
@ivar ranges: Pointer pairs into the string, where the tag applies.
@type ranges: list of (int(start), int(end)) tuples.
"""
def __init__(self, name=None, value=None, ranges=None):
"""Setup initial instance variable values."""
self.name = StyledTextTagType(name)
self.value = value
self.ranges = ranges
def serialize(self):
"""Convert the object to a serialized tuple of data.
@returns: Serialized format of the instance.
@returntype: tuple
"""
return (self.name.serialize(), self.value, self.ranges)
def unserialize(self, data):
"""Convert a serialized tuple of data to an object.
@param data: Serialized format of instance variables.
@type data: tuple
"""
(the_name, self.value, self.ranges) = data
self.name = StyledTextTagType()
self.name.unserialize(the_name)

View File

@@ -0,0 +1,73 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Zsolt Foldvari
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"Define text formatting tag types."
#------------------------------------------------------------------------
#
# Python modules
#
#------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.lib.grampstype import GrampsType
#-------------------------------------------------------------------------
#
# StyledTextTagType class
#
#-------------------------------------------------------------------------
class StyledTextTagType(GrampsType):
"""Text formatting tag type definition.
Here we only define new class variables. For details see L{GrampsType}.
"""
NONE_ = -1
BOLD = 0
ITALIC = 1
UNDERLINE = 2
FONTFACE = 3
FONTCOLOR = 4
HIGHLIGHT = 5
SUPERSCRIPT = 6
_CUSTOM = NONE_
_DEFAULT = NONE_
_DATAMAP = [
(BOLD, _("Bold"), "bold"),
(ITALIC, _("Italic"), "italic"),
(UNDERLINE, _("Underline"), "underline"),
(FONTFACE, _("Fontface"), "fontface"),
(FONTCOLOR, _("Fontcolor"), "fontcolor"),
(HIGHLIGHT, _("Highlight"), "highlight"),
(SUPERSCRIPT, _("Superscript"), "superscript"),
]
def __init__(self, value=None):
GrampsType.__init__(self, value)