Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Petr Hejl 2016-09-02 12:16:17 +02:00
commit 639ca24ffb
24 changed files with 76611 additions and 15462 deletions

1822
data/tests/data.gramps Normal file

File diff suppressed because it is too large Load Diff

65712
data/tests/example.gramps Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
"http://gramps-project.org/xml/1.7.1/grampsxml.dtd">
<database xmlns="http://gramps-project.org/xml/1.7.1/">
<header>
<created date="2016-06-29" version="5.0.0"/>
<created date="2016-08-31" version="5.0.0"/>
<researcher>
<resname>Alex Roitman,,,</resname>
</researcher>
@ -40537,6 +40537,250 @@
<eventref hlink="_d583a5b8de520210f77" role="Primary"/>
<childof hlink="_d583a5b9c2011be735e"/>
</person>
<person handle="_d64cc45225909a9f8e4" change="1471261290" id="I2128">
<gender>M</gender>
<name type="Birth Name">
<first>演</first>
<surname>賈</surname>
<title>寧國公</title>
</name>
<parentin hlink="_d64cc45226a0dfb300f"/>
</person>
<person handle="_d64cc4522a25541863a" change="1471261530" id="I2129">
<gender>M</gender>
<name type="Birth Name">
<first>代化</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45226a0dfb300f"/>
<parentin hlink="_d64cc4522b06749ba4c"/>
</person>
<person handle="_d64cc4522c47c1ef24b" change="1471261530" id="I2130">
<gender>M</gender>
<name type="Birth Name">
<first>敷</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4522b06749ba4c"/>
</person>
<person handle="_d64cc4522e6663313ec" change="1471261583" id="I2131">
<gender>M</gender>
<name type="Birth Name">
<first>敬</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4522b06749ba4c"/>
<parentin hlink="_d64cc4522f47c94569c"/>
</person>
<person handle="_d64cc4523087ccd3035" change="1471262021" id="I2132">
<gender>M</gender>
<name type="Birth Name">
<first>珍</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4522f47c94569c"/>
<parentin hlink="_d64cc4523142408321f"/>
</person>
<person handle="_d64cc45234f188bf949" change="1471261583" id="I2133">
<gender>F</gender>
<name type="Birth Name">
<first>惜春</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4522f47c94569c"/>
</person>
<person handle="_d64cc45236a783dbbf6" change="1471262021" id="I2134">
<gender>F</gender>
<name type="Birth Name">
<surname>尤</surname>
<suffix>氏</suffix>
</name>
<parentin hlink="_d64cc4523142408321f"/>
</person>
<person handle="_d64cc45238476e9d26a" change="1471262124" id="I2135">
<gender>M</gender>
<name type="Birth Name">
<first>蓉</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4523142408321f"/>
<parentin hlink="_d64cc45239001cdf947"/>
</person>
<person handle="_d64cc4523a4611260bf" change="1471262124" id="I2136">
<gender>F</gender>
<name type="Birth Name">
<first>可卿</first>
<surname>秦</surname>
</name>
<parentin hlink="_d64cc45239001cdf947"/>
</person>
<person handle="_d64cc4523be0c1791d5" change="1471262210" id="I2137">
<gender>M</gender>
<name type="Birth Name">
<first>源</first>
<surname>賈</surname>
</name>
<parentin hlink="_d64cc4523c966e01266"/>
</person>
<person handle="_d64cc452402720737d5" change="1471262354" id="I2138">
<gender>M</gender>
<name type="Birth Name">
<first>代善</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4523c966e01266"/>
<parentin hlink="_d64cc452410372bc064"/>
</person>
<person handle="_d64cc4524240e0ea6ff" change="1471262354" id="I2139">
<gender>F</gender>
<name type="Birth Name">
<surname>史</surname>
<suffix>太君</suffix>
<nick>賈母</nick>
</name>
<parentin hlink="_d64cc452410372bc064"/>
</person>
<person handle="_d64cc45243f29eeabeb" change="1471262469" id="I2140">
<gender>M</gender>
<name type="Birth Name">
<first>赦</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc452410372bc064"/>
<parentin hlink="_d64cc45244b4e1a8567"/>
</person>
<person handle="_d64cc45246078d746fa" change="1471262876" id="I2141">
<gender>M</gender>
<name type="Birth Name">
<first>政</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc452410372bc064"/>
<parentin hlink="_d64cc45246e02fe0334"/>
<parentin hlink="_d64cc4524747894466e"/>
</person>
<person handle="_d64cc4524ae5d46fe71" change="1471262377" id="I2142">
<gender>M</gender>
<name type="Birth Name">
<first>敏</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc452410372bc064"/>
</person>
<person handle="_d64cc4524c9414ca537" change="1471262469" id="I2143">
<gender>F</gender>
<name type="Birth Name">
<surname>邢</surname>
<suffix>夫人</suffix>
</name>
<parentin hlink="_d64cc45244b4e1a8567"/>
</person>
<person handle="_d64cc4524e20ba8c5d6" change="1471262627" id="I2144">
<gender>M</gender>
<name type="Birth Name">
<first>璉</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45244b4e1a8567"/>
<parentin hlink="_d64cc4524ef256e2df7"/>
</person>
<person handle="_d64cc45250328111b9b" change="1471262469" id="I2145">
<gender>F</gender>
<name type="Birth Name">
<first>迎春</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45244b4e1a8567"/>
</person>
<person handle="_d64cc45251c7930ed38" change="1471262627" id="I2146">
<gender>F</gender>
<name type="Birth Name">
<first>熙鳳</first>
<surname>王</surname>
</name>
<parentin hlink="_d64cc4524ef256e2df7"/>
</person>
<person handle="_d64cc45255a74180535" change="1471262627" id="I2147">
<gender>F</gender>
<name type="Birth Name">
<first>巧姊</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4524ef256e2df7"/>
</person>
<person handle="_d64cc4525764d82e6ba" change="1471262779" id="I2148">
<gender>F</gender>
<name type="Birth Name">
<surname>王</surname>
<suffix>夫人</suffix>
</name>
<parentin hlink="_d64cc45246e02fe0334"/>
</person>
<person handle="_d64cc45258f454e7dac" change="1471262968" id="I2149">
<gender>M</gender>
<name type="Birth Name">
<first>珠</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45246e02fe0334"/>
<parentin hlink="_d64cc45259c01f324b4"/>
</person>
<person handle="_d64cc4525af3a331cd9" change="1471262779" id="I2150">
<gender>F</gender>
<name type="Birth Name">
<first>元春</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45246e02fe0334"/>
</person>
<person handle="_d64cc4525c94ed2c938" change="1471262779" id="I2151">
<gender>M</gender>
<name type="Birth Name">
<first>寶玉</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45246e02fe0334"/>
</person>
<person handle="_d64cc4526074d046198" change="1471262876" id="I2152">
<gender>F</gender>
<name type="Birth Name">
<surname>趙</surname>
<suffix>姨娘</suffix>
</name>
<parentin hlink="_d64cc4524747894466e"/>
</person>
<person handle="_d64cc452621787a9a8a" change="1471262891" id="I2153">
<gender>F</gender>
<name type="Birth Name">
<first>探春</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4524747894466e"/>
</person>
<person handle="_d64cc45263b36486ac0" change="1471262876" id="I2154">
<gender>M</gender>
<name type="Birth Name">
<first>環</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc4524747894466e"/>
</person>
<person handle="_d64cc452655308a46f8" change="1471262968" id="I2155">
<gender>F</gender>
<name type="Birth Name">
<first>紈</first>
<surname>李</surname>
</name>
<parentin hlink="_d64cc45259c01f324b4"/>
</person>
<person handle="_d64cc45266e3ae4c5fd" change="1471263007" id="I2156">
<gender>M</gender>
<name type="Birth Name">
<first>蘭</first>
<surname>賈</surname>
</name>
<childof hlink="_d64cc45259c01f324b4"/>
</person>
</people>
<families>
<family handle="_03GKQCH37C1SL9C5B3" change="1185438865" id="F0372">
@ -47000,6 +47244,81 @@
<mother hlink="_d583a5ba4be3acdd312"/>
<childref hlink="_d583a5b9ced473a7e6a"/>
</family>
<family handle="_d64cc45226a0dfb300f" change="1471261290" id="F0750">
<rel type="Married"/>
<father hlink="_d64cc45225909a9f8e4"/>
<childref hlink="_d64cc4522a25541863a"/>
</family>
<family handle="_d64cc4522b06749ba4c" change="1471261530" id="F0751">
<rel type="Unknown"/>
<father hlink="_d64cc4522a25541863a"/>
<childref hlink="_d64cc4522c47c1ef24b"/>
<childref hlink="_d64cc4522e6663313ec"/>
</family>
<family handle="_d64cc4522f47c94569c" change="1471261583" id="F0752">
<rel type="Unknown"/>
<father hlink="_d64cc4522e6663313ec"/>
<childref hlink="_d64cc4523087ccd3035"/>
<childref hlink="_d64cc45234f188bf949"/>
</family>
<family handle="_d64cc4523142408321f" change="1471262070" id="F0753">
<rel type="Married"/>
<father hlink="_d64cc4523087ccd3035"/>
<mother hlink="_d64cc45236a783dbbf6"/>
<childref hlink="_d64cc45238476e9d26a"/>
</family>
<family handle="_d64cc45239001cdf947" change="1471262124" id="F0754">
<rel type="Unknown"/>
<father hlink="_d64cc45238476e9d26a"/>
<mother hlink="_d64cc4523a4611260bf"/>
</family>
<family handle="_d64cc4523c966e01266" change="1471262210" id="F0755">
<rel type="Unknown"/>
<father hlink="_d64cc4523be0c1791d5"/>
<childref hlink="_d64cc452402720737d5"/>
</family>
<family handle="_d64cc452410372bc064" change="1471262377" id="F0756">
<rel type="Married"/>
<father hlink="_d64cc452402720737d5"/>
<mother hlink="_d64cc4524240e0ea6ff"/>
<childref hlink="_d64cc45243f29eeabeb"/>
<childref hlink="_d64cc45246078d746fa"/>
<childref hlink="_d64cc4524ae5d46fe71"/>
</family>
<family handle="_d64cc45244b4e1a8567" change="1471262469" id="F0757">
<rel type="Married"/>
<father hlink="_d64cc45243f29eeabeb"/>
<mother hlink="_d64cc4524c9414ca537"/>
<childref hlink="_d64cc4524e20ba8c5d6"/>
<childref hlink="_d64cc45250328111b9b"/>
</family>
<family handle="_d64cc45246e02fe0334" change="1471262779" id="F0759">
<rel type="Married"/>
<father hlink="_d64cc45246078d746fa"/>
<mother hlink="_d64cc4525764d82e6ba"/>
<childref hlink="_d64cc45258f454e7dac"/>
<childref hlink="_d64cc4525af3a331cd9"/>
<childref hlink="_d64cc4525c94ed2c938"/>
</family>
<family handle="_d64cc4524747894466e" change="1471262876" id="F0760">
<rel type="Unknown"/>
<father hlink="_d64cc45246078d746fa"/>
<mother hlink="_d64cc4526074d046198"/>
<childref hlink="_d64cc452621787a9a8a"/>
<childref hlink="_d64cc45263b36486ac0"/>
</family>
<family handle="_d64cc4524ef256e2df7" change="1471262627" id="F0758">
<rel type="Married"/>
<father hlink="_d64cc4524e20ba8c5d6"/>
<mother hlink="_d64cc45251c7930ed38"/>
<childref hlink="_d64cc45255a74180535"/>
</family>
<family handle="_d64cc45259c01f324b4" change="1471263007" id="F0761">
<rel type="Married"/>
<father hlink="_d64cc45258f454e7dac"/>
<mother hlink="_d64cc452655308a46f8"/>
<childref hlink="_d64cc45266e3ae4c5fd"/>
</family>
</families>
<citations>
<citation handle="_c140d2362f25a92643b" change="1328025930" id="C0000">

