Example #1
0
    def __create_gui(self):
        vbox = Gtk.VBox(orientation=Gtk.Orientation.VERTICAL)
        vbox.set_spacing(4)

        label = Gtk.Label(
            _("This gramplet allows setting properties for multiple places at the same time"
              ))
        label.set_halign(Gtk.Align.START)
        label.set_line_wrap(True)
        vbox.pack_start(label, False, True, 0)

        pt_label = Gtk.Label(_('Place type:'))
        pt_label.set_halign(Gtk.Align.START)
        self.typecombo = Gtk.ComboBoxText.new_with_entry()
        self.typecombo.set_tooltip_text(
            _("New place type for the selected places"))
        self.__fill_combo(self.typecombo,
                          list(self.__typenames()),
                          wrap_width=4)

        tag_label = Gtk.Label(_('Tag:'))
        tag_label.set_halign(Gtk.Align.START)
        self.tagcombo = Gtk.ComboBoxText.new_with_entry()
        self.tagcombo.set_tooltip_text(_("New tag for the selected places"))
        self.__fill_combo(self.tagcombo, list(self.__tagnames()))

        date_label = Gtk.Label(_('Timespan:'))
        date_label.set_halign(Gtk.Align.START)
        self.date_entry = ValidatableMaskedEntry()
        date_button = Gtk.Button.new_from_icon_name("gramps-date", -1)
        timespan_tooltip = _("Set timespan for enclosing places")
        date_label.set_tooltip_text(timespan_tooltip)
        date_button.set_tooltip_text(timespan_tooltip)
        self.date_entry.set_tooltip_text(timespan_tooltip)
        self.date_object = Date()
        self.track = []
        self.date_field = MonitoredDate(self.date_entry, date_button,
                                        self.date_object, self.uistate,
                                        self.track)

        label1 = Gtk.Label(_("New enclosing place:"))
        label1.set_halign(Gtk.Align.START)
        label1.set_line_wrap(True)
        self.label1 = label1

        self.enclosing_place = Gtk.Label(_("None"))
        self.enclosing_place.set_halign(Gtk.Align.START)
        self.enclosing_place.set_tooltip_text(
            _("New enclosing place for the selected places"))

        pt_grid = Gtk.Grid(column_spacing=10, row_spacing=2)
        pt_grid.attach(pt_label, 0, 0, 1, 1)
        pt_grid.attach(self.typecombo, 1, 0, 1, 1)

        pt_grid.attach(tag_label, 0, 1, 1, 1)
        pt_grid.attach(self.tagcombo, 1, 1, 1, 1)

        pt_grid.attach(date_label, 0, 2, 1, 1)
        pt_grid.attach(self.date_entry, 1, 2, 1, 1)
        pt_grid.attach(date_button, 2, 2, 1, 1)

        pt_grid.attach(label1, 0, 3, 1, 1)
        pt_grid.attach(self.enclosing_place, 1, 3, 1, 1)

        vbox.pack_start(pt_grid, False, True, 0)

        but_set_enclosing = Gtk.Button(label=_('Select enclosing place'))
        but_set_enclosing.connect("clicked", self.cb_select)
        but_set_enclosing.set_tooltip_text(
            _("Select a new enclosing place for the selected places"))
        vbox.pack_start(but_set_enclosing, False, True, 10)

        self.clear_enclosing = Gtk.CheckButton(
            _("Clear original enclosing places"))
        self.clear_enclosing.set_tooltip_text(
            _("If checked then any previous enclosing place will be removed from the selected places"
              ))
        vbox.pack_start(self.clear_enclosing, False, True, 0)

        self.clear_tags = Gtk.CheckButton(_("Clear tags"))
        self.clear_tags.set_tooltip_text(
            _("If checked then any previous tag will be removed from the selected places"
              ))
        vbox.pack_start(self.clear_tags, False, True, 0)

        self.generate_hierarchy = Gtk.CheckButton(_("Generate hierarchy"))
        self.generate_hierarchy.connect("clicked",
                                        self.cb_select_generate_hierarchy)
        self.generate_hierarchy.set_tooltip_text(
            _("If checked then a place hierarchy will be generated, based on the names of the original places"
              ))
        vbox.pack_start(self.generate_hierarchy, False, True, 0)

        box1 = Gtk.VBox()
        box1.set_margin_left(20)

        box2 = Gtk.HBox()

        box2.pack_start(Gtk.Label(_("Separator:")), False, True, 0)

        group = None
        rownum = 0
        group = Gtk.RadioButton.new_with_label_from_widget(group, _("Comma"))
        group.connect("toggled", self.cb_set_sep, ',')
        group.set_tooltip_text(
            _("If selected then the original names will be split at commas to create the new hierarchy"
              ))
        group.set_sensitive(False)
        box2.pack_start(group, False, True, 0)
        group.set_active(True)

        rownum += 1
        group = Gtk.RadioButton.new_with_label_from_widget(group, _("Space"))
        group.connect("toggled", self.cb_set_sep, None)
        group.set_tooltip_text(
            _("If selected then the original names will be split at blank spaces to create the new hierarchy"
              ))
        group.set_sensitive(False)
        box2.pack_start(group, False, True, 0)
        self.sep_group = group

        box1.pack_start(box2, False, True, 0)

        self.reverse = Gtk.CheckButton(_("reverse hierarchy"))
        self.reverse.set_tooltip_text(
            _("If checked then the original name is assumed to start with the largest place in the hierarchy"
              ))
        self.reverse.set_sensitive(False)
        box1.pack_start(self.reverse, False, True, 0)

        vbox.pack_start(box1, False, True, 0)

        self.replace_text = Gtk.CheckButton(_("Replace text"))
        self.replace_text.set_tooltip_text(
            _("If checked then a specified text is replaced with a new text in the selected place names"
              ))
        self.replace_text.connect("clicked", self.cb_select_replace_text)

        self.use_regex = Gtk.CheckButton(_("Use regex"))
        self.use_regex.set_tooltip_text(
            _("If checked then the old text can be a regular expression and the new text can contain substitutions (\\1, \\2 etc.)"
              ))
        self.use_regex.set_sensitive(False)

        replace_text_box = Gtk.HBox()
        replace_text_box.pack_start(self.replace_text, False, True, 0)
        replace_text_box.pack_start(self.use_regex, False, True, 0)
        vbox.pack_start(replace_text_box, False, True, 0)

        old_text_label = Gtk.Label(_("Old text:"))
        self.old_text = Gtk.Entry()
        self.old_text.set_sensitive(False)
        self.old_text.set_tooltip_text(
            _("The original text (or regular expression) to be  replaced"))

        new_text_label = Gtk.Label(_("New text:"))
        self.new_text = Gtk.Entry()
        self.new_text.set_sensitive(False)
        self.new_text.set_tooltip_text(
            _("The new text that will replace the old text"))

        replace_grid = Gtk.Grid(column_spacing=10)
        replace_grid.set_margin_left(20)
        replace_grid.attach(old_text_label, 1, 0, 1, 1)
        replace_grid.attach(self.old_text, 2, 0, 1, 1)
        replace_grid.attach(new_text_label, 1, 1, 1, 1)
        replace_grid.attach(self.new_text, 2, 1, 1, 1)
        vbox.pack_start(replace_grid, False, True, 0)

        but_clear = Gtk.Button(label=_('Clear selections'))
        but_clear.connect("clicked", self.cb_clear)
        but_clear.set_tooltip_text(_("Clears all settings"))
        vbox.pack_start(but_clear, False, True, 10)

        but_apply = Gtk.Button(label=_('Apply to selected places'))
        but_apply.connect("clicked", self.cb__apply)
        but_apply.set_tooltip_text(
            _("Executes all specified operations for selected places"))
        vbox.pack_start(but_apply, False, True, 0)

        vbox.show_all()
        return vbox
