Major updates to GraphViz plugin.
Re-factoring: - split large functions to smaller ones to make code more readable - renamed few methods and variables to what they actually do - collect the report text to a buffer first so that it can be converted to latin-1 at one go - Move common style stuff to GraphViz header and remove from .dot comments stuff that's obvious from first .dot file settings Fixes: - latin-1 conversion option is explicit, not depending on font - set the GraphViz charset attribute according to latin1 - quote node and edge identifiers - rankdir options correspond now to TB and LR (earlier LR and RL) New features: - Use christening/burial dates if birth/death dates are missing - User can add a (e.g. copyright) note to the graph and set its location (newlines and double quotes are automatically escaped) - User can give the paging direction - User can set the GraphViz aspect ratio setting - The weight option (either for children or parents) - Women have rounded boxes, except in filled mode (current GraphViz doesn't support boxes that are both rounded and filled) New default settings: - set the ratio to "compress" instead of "fill" - "mclimit=2.0", prevents crossed lines - minimum node separation is 0.25 svn: r6010
This commit is contained in:
parent
9209f7eca9
commit
2bf08ece8f
@ -1,3 +1,32 @@
|
|||||||
|
2006-02-28 Eero Tamminen <eerot@sf>
|
||||||
|
* src/plugins/GraphViz.py: major changes:
|
||||||
|
Re-factoring:
|
||||||
|
- split large functions to smaller ones to make code more readable
|
||||||
|
- renamed few methods and variables to what they actually do
|
||||||
|
- collect the report text to a buffer first so that it can be
|
||||||
|
converted to latin-1 at one go
|
||||||
|
- Move common style stuff to GraphViz header and remove from .dot
|
||||||
|
comments stuff that's obvious from first .dot file settings
|
||||||
|
Fixes:
|
||||||
|
- latin-1 conversion option is explicit, not depending on font
|
||||||
|
- set the GraphViz charset attribute according to latin1
|
||||||
|
- quote node and edge identifiers
|
||||||
|
- rankdir options correspond now to TB and LR (earlier LR and RL)
|
||||||
|
New features:
|
||||||
|
- Use christening/burial dates if birth/death dates are missing
|
||||||
|
- User can add a (e.g. copyright) note to the graph and set its
|
||||||
|
location (newlines and double quotes are automatically escaped)
|
||||||
|
- User can give the paging direction
|
||||||
|
- User can set the GraphViz aspect ratio setting
|
||||||
|
- The weight option (either for children or parents)
|
||||||
|
- Women have rounded boxes, except in filled mode
|
||||||
|
(current GraphViz doesn't support boxes that are
|
||||||
|
both rounded and filled)
|
||||||
|
New default settings:
|
||||||
|
- set the ratio to "compress" instead of "fill"
|
||||||
|
- "mclimit=2.0", prevents crossed lines
|
||||||
|
- minimum node separation is 0.25
|
||||||
|
|
||||||
2006-02-27 Alex Roitman <shura@gramps-project.org>
|
2006-02-27 Alex Roitman <shura@gramps-project.org>
|
||||||
* configure.in: Bump up release number.
|
* configure.in: Bump up release number.
|
||||||
* Release: Version 2.0.10 "Holy Hand Grenade of Antioch" released.
|
* Release: Version 2.0.10 "Holy Hand Grenade of Antioch" released.
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#
|
#
|
||||||
|
|
||||||
# $Id$
|
# $Id$
|
||||||
|
|
||||||
"Generate files/Relationship graph"
|
"Generate files/Relationship graph"
|
||||||
@ -68,19 +67,42 @@ class _options:
|
|||||||
("gif", "GIF image", _("GIF image")),
|
("gif", "GIF image", _("GIF image")),
|
||||||
)
|
)
|
||||||
fonts = (
|
fonts = (
|
||||||
# Last items tells whether strings need to be converted to Latin1
|
("", "Default", _("Default")),
|
||||||
("", "Default", _("Default"), 1),
|
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica")),
|
||||||
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica"), 1),
|
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans")),
|
||||||
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans"), 0),
|
|
||||||
)
|
)
|
||||||
colors = (
|
colors = (
|
||||||
("outline", "B&W Outline", _("B&W outline")),
|
("outline", "B&W Outline", _("B&W outline")),
|
||||||
("colored", "Colored outline", _("Colored outline")),
|
("colored", "Colored outline", _("Colored outline")),
|
||||||
("filled", "Color fill", _("Color fill")),
|
("filled", "Color fill", _("Color fill")),
|
||||||
)
|
)
|
||||||
|
ratio = (
|
||||||
|
("compress", "Minimal size", _("Minimal size")),
|
||||||
|
("fill", "Fill the given area", _("Fill the given area")),
|
||||||
|
("expand", "Automatically use optimal number of pages", _("Automatically use optimal number of pages"))
|
||||||
|
)
|
||||||
|
attract = (
|
||||||
|
("parents", "Parents", _("Parents")),
|
||||||
|
("children", "Children", _("Children")),
|
||||||
|
("none", "Neither", _("Neither"))
|
||||||
|
)
|
||||||
rankdir = (
|
rankdir = (
|
||||||
|
("TB", "Vertical", _("Vertical")),
|
||||||
("LR", "Horizontal", _("Horizontal")),
|
("LR", "Horizontal", _("Horizontal")),
|
||||||
("RL", "Vertical", _("Vertical")),
|
)
|
||||||
|
pagedir = (
|
||||||
|
("BL", "Bottom, left", _("Bottom, left")),
|
||||||
|
("BR", "Bottom, right", _("Bottom, right")),
|
||||||
|
("TL", "Top, left", _("Top, left")),
|
||||||
|
("TR", "Top, right", _("Top, Right")),
|
||||||
|
("RB", "Right, bottom", _("Right, bottom")),
|
||||||
|
("RT", "Right, top", _("Right, top")),
|
||||||
|
("LB", "Left, bottom", _("Left, bottom")),
|
||||||
|
("LT", "Left, top", _("Left, top")),
|
||||||
|
)
|
||||||
|
noteloc = (
|
||||||
|
("t", "Top", _("Top")),
|
||||||
|
("b", "Bottom", _("Bottom")),
|
||||||
)
|
)
|
||||||
arrowstyles = (
|
arrowstyles = (
|
||||||
('d', "Descendants <- Ancestors", _("Descendants <- Ancestors")),
|
('d', "Descendants <- Ancestors", _("Descendants <- Ancestors")),
|
||||||
@ -115,7 +137,7 @@ class GraphViz:
|
|||||||
The option class carries its number, and the function
|
The option class carries its number, and the function
|
||||||
returning the list of filters.
|
returning the list of filters.
|
||||||
font - Font to use.
|
font - Font to use.
|
||||||
latin - Set if font supports only Latin1
|
latin - Set if text needs to be converted to latin-1
|
||||||
arrow - Arrow styles for heads and tails.
|
arrow - Arrow styles for heads and tails.
|
||||||
showfamily - Whether to show family nodes.
|
showfamily - Whether to show family nodes.
|
||||||
incid - Whether to include IDs.
|
incid - Whether to include IDs.
|
||||||
@ -123,12 +145,16 @@ class GraphViz:
|
|||||||
justyears - Use years only.
|
justyears - Use years only.
|
||||||
placecause - Whether to replace missing dates with place or cause
|
placecause - Whether to replace missing dates with place or cause
|
||||||
url - Whether to include URLs.
|
url - Whether to include URLs.
|
||||||
rankdir - Graph direction
|
rankdir - Graph direction, LR or RL
|
||||||
|
ratio - Output aspect ration, fill/compress/auto
|
||||||
color - Whether to use outline, colored outline or filled color in graph
|
color - Whether to use outline, colored outline or filled color in graph
|
||||||
dashedl - Whether to use dashed lines for non-birth relationships.
|
dashedl - Whether to use dashed lines for non-birth relationships.
|
||||||
margin - Margins, in cm.
|
margin - Margins, in cm.
|
||||||
pagesh - Number of pages in horizontal direction.
|
pagesh - Number of pages in horizontal direction.
|
||||||
pagesv - Number of pages in vertical direction.
|
pagesv - Number of pages in vertical direction.
|
||||||
|
pagedir - Paging direction
|
||||||
|
note - Note to add to the graph
|
||||||
|
noteloc - Note location t/b
|
||||||
"""
|
"""
|
||||||
colored = {
|
colored = {
|
||||||
'male': 'dodgerblue4',
|
'male': 'dodgerblue4',
|
||||||
@ -151,11 +177,14 @@ class GraphViz:
|
|||||||
self.height = self.paper.get_height_inches()
|
self.height = self.paper.get_height_inches()
|
||||||
|
|
||||||
options = options_class.handler.options_dict
|
options = options_class.handler.options_dict
|
||||||
|
self.pagedir = options['pagedir']
|
||||||
self.hpages = options['pagesh']
|
self.hpages = options['pagesh']
|
||||||
self.vpages = options['pagesv']
|
self.vpages = options['pagesv']
|
||||||
margin_cm = options['margin']
|
margin_cm = options['margin']
|
||||||
self.margin = round(margin_cm/2.54,2)
|
self.margin = round(margin_cm/2.54,2)
|
||||||
if margin_cm > 0.1:
|
if margin_cm > 0.1:
|
||||||
|
# GraphViz has rounding errors so have to make the real
|
||||||
|
# margins slightly smaller than (page - content size)
|
||||||
self.margin_small = round((margin_cm-0.1)/2.54,2)
|
self.margin_small = round((margin_cm-0.1)/2.54,2)
|
||||||
else:
|
else:
|
||||||
self.margin_small = 0
|
self.margin_small = 0
|
||||||
@ -167,8 +196,9 @@ class GraphViz:
|
|||||||
self.just_years = options['justyears']
|
self.just_years = options['justyears']
|
||||||
self.placecause = options['placecause']
|
self.placecause = options['placecause']
|
||||||
self.rankdir = options['rankdir']
|
self.rankdir = options['rankdir']
|
||||||
|
self.attract = options['attract']
|
||||||
|
self.ratio = options['ratio']
|
||||||
self.fontname = options['font']
|
self.fontname = options['font']
|
||||||
self.latin = options['latin']
|
|
||||||
self.colorize = options['color']
|
self.colorize = options['color']
|
||||||
if self.colorize == 'colored':
|
if self.colorize == 'colored':
|
||||||
self.colors = colored
|
self.colors = colored
|
||||||
@ -184,185 +214,300 @@ class GraphViz:
|
|||||||
else:
|
else:
|
||||||
self.arrowtailstyle = 'none'
|
self.arrowtailstyle = 'none'
|
||||||
|
|
||||||
|
self.latin = options['latin']
|
||||||
|
self.noteloc = options['noteloc']
|
||||||
|
self.note = options['note']
|
||||||
|
|
||||||
filter_num = options_class.get_filter_number()
|
filter_num = options_class.get_filter_number()
|
||||||
filters = options_class.get_report_filters(person)
|
filters = options_class.get_report_filters(person)
|
||||||
filters.extend(GenericFilter.CustomFilters.get_filters())
|
filters.extend(GenericFilter.CustomFilters.get_filters())
|
||||||
self.filter = filters[filter_num]
|
self.filter = filters[filter_num]
|
||||||
|
|
||||||
|
buffer = self.get_report()
|
||||||
self.f = open(options_class.get_output(),'w')
|
self.f = open(options_class.get_output(),'w')
|
||||||
self.write_report()
|
if self.latin:
|
||||||
|
self.f.write(buffer.encode('iso-8859-1'))
|
||||||
|
else:
|
||||||
|
self.f.write(buffer)
|
||||||
self.f.close()
|
self.f.close()
|
||||||
|
|
||||||
def write_report(self):
|
|
||||||
|
|
||||||
self.ind_list = self.filter.apply(self.database,
|
def get_report(self):
|
||||||
|
"return string of the .dot file contents"
|
||||||
|
self.person_handles = self.filter.apply(self.database,
|
||||||
self.database.get_person_handles(sort_handles=False))
|
self.database.get_person_handles(sort_handles=False))
|
||||||
|
|
||||||
self.write_header()
|
# graph size
|
||||||
self.f.write("digraph GRAMPS_relationship_graph {\n")
|
|
||||||
self.f.write("bgcolor=white;\n")
|
|
||||||
self.f.write("rankdir=%s;\n" % self.rankdir)
|
|
||||||
self.f.write("center=1;\n")
|
|
||||||
self.f.write("margin=%3.2f;\n" % self.margin_small)
|
|
||||||
self.f.write("ratio=fill;\n")
|
|
||||||
if self.orient == PAPER_LANDSCAPE:
|
if self.orient == PAPER_LANDSCAPE:
|
||||||
self.f.write("size=\"%3.2f,%3.2f\";\n" % (
|
rotate = 90
|
||||||
(self.height-self.margin*2)*self.hpages,
|
sizew = (self.height - self.margin*2) * self.hpages
|
||||||
(self.width-self.margin*2)*self.vpages
|
sizeh = (self.width - self.margin*2) * self.vpages
|
||||||
))
|
|
||||||
else:
|
else:
|
||||||
self.f.write("size=\"%3.2f,%3.2f\";\n" % (
|
rotate = 0
|
||||||
(self.width-self.margin*2)*self.hpages,
|
sizew = (self.width - self.margin*2) * self.hpages
|
||||||
(self.height-self.margin*2)*self.vpages
|
sizeh = (self.height - self.margin*2) * self.vpages
|
||||||
))
|
|
||||||
self.f.write("page=\"%3.2f,%3.2f\";\n" % (self.width,self.height))
|
|
||||||
|
|
||||||
if self.orient == PAPER_LANDSCAPE:
|
|
||||||
self.f.write("rotate=90;\n")
|
|
||||||
|
|
||||||
if len(self.ind_list) > 1:
|
buffer = self.get_comment_header()
|
||||||
self.dump_index()
|
buffer += """
|
||||||
self.dump_person()
|
digraph GRAMPS_relationship_graph {
|
||||||
|
/* whole graph attributes */
|
||||||
|
bgcolor=white;
|
||||||
|
center=1;
|
||||||
|
ratio=%s;
|
||||||
|
rankdir=%s;
|
||||||
|
mclimit=2.0;
|
||||||
|
margin="%3.2f";
|
||||||
|
pagedir="%s";
|
||||||
|
page="%3.2f,%3.2f";
|
||||||
|
size="%3.2f,%3.2f";
|
||||||
|
rotate=%d;
|
||||||
|
/* default node and edge attributes */
|
||||||
|
nodesep=0.25;
|
||||||
|
edge [syle=solid, arrowhead=%s arrowtail=%s];
|
||||||
|
""" % (
|
||||||
|
self.ratio,
|
||||||
|
self.rankdir,
|
||||||
|
self.margin_small,
|
||||||
|
self.pagedir,
|
||||||
|
self.width, self.height,
|
||||||
|
sizew, sizeh,
|
||||||
|
rotate,
|
||||||
|
self.arrowheadstyle,
|
||||||
|
self.arrowtailstyle
|
||||||
|
)
|
||||||
|
|
||||||
self.f.write("}\n")
|
if self.fontname:
|
||||||
|
font = 'fontname="%s"' % self.fontname
|
||||||
|
else:
|
||||||
|
font = ''
|
||||||
|
if self.colorize == 'filled':
|
||||||
|
buffer += 'node [style=filled %s];\n' % font
|
||||||
|
else:
|
||||||
|
buffer += 'node [%s];\n' % font
|
||||||
|
if self.latin:
|
||||||
|
# GraphViz default is UTF-8
|
||||||
|
buffer += 'charset="iso-8859-1";\n'
|
||||||
|
|
||||||
def dump_person(self):
|
if len(self.person_handles) > 1:
|
||||||
# Hash people in a dictionary for faster inclusion checking.
|
buffer += "/* persons and their families */\n"
|
||||||
|
buffer += self.get_persons_and_families()
|
||||||
|
buffer += "/* link children to families */\n"
|
||||||
|
buffer += self.get_child_links_to_families()
|
||||||
|
|
||||||
|
if self.note:
|
||||||
|
buffer += 'labelloc="%s";\n' % self.noteloc
|
||||||
|
buffer += 'label="%s";\n' % self.note.replace('\n', '\\n').replace('"', '\\\"')
|
||||||
|
buffer += 'fontsize="20";\n' # in points
|
||||||
|
|
||||||
|
return buffer + "}\n"
|
||||||
|
|
||||||
|
|
||||||
|
def get_comment_header(self):
|
||||||
|
"return comment of Gramps options which are not Graphviz options"
|
||||||
|
return """/*
|
||||||
|
GRAMPS - Relationship graph
|
||||||
|
|
||||||
|
Generated on %s.
|
||||||
|
|
||||||
|
Report content options:
|
||||||
|
include URLs : %s
|
||||||
|
IDs : %s
|
||||||
|
dates : %s
|
||||||
|
just year : %s
|
||||||
|
place or cause : %s
|
||||||
|
colorize : %s
|
||||||
|
dotted adoptions : %s
|
||||||
|
show family nodes : %s
|
||||||
|
pages horizontal : %s
|
||||||
|
vertical : %s
|
||||||
|
|
||||||
|
For other options, see graph settings below.
|
||||||
|
|
||||||
|
If you need to switch between iso-8859-1 and utf-8 text encodings,
|
||||||
|
e.g. because you're using different font or -T output format,
|
||||||
|
just use iconv:
|
||||||
|
iconv -f iso-8859-1 -t utf-8 old.dot > new.dot
|
||||||
|
iconv -t utf-8 -f iso-8859-1 old.dot > new.dot
|
||||||
|
*/
|
||||||
|
""" % (
|
||||||
|
asctime(),
|
||||||
|
bool(self.includeurl),
|
||||||
|
bool(self.includeid),
|
||||||
|
bool(self.includedates),
|
||||||
|
bool(self.just_years),
|
||||||
|
bool(self.placecause),
|
||||||
|
bool(self.colorize),
|
||||||
|
bool(self.adoptionsdashed),
|
||||||
|
bool(self.show_families),
|
||||||
|
self.hpages, self.vpages
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_child_links_to_families(self):
|
||||||
|
"returns string of GraphViz edges linking parents to families or children"
|
||||||
person_dict = {}
|
person_dict = {}
|
||||||
for p_id in self.ind_list:
|
# Hash people in a dictionary for faster inclusion checking
|
||||||
person_dict[p_id] = 1
|
for person_handle in self.person_handles:
|
||||||
|
person_dict[person_handle] = 1
|
||||||
for person_handle in self.ind_list:
|
buffer = ""
|
||||||
|
for person_handle in self.person_handles:
|
||||||
person = self.database.get_person_from_handle(person_handle)
|
person = self.database.get_person_from_handle(person_handle)
|
||||||
pid = person.get_gramps_id().replace('-','_')
|
p_id = person.get_gramps_id()
|
||||||
for family_handle, mrel, frel in person.get_parent_family_handle_list():
|
for fam_handle,mrel,frel in person.get_parent_family_handle_list():
|
||||||
family = self.database.get_family_from_handle(family_handle)
|
family = self.database.get_family_from_handle(fam_handle)
|
||||||
father_handle = family.get_father_handle()
|
father_handle = family.get_father_handle()
|
||||||
mother_handle = family.get_mother_handle()
|
mother_handle = family.get_mother_handle()
|
||||||
fadopted = frel != RelLib.Person.CHILD_REL_BIRTH
|
|
||||||
madopted = mrel != RelLib.Person.CHILD_REL_BIRTH
|
|
||||||
famid = family.get_gramps_id().replace('-','_')
|
|
||||||
if (self.show_families and
|
if (self.show_families and
|
||||||
(father_handle and person_dict.has_key(father_handle) or
|
((father_handle and father_handle in person_dict) or
|
||||||
mother_handle and person_dict.has_key(mother_handle))):
|
(mother_handle and mother_handle in person_dict))):
|
||||||
# Link to the family node.
|
# Link to the family node if either parent is in graph
|
||||||
self.f.write('p%s -> f%s [' % (pid, famid))
|
buffer += self.get_family_link(p_id, family, frel, mrel)
|
||||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
|
||||||
(self.arrowheadstyle, self.arrowtailstyle))
|
|
||||||
if self.adoptionsdashed and (fadopted or madopted):
|
|
||||||
self.f.write('style=dotted')
|
|
||||||
else:
|
|
||||||
self.f.write('style=solid')
|
|
||||||
self.f.write('];\n')
|
|
||||||
else:
|
else:
|
||||||
# Link to the parents' nodes directly.
|
# Link to the parents' nodes directly, if they are in graph
|
||||||
if father_handle and person_dict.has_key(father_handle):
|
if father_handle and father_handle in person_dict:
|
||||||
father = self.database.get_person_from_handle(father_handle)
|
buffer += self.get_parent_link(p_id, father_handle, frel)
|
||||||
fid = father.get_gramps_id().replace('-','_')
|
if mother_handle and mother_handle in person_dict:
|
||||||
self.f.write('p%s -> p%s [' % (pid, fid))
|
buffer += self.get_parent_link(p_id, mother_handle, mrel)
|
||||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
return buffer
|
||||||
(self.arrowheadstyle, self.arrowtailstyle))
|
|
||||||
if self.adoptionsdashed and fadopted:
|
|
||||||
self.f.write('style=dotted')
|
|
||||||
else:
|
|
||||||
self.f.write('style=solid')
|
|
||||||
self.f.write('];\n')
|
|
||||||
if mother_handle and person_dict.has_key(mother_handle):
|
|
||||||
mother = self.database.get_person_from_handle(mother_handle)
|
|
||||||
mid = mother.get_gramps_id().replace('-','_')
|
|
||||||
self.f.write('p%s -> p%s [' % (pid, mid))
|
|
||||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
|
||||||
(self.arrowheadstyle, self.arrowtailstyle))
|
|
||||||
if self.adoptionsdashed and madopted:
|
|
||||||
self.f.write('style=dotted')
|
|
||||||
else:
|
|
||||||
self.f.write('style=solid')
|
|
||||||
self.f.write('];\n')
|
|
||||||
|
|
||||||
def dump_index(self):
|
|
||||||
# The list of families for which we have output the node, so we
|
def get_family_link(self, p_id, family, frel, mrel):
|
||||||
# don't do it twice.
|
"returns string of GraphViz edge linking child to family"
|
||||||
families_done = []
|
weight = style = ''
|
||||||
for person_handle in self.ind_list:
|
adopted = ((frel != RelLib.Person.CHILD_REL_BIRTH) or
|
||||||
|
(mrel != RelLib.Person.CHILD_REL_BIRTH))
|
||||||
|
if adopted and self.adoptionsdashed:
|
||||||
|
style = 'style=dotted'
|
||||||
|
if self.attract == "children":
|
||||||
|
weight = 'weight="5"'
|
||||||
|
return '"p%s" -> "f%s" [%s %s];\n' % (p_id,
|
||||||
|
family.get_gramps_id(), style, weight)
|
||||||
|
|
||||||
|
def get_parent_link(self, p_id, parent_handle, rel):
|
||||||
|
"returns string of GraphViz edge linking child to parent"
|
||||||
|
style = ''
|
||||||
|
if (rel != RelLib.Person.CHILD_REL_BIRTH) and self.adoptionsdashed:
|
||||||
|
style = 'style=dotted'
|
||||||
|
parent = self.database.get_person_from_handle(parent_handle)
|
||||||
|
return '"p%s" -> "p%s" [%s];\n' % (p_id, parent.get_gramps_id(), style)
|
||||||
|
|
||||||
|
|
||||||
|
def get_persons_and_families(self):
|
||||||
|
"returns string of GraphViz nodes for persons and their families"
|
||||||
|
# The list of families for which we have output the node,
|
||||||
|
# so we don't do it twice
|
||||||
|
buffer = ""
|
||||||
|
families_done = {}
|
||||||
|
for person_handle in self.person_handles:
|
||||||
person = self.database.get_person_from_handle(person_handle)
|
person = self.database.get_person_from_handle(person_handle)
|
||||||
# Output the person's node.
|
p_id = person.get_gramps_id()
|
||||||
label = person.get_primary_name().get_name()
|
# Output the person's node
|
||||||
the_id = person.get_gramps_id().replace('-','_')
|
label = self.get_person_label(person)
|
||||||
if self.includeid:
|
style = self.get_gender_style(person)
|
||||||
label = label + " (%s)" % the_id
|
url = ""
|
||||||
if self.includedates:
|
|
||||||
birth_handle = person.get_birth_handle()
|
|
||||||
if birth_handle:
|
|
||||||
birth_event = self.database.get_event_from_handle(birth_handle)
|
|
||||||
birth = self.dump_event(birth_event)
|
|
||||||
else:
|
|
||||||
birth = ''
|
|
||||||
death_handle = person.get_death_handle()
|
|
||||||
if death_handle:
|
|
||||||
death_event = self.database.get_event_from_handle(death_handle)
|
|
||||||
death = self.dump_event(death_event)
|
|
||||||
else:
|
|
||||||
death = ''
|
|
||||||
label = label + '\\n(%s - %s)' % (birth, death)
|
|
||||||
self.f.write('p%s [shape=box, ' % the_id)
|
|
||||||
if self.includeurl:
|
if self.includeurl:
|
||||||
h = person.get_handle()
|
h = person_handle
|
||||||
self.f.write('URL="ppl/%s/%s/%s.html", ' % (h[0],h[1],h))
|
url = ', URL="ppl/%s/%s/%s.html", ' % (h[0],h[1],h)
|
||||||
if self.colorize != 'outline':
|
buffer += '"p%s" [label="%s", %s%s];\n' % (p_id, label, style, url)
|
||||||
if self.colorize == 'filled':
|
|
||||||
style = 'style=filled, fillcolor'
|
|
||||||
else:
|
|
||||||
style = 'color'
|
|
||||||
gender = person.get_gender()
|
|
||||||
if gender == person.MALE:
|
|
||||||
self.f.write('%s=%s, ' % (style, self.colors['male']))
|
|
||||||
elif gender == person.FEMALE:
|
|
||||||
self.f.write('%s=%s, ' % (style, self.colors['female']))
|
|
||||||
else:
|
|
||||||
self.f.write('%s=%s, ' % (style, self.colors['unknown']))
|
|
||||||
if self.latin:
|
|
||||||
label = label.encode('iso-8859-1')
|
|
||||||
self.f.write('fontname="%s", label="%s"];\n' % (self.fontname,label))
|
|
||||||
|
|
||||||
# Output families's nodes.
|
# Output families where person is a parent
|
||||||
if self.show_families:
|
if self.show_families:
|
||||||
family_list = person.get_family_handle_list()
|
family_list = person.get_family_handle_list()
|
||||||
for fam_handle in family_list:
|
for fam_handle in family_list:
|
||||||
fam = self.database.get_family_from_handle(fam_handle)
|
fam = self.database.get_family_from_handle(fam_handle)
|
||||||
fid = fam.get_gramps_id().replace('-','_')
|
fam_id = fam.get_gramps_id()
|
||||||
if fam_handle not in families_done:
|
if fam_handle not in families_done:
|
||||||
families_done.append(fam_handle)
|
families_done[fam_handle] = 1
|
||||||
self.f.write('f%s [shape=ellipse, ' % fid)
|
label = ""
|
||||||
if self.colorize == 'colored':
|
|
||||||
self.f.write('color=%s, ' % self.colors['family'])
|
|
||||||
elif self.colorize == 'filled':
|
|
||||||
self.f.write('style=filled fillcolor=%s, ' % self.colors['family'])
|
|
||||||
|
|
||||||
marriage = ""
|
|
||||||
for event_handle in fam.get_event_list():
|
for event_handle in fam.get_event_list():
|
||||||
if event_handle:
|
if event_handle:
|
||||||
event = self.database.get_event_from_handle(event_handle)
|
event = self.database.get_event_from_handle(event_handle)
|
||||||
if event.get_name() == "Marriage":
|
if event.get_name() == "Marriage":
|
||||||
m = event
|
label = self.get_event_string(event)
|
||||||
break
|
break
|
||||||
else:
|
|
||||||
m = None
|
|
||||||
|
|
||||||
if m:
|
|
||||||
marriage = self.dump_event(m)
|
|
||||||
if self.includeid:
|
if self.includeid:
|
||||||
marriage = marriage + " (%s)" % fid
|
label = "%s (%s)" % (label, fam_id)
|
||||||
self.f.write('fontname="%s", label="%s"];\n'
|
color = ""
|
||||||
% (self.fontname,marriage))
|
if self.colorize == 'colored':
|
||||||
|
color = ', color="%s"' % self.colors['family']
|
||||||
|
elif self.colorize == 'filled':
|
||||||
|
color = ', fillcolor="%s"' % self.colors['family']
|
||||||
|
buffer += '"f%s" [shape=ellipse, label="%s"%s];\n' % (fam_id, label, color)
|
||||||
# Link this person to all his/her families.
|
# Link this person to all his/her families.
|
||||||
self.f.write('f%s -> p%s [' % (fid, the_id))
|
if self.attract == "parents":
|
||||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
weight = 'weight="5"'
|
||||||
(self.arrowheadstyle, self.arrowtailstyle))
|
else:
|
||||||
self.f.write('style=solid];\n')
|
weight = ''
|
||||||
|
buffer += '"f%s" -> "p%s" [%s];\n' % (fam_id, p_id, weight)
|
||||||
|
return buffer
|
||||||
|
|
||||||
def dump_event(self,event):
|
|
||||||
|
def get_gender_style(self, person):
|
||||||
|
"return gender specific person style"
|
||||||
|
gender = person.get_gender()
|
||||||
|
if gender == person.MALE:
|
||||||
|
shape = 'shape="box"'
|
||||||
|
elif gender == person.FEMALE:
|
||||||
|
shape = 'shape="box", style="rounded"'
|
||||||
|
else:
|
||||||
|
shape = 'shape="hexagon"'
|
||||||
|
if self.colorize == 'outline':
|
||||||
|
return shape
|
||||||
|
else:
|
||||||
|
if gender == person.MALE:
|
||||||
|
color = self.colors['male']
|
||||||
|
elif gender == person.FEMALE:
|
||||||
|
color = self.colors['female']
|
||||||
|
else:
|
||||||
|
color = self.colors['unknown']
|
||||||
|
if self.colorize == 'filled':
|
||||||
|
# In current GraphViz boxes cannot be both rounded and filled
|
||||||
|
return 'shape="box", fillcolor="%s"' % color
|
||||||
|
else:
|
||||||
|
return '%s, color="%s"' % (shape, color)
|
||||||
|
|
||||||
|
def get_person_label(self, person):
|
||||||
|
"return person label string"
|
||||||
|
label = person.get_primary_name().get_name()
|
||||||
|
p_id = person.get_gramps_id()
|
||||||
|
if self.includeid:
|
||||||
|
label = label + " (%s)" % p_id
|
||||||
|
if self.includedates:
|
||||||
|
birth, death = self.get_date_strings(person)
|
||||||
|
label = label + '\\n(%s - %s)' % (birth, death)
|
||||||
|
return label.replace('"', '\\\"')
|
||||||
|
|
||||||
|
def get_date_strings(self, person):
|
||||||
|
"returns tuple of birth/christening and death/burying date strings"
|
||||||
|
birth_handle = person.get_birth_handle()
|
||||||
|
if birth_handle:
|
||||||
|
birth_event = self.database.get_event_from_handle(birth_handle)
|
||||||
|
birth = self.get_event_string(birth_event)
|
||||||
|
else:
|
||||||
|
birth = ''
|
||||||
|
death_handle = person.get_death_handle()
|
||||||
|
if death_handle:
|
||||||
|
death_event = self.database.get_event_from_handle(death_handle)
|
||||||
|
death = self.get_event_string(death_event)
|
||||||
|
else:
|
||||||
|
death = ''
|
||||||
|
if birth and death:
|
||||||
|
return (birth, death)
|
||||||
|
# missing info, use (first) christening/burial instead
|
||||||
|
for event_handle in person.get_event_list():
|
||||||
|
event = self.database.get_event_from_handle(event_handle)
|
||||||
|
if event.get_name() == "Christening":
|
||||||
|
if not birth:
|
||||||
|
birth = self.get_event_string(event)
|
||||||
|
elif event.get_name() == "Burial":
|
||||||
|
if not death:
|
||||||
|
death = self.get_event_string(event)
|
||||||
|
return (birth, death)
|
||||||
|
|
||||||
|
def get_event_string(self, event):
|
||||||
"""
|
"""
|
||||||
Compile an event label.
|
return string for for an event label.
|
||||||
|
|
||||||
Based on the data availability and preferences, we select one
|
Based on the data availability and preferences, we select one
|
||||||
of the following for a given event:
|
of the following for a given event:
|
||||||
@ -386,33 +531,6 @@ class GraphViz:
|
|||||||
return event.get_cause()
|
return event.get_cause()
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def write_header(self):
|
|
||||||
"""
|
|
||||||
Write header listing the options used.
|
|
||||||
"""
|
|
||||||
self.f.write("/* GRAMPS - Relationship graph\n")
|
|
||||||
self.f.write(" *\n")
|
|
||||||
self.f.write(" * Report options:\n")
|
|
||||||
self.f.write(" * font style : %s\n" % self.fontname)
|
|
||||||
self.f.write(" * style arrow head : %s\n" % self.arrowheadstyle)
|
|
||||||
self.f.write(" * tail : %s\n" % self.arrowtailstyle)
|
|
||||||
self.f.write(" * graph direction : %s\n" % self.rankdir)
|
|
||||||
self.f.write(" * include URLs : %s\n" % bool(self.includeurl))
|
|
||||||
self.f.write(" * IDs : %s\n" % bool(self.includeid))
|
|
||||||
self.f.write(" * dates : %s\n" % bool(self.includedates))
|
|
||||||
self.f.write(" * just year : %s\n" % bool(self.just_years))
|
|
||||||
self.f.write(" * place or cause : %s\n" % bool(self.placecause))
|
|
||||||
self.f.write(" * colorize : %s\n" % bool(self.colorize))
|
|
||||||
self.f.write(" * dotted adoptions : %s\n" % bool(self.adoptionsdashed))
|
|
||||||
self.f.write(" * show family nodes : %s\n" % bool(self.show_families))
|
|
||||||
self.f.write(" * margin : %3.2fin\n" % self.margin_small)
|
|
||||||
self.f.write(" * pages horizontal : %s\n" % self.hpages)
|
|
||||||
self.f.write(" * vertical : %s\n" % self.vpages)
|
|
||||||
self.f.write(" * page width : %3.2fin\n" % self.width)
|
|
||||||
self.f.write(" * height : %3.2fin\n" % self.height)
|
|
||||||
self.f.write(" *\n")
|
|
||||||
self.f.write(" * Generated on %s by GRAMPS\n" % asctime())
|
|
||||||
self.f.write(" */\n\n")
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -440,12 +558,17 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
'justyears' : 0,
|
'justyears' : 0,
|
||||||
'placecause' : 1,
|
'placecause' : 1,
|
||||||
'url' : 1,
|
'url' : 1,
|
||||||
|
'ratio' : "compress",
|
||||||
|
'attract' : "none",
|
||||||
'rankdir' : "LR",
|
'rankdir' : "LR",
|
||||||
'color' : "filled",
|
'color' : "filled",
|
||||||
'dashedl' : 1,
|
'dashedl' : 1,
|
||||||
'margin' : 1.0,
|
'margin' : 1.0,
|
||||||
|
'pagedir' : 'BL',
|
||||||
'pagesh' : 1,
|
'pagesh' : 1,
|
||||||
'pagesv' : 1,
|
'pagesv' : 1,
|
||||||
|
'note' : '',
|
||||||
|
'noteloc' : 'b',
|
||||||
'gvof' : 'ps',
|
'gvof' : 'ps',
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +600,13 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
'url' : ("=0/1","Whether to include URLs.",
|
'url' : ("=0/1","Whether to include URLs.",
|
||||||
["Do not include URLs","Include URLs"],
|
["Do not include URLs","Include URLs"],
|
||||||
True),
|
True),
|
||||||
'rankdir' : ("=str","Graph direction.",
|
'ratio' : ("=str","Graph aspect ratio.",
|
||||||
|
[ "%s\t%s" % (item[0],item[1]) for item in _options.ratio ],
|
||||||
|
False),
|
||||||
|
'attract' : ("=str","What to group closer.",
|
||||||
|
[ "%s\t%s" % (item[0],item[1]) for item in _options.attract ],
|
||||||
|
False),
|
||||||
|
'rankdir' : ("=str","Graph direction.",
|
||||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.rankdir ],
|
[ "%s\t%s" % (item[0],item[1]) for item in _options.rankdir ],
|
||||||
False),
|
False),
|
||||||
'color' : ("=str","Whether and how to colorize graph.",
|
'color' : ("=str","Whether and how to colorize graph.",
|
||||||
@ -488,10 +617,18 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
True),
|
True),
|
||||||
'margin' : ("=num","Margin size.",
|
'margin' : ("=num","Margin size.",
|
||||||
"Floating point value, in cm"),
|
"Floating point value, in cm"),
|
||||||
|
'pagedir' : ("=str","Paging direction.",
|
||||||
|
[ "%s\t%s" % (item[0],item[1]) for item in _options.pagedir ],
|
||||||
|
False),
|
||||||
'pagesh' : ("=num","Number of pages in horizontal direction.",
|
'pagesh' : ("=num","Number of pages in horizontal direction.",
|
||||||
"Integer values"),
|
"Integer values"),
|
||||||
'pagesv' : ("=num","Number of pages in vertical direction.",
|
'pagesv' : ("=num","Number of pages in vertical direction.",
|
||||||
"Integer values"),
|
"Integer values"),
|
||||||
|
'note' : ("=str","Note to add to the graph.",
|
||||||
|
"Text"),
|
||||||
|
'noteloc' : ("=str","Note location.",
|
||||||
|
[ "%s\t%s" % (item[0],item[1]) for item in _options.noteloc ],
|
||||||
|
False),
|
||||||
'gvof' : ("=str","Output format to convert dot file into.",
|
'gvof' : ("=str","Output format to convert dot file into.",
|
||||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.formats ],
|
[ "%s\t%s" % (item[0],item[1]) for item in _options.formats ],
|
||||||
False),
|
False),
|
||||||
@ -533,6 +670,22 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
def make_doc_menu(self,dialog,active=None):
|
def make_doc_menu(self,dialog,active=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def add_list(self, options, default):
|
||||||
|
"returns compobox of given options and default value"
|
||||||
|
box = gtk.ComboBox()
|
||||||
|
store = gtk.ListStore(str)
|
||||||
|
box.set_model(store)
|
||||||
|
cell = gtk.CellRendererText()
|
||||||
|
box.pack_start(cell,True)
|
||||||
|
box.add_attribute(cell,'text',0)
|
||||||
|
index = 0
|
||||||
|
for item in options:
|
||||||
|
store.append(row=[item[2]])
|
||||||
|
if item[0] == default:
|
||||||
|
box.set_active(index)
|
||||||
|
index = index + 1
|
||||||
|
return box
|
||||||
|
|
||||||
def add_user_options(self,dialog):
|
def add_user_options(self,dialog):
|
||||||
if self.handler.module_name == "rel_graph2":
|
if self.handler.module_name == "rel_graph2":
|
||||||
dialog.make_doc_menu = self.make_doc_menu
|
dialog.make_doc_menu = self.make_doc_menu
|
||||||
@ -586,36 +739,16 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
_("Include individual and family IDs."))
|
_("Include individual and family IDs."))
|
||||||
|
|
||||||
# GraphViz output options tab
|
# GraphViz output options tab
|
||||||
self.rank_box = gtk.ComboBox()
|
self.rank_box = self.add_list(_options.rankdir,
|
||||||
store = gtk.ListStore(str)
|
self.options_dict['rankdir'])
|
||||||
self.rank_box.set_model(store)
|
|
||||||
cell = gtk.CellRendererText()
|
|
||||||
self.rank_box.pack_start(cell,True)
|
|
||||||
self.rank_box.add_attribute(cell,'text',0)
|
|
||||||
index = 0
|
|
||||||
for item in _options.rankdir:
|
|
||||||
store.append(row=[item[2]])
|
|
||||||
if item[0] == self.options_dict['rankdir']:
|
|
||||||
self.rank_box.set_active(index)
|
|
||||||
index = index + 1
|
|
||||||
dialog.add_frame_option(_("GraphViz Options"),
|
dialog.add_frame_option(_("GraphViz Options"),
|
||||||
_("Graph direction"),
|
_("Graph direction"),
|
||||||
self.rank_box,
|
self.rank_box,
|
||||||
_("Whether generations go from top to bottom "
|
_("Whether generations go from top to bottom "
|
||||||
"or left to right."))
|
"or left to right."))
|
||||||
|
|
||||||
self.color_box = gtk.ComboBox()
|
self.color_box = self.add_list(_options.colors,
|
||||||
store = gtk.ListStore(str)
|
self.options_dict['color'])
|
||||||
self.color_box.set_model(store)
|
|
||||||
cell = gtk.CellRendererText()
|
|
||||||
self.color_box.pack_start(cell,True)
|
|
||||||
self.color_box.add_attribute(cell,'text',0)
|
|
||||||
index = 0
|
|
||||||
for item in _options.colors:
|
|
||||||
store.append(row=[item[2]])
|
|
||||||
if item[0] == self.options_dict['color']:
|
|
||||||
self.color_box.set_active(index)
|
|
||||||
index = index + 1
|
|
||||||
dialog.add_frame_option(_("GraphViz Options"),
|
dialog.add_frame_option(_("GraphViz Options"),
|
||||||
_("Graph coloring"),
|
_("Graph coloring"),
|
||||||
self.color_box,
|
self.color_box,
|
||||||
@ -623,39 +756,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
"with red. If the sex of an individual "
|
"with red. If the sex of an individual "
|
||||||
"is unknown it will be shown with gray."))
|
"is unknown it will be shown with gray."))
|
||||||
|
|
||||||
self.arrowstyle_box = gtk.ComboBox()
|
self.arrowstyle_box = self.add_list(_options.arrowstyles,
|
||||||
store = gtk.ListStore(str)
|
self.options_dict['arrow'])
|
||||||
self.arrowstyle_box.set_model(store)
|
|
||||||
cell = gtk.CellRendererText()
|
|
||||||
self.arrowstyle_box.pack_start(cell,True)
|
|
||||||
self.arrowstyle_box.add_attribute(cell,'text',0)
|
|
||||||
index = 0
|
|
||||||
for item in _options.arrowstyles:
|
|
||||||
store.append(row=[item[2]])
|
|
||||||
if item[0] == self.options_dict['arrow']:
|
|
||||||
self.arrowstyle_box.set_active(index)
|
|
||||||
index = index + 1
|
|
||||||
dialog.add_frame_option(_("GraphViz Options"),
|
dialog.add_frame_option(_("GraphViz Options"),
|
||||||
_("Arrowhead direction"),
|
_("Arrowhead direction"),
|
||||||
self.arrowstyle_box,
|
self.arrowstyle_box,
|
||||||
_("Choose the direction that the arrows point."))
|
_("Choose the direction that the arrows point."))
|
||||||
|
|
||||||
self.font_box = gtk.ComboBox()
|
self.font_box = self.add_list(_options.fonts,
|
||||||
store = gtk.ListStore(str)
|
self.options_dict['font'])
|
||||||
self.font_box.set_model(store)
|
|
||||||
cell = gtk.CellRendererText()
|
|
||||||
self.font_box.pack_start(cell,True)
|
|
||||||
self.font_box.add_attribute(cell,'text',0)
|
|
||||||
index = 0
|
|
||||||
for item in _options.fonts:
|
|
||||||
if item[3]:
|
|
||||||
name = "%s (iso-latin1 font)" % item[2]
|
|
||||||
else:
|
|
||||||
name = item[2]
|
|
||||||
store.append(row=[name])
|
|
||||||
if item[0] == self.options_dict['font']:
|
|
||||||
self.font_box.set_active(index)
|
|
||||||
index = index + 1
|
|
||||||
dialog.add_frame_option(_("GraphViz Options"),
|
dialog.add_frame_option(_("GraphViz Options"),
|
||||||
_("Font family"),
|
_("Font family"),
|
||||||
self.font_box,
|
self.font_box,
|
||||||
@ -664,6 +773,13 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
"FreeSans is available from: "
|
"FreeSans is available from: "
|
||||||
"http://www.nongnu.org/freefont/"))
|
"http://www.nongnu.org/freefont/"))
|
||||||
|
|
||||||
|
self.latin_cb = gtk.CheckButton(_("Output format/font requires text as latin-1"))
|
||||||
|
self.latin_cb.set_active(self.options_dict['latin'])
|
||||||
|
dialog.add_frame_option(_("GraphViz Options"), '',
|
||||||
|
self.latin_cb,
|
||||||
|
_("If text doesn't show correctly in report, use this. "
|
||||||
|
"Required e.g. for default font with PS output."))
|
||||||
|
|
||||||
self.adoptionsdashed_cb = gtk.CheckButton(_("Indicate non-birth relationships with dotted lines"))
|
self.adoptionsdashed_cb = gtk.CheckButton(_("Indicate non-birth relationships with dotted lines"))
|
||||||
self.adoptionsdashed_cb.set_active(self.options_dict['dashedl'])
|
self.adoptionsdashed_cb.set_active(self.options_dict['dashedl'])
|
||||||
dialog.add_frame_option(_("GraphViz Options"), '',
|
dialog.add_frame_option(_("GraphViz Options"), '',
|
||||||
@ -678,13 +794,31 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
_("Families will show up as ellipses, linked "
|
_("Families will show up as ellipses, linked "
|
||||||
"to parents and children."))
|
"to parents and children."))
|
||||||
|
|
||||||
# Page options tab
|
# Page/layout options tab
|
||||||
|
self.attract_box = self.add_list(_options.attract,
|
||||||
|
self.options_dict['attract'])
|
||||||
|
dialog.add_frame_option(_("Layout Options"),
|
||||||
|
_("What to group closer together"),
|
||||||
|
self.attract_box,
|
||||||
|
_("Whether to group parents or children "
|
||||||
|
"together or whether both have same "
|
||||||
|
"weights."))
|
||||||
|
|
||||||
|
self.ratio_box = self.add_list(_options.ratio,
|
||||||
|
self.options_dict['ratio'])
|
||||||
|
dialog.add_frame_option(_("Layout Options"),
|
||||||
|
_("Aspect ratio"),
|
||||||
|
self.ratio_box,
|
||||||
|
_("Affects greatly how the graph is layed out "
|
||||||
|
"on the page. Multiple pages overrides the "
|
||||||
|
"pages settings below."))
|
||||||
|
|
||||||
margin_adj = gtk.Adjustment(value=self.options_dict['margin'],
|
margin_adj = gtk.Adjustment(value=self.options_dict['margin'],
|
||||||
lower=0.0, upper=10.0, step_incr=1.0)
|
lower=0.0, upper=10.0, step_incr=1.0)
|
||||||
|
|
||||||
self.margin_sb = gtk.SpinButton(adjustment=margin_adj, digits=1)
|
self.margin_sb = gtk.SpinButton(adjustment=margin_adj, digits=1)
|
||||||
|
|
||||||
dialog.add_frame_option(_("Page Options"),
|
dialog.add_frame_option(_("Layout Options"),
|
||||||
_("Margin size"),
|
_("Margin size"),
|
||||||
self.margin_sb)
|
self.margin_sb)
|
||||||
|
|
||||||
@ -696,14 +830,14 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
self.hpages_sb = gtk.SpinButton(adjustment=hpages_adj, digits=0)
|
self.hpages_sb = gtk.SpinButton(adjustment=hpages_adj, digits=0)
|
||||||
self.vpages_sb = gtk.SpinButton(adjustment=vpages_adj, digits=0)
|
self.vpages_sb = gtk.SpinButton(adjustment=vpages_adj, digits=0)
|
||||||
|
|
||||||
dialog.add_frame_option(_("Page Options"),
|
dialog.add_frame_option(_("Layout Options"),
|
||||||
_("Number of Horizontal Pages"),
|
_("Number of Horizontal Pages"),
|
||||||
self.hpages_sb,
|
self.hpages_sb,
|
||||||
_("GraphViz can create very large graphs by "
|
_("GraphViz can create very large graphs by "
|
||||||
"spreading the graph across a rectangular "
|
"spreading the graph across a rectangular "
|
||||||
"array of pages. This controls the number "
|
"array of pages. This controls the number "
|
||||||
"pages in the array horizontally."))
|
"pages in the array horizontally."))
|
||||||
dialog.add_frame_option(_("Page Options"),
|
dialog.add_frame_option(_("Layout Options"),
|
||||||
_("Number of Vertical Pages"),
|
_("Number of Vertical Pages"),
|
||||||
self.vpages_sb,
|
self.vpages_sb,
|
||||||
_("GraphViz can create very large graphs "
|
_("GraphViz can create very large graphs "
|
||||||
@ -711,6 +845,32 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
"rectangular array of pages. This "
|
"rectangular array of pages. This "
|
||||||
"controls the number pages in the array "
|
"controls the number pages in the array "
|
||||||
"vertically."))
|
"vertically."))
|
||||||
|
self.pagedir_box = self.add_list(_options.pagedir,
|
||||||
|
self.options_dict['pagedir'])
|
||||||
|
dialog.add_frame_option(_("Layout Options"),
|
||||||
|
_("Paging direction"),
|
||||||
|
self.pagedir_box,
|
||||||
|
_("The order in which the graph pages are output."))
|
||||||
|
|
||||||
|
# Notes tab
|
||||||
|
self.textbox = gtk.TextView()
|
||||||
|
self.textbox.get_buffer().set_text(self.options_dict['note'])
|
||||||
|
self.textbox.set_editable(1)
|
||||||
|
swin = gtk.ScrolledWindow()
|
||||||
|
swin.set_shadow_type(gtk.SHADOW_IN)
|
||||||
|
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
||||||
|
swin.add(self.textbox)
|
||||||
|
dialog.add_frame_option(_("Notes"),
|
||||||
|
_("Note to add to the graph"),
|
||||||
|
swin,
|
||||||
|
_("This text will be added to the graph."))
|
||||||
|
self.noteloc_box = self.add_list(_options.noteloc,
|
||||||
|
self.options_dict['noteloc'])
|
||||||
|
dialog.add_frame_option(_("Notes"),
|
||||||
|
_("Note location"),
|
||||||
|
self.noteloc_box,
|
||||||
|
_("Whether note will on top or bottom of the page."))
|
||||||
|
|
||||||
|
|
||||||
def toggle_date(self, obj):
|
def toggle_date(self, obj):
|
||||||
self.just_years_cb.set_sensitive(self.includedates_cb.get_active())
|
self.just_years_cb.set_sensitive(self.includedates_cb.get_active())
|
||||||
@ -727,6 +887,10 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
self.options_dict['incid'] = int(self.includeid_cb.get_active())
|
self.options_dict['incid'] = int(self.includeid_cb.get_active())
|
||||||
self.options_dict['justyears'] = int(self.just_years_cb.get_active())
|
self.options_dict['justyears'] = int(self.just_years_cb.get_active())
|
||||||
self.options_dict['placecause'] = int(self.place_cause_cb.get_active())
|
self.options_dict['placecause'] = int(self.place_cause_cb.get_active())
|
||||||
|
self.options_dict['attract'] = \
|
||||||
|
_options.attract[self.attract_box.get_active()][0]
|
||||||
|
self.options_dict['ratio'] = \
|
||||||
|
_options.ratio[self.ratio_box.get_active()][0]
|
||||||
self.options_dict['rankdir'] = \
|
self.options_dict['rankdir'] = \
|
||||||
_options.rankdir[self.rank_box.get_active()][0]
|
_options.rankdir[self.rank_box.get_active()][0]
|
||||||
self.options_dict['color'] = \
|
self.options_dict['color'] = \
|
||||||
@ -735,8 +899,14 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
|||||||
_options.arrowstyles[self.arrowstyle_box.get_active()][0]
|
_options.arrowstyles[self.arrowstyle_box.get_active()][0]
|
||||||
self.options_dict['font'] = \
|
self.options_dict['font'] = \
|
||||||
_options.fonts[self.font_box.get_active()][0]
|
_options.fonts[self.font_box.get_active()][0]
|
||||||
self.options_dict['latin'] = \
|
self.options_dict['pagedir'] = \
|
||||||
_options.fonts[self.font_box.get_active()][3]
|
_options.pagedir[self.pagedir_box.get_active()][0]
|
||||||
|
self.options_dict['noteloc'] = \
|
||||||
|
_options.noteloc[self.noteloc_box.get_active()][0]
|
||||||
|
b = self.textbox.get_buffer()
|
||||||
|
self.options_dict['note'] = \
|
||||||
|
b.get_text(b.get_start_iter(), b.get_end_iter(), False)
|
||||||
|
|
||||||
if self.handler.module_name == "rel_graph2":
|
if self.handler.module_name == "rel_graph2":
|
||||||
self.options_dict['gvof'] = dialog.format_menu.get_format_str()
|
self.options_dict['gvof'] = dialog.format_menu.get_format_str()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user