示例#1
0
    def match(self, lat, lon):
        """
        coordinates matching.
        """
        rds = float(self.radius)
        self.places = []

        # place
        for entry in self.place_list:
            if (math.hypot(lat-float(entry[3]),
                           lon-float(entry[4])) <= rds) == True:
                # Do we already have this place ? avoid duplicates
                (country, state, county,
                 place, other) = self.get_location(entry[9])
                if not [country, state, county, place, other] in self.places:
                    self.places.append([country, state, county, place, other])
        self.warning = False
        for place in self.dbstate.db.iter_places():
            latn = place.get_latitude()
            lonn = place.get_longitude()
            if latn and lonn:
                latn, ignore = conv_lat_lon(latn, "0", "D.D8")
                if not latn:
                    if not self.warning:
                        self.close()
                    warn1 = _("you have a wrong latitude for:")
                    warn2 = _pd.display(self.dbstate.db, place) + "\n\n<b>"
                    warn2 += _("Please, correct this before linking") + "</b>"
                    WarningDialog(warn1, warn2, parent=self.uistate.window)
                    self.warning = True
                    continue
                ignore, lonn = conv_lat_lon("0", lonn, "D.D8")
                if not lonn:
                    if not self.warning:
                        self.close()
                    warn1 = _("you have a wrong longitude for:") + "\n"
                    warn2 = _pd.display(self.dbstate.db, place) + "\n\n<b>"
                    warn2 += _("Please, correct this before linking") + "</b>"
                    WarningDialog(warn1, warn2, parent=self.uistate.window)
                    self.warning = True
                    continue
                if (math.hypot(lat-float(latn),
                               lon-float(lonn)) <= rds) == True:
                    (country, state, county,
                     place, other) = self.get_location(place.get_gramps_id())
                    if not [country, state, county,
                            place, other] in self.places:
                        self.places.append([country, state, county,
                                            place, other])
示例#2
0
文件: htmldoc.py 项目: oluul/gramps
    def copy_file(self, from_fname, to_fname, to_dir=''):
        """
        Copy a file from a source to a (report) destination.
        If to_dir is not present, then the destination directory will be created.

        Normally 'to_fname' will be just a filename, without directory path.

        'to_dir' is the relative path name in the destination root. It will
        be prepended before 'to_fname'.
        """
        #build absolute path
        dest = os.path.join(self._backend.datadirfull(), to_dir, to_fname)

        destdir = os.path.dirname(dest)
        if not os.path.isdir(destdir):
            os.makedirs(destdir)

        if from_fname != dest:
            shutil.copyfile(from_fname, dest)
        elif self.warn_dir:
            from gramps.gui.dialog import WarningDialog
            WarningDialog(
                _("Possible destination error") + "\n" +
                _("You appear to have set your target directory "
                  "to a directory used for data storage. This "
                  "could create problems with file management. "
                  "It is recommended that you consider using "
                  "a different directory to store your generated "
                  "web pages."))
            self.warn_dir = False
示例#3
0
    def run(self):
        """Run function of Remove Tag Tool."""
        self.db = self.dbstate.get_database()
        if not self.__opt_by_name('add_remove'):
            # when the database is empty, prevent further tool processing
            # 'add_remove' menu option is not generated when db is empty
            txt = _("Unable to run the tool. Please check if your database "
                    "contains tags, filters and objects.")
            WarningDialog(_("WARNING"), txt, parent=self.window)
            return  # stop the tool
        self.remove = bool(self.__opt_by_name('add_remove').get_value())
        tag_info = self.__get_tag_info()

        tag_value = self.options.handler.options_dict['tag_name']
        for info in tag_info:
            if info[0] == tag_value:
                self.tag_handle = info[1]
                self.tag_name = info[2]

        lst = [
            'Person', 'Family', 'Event', 'Place', 'Source', 'Citation',
            'Repository', 'Media', 'Note'
        ]
        category_value = self.__opt_by_name('category').get_value()
        self.__menu_opt_handling(lst[category_value].lower())
示例#4
0
    def write_family(self, family_handle, person = None):
        family = self.dbstate.db.get_family_from_handle(family_handle)
        if family is None:
            from gramps.gui.dialog import WarningDialog
            WarningDialog(
                _('Broken family detected'),
                _('Please run the Check and Repair Database tool'),
                parent=self.uistate.window)
            return

        father_handle = family.get_father_handle()
        mother_handle = family.get_mother_handle()
        if self.get_handle() == father_handle:
            handle = mother_handle
        else:
            handle = father_handle

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        heading = self.write_label(_('Family'), family, False)
        vbox.pack_start(heading, False, False, 1)

        if handle or family.get_relationship() != FamilyRelType.UNKNOWN:
            box = self.write_person(_('Spouse'), handle)
            if not self.write_relationship_events(box, family):
                self.write_relationship(box, family)
            ebox = self.make_dragbox(box, 'Person', handle)
            vbox.pack_start(ebox, False, False, 1)

        count = len(family.get_child_ref_list())
        ex2 = Gtk.Expander(label='%s (%s):' % (_('Children'), count))
        ex2.set_expanded(True)
        ex2.set_margin_start(24)
        vbox.pack_start(ex2, False, False, 6)

        vbox2 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        hbox = Gtk.Box()
        addchild = widgets.IconButton(self.add_child_to_fam,
                                      family.handle,
                                      'list-add')
        addchild.set_tooltip_text(_('Add new child to family'))
        selchild = widgets.IconButton(self.sel_child_to_fam,
                                      family.handle,
                                      'gtk-index')
        selchild.set_tooltip_text(_('Add existing child to family'))
        hbox.pack_start(addchild, False, True, 0)
        hbox.pack_start(selchild, False, True, 0)

        vbox2.pack_start(hbox, False, False, 0)

        i = 1
        child_list = family.get_child_ref_list()
        for child_ref in child_list:
            widget = self.write_child(child_ref.ref, i, True)
            vbox2.pack_start(widget, True, True, 1)
            i += 1

        ex2.add(vbox2)

        self.vbox2.pack_start(vbox, False, True, 0)