Example #2
0
    def print_page(self, month):
        """
        This method actually writes the calendar page.
        """
        style_sheet = self.doc.get_style_sheet()
        ptitle = style_sheet.get_paragraph_style("CAL-Title")
        ptext = style_sheet.get_paragraph_style("CAL-Text")
        pdaynames = style_sheet.get_paragraph_style("CAL-Daynames")
        pnumbers = style_sheet.get_paragraph_style("CAL-Numbers")
        numpos = pt2cm(pnumbers.get_font().get_size())
        ptext1style = style_sheet.get_paragraph_style("CAL-Text1style")
        long_days = self._ldd.long_days

        self.doc.start_page()
        width = self.doc.get_usable_width()
        height = self.doc.get_usable_height()
        header = 2.54 # one inch
        mark = None
        if month == 1:
            mark = IndexMark(self._('Calendar Report'), INDEX_TYPE_TOC, 1)
        self.draw_rectangle("CAL-Border", 0, 0, width, height)
        self.doc.draw_box("CAL-Title", "", 0, 0, width, header, mark)
        self.doc.draw_line("CAL-Border", 0, header, width, header)
        year = self.year
        # assume every calendar header in the world is "<month-name> <year>"
        title = "%s %s" % (self._ldd.long_months[month].capitalize(),
                           self._get_date(Date(self.year))) # localized year
        mark = IndexMark(title, INDEX_TYPE_TOC, 2)
        font_height = pt2cm(ptitle.get_font().get_size())
        self.doc.center_text("CAL-Title", title,
                             width/2, font_height * 0.25, mark)
        cell_width = width / 7
        cell_height = (height - header)/ 6
        current_date = datetime.date(year, month, 1)
        spacing = pt2cm(1.25 * ptext.get_font().get_size()) # 158
        if current_date.isoweekday() != g2iso(self.start_dow + 1):
            # Go back to previous first day of week, and start from there
            current_ord = (current_date.toordinal() -
                           ((current_date.isoweekday() + 7) -
                            g2iso(self.start_dow + 1)) % 7)
        else:
            current_ord = current_date.toordinal()
        for day_col in range(7):
            font_height = pt2cm(pdaynames.get_font().get_size())
            self.doc.center_text("CAL-Daynames",
                                 long_days[(day_col+ g2iso(self.start_dow + 1))
                                                        % 7 + 1].capitalize(),
                                 day_col * cell_width + cell_width/2,
                                 header - font_height * 1.5)
        for week_row in range(6):
            something_this_week = 0
            for day_col in range(7):
                thisday = current_date.fromordinal(current_ord)
                if thisday.month == month:
                    something_this_week = 1
                    self.draw_rectangle("CAL-Border", day_col * cell_width,
                                        header + week_row * cell_height,
                                        (day_col + 1) * cell_width,
                                        header + (week_row + 1) * cell_height)
                    last_edge = (day_col + 1) * cell_width
                    self.doc.center_text("CAL-Numbers", str(thisday.day),
                                         day_col * cell_width + cell_width/2,
                                         header + week_row * cell_height)
                    list_ = self.calendar.get(month, {}).get(thisday.day, [])
                    list_.sort() # to get CAL-Holiday on bottom
                    position = spacing
                    for (format, p, m_list) in list_:
                        for line in reversed(p.split("\n")):
                            # make sure text will fit:
                            if position - 0.1 >= cell_height - numpos: # font daynums
                                break
                            font = ptext.get_font()
                            line = string_trim(font, line, cm2pt(cell_width + 0.2))
                            self.doc.draw_text(format, line,
                                               day_col * cell_width + 0.1,
                                               header + (week_row + 1) * cell_height - position - 0.1, m_list[0])
                            if len(m_list) > 1: # index the spouse too
                                self.doc.draw_text(format, "",0,0, m_list[1])
                            position += spacing
                current_ord += 1
        if not something_this_week:
            last_edge = 0
        font_height = pt2cm(1.5 * ptext1style.get_font().get_size())
        x = last_edge + (width - last_edge)/2
        text1 = str(self.text1)
        if text1 == _(_TITLE1):
            text1 = self._(_TITLE1)
        self.doc.center_text("CAL-Text1style", text1,
                             x, height - font_height * 3)
        text2 = str(self.text2)
        if text2 == _(_TITLE2):
            text2 = self._(_TITLE2)
        self.doc.center_text("CAL-Text2style", text2,
                             x, height - font_height * 2)
        self.doc.center_text("CAL-Text3style", self.text3,
                             x, height - font_height * 1)
        self.doc.end_page()
Example #3
0
    def collect_data(self):
        """
        This method runs through the data, and collects the relevant dates
        and text.
        """
        db = self.database
        people = db.iter_person_handles()
        people = self.filter.apply(self.database, people, user=self._user)

        ngettext = self._locale.translation.ngettext  # to see "nearby" comments

        with self._user.progress(_('Calendar Report'),
                                 _('Reading database...'),
                                 len(people)) as step:
            for person_handle in people:
                step()
                person = db.get_person_from_handle(person_handle)
                mark = utils.get_person_mark(db, person)
                birth_ref = person.get_birth_ref()
                birth_date = None
                if birth_ref:
                    birth_event = db.get_event_from_handle(birth_ref.ref)
                    birth_date = birth_event.get_date_object()

                if (self.birthdays and birth_date is not None
                        and birth_date.is_valid()):
                    birth_date = gregorian(birth_date)

                    year = birth_date.get_year()
                    month = birth_date.get_month()
                    day = birth_date.get_day()

                    prob_alive_date = Date(self.year, month, day)

                    nyears = self.year - year
                    # add some things to handle maiden name:
                    father_lastname = None  # husband, actually
                    if self.maiden_name in ['spouse_first', 'spouse_last'
                                            ]:  # get husband's last name:
                        if person.get_gender() == Person.FEMALE:
                            family_list = person.get_family_handle_list()
                            if family_list:
                                if self.maiden_name == 'spouse_first':
                                    fhandle = family_list[0]
                                else:
                                    fhandle = family_list[-1]
                                fam = db.get_family_from_handle(fhandle)
                                father_handle = fam.get_father_handle()
                                mother_handle = fam.get_mother_handle()
                                if mother_handle == person_handle:
                                    if father_handle:
                                        father = db.get_person_from_handle(
                                            father_handle)
                                        if father:
                                            father_lastname = father.get_primary_name(
                                            ).get_surname()
                    short_name = self.get_name(person, father_lastname)
                    alive = probably_alive(person, db, prob_alive_date)

                    if not self.alive or alive:
                        if nyears == 0:
                            text = self._('%(person)s, birth') % {
                                'person': short_name
                            }
                        else:
                            # translators: leave all/any {...} untranslated
                            text = ngettext('{person}, {age}',
                                            '{person}, {age}',
                                            nyears).format(person=short_name,
                                                           age=nyears)
                        self.add_day_item(text, month, day, marks=[mark])
                if self.anniversaries:
                    family_list = person.get_family_handle_list()
                    for fhandle in family_list:
                        fam = db.get_family_from_handle(fhandle)
                        father_handle = fam.get_father_handle()
                        mother_handle = fam.get_mother_handle()
                        if father_handle == person.get_handle():
                            spouse_handle = mother_handle
                        else:
                            continue  # with next person if the father is not "person"
                            # this will keep from duplicating the anniversary
                        if spouse_handle:
                            spouse = db.get_person_from_handle(spouse_handle)
                            if spouse:
                                s_m = utils.get_person_mark(db, spouse)
                                spouse_name = self.get_name(spouse)
                                short_name = self.get_name(person)
                                # TEMP: this will handle ordered events
                                # Gramps 3.0 will have a new mechanism for start/stop events
                                are_married = None
                                for event_ref in fam.get_event_ref_list():
                                    event = db.get_event_from_handle(
                                        event_ref.ref)
                                    et = EventType
                                    rt = EventRoleType
                                    if event.type in [et.MARRIAGE,
                                                      et.MARR_ALT] and \
                                        (event_ref.get_role() == rt.FAMILY or
                                         event_ref.get_role() == rt.PRIMARY ):
                                        are_married = event
                                    elif event.type in [et.DIVORCE,
                                                        et.ANNULMENT,
                                                        et.DIV_FILING] and \
                                        (event_ref.get_role() == rt.FAMILY or
                                         event_ref.get_role() == rt.PRIMARY ):
                                        are_married = None
                                if are_married is not None:
                                    for event_ref in fam.get_event_ref_list():
                                        event = db.get_event_from_handle(
                                            event_ref.ref)
                                        event_obj = event.get_date_object()

                                        if event_obj.is_valid():
                                            event_obj = gregorian(event_obj)

                                            year = event_obj.get_year()
                                            month = event_obj.get_month()
                                            day = event_obj.get_day()

                                            prob_alive_date = Date(
                                                self.year, month, day)

                                            nyears = self.year - year
                                            if nyears == 0:
                                                text = self._(
                                                    '%(spouse)s and\n %(person)s, wedding'
                                                ) % {
                                                    'spouse': spouse_name,
                                                    'person': short_name,
                                                }
                                            else:
                                                # translators: leave all/any {...} untranslated
                                                text = ngettext(
                                                    "{spouse} and\n {person}, {nyears}",
                                                    "{spouse} and\n {person}, {nyears}",
                                                    nyears).format(
                                                        spouse=spouse_name,
                                                        person=short_name,
                                                        nyears=nyears)

                                            alive1 = probably_alive(
                                                person, self.database,
                                                prob_alive_date)
                                            alive2 = probably_alive(
                                                spouse, self.database,
                                                prob_alive_date)
                                            if ((self.alive and alive1
                                                 and alive2)
                                                    or not self.alive):
                                                self.add_day_item(
                                                    text,
                                                    month,
                                                    day,
                                                    marks=[mark, s_m])
Example #4
0
    def get_info(self, person_handle, generation):
        """ get info about a person """
        person = self.database.get_person_from_handle(person_handle)
        p_pn = person.get_primary_name()
        self.calendar = config.get('preferences.calendar-format-report')

        birth = get_birth_or_fallback(self.database, person)
        bth = ""
        if birth:
            bth = birth.get_date_object()
            bth = self._get_date(
                Date(bth.to_calendar(self.calendar).get_year()))  # localized
            if bth == 0:
                bth = ""
            elif birth.get_type() != EventType.BIRTH:
                bth += '*'

        death = get_death_or_fallback(self.database, person)
        dth = ""
        if death:
            dth = death.get_date_object()
            dth = self._get_date(
                Date(dth.to_calendar(self.calendar).get_year()))  # localized
            if dth == 0:
                dth = ""
            elif death.get_type() != EventType.DEATH:
                dth += '*'
        if bth and dth:
            val = "%s - %s" % (str(bth), str(dth))
        elif bth:
            val = "* %s" % (str(bth))
        elif dth:
            val = "+ %s" % (str(dth))
        else:
            val = ""

        if generation > 7:
            if (p_pn.get_first_name() != "") and (p_pn.get_surname() != ""):
                name = p_pn.get_first_name() + " " + p_pn.get_surname()
            else:
                name = p_pn.get_first_name() + p_pn.get_surname()
            if (name != "") and (val != ""):
                string = name + self._(", ") + val  # Arabic OK
            else:
                string = name + val
            return [string]
        elif generation == 7:
            if (p_pn.get_first_name() != "") and (p_pn.get_surname() != ""):
                name = p_pn.get_first_name() + " " + p_pn.get_surname()
            else:
                name = p_pn.get_first_name() + p_pn.get_surname()

            if self.circle == FULL_CIRCLE:
                return [name, val]
            elif self.circle == HALF_CIRCLE:
                return [name, val]
            else:
                if (name != "") and (val != ""):
                    string = name + self._(", ") + val  # Arabic OK
                else:
                    string = name + val
                return [string]
        elif generation == 6:
            if self.circle == FULL_CIRCLE:
                return [p_pn.get_first_name(), p_pn.get_surname(), val]
            elif self.circle == HALF_CIRCLE:
                return [p_pn.get_first_name(), p_pn.get_surname(), val]
            else:
                if (p_pn.get_first_name() != "") and (p_pn.get_surname() !=
                                                      ""):
                    name = p_pn.get_first_name() + " " + p_pn.get_surname()
                else:
                    name = p_pn.get_first_name() + p_pn.get_surname()
                return [name, val]
        else:
            return [p_pn.get_first_name(), p_pn.get_surname(), val]
