Looking for an example of a Gramplet with a Custom Filter Configuration option

I would like to put a Filter or Custom Filter option in the Configuration options for a Gramplet and to add to the wiki’s Addon Development x-ref. Is there an Example of a Gramplet that has a Filter selection in the Configuration options?

Objective: To initially start the What’s Next? gramplet with the scope limited to families of the Home Person’s family members. But be able to optionally release that scope limitation.
The Gramplet needs to be less of a resource hog and starting with a small scope seems like the way to do it.

Searching the Addons offline manual, I found examples of Custom Filters in Tools, Reports, and Exporter plugin Types… but those are not examples of how to add things to the Configuration tab.

The wiki article for making Gramplets just has a list of GUI Options without links to the documentation or examples.

@Urchello asked for something similar for the filtering the Records Gramplet and @GeorgeWilmes asked about filtering DNA matches. But both would be considered major hacks to effort and went unanswered.

@eugene requested a universal Custom Filter option as an upgrade to Reports in “Filters are great! Why don’t all reports use them?

Here is a more or less minimal example that uses the Filter option. Is this what you are looking for?

from gramps.gen.filters import CustomFilters
from gramps.gen.plug import Gramplet
from gramps.gen.plug.menu import FilterOption

class SampleGramplet(Gramplet):

    def init(self):
        self.filter_list = CustomFilters.get_filters('Person')
        self.filter_index = 0

    def build_options(self):
        self.filter_option = FilterOption('Filter', self.filter_index)
        self.filter_option.set_filters(self.filter_list)
        self.add_option(self.filter_option)
        self.print_filter_name()
        
    def on_load(self):
        if len(self.gui.data) > 0:           
            self.filter_index = int(self.gui.data[0])

    def save_options(self):
        self.filter_index = self.filter_option.get_value()
        self.gui.data = [self.filter_index]
        self.print_filter_name()

    def print_filter_name(self):
        selected_filter = self.filter_option.get_filter()
        self.append_text("Filter = " + selected_filter.name + "\n")
1 Like

Thanks for the sample code and sorry for delay. It took 3 days to make progress with this because I couldn’t get a Gramps Plugin Registration (.gpr.py) to work.

I needed the extra feedback launching Gramps from the terminal to isolate the problem. (Which was: other addons were freaking out the Registration and causing it to stop processing. Resolving those other problems allowed this registration to complete.)

But that meant discovering how to get Gramps to start launching from the terminal again. (I had removed a developmental version of Gramps and it fell back to a Flatpak instance. Launching the Flatpak instance is very different then launching from the development instance.)

Saved your sample into a new file called SampleGramplet.py in a SampleGramplet folder in my gramps52/plugins folder of my Gramps User Directory.

The corresponding Gramps Plugin Registration file is called SampleGramplet.gpr.py with the content:

# encoding:utf-8
#
# Gramps plugin- an addon gramplet for
# the Gramps GTK+/GNOME based genealogy program
#
# Copyright (C) 2024     Kari Kujansuu
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

# ------------------------------------------------------------------------
#
# Gramps Plugin Registration (metadata and configuration information)
#    a sidecar to the file idendified below as the fname (filename)
#    see https://gramps-project.org/wiki/index.php/Gramps_Glossary#addon
#
# ------------------------------------------------------------------------

# See https://www.gramps-project.org/wiki/index.php/Gramplets

from gramps.version import major_version, VERSION_TUPLE

if VERSION_TUPLE < (5, 2, 0):
    additional_args = {
        "status": UNSTABLE, # Status attribute required
        "help_url": "Gramplets",#secure http not supported in these versions
    }
else:
    additional_args = {
        "status": EXPERIMENTAL, # Status attribute required
        "audience": EXPERT,
        "maintainers": ["Kari Kujansuu",
            "Gramps Bugtracker"],
        "maintainers_email": ["kari.kujansuu@gmail.com",
            "https://gramps-project.org/bugs"],
        "help_url": "https://www.gramps-project.org/wiki/index.php/Gramplets",
#        "requires_mod": ['svgwrite'],
#        "requires_gi": [('GooCanvas', '2.0,3.0')],
#        "requires_exe": ['dot'],
    }

# ------------------------------------------------------------------------
#
# Register Gramplet
#
# ------------------------------------------------------------------------

register(GRAMPLET, # uppercase
         id="SampleGramplet", # required to be unique
         name=_("Sample Gramplet"), # uniqueness helpful
         description=_("sample Gramplet with "
             "filter Configuration options"
         ), # optional attribute, uniqueness helpful
         navtypes=["Person","Families"], # optional attribute
         authors=["Kari Kujansuu"], # optional attribute
         authors_email=["kari.kujansuu@gmail.com"], # optional attribute
         fname="SampleGramplet.py",
         height=300,
         detached_width=250, # optional attribute
         detached_height=400, # optional attribute
         expand=True, # optional attribute
         gramplet='SampleGramplet',
         gramplet_title=_("Sample Gramplet"), # uniqueness helpful
         version = '0.0.0',
         gramps_target_version=major_version,
         **additional_args,
         )

5 posts were split to a new topic: Add an Experimental Addons repository?

Can the filter.comment be added as a tooltip for each filtername menu item too?

set_tooltip_text(filter.comment)

Adding some Inspect module debug statements using formatted string literals (f-string) in the print_filter_name

# encoding:utf-8
#
# Gramps plugin- a template to create an filtered addon gramplet for
# the Gramps GTK+/GNOME based genealogy program
#
# Copyright (C) 2024     Kari Kujansuu
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

# ------------------------------------------------------------------------
#
# Gramps modules
#
# ------------------------------------------------------------------------

# See https://www.gramps-project.org/wiki/index.php/Gramplets

import inspect # debug library
from gramps.gen.filters import CustomFilters
from gramps.gen.plug.menu import FilterOption
from gramps.gen.plug import Gramplet

class SampleGramplet(Gramplet):

    def init(self):
        self.filter_list = CustomFilters.get_filters('Person')
        self.filter_index = 0

    def build_options(self):
        self.filter_option = FilterOption('Filter', self.filter_index)
        self.filter_option.set_filters(self.filter_list)
        self.add_option(self.filter_option)
        self.print_filter_name() # debug

    def on_load(self):
        if len(self.gui.data) > 0:
            self.filter_index = int(self.gui.data[0])

    def save_options(self):
        self.filter_index = self.filter_option.get_value()
        self.gui.data = [self.filter_index]
        self.print_filter_name() # debug

    def print_filter_name(self):
        selected_filter = self.filter_option.get_filter()
        self.append_text(
            f"Called from: {inspect.currentframe().f_back.f_code.co_name}\n"
        )  # debug: ID the function's name which calls this function
        self.append_text(f"Filter =  {selected_filter.name}\n")

image

Some Reports (like Complete Individual, Birthday and Anniversary, and Family Group) push a set of preset filters from report/utils.py into the Custom Filters. Samples include :

People generic filters

  • <active person>
  • Entire Database/None
  • Descendants of <active person>
  • Descendant Families of <active person>
  • Ancestors of <active person>
  • People with common ancestor with <active person>

Family generic filters

  • <active family>
  • Every family
  • Descendant families of <active family>
  • Ancestor families of <active family>

Pushing preset filters for Active Person and Home Person would probably be commonly needed and good examples to embed in this example.