View File

@ -36,6 +36,7 @@ import collections
#-------------------------------------------------------------------------
from ._filterparser import FilterParser
from ..plug import BasePluginManager
from ..const import GRAMPS_LOCALE as glocale
PLUGMAN = BasePluginManager.get_instance()
#-------------------------------------------------------------------------
@ -129,7 +130,8 @@ class FilterList:
file.write(' <object type="%s">\n' % namespace)
filter_list = self.filter_namespaces[namespace]
sorted_filters = sorted([(filter.get_name(), filter)
for filter in filter_list])
for filter in filter_list],
key=lambda x: glocale.sort_key(x[0]))
for (name, the_filter) in sorted_filters: # enable a diff
file.write(' <filter name="%s"' % self.fix(name))
file.write(' function="%s"' % the_filter.get_logical_op())

View File

@ -22,10 +22,12 @@
Unittest that tests event-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilterFactory
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.event import (
AllEvents, HasType, HasIdOf, HasGallery, RegExpIdOf, HasCitation, HasNote,
@ -33,6 +35,8 @@ from gramps.gen.filters.rules.event import (
MatchesSourceConfidence, HasAttribute, HasData, ChangedSince, HasTag,
HasDayOfWeek)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
GenericEventFilter = GenericFilterFactory('Event')
class BaseTest(unittest.TestCase):
@ -45,7 +49,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -22,10 +22,12 @@
Unittest that tests family-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilterFactory
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.family import (
AllFamilies, HasRelType, HasGallery, HasIdOf, HasLDS, HasNote, RegExpIdOf,
@ -35,6 +37,8 @@ from gramps.gen.filters.rules.family import (
MotherHasIdOf, ChildHasNameOf, ChildHasIdOf, ChangedSince, HasTag,
HasTwins, IsAncestorOf, IsDescendantOf)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
GenericFamilyFilter = GenericFilterFactory('Family')
class BaseTest(unittest.TestCase):
@ -47,7 +51,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -22,10 +22,12 @@
Unittest that tests media-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilterFactory
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.media import (
AllMedia, HasIdOf, RegExpIdOf, HasCitation, HasNoteRegexp,
@ -33,6 +35,8 @@ from gramps.gen.filters.rules.media import (
HasSourceOf, MediaPrivate, MatchesSourceConfidence, HasMedia,
HasAttribute, ChangedSince, HasTag)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
GenericMediaFilter = GenericFilterFactory('Media')
class BaseTest(unittest.TestCase):
@ -45,7 +49,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -22,15 +22,19 @@
Unittest that tests note-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilterFactory
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.note import (
AllNotes, HasIdOf, RegExpIdOf, HasNote, MatchesRegexpOf,
HasReferenceCountOf, NotePrivate, ChangedSince, HasTag, HasType)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
GenericNoteFilter = GenericFilterFactory('Note')
class BaseTest(unittest.TestCase):
@ -43,7 +47,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -22,10 +22,12 @@
Unittest that tests person-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilter
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.person import (
Disconnected, Everyone, FamilyWithIncompleteEvent, HasAlternateName,
@ -36,6 +38,9 @@ from gramps.gen.filters.rules.person import (
NoDeathdate, PeoplePrivate, PeoplePublic, PersonWithIncompleteEvent,
RelationshipPathBetweenBookmarks)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
class BaseTest(unittest.TestCase):
"""
Person rule tests.
@ -46,7 +51,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -22,10 +22,12 @@
Unittest that tests place-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilterFactory
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.place import (
AllPlaces, HasCitation, HasGallery, HasIdOf, RegExpIdOf, HasNote,
@ -33,6 +35,8 @@ from gramps.gen.filters.rules.place import (
PlacePrivate, MatchesSourceConfidence, HasData, HasNoLatOrLon,
InLatLonNeighborhood, ChangedSince, HasTag, HasTitle, IsEnclosedBy)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
GenericPlaceFilter = GenericFilterFactory('Place')
class BaseTest(unittest.TestCase):
@ -45,7 +49,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -22,15 +22,19 @@
Unittest that tests repository-specific filter rules
"""
import unittest
import os
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.filters import GenericFilterFactory
from gramps.gen.const import DATA_DIR
from gramps.gen.filters.rules.repository import (
AllRepos, HasIdOf, RegExpIdOf, HasNoteRegexp, HasReferenceCountOf,
RepoPrivate, ChangedSince, MatchesNameSubstringOf, HasTag)
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
GenericRepositoryFilter = GenericFilterFactory('Repository')
class BaseTest(unittest.TestCase):
@ -43,7 +47,7 @@ class BaseTest(unittest.TestCase):
"""
Import example database.
"""
cls.db = import_as_dict("example/gramps/example.gramps", User())
cls.db = import_as_dict(EXAMPLE, User())
def filter_with_rule(self, rule):
"""

View File

@ -21,6 +21,7 @@
""" Unittest for to_struct, from_struct """
import unittest
import os
from .. import (Person, Family, Event, Source, Place, Citation,
Repository, Media, Note, Tag)
@ -28,6 +29,10 @@ from gramps.gen.lib.struct import Struct
from gramps.gen.merge.diff import import_as_dict
from gramps.cli.user import User
from gramps.gen.merge.diff import *
from gramps.gen.const import DATA_DIR
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
EXAMPLE = os.path.join(TEST_DIR, "example.gramps")
class BaseCheck:
def test_from_struct(self):
@ -108,7 +113,7 @@ def generate_case(obj):
#name = "test_create_%s_%s" % (obj.__class__.__name__, obj.handle)
#setattr(DatabaseCheck, name, test2)
db = import_as_dict("example/gramps/example.gramps", User())
db = import_as_dict(EXAMPLE, User())
for table in db.get_table_func():
for handle in db.get_table_func(table,"handles_func")():
obj = db.get_table_func(table,"handle_func")(handle)

View File

@ -49,10 +49,6 @@ class MockEditReference(EditReference):
self.window = MockWindow()
super().__init__(dbstate, uistate, track, source, source_ref, update)
example = os.path.abspath(
os.path.join(os.path.dirname(os.path.abspath(__file__)),
"../../../..",
"example/gramps/example.gramps"))
class TestEditReference(unittest.TestCase):

View File

@ -24,10 +24,10 @@ import os
from gramps.test.test_util import Gramps
from gramps.gen.db import open_database
from gramps.gen.lib import *
from gramps.gen.const import DATA_DIR
ddir = os.path.dirname(__file__)
example = os.path.join(ddir, "..", "..", "..", "..",
"example", "gramps", "data.gramps")
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
example = os.path.join(TEST_DIR, "data.gramps")
class BSDDB:
NAME = "Example BSDDB Test"

View File

@ -174,7 +174,7 @@ class _PersonWidgetBase(Gtk.DrawingArea):
class PersonBoxWidgetCairo(_PersonWidgetBase):
"""Draw person box using cairo library"""
def __init__(self, view, format_helper, dbstate, person, alive, maxlines,
image=None):
image=None, tags=False):
_PersonWidgetBase.__init__(self, view, format_helper, person)
self.set_size_request(120, 25)
# Required for tooltip and mouse-over
@ -193,6 +193,13 @@ class PersonBoxWidgetCairo(_PersonWidgetBase):
else:
gender = None
self.bgcolor, self.bordercolor = color_graph_box(alive, gender)
if tags and person:
for tag_handle in person.get_tag_list():
# For the complete tag, don't modify the default color
# which is black (#000000000000)
tag = dbstate.db.get_tag_from_handle(tag_handle)
if tag.get_color() != "#000000000000": # only if the color
self.bgcolor = tag.get_color() # is not black
self.bgcolor = hex_to_rgb_float(self.bgcolor)
self.bordercolor = hex_to_rgb_float(self.bordercolor)
@ -504,6 +511,7 @@ class PedigreeView(NavigationView):
('interface.pedview-layout', 0),
('interface.pedview-show-images', True),
('interface.pedview-show-marriage', True),
('interface.pedview-show-tags', False),
('interface.pedview-tree-direction', 2),
('interface.pedview-show-unknown-people', True),
)
@ -549,6 +557,8 @@ class PedigreeView(NavigationView):
# Hide marriage data by default
self.show_marriage_data = self._config.get(
'interface.pedview-show-marriage')
# Show person with tag color
self.show_tag_color = self._config.get('interface.pedview-show-tags')
# Tree draw direction
self.tree_direction = self._config.get('interface.pedview-tree-direction')
self.cb_change_scroll_direction(None, self.tree_direction < 2)
@ -929,7 +939,8 @@ class PedigreeView(NavigationView):
# No person -> show empty box
#
pbw = PersonBoxWidgetCairo(self, self.format_helper,
self.dbstate, None, False, 0, None)
self.dbstate, None, False, 0, None,
tags=self.show_tag_color)
if i > 0 and lst[((i+1) // 2) - 1]:
fam_h = None
@ -952,7 +963,8 @@ class PedigreeView(NavigationView):
image = True
pbw = PersonBoxWidgetCairo(self, self.format_helper,
self.dbstate, lst[i][0], lst[i][3], height, image)
self.dbstate, lst[i][0], lst[i][3], height, image,
tags=self.show_tag_color)
lst[i][4] = pbw
if height < 7:
pbw.set_tooltip_text(self.format_helper.format_person(
@ -1917,6 +1929,16 @@ class PedigreeView(NavigationView):
self.menu.popup(None, None, None, None, 0, event.time)
return 1
def cb_update_show_tags(self, client, cnxn_id, entry, data):
"""
Called when the configuration menu changes the tags setting.
"""
if entry == 'True':
self.show_tag_color = True
else:
self.show_tag_color = False
self.rebuild_trees(self.get_active())
def cb_update_show_images(self, client, cnxn_id, entry, data):
"""
Called when the configuration menu changes the images setting.
@ -1989,6 +2011,8 @@ class PedigreeView(NavigationView):
self.cb_update_show_images)
self._config.connect('interface.pedview-show-marriage',
self.cb_update_show_marriage)
self._config.connect('interface.pedview-show-tags',
self.cb_update_show_tags)
self._config.connect('interface.pedview-show-unknown-people',
self.cb_update_show_unknown_people)
self._config.connect('interface.pedview-tree-direction',
@ -2023,6 +2047,9 @@ class PedigreeView(NavigationView):
configdialog.add_checkbox(grid,
_('Show unknown people'),
2, 'interface.pedview-show-unknown-people')
configdialog.add_checkbox(grid,
_('Show tags'),
3, 'interface.pedview-show-tags')
configdialog.add_combo(grid,
_('Tree style'),
4, 'interface.pedview-layout',

View File

@ -1711,6 +1711,8 @@ class BasePage:
else:
msg += _(' on %(date)s') % {'date' : _dd.display(Today())}
origin1 = self.report.filter.get_name()
filt_number = self.report.options['filter']
# optional "link-home" feature; see bug report #2736
if self.report.options['linkhome']:
center_person = self.r_db.get_person_from_gramps_id(
@ -1721,12 +1723,20 @@ class BasePage:
center_person.handle, "ppl", self.uplink)
person_name = self.get_name(center_person)
subject_url = '<a href="' + center_person_url + '">'
subject_url += person_name + '</a>'
if filt_number > 0 and filt_number < 5:
subject_url = '<a href="' + center_person_url + '">'
subject_url += origin1 + '</a>'
else:
subject_url = origin1
msg += _(
'%(http_break)sCreated for %(subject_url)s') % {
'http_break' : '<br />',
'subject_url' : subject_url}
else:
msg += _(
'%(http_break)sCreated for %(subject_url)s') % {
'http_break' : '<br />',
'subject_url' : origin1}
# creation author
footer += Html("p", msg, id='createdate')
@ -1893,6 +1903,7 @@ class BasePage:
('download', _("Download"), self.report.inc_download),
("addressbook", _("Address Book"), self.report.inc_addressbook),
('contact', _("Contact"), self.report.use_contact),
("stats", _("Statistics"), True),
(self.target_cal_uri, _("Web Calendar"), self.usecal)
]
@ -1971,6 +1982,13 @@ class BasePage:
index += 1
cols += 1
if rows == num_rows - 1:
prv = Html('<a onclick="history.go(-1);">%s</a>' %
_("Previous"))
nxt = Html('<a onclick="history.go(+1);">%s</a>' %
_("Next"))
unordered.extend(Html("li", prv, inline=True))
unordered.extend(Html("li", nxt, inline=True))
container += unordered
navigation += container
return navigation
@ -8013,6 +8031,180 @@ class AddressBookPage(BasePage):
# and close the file
self.xhtml_writer(addressbookpage, output_file, sio, 0)
class StatisticsPage(BasePage):
"""
Create one page for statistics
"""
def __init__(self, report, title, step):
"""
@param: report -- The instance of the main report class
for this report
@param: title -- Is the title of the web page
"""
import posixpath
BasePage.__init__(self, report, title)
self.bibli = Bibliography()
self.uplink = False
self.report = report
# set the file name and open file
output_file, sio = self.report.create_file("stats")
addressbookpage, head, body = self.write_header(_("Statistics"))
(males,
females,
unknown) = self.get_gender(report.database.iter_person_handles())
mobjects = report.database.get_number_of_media()
npersons = report.database.get_number_of_people()
nfamilies = report.database.get_number_of_families()
nsurnames = len(set(report.database.surname_list))
notfound = []
total_media = 0
mbytes = "0"
bytes = 0
for media in report.database.iter_media():
total_media += 1
fullname = media_path_full(report.database, media.get_path())
try:
bytes += posixpath.getsize(fullname)
length = len(str(bytes))
if bytes <= 999999:
mbytes = _("less than 1")
else:
mbytes = str(bytes)[:(length-6)]
except OSError:
notfound.append(media.get_path())
with Html("div", class_="content", id='EventDetail') as section:
section += Html("h3", _("Database overview"), inline=True)
body += section
with Html("div", class_="content", id='subsection narrative') as sec11:
sec11 += Html("h4", _("Individuals"), inline=True)
body += sec11
with Html("div", class_="content", id='subsection narrative') as sec1:
sec1 += Html("br", _("Number of individuals") + ":" +
"%d" % npersons, inline=True)
sec1 += Html("br", _("Males") + ":" +
"%d" % males, inline=True)
sec1 += Html("br", _("Females") + ":" +
"%d" % females, inline=True)
sec1 += Html("br", _("Individuals with unknown gender") + ":" +
"%d" % unknown, inline=True)
body += sec1
with Html("div", class_="content", id='subsection narrative') as sec2:
sec2 += Html("h4", _("Family Information"), inline=True)
sec2 += Html("br", _("Number of families") + ":" +
"%d" % nfamilies, inline=True)
sec2 += Html("br", _("Unique surnames") + ":" +
"%d" % nsurnames, inline=True)
body += sec2
with Html("div", class_="content", id='subsection narrative') as sec3:
sec3 += Html("h4", _("Media Objects"), inline=True)
sec3 += Html("br", _("Total number of media object references") +
":" + "%d" % total_media, inline=True)
sec3 += Html("br", _("Number of unique media objects") +
":" + "%d" % mobjects, inline=True)
sec3 += Html("br", _("Total size of media objects") +
":" + "%8s %s" % (mbytes, _("Megabyte|MB")),
inline=True)
sec3 += Html("br", _("Missing Media Objects") +
":" + "%d" % len(notfound), inline=True)
body += sec3
with Html("div", class_="content", id='subsection narrative') as sec4:
sec4 += Html("h4", _("Miscellaneous"), inline=True)
sec4 += Html("br", _("Number of events") +
":" + "%d" % report.database.get_number_of_events(),
inline=True)
sec4 += Html("br", _("Number of places") +
":" + "%d" % report.database.get_number_of_places(),
inline=True)
nsources = report.database.get_number_of_sources()
sec4 += Html("br", _("Number of sources") +
":" + "%d" % nsources,
inline=True)
ncitations = report.database.get_number_of_citations()
sec4 += Html("br", _("Number of citations") +
":" + "%d" % ncitations,
inline=True)
nrepo = report.database.get_number_of_repositories()
sec4 += Html("br", _("Number of repositories") +
":" + "%d" % nrepo,
inline=True)
body += sec4
(males,
females,
unknown) = self.get_gender(self.report.bkref_dict[Person].keys())
center_person = self.report.database.get_person_from_gramps_id(
self.report.options['pid'])
origin = " :<br/>" + report.filter.get_name()
with Html("div", class_="content", id='EventDetail') as section:
section += Html("h3", _("Narrative web content report for") +
origin,
inline=True)
body += section
with Html("div", class_="content", id='subsection narrative') as sec5:
sec5 += Html("h4", _("Individuals"), inline=True)
sec5 += Html("br", _("Number of individuals") + ":" +
"%d" % len(self.report.bkref_dict[Person]),
inline=True)
sec5 += Html("br", _("Males") + ":" +
"%d" % males, inline=True)
sec5 += Html("br", _("Females") + ":" +
"%d" % females, inline=True)
sec5 += Html("br", _("Individuals with unknown gender") + ":" +
"%d" % unknown, inline=True)
body += sec5
with Html("div", class_="content", id='subsection narrative') as sec6:
sec6 += Html("h4", _("Family Information"), inline=True)
sec6 += Html("br", _("Number of families") + ":" +
"%d" % len(self.report.bkref_dict[Family]),
inline=True)
body += sec6
with Html("div", class_="content", id='subsection narrative') as sec7:
sec7 += Html("h4", _("Miscellaneous"), inline=True)
sec7 += Html("br", _("Number of events") +
":" + "%d" % len(self.report.bkref_dict[Event]),
inline=True)
sec7 += Html("br", _("Number of places") +
":" + "%d" % len(self.report.bkref_dict[Place]),
inline=True)
sec7 += Html("br", _("Number of sources") +
":" + "%d" % len(self.report.bkref_dict[Source]),
inline=True)
sec7 += Html("br", _("Number of citations") +
":" + "%d" % len(self.report.bkref_dict[Citation]),
inline=True)
sec7 += Html("br", _("Number of repositories") +
":" + "%d" % len(self.report.bkref_dict[Repository]),
inline=True)
body += sec7
# add fullclear for proper styling
# and footer section to page
footer = self.write_footer(None)
body += (FULLCLEAR, footer)
# send page out for processing
# and close the file
self.xhtml_writer(addressbookpage, output_file, sio, 0)
def get_gender(self, person_list):
males = 0
females = 0
unknown = 0
for person_handle in person_list:
person = self.report.database.get_person_from_handle(person_handle)
gender = person.get_gender()
if gender == Person.MALE:
males += 1
elif gender == Person.FEMALE:
females += 1
else:
unknown += 1
return (males, females, unknown)
class NavWebReport(Report):
"""
Create WebReport object that produces the report.
@ -8314,6 +8506,9 @@ class NavWebReport(Report):
# build classes SourceListPage and SourcePage
self.tab["Source"].display_pages(self.title)
# build classes StatisticsPage
self.statistics_preview_page(self.title)
# copy all of the neccessary files
self.copy_narrated_files()
@ -8971,6 +9166,15 @@ class NavWebReport(Report):
len(self.obj_dict[Media])) as step:
ThumbnailPreviewPage(self, self.title, step)
def statistics_preview_page(self, title):
"""
creates the statistics preview page
"""
with self.user.progress(_("Narrated Web Site Report"),
_("Creating statistics page..."),
len(self.obj_dict[Media])) as step:
StatisticsPage(self, title, step)
def addressbook_pages(self, ind_list):
"""
Create a webpage with a list of address availability for each person

3901
po/cs.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

18179
po/pt_BR.po

File diff suppressed because it is too large Load Diff

View File

@ -142,7 +142,7 @@ class buildbase(GObject.GObject):
outfile = file
if file == 'NEWS':
#Jump through hoops tomake sure the end of line charactors are windows format (wont work on linux!!)
outfile = 'NEWS.TXT' #Lets add .TXT suffix to filename so installer knows to call notepad
outfile = 'NEWS.TXT' #Lets add .TXT suffix to filename so installer knows to call notepad
fnews = open(os.path.join(source_path,file), 'r')
newslines = fnews.readlines()
newsout = open(os.path.join(self.build_src,outfile), 'w')
@ -162,7 +162,7 @@ class buildbase(GObject.GObject):
# need to ensure __file__ has full path, under linux it does not.
thisfilepath = os.path.abspath(__file__)
pth = os.path.relpath(os.path.dirname( thisfilepath ), os.getcwd())
pth2nsis_script = os.path.join(pth, 'gramps2.nsi')
pth2nsis_script = os.path.join(pth, 'gramps2.nsi')
#should tests be more along lines of os.name which returns 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
if sys.platform == 'win32':
@ -241,9 +241,9 @@ class buildbase(GObject.GObject):
# log.error( "msgfmt not found - unable to generate mo files")
# return
log.info( "Generating mo files" )
global po_errs, po_oks
global po_errs, po_oks
po_total = len(po_files)
po_count = 0
po_count = 0
for po_file in po_files:
po_count = po_count + 1
#This will be interesting
@ -317,7 +317,7 @@ class buildbase(GObject.GObject):
log.error( e )
def getNSISVersionNumber(self):
#Check version of NSIS, to ensure NSIS is compatible with script features
#Check version of NSIS, to ensure NSIS is compatible with script features
# >"c:\Program Files\NSIS\makensis.exe" /version
# v2.42
cmd = '"%s" -VERSION' % (MAKENSIS_exe)
@ -338,7 +338,7 @@ class buildbase(GObject.GObject):
ver = output[1:].split('.')
major = int(ver[0])
try:
minor = int(ver[1])
minor = int(ver[1])
except ValueError as e:
m = ver[1]
minor = int(m[:2])
@ -511,7 +511,7 @@ def buildGRAMPS( base, out_dir, bTarball):
bo.exportSVN(os.path.join(base, 'src'), os.path.join(bo.build_root, 'src') )
bo.exportSVN(os.path.join(base, 'po'), os.path.join(bo.build_root, 'po') )
bo.exportSVN(os.path.join(base, 'example'), os.path.join(bo.build_root, 'examples') )
bo.generateConstPy( )
bo.generateConstPy( )
bo.copyExtraFilesToBuildDir(base)
if bPatchBuild:
@ -545,9 +545,9 @@ Options:
-mDIR, --msgdir=DIR Directory to msgfmt.exe
-pDIR, --patch=DIR Specify a directory to patch files into the build.
only valid for a tarball build.
This directory will allow you to patch the release after expanding
This directory will allow you to patch the release after expanding
from tarball and before creating installer.
(n.b. each file to be replaced needs to be specified with full path
(n.b. each file to be replaced needs to be specified with full path
to exactly mimic the paths in the expanded tarball)
'''
# TODO: nsis_dir option - a path to nsismake (for occasions script cannot work it out)
@ -636,4 +636,4 @@ Options:
#==========================
sys.exit(buildGRAMPS(repository_path,out_dir, bTarball))
GObject.type_register(buildbase)
GObject.type_register(buildbase)

View File

@ -37,14 +37,14 @@ testdlls = ['libgdk-win32-2.0-0.dll', 'libglib-2.0-0.dll', 'libgobject-2.0-0.dll
explain_exposed = ''' ***********************************************************
* It seems that other installations are exposing GTK DLL's
* to the operating system as they are in the environment
* path variable BEFORE the runtime directory.
* path variable BEFORE the runtime directory.
* You should reorder the path variable to put your GTK
* runtime path before these other installations on the path'''
* runtime path before these other installations on the path'''
explain_safe = ''' ***************************************************************
* While there are other installations of GTK DLL's on the path,
* it should be safe as they are on the path AFTER the runtime
* directory. '''
* directory. '''
def RunExeCommand( app, args ):
cmd = app + ' ' + args
@ -72,8 +72,8 @@ def CheckGtkInReg():
except WindowsError as e:
log.info( '\n GTK registry key not found in registry' )
log.info( ''' ********************************************************************
* This might not be an error, but means I don't know the directory to
* your preferred GTK installation.
* This might not be an error, but means I don't know the directory to
* your preferred GTK installation.
* - try passing in your GTK installation path.\n''' )
log.info( '-' * 60 )
log.info( usage )
@ -92,7 +92,7 @@ def WorkOutShortDosPath():
log.info( ' if you want this function to work' )
def FindLibsWithCtypes():
# use ctypes to check where windows finds it's DLL's
# use ctypes to check where windows finds it's DLL's
log.info( '\n==== Use ctypes to find dlls ====' )
other_paths = []
for dll in testdlls:
@ -193,7 +193,7 @@ def CheckWithDependencyWalker():
log.info( ' get dependency walker from http://www.dependencywalker.com/' )
log.info( ' and unzip into this directory for it to work.' )
def CheckPathForOtherGtkInstalls():
def CheckPathForOtherGtkInstalls():
log.info( '\n====Checking environment path for other gtk installations====' )
ePath = os.environ['path']
dirs = ePath.split(';')
@ -281,7 +281,7 @@ def Import_pyGtkIntoPython():
#test the gobject version
try:
import gobject
PrintVersionResult(' gobject', MIN_GOBJECT_VER, GObject.pygobject_version, UNTESTED_GOBJECT_VER)
PrintVersionResult(' gobject', MIN_GOBJECT_VER, GObject.pygobject_version, UNTESTED_GOBJECT_VER)
except ImportError:
PrintFailedImport(' gobject', MIN_GOBJECT_VER, NOT_FOUND_STR)
@ -290,7 +290,7 @@ def Import_pyGtkIntoPython():
#test the cairo version
try:
import cairo
PrintVersionResult(' cairo ', MIN_CAIRO_VER, cairo.version_info, UNTESTED_CAIRO_VER )
PrintVersionResult(' cairo ', MIN_CAIRO_VER, cairo.version_info, UNTESTED_CAIRO_VER )
except ImportError:
PrintFailedImport(' cairo ', MIN_CAIRO_VER, NOT_FOUND_STR)

View File

@ -52,12 +52,12 @@ langLookup = {
'eo' : 'Esperanto',
'es' : 'Spanish',
'fi' : 'Finnish',
'fr' : 'French',
'fr' : 'French',
'ga' : 'Irish',
'he' : 'Hebrew',
'hr' : 'Croatian',
'hu' : 'Hungarian',
'it' : 'Italian',
'it' : 'Italian',
'ja' : 'Japanese',
'lt' : 'Lithuanian',
'mk' : 'Macedonian',
@ -73,8 +73,8 @@ langLookup = {
'sq' : 'Albanian',
'sr' : 'Serbian',
'sv' : 'Swedish',
'tr' : 'Turkish',
'uk' : 'Ukrainian',
'tr' : 'Turkish',
'uk' : 'Ukrainian',
'vi' : 'Vietnamese',
'zh_CN' : 'Chinese (PRC)',
}
@ -118,17 +118,17 @@ def GetLanguageFromLocale():
lang = locale.getlocale()[0]
if not lang:
# if lang is empty/None
lang = locale.getdefaultlocale()[0]
lang = locale.getdefaultlocale()[0]
return lang
def writeLauncher(language, langcode, runtimepath, grampspath):
lines = []
lines.append('''@rem Setting the working language
@rem ============================
@rem GRAMPS looks during the start-up-phase for an environment variable (called LANG)
@rem GRAMPS looks during the start-up-phase for an environment variable (called LANG)
@rem to switch to a special language. It's better to use a ".CMD" or ".BAT" file to
@rem control this environment variable instead a permanent setting in the windows registry,
@rem to have the possibility to go back to the GRAMPS standard language (English) in the
@rem to have the possibility to go back to the GRAMPS standard language (English) in the
@rem case you want to report about a problem or a bug.
''')
lines.append('\n@rem Set GRAMPS environment settings to %s \n' % language)
@ -137,9 +137,9 @@ def writeLauncher(language, langcode, runtimepath, grampspath):
lines.append('''\n\n@rem Setting the configuration path
@rem ==============================
@rem During the boot process of GRAMPS there is a check for an environment variable
@rem called GRAMPSHOME. Without this environment variable GRAMPS uses the default
@rem called GRAMPSHOME. Without this environment variable GRAMPS uses the default
@rem windows path as the location to save all configuration files:
@rem <system drive>\<userpath>\<application data>\gramps
@rem <system drive>\<userpath>\<application data>\gramps
@rem If required, uncomment GRAMPSHOME line and edit to suit your use.
''')
lines.append('\n@rem set the path for GRAMPS configuration files')
@ -154,7 +154,7 @@ def writeLauncher(language, langcode, runtimepath, grampspath):
path = '\npath="%s";%%PATH%%' % runtimepath
else:
lines.append('\n@rem Uncommnet following line, and edit path to your GTK runtime')
path = "\n@rem path=PATH_TO_YOUR_GTK_RUNTIME;%%PATH%%\n"
path = "\n@rem path=PATH_TO_YOUR_GTK_RUNTIME;%%PATH%%\n"
lines.append(path)
lines.append('''\n\n@rem Start GRAMPS application
@rem =========================

View File

@ -26,7 +26,7 @@ py_str = 'found %d.%d.%d' % sys.version_info[:3]
try:
import gtk
try:
gtkver_str = 'found %d.%d.%d' % Gtk.gtk_version
gtkver_str = 'found %d.%d.%d' % Gtk.gtk_version
except : # any failure to 'get' the version
gtkver_str = 'unknown version'
try:
@ -52,7 +52,7 @@ except ImportError:
try:
import cairo
try:
cairover_str = 'found %d.%d.%d' % cairo.version_info
cairover_str = 'found %d.%d.%d' % cairo.version_info
except :# any failure to 'get' the version
cairover_str = 'unknown version'
@ -63,4 +63,4 @@ print('python:%s;'%py_str)
print('gtk++:%s;'%gtkver_str)
print('pygtk:%s;'%pygtkver_str)
print('gobject:%s;'%gobjectver_str)
print('cairo:%s;'%cairover_str)
print('cairo:%s;'%cairover_str)

View File

@ -32,7 +32,7 @@ testdlls = ['libgdk-win32-2.0-0.dll', 'libglib-2.0-0.dll', 'libgobject-2.0-0.dll
explain_exposed = ''' ***********************************************************
* It seems that other installations are exposing GTK DLL's
* to the operating system as they are in the environment
* path variable BEFORE the runtime directory.
* path variable BEFORE the runtime directory.
* You should reorder the path variable to put your GTK
* runtime path before these other installations on the path'''
@ -67,7 +67,7 @@ def CheckGtkInReg():
except WindowsError as e:
print('\n GTK registry key not found in registry')
print(''' ********************************************************************
* This might not be an error, but means I don't know the directory to
* This might not be an error, but means I don't know the directory to
* your preferred GTK installation.
* - try passing in your GTK installation path.\n''')
print('-' * 60)
@ -121,7 +121,7 @@ def ScanDependencyFileForErrors(fname):
for line in lines:
if line.startswith(" Module"): # work out were paths end
pthend_idx = line.find("File Time Stamp")
acceptablePaths = [ dllPathShort.lower(),
acceptablePaths = [ dllPathShort.lower(),
dllPathInRegistry.lower(),
os.path.join(sysroot, 'system32').lower()
]
@ -249,7 +249,7 @@ def PrintVersionResult(appl, minVersion, actualVersion, untestedVersion):
print(appl,)
print('version %d.%d.%d or above.....\t' % minVersion ,)
print('found %d.%d.%d' % actualVersion ,)
if minVersion <= actualVersion < untestedVersion:
if minVersion <= actualVersion < untestedVersion:
print('...OK')
elif actualVersion >= untestedVersion:
print('...UNTESTED VERSION')
@ -287,7 +287,7 @@ def Import_pyGtkIntoPython():
#test the cairo version
try:
import cairo
PrintVersionResult(' cairo ', MIN_CAIRO_VER, cairo.version_info, UNTESTED_CAIRO_VER )
PrintVersionResult(' cairo ', MIN_CAIRO_VER, cairo.version_info, UNTESTED_CAIRO_VER )
except ImportError:
PrintFailedImport(' cairo ', MIN_CAIRO_VER, NOT_FOUND_STR)