Example #5
0
def find_records(db,
                 filter,
                 top_size,
                 callname,
                 trans_text=glocale.translation.sgettext,
                 name_format=None,
                 living_mode=LivingProxyDb.MODE_INCLUDE_ALL,
                 user=None):
    """
    @param trans_text: allow deferred translation of strings
    @type trans_text: a GrampsLocale sgettext instance
    trans_text is a defined keyword (see po/update_po.py, po/genpot.sh)
    :param name_format: optional format to control display of person's name
    :type name_format: None or int
    :param living_mode: enable optional control of living people's records
    :type living_mode: int
    """
    def get_unfiltered_person_from_handle(person_handle):
        if living_mode == LivingProxyDb.MODE_INCLUDE_ALL:
            return db.get_person_from_handle(person_handle)
        else:  # we are in the proxy so get the person before proxy changes
            return db.get_unfiltered_person(person_handle)

    today = datetime.date.today()
    today_date = Date(today.year, today.month, today.day)

    # Person records
    person_youngestliving = []
    person_oldestliving = []
    person_youngestdied = []
    person_oldestdied = []
    person_youngestmarried = []
    person_oldestmarried = []
    person_youngestdivorced = []
    person_oldestdivorced = []
    person_youngestfather = []
    person_youngestmother = []
    person_oldestfather = []
    person_oldestmother = []
    person_mostkidsfather = []
    person_mostkidsmother = []
    person_mostgrandkidsfather = []
    person_mostgrandkidsmother = []

    person_handle_list = db.iter_person_handles()

    # the next "if" will turn person_handle_list from a generator into a
    # list, but only when this code is called from a report (which has a
    # filter) and not when called from a gramplet (which has no filter);
    # so the next line drains the generator and turns it into a list
    # always, so the gramplet can use it later, in the second loop
    person_handle_list = list(person_handle_list)

    if filter:
        person_handle_list = filter.apply(db, person_handle_list, user=user)

    for person_handle in person_handle_list:
        person = db.get_person_from_handle(person_handle)
        unfil_person = get_unfiltered_person_from_handle(person_handle)
        if person is None:
            continue

        # FIXME this should check for a "fallback" birth also/instead
        birth_ref = person.get_birth_ref()

        if not birth_ref:
            # No birth event, so we can't calculate any age.
            continue

        birth = db.get_event_from_handle(birth_ref.ref)
        birth_date = birth.get_date_object()

        death_date = _find_death_date(db, person)

        if not _good_date(birth_date):
            # Birth date unknown or incomplete, so we can't calculate any age.
            continue

        name = _get_styled_primary_name(person,
                                        callname,
                                        trans_text=trans_text,
                                        name_format=name_format)

        if death_date is None:
            if probably_alive(unfil_person, db):
                # Still living, look for age records
                _record(person_youngestliving, person_oldestliving,
                        today_date - birth_date, name, 'Person', person_handle,
                        top_size)
        elif _good_date(death_date):
            # Already died, look for age records
            _record(person_youngestdied, person_oldestdied,
                    death_date - birth_date, name, 'Person', person_handle,
                    top_size)

        for family_handle in person.get_family_handle_list():
            family = db.get_family_from_handle(family_handle)

            marriage_date = None
            divorce_date = None
            for event_ref in family.get_event_ref_list():
                event = db.get_event_from_handle(event_ref.ref)
                if (event.get_type().is_marriage()
                        and (event_ref.get_role().is_family()
                             or event_ref.get_role().is_primary())):
                    marriage_date = event.get_date_object()
                elif (event.get_type().is_divorce()
                      and (event_ref.get_role().is_family()
                           or event_ref.get_role().is_primary())):
                    divorce_date = event.get_date_object()

            if _good_date(marriage_date):
                _record(person_youngestmarried, person_oldestmarried,
                        marriage_date - birth_date, name, 'Person',
                        person_handle, top_size)

            if _good_date(divorce_date):
                _record(person_youngestdivorced, person_oldestdivorced,
                        divorce_date - birth_date, name, 'Person',
                        person_handle, top_size)

            for child_ref in family.get_child_ref_list():
                if person.get_gender() == person.MALE:
                    relation = child_ref.get_father_relation()
                elif person.get_gender() == person.FEMALE:
                    relation = child_ref.get_mother_relation()
                else:
                    continue
                if relation != ChildRefType.BIRTH:
                    continue

                child = db.get_person_from_handle(child_ref.ref)

                # FIXME this should check for a "fallback" birth also/instead
                child_birth_ref = child.get_birth_ref()
                if not child_birth_ref:
                    continue

                child_birth = db.get_event_from_handle(child_birth_ref.ref)
                child_birth_date = child_birth.get_date_object()

                if not _good_date(child_birth_date):
                    continue

                if person.get_gender() == person.MALE:
                    _record(person_youngestfather, person_oldestfather,
                            child_birth_date - birth_date, name, 'Person',
                            person_handle, top_size)
                elif person.get_gender() == person.FEMALE:
                    _record(person_youngestmother, person_oldestmother,
                            child_birth_date - birth_date, name, 'Person',
                            person_handle, top_size)

    for person_handle in person_handle_list:
        # this "person loop" doesn't care about a person's birth or death
        person = db.get_person_from_handle(person_handle)
        if person is None:
            continue

        name = _get_styled_primary_name(person,
                                        callname,
                                        trans_text=trans_text,
                                        name_format=name_format)

        person_child_list = get_birth_children(db, person)
        if person.get_gender() == person.MALE:
            _record(None, person_mostkidsfather, len(person_child_list), name,
                    'Person', person_handle, top_size)
        elif person.get_gender() == person.FEMALE:
            _record(None, person_mostkidsmother, len(person_child_list), name,
                    'Person', person_handle, top_size)

        person_grandchild_list = []
        for child in person_child_list:
            person_grandchild_list += get_birth_children(db, child)
        if person.get_gender() == person.MALE:
            _record(None, person_mostgrandkidsfather,
                    len(person_grandchild_list), name, 'Person', person_handle,
                    top_size)
        elif person.get_gender() == person.FEMALE:
            _record(None, person_mostgrandkidsmother,
                    len(person_grandchild_list), name, 'Person', person_handle,
                    top_size)

    # Family records
    family_mostchildren = []
    family_youngestmarried = []
    family_oldestmarried = []
    family_shortest = []
    family_longest = []
    family_smallestagediff = []
    family_biggestagediff = []

    for family in db.iter_families():
        #family = db.get_family_from_handle(family_handle)
        if living_mode != LivingProxyDb.MODE_INCLUDE_ALL:
            # FIXME no iter_families method in LivingProxyDb so do it this way
            family = db.get_family_from_handle(family.get_handle())

        father_handle = family.get_father_handle()
        if not father_handle:
            continue
        mother_handle = family.get_mother_handle()
        if not mother_handle:
            continue

        # Test if either father or mother are in filter
        if filter:
            # we don't want many progress reports popping up, so no user=user
            if not filter.apply(db, [father_handle, mother_handle]):
                continue

        father = db.get_person_from_handle(father_handle)
        unfil_father = get_unfiltered_person_from_handle(father_handle)
        if father is None:
            continue
        mother = db.get_person_from_handle(mother_handle)
        unfil_mother = get_unfiltered_person_from_handle(mother_handle)
        if mother is None:
            continue

        name = StyledText(trans_text("%(father)s and %(mother)s")) % {
            'father':
            _get_styled_primary_name(father,
                                     callname,
                                     trans_text=trans_text,
                                     name_format=name_format),
            'mother':
            _get_styled_primary_name(mother,
                                     callname,
                                     trans_text=trans_text,
                                     name_format=name_format)
        }

        if (living_mode == LivingProxyDb.MODE_INCLUDE_ALL
                or (not probably_alive(unfil_father, db)
                    and not probably_alive(unfil_mother, db))):
            _record(None, family_mostchildren,
                    len(family.get_child_ref_list()), name, 'Family',
                    family.handle, top_size)

        father_birth_ref = father.get_birth_ref()
        if father_birth_ref:
            father_birth_date = db.get_event_from_handle(
                father_birth_ref.ref).get_date_object()
        else:
            father_birth_date = None

        mother_birth_ref = mother.get_birth_ref()
        if mother_birth_ref:
            mother_birth_date = db.get_event_from_handle(
                mother_birth_ref.ref).get_date_object()
        else:
            mother_birth_date = None

        if _good_date(father_birth_date) and _good_date(mother_birth_date):
            if father_birth_date >> mother_birth_date:
                _record(family_smallestagediff, family_biggestagediff,
                        father_birth_date - mother_birth_date, name, 'Family',
                        family.handle, top_size)
            elif mother_birth_date >> father_birth_date:
                _record(family_smallestagediff, family_biggestagediff,
                        mother_birth_date - father_birth_date, name, 'Family',
                        family.handle, top_size)

        marriage_date = None
        divorce = None
        divorce_date = None
        for event_ref in family.get_event_ref_list():
            event = db.get_event_from_handle(event_ref.ref)
            if (event.get_type().is_marriage()
                    and (event_ref.get_role().is_family()
                         or event_ref.get_role().is_primary())):
                marriage_date = event.get_date_object()
            if (event and event.get_type().is_divorce()
                    and (event_ref.get_role().is_family()
                         or event_ref.get_role().is_primary())):
                divorce = event
                divorce_date = event.get_date_object()

        father_death_date = _find_death_date(db, father)
        mother_death_date = _find_death_date(db, mother)

        if not _good_date(marriage_date):
            # Not married or marriage date unknown
            continue

        if divorce is not None and not _good_date(divorce_date):
            # Divorced but date unknown or inexact
            continue

        if (not probably_alive(unfil_father, db)
                and not _good_date(father_death_date)):
            # Father died but death date unknown or inexact
            continue

        if (not probably_alive(unfil_mother, db)
                and not _good_date(mother_death_date)):
            # Mother died but death date unknown or inexact
            continue

        if (divorce_date is None and father_death_date is None
                and mother_death_date is None):
            # Still married and alive
            if (probably_alive(unfil_father, db)
                    and probably_alive(unfil_mother, db)):
                _record(family_youngestmarried, family_oldestmarried,
                        today_date - marriage_date, name, 'Family',
                        family.handle, top_size)
        elif (_good_date(divorce_date) or _good_date(father_death_date)
              or _good_date(mother_death_date)):
            end = None
            if _good_date(father_death_date) and _good_date(mother_death_date):
                end = min(father_death_date, mother_death_date)
            elif _good_date(father_death_date):
                end = father_death_date
            elif _good_date(mother_death_date):
                end = mother_death_date
            if _good_date(divorce_date):
                if end:
                    end = min(end, divorce_date)
                else:
                    end = divorce_date
            duration = end - marriage_date

            _record(family_shortest, family_longest, duration, name, 'Family',
                    family.handle, top_size)
    #python 3 workaround: assign locals to tmp so we work with runtime version
    tmp = locals()
    return [(trans_text(text), varname, tmp[varname])
            for (text, varname, default) in RECORDS]