示例#5
0
    def export_results(self, _button):
        """
        Export the results to a text file.
        """
        chooser = Gtk.FileChooserDialog(
            _("Export results to a text file"),
            self.uistate.window,
            Gtk.FileChooserAction.SAVE,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
             Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
        chooser.set_do_overwrite_confirmation(True)

        while True:
            value = chooser.run()
            filename = chooser.get_filename()
            if value == Gtk.ResponseType.OK:
                if filename:
                    chooser.destroy()
                    break
            else:
                chooser.destroy()
                return
        try:
            with io.open(filename, 'w') as report_file:
                for title, model in zip(self.titles, self.models):
                    self.export_page(report_file, title, model)
        except IOError as err:
            WarningDialog(self.window_name,
                          _('Error when writing the report: %s') %
                          err.strerror, self.window)
示例#6
0
 def link_place(self, menu, event, lat, lon):
     """
     Link an existing place using longitude and latitude of location centered
     on the map
     If we have a place history, we must show all places to avoid an empty
     place selection in the PlaceSelection.
     """
     if self.uistate.get_active('Place'):
         self._createmap(None)
     selector = SelectPlace(self.dbstate, self.uistate, [])
     place = selector.run()
     if place:
         parent_list = place.get_placeref_list()
         if len(parent_list) > 0:
             parent = parent_list[0].ref
         else:
             parent = None
         places_handle = self.dbstate.db.iter_place_handles()
         nb_places = 0
         gids = ""
         place_title = _pd.display(self.dbstate.db, place)
         for place_hdl in places_handle:
             plce = self.dbstate.db.get_place_from_handle(place_hdl)
             plce_title = _pd.display(self.dbstate.db, plce)
             if plce_title == place_title:
                 nb_places += 1
                 if gids == "":
                     gids = plce.gramps_id
                 else:
                     # TODO for Arabic, should the next comma be translated?
                     gids = gids + ", " + plce.gramps_id
         if nb_places > 1:
             from gramps.gui.dialog import WarningDialog
             WarningDialog(
                   _('You have at least two places with the same title.'),
                   _("The title of the places is:\n%(title)s\n"
                     "The following places are similar: %(gid)s\n"
                     "You should eiher rename the places or merge them.\n\n"
                     "%(bold_start)s"
                     "I can't proceed with your request"
                     "%(bold_end)s.\n") % {
                         'bold_start' : '<b>',
                         'bold_end'   : '</b>',
                         'title': '<b>' + place_title + '</b>',
                         'gid': gids},
                    parent=self.uistate.window
                   )
         else:
             self.mark = [None, None, None, None, None, None, None,
                          None, None, place.gramps_id, None, None]
             self.select_fct = PlaceSelection(self.uistate,
                                              self.dbstate,
                                              self.osm,
                                              self.selection_layer,
                                              self.place_list,
                                              lat,
                                              lon,
                                              self.__edit_place,
                                              parent)
示例#7
0
 def add_bookmark(self, *obj):
     mlist = self.selected_handles()
     if mlist:
         self.bookmarks.add(mlist[0])
     else:
         from gramps.gui.dialog import WarningDialog
         WarningDialog(_("Could Not Set a Bookmark"),
                       _("A bookmark could not be set because "
                         "no one was selected."),
                       parent=self.uistate.window)
示例#8
0
 def __menu_opt_handling(self, category):
     """General menu option handling."""
     iter_ = list(self.db.method('iter_%s_handles', category)())
     if iter_ == []:
         txt = _("No %s objects were found in database." % category)
         WarningDialog(_("WARNING"), txt, parent=self.window)
         return  # stop the tool
     filter_opt = self.__opt_by_name(category)
     filter_ = filter_opt.get_filter()
     objects = filter_.apply(self.dbstate.db, iter_)
     self.__remove_from(objects, category)
示例#9
0
 def add_bookmark(self, menu, handle):
     if handle:
         self.uistate.set_active(handle, self.navigation_type())
         self.bookmarks.add(handle)
         self.bookmarks.redraw()
     else:
         from gramps.gui.dialog import WarningDialog
         WarningDialog(
             _("Could Not Set a Bookmark"),
             _("A bookmark could not be set because "
               "no one was selected."))
示例#10
0
 def link_place(self, menu, event, lat, lon):
     """
     Link an existing place using longitude and latitude of location centered
     on the map
     If we have a place history, we must show all places to avoid an empty
     place selection in the PlaceSelection.
     """
     if self.uistate.get_active('Place'):
         self._createmap(None)
     selector = SelectPlace(self.dbstate, self.uistate, [])
     place = selector.run()
     if place:
         parent_list = place.get_placeref_list()
         if len(parent_list) > 0:
             parent = parent_list[0].ref
         else:
             parent = None
         places_handle = self.dbstate.db.iter_place_handles()
         nb_places = 0
         gids = ""
         for place_hdl in places_handle:
             plce = self.dbstate.db.get_place_from_handle(place_hdl)
             if plce.get_title() == place.get_title():
                 nb_places += 1
                 if gids == "":
                     gids = plce.gramps_id
                 else:
                     gids = gids + ", " + plce.gramps_id
         if nb_places > 1:
             from gramps.gui.dialog import WarningDialog
             WarningDialog(
                   _('You have at least two places with the same title.'),
                   _("The title of the places is :\n"
                     "<b>%(title)s</b>\n"
                     "The following places are similar : %(gid)s\n"
                     "Eiher you rename the places either you merge them."
                     "\n\n<b>I can't proceed your request</b>.\n") % {
                                           'title': place.get_title(),
                                           'gid': gids}
                   )
         else:
             self.mark = [None, None, None, None, None, None, None,
                          None, None, place.gramps_id, None, None]
             self.select_fct = PlaceSelection(self.uistate,
                                              self.dbstate,
                                              self.osm,
                                              self.selection_layer,
                                              self.place_list,
                                              lat,
                                              lon,
                                              self.__edit_place,
                                              parent)
示例#11
0
 def add_bookmark(self, menu):
     """
     Add the place to the bookmark
     """
     mlist = self.selected_handles()
     if mlist:
         self.bookmarks.add(mlist[0])
     else:
         from gramps.gui.dialog import WarningDialog
         WarningDialog(
             _("Could Not Set a Bookmark"),
             _("A bookmark could not be set because "
               "no one was selected."))
示例#12
0
 def time_str_to_sec(self, time_str):
     time_sec = None
     iso_date_time = self.add_time(time_str)
     try:
         time_tup = time.strptime(iso_date_time, "%Y-%m-%d %H:%M:%S")
         time_sec = time.mktime(time_tup)
     except ValueError:
         from gramps.gui.dialog import WarningDialog
         WarningDialog(_("Wrong format of date-time"),
             _("Only date-times in the iso format of yyyy-mm-dd "
               "hh:mm:ss, where the time part is optional, are "
               "accepted. %s does not satisfy.") % iso_date_time)
     return time_sec
示例#13
0
 def add_bookmark_from_popup(self, menu, handle):
     """
     Add the place to the bookmark from the popup menu
     """
     if handle:
         self.uistate.set_active(handle, self.navigation_type())
         self.bookmarks.add(handle)
         self.bookmarks.redraw()
     else:
         from gramps.gui.dialog import WarningDialog
         WarningDialog(_("Could Not Set a Bookmark"),
                       _("A bookmark could not be set because "
                         "no one was selected."),
                       parent=self.uistate.window)
示例#14
0
    def printview(self, obj):
        """
        Print or save the view that is currently shown
        """
        if Gtk.MAJOR_VERSION == 3 and Gtk.MINOR_VERSION < 11:
            from gramps.gui.dialog import WarningDialog
            WarningDialog(_("You can't use the print functionality"),
                          _("Your Gtk version is too old."),
                          parent=self.uistate.window)
            return

        req = self.osm.get_allocation()
        widthpx = req.width
        heightpx = req.height
        prt = CairoPrintSave(widthpx, heightpx, self.osm.do_draw, self.osm)
        prt.run()
示例#15
0
    def __init__(self, dbstate, user, options_class, name, callback=None):
        set_det_id(True)
        uistate = user.uistate
        if not uistate: return

        tool.Tool.__init__(self, dbstate, options_class, name)

        self.window_name = _('Deterministic ID Tool')
        ManagedWindow.__init__(self, uistate, [], self.__class__)

        window = MyWindow(dbstate, self.uistate, [])
        self.set_window(window, None, self.window_name)
        WarningDialog(self.window_name,
              _("The ID and handles now start at 0x00000000, and increment by 0x100000001"),
                self.window)
        self.close()
示例#16
0
 def home(self, *obj):
     """
     Move to the default person.
     """
     defperson = self.dbstate.db.get_default_person()
     if defperson:
         self.change_active(('Person', defperson.get_handle()))
     else:
         from ..dialog import WarningDialog
         WarningDialog(
             _("No Home Person"),
             _("You need to set a 'default person' to go to. "
               "Select the People View, select the person you want as "
               "'Home Person', then confirm your choice "
               "via the menu Edit -> Set Home Person."),
             parent=self.uistate.window)
 def find_an_incomplete_place(self):
     """ in our db.  Will return with a place (and active set to place)
     or None if no incomplete places, in which case active will be the same.
     Will also find unused places, and offer to delete."""
     p_hndls = self.dbstate.db.get_place_handles()
     if not p_hndls:
         return None  # in case there aren't any
     # keep handles in an order to avoid inconsistant
     # results when db returns them in different orders.
     p_hndls.sort()
     # try to find the handle after the previously scanned handle in the
     # list.
     found = False
     for indx, hndl in enumerate(p_hndls):
         if hndl > self.incomp_hndl:
             found = True
             break
     if not found:
         indx = 0
     # now, starting from previous place, look for incomplete place
     start = indx
     while True:
         hndl = p_hndls[indx]
         place_data = self.dbstate.db.get_raw_place_data(hndl)
         p_type = place_data[8][0]  # place_type
         refs = list(self.dbstate.db.find_backlink_handles(hndl))
         if(p_type == PlaceType.UNKNOWN or
            not refs or
            p_type != PlaceType.COUNTRY and
            not place_data[5]):  # placeref_list
             # need to get view to this place...
             self.set_active("Place", hndl)
             self.incomp_hndl = hndl
             if not refs:
                 WarningDialog(
                     _('This Place is not used!'),
                     msg2=_('You should delete it, or, if it contains '
                            'useful notes or other data, use the Find to '
                            'merge it into a valid place.'),
                     parent=self.uistate.window)
             return self.dbstate.db.get_place_from_handle(hndl)
         indx += 1
         if indx == len(p_hndls):
             indx = 0
         if indx == start:
             break
     return None
示例#18
0
文件: eventcmp.py 项目: vperic/gramps
    def on_apply_clicked(self, obj):
        cfilter = self.filter_model[self.filters.get_active()][1]

        progress_bar = ProgressMeter(_('Comparing events'), '')
        progress_bar.set_pass(_('Selecting people'), 1)

        plist = cfilter.apply(self.db, self.db.iter_person_handles())

        progress_bar.step()
        progress_bar.close()
        self.options.handler.options_dict['filter'] = self.filters.get_active()
        # Save options
        self.options.handler.save_options()

        if len(plist) == 0:
            WarningDialog(_("No matches were found"))
        else:
            DisplayChart(self.dbstate, self.uistate, plist, self.track)
示例#19
0
    def add(self, handle):
        """Append the citation to the bottom of the bookmarks."""
        if self.dbstate.db.get_citation_from_handle(handle):
            ListBookmarks.add(self, handle)
        else:
            # Probably trying to bookmark a source when the navigation type is
            # citation. This can occur when in the Citation Tree View and we
            # bookmark a source.

            # FIXME: See http://www.gramps-project.org/bugs/view.php?id=6352 a
            # more comprehensive solution is needed in the long term. See also
            # change_active in CitatinTreeView
            from gramps.gui.dialog import WarningDialog
            WarningDialog(_("Cannot bookmark this reference"),
                          "Only Citations can be bookmarked in this view. "
                          "You are probably trying to bookmark a Source in the "
                          "Citation Tree View. In this view, only Citations "
                          "can be bookmarked. To bookmark a Source, switch to "
                          "the Source View")
示例#20
0
 def share(self, obj):
     """
     share:      Add a new citation to an existing source (when a source is
                   selected)
     """
     for handle in self.selected_handles():
         # The handle will either be a Source handle or a Citation handle
         source, citation = self.get_source_or_citation(handle)
         if not source:
             source = self.dbstate.db.get_source_from_handle(
                 citation.get_reference_handle())
         try:
             EditCitation(self.dbstate, self.uistate, [], Citation(),
                          source)
         except WindowActiveError:
             from gramps.gui.dialog import WarningDialog
             WarningDialog(_("Cannot share this reference"),
                           self.__blocked_text(),
                           parent=self.uistate.window)
示例#21
0
    def add_bookmark(self, *obj):
        """
        Add a bookmark to the list.
        """
        from gramps.gen.display.name import displayer as name_displayer

        active_handle = self.uistate.get_active('Person')
        active_person = self.dbstate.db.get_person_from_handle(active_handle)
        if active_person:
            self.bookmarks.add(active_handle)
            name = name_displayer.display(active_person)
            self.uistate.push_message(self.dbstate,
                                      _("%s has been bookmarked") % name)
        else:
            from gramps.gui.dialog import WarningDialog
            WarningDialog(_("Could Not Set a Bookmark"),
                          _("A bookmark could not be set because "
                            "no one was selected."),
                          parent=self.uistate.window)
示例#22
0
 def edit(self, obj):
     """
     Edit either a Source or a Citation, depending on user selection
     """
     for handle in self.selected_handles():
         # The handle will either be a Source handle or a Citation handle
         source, citation = self.get_source_or_citation(handle)
         if citation:
             try:
                 EditCitation(self.dbstate, self.uistate, [], citation)
             except WindowActiveError:
                 pass
         else:
             try:
                 EditSource(self.dbstate, self.uistate, [], source)
             except WindowActiveError:
                 from gramps.gui.dialog import WarningDialog
                 WarningDialog(_("Cannot share this reference"),
                               self.__blocked_text2(),
                               parent=self.uistate.window)
示例#23
0
 def new_clicked(self, obj):
     """
     Create a new To Do note.
     """
     nav_type = self.uistate.viewmanager.active_page.navigation_type()
     active_handle = self.get_active(nav_type)
     if active_handle:
         from gramps.gui.editors import EditNote
         note = Note()
         note.set_type(NoteType.TODO)
         try:
             EditNote(self.gui.dbstate, self.gui.uistate, [], note,
                      self.created)
         except WindowActiveError:
             pass
     else:
         WarningDialog(
             _("No active object"),
             _("First select the object to which you want to attach a note")
             + _(":") + _(nav_type),
             parent=self.uistate.window)
示例#24
0
 def edit(self, obj):
     """
     Edit either a Source or a Citation, depending on user selection
     """
     for handle in self.selected_handles():
         # The handle will either be a Source handle or a Citation handle
         source = self.dbstate.db.get_source_from_handle(handle)
         citation = self.dbstate.db.get_citation_from_handle(handle)
         if (not source and not citation) or (source and citation):
             raise ValueError("selection must be either source or citation")
         if citation:
             try:
                 EditCitation(self.dbstate, self.uistate, [], citation)
             except WindowActiveError:
                 pass
         else: # FIXME need try block here
             try:
                 EditSource(self.dbstate, self.uistate, [], source)
             except WindowActiveError:
                 from gramps.gui.dialog import WarningDialog
                 WarningDialog(_("Cannot share this reference"),
                               self.__blocked_text2())
示例#25
0
    def save(self):
        """
        save action
        """
        doc = ODSTab(len(self.stats_list))
        doc.creator(self.db.get_researcher().get_name())
        name = self.dbstate.db.get_default_person().get_handle() + '.ods'
        if self.path != '.':
            name = os.path.join(self.path, name)
        try:
            import io
            io.open(name, "w", encoding='utf8')
        except PermissionError or IsADirectoryError:
            WarningDialog(_("You do not have write rights on this folder"))
            return

        spreadsheet = TableReport(name, doc)

        new_titles = []
        skip_columns = []
        index = 0
        for title in self.titles:
            if title == 'sort':
                skip_columns.append(index)
            else:
                new_titles.append(title)
            index += 1
        spreadsheet.initialize(len(new_titles))

        spreadsheet.write_table_head(new_titles)

        index = 0
        for top in self.stats_list:
            spreadsheet.set_row(index % 2)
            index += 1
            spreadsheet.write_table_data(top, skip_columns)

        spreadsheet.finalize()
示例#26
0
 def share(self, obj):
     """
     share:      Add a new citation to an existing source (when a source is
                   selected)
     """
     for handle in self.selected_handles():
         # The handle will either be a Source handle or a Citation handle
         source = self.dbstate.db.get_source_from_handle(handle)
         citation = self.dbstate.db.get_citation_from_handle(handle)
         if (not source and not citation) or (source and citation):
             raise ValueError("selection must be either source or citation")
         if source:
             try:
                 EditCitation(self.dbstate, self.uistate, [], Citation(),
                              source)
             except WindowActiveError:
                 from gramps.gui.dialog import WarningDialog
                 WarningDialog(_("Cannot share this reference"),
                               self.__blocked_text())
         else:
             msg = _("Cannot add citation.")
             msg2 = _("In order to add a citation to an existing source, "
                      " you must select a source.")
             ErrorDialog(msg, msg2)
示例#27
0
    def __init__(self, dbstate, user, options_class, name, callback=None):
        uistate = user.uistate

        tool.Tool.__init__(self, dbstate, options_class, name)

        self.window_name = _('Note Cleanup Tool')
        ManagedWindow.__init__(self, uistate, [], self.__class__)

        self.dbstate = dbstate
        self.trans = None
        self.moved_files = []
        self.titles = [_('Cleaned Notes'), _('Links Only'),
                       _('Issues')]
        self.models = []
        self.views = []
        self.changelist = []
        self.changelistidx = 0

        window = MyWindow(self.dbstate, self.uistate, [])
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        hbox.set_homogeneous(True)
        rvbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2,
                        width_request=400)
        vbox.pack_start(hbox, True, True, 5)
        self.notebook = Gtk.Notebook()
        self.notebook.set_scrollable(True)
        self.notebook.connect('switch-page', self.pagesw)
        for title in self.titles:
            self.create_tab(title)
        hbox.pack_start(self.notebook, True, True, 3)
        hbox.pack_start(rvbox, True, True, 3)

        bbox = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL)
        vbox.pack_start(bbox, False, False, 5)
        close = Gtk.Button(label=_('Close'))
        close.set_tooltip_text(_('Close the Note Cleanup Tool'))
        close.connect('clicked', self.close)
        save = Gtk.Button(label=_('Save All'))
        save.set_tooltip_text(_('Save All Changes'))
        save.connect('clicked', self.saveit)
        search = Gtk.Button(label=_('Search'))
        search.set_tooltip_text(_('Search for Untidy Notes'))
        search.connect('clicked', self.cleanup)
        testnote = Gtk.Button(label=_('Generate Test Notes'))
        testnote.set_tooltip_text(_(
            'Generate Test notes in range N99996-N99999.\n'
            'These are added to your database, so you may want to work with'
            ' a test database or delete them later.'))
        testnote.connect('clicked', self.gentest)
        export = Gtk.Button(label=_('Export'))
        export.set_tooltip_text(_('Export the results to a text file'))
        export.connect('clicked', self.export_results)
        bbox.add(search)
        bbox.add(testnote)
        bbox.add(export)
        bbox.add(save)
        bbox.add(close)
        self.tb = StyledTextEditor()
        self.tb.set_editable(False)
        self.tb.set_wrap_mode(Gtk.WrapMode.WORD)
        tbw = Gtk.ScrolledWindow()
        tbw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        tbw.add(self.tb)
        rvbox.pack_start(tbw, True, True, 0)
        self.ta = StyledTextEditor()
        self.ta.set_transient_parent(window)
        self.ta.set_editable(True)
        self.ta.set_wrap_mode(Gtk.WrapMode.WORD)
        taw = Gtk.ScrolledWindow()
        taw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        taw.add(self.ta)
        # tat=self.ta.get_toolbar()
        tat, self.action_group = self.ta.create_toolbar(
            uistate.uimanager, window)
        tat.set_icon_size(Gtk.IconSize.SMALL_TOOLBAR)
        tatb = tat.get_nth_item(5)
        tat.remove(tatb)
        tatb = tat.get_nth_item(5)
        tat.remove(tatb)
        rvbox.pack_start(tat, False, False, 0)
        rvbox.pack_start(taw, True, True, 0)
        self.clear_models()
        vbox.show_all()
        window.add(vbox)
        window.set_size_request(800, 400)
        self.set_window(window, None, self.window_name)
        self.show()

        self.show_tabs()
        WarningDialog(
            self.window_name,
            _("Please back up your database before running this tool.\n\n"
              "Start the tool by pressing the 'Search' button, then review"
              " the results.\n"
              "When satisifed press the 'Save All' button to save your work.\n"
              "You may export a summary list of the notes that"
              " were found using the 'Export' button."),
            self.window)
