From 4232d8b621a06c5258ccda573e22593d1142311f Mon Sep 17 00:00:00 2001 From: "Craig J. Anderson" Date: Tue, 15 Feb 2011 23:31:16 +0000 Subject: [PATCH] Updates to all three reports. Ancestor Descendant Family Descendant fixes error 4602, 4603 and other errors I found svn: r16626 --- src/plugins/drawreport/AncestorTree.py | 49 +++++--- src/plugins/drawreport/DescendTree.py | 151 +++++++++++++------------ src/plugins/lib/libtreebase.py | 97 ++++++++++------ 3 files changed, 178 insertions(+), 119 deletions(-) diff --git a/src/plugins/drawreport/AncestorTree.py b/src/plugins/drawreport/AncestorTree.py index 0f223e956..ef83cbeb9 100644 --- a/src/plugins/drawreport/AncestorTree.py +++ b/src/plugins/drawreport/AncestorTree.py @@ -62,6 +62,8 @@ from gui.plug.report import MenuReportOptions from gen.display.name import displayer as name_displayer +from gui.utils import ProgressMeter + PT2CM = ReportUtils.pt2cm #cm2pt = ReportUtils.cm2pt @@ -92,7 +94,7 @@ class AncestorBoxBase(BoxBase): """ Calculate the column or generation that this person is in. """ x_level = self.level[0] #Calculate which row in the column of people. - tmp_y = self.level[1] - (2**x_level) + tmp_y = self.level[2] - (2**x_level) #Calculate which row in the table (yes table) of people. delta = (2**max_gen) // (2**(x_level)) return int((delta/2) + (tmp_y*delta)) @@ -103,7 +105,7 @@ class PersonBox(AncestorBoxBase): """ def __init__(self, level): AncestorBoxBase.__init__(self, "AC2-box") - self.level = (X_INDEX(level), level) + self.level = (X_INDEX(level), 0, level) class FamilyBox(AncestorBoxBase): """ @@ -111,13 +113,13 @@ class FamilyBox(AncestorBoxBase): """ def __init__(self, level): AncestorBoxBase.__init__(self, "AC2-fam-box") - self.level = (X_INDEX(level)+1, level) + self.level = (X_INDEX(level)+1, 1, level) def y_index(self, max_gen): """ Calculate the column or generation that this person is in. """ x_level = self.level[0] - 1 #Calculate which row in the column of people. - tmp_y = self.level[1] - (2**x_level) + tmp_y = self.level[2] - (2**x_level) #Calculate which row in the table (yes table) of people. delta = (2**max_gen) // (2**(x_level)) return int((delta/2) + (tmp_y*delta)) @@ -128,11 +130,11 @@ class FamilyBox(AncestorBoxBase): # Line class # #------------------------------------------------------------------------ -class Line(LineBase): - """ Our line class.""" - def __init__(self, start): - LineBase.__init__(self, start) - self.linestr = 'AC2-line' +#class Line(LineBase): +# """ Our line class.""" +# def __init__(self, start): +# LineBase.__init__(self, start) +# self.linestr = 'AC2-line' #------------------------------------------------------------------------ @@ -274,13 +276,13 @@ class MakeAncestorTree(object): if father is None and mother is None: return - line = Line(person) + line = LineBase(person) if father: line.add_to(father) if mother: line.add_to(mother) - self.canvas.add_line(line) + person.line_to = line return line @@ -516,13 +518,13 @@ class MakeReport(): if box.width > self.doc.report_opts.max_box_width: self.doc.report_opts.max_box_width = box.width #+ box.shadow - if box.level[1] > 0: - if box.level[1] % 2 == 0 and box.height > self.father_ht: + if box.level[2] > 0: + if box.level[2] % 2 == 0 and box.height > self.father_ht: self.father_ht = box.height - elif box.level[1] % 2 == 1 and box.height > self.mother_ht: + elif box.level[2] % 2 == 1 and box.height > self.mother_ht: self.mother_ht = box.height - tmp = log2(box.level[1]) + tmp = log2(box.level[2]) if tmp > self.max_generations: self.max_generations = tmp @@ -612,15 +614,19 @@ class AncestorTree2(Report): """ Report.__init__(self, database, options_class) + self.progress = ProgressMeter(_('Ancestor Tree')) + self.connect = GUIConnect() self.connect.set__opts(options_class.menu) style_sheet = self.doc.get_style_sheet() font_normal = style_sheet.get_paragraph_style("AC2-Normal").get_font() - self.doc.report_opts = ReportOptions(self.doc, font_normal) + self.doc.report_opts = ReportOptions(self.doc, font_normal, 'AC2-line') self.canvas = Canvas(self.doc) + self.progress.set_pass(_('Making the Tree...'), 4) + #make the tree into self.canvas inlc_marr = self.connect.get_val('incmarr') self.max_generations = self.connect.get_val('maxgen') @@ -630,6 +636,8 @@ class AncestorTree2(Report): tree.start(self.connect.get_val('pid')) tree = None + self.progress.step() + #Title title = self.connect.title_class(self.doc) center = self.database.get_person_from_gramps_id( @@ -655,6 +663,8 @@ class AncestorTree2(Report): almost all of this should be moved into Canvas! """ + self.progress.step() + if self.connect.get_val('use_note'): note_box = NoteBox(self.doc, "AC2-fam-box", self.connect.get_val('note_local')) @@ -695,6 +705,7 @@ class AncestorTree2(Report): if prnnum: page_num_box = PageNumberBox(self.doc, 'AC2-box') + self.progress.step() ##################### #ok, everyone is now ready to print on the canvas. Paginate? self.canvas.paginate(colsperpage, one_page) @@ -703,6 +714,9 @@ class AncestorTree2(Report): #Yeah!!! #lets finally make some pages!!! ##################### + pages = self.canvas.page_count(incblank) + self.progress.set_pass(_('Printing the Tree...'), pages) + for page in self.canvas.page_iter_gen(incblank): self.doc.start_page() @@ -718,7 +732,10 @@ class AncestorTree2(Report): #Print the individual people and lines page.display() + self.progress.step() self.doc.end_page() + + self.progress.close() def scale_styles(self, scale): diff --git a/src/plugins/drawreport/DescendTree.py b/src/plugins/drawreport/DescendTree.py index ce0e2fdd5..d544b1b95 100644 --- a/src/plugins/drawreport/DescendTree.py +++ b/src/plugins/drawreport/DescendTree.py @@ -84,7 +84,6 @@ class DescendantBoxBase(BoxBase): BoxBase.__init__(self) self.boxstr = boxstr self.next = None - self.line_to = None self.father = None def calc_text(self, database, person, family): @@ -127,6 +126,8 @@ class PlaceHolderBox(BoxBase): BoxBase.__init__(self) self.boxstr = "None" self.level = level + self.line_to = None + self.next = None def calc_text(self, database, person, family): """ move along. Nothing to see here """ @@ -138,12 +139,12 @@ class PlaceHolderBox(BoxBase): # Line class # #------------------------------------------------------------------------ -class Line(LineBase): - """ Our line class.""" - - def __init__(self, start): - LineBase.__init__(self, start) - self.linestr = "CG2-line" +#class Line(LineBase): +# """ Our line class.""" +# +# def __init__(self, start): +# LineBase.__init__(self, start) +# self.linestr = "CG2-line" #------------------------------------------------------------------------ @@ -162,9 +163,13 @@ class DescendantTitleBase(TitleBox): If in the Family reports and there are two families, person_list2 will be used. """ - + + if len(person_list) == len(person_list2) == 1: + person_list = person_list + person_list2 + person_list2 = [] + names = self._get_names(person_list) - + if person_list2: names2 = self._get_names(person_list2) if len(names) + len(names2) == 3: @@ -413,7 +418,7 @@ class RecurseDown: self.cols.append(None) self.__last_direct.append(None) - if self.cols[level]: + if self.cols[level]: #if (not the first box in this column) last_box = self.cols[level] last_box.next = box @@ -429,7 +434,11 @@ class RecurseDown: box.y_cm += self.canvas.doc.report_opts.box_mgap if box.level[1] == 0 and self.__last_direct[level]: - if box.father != self.__last_direct[level].father: + #ok, a new direct descendant. + #print level, box.father is not None, self.__last_direct[level].father is not None, box.text[0], \ + # self.__last_direct[level].text[0] + if box.father != self.__last_direct[level].father and \ + box.father != self.__last_direct[level]: box.y_cm += self.canvas.doc.report_opts.box_pgap self.cols[level] = box @@ -443,6 +452,7 @@ class RecurseDown: def add_person_box(self, level, indi_handle, fams_handle, father): """ Makes a person box and add that person into the Canvas. """ myself = PersonBox(level) + myself.father = father if myself.level[1] == 0 and self.bold_direct and self.bold_now: if self.bold_now == 1: @@ -451,15 +461,14 @@ class RecurseDown: if level[1] == 0 and father and myself.level[0] != father.level[0]: #I am a child - if not father.line_to: - line = Line(father) - father.line_to = line - self.canvas.add_line(father.line_to) - else: + if father.line_to: line = father.line_to + else: + line = LineBase(father) + father.line_to = line + #self.canvas.add_line(line) - father.line_to.end.append(myself) - myself.father = father + line.end.append(myself) #calculate the text. myself.calc_text(self.database, indi_handle, fams_handle) @@ -528,8 +537,6 @@ class RecurseDown: spouse_handle, family_handle, who) if s_level > 0: spouse = _spouse_box(father) - elif first == 1: - spouse = _spouse_box(myself) elif self.inlc_marr: spouse = _spouse_box(marr) else: @@ -542,6 +549,8 @@ class RecurseDown: for child_ref in mykids: if self.inlc_marr and self.max_spouses > 0: _child_recurse(marr) + elif first == 1 and s_level == 0: + _child_recurse(myself) elif spouse: _child_recurse(spouse) else: @@ -586,18 +595,19 @@ class RecurseDown: (level, 0), None, None, father_b) retrn.append(mother_b) + family_line = family_b if self.inlc_marr else father_b for child_ref in family.get_child_ref_list(): - self.recurse(child_ref.ref, level+1, 0, - family_b if self.inlc_marr else father_b) + self.recurse(child_ref.ref, level+1, 0, family_line) self.bold_now = 0 - #Future code. - family_line = family_b if self.inlc_marr else father_b - if family_line.line_to: - if self.inlc_marr: - family_line.line_to.start.append(father_b) - family_line.line_to.start.append(mother_b) + #Set up the lines for the family + if not family_line.line_to: + #no children. + family_line.line_to = LineBase(family_line) + if self.inlc_marr: + family_line.line_to.start.append(father_b) + family_line.line_to.start.append(mother_b) return retrn @@ -834,10 +844,11 @@ class MakeFamilyTree(RecurseDown): #make sure there is at least one child in this family. #if not put in a placeholder family1_line = family1_l[1] if self.inlc_marr else family1_l[0] - if family1_line.line_to and not family1_line.line_to.end: - box = PlaceHolderBox((father1_b[0]+1, 0)) + if family1_line.line_to.end == []: + box = PlaceHolderBox((mother1_b.level[0]+1, 0)) + box.father = family1_l[0] self.add_to_col(box) - line.end = [box] + family1_line.line_to.end = [box] ####################### ####################### @@ -896,7 +907,7 @@ class MakeFamilyTree(RecurseDown): family2_line = family2_l[1] if self.inlc_marr else family2_l[0] family2_line = family2_line.line_to - if family2_line.end: + if family2_line.end != []: family2_line.end.insert(0, mother1_b) else: family2_line.end = [mother1_b] @@ -993,36 +1004,39 @@ class MakeReport(object): get this family block. """ while box: left_group = [] + line = None #Form the parental (left) group. #am I a direct descendant? if box.level[1] == 0: #I am the father/mother. left_group.append(box) + if box.line_to: + line = box.line_to box = box.next if box and box.level[1] != 0 and self.inlc_marr: #add/start with the marriage box left_group.append(box) + if box.line_to: + line = box.line_to box = box.next if box and box.level[1] != 0 and self.max_spouses > 0: #add/start with the spousal box left_group.append(box) + if box.line_to: + line = box.line_to box = box.next - - right_group = [] - #Form the children (right) group. - for spouses in left_group: - if spouses.line_to: - right_group += spouses.line_to.end - #will only be one. but in the family report, - #Dad and mom point to the same line - break - - #we now have everyone we want - if right_group: - return left_group, right_group + + if line: + if len(line.start) > 1 and line.start[-1].level[1] == 0: + #a dad and mom family from RecurseDown.add_family. add mom + left_group.append(line.start[-1]) + box = box.next + + #we now have everyone we want + return left_group, line.end #else # no children, so no family. go again until we find one to return. @@ -1031,7 +1045,7 @@ class MakeReport(object): def __reverse_family_group(self): """ go through the n-1 to 0 cols of boxes looking for famalies (parents with children) that may need to be moved. """ - for x_col in range(len(self.cols)-2, -1, -1): + for x_col in range(len(self.cols)-1, -1, -1): box = self.cols[x_col][0] #The first person in this col while box: left_group, right_group = self.__next_family_group(box) @@ -1104,42 +1118,37 @@ class MakeReport(object): amt = (right_y_cm - left_y_cm) self.__move_col_from_here_down(left_group[0], amt) - #6. now check to see if we are working with dad. + #6. now check to see if we are working with dad and mom. #if so we need to move down mariage information #and mom! left_line = left_group[0].line_to if not left_line: left_line = left_group[1].line_to - left_group = left_line.start + #left_line = left_line.start - if len(left_group) > 1 and not seen_parents: + if len(left_line.start) > 1 and not seen_parents: + #only do Dad and Mom. len(left_line) > 1 seen_parents = True - #only do Dad and Mom. len(left_group) > 1 - #works great when No marriage info - #This code needs work. when there is marriage info. - left_up = left_group[0].y_cm - left_down = left_group[-1].y_cm + left_group[-1].height - right_up = right_group[0].y_cm - right_down = right_group[-1].y_cm + right_group[-1].height - - #if the parents height is less than the children height + + mom_cm = left_group[-1].y_cm + left_group[-1].height/2 + last_child_cm = right_group[-1].y_cm + if not self.compress_tree: + last_child_cm += right_group[-1].height/2 + move_amt = last_child_cm - mom_cm + + #if the moms height is less than the last childs height #The 0.2 is to see if this is even worth it. - if (left_down-left_up+0.2) < (right_down-right_up): + if move_amt > 0.2: #our children take up more space than us parents. - #so space us parents out! - - #move Dad - if self.compress_tree: - left_group[0].y_cm += right_group[0].height/2 - - move_amt = right_group[-1].y_cm + right_group[-1].height/2 - move_amt -= (left_group[-1].y_cm + left_group[-1].height/2) - #move Mom - self.__move_col_from_here_down(left_group[-1], move_amt) + #so space mom out! + self.__move_col_from_here_down(left_group[-1], move_amt) #move marriage info if self.inlc_marr: - left_group[0].next.y_cm += move_amt/2 + left_group[1].y_cm += move_amt/2 + + if left_line.end[0].boxstr == 'None': + left_line.end = [] def start(self): """Make the report""" @@ -1268,7 +1277,7 @@ class Descend2Tree(Report): style_sheet = self.doc.get_style_sheet() font_normal = style_sheet.get_paragraph_style("CG2-Normal").get_font() - self.doc.report_opts = ReportOptions(self.doc, font_normal) + self.doc.report_opts = ReportOptions(self.doc, font_normal, "CG2-line") self.canvas = Canvas(self.doc) diff --git a/src/plugins/lib/libtreebase.py b/src/plugins/lib/libtreebase.py index f62e7b5b8..4ce3fbcef 100644 --- a/src/plugins/lib/libtreebase.py +++ b/src/plugins/lib/libtreebase.py @@ -246,6 +246,17 @@ class Canvas(Page): height = len(box.text) * font.get_size() * 1.5 height += 1.0/2.0 * font.get_size() #funny number(s) based upon font. box.height = PT2CM(height) + + def page_count(self, incblank): + count = 0 + if incblank: + return self.y_pages * self.x_pages + + for y_p in range(self.y_pages): + for x_p in range(self.x_pages): + if self.__pages.has_key((x_p, y_p)): + count += 1 + return count def page_iter_gen(self, incblank): """ generate the pages of the report. do so in a left to right @@ -419,30 +430,30 @@ class Canvas(Page): def __paginate_lines(self, x_page_offsets, page_y_top): """ Step three go through the lines and put each in page(s) """ - for line in self.lines: - pages = [] - #if type(line.start) == type([]): - pages = [] + for box1 in self.boxes: + if not box1.line_to: + continue + + line = box1.line_to + + pages = [box1.page.y_page_num] + end = line.start + line.end - #else: - # end = [line.start] + line.end - # pages = [] - start_x_page = end[0].page.x_page_num + x_page = box1.page.x_page_num start_y_page = end[0].page.y_page_num end_y_page = end[0].page.y_page_num for box in end: - x_page = box.page.x_page_num y_page = box.page.y_page_num - if (x_page, y_page) not in pages: + if y_page not in pages: if not self.__pages.has_key((x_page, y_page)): #Add the new page into the dictionary self.__new_page(x_page, y_page, x_page_offsets[x_page], page_y_top[y_page]) - self.__pages[x_page, y_page].add_line(line) - pages.append((x_page, y_page)) + self.__pages[x_page, y_page].add_line(box1.line_to) + pages.append(y_page) if y_page < start_y_page: start_y_page = y_page @@ -451,15 +462,15 @@ class Canvas(Page): #if len(end) = 2 & end[0].y_page = 0 & end[1].y_page = 4 #the line will not print on y_pages 1,2,3. Fix that here. - x_page = start_x_page + #x_page = start_x_page for y_page in range(start_y_page, end_y_page+1): - if (x_page, y_page) not in pages: + if y_page not in pages: if not self.__pages.has_key((x_page, y_page)): #Add the new page into the dictionary self.__new_page(x_page, y_page, x_page_offsets[x_page], page_y_top[y_page]) - self.__pages[x_page, y_page].add_line(line) + self.__pages[x_page, y_page].add_line(box1.line_to) def __paginate_title(self, x_page_offsets): #step four work with the title @@ -555,11 +566,16 @@ class BoxBase(object): #'None' will cause an error. Sub-classes will init self.boxstr = "None" self.text = "" - self.level = (0,) #which column/level am I in? int zero based. + #level requires ... + # (# - which column am I in (zero based) + # ,# - Am I a (0)direct descendant/ancestor or (>0)other + # , ) - anything else the report needs to run + self.level = (0,0) self.x_cm = 0.0 self.y_cm = 0.0 self.width = 0.0 self.height = 0.0 + self.line_to = None def scale(self, scale_amount): """ Scale the amounts """ @@ -571,15 +587,30 @@ class BoxBase(object): def display(self): """ display the box accounting for page x, y offsets Ignore any box with 'None' is boxstr """ - if self.boxstr != "None": - text = '\n'.join(self.text) - xbegin = self.x_cm - self.page.page_x_offset - ybegin = self.y_cm - self.page.page_y_offset - - self.page.doc.draw_box(self.boxstr, - text, - xbegin, ybegin, - self.width, self.height) + if self.boxstr == "None": + return + + text = '\n'.join(self.text) + xbegin = self.x_cm - self.page.page_x_offset + ybegin = self.y_cm - self.page.page_y_offset + + self.page.doc.draw_box(self.boxstr, + text, + xbegin, ybegin, + self.width, self.height) + + #I am responsible for my own lines. Do them here. + if self.line_to: + #draw my line out here. + self.line_to.display(self.page) + if self.page.x_page_num > 0 and self.level[1] == 0 and \ + xbegin < self.page.doc.report_opts.littleoffset*2: + #I am a child on the first column + yme = ybegin + self.height/2 + self.page.doc.draw_line(self.page.doc.report_opts.line_str, \ + 0, yme, xbegin, yme) + + class TitleBox(BoxBase): """ @@ -661,7 +692,6 @@ class PageNumberBox(BoxBase): self.x_cm = self.doc.get_usable_width() - self.width self.y_cm = self.doc.get_usable_height() - self.height - def display(self, page): """ If this is the first time I am ran, get my position then display the page number """ @@ -763,7 +793,7 @@ class LineBase(object): self.end are the boxes that we are drawing lines to. """ def __init__(self, start): - self.linestr = "None" + #self.linestr = "None" self.start = [start] self.end = [] @@ -774,7 +804,7 @@ class LineBase(object): def display(self, page): """ display the line. left to right line. one start, multiple end. page will tell us what parts of the line we can print """ - if self.end == []: + if self.end == [] and len(self.start) == 1: return # y_cm and x_cm start points - take into account page offsets @@ -783,6 +813,7 @@ class LineBase(object): # self.start = [self.start] start = self.start[0] doc = start.page.doc + linestr = doc.report_opts.line_str xbegin = start.x_cm + start.width - page.page_x_offset # out 3/4 of the way and x_cm end point(s) @@ -796,7 +827,7 @@ class LineBase(object): yme = box.y_cm + box.height/2 - page.page_y_offset if box.page.y_page_num == page.y_page_num: # and 0 < yme < usable_height and \ - doc.draw_line(self.linestr, xbegin, yme, x34, yme) + doc.draw_line(linestr, xbegin, yme, x34, yme) #2 - veritcal line mid = [] @@ -810,7 +841,7 @@ class LineBase(object): if mid[1] > usable_height: mid[1] = usable_height #draw the connecting vertical line. - doc.draw_line(self.linestr, x34, mid[0], x34, mid[1]) + doc.draw_line(linestr, x34, mid[0], x34, mid[1]) else: x34 = 0 @@ -818,7 +849,7 @@ class LineBase(object): for box in self.end: if box.page.y_page_num == page.y_page_num: yme = box.y_cm + box.height/2 - box.page.page_y_offset - doc.draw_line(self.linestr, x34, yme, xend, yme) + doc.draw_line(linestr, x34, yme, xend, yme) #------------------------------------------------------------------------ @@ -835,7 +866,7 @@ class ReportOptions(object): the left hand spacing for spouses (Descendant report only) """ - def __init__(self, doc, normal_font): + def __init__(self, doc, normal_font, normal_line): """ initalize various report variables that are used """ self.box_pgap = PT2CM(1.25*normal_font.get_size()) #gap between persons self.box_mgap = self.box_pgap /2 #gap between marriage information @@ -845,6 +876,8 @@ class ReportOptions(object): self.col_width = PT2CM(doc.string_width(normal_font, "(000,0)")) self.littleoffset = PT2CM(1) self.x_cm_cols = [self.littleoffset] + + self.line_str = normal_line #Things that will get added later self.max_box_width = 0