Example #6
0
def find_records(db, filter, top_size, callname,
                 trans_text=glocale.translation.sgettext):
    """
    @param trans_text: allow deferred translation of strings
    @type trans_text: a GrampsLocale sgettext instance
    trans_text is a defined keyword (see po/update_po.py, po/genpot.sh)
    """

    today = datetime.date.today()
    today_date = Date(today.year, today.month, today.day)

    # Person records
    person_youngestliving = []
    person_oldestliving = []
    person_youngestdied = []
    person_oldestdied = []
    person_youngestmarried = []
    person_oldestmarried = []
    person_youngestdivorced = []
    person_oldestdivorced = []
    person_youngestfather = []
    person_youngestmother = []
    person_oldestfather = []
    person_oldestmother = []

    person_handle_list = db.iter_person_handles()

    if filter:
        person_handle_list = filter.apply(db, person_handle_list)

    for person_handle in person_handle_list:
        person = db.get_person_from_handle(person_handle)

        # FIXME this should check for a "fallback" birth also/instead
        birth_ref = person.get_birth_ref()

        if not birth_ref:
            # No birth event, so we can't calculate any age.
            continue

        birth = db.get_event_from_handle(birth_ref.ref)
        birth_date = birth.get_date_object()

        death_date = _find_death_date(db, person)

        if not _good_date(birth_date):
            # Birth date unknown or incomplete, so we can't calculate any age.
            continue

        name = _get_styled_primary_name(person, callname)

        if death_date is None:
            if probably_alive(person, db):
                # Still living, look for age records
                _record(person_youngestliving, person_oldestliving,
                        today_date - birth_date, name, 'Person', person_handle,
                        top_size)
        elif _good_date(death_date):
            # Already died, look for age records
            _record(person_youngestdied, person_oldestdied,
                    death_date - birth_date, name, 'Person', person_handle,
                    top_size)

        for family_handle in person.get_family_handle_list():
            family = db.get_family_from_handle(family_handle)

            marriage_date = None
            divorce_date = None
            for event_ref in family.get_event_ref_list():
                event = db.get_event_from_handle(event_ref.ref)
                if (event.get_type().is_marriage() and 
                    (event_ref.get_role().is_family() or 
                     event_ref.get_role().is_primary())):
                    marriage_date = event.get_date_object()
                elif (event.get_type().is_divorce() and 
                      (event_ref.get_role().is_family() or 
                       event_ref.get_role().is_primary())):
                    divorce_date = event.get_date_object()

            if _good_date(marriage_date):
                _record(person_youngestmarried, person_oldestmarried,
                        marriage_date - birth_date,
                        name, 'Person', person_handle, top_size)

            if _good_date(divorce_date):
                _record(person_youngestdivorced, person_oldestdivorced,
                        divorce_date - birth_date,
                        name, 'Person', person_handle, top_size)

            for child_ref in family.get_child_ref_list():
                if person.get_gender() == person.MALE:
                    relation = child_ref.get_father_relation()
                elif person.get_gender() == person.FEMALE:
                    relation = child_ref.get_mother_relation()
                else:
                    continue
                if relation != ChildRefType.BIRTH:
                    continue

                child = db.get_person_from_handle(child_ref.ref)

                # FIXME this should check for a "fallback" birth also/instead
                child_birth_ref = child.get_birth_ref()
                if not child_birth_ref:
                    continue

                child_birth = db.get_event_from_handle(child_birth_ref.ref)
                child_birth_date = child_birth.get_date_object()

                if not _good_date(child_birth_date):
                    continue

                if person.get_gender() == person.MALE:
                    _record(person_youngestfather, person_oldestfather,
                            child_birth_date - birth_date,
                            name, 'Person', person_handle, top_size)
                elif person.get_gender() == person.FEMALE:
                    _record(person_youngestmother, person_oldestmother,
                            child_birth_date - birth_date,
                            name, 'Person', person_handle, top_size)


    # Family records
    family_mostchildren = []
    family_youngestmarried = []
    family_oldestmarried = []
    family_shortest = []
    family_longest = []

    for family in db.iter_families():
        #family = db.get_family_from_handle(family_handle)

        father_handle = family.get_father_handle()
        if not father_handle:
            continue
        mother_handle = family.get_mother_handle()
        if not mother_handle:
            continue

        # Test if either father or mother are in filter
        if filter:
            if not filter.apply(db, [father_handle, mother_handle]):
                continue

        father = db.get_person_from_handle(father_handle)
        mother = db.get_person_from_handle(mother_handle)

        name = StyledText(trans_text("%(father)s and %(mother)s")) % {
                'father': _get_styled_primary_name(father, callname),
                'mother': _get_styled_primary_name(mother, callname)}

        _record(None, family_mostchildren,
                len(family.get_child_ref_list()),
                name, 'Family', family.handle, top_size)

        marriage_date = None
        divorce = None
        divorce_date = None
        for event_ref in family.get_event_ref_list():
            event = db.get_event_from_handle(event_ref.ref)
            if (event.get_type().is_marriage() and 
                (event_ref.get_role().is_family() or 
                 event_ref.get_role().is_primary())):
                marriage_date = event.get_date_object()
            if (event and event.get_type().is_divorce() and 
                (event_ref.get_role().is_family() or 
                 event_ref.get_role().is_primary())):
                divorce = event
                divorce_date = event.get_date_object()

        father_death_date = _find_death_date(db, father)
        mother_death_date = _find_death_date(db, mother)

        if not _good_date(marriage_date):
            # Not married or marriage date unknown
            continue

        if divorce is not None and not _good_date(divorce_date):
            # Divorced but date unknown or inexact
            continue

        if not probably_alive(father, db) and not _good_date(father_death_date):
            # Father died but death date unknown or inexact
            continue

        if not probably_alive(mother, db) and not _good_date(mother_death_date):
            # Mother died but death date unknown or inexact
            continue

        if (divorce_date is None 
            and father_death_date is None 
            and mother_death_date is None):
            # Still married and alive
            if probably_alive(father, db) and probably_alive(mother, db):
                _record(family_youngestmarried, family_oldestmarried,
                        today_date - marriage_date,
                        name, 'Family', family.handle, top_size)
        elif (_good_date(divorce_date) or 
              _good_date(father_death_date) or 
              _good_date(mother_death_date)):
            end = None
            if _good_date(father_death_date) and _good_date(mother_death_date):
                end = min(father_death_date, mother_death_date)
            elif _good_date(father_death_date):
                end = father_death_date
            elif _good_date(mother_death_date):
                end = mother_death_date
            if _good_date(divorce_date):
                if end:
                    end = min(end, divorce_date)
                else:
                    end = divorce_date
            duration = end - marriage_date

            _record(family_shortest, family_longest,
                    duration, name, 'Family', family.handle, top_size)
    #python 3 workaround: assign locals to tmp so we work with runtime version
    tmp = locals()
    return [(trans_text(text), varname, tmp[varname]) 
                for (text, varname, default) in RECORDS]