示例#28
0
    def calc_url(self):
        """ Determine the url to use on maps.google.com
            Logic: valid for places within Sweden and
                   Denmark, only if lat lon avalible
                   use lat lon if present
                   otherwise use city and country if present
                   otherwise use description of the place
        """
        place = self._get_first_place()[0]
        path = ""
        # First see if we are in or near Sweden or Denmark
        # Change country to upper case
        location = get_main_location(self.database, place)
        country = location.get(PlaceType.COUNTRY, '').upper().strip()
        country_given = (country in MAP_NAMES_SWEDEN or \
                        country in MAP_NAMES_DENMARK) and (country != "")
        # if no country given, check if we might be in the vicinity defined by
        # 54 33' 0" < lat < 66 9' 0", 54.55 and 69.05
        # 8 3' 0" < long < 24 9' 0", 8.05 and 24.15 
        latitude, longitude = self._lat_lon(place)
        if latitude is None or longitude is None:
            coord_ok = False
        else:
            latitude = float(latitude) 
            longitude = float(longitude)
            # Check if coordinates are inside Sweden and Denmark
            if (54.55 < latitude < 69.05) and (8.05 < longitude < 24.15):
                coord_ok = True
            else:
                msg2 = _("Latitude not within '54.55' to '69.05'\n") + \
                       _("Longitude not within '8.05' to '24.15'")
                WarningDialog(_("Eniro map not available"), msg2 )
                return

        if coord_ok:
            place_title = _build_title(self.database, place)
            place_city =  _build_city(self.database, place)
            x_coord, y_coord = self._lat_lon(place, format="RT90")
            # Set zoom level to 5 if Sweden/Denmark, others 3
            zoom = 5
            if not country_given:
                zoom = 3
            path = "http://www.eniro.se/partner.fcgi?pis=1&x=%s&y=%s" \
                   "&zoom_level=%i&map_size=0&title=%s&city=%s&partner=gramps"
            # Note x and y are swapped!
            path = path % (y_coord , x_coord, zoom, place_title, place_city)
            self.url = path.replace(" ","%20")
            return

        place_area = _build_area(self.database, place)
        if country_given and place_area:
            if country in MAP_NAMES_SWEDEN:
                path = "http://kartor.eniro.se/query?&what=map_adr&mop=aq" \
                       "&geo_area=%s&partner=gramps"
                path = path % (place_area)
                self.url = path.replace(" ","%20")
                return
            else:
                WarningDialog(_("Eniro map not available"), \
                              _("Coordinates needed in Denmark") )
                self.url = ""
                return

        WarningDialog(_("Eniro map not available"), 
                      _("Latitude and longitude,\n" \
                    "or street and city needed") )
        return