Example #7
0
    def collect_data(self):
        """
        This method runs through the data, and collects the relevant dates
        and text.
        """
        people = self.database.iter_person_handles()
        people = self.filter.apply(self.database, people, user=self._user)

        ngettext = self._locale.translation.ngettext  # to see "nearby" comments
        rel_calc = get_relationship_calculator(reinit=True,
                                               clocale=self._locale)

        with self._user.progress(_('Birthday and Anniversary Report'),
                                 _('Reading database...'),
                                 len(people)) as step:
            for person_handle in people:
                step()
                person = self.database.get_person_from_handle(person_handle)
                birth_ref = person.get_birth_ref()
                birth_date = None
                if birth_ref:
                    birth_event = self.database.get_event_from_handle(
                        birth_ref.ref)
                    birth_date = birth_event.get_date_object()

                if (self.birthdays and birth_date is not None
                        and birth_date.is_valid()):
                    birth_date = gregorian(birth_date)

                    year = birth_date.get_year()
                    month = birth_date.get_month()
                    day = birth_date.get_day()

                    prob_alive_date = Date(self.year, month, day)

                    nyears = self.year - year
                    # add some things to handle maiden name:
                    father_lastname = None  # husband, actually
                    if self.maiden_name in ['spouse_first', 'spouse_last'
                                            ]:  # get husband's last name:
                        if person.get_gender() == Person.FEMALE:
                            family_list = person.get_family_handle_list()
                            if len(family_list) > 0:
                                if self.maiden_name == 'spouse_first':
                                    fhandle = family_list[0]
                                else:
                                    fhandle = family_list[-1]
                                fam = self.database.get_family_from_handle(
                                    fhandle)
                                father_handle = fam.get_father_handle()
                                mother_handle = fam.get_mother_handle()
                                if mother_handle == person_handle:
                                    if father_handle:
                                        father = self.database.get_person_from_handle(
                                            father_handle)
                                        if father is not None:
                                            primary_name = father.get_primary_name(
                                            )
                                            if primary_name:
                                                father_lastname = Surname.get_surname(
                                                    primary_name.
                                                    get_primary_surname())

                    short_name = self.get_name(person, father_lastname)

                    alive = probably_alive(person, self.database,
                                           prob_alive_date)
                    if ((self.alive and alive) or not self.alive):

                        comment = ""
                        if self.relationships:
                            relation = rel_calc.get_one_relationship(
                                self.database,
                                self.center_person,
                                person,
                                olocale=self._locale)
                            if relation:
                                # FIXME this won't work for RTL languages
                                comment = " --- %s" % relation
                        deadtxt = ""
                        if (not alive):
                            deadtxt = self.deadtxt
                        yeartxt = ""
                        if self.showyear:
                            yeartxt = "(%s) " % year
                        if nyears == 0:
                            text = self._(
                                '* %(person)s, birth%(relation)s') % {
                                    'person': short_name,
                                    'relation': comment
                                }
                        else:
                            # translators: leave all/any {...} untranslated
                            text = ngettext(
                                '* {year}{person}{dead}, {age}{relation}',
                                '* {year}{person}{dead}, {age}{relation}',
                                nyears).format(year=yeartxt,
                                               person=short_name,
                                               dead=deadtxt,
                                               age=nyears,
                                               relation=comment)

                        self.add_day_item(text, month, day, person)
                if self.anniversaries:
                    family_list = person.get_family_handle_list()
                    for fhandle in family_list:
                        fam = self.database.get_family_from_handle(fhandle)
                        father_handle = fam.get_father_handle()
                        mother_handle = fam.get_mother_handle()
                        if father_handle == person.get_handle():
                            spouse_handle = mother_handle
                        else:
                            continue  # with next person if the father is not "person"
                            # this will keep from duplicating the anniversary
                        if spouse_handle:
                            spouse = self.database.get_person_from_handle(
                                spouse_handle)
                            if spouse:
                                spouse_name = self.get_name(spouse)
                                short_name = self.get_name(person)
                                # TEMP: this will handle ordered events
                                # Gramps 3.0 will have a new mechanism for start/stop events
                                are_married = None
                                for event_ref in fam.get_event_ref_list():
                                    event = self.database.get_event_from_handle(
                                        event_ref.ref)
                                    if event.type in [
                                            EventType.MARRIAGE,
                                            EventType.MARR_ALT
                                    ]:
                                        are_married = event
                                    elif event.type in [
                                            EventType.DIVORCE,
                                            EventType.ANNULMENT,
                                            EventType.DIV_FILING
                                    ]:
                                        are_married = None
                                if are_married is not None:
                                    for event_ref in fam.get_event_ref_list():
                                        event = self.database.get_event_from_handle(
                                            event_ref.ref)
                                        event_obj = event.get_date_object()
                                        if event_obj is not Date.EMPTY and event_obj.is_valid(
                                        ):
                                            event_obj = gregorian(event_obj)
                                        year = event_obj.get_year()
                                        month = event_obj.get_month()
                                        day = event_obj.get_day()
                                        nyears = self.year - year

                                        if event_obj.is_valid():
                                            prob_alive_date = Date(
                                                self.year, month, day)
                                            alive1 = probably_alive(
                                                person, self.database,
                                                prob_alive_date)
                                            alive2 = probably_alive(
                                                spouse, self.database,
                                                prob_alive_date)
                                            deadtxt1 = ""
                                            deadtxt2 = ""
                                            if (not alive1):
                                                deadtxt1 = self.deadtxt
                                            if (not alive2):
                                                deadtxt2 = self.deadtxt
                                            yeartxt = ""
                                            if self.showyear:
                                                yeartxt = "(%s) " % year
                                            if nyears == 0:
                                                text = self._(
                                                    "⚭ %(spouse)s and\n %(person)s, wedding"
                                                ) % {
                                                    'spouse': spouse_name,
                                                    'person': short_name
                                                }
                                            else:
                                                # translators: leave all/any {...} untranslated
                                                text = ngettext(
                                                    "⚭ {year}{spouse}{deadtxt2} and\n {person}{deadtxt1}, {nyears}",
                                                    "⚭ {year}{spouse}{deadtxt2} and\n {person}{deadtxt1}, {nyears}",
                                                    nyears).format(
                                                        year=yeartxt,
                                                        spouse=spouse_name,
                                                        deadtxt2=deadtxt2,
                                                        person=short_name,
                                                        deadtxt1=deadtxt1,
                                                        nyears=nyears)
                                                if (self.alive and alive1
                                                        and alive2
                                                    ) or not self.alive:
                                                    self.add_day_item(
                                                        text, month, day,
                                                        spouse)

                death_ref = person.get_death_ref()
                death_date = None
                if death_ref:
                    death_event = self.database.get_event_from_handle(
                        death_ref.ref)
                    death_date = death_event.get_date_object()

                if (self.death_anniversaries and death_date is not None
                        and death_date.is_valid()):
                    death_date = gregorian(death_date)

                    year = death_date.get_year()
                    month = death_date.get_month()
                    day = death_date.get_day()

                    nyears = self.year - year

                    comment = ""
                    if self.relationships:
                        relation = rel_calc.get_one_relationship(
                            self.database,
                            self.center_person,
                            person,
                            olocale=self._locale)
                        if relation:
                            # FIXME this won't work for RTL languages
                            comment = " --- %s" % relation
                    yeartxt = ""
                    if self.showyear:
                        yeartxt = "(%s) " % year
                    if nyears == 0:
                        text = _('✝ {person}, death {relation}').format(
                            person=short_name, relation=comment)
                    else:
                        text = ngettext('✝ {year}{person}, {age}{relation}',
                                        '✝ {year}{person}, {age}{relation}',
                                        nyears).format(year=yeartxt,
                                                       person=short_name,
                                                       age=nyears,
                                                       relation=comment)
                    self.add_day_item(text, month, day, person)
Example #8
0
    def write_people(self):
        """ write the people """

        self.doc.add_comment('')

        # If we're going to attempt to include images, then use the HTML style
        # of .gv file.
        use_html_output = False
        if self._incimages:
            use_html_output = True

        # loop through all the people we need to output
        for handle in sorted(self._people): # enable a diff
            person = self._db.get_person_from_handle(handle)
            name = self._name_display.display(person)
            p_id = person.get_gramps_id()

            # figure out what colour to use
            gender = person.get_gender()
            colour = self._colorunknown
            if gender == Person.MALE:
                colour = self._colormales
            elif gender == Person.FEMALE:
                colour = self._colorfemales

            # see if we have surname colours that match this person
            surname = person.get_primary_name().get_surname()
            surname = surname.encode('iso-8859-1', 'xmlcharrefreplace')
            if surname in self._surnamecolors:
                colour = self._surnamecolors[surname]

            # see if we have a birth/death or fallback dates we can use
            if self._incdates or self._incplaces:
                bth_event = get_birth_or_fallback(self._db, person)
                dth_event = get_death_or_fallback(self._db, person)
            else:
                bth_event = None
                dth_event = None

            # output the birth or fallback event
            birth_str = None
            if bth_event and self._incdates:
                date = bth_event.get_date_object()
                if self._just_years and date.get_year_valid():
                    birth_str = self._get_date( # localized year
                        Date(date.get_year()))
                else:
                    birth_str = self._get_date(date)

            # get birth place (one of:  hamlet, village, town, city, parish,
            # county, province, region, state or country)
            birthplace = None
            if bth_event and self._incplaces:
                birthplace = self.get_event_place(bth_event)

            # see if we have a deceased date we can use
            death_str = None
            if dth_event and self._incdates:
                date = dth_event.get_date_object()
                if self._just_years and date.get_year_valid():
                    death_str = self._get_date( # localized year
                        Date(date.get_year()))
                else:
                    death_str = self._get_date(date)

            # get death place (one of:  hamlet, village, town, city, parish,
            # county, province, region, state or country)
            deathplace = None
            if dth_event and self._incplaces:
                deathplace = self.get_event_place(dth_event)

            # see if we have an image to use for this person
            image_path = None
            if self._incimages:
                media_list = person.get_media_list()
                if len(media_list) > 0:
                    media_handle = media_list[0].get_reference_handle()
                    media = self._db.get_media_from_handle(media_handle)
                    media_mime_type = media.get_mime_type()
                    if media_mime_type[0:5] == "image":
                        image_path = get_thumbnail_path(
                            media_path_full(self._db, media.get_path()),
                            rectangle=media_list[0].get_rectangle(),
                            size=self._imagesize)

            # put the label together and output this person
            label = ""
            line_delimiter = '\\n'
            if use_html_output:
                line_delimiter = '<BR/>'

            # if we have an image, then start an HTML table;
            # remember to close the table afterwards!
            if image_path:
                label = ('<TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0" '
                         'CELLBORDER="0"><TR><TD><IMG SRC="%s"/></TD>' %
                         image_path)
                if self._imageonside == 0:
                    label += '</TR><TR>'
                label += '<TD>'

            # at the very least, the label must have the person's name
            name = name.replace('"', '&#34;')
            label += name.replace('<', '&#60;').replace('>', '&#62;')
            if self.includeid == 1: # same line
                label += " (%s)" % p_id
            elif self.includeid == 2: # own line
                label += "%s(%s)" % (line_delimiter, p_id)

            if birth_str or death_str:
                label += '%s(' % line_delimiter
                if birth_str:
                    label += '%s' % birth_str
                label += ' – '
                if death_str:
                    label += '%s' % death_str
                label += ')'
            if birthplace or deathplace:
                if birthplace == deathplace:
                    deathplace = None    # no need to print the same name twice
                label += '%s' % line_delimiter
                if birthplace:
                    label += '%s' % birthplace
                if birthplace and deathplace:
                    label += ' / '
                if deathplace:
                    label += '%s' % deathplace

            # see if we have a table that needs to be terminated
            if image_path:
                label += '</TD></TR></TABLE>'
            else:
                # non html label is enclosed by "" so escape other "
                label = label.replace('"', '\\\"')

            shape = "box"
            style = "solid"
            border = colour
            fill = colour

            # do not use colour if this is B&W outline
            if self._colorize == 'outline':
                border = ""
                fill = ""

            if gender == person.FEMALE and ("f" in self._useroundedcorners):
                style = "rounded"
            elif gender == person.MALE and ("m" in self._useroundedcorners):
                style = "rounded"
            elif gender == person.UNKNOWN:
                shape = "hexagon"

            # if we're filling the entire node:
            if self._colorize == 'filled':
                style += ",filled"
                border = ""

            # we're done -- add the node
            self.doc.add_node(p_id,
                              label=label,
                              shape=shape,
                              color=border,
                              style=style,
                              fillcolor=fill,
                              htmloutput=use_html_output)
Example #9
0
    def write_families(self):
        """ write the families """

        self.doc.add_comment('')
        ngettext = self._locale.translation.ngettext # to see "nearby" comments

        # loop through all the families we need to output
        for family_handle in sorted(self._families): # enable a diff
            family = self._db.get_family_from_handle(family_handle)
            fgid = family.get_gramps_id()

            # figure out a wedding date or placename we can use
            wedding_date = None
            wedding_place = None
            if self._incdates or self._incplaces:
                for event_ref in family.get_event_ref_list():
                    event = self._db.get_event_from_handle(event_ref.ref)
                    if (event.get_type() == EventType.MARRIAGE and
                            (event_ref.get_role() == EventRoleType.FAMILY or
                             event_ref.get_role() == EventRoleType.PRIMARY)):
                        # get the wedding date
                        if self._incdates:
                            date = event.get_date_object()
                            if self._just_years and date.get_year_valid():
                                wedding_date = self._get_date( # localized year
                                    Date(date.get_year()))
                            else:
                                wedding_date = self._get_date(date)
                        # get the wedding location
                        if self._incplaces:
                            wedding_place = self.get_event_place(event)
                        break

            # figure out the number of children (if any)
            children_str = None
            if self._incchildcount:
                child_count = len(family.get_child_ref_list())
                if child_count >= 1:
                    # translators: leave all/any {...} untranslated
                    children_str = ngettext("{number_of} child",
                                            "{number_of} children", child_count
                                           ).format(number_of=child_count)

            label = ''
            fgid_already = False
            if wedding_date:
                if label != '':
                    label += '\\n'
                label += '%s' % wedding_date
                if self.includeid == 1 and not fgid_already: # same line
                    label += " (%s)" % fgid
                    fgid_already = True
            if wedding_place:
                if label != '':
                    label += '\\n'
                label += '%s' % wedding_place
                if self.includeid == 1 and not fgid_already: # same line
                    label += " (%s)" % fgid
                    fgid_already = True
            if self.includeid == 1 and not label:
                label = "(%s)" % fgid
                fgid_already = True
            elif self.includeid == 2 and not label: # own line
                label = "(%s)" % fgid
                fgid_already = True
            elif self.includeid == 2 and label and not fgid_already:
                label += "\\n(%s)" % fgid
                fgid_already = True
            if children_str:
                if label != '':
                    label += '\\n'
                label += '%s' % children_str
                if self.includeid == 1 and not fgid_already: # same line
                    label += " (%s)" % fgid
                    fgid_already = True

            shape = "ellipse"
            style = "solid"
            border = self._colorfamilies
            fill = self._colorfamilies

            # do not use colour if this is B&W outline
            if self._colorize == 'outline':
                border = ""
                fill = ""

            # if we're filling the entire node:
            if self._colorize == 'filled':
                style += ",filled"
                border = ""

            # we're done -- add the node
            self.doc.add_node(fgid, label, shape, border, style, fill)

        # now that we have the families written,
        # go ahead and link the parents and children to the families
        for family_handle in self._families:

            # get the parents for this family
            family = self._db.get_family_from_handle(family_handle)
            fgid = family.get_gramps_id()
            father_handle = family.get_father_handle()
            mother_handle = family.get_mother_handle()

            self.doc.add_comment('')

            if self._usesubgraphs and father_handle and mother_handle:
                self.doc.start_subgraph(fgid)

            # see if we have a father to link to this family
            if father_handle:
                if father_handle in self._people:
                    father = self._db.get_person_from_handle(father_handle)
                    father_rn = father.get_primary_name().get_regular_name()
                    comment = self._("father: %s") % father_rn
                    self.doc.add_link(father.get_gramps_id(), fgid, "",
                                      self._arrowheadstyle, self._arrowtailstyle,
                                      comment=comment)

            # see if we have a mother to link to this family
            if mother_handle:
                if mother_handle in self._people:
                    mother = self._db.get_person_from_handle(mother_handle)
                    mother_rn = mother.get_primary_name().get_regular_name()
                    comment = self._("mother: %s") % mother_rn
                    self.doc.add_link(mother.get_gramps_id(), fgid, "",
                                      self._arrowheadstyle, self._arrowtailstyle,
                                      comment=comment)

            if self._usesubgraphs and father_handle and mother_handle:
                self.doc.end_subgraph()

            # link the children to the family
            for childref in family.get_child_ref_list():
                if childref.ref in self._people:
                    child = self._db.get_person_from_handle(childref.ref)
                    child_rn = child.get_primary_name().get_regular_name()
                    comment = self._("child: %s") % child_rn
                    self.doc.add_link(fgid, child.get_gramps_id(), "",
                                      self._arrowheadstyle, self._arrowtailstyle,
                                      comment=comment)