示例#29
0
    def verify_media(self, button):
        """
        Verify media objects have the correct path to files in the media
        directory.  List missing files, duplicate files, and files that do not
        yet have a media file in Gramps.
        """
        self.clear_models()
        self.moved_files = []

        media_path = self.db.get_mediapath()
        if media_path is None:
            WarningDialog(
                self.window_name,
                _('Media path not set.  You must set the "Base path '
                  'for relative media paths" in the Preferences.'),
                self.window)
            return

        progress = ProgressMeter(self.window_name,
                                 can_cancel=True,
                                 parent=self.window)

        length = 0
        for root, dirs, files in os.walk(media_path):
            length += len(files)
        progress.set_pass(_('Finding files'), length)

        all_files = {}
        for root, dirs, files in os.walk(media_path):
            for file_name in files:
                full_path = os.path.join(root, file_name)
                try:
                    with io.open(full_path, 'rb') as media_file:
                        md5sum = hashlib.md5(media_file.read()).hexdigest()
                except IOError as err:
                    error_msg = '%s: %s' % (err.strerror, full_path)
                    self.models[5].append((error_msg, None))
                    progress.step()
                    continue

                rel_path = relative_path(full_path, media_path)
                if md5sum in all_files:
                    all_files[md5sum].append(rel_path)
                else:
                    all_files[md5sum] = [rel_path]

                progress.step()
                if progress.get_cancelled():
                    break

        length = self.db.get_number_of_media()
        progress.set_pass(_('Checking paths'), length)

        in_gramps = []
        for handle in self.db.get_media_handles():
            media = self.db.get_media_from_handle(handle)

            md5sum = media.get_checksum()
            in_gramps.append(md5sum)

            # Moved files
            gramps_path = media.get_path()
            if md5sum in all_files:
                file_path = all_files[md5sum]
                if gramps_path not in file_path:
                    if len(file_path) == 1:
                        self.moved_files.append((handle, file_path[0]))
                        text = '%s -> %s' % (gramps_path, file_path[0])
                        self.models[0].append((text, handle))
                    else:
                        gramps_name = os.path.basename(gramps_path)
                        for path in file_path:
                            if os.path.basename(path) == gramps_name:
                                self.moved_files.append((handle, path))
                                text = '%s -> %s' % (gramps_path, path)
                                self.models[0].append((text, handle))
            elif md5sum is None:
                text = '[%s] %s' % (media.get_gramps_id(), gramps_path)
                self.models[4].append((text, str(handle)))
            else:
                self.models[1].append((gramps_path, handle))

            progress.step()
            if progress.get_cancelled():
                break

        # Duplicate files or files not in Gramps
        for md5sum in all_files:
            if len(all_files[md5sum]) > 1:
                text = ', '.join(all_files[md5sum])
                self.models[2].append((text, all_files[md5sum][0]))
            if md5sum not in in_gramps:
                text = ', '.join(all_files[md5sum])
                self.models[3].append((text, all_files[md5sum][0]))

        self.show_tabs()
        progress.close()