Example #10
0
    def run(self):
        BUTTONS = (
            (_("Select All"), self.select_all),
            (_("Select None"), self.select_none),
            (_("Toggle Selection"), self.toggle_select),
            (_("Add Selected Events"), self.apply_selection),
        )

        if hasattr(self, "table") and self.table:
            self.reselect = False
            if self.options.handler.options_dict['remove']:
                QuestionDialog(
                    _("Remove Events, Notes, and Source and Reselect Data"),
                    _("Are you sure you want to remove previous events, notes, and source and reselect data?"
                      ), _("Remove and Run Select Again"), self.set_reselect,
                    self.window)
            else:
                QuestionDialog(_("Reselect Data"),
                               _("Are you sure you want to reselect data?"),
                               _("Run Select Again"), self.set_reselect,
                               self.window)
            if not self.reselect:
                return

        current_date = Date()
        current_date.set_yr_mon_day(*time.localtime(time.time())[0:3])
        self.action = {}
        widget = self.add_results_frame(_("Select"))
        document = TextBufDoc(make_basic_stylesheet(), None)
        document.dbstate = self.dbstate
        document.uistate = self.uistate
        document.open("", container=widget)
        self.sdb = SimpleAccess(self.db)
        sdoc = SimpleDoc(document)
        stab = QuickTable(self.sdb)
        self.table = stab
        stab.columns(_("Select"), _("Person"), _("Action"), _("Birth Date"),
                     _("Death Date"), _("Evidence"), _("Relative"))
        self.results_write(_("Processing...\n"))
        self.filter_option = self.options.menu.get_option_by_name('filter')
        self.filter = self.filter_option.get_filter()  # the actual filter
        people = self.filter.apply(self.db, self.db.iter_person_handles())
        num_people = self.db.get_number_of_people()
        source_text = self.options.handler.options_dict['source_text']
        source = None
        add_birth = self.options.handler.options_dict['add_birth']
        add_death = self.options.handler.options_dict['add_death']
        remove_old = self.options.handler.options_dict['remove']

        self.MAX_SIB_AGE_DIFF = self.options.handler.options_dict[
            'MAX_SIB_AGE_DIFF']
        self.MAX_AGE_PROB_ALIVE = self.options.handler.options_dict[
            'MAX_AGE_PROB_ALIVE']
        self.AVG_GENERATION_GAP = self.options.handler.options_dict[
            'AVG_GENERATION_GAP']
        if remove_old:
            with DbTxn("", self.db, batch=True) as self.trans:
                self.db.disable_signals()
                self.results_write(_("Removing old estimations... "))
                self.progress.set_pass((_("Removing '%s'...") % source_text),
                                       num_people)
                supdate = None
                for person_handle in people:
                    self.progress.step()
                    pupdate = 0
                    person = self.db.get_person_from_handle(person_handle)
                    birth_ref = person.get_birth_ref()
                    if birth_ref:
                        birth = self.db.get_event_from_handle(birth_ref.ref)
                        for citation_handle in birth.get_citation_list():
                            citation = self.db.get_citation_from_handle(
                                citation_handle)
                            source_handle = citation.get_reference_handle()
                            #print "birth handle:", source_handle
                            source = self.db.get_source_from_handle(
                                source_handle)
                            if source:
                                if source.get_title() == source_text:
                                    #print("birth event removed from:",
                                    #      person.gramps_id)
                                    person.set_birth_ref(None)
                                    person.remove_handle_references(
                                        'Event', [birth_ref.ref])
                                    # remove note
                                    note_list = birth.get_referenced_note_handles(
                                    )
                                    birth.remove_handle_references(
                                        'Note', [
                                            note_handle
                                            for (obj_type,
                                                 note_handle) in note_list
                                        ])
                                    for (obj_type, note_handle) in note_list:
                                        self.db.remove_note(
                                            note_handle, self.trans)
                                    self.db.remove_event(
                                        birth_ref.ref, self.trans)
                                    self.db.remove_citation(
                                        citation_handle, self.trans)
                                    pupdate = 1
                                    supdate = source  # found the source.
                                    break
                    death_ref = person.get_death_ref()
                    if death_ref:
                        death = self.db.get_event_from_handle(death_ref.ref)
                        for citation_handle in death.get_citation_list():
                            citation = self.db.get_citation_from_handle(
                                citation_handle)
                            source_handle = citation.get_reference_handle()
                            #print "death handle:", source_handle
                            source = self.db.get_source_from_handle(
                                source_handle)
                            if source:
                                if source.get_title() == source_text:
                                    #print("death event removed from:",
                                    #      person.gramps_id)
                                    person.set_death_ref(None)
                                    person.remove_handle_references(
                                        'Event', [death_ref.ref])
                                    # remove note
                                    note_list = death.get_referenced_note_handles(
                                    )
                                    death.remove_handle_references(
                                        'Note', [
                                            note_handle
                                            for (obj_type,
                                                 note_handle) in note_list
                                        ])
                                    for (obj_type, note_handle) in note_list:
                                        self.db.remove_note(
                                            note_handle, self.trans)
                                    self.db.remove_event(
                                        death_ref.ref, self.trans)
                                    self.db.remove_citation(
                                        citation_handle, self.trans)
                                    pupdate = 1
                                    supdate = source  # found the source.
                                    break
                    if pupdate == 1:
                        self.db.commit_person(person, self.trans)
                if supdate:
                    self.db.remove_source(supdate.handle, self.trans)
            self.results_write(_("done!\n"))
            self.db.enable_signals()
            self.db.request_rebuild()
        if add_birth or add_death:
            self.results_write(_("Selecting... \n\n"))
            self.progress.set_pass(_('Selecting...'), num_people)
            row = 0
            for person_handle in people:
                self.progress.step()
                person = self.db.get_person_from_handle(person_handle)
                birth_ref = person.get_birth_ref()
                death_ref = person.get_death_ref()
                add_birth_event, add_death_event = False, False
                if not birth_ref or not death_ref:
                    date1, date2, explain, other = self.calc_estimates(person)
                    if birth_ref:
                        ev = self.db.get_event_from_handle(birth_ref.ref)
                        date1 = ev.get_date_object()
                    elif not birth_ref and add_birth and date1:
                        if date1.match(current_date, "<"):
                            add_birth_event = True
                            date1.make_vague()
                        else:
                            date1 = Date()
                    else:
                        date1 = Date()
                    if death_ref:
                        ev = self.db.get_event_from_handle(death_ref.ref)
                        date2 = ev.get_date_object()
                    elif not death_ref and add_death and date2:
                        if date2.match(current_date, "<"):
                            add_death_event = True
                            date2.make_vague()
                        else:
                            date2 = Date()
                    else:
                        date2 = Date()
                    # Describe
                    if add_birth_event and add_death_event:
                        action = _("Add birth and death events")
                    elif add_birth_event:
                        action = _("Add birth event")
                    elif add_death_event:
                        action = _("Add death event")
                    else:
                        continue
                    #stab.columns(_("Select"), _("Person"), _("Action"),
                    # _("Birth Date"), _("Death Date"), _("Evidence"), _("Relative"))
                    if add_birth == 1 and not birth_ref:  # no date
                        date1 = Date()
                    if add_death == 1 and not death_ref:  # no date
                        date2 = Date()
                    if person == other:
                        other = None
                    stab.row("checkbox", person, action, date1, date2, explain
                             or "", other or "")
                    if add_birth_event:
                        stab.set_cell_markup(
                            3, row,
                            "<b>%s</b>" % date_displayer.display(date1))
                    if add_death_event:
                        stab.set_cell_markup(
                            4, row,
                            "<b>%s</b>" % date_displayer.display(date2))
                    self.action[person.handle] = (add_birth_event,
                                                  add_death_event)
                    row += 1
            if row > 0:
                self.results_write("  ")
                for text, function in BUTTONS:
                    self.make_button(text, function, widget)
                self.results_write("\n")
                stab.write(sdoc)
                self.results_write("  ")
                for text, function in BUTTONS:
                    self.make_button(text, function, widget)
                self.results_write("\n")
            else:
                self.results_write(_("No events to be added."))
                self.results_write("\n")
        self.results_write("\n")
        self.set_current_frame(_("Select"))
Example #11
0
 def column_date(self, data):
     if data[10]:
         date = Date()
         date.unserialize(data[10])
         return displayer.display(date)
     return ''
Example #12
0
    def run_tool(self):
        self.progress = ProgressMeter(_('Running Date Test'),
                                      '',
                                      parent=self.parent_window)
        self.progress.set_pass(_('Generating dates'), 4)
        dates = []
        # first some valid dates
        calendar = Date.CAL_GREGORIAN
        for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED,
                        Date.QUAL_CALCULATED):
            for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER,
                             Date.MOD_ABOUT):
                for slash1 in (False, True):
                    for month in range(0, 13):
                        for day in (0, 5, 27):
                            if not month and day:
                                continue
                            d = Date()
                            d.set(quality, modifier, calendar,
                                  (day, month, 1789, slash1), "Text comment")
                            dates.append(d)
            for modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
                for slash1 in (False, True):
                    for slash2 in (False, True):
                        for month in range(0, 13):
                            for day in (0, 5, 27):
                                if not month and day:
                                    continue

                                d = Date()
                                d.set(quality, modifier, calendar,
                                      (day, month, 1789, slash1, day, month,
                                       1876, slash2), "Text comment")
                                dates.append(d)

                                if not month:
                                    continue

                                d = Date()
                                d.set(quality, modifier, calendar,
                                      (day, month, 1789, slash1, day,
                                       13 - month, 1876, slash2),
                                      "Text comment")
                                dates.append(d)

                                if not day:
                                    continue

                                d = Date()
                                d.set(quality, modifier, calendar,
                                      (day, month, 1789, slash1, 32 - day,
                                       month, 1876, slash2), "Text comment")
                                dates.append(d)
                                d = Date()
                                d.set(quality, modifier, calendar,
                                      (day, month, 1789, slash1, 32 - day,
                                       13 - month, 1876, slash2),
                                      "Text comment")
                                dates.append(d)
            modifier = Date.MOD_TEXTONLY
            d = Date()
            d.set(quality, modifier, calendar, Date.EMPTY,
                  "This is a textual date")
            dates.append(d)
            self.progress.step()

        # test invalid dates
        #dateval = (4,7,1789,False,5,8,1876,False)
        #for l in range(1,len(dateval)):
        #    d = Date()
        #    try:
        #        d.set(Date.QUAL_NONE,Date.MOD_NONE,
        #              Date.CAL_GREGORIAN,dateval[:l],"Text comment")
        #        dates.append( d)
        #    except DateError, e:
        #        d.set_as_text("Date identified value correctly as invalid.\n%s" % e)
        #        dates.append( d)
        #    except:
        #        d = Date()
        #        d.set_as_text("Date.set Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
        #        dates.append( d)
        #for l in range(1,len(dateval)):
        #    d = Date()
        #    try:
        #        d.set(Date.QUAL_NONE,Date.MOD_SPAN,Date.CAL_GREGORIAN,dateval[:l],"Text comment")
        #        dates.append( d)
        #    except DateError, e:
        #        d.set_as_text("Date identified value correctly as invalid.\n%s" % e)
        #        dates.append( d)
        #    except:
        #        d = Date()
        #        d.set_as_text("Date.set Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
        #        dates.append( d)
        #self.progress.step()
        #d = Date()
        #d.set(Date.QUAL_NONE,Date.MOD_NONE,
        #      Date.CAL_GREGORIAN,(44,7,1789,False),"Text comment")
        #dates.append( d)
        #d = Date()
        #d.set(Date.QUAL_NONE,Date.MOD_NONE,
        #      Date.CAL_GREGORIAN,(4,77,1789,False),"Text comment")
        #dates.append( d)
        #d = Date()
        #d.set(Date.QUAL_NONE,Date.MOD_SPAN,
        #      Date.CAL_GREGORIAN,
        #      (4,7,1789,False,55,8,1876,False),"Text comment")
        #dates.append( d)
        #d = Date()
        #d.set(Date.QUAL_NONE,Date.MOD_SPAN,
        #      Date.CAL_GREGORIAN,
        #      (4,7,1789,False,5,88,1876,False),"Text comment")
        #dates.append( d)

        with DbTxn(_("Date Test Plugin"), self.db, batch=True) as self.trans:
            self.db.disable_signals()
            self.progress.set_pass(_('Generating dates'), len(dates))

            # create pass and fail tags
            pass_handle = self.create_tag(_('Pass'), '#0000FFFF0000')
            fail_handle = self.create_tag(_('Fail'), '#FFFF00000000')

            # now add them as birth to new persons
            i = 1
            for dateval in dates:
                person = Person()
                surname = Surname()
                surname.set_surname("DateTest")
                name = Name()
                name.add_surname(surname)
                name.set_first_name("Test %d" % i)
                person.set_primary_name(name)
                self.db.add_person(person, self.trans)
                bevent = Event()
                bevent.set_type(EventType.BIRTH)
                bevent.set_date_object(dateval)
                bevent.set_description("Date Test %d (source)" % i)
                bevent_h = self.db.add_event(bevent, self.trans)
                bevent_ref = EventRef()
                bevent_ref.set_reference_handle(bevent_h)
                # for the death event display the date as text and parse it back to a new date
                ndate = None
                try:
                    datestr = _dd.display(dateval)
                    try:
                        ndate = _dp.parse(datestr)
                        if not ndate:
                            ndate = Date()
                            ndate.set_as_text("DateParser None")
                            person.add_tag(fail_handle)
                        else:
                            person.add_tag(pass_handle)
                    except:
                        ndate = Date()
                        ndate.set_as_text("DateParser Exception %s" % ("".join(
                            traceback.format_exception(*sys.exc_info())), ))
                        person.add_tag(fail_handle)
                    else:
                        person.add_tag(pass_handle)
                except:
                    ndate = Date()
                    ndate.set_as_text("DateDisplay Exception: %s" % ("".join(
                        traceback.format_exception(*sys.exc_info())), ))
                    person.add_tag(fail_handle)

                if dateval.get_modifier() != Date.MOD_TEXTONLY \
                       and ndate.get_modifier() == Date.MOD_TEXTONLY:
                    # parser was unable to correctly parse the string
                    ndate.set_as_text("TEXTONLY: " + ndate.get_text())
                    person.add_tag(fail_handle)
                if dateval.get_modifier() == Date.MOD_TEXTONLY \
                        and dateval.get_text().count("Traceback") \
                        and pass_handle in person.get_tag_list():
                    person.add_tag(fail_handle)

                devent = Event()
                devent.set_type(EventType.DEATH)
                devent.set_date_object(ndate)
                devent.set_description("Date Test %d (result)" % i)
                devent_h = self.db.add_event(devent, self.trans)
                devent_ref = EventRef()
                devent_ref.set_reference_handle(devent_h)
                person.set_birth_ref(bevent_ref)
                person.set_death_ref(devent_ref)
                self.db.commit_person(person, self.trans)
                i = i + 1
                self.progress.step()
        self.db.enable_signals()
        self.db.request_rebuild()
        self.progress.close()
Example #13
0
 def _convert_date(self, date_in):
     """Convert the change date to the preferred date format and return a string"""
     change_date = Date()
     change_date.set_yr_mon_day(*time.localtime(date_in)[0:3])
     return gramps.gen.datehandler.displayer.display(change_date)
Example #14
0
    def __create_gui(self):
        vbox = Gtk.VBox(orientation=Gtk.Orientation.VERTICAL)
        vbox.set_spacing(4)

        label = Gtk.Label(
            _("This gramplet allows setting properties for multiple places at the same time"
              ))
        label.set_halign(Gtk.Align.START)
        label.set_line_wrap(True)
        vbox.pack_start(label, False, True, 0)

        pt_label = Gtk.Label(_('Place type:'))
        pt_label.set_halign(Gtk.Align.START)
        self.typecombo = Gtk.ComboBoxText.new_with_entry()
        self.__fill_combo(self.typecombo,
                          list(self.__typenames()),
                          wrap_width=4)

        tag_label = Gtk.Label(_('Tag:'))
        tag_label.set_halign(Gtk.Align.START)
        self.tagcombo = Gtk.ComboBoxText.new_with_entry()
        self.__fill_combo(self.tagcombo, list(self.__tagnames()))

        label1 = Gtk.Label(_("New enclosing place"))
        label1.set_halign(Gtk.Align.START)
        label1.set_line_wrap(True)
        self.label1 = label1

        self.enclosing_place = Gtk.Label(_("None"))
        self.enclosing_place.set_halign(Gtk.Align.START)

        date_label = Gtk.Label(_('Timespan:'))
        date_label.set_halign(Gtk.Align.START)
        self.date_entry = ValidatableMaskedEntry()
        date_button = Gtk.Button.new_from_icon_name("gramps-date", -1)
        timespan_tooltip = _("Set timespan for enclosing places")
        date_label.set_tooltip_text(timespan_tooltip)
        date_button.set_tooltip_text(timespan_tooltip)
        self.date_entry.set_tooltip_text(timespan_tooltip)
        self.date_object = Date()
        self.track = []
        self.date_field = MonitoredDate(self.date_entry, date_button,
                                        self.date_object, self.uistate,
                                        self.track)

        pt_grid = Gtk.Grid(column_spacing=10)
        pt_grid.attach(pt_label, 0, 0, 1, 1)
        pt_grid.attach(self.typecombo, 1, 0, 1, 1)

        pt_grid.attach(tag_label, 0, 1, 1, 1)
        pt_grid.attach(self.tagcombo, 1, 1, 1, 1)

        pt_grid.attach(label1, 0, 2, 1, 1)

        pl_grid = Gtk.Grid(column_spacing=10)
        pl_grid.set_margin_left(20)
        #pt_grid.attach(self.enclosing_place, 1, 2, 1, 1)

        pl_grid.attach(date_label, 1, 4, 1, 1)
        pl_grid.attach(self.date_entry, 2, 4, 1, 1)
        pl_grid.attach(date_button, 3, 4, 1, 1)

        vbox.pack_start(pt_grid, False, True, 0)
        vbox.pack_start(pl_grid, False, True, 0)

        self.but_set_enclosing = Gtk.Button(label=_('Select'))
        self.but_set_enclosing.connect("clicked", self.cb_select)
        #vbox.pack_start(self.but_set_enclosing, False, True, 10)
        pt_grid.attach(self.but_set_enclosing, 1, 2, 1, 1)

        self.clear_enclosing = Gtk.CheckButton(
            _("Clear original enclosing places"))
        vbox.pack_start(self.clear_enclosing, False, True, 0)

        self.clear_tags = Gtk.CheckButton(_("Clear tags"))
        vbox.pack_start(self.clear_tags, False, True, 0)

        self.generate_hierarchy = Gtk.CheckButton(_("Generate hierarchy"))
        self.generate_hierarchy.connect("clicked",
                                        self.cb_select_generate_hierarchy)
        vbox.pack_start(self.generate_hierarchy, False, True, 0)

        butbox1 = Gtk.VBox()
        butbox1.set_margin_left(20)
        self.spaces = Gtk.CheckButton(_("use spaces as separator"))
        self.spaces.set_sensitive(False)
        butbox1.pack_start(self.spaces, False, True, 0)

        self.reverse = Gtk.CheckButton(_("reverse hierarchy"))
        self.reverse.set_sensitive(False)
        butbox1.pack_start(self.reverse, False, True, 0)

        vbox.pack_start(butbox1, False, True, 0)

        self.replace_text = Gtk.CheckButton(_("Replace text"))
        self.replace_text.connect("clicked", self.cb_select_replace_text)

        self.use_regex = Gtk.CheckButton(_("Use regex"))
        self.use_regex.set_sensitive(False)

        replace_text_box = Gtk.HBox()
        replace_text_box.pack_start(self.replace_text, False, True, 0)
        replace_text_box.pack_start(self.use_regex, False, True, 0)
        vbox.pack_start(replace_text_box, False, True, 0)

        old_text_label = Gtk.Label(_("Old text:"))
        self.old_text = Gtk.Entry()
        self.old_text.set_sensitive(False)

        new_text_label = Gtk.Label(_("New text:"))
        self.new_text = Gtk.Entry()
        self.new_text.set_sensitive(False)

        replace_grid = Gtk.Grid(column_spacing=10)
        replace_grid.set_margin_left(20)
        replace_grid.attach(old_text_label, 1, 0, 1, 1)
        replace_grid.attach(self.old_text, 2, 0, 1, 1)
        replace_grid.attach(new_text_label, 1, 1, 1, 1)
        replace_grid.attach(self.new_text, 2, 1, 1, 1)
        vbox.pack_start(replace_grid, False, True, 0)

        but_clear = Gtk.Button(label=_('Clear selections'))
        but_clear.connect("clicked", self.cb_clear)
        vbox.pack_start(but_clear, False, True, 10)

        but_apply = Gtk.Button(label=_('Apply to selected places'))
        but_apply.connect("clicked", self.cb__apply)
        vbox.pack_start(but_apply, False, True, 0)

        vbox.show_all()
        return vbox