示例#30
0
    def __init__(self, dbstate, user, options_class, name, callback=None):
        uistate = user.uistate
        self.label = _("Relation and distances with root")
        self.dbstate = dbstate
        FilterClass = GenericFilterFactory('Person')
        self.path = '.'
        filter = FilterClass()

        tool.Tool.__init__(self, dbstate, options_class, name)
        if uistate:

            window = Gtk.Window()
            window.set_default_size(880, 600)

            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
            window.add(box)

            # dirty work-around for Gtk.HeaderBar() and FolderChooser

            chooser = Gtk.FileChooserDialog(
                _("Folder Chooser"),
                parent=uistate.window,
                action=Gtk.FileChooserAction.SELECT_FOLDER,
                buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL, _('_Select'),
                         Gtk.ResponseType.OK))
            chooser.set_tooltip_text(_("Please, select a folder"))
            status = chooser.run()
            if status == Gtk.ResponseType.OK:
                # work-around 'IsADirectoryError' with self()
                # TypeError: invalid file: gi.FunctionInfo()
                self.path = chooser.get_current_folder()
            chooser.destroy()

            ManagedWindow.__init__(self, uistate, [], self.__class__)
            self.titles = [
                (_('Rel_id'), 0, 40, INTEGER),  # would be INTEGER
                (_('Relation'), 1, 300, str),
                (_('Name'), 2, 200, str),
                (_('up'), 3, 35, INTEGER),
                (_('down'), 4, 35, INTEGER),
                (_('Common MRA'), 5, 40, INTEGER),
                (_('Rank'), 6, 40, INTEGER),
                (_('Period'), 7, 40, str),
            ]

            treeview = Gtk.TreeView()
            model = ListModel(treeview, self.titles)
            s = Gtk.ScrolledWindow()
            s.add(treeview)
            box.pack_start(s, True, True, 0)

            button = Gtk.Button(label=_("Save"))
            button.connect("clicked", self.button_clicked)
            box.pack_end(button, False, True, 0)

        self.stats_list = []

        # behavior can be different according to CPU and generation depth

        max_level = config.get('behavior.generation-depth')
        # compact and interlinked tree
        # single core 2.80 Ghz needs +/- 0.1 second per person
        if max_level >= 15:
            var = max_level * 0.01
        elif 10 <= max_level < 15:
            var = max_level * 0.02
        else:
            var = max_level * 0.025

        plist = self.dbstate.db.iter_person_handles()
        length = self.dbstate.db.get_number_of_people()
        default_person = self.dbstate.db.get_default_person()
        if uistate:
            self.progress = ProgressMeter(self.label,
                                          can_cancel=True,
                                          parent=window)
        else:
            self.progress = ProgressMeter(self.label)

        if default_person:  # rather designed for run via GUI...
            root_id = default_person.get_gramps_id()
            ancestors = rules.person.IsAncestorOf([str(root_id), True])
            descendants = rules.person.IsDescendantOf([str(root_id), True])
            related = rules.person.IsRelatedWith([str(root_id)])

            # filtering people can be useful on some large data set
            # counter on filtering pass was not efficient
            # Not the proper solution, but a lazy one providing expected message

            filter.add_rule(related)
            self.progress.set_pass(_('Please wait, filtering...'))
            filtered_list = filter.apply(self.dbstate.db, plist)

            relationship = get_relationship_calculator()
        else:  # TODO: provide selection widget for CLI and GUI
            WarningDialog(_("No default_person"))
            return

        count = 0
        filtered_people = len(filtered_list)
        self.progress.set_pass(_('Generating relation map...'),
                               filtered_people)
        if self.progress.get_cancelled():
            self.progress.close()
            return
        step_one = time.clock()  # init for counters
        for handle in filtered_list:
            nb = len(self.stats_list)
            count += 1
            self.progress.step()
            step_two = time.clock()
            start = 99
            if count > start:  # provide a basic interface for counters
                need = (step_two - step_one) / count
                wait = need * filtered_people
                remain = int(wait) - int(step_two - step_one)
                # sorry, lazy
                header = _("%d/%d \n %d/%d seconds \n %d/%d \n%f|\t%f" %
                           (count, filtered_people, remain, int(wait), nb,
                            length, float(need), float(var)))
                self.progress.set_header(header)
                if self.progress.get_cancelled():
                    self.progress.close()
                    return
            person = dbstate.db.get_person_from_handle(handle)

            timeout_one = time.clock()  # for delta and timeout estimations
            dist = relationship.get_relationship_distance_new(dbstate.db,
                                                              default_person,
                                                              person,
                                                              only_birth=True)
            timeout_two = time.clock()

            rank = dist[0][0]
            if rank == -1 or rank > max_level:  # not related and ignored people
                continue

            limit = timeout_two - timeout_one
            expect = (limit - var) / max_level
            if limit > var:
                n = name_displayer.display(person)
                _LOG.debug("Sorry! '{0}' needs {1} second, \
                            variation = '{2}'".format(n, limit, expect))
                continue
            else:
                _LOG.debug("variation = '{}'".format(
                    limit))  # delta, see above max_level 'wall' section
                rel = relationship.get_one_relationship(
                    dbstate.db, default_person, person)
                rel_a = dist[0][2]
                Ga = len(rel_a)
                rel_b = dist[0][4]
                Gb = len(rel_b)
                mra = 1

                # m: mother; f: father
                if Ga > 0:
                    for letter in rel_a:
                        if letter == 'm':
                            mra = mra * 2 + 1
                        if letter == 'f':
                            mra = mra * 2
                    # design: mra gender will be often female (m: mother)
                    if rel_a[-1] == "f" and Gb != 0:  # male gender, look at spouse
                        mra = mra + 1

                name = name_displayer.display(person)
                # pseudo privacy; sample for DNA stuff and mapping
                import hashlib
                no_name = hashlib.sha384(name.encode() +
                                         handle.encode()).hexdigest()
                _LOG.info(no_name)  # own internal password via handle

                kekule = number.get_number(Ga, Gb, rel_a, rel_b)

                # workaround - possible unique ID and common numbers
                uuid = str(uuid4())
                _LOG.info("Random UUID: {}".format(uuid))

                if kekule == "u":  # TODO: cousin(e)s need a key
                    kekule = 0
                if kekule == "nb":  # non-birth
                    kekule = -1
                try:
                    test = int(kekule)
                except:  # 1: related to mother; 0.x : no more girls lineage
                    kekule = 1

                period = get_timeperiod(self.dbstate.db, handle)

                # sometimes 'iterator' (generator) is more faster
                #handle_list = map(handle, filtered_list)
                iterator = (handle for handle in filtered_list)

                # experimentations; not used yet
                new_list = [int(kekule), int(Ga), int(Gb), int(mra), int(rank)]
                line = (iterator, array('b', new_list))

                self.stats_list.append(
                    (int(kekule), rel, name, int(Ga), int(Gb), int(mra),
                     int(rank), str(period)))
        self.progress.close()

        from itertools import groupby
        for key, items in groupby(self.stats_list, lambda x: x[0]):
            for subitem in items:
                _LOG.info(subitem)

        _LOG.debug("total: {}".format(nb))
        for entry in self.stats_list:
            if uistate:
                model.add(entry, entry[0])
            else:
                print(entry)
        if uistate:
            window.show()
            self.set_window(window, None, self.label)
            self.show()