Compare commits

...

45 Commits

Author SHA1 Message Date
romjerome fe0f125ad6 test if 'lmodern' exists 2019-12-14 19:10:51 +01:00
romjerome e8b63987ac pylint ... 2019-12-14 19:04:48 +01:00
romjerome 461ee4fe5c pylint 2019-12-14 18:55:39 +01:00
romjerome d571516212 better variable name for lang 2019-12-09 20:53:24 +01:00
romjerome 9208b8a3a8 polish, use LATIN group 2019-12-07 09:06:06 +01:00
romjerome 9e013f6781 do not need to load 'lmodern' every time 2019-12-07 09:00:54 +01:00
romjerome c460506e4f Need 'lmodern' for some non-ASCII char 2019-12-07 08:56:12 +01:00
romjerome 3fcb9411dc typo 2019-12-07 08:41:54 +01:00
romjerome f7a50a0e74 limit locale set to supported lang (genealogytree) 2019-12-07 08:39:42 +01:00
romjerome 6709d37526 fix issues around localization
* specific non-ASCII characters related to our locale are not displayed on PDF
* date cannot be parsed (one calendar format and in english)
genealogytree macro needs a lang set in english
2019-12-06 22:49:37 +01:00
Paulo Henrique Moraes fc9e5c2a4a Updated translation. (#952) 2019-11-27 11:51:50 -06:00
prculley e3eedb2219 Merge branch 'gramps51' 2019-11-08 11:46:40 -06:00
Nick Hall f5861169fe Merge pull request #908 from SNoiraud:FR11336
New narrative web and web calendar features:

* Allow urls in the user's css files
* Allow alternate stylesheets in pages for narrative web and webcal
* Webcal: incorrect results when divorce event.
* Some pylint improvements

Resolves #11336.
2019-10-05 18:10:45 +01:00
SNoiraud 4e2f98da02 Better score for pylint 2019-10-05 18:05:21 +01:00
SNoiraud 95a0216287 Duplicate marriage 2019-10-05 18:05:21 +01:00
SNoiraud 03fb2ff1c2 Incorrect results when divorce event 2019-10-05 18:05:15 +01:00
SNoiraud 17141a0536 Add alternate stylesheets 2019-10-05 18:03:03 +01:00
SNoiraud 528852b9b3 Allow alternate stylesheets in pages
Useful when you create a site web, you don't need to create a new
web when you are testing the stylesheets. The final user can change
the stylesheet for the current page.

i.e. on Firefox: View -> Page style -> The stylesheet
2019-10-05 18:02:51 +01:00
SNoiraud 0de286e7a8 Allow urls for images in user css files 2019-10-05 17:59:17 +01:00
SNoiraud 7979bf79fd Better code quality for within area rule 2019-10-05 17:28:21 +01:00
Nick Hall 7100c51a31 Merge pull request #903 from prculley:deprecations 2019-10-05 17:22:19 +01:00
prculley 57f7502105 Fix deprecation of Gtk positional arguments 2019-10-05 17:17:54 +01:00
prculley 0f925a86f5 Fix Gtk deprecation Menu.set_title 2019-10-05 17:17:54 +01:00
prculley 17f4d93363 Fix Gtk deprecatioon ScrolledWindow.add_with_viewport 2019-10-05 17:17:54 +01:00
prculley cea48b618f Fix GObject.PARAM_READWRITE deprecation 2019-10-05 17:17:54 +01:00
prculley 290d6f7287 Fix deprecation GObject.GError -> GLib.GError 2019-10-05 17:17:54 +01:00
prculley 4d0e86a2e8 Fix Gtk deprecation Widget.reparent 2019-10-05 17:17:54 +01:00
prculley 831c7f9c66 Fix Gtk deprecation Widget.set_padding 2019-10-05 17:17:54 +01:00
prculley 702e51dd47 Fix deprecation on Gtk.Widget.override_font and modify_font 2019-10-05 17:17:54 +01:00
Jonas Hahnfeld f3555d0168 Add new graph output format to the tree document generator
The "graph" is the data part for genealogytree without the boilerplate
code around it that makes up a full LaTeX file. This format is useful
for people who have their own (more sophisticated) LaTeX file with
custom styles and so on.
The implementation is pretty straight-forward: Just don't output the
LaTeX code.
2019-10-05 17:05:38 +01:00
Matthias Kemmer bedc4b8e74 Add a new person filter rule 'HasAddressText' 2019-10-04 21:07:52 +01:00
Matthias Kemmer 8a8a21f85d Add date format option for 'numeric date with leading zeros' 2019-10-04 19:59:54 +01:00
Nick Hall c7350c53e2 Remove irrelevant comment 2019-10-04 19:54:00 +01:00
Fredrik Lindseth 52e76b506a Add descriptions to decendant tree report styles 2019-10-04 19:18:16 +01:00
Matthias Kemmer ab52d0988e Remove tag from selected rows 2019-10-03 21:28:33 +01:00
Matthias Kemmer 5935a315b2 Add 'HasAttribute' filter rule to repositories, sources and citations
Fixes #9845
2019-10-03 21:05:14 +01:00
prculley 1eaa609058 Get BetaWarning correct for master 2019-09-16 11:13:08 -05:00
prculley 5f0c2c1c54 Set Beta warning to True 2019-09-16 11:02:03 -05:00
prculley 6d39920e6f Merge branch 'gramps51' 2019-09-16 10:54:55 -05:00
prculley 4859c14aaa Fix typo in merge 2019-08-12 16:58:55 -05:00
prculley f4a8f21032 Merge from gramps51 2019-08-09 09:06:42 -05:00
prculley e894c4478f Some pylint cleanups 2019-08-09 08:55:05 -05:00
romjerome 56afb5bca9 Add missing 'get_number_of_citations' method (#859)
* Add missing 'get_number_of_citations' method

* update db test for bsddb

* fix trailing whitespace

* typo
2019-08-07 13:47:09 -05:00
SNoiraud 9da8f705f6 Narrative web: Add popup to manage markers
If you click on a marker in the family map page, you get a popup.
In this popup associated with a place, if you have several events,
for each event you see the person and the event type.
If you click on the person, you go to the related page for this person.
If you click on the event type, you go to the related page for this event.

Fixes #11150
2019-07-07 19:25:42 +02:00
SNoiraud ce4cd33139 Narrative web: Add Stamen map
Fixes #05984
2019-07-07 19:24:44 +02:00
86 changed files with 3237 additions and 2690 deletions
+45
View File
@@ -66,3 +66,48 @@ div#FamilyMapDetail div#references table.infolist {
div#FamilyMapDetail div#references table.infolist tbody tr td.ColumnPlace {
width: 40%;
}
/* Subsection: popup
------------------------------------------------------ */
.ol-popup {
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
padding: 15px;
border-radius: 10px;
border: 2px solid #111111;
bottom: 12px;
left: -50px;
min-width: 450px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
+14 -1
View File
@@ -290,7 +290,8 @@ class DateDisplayDE(DateDisplay):
formats = (
"JJJJ-MM-DD (ISO)", "Numerisch", "Monat Tag Jahr",
"MONAT Tag Jahr", "Tag. Monat Jahr", "Tag. MONAT Jahr"
"MONAT Tag Jahr", "Tag. Monat Jahr", "Tag. MONAT Jahr",
"Numerisch mit führenden Nullen"
)
# this definition must agree with its "_display_gregorian" method
@@ -343,6 +344,18 @@ class DateDisplayDE(DateDisplay):
else:
value = "%d. %s %s" % (date_val[0],
self.long_months[date_val[1]], year)
elif self.format == 6:
# day.month_number.year with leading zeros
if date_val[3]:
return self.display_iso(date_val)
else:
if date_val[0] == date_val[1] == 0:
value = str(date_val[2])
else:
value = self.dhformat.replace('%m', str(date_val[1])
.zfill(2))
value = value.replace('%d', str(date_val[0]).zfill(2))
value = value.replace('%Y', str(date_val[2]))
else:
# day. month_abbreviation year
if date_val[0] == 0:
+9 -1
View File
@@ -32,7 +32,7 @@ database to fetch data from). Thus, dbstate.db cannot be left as 'None' because
None has no 'is_open' attribute. Therefore this database class is provided so
that it can be instantiated for dbstate.db.
FIXME: Ideally, only is_open() needs to be implemented here, bacause that is the
FIXME: Ideally, only is_open() needs to be implemented here, because that is the
only method that should really be called, but the Gramps code is not perfect,
and many other methods are called. Calls of other methods could be considered
bugs, so when these are fixed, this class could be reduced.
@@ -757,6 +757,14 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
LOG.warning("database is closed")
return 0
def get_number_of_citations(self):
"""
Return the number of citations currently in the database.
"""
if not self.db_is_open:
LOG.warning("database is closed")
return 0
def get_number_of_tags(self):
"""
Return the number of tags currently in the database.
@@ -28,6 +28,7 @@ from ._hascitation import HasCitation
from ._allcitations import AllCitations
from ._changedsince import ChangedSince
from ._citationprivate import CitationPrivate
from ._hasattribute import HasAttribute
from ._hasgallery import HasGallery
from ._hasidof import HasIdOf
from ._hasnote import HasNote
@@ -50,6 +51,7 @@ editor_rule_list = [
AllCitations,
ChangedSince,
CitationPrivate,
HasAttribute,
HasGallery,
HasIdOf,
HasNote,
@@ -0,0 +1,49 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2019 Matthias Kemmer
#
# 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.
#
# -------------------------------------------------------------------------
#
# Standard Python modules
#
# -------------------------------------------------------------------------
from ....const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
# -------------------------------------------------------------------------
#
# Gramps modules
#
# -------------------------------------------------------------------------
from .._hasattributebase import HasAttributeBase
# -------------------------------------------------------------------------
#
# HasAttribute
#
# -------------------------------------------------------------------------
class HasAttribute(HasAttributeBase):
"""Rule that checks for a citation with a particular attribute"""
labels = [_('Citation attribute:'), _('Value:')]
name = _('Citations with the attribute <attribute>')
description = _("Matches citations with the attribute "
"of a particular value")
@@ -29,6 +29,7 @@ from ._disconnected import Disconnected
from ._everyone import Everyone
from ._familywithincompleteevent import FamilyWithIncompleteEvent
from ._hasaddress import HasAddress
from ._hasaddresstext import HasAddressText
from ._hasalternatename import HasAlternateName
from ._hasassociation import HasAssociation
from ._hasattribute import HasAttribute
@@ -125,6 +126,7 @@ editor_rule_list = [
IsBookmarked,
HasAlternateName,
HasAddress,
HasAddressText,
HasAssociation,
HasIdOf,
HasLDS,
@@ -0,0 +1,54 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Brian G. Matherly
# Copyright (C) 2008 Jerome Rapinat
# Copyright (C) 2008 Benny Malengier
#
# 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
#
# -------------------------------------------------------------------------
from .. import Rule
from ....const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
# -------------------------------------------------------------------------
#
# HasAddressText
#
# -------------------------------------------------------------------------
class HasAddressText(Rule):
"""Rule that checks for text in personal addresses"""
labels = [_('Text:')]
name = _('People with an address containing <text>')
description = _("Matches people with a personal address containing "
"the given text")
category = _('General filters')
allow_regex = True
def apply(self, db, person):
for address in person.get_address_list():
for string in address.get_text_data_list():
if self.match_substring(0, string):
return True
return False
@@ -37,10 +37,10 @@ import re
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.errors import FilterError
from ....const import GRAMPS_LOCALE as glocale
from .. import Rule
from ....utils.place import conv_lat_lon
from gramps.gen.errors import FilterError
_ = glocale.translation.sgettext
@@ -81,13 +81,13 @@ class WithinArea(Rule):
"D.D8")
if self.latitude is None or self.longitude is None:
raise FilterError(_("Cannot use the filter 'within area'"),
_("The place you selected contains bad coordinates. "
"Please, run the tool 'clean input data'"))
return
_("The place you selected contains bad"
" coordinates. Please, run the tool "
"'clean input data'"))
val = self.list[1]
if isinstance(val, str):
val = re.sub(r"\D", "", val) # suppress all alpha characters
val = re.sub(r"\D", "", val) # suppress all alpha characters
value = int(val)
unit = int(self.list[2])
# earth perimeter in kilometers for latitude
@@ -25,6 +25,7 @@ Package providing filter rules for Gramps.
from ._allrepos import AllRepos
from ._hasidof import HasIdOf
from ._regexpidof import RegExpIdOf
from ._hasattribute import HasAttribute
from ._hasnoteregexp import HasNoteRegexp
from ._hasnotematchingsubstringof import HasNoteMatchingSubstringOf
from ._hasreferencecountof import HasReferenceCountOf
@@ -37,6 +38,7 @@ from ._hastag import HasTag
editor_rule_list = [
AllRepos,
HasAttribute,
HasIdOf,
RegExpIdOf,
HasNoteRegexp,
@@ -0,0 +1,49 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2019 Matthias Kemmer
#
# 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.
#
# -------------------------------------------------------------------------
#
# Standard Python modules
#
# -------------------------------------------------------------------------
from ....const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
# -------------------------------------------------------------------------
#
# Gramps modules
#
# -------------------------------------------------------------------------
from .._hasattributebase import HasAttributeBase
# -------------------------------------------------------------------------
#
# HasAttribute
#
# -------------------------------------------------------------------------
class HasAttribute(HasAttributeBase):
"""Rule that checks for a repository with a particular attribute"""
labels = [_('Repository attribute:'), _('Value:')]
name = _('Repositories with the attribute <attribute>')
description = _("Matches repositories with the attribute "
"of a particular value")
@@ -27,6 +27,7 @@ Package providing filter rules for Gramps.
from .._hassourcebase import HasSourceBase as HasSource
from ._allsources import AllSources
from ._hasattribute import HasAttribute
from ._hasgallery import HasGallery
from ._hasidof import HasIdOf
from ._regexpidof import RegExpIdOf
@@ -45,6 +46,7 @@ from ._hastag import HasTag
editor_rule_list = [
AllSources,
HasAttribute,
HasGallery,
HasIdOf,
RegExpIdOf,
@@ -0,0 +1,49 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2019 Matthias Kemmer
#
# 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.
#
# -------------------------------------------------------------------------
#
# Standard Python modules
#
# -------------------------------------------------------------------------
from ....const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
# -------------------------------------------------------------------------
#
# Gramps modules
#
# -------------------------------------------------------------------------
from .._hasattributebase import HasAttributeBase
# -------------------------------------------------------------------------
#
# HasAttribute
#
# -------------------------------------------------------------------------
class HasAttribute(HasAttributeBase):
"""Rule that checks for a source with a particular attribute"""
labels = [_('Source attribute:'), _('Value:')]
name = _('Sources with the attribute <attribute>')
description = _("Matches sources with the attribute "
"of a particular value")
+60
View File
@@ -46,8 +46,14 @@ from ..menu import NumberOption, TextOption, EnumeratedListOption
from ...constfunc import win
from ...config import config
from ...const import GRAMPS_LOCALE as glocale
from ...utils.grampslocale import GrampsLocale
_ = glocale.translation.gettext
LOCALE = GrampsLocale(lang='en')
LATIN = ['french', 'italian', 'spanish']
LANG_SUPPORT = ['danish', 'dutch', 'german', 'swedish'] + LATIN
#-------------------------------------------------------------------------
#
# set up logging
@@ -339,6 +345,14 @@ class TreeDocBase(BaseDoc, TreeDoc):
self.write(0, '\\usepackage[%s,%s]{geometry}\n' % (paper, margin))
self.write(0, '\\usepackage[all]{genealogytree}\n')
self.write(0, '\\usepackage{color}\n')
trans = glocale.language[0][:2]
lang = LOCALE._get_language_string(trans).lower()
if lang in LANG_SUPPORT:
self.write(0, '\\gtrset{language=%s}\n' % lang)
if lang in LATIN:
self.write(0, '\\IfFileExists{lmodern.sty}{\n')
self.write(0, ' \\usepackage{lmodern}\n')
self.write(0, '}{}\n')
self.write(0, '\\begin{document}\n')
if self.nodecolor == 'preferences':
@@ -586,6 +600,47 @@ class TreeDocBase(BaseDoc, TreeDoc):
self.write_end()
#------------------------------------------------------------------------------
#
# TreeGraphDoc
#
#------------------------------------------------------------------------------
class TreeGraphDoc(TreeDocBase):
"""
TreeGraphDoc implementation that generates a .graph file.
"""
def write_start(self):
"""
Write the start of the document - nothing for a graph file.
"""
pass
def start_tree(self, option_list):
"""
Write the start of a tree - nothing for a graph file.
"""
pass
def end_tree(self):
"""
Write the end of a tree - nothing for a graph file.
"""
pass
def write_end(self):
"""
Write the end of the document - nothing for a graph file.
"""
pass
def close(self):
""" Implements TreeDocBase.close() """
TreeDocBase.close(self)
with open(self._filename, 'w', encoding='utf-8') as texfile:
texfile.write(self._tex.getvalue())
#------------------------------------------------------------------------------
#
# TreeTexDoc
@@ -653,6 +708,11 @@ if _LATEX_FOUND:
'mime' : "application/pdf",
'class': TreePdfDoc}]
FORMATS += [{'type' : "graph",
'ext' : "graph",
'descr': _("Graph File for genealogytree"),
'class': TreeGraphDoc}]
FORMATS += [{'type' : "tex",
'ext' : "tex",
'descr': _("LaTeX File"),
+2 -2
View File
@@ -161,12 +161,12 @@ def image_size(source):
:returns: a tuple consisting of the width and height
"""
from gi.repository import GdkPixbuf
from gi.repository import GObject
from gi.repository import GLib
try:
img = GdkPixbuf.Pixbuf.new_from_file(source)
width = img.get_width()
height = img.get_height()
except GObject.GError:
except GLib.GError:
width = 0
height = 0
return (width, height)
+4 -4
View File
@@ -36,7 +36,7 @@ from hashlib import md5
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import GdkPixbuf
try:
@@ -98,7 +98,7 @@ def __get_gconf_string(key):
"""
try:
val = CLIENT.get_string(key)
except GObject.GError:
except GLib.GError:
val = None
return str(val)
@@ -119,7 +119,7 @@ def __get_gconf_bool(key):
"""
try:
val = CLIENT.get_bool(key)
except GObject.GError:
except GLib.GError:
val = None
return val
@@ -318,7 +318,7 @@ def get_thumbnail_image(src_file, mtype=None, rectangle=None, size=SIZE_NORMAL):
try:
filename = get_thumbnail_path(src_file, mtype, rectangle, size)
return GdkPixbuf.Pixbuf.new_from_file(filename)
except (GObject.GError, OSError):
except (GLib.GError, OSError):
if mtype:
return find_mime_type_pixbuf(mtype)
else:
+12 -21
View File
@@ -690,7 +690,7 @@ class GrampsPreferences(ConfigureDialog):
hbox.pack_start(lwidget, False, False, 0)
hbox.pack_start(self.color_scheme_box, False, False, 0)
restore_btn = Gtk.Button(_('Restore to defaults'))
restore_btn = Gtk.Button(label=_('Restore to defaults'))
restore_btn.set_tooltip_text(
_('Restore colors for current theme to default.'))
restore_btn.connect('clicked', self.restore_colors)
@@ -1828,12 +1828,10 @@ class GrampsPreferences(ConfigureDialog):
Show dialog to choose media directory.
"""
f = Gtk.FileChooserDialog(title=_("Select media directory"),
parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
transient_for=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER)
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
mpath = media_path(self.dbstate.db)
f.set_current_folder(os.path.dirname(mpath))
@@ -1878,12 +1876,10 @@ class GrampsPreferences(ConfigureDialog):
Show dialog to choose backup directory.
"""
f = Gtk.FileChooserDialog(title=_("Select backup directory"),
parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
transient_for=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER)
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
backup_path = config.get('database.backup-path')
if not backup_path:
backup_path = config.get('database.path')
@@ -2163,11 +2159,9 @@ class GrampsPreferences(ConfigureDialog):
scrollw.set_size_request(600, 100)
text = Gtk.Label()
text.set_line_wrap(True)
font_description = Pango.font_description_from_string(font)
text.modify_font(font_description)
self.activate_change_font()
text.set_halign(Gtk.Align.START)
text.set_text(my_characters)
text.set_markup("<span font='%s'>%s</span>" % (font, my_characters))
scrollw.add(text)
scrollw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.grid.attach(scrollw, 1, 7, 8, 1)
@@ -2180,12 +2174,9 @@ class GrampsPreferences(ConfigureDialog):
my_characters += symbols.get_death_symbol_for_char(death_symbl)
text = Gtk.Label()
text.set_line_wrap(True)
font_description = Pango.font_description_from_string(font)
text.modify_font(font_description)
text.set_halign(Gtk.Align.START)
text.set_markup("<big><big><big><big>" +
my_characters +
"</big></big></big></big>")
text.set_markup("<big><big><big><big><span font='%s'>%s</span>"
"</big></big></big></big>" % (font, my_characters))
self.grid.attach(text, 1, 8, 8, 1)
scrollw.show_all()
text.show_all()
+1 -1
View File
@@ -380,7 +380,7 @@ class GrampsLoginDialog(ManagedWindow):
self.title = _("Login")
ManagedWindow.__init__(self, uistate, [], self.__class__, modal=True)
dialog = Gtk.Dialog(parent=uistate.window)
dialog = Gtk.Dialog(transient_for=uistate.window)
grid = Gtk.Grid()
grid.set_border_width(6)
grid.set_row_spacing(6)
+7 -6
View File
@@ -42,6 +42,7 @@ import pickle
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Pango
from gi.repository.GLib import markup_escape_text
#-------------------------------------------------------------------------
#
@@ -435,7 +436,6 @@ class EditPerson(EditPrimary):
obj.connect('changed', self._changed_name)
self.preview_name = self.top.get_object("full_name")
self.preview_name.override_font(Pango.FontDescription('sans bold 12'))
self.surntab = SurnameTab(self.dbstate, self.uistate, self.track,
self.obj.get_primary_name(),
on_change=self._changed_name)
@@ -550,7 +550,9 @@ class EditPerson(EditPrimary):
Update the window title, and default name in name tab
"""
self.update_title(self.get_menu_title())
self.preview_name.set_text(self.get_preview_name())
self.preview_name.set_markup(
"<span size='x-large' weight='bold'>%s</span>" %
markup_escape_text(self.get_preview_name(), -1))
self.name_list.update_defname()
def name_callback(self):
@@ -638,7 +640,6 @@ class EditPerson(EditPrimary):
"""
self.imgmenu = Gtk.Menu()
menu = self.imgmenu
menu.set_title(_("Media Object"))
obj = self.db.get_media_from_handle(photo.get_reference_handle())
if obj:
add_menuitem(menu, _("View"), photo,
@@ -1086,9 +1087,9 @@ class EditPerson(EditPrimary):
class GenderDialog(Gtk.MessageDialog):
def __init__(self, parent=None):
Gtk.MessageDialog.__init__(self,
parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.QUESTION,
transient_for=parent,
modal=True,
message_type=Gtk.MessageType.QUESTION,
)
self.set_icon(ICON)
self.set_title('')
+1 -1
View File
@@ -101,7 +101,7 @@ class EditTagList(ManagedWindow):
Create a dialog box to select tags.
"""
# pylint: disable-msg=E1101
top = Gtk.Dialog(parent=self.uistate.window)
top = Gtk.Dialog(transient_for=self.uistate.window)
top.vbox.set_spacing(5)
columns = [('', -1, 300),
+1 -1
View File
@@ -618,7 +618,7 @@ class Gramps:
and not gettext.find(GTK_GETTEXT_DOMAIN)):
_display_gtk_gettext_message(parent=self._vm.window)
#_display_welcome_message(parent=self._vm.window)
_display_welcome_message(parent=self._vm.window)
_display_translator_message(parent=self._vm.window)
+21 -14
View File
@@ -284,7 +284,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"information included in the error please remove "
"it."))
label.set_halign(Gtk.Align.START)
label.set_padding(0, 4)
label.set_margin_top(4)
label.set_margin_bottom(4)
label.set_line_wrap(True)
swin = Gtk.ScrolledWindow()
@@ -300,9 +301,9 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
sw_frame = Gtk.Frame()
sw_frame.add(swin)
reset = Gtk.Button("Reset")
reset = Gtk.Button(label="Reset")
reset.connect('clicked', self._reset_error_details)
clear = Gtk.Button("Clear")
clear = Gtk.Button(label="Clear")
clear.connect('clicked', self._clear_error_details)
button_box = Gtk.ButtonBox()
@@ -364,7 +365,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"remove anything that you would rather not have "
"included in the bug report."))
label.set_halign(Gtk.Align.START)
label.set_padding(0, 4)
label.set_margin_top(4)
label.set_margin_bottom(4)
label.set_line_wrap(True)
swin = Gtk.ScrolledWindow()
@@ -380,9 +382,9 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
sw_frame = Gtk.Frame()
sw_frame.add(swin)
reset = Gtk.Button("Reset")
reset = Gtk.Button(label="Reset")
reset.connect('clicked', self._reset_sys_information)
clear = Gtk.Button("Clear")
clear = Gtk.Button(label="Clear")
clear.connect('clicked', self._clear_sys_information)
@@ -441,7 +443,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"can about what you were doing when the error "
"occurred."))
label.set_halign(Gtk.Align.START)
label.set_padding(0, 4)
label.set_margin_top(4)
label.set_margin_bottom(4)
label.set_line_wrap(True)
swin = Gtk.ScrolledWindow()
@@ -456,7 +459,7 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
sw_frame = Gtk.Frame()
sw_frame.add(swin)
clear = Gtk.Button("Clear")
clear = Gtk.Button(label="Clear")
clear.connect('clicked', self._clear_user_information)
button_box = Gtk.ButtonBox()
@@ -514,7 +517,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"that it does not contain anything that you do not "
"want to be sent to the developers."))
label.set_halign(Gtk.Align.START)
label.set_padding(0, 4)
label.set_margin_top(4)
label.set_margin_bottom(4)
label.set_line_wrap(True)
swin = Gtk.ScrolledWindow()
@@ -580,7 +584,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"clipboard and then open a webbrowser to file a bug report at "),
URL_BUGTRACKER))
label.set_halign(Gtk.Align.START)
label.set_padding(0, 4)
label.set_margin_top(4)
label.set_margin_bottom(4)
label.set_line_wrap(True)
label.set_use_markup(True)
@@ -589,11 +594,12 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"and file a bug report on the Gramps bug "
"tracking system."))
url_label.set_halign(Gtk.Align.START)
url_label.set_padding(0, 4)
url_label.set_margin_top(4)
url_label.set_margin_bottom(4)
url_label.set_line_wrap(True)
url_label.set_size_request(200, -1)
url_button = Gtk.Button("File bug report")
url_button = Gtk.Button(label="File bug report")
url_button.connect('clicked', self._start_gramps_bts_in_browser)
url_button_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
url_button_vbox.pack_start(url_button, True, False, 0)
@@ -613,11 +619,12 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
"the button below, paste the report and click "
"submit report"))
clip_label.set_halign(Gtk.Align.START)
clip_label.set_padding(0, 4)
clip_label.set_margin_top(4)
clip_label.set_margin_bottom(4)
clip_label.set_line_wrap(True)
clip_label.set_size_request(200, -1)
clip_button = Gtk.Button("Copy to clipboard")
clip_button = Gtk.Button(label="Copy to clipboard")
clip_button.connect('clicked', self._copy_to_clipboard)
clip_button_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
clip_button_vbox.pack_start(clip_button, True, False, 0)
+1 -1
View File
@@ -105,7 +105,7 @@ class ErrorView(ManagedWindow):
def draw_window(self):
title = "%s - Gramps" % _("Error Report")
self.top = Gtk.Dialog(title)
self.top = Gtk.Dialog(title=title)
# look over the top level windows, it seems the oldest come first, so
# the most recent still visible window appears to be a good choice for
# a transient parent
+10 -11
View File
@@ -75,16 +75,17 @@ class LastNameDialog(ManagedWindow):
def __init__(self, database, uistate, track, surnames, skip_list=set()):
ManagedWindow.__init__(self, uistate, track, self, modal=True)
flags = Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT
buttons = (_('_Cancel'), Gtk.ResponseType.REJECT,
_('_OK'), Gtk.ResponseType.ACCEPT)
self.__dlg = Gtk.Dialog(None, uistate.window, flags, buttons)
self.__dlg = Gtk.Dialog(
transient_for=uistate.window, destroy_with_parent=True,
modal=True)
self.__dlg.add_buttons(_('_Cancel'), Gtk.ResponseType.REJECT,
_('_OK'), Gtk.ResponseType.ACCEPT)
self.set_window(self.__dlg, None, _('Select surname'))
self.setup_configs('interface.lastnamedialog', 400, 400)
# build up a container to display all of the people of interest
self.__model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT)
self.__tree_view = Gtk.TreeView(self.__model)
self.__tree_view = Gtk.TreeView(model=self.__model)
col1 = Gtk.TreeViewColumn(_('Surname'), Gtk.CellRendererText(), text=0)
col2 = Gtk.TreeViewColumn(_('Count'), Gtk.CellRendererText(), text=1)
col1.set_resizable(True)
@@ -1739,12 +1740,10 @@ class GuiDestinationOption(Gtk.Box):
else:
my_action = Gtk.FileChooserAction.SAVE
fcd = Gtk.FileChooserDialog(_("Save As"), action=my_action,
parent=self.__uistate.window,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Open'),
Gtk.ResponseType.OK))
fcd = Gtk.FileChooserDialog(title=_("Save As"), action=my_action,
transient_for=self.__uistate.window)
fcd.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Open'), Gtk.ResponseType.OK)
name = os.path.abspath(self.__option.get_value())
if self.__option.get_directory_entry():
+9 -11
View File
@@ -435,12 +435,10 @@ class PluginStatus(ManagedWindow):
"""
Select a file from the file system.
"""
fcd = Gtk.FileChooserDialog(_("Load Addon"),
parent=self.__uistate.window,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Open'),
Gtk.ResponseType.OK))
fcd = Gtk.FileChooserDialog(title=_("Load Addon"),
transient_for=self.__uistate.window)
fcd.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Open'), Gtk.ResponseType.OK)
name = self.install_addon_path.get_text()
dir = os.path.dirname(name)
if not os.path.isdir(dir):
@@ -688,10 +686,10 @@ class PluginTrace(ManagedWindow):
) % {'str1': _("Plugin Error"), 'str2': name}
ManagedWindow.__init__(self, uistate, track, self)
self.set_window(Gtk.Dialog("", uistate.window,
Gtk.DialogFlags.DESTROY_WITH_PARENT,
(_('_Close'), Gtk.ResponseType.CLOSE)),
None, title)
dlg = Gtk.Dialog(title="", transient_for=uistate.window,
destroy_with_parent=True)
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE),
self.set_window(dlg, None, title)
self.setup_configs('interface.plugintrace', 600, 400)
self.window.connect('response', self.close)
@@ -742,7 +740,7 @@ class ToolManagedWindowBase(ManagedWindow):
self.format_menu = None
self.style_button = None
window = Gtk.Dialog('Tool')
window = Gtk.Dialog(title='Tool')
self.set_window(window, None, self.get_title())
#self.window.connect('response', self.close)
+1 -1
View File
@@ -286,7 +286,7 @@ class ExportAssistant(ManagedWindow, Gtk.Assistant):
self.set_page_complete(vbox, True)
def create_page_fileselect(self):
self.chooser = Gtk.FileChooserWidget(Gtk.FileChooserAction.SAVE)
self.chooser = Gtk.FileChooserWidget(action=Gtk.FileChooserAction.SAVE)
self.chooser.set_homogeneous(False) # Fix for bug #8350.
#add border
self.chooser.set_border_width(12)
+16 -11
View File
@@ -164,9 +164,9 @@ class WriterOptionBox:
full_database_row.pack_start(label, True, True, 0)
people_count = len(self.dbstate.db.get_person_handles())
# translators: leave all/any {...} untranslated
button = Gtk.Button(ngettext("{number_of} Person",
"{number_of} People", people_count
).format(number_of=people_count) )
button = Gtk.Button(label=ngettext("{number_of} Person",
"{number_of} People", people_count
).format(number_of=people_count))
button.set_tooltip_text(_("Click to see preview of unfiltered data"))
button.set_size_request(107, -1)
button.connect("clicked", self.show_preview_data)
@@ -271,9 +271,9 @@ class WriterOptionBox:
from gi.repository import Gtk
from ...widgets import SimpleButton
# translators: leave all/any {...} untranslated
button = Gtk.Button(ngettext("{number_of} Person",
"{number_of} People", 0
).format(number_of=0) )
button = Gtk.Button(label=ngettext("{number_of} Person",
"{number_of} People", 0
).format(number_of=0))
button.set_size_request(107, -1)
button.connect("clicked", self.show_preview_data)
button.proxy_name = proxy_name
@@ -283,7 +283,8 @@ class WriterOptionBox:
label = Gtk.Label(label=_('_Person Filter') + COLON)
label.set_halign(Gtk.Align.START)
label.set_size_request(120, -1)
label.set_padding(5, 0)
label.set_margin_start(5)
label.set_margin_end(5)
label.set_use_underline(True)
label.set_mnemonic_widget(self.filter_obj)
box = Gtk.Box()
@@ -301,7 +302,8 @@ class WriterOptionBox:
label_note = Gtk.Label(label=_('_Note Filter') + COLON)
label_note.set_halign(Gtk.Align.START)
label_note.set_size_request(120, -1)
label_note.set_padding(5, 0)
label_note.set_margin_start(5)
label_note.set_margin_end(5)
label_note.set_use_underline(True)
label_note.set_mnemonic_widget(self.filter_note)
box = Gtk.Box()
@@ -317,7 +319,8 @@ class WriterOptionBox:
label = Gtk.Label(label=_("Privacy Filter") + COLON)
label.set_halign(Gtk.Align.START)
label.set_size_request(120, -1)
label.set_padding(5, 0)
label.set_margin_start(5)
label.set_margin_end(5)
box = Gtk.Box()
box.pack_start(label, False, True, 0)
box.add(self.private_check)
@@ -327,7 +330,8 @@ class WriterOptionBox:
label = Gtk.Label(label=_("Living Filter") + COLON)
label.set_halign(Gtk.Align.START)
label.set_size_request(120, -1)
label.set_padding(5, 0)
label.set_margin_start(5)
label.set_margin_end(5)
box = Gtk.Box()
box.pack_start(label, False, True, 0)
self.restrict_option = Gtk.ComboBox()
@@ -339,7 +343,8 @@ class WriterOptionBox:
label = Gtk.Label(label=_('Reference Filter') + COLON)
label.set_halign(Gtk.Align.START)
label.set_size_request(120, -1)
label.set_padding(5, 0)
label.set_margin_start(5)
label.set_margin_end(5)
box = Gtk.Box()
box.pack_start(label, False, True, 0)
box.pack_start(self.reference_filter, True, True, 0)
+5 -7
View File
@@ -58,13 +58,11 @@ class FileEntry(Gtk.Box):
else:
my_action = Gtk.FileChooserAction.SAVE
dialog = Gtk.FileChooserDialog(self.title,
self.parent,
action=my_action,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Open'),
Gtk.ResponseType.OK))
dialog = Gtk.FileChooserDialog(title=self.title,
transient_for=self.parent,
action=my_action)
dialog.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Open'), Gtk.ResponseType.OK)
name = os.path.basename(self.entry.get_text())
if self.dir:
+2 -1
View File
@@ -175,7 +175,8 @@ class PaperFrame(Gtk.Box):
self.paper_grid.show_all()
# Shift the grid from glade toplevel window to this box
self.paper_grid.reparent(self)
self.paper_grid.get_parent().remove(self.paper_grid)
self.add(self.paper_grid)
# need to get rid of glade toplevel now that we are done with it.
self.top.destroy()
+1 -1
View File
@@ -414,7 +414,7 @@ class StyleEditor(ManagedWindow):
spin.set_value(t.get_column_width(i))
self.column.append(spin)
hbox.pack_start(spin, False, False, 6)
hbox.pack_start(Gtk.Label('%'), False, False, 6)
hbox.pack_start(Gtk.Label(label='%'), False, False, 6)
hbox.show_all()
self.vbox.pack_start(hbox, False, False, 3)
+7 -9
View File
@@ -1649,9 +1649,9 @@ class QuickBackup(ManagedWindow): # TODO move this class into its own module
self.user = user
ManagedWindow.__init__(self, uistate, [], self.__class__)
window = Gtk.Dialog('',
self.uistate.window,
Gtk.DialogFlags.DESTROY_WITH_PARENT, None)
window = Gtk.Dialog(title='',
transient_for=self.uistate.window,
destroy_with_parent=True)
self.set_window(window, None, _("Gramps XML Backup"))
self.setup_configs('interface.quick-backup', 500, 150)
close_button = window.add_button(_('_Close'),
@@ -1787,12 +1787,10 @@ class QuickBackup(ManagedWindow): # TODO move this class into its own module
"""
fdialog = Gtk.FileChooserDialog(
title=_("Select backup directory"),
parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
transient_for=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER)
fdialog.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
mpath = path_entry.get_text()
if not mpath:
mpath = HOME_DIR
+1 -1
View File
@@ -269,7 +269,7 @@ class BookmarksDialog(ManagedWindow):
def draw_window(self):
"""Draw the bookmark dialog box."""
self.top = Gtk.Dialog(parent=self.parent_window)
self.top = Gtk.Dialog(transient_for=self.parent_window)
self.top.vbox.set_spacing(5)
label = Gtk.Label(label='<span size="larger" weight="bold">%s</span>'
% _("Organize Bookmarks"))
+5 -5
View File
@@ -1059,11 +1059,11 @@ class ListView(NavigationView):
####################################################################
def export(self, *obj):
chooser = Gtk.FileChooserDialog(
_("Export View as Spreadsheet"),
self.uistate.window,
Gtk.FileChooserAction.SAVE,
(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Save'), Gtk.ResponseType.OK))
title=_("Export View as Spreadsheet"),
transient_for=self.uistate.window,
action=Gtk.FileChooserAction.SAVE)
chooser.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Save'), Gtk.ResponseType.OK)
chooser.set_do_overwrite_confirmation(True)
combobox = Gtk.ComboBoxText()
+2 -1
View File
@@ -331,7 +331,8 @@ class NavigationView(PageView):
"""
A dialog to move to a Gramps ID entered by the user.
"""
dialog = Gtk.Dialog(_('Jump to by Gramps ID'), self.uistate.window)
dialog = Gtk.Dialog(title=_('Jump to by Gramps ID'),
transient_for=self.uistate.window)
dialog.set_border_width(12)
label = Gtk.Label(label='<span weight="bold" size="larger">%s</span>' %
_('Jump to by Gramps ID'))
+33 -4
View File
@@ -241,14 +241,21 @@ class Tags(DbGUIElement):
tag_menu = ''
menuitem = '''
<item>
<attribute name="action">win.TAG-%s</attribute>
<attribute name="action">win.%s</attribute>
<attribute name="label">%s</attribute>
</item>'''
for tag_name, handle in self.__tag_list:
tag_menu += menuitem % (handle, escape(tag_name))
tag_menu += menuitem % ("TAG-%s" % handle,
"Add tag '%s'" % tag_name)
actions.append(('TAG-%s' % handle,
make_callback(self.tag_selected_rows, handle)))
for tag_name, handle in self.__tag_list:
tag_menu += menuitem % ("R-TAG-%s" % handle,
"Remove tag '%s'" % tag_name)
actions.append(('R-TAG-%s' % handle,
make_callback(self.remove_tag_selected_rows,
handle)))
tag_menu = TAG_MENU % tag_menu
self.tag_ui = [TAG_1 % tag_menu, TAG_2, TAG_3 % tag_menu]
@@ -315,6 +322,28 @@ class Tags(DbGUIElement):
view.add_tag(trans, object_handle, tag_handle)
status.end()
def remove_tag_selected_rows(self, tag_handle):
"""
Remove tag from selected rows.
"""
view = self.uistate.viewmanager.active_page
selected = view.selected_handles()
# Make the dialog modal so that the user can't start another
# database transaction while the one setting tags is still running.
pmon = progressdlg.ProgressMonitor(progressdlg.GtkProgressDialog,
("", self.uistate.window, Gtk.DialogFlags.MODAL), popup_time=2)
status = progressdlg.LongOpStatus(msg=_("Adding Tags"),
total_steps=len(selected),
interval=len(selected)//20)
pmon.add_op(status)
tag = self.db.get_tag_from_handle(tag_handle)
msg = _('Tag Selection (%s)') % tag.get_name()
with DbTxn(msg, self.db) as trans:
for object_handle in selected:
status.heartbeat()
view.remove_tag(trans, object_handle, tag_handle)
status.end()
def cb_menu_position(*args):
"""
Determine the position of the popup menu.
@@ -430,7 +459,7 @@ class OrganizeTagsDialog(ManagedWindow):
Create a dialog box to organize tags.
"""
# pylint: disable-msg=E1101
top = Gtk.Dialog(parent=self.parent_window)
top = Gtk.Dialog(transient_for=self.parent_window)
top.vbox.set_spacing(5)
label = Gtk.Label(label='<span size="larger" weight="bold">%s</span>'
% _("Organize Tags"))
@@ -659,7 +688,7 @@ class EditTag(ManagedWindow):
Create a dialog box to enter a new tag.
"""
# pylint: disable-msg=E1101
top = Gtk.Dialog(parent=self.parent_window)
top = Gtk.Dialog(transient_for=self.parent_window)
top.vbox.set_spacing(5)
hbox = Gtk.Box()
+7 -8
View File
@@ -630,13 +630,11 @@ class DetachedWindow(ManagedWindow):
self.grampletbar = grampletbar
self.gramplet = gramplet
ManagedWindow.__init__(self, gramplet.uistate, [],
self.title)
self.set_window(Gtk.Dialog("", gramplet.uistate.window,
Gtk.DialogFlags.DESTROY_WITH_PARENT,
(_('_Close'), Gtk.ResponseType.CLOSE)),
None,
self.title)
ManagedWindow.__init__(self, gramplet.uistate, [], self.title)
dlg = Gtk.Dialog(transient_for=gramplet.uistate.window,
destroy_with_parent = True)
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE)
self.set_window(dlg, None, self.title)
self.window.move(x_pos, y_pos)
self.window.set_default_size(gramplet.detached_width,
gramplet.detached_height)
@@ -701,7 +699,8 @@ class DetachedWindow(ManagedWindow):
self.gramplet.detached_width = size[0]
self.gramplet.detached_height = size[1]
self.gramplet.detached_window = None
self.gramplet.reparent(self.grampletbar)
self.notebook.remove(self.gramplet)
self.grampletbar.add(self.gramplet)
ManagedWindow.close(self, *args)
#-------------------------------------------------------------------------
+9 -8
View File
@@ -233,12 +233,11 @@ class GrampletWindow(ManagedWindow):
self.docked_state = gramplet.gstate
# Now detach it
self.gramplet.set_state("detached")
ManagedWindow.__init__(self, gramplet.uistate, [],
self.title)
self.set_window(Gtk.Dialog("", gramplet.uistate.window,
Gtk.DialogFlags.DESTROY_WITH_PARENT,
(_('_Close'), Gtk.ResponseType.CLOSE)),
None, self.title)
ManagedWindow.__init__(self, gramplet.uistate, [], self.title)
dlg = Gtk.Dialog(transient_for=gramplet.uistate.window,
destroy_with_parent=True)
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE)
self.set_window(dlg, None, self.title)
cfg_name = gramplet.gname.replace(' ', '').lower() + '-gramplet'
self.setup_configs('interface.' + cfg_name,
gramplet.detached_width, gramplet.detached_height)
@@ -246,7 +245,8 @@ class GrampletWindow(ManagedWindow):
# add gramplet:
if self.gramplet.pui:
self.gramplet.pui.active = True
self.gramplet.mainframe.reparent(self.window.vbox)
self.gramplet.mainframe.get_parent().remove(self.gramplet.mainframe)
self.window.vbox.add(self.gramplet.mainframe)
self.window.connect('response', self.handle_response)
self.show()
# After we show, then we hide:
@@ -310,7 +310,8 @@ class GrampletWindow(ManagedWindow):
expand = self.gramplet.gstate == "maximized" and self.gramplet.expand
column = pane.columns[col]
parent = self.gramplet.pane.get_column_frame(self.gramplet.column)
self.gramplet.mainframe.reparent(parent)
self.gramplet.mainframe.get_parent().remove(self.gramplet.mainframe)
parent.add(self.gramplet.mainframe)
if self.gramplet.pui:
self.gramplet.pui.active = self.gramplet.pane.pageview.active
for gframe in stack:
+7 -19
View File
@@ -18,7 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
__all__ = ["LinkLabel", "EditLabel", "BasicLabel", "GenderLabel",
__all__ = ["LinkLabel", "EditLabel", "BasicLabel",
"MarkupLabel", "DualMarkupLabel"]
#-------------------------------------------------------------------------
@@ -127,7 +127,7 @@ class LinkLabel(Gtk.EventBox):
hbox = Gtk.Box()
hbox.pack_start(self.label, False, False, 0)
if label[1]:
hbox.pack_start(GenderLabel(label[1]), False, False, 0)
hbox.pack_start(Gtk.Label(label=label[1]), False, False, 0)
hbox.set_spacing(4)
self.add(hbox)
@@ -138,7 +138,10 @@ class LinkLabel(Gtk.EventBox):
self.connect('realize', realize_cb)
def set_padding(self, x, y):
self.label.set_padding(x, y)
self.label.set_margin_start(x)
self.label.set_margin_end(x)
self.label.set_margin_top(x)
self.label.set_margin_bottom(x)
def enter_text(self, obj, event, handle):
if self.emph:
@@ -205,20 +208,6 @@ class BasicLabel(Gtk.Label):
self.set_ellipsize(ellipsize)
self.show()
#-------------------------------------------------------------------------
#
# GenderLabel class
#
#-------------------------------------------------------------------------
class GenderLabel(Gtk.Label):
def __init__(self, text):
Gtk.Label.__init__(self, label=text)
self.set_halign(Gtk.Align.START)
if win():
pangoFont = Pango.FontDescription('Arial')
self.override_font(pangoFont)
self.show()
#-------------------------------------------------------------------------
#
@@ -247,7 +236,6 @@ class DualMarkupLabel(Gtk.Box):
label.set_use_markup(True)
self.pack_start(label, False, False, 0)
b = GenderLabel(alt)
b.set_use_markup(True)
b = Gtk.Label(label=alt)
self.pack_start(b, False, False, 4)
self.show()
+1 -29
View File
@@ -177,36 +177,8 @@ class MonitoredEntryIndicator(MonitoredEntry):
autolist=None, changed=None):
MonitoredEntry.__init__(self, obj, set_val, get_val, read_only,
autolist, changed)
self.origcolor = obj.get_style_context().get_color(Gtk.StateType.NORMAL)
if get_val():
self.indicatorshown = False
else:
self.indicatorshown = True
self.indicator = indicator
self.obj.set_text(indicator)
rgba = Gdk.RGBA()
Gdk.RGBA.parse(rgba, 'grey')
self.obj.override_color(Gtk.StateType.NORMAL, rgba)
self.obj.override_font(Pango.FontDescription('sans italic'))
self.fockey = self.obj.connect('focus-in-event',
self._obj_focus)
self.obj.set_placeholder_text(indicator)
def _on_change(self, obj):
if not self.indicatorshown:
self.set_val(str(obj.get_text()))
if self.changed:
self.changed(obj)
def _obj_focus(self, widg, eve):
"""
callback for when prefix obtains focus
"""
self.set_text('')
self.obj.override_color(Gtk.StateType.NORMAL, self.origcolor)
self.obj.override_font(Pango.FontDescription('normal'))
self.obj.disconnect(self.fockey)
self.indicatorshown = False
return False
#-------------------------------------------------------------------------
#
-1
View File
@@ -84,7 +84,6 @@ class Photo(Gtk.EventBox):
elif is_right_click(event):
if self.handle and self.uistate:
self.menu = Gtk.Menu()
self.menu.set_title(_("Media Object"))
add_menuitem(self.menu, _("Make Active Media"), widget,
lambda obj: self.uistate.set_active(self.handle, "Media"))
self.menu.popup(None, None, None, None, event.button, event.time)
+2 -2
View File
@@ -26,7 +26,7 @@
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GdkPixbuf
from gi.repository import GObject
from gi.repository import GLib, GObject
#-------------------------------------------------------------------------
#
@@ -305,7 +305,7 @@ class SelectionWidget(Gtk.ScrolledWindow):
viewport_size.height)
self._rescale()
self.loaded = True
except (GObject.GError, OSError):
except (GLib.GError, OSError):
self.show_missing()
def show_missing(self):
+8 -4
View File
@@ -191,7 +191,7 @@ class MaskedEntry(UndoableEntry):
:param mask: the mask to set
"""
if not mask:
self.override_font(Pango.FontDescription("sans"))
# self.override_font(Pango.FontDescription("sans"))
self._mask = mask
return
@@ -221,7 +221,9 @@ class MaskedEntry(UndoableEntry):
pos += 1
self._mask_fields.append((field_begin, field_end))
self.override_font(Pango.FontDescription("monospace"))
# The set_mask function doesn't seem to be used, except for the test
# so removing the monospace doesn't change visible functionality
# self.override_font(Pango.FontDescription("monospace"))
self._really_delete_text(0, -1)
self._insert_mask(0, input_length)
@@ -940,6 +942,8 @@ VALIDATION_ICON_WIDTH = 16
MANDATORY_ICON = 'dialog-information'
ERROR_ICON = 'process-stop'
DELAY_TIME = 2500
READWRITE = (GObject.PARAM_READWRITE if GLib.check_version(2, 42, 0) else
GObject.ParamFlags.READWRITE)
class ValidatableMaskedEntry(MaskedEntry):
"""
@@ -969,12 +973,12 @@ class ValidatableMaskedEntry(MaskedEntry):
'data-type': (GObject.TYPE_PYOBJECT,
'Data Type of the widget',
'Type object',
GObject.PARAM_READWRITE),
READWRITE),
'mandatory': (GObject.TYPE_BOOLEAN,
'Mandatory',
'Mandatory',
False,
GObject.PARAM_READWRITE),
READWRITE),
}
# FIXME put the data type support back
+1
View File
@@ -81,6 +81,7 @@ class DbTest(unittest.TestCase):
"get_number_of_places",
"get_number_of_repositories",
"get_number_of_sources",
"get_number_of_citations",
"get_number_of_tags",
"get_media_from_gramps_id",
"get_media_from_handle",
+59 -51
View File
@@ -42,7 +42,6 @@ from gramps.gen.plug.menu import (TextOption, NumberOption, BooleanOption,
EnumeratedListOption, StringOption,
PersonOption)
from gramps.gen.plug.report import Report, MenuReportOptions, stdoptions
from gramps.gen.plug.report import utils
from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle,
FONT_SANS_SERIF, PARA_ALIGN_CENTER)
from gramps.plugins.lib.libtreebase import *
@@ -64,6 +63,7 @@ _MARR = _("marriage abbreviation|m."),
LVL_GEN, LVL_INDX, LVL_Y = range(3)
#------------------------------------------------------------------------
#
# Box classes
@@ -82,6 +82,7 @@ class PersonBox(BoxBase):
def __lt__(self, other):
return self.level[LVL_Y] < other.level[LVL_Y]
class FamilyBox(BoxBase):
"""
Calculates information about the box that will print on a page
@@ -114,6 +115,7 @@ class TitleN(TitleNoDisplay):
self.mark_text = self._("Ancestor Graph")
self.text = ''
class TitleA(TitleBox):
"""Title class for the report """
def __init__(self, doc, locale, name_displayer):
@@ -172,31 +174,32 @@ class CalcItems:
def calc_person(self, index, indi_handle, fams_handle):
working_lines = ""
if index[1] % 2 == 0 or (index[1] == 1 and self.center_use == 0):
if indi_handle == fams_handle == None:
if indi_handle == fams_handle is None:
working_lines = self.__calc_l.calc_lines(
None, None, self._gui.get_val("father_disp"))
else:
working_lines = self.disp_father
else:
if indi_handle == fams_handle == None:
if indi_handle == fams_handle is None:
working_lines = self.__calc_l.calc_lines(
None, None, self._gui.get_val("mother_disp"))
else:
working_lines = self.disp_mother
if indi_handle == fams_handle == None:
if indi_handle == fams_handle is None:
return working_lines
else:
return self.__calc_l.calc_lines(indi_handle, fams_handle,
working_lines)
def calc_marriage(self, indi_handle, fams_handle):
if indi_handle == fams_handle == None:
if indi_handle == fams_handle is None:
return self.__blank_marriage
else:
return self.__calc_l.calc_lines(indi_handle, fams_handle,
self.disp_marr)
class MakeAncestorTree(AscendPerson):
"""
The main procedure to use recursion to make the tree based off of a person.
@@ -223,9 +226,9 @@ class MakeAncestorTree(AscendPerson):
""" Makes a person box and add that person into the Canvas. """
#print str(index) + " add_person " + str(indi_handle)
myself = PersonBox((index[0]-1,) + index[1:])
myself = PersonBox((index[0] - 1,) + index[1:])
if index[LVL_GEN] == 1: #Center Person
if index[LVL_GEN] == 1: # Center Person
self.center_family = fams_handle
if index[LVL_GEN] > self.max_generation:
@@ -235,7 +238,7 @@ class MakeAncestorTree(AscendPerson):
indi_handle, fams_handle)
# myself.text[0] = myself.text[0] + ' ' + repr(index) # for debugging
if indi_handle is not None: # None is legal for an empty box
if indi_handle is not None: # None is legal for an empty box
myself.add_mark(self.database,
self.database.get_person_from_handle(indi_handle))
@@ -245,12 +248,12 @@ class MakeAncestorTree(AscendPerson):
indx = index[LVL_GEN]
self.lines[indx] = myself
if indx > 1:
if self.lines[indx-1].line_to is None:
line = LineBase(self.lines[indx-1])
self.lines[indx-1].line_to = line
if self.lines[indx - 1].line_to is None:
line = LineBase(self.lines[indx - 1])
self.lines[indx - 1].line_to = line
self.canvas.add_line(line)
else:
line = self.lines[indx-1].line_to
line = self.lines[indx - 1].line_to
line.add_to(myself)
return myself
@@ -264,7 +267,7 @@ class MakeAncestorTree(AscendPerson):
if not self.inlc_marr:
return
myself = FamilyBox((index[0]-1,) + index[1:])
myself = FamilyBox((index[0] - 1,) + index[1:])
#calculate the text.
myself.text = self.calc_items.calc_marriage(indi_handle, fams_handle)
@@ -280,7 +283,7 @@ class MakeAncestorTree(AscendPerson):
tmp_y = index - (2**x_level)
#Calculate which row in the table (yes table) of people.
delta = (2**self.max_generation) // (2**(x_level))
return int((delta/2) + (tmp_y*delta)) -1
return int((delta / 2) + (tmp_y * delta)) - 1
def do_y_indx(self):
''' Make the y_index for all boxes
@@ -292,8 +295,8 @@ class MakeAncestorTree(AscendPerson):
for box in self.canvas.boxes:
if "fam" in box.boxstr:
box.level = box.level + \
(self.y_index(box.level[LVL_GEN]-1,
int(box.level[LVL_INDX]/2)),)
(self.y_index(box.level[LVL_GEN] - 1,
int(box.level[LVL_INDX] / 2)),)
else:
box.level = box.level + \
(self.y_index(box.level[LVL_GEN], box.level[LVL_INDX]),)
@@ -304,10 +307,10 @@ class MakeAncestorTree(AscendPerson):
#Then there could be a gap. Remove this gap
if min_y > 0:
for box in self.canvas.boxes:
box.level = box.level[:LVL_Y] + (box.level[LVL_Y]-min_y,)
box.level = box.level[:LVL_Y] + (box.level[LVL_Y] - min_y,)
#Now that we have y_index, lets see if we need to squish the tree
self.canvas.boxes.sort() #Sort them on the y_index
self.canvas.boxes.sort() # Sort them on the y_index
if not self.compress_tree:
return
#boxes are already in top down [LVL_Y] form so lets
@@ -336,20 +339,19 @@ class MakeAncestorTree(AscendPerson):
line = center.line_to
level = center.level[LVL_Y]
move = level - (len(mykids)//2) + ((len(mykids)+1)%2)
move = level - (len(mykids) // 2) + ((len(mykids) + 1) % 2)
if move < 0:
# more kids than parents. ran off the page. Move them all down
for box in self.canvas.boxes:
box.level = (box.level[0], box.level[1], box.level[2]-move)
box.level = (box.level[0], box.level[1], box.level[2] - move)
move = 0
line.start = []
rrr = -1 # if len(mykids)%2 == 1 else 0
for kid in mykids:
rrr += 1
mee = self.add_person((1, 1, move+rrr), kid, self.center_family)
mee = self.add_person((1, 1, move + rrr), kid, self.center_family)
line.add_from(mee)
#mee.level = (0, 1, level - (len(mykids)//2)+rrr)
mee.line_to = line
@@ -387,7 +389,8 @@ class LRTransform:
def __init__(self, canvas, max_generations):
self.canvas = canvas
self.rept_opts = canvas.report_opts
self.y_offset = self.rept_opts.littleoffset*2 + self.canvas.title.height
self.y_offset = (self.rept_opts.littleoffset * 2 +
self.canvas.title.height)
def _place(self, box):
""" put the box in it's correct spot """
@@ -410,6 +413,7 @@ class LRTransform:
for box in self.canvas.boxes:
self._place(box)
#------------------------------------------------------------------------
#
# class make_report
@@ -441,7 +445,7 @@ class MakeReport:
self.canvas.set_box_height_width(box)
if box.width > self.canvas.report_opts.max_box_width:
self.canvas.report_opts.max_box_width = box.width #+ box.shadow
self.canvas.report_opts.max_box_width = box.width # + box.shadow
if box.level[LVL_Y] > 0:
if box.level[LVL_INDX] % 2 == 0 and box.height > self.father_ht:
@@ -456,7 +460,7 @@ class MakeReport:
return self.max_generations
def start(self):
## __gui = GUIConnect()
# __gui = GUIConnect()
# 1.
#set the sizes for each box and get the max_generations.
self.father_ht = 0.0
@@ -466,10 +470,10 @@ class MakeReport:
if self.compress_tree and not self.inlc_marr:
self.canvas.report_opts.max_box_height = \
min(self.father_ht, self.mother_ht)
min(self.father_ht, self.mother_ht)
else:
self.canvas.report_opts.max_box_height = \
max(self.father_ht, self.mother_ht)
max(self.father_ht, self.mother_ht)
#At this point we know everything we need to make the report.
#Size of each column of people - self.rept_opt.box_width
@@ -492,7 +496,8 @@ class GUIConnect:
"""
__shared_state = {}
def __init__(self): #We are BORG!
def __init__(self): # We are BORG!
self.__dict__ = self.__shared_state
def set__opts(self, options, locale, name_displayer):
@@ -533,6 +538,7 @@ class GUIConnect:
def compress_tree(self):
return self.get_val("compress_tree")
#------------------------------------------------------------------------
#
# AncestorTree
@@ -600,7 +606,7 @@ class AncestorTree(Report):
ReportOptions(self.doc, font_normal, 'AC2-line'))
self.canvas.report_opts.box_shadow *= \
self.connect.get_val('shadowscale')
self.connect.get_val('shadowscale')
self.canvas.report_opts.box_pgap *= self.connect.get_val('box_Yscale')
self.canvas.report_opts.box_mgap *= self.connect.get_val('box_Yscale')
@@ -608,7 +614,7 @@ class AncestorTree(Report):
_('Making the Tree...'), 4) as step:
#make the tree onto the canvas
## inlc_marr = self.connect.get_val("inc_marr")
# inlc_marr = self.connect.get_val("inc_marr")
self.max_generations = self.connect.get_val('maxgen')
tree = MakeAncestorTree(database, self.canvas)
tree.start(self.connect.get_val('pid'))
@@ -626,7 +632,7 @@ class AncestorTree(Report):
#make the report as big as it wants to be.
report = MakeReport(database, self.doc, self.canvas, font_normal)
report.start()
self.max_generations = report.get_generations() #already know
self.max_generations = report.get_generations() # already know
report = None
step()
@@ -670,8 +676,9 @@ class AncestorTree(Report):
colsperpage = self.doc.get_usable_width()
colsperpage += self.canvas.report_opts.col_width
colsperpage = int(colsperpage / (self.canvas.report_opts.max_box_width +
self.canvas.report_opts.col_width))
colsperpage = int(
colsperpage / (self.canvas.report_opts.max_box_width +
self.canvas.report_opts.col_width))
colsperpage = colsperpage or 1
#####################
@@ -761,6 +768,7 @@ class AncestorTree(Report):
self.doc.set_style_sheet(style_sheet)
#------------------------------------------------------------------------
#
# AncestorTreeOptions
@@ -853,8 +861,7 @@ class AncestorTreeOptions(MenuReportOptions):
self.scale.add_item(1, _("Scale tree to fit page width only"))
self.scale.add_item(2, _("Scale tree to fit the size of the page"))
self.scale.set_help(
_("Whether to scale the tree to fit a specific paper size")
)
_("Whether to scale the tree to fit a specific paper size"))
menu.add_option(category_name, "scale_tree", self.scale)
self.scale.connect('value-changed', self.__check_blank)
@@ -863,7 +870,7 @@ class AncestorTreeOptions(MenuReportOptions):
_("Resize Page to Fit Tree size\n"
"\n"
"Note: Overrides options in the 'Paper Option' tab"
),
),
False)
self.__onepage.set_help(
_("Whether to resize the page to fit the size \n"
@@ -880,7 +887,7 @@ class AncestorTreeOptions(MenuReportOptions):
"\n"
"With 'Scale tree to fit the size of the page' the page\n"
" is resized to remove any gap in either height or width"
))
))
menu.add_option(category_name, "resize_page", self.__onepage)
self.__onepage.connect('value-changed', self.__check_blank)
else:
@@ -910,8 +917,8 @@ class AncestorTreeOptions(MenuReportOptions):
disp = TextOption(_("Father\nDisplay Format"),
["$n",
"%s $b" %_BORN,
"-{%s $d}" %_DIED])
"%s $b" % _BORN,
"-{%s $d}" % _DIED])
disp.set_help(_("Display format for the fathers box."))
menu.add_option(category_name, "father_disp", disp)
@@ -925,9 +932,9 @@ class AncestorTreeOptions(MenuReportOptions):
disp_mom = TextOption(_("Mother\nDisplay Format"),
["$n",
"%s $b" %_BORN,
"%s $m" %_MARR,
"-{%s $d}" %_DIED])
"%s $b" % _BORN,
"%s $m" % _MARR,
"-{%s $d}" % _DIED])
disp_mom.set_help(_("Display format for the mothers box."))
menu.add_option(category_name, "mother_disp", disp_mom)
@@ -945,7 +952,7 @@ class AncestorTreeOptions(MenuReportOptions):
self.incmarr.connect('value-changed', self._incmarr_changed)
self.marrdisp = StringOption(_("Marriage\nDisplay Format"),
"%s $m" % _MARR)
"%s $m" % _MARR)
self.marrdisp.set_help(_("Display format for the marital box."))
menu.add_option(category_name, "marr_disp", self.marrdisp)
self._incmarr_changed()
@@ -964,7 +971,8 @@ class AncestorTreeOptions(MenuReportOptions):
# _('Include thumbnail images of people'), False)
# self.__include_images.set_help(
# _("Whether to include thumbnails of people."))
# menu.add_option(category_name, "includeImages", self.__include_images)
# menu.add_option(category_name, "includeImages",
# self.__include_images)
self.usenote = BooleanOption(_('Include a note'), False)
self.usenote.set_help(_("Whether to include a note on the report."))
@@ -991,7 +999,7 @@ class AncestorTreeOptions(MenuReportOptions):
menu.add_option(category_name, "box_Yscale", self.box_Y_sf)
self.box_shadow_sf = NumberOption(_("box shadow scale factor"),
1.00, 0.00, 2.00, 0.01) # down to 0
1.00, 0.00, 2.00, 0.01) # down to 0
self.box_shadow_sf.set_help(_("Make the box shadow bigger or smaller"))
menu.add_option(category_name, "shadowscale", self.box_shadow_sf)
@@ -1033,13 +1041,13 @@ class AncestorTreeOptions(MenuReportOptions):
for itr in range(2, max_gen))
self.fillout.set_items(item_list)
if old_val+2 > len(item_list):
self.fillout.set_value(len(item_list) -2)
if old_val + 2 > len(item_list):
self.fillout.set_value(len(item_list) - 2)
def make_default_style(self, default_style):
"""Make the default output style for the Ancestor Tree."""
## Paragraph Styles:
# Paragraph Styles:
font = FontStyle()
font.set_size(9)
font.set_type_face(FONT_SANS_SERIF)
@@ -1068,16 +1076,16 @@ class AncestorTreeOptions(MenuReportOptions):
para_style.set_description(_('The style used for the title.'))
default_style.add_paragraph_style("AC2-Title", para_style)
## Draw styles
# Draw styles
graph_style = GraphicsStyle()
graph_style.set_paragraph_style("AC2-Normal")
graph_style.set_shadow(1, box_shadow) #shadow set by text size
graph_style.set_shadow(1, box_shadow) # shadow set by text size
graph_style.set_fill_color((255, 255, 255))
default_style.add_draw_style("AC2-box", graph_style)
graph_style = GraphicsStyle()
graph_style.set_paragraph_style("AC2-Normal")
#graph_style.set_shadow(0, PT2CM(9)) #shadow set by text size
#graph_style.set_shadow(0, PT2CM(9)) # shadow set by text size
graph_style.set_fill_color((255, 255, 255))
default_style.add_draw_style("AC2-fam-box", graph_style)
+7 -6
View File
@@ -1820,30 +1820,31 @@ class DescendTreeOptions(MenuReportOptions):
graph_style = GraphicsStyle()
graph_style.set_paragraph_style("CG2-Normal")
graph_style.set_fill_color((255, 255, 255))
graph_style.set_description(_("The style for the marriage box."))
default_style.add_draw_style("CG2-fam-box", graph_style)
graph_style = GraphicsStyle()
graph_style.set_paragraph_style("CG2-Normal")
graph_style.set_shadow(1, box_shadow)
graph_style.set_fill_color((255, 255, 255))
graph_style.set_description(_("The style for the spouse box."))
default_style.add_draw_style("CG2-box", graph_style)
graph_style = GraphicsStyle()
graph_style.set_paragraph_style("CG2-Bold")
graph_style.set_shadow(1, box_shadow)
graph_style.set_fill_color((255, 255, 255))
graph_style.set_description(
_("The style for the direct descendant box."))
default_style.add_draw_style("CG2b-box", graph_style)
graph_style = GraphicsStyle()
graph_style.set_paragraph_style("CG2-Note")
graph_style.set_fill_color((255, 255, 255))
graph_style.set_description(_("The style for the note box."))
default_style.add_draw_style("CG2-note-box", graph_style)
graph_style = GraphicsStyle()
graph_style.set_description(
_("The style for the connection lines and report border."))
default_style.add_draw_style("CG2-line", graph_style)
#=====================================
#So do not fear, for I am with you; do not be dismayed,
#for I am your God. I will strengthen you and help you;
#I will uphold you with my righteous right hand.
#Isaiah 41:10
-1
View File
@@ -139,7 +139,6 @@ class GeoEvents(Gramplet, DbGUIElement):
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title(_('Edit'))
title = _('Edit the event')
add_item = Gtk.MenuItem(label=title)
add_item.connect("activate", self.edit_event, treeview)
@@ -70,7 +70,7 @@ class FanChart2WayGramplet(FanChart2WayGrampsGUI, Gramplet):
self.on_popup))
# Replace the standard textview with the fan chart widget:
self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add_with_viewport(self.fan)
self.gui.get_container_widget().add(self.fan)
# Make sure it is visible:
self.fan.show()
+6 -5
View File
@@ -24,7 +24,7 @@
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
from gi.repository import Pango
from gi.repository.GLib import markup_escape_text
#-------------------------------------------------------------------------
#
@@ -61,7 +61,6 @@ class PersonDetails(Gramplet):
self.photo = Photo(self.uistate.screen_height() < 1000)
self.photo.show()
self.name = Gtk.Label(halign=Gtk.Align.START)
self.name.override_font(Pango.FontDescription('sans bold 12'))
self.name.set_selectable(True)
vbox.pack_start(self.name, fill=True, expand=False, padding=7)
self.grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
@@ -150,7 +149,9 @@ class PersonDetails(Gramplet):
Display details of the active person.
"""
self.load_person_image(active_person)
self.name.set_text(name_displayer.display(active_person))
self.name.set_markup(
"<span size='large' weight='bold'>%s</span>" %
markup_escape_text(name_displayer.display(active_person), -1))
self.clear_grid()
self.display_alternate_names(active_person)
self.display_parents(active_person)
@@ -177,8 +178,8 @@ class PersonDetails(Gramplet):
"""
Display an empty row to separate groupd of entries.
"""
label = Gtk.Label(label='')
label.override_font(Pango.FontDescription('sans 4'))
label = Gtk.Label()
label.set_markup("<span font='sans 4'> </span>")
label.set_selectable(True)
label.show()
self.grid.add(label)
+5 -5
View File
@@ -23,7 +23,7 @@
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
from gi.repository import Pango
from gi.repository.GLib import markup_escape_text
#-------------------------------------------------------------------------
#
@@ -55,7 +55,6 @@ class PlaceDetails(Gramplet):
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.photo = Photo(self.uistate.screen_height() < 1000)
self.title = Gtk.Label(halign=Gtk.Align.START)
self.title.override_font(Pango.FontDescription('sans bold 12'))
self.title.set_selectable(True)
vbox.pack_start(self.title, False, True, 7)
self.grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
@@ -119,7 +118,8 @@ class PlaceDetails(Gramplet):
"""
self.load_place_image(place)
title = place_displayer.display(self.dbstate.db, place)
self.title.set_text(title)
self.title.set_markup("<span size='large' weight='bold'>%s</span>" %
markup_escape_text(title))
self.clear_grid()
self.add_row(_('Name'), place.get_name().get_value())
@@ -158,8 +158,8 @@ class PlaceDetails(Gramplet):
"""
Display an empty row to separate groupd of entries.
"""
label = Gtk.Label(label='')
label.override_font(Pango.FontDescription('sans 4'))
label = Gtk.Label()
label.set_markup("<span font='sans 4'> </span>")
label.set_selectable(True)
label.show()
self.grid.add(label)
+6 -4
View File
@@ -24,6 +24,7 @@
#-------------------------------------------------------------------------
from gi.repository import Gtk
from gi.repository import Pango
from gi.repository.GLib import markup_escape_text
#-------------------------------------------------------------------------
#
@@ -51,7 +52,6 @@ class RepositoryDetails(Gramplet):
self.top = Gtk.Box()
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.name = Gtk.Label(halign=Gtk.Align.START)
self.name.override_font(Pango.FontDescription('sans bold 12'))
self.name.set_selectable(True)
vbox.pack_start(self.name, fill=True, expand=False, padding=7)
self.grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
@@ -112,7 +112,9 @@ class RepositoryDetails(Gramplet):
"""
Display details of the active repository.
"""
self.name.set_text(repo.get_name())
self.name.set_markup(
"<span size='large' weight='bold'>%s</span>" %
markup_escape_text(repo.get_name(), -1))
self.clear_grid()
address_list = repo.get_address_list()
@@ -154,8 +156,8 @@ class RepositoryDetails(Gramplet):
"""
Display an empty row to separate groupd of entries.
"""
label = Gtk.Label(label='')
label.override_font(Pango.FontDescription('sans 4'))
label = Gtk.Label()
label.set_markup("<span font='sans 4'> </span>")
label.set_selectable(True)
label.show()
self.grid.add(label)
+8
View File
@@ -559,6 +559,14 @@ class BasePersonView(ListView):
person.add_tag(tag_handle)
self.dbstate.db.commit_person(person, transaction)
def remove_tag(self, transaction, person_handle, tag_handle):
"""
Remove the given tag from the given person.
"""
person = self.dbstate.db.get_person_from_handle(person_handle)
person.remove_tag(tag_handle)
self.dbstate.db.commit_person(person, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+8
View File
@@ -595,6 +595,14 @@ class PlaceBaseView(ListView):
place.add_tag(tag_handle)
self.dbstate.db.commit_place(place, transaction)
def remove_tag(self, transaction, place_handle, tag_handle):
"""
Remove the given tag from the given place.
"""
place = self.dbstate.db.get_place_from_handle(place_handle)
place.remove_tag(tag_handle)
self.dbstate.db.commit_place(place, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+22 -16
View File
@@ -22,7 +22,6 @@
"""
from gramps.gen.plug.report import utils
from gramps.gen.lib import ChildRefType
#------------------------------------------------------------------------
@@ -56,6 +55,7 @@ class _PersonSeen:
if person_handle is not None:
self.people_seen.add(person_handle)
class _FamilySeen:
""" librecurse base boject only
Keep track of the famalies that have been seen so we can call the correct
@@ -80,6 +80,7 @@ class _FamilySeen:
self.add_marriage(level, person_handle, family_handle)
self.families_seen.add(family_handle)
class _StopRecurse:
""" A simple class to break out the
. stop_recursion
@@ -101,7 +102,7 @@ class _StopRecurse:
def can_recurse(self):
""" Has the upper class told up to stop or can we continue? """
return self.__stop_recursion == False
return not self.__stop_recursion
#------------------------------------------------------------------------
@@ -276,7 +277,7 @@ class DescendPerson(_StopRecurse, _PersonSeen, _FamilySeen):
for family_handle in family_handles:
#Marriage box if the option is there.
self._add_marriage((g_level, s_level + 1),
person_handle, family_handle)
person_handle, family_handle)
if not self.can_recurse():
self.continue_recursion()
@@ -288,7 +289,7 @@ class DescendPerson(_StopRecurse, _PersonSeen, _FamilySeen):
if self.max_spouses > s_level:
self.__this_slevel = s_level + 1
self._add_person((g_level, s_level + 1),
spouse_handle, family_handle)
spouse_handle, family_handle)
if not self.can_recurse:
self.continue_recursion()
@@ -446,13 +447,13 @@ class AscendPerson(_StopRecurse, _PersonSeen):
# Recursively call the function. It is okay if the handle is None,
# since routine handles a handle of None
self.__fill(generation+1, index*2, mx_fill-1)
self.__fill(generation + 1, index * 2, mx_fill - 1)
if mx_fill > 1: # marriage of parents
self.add_marriage((generation+1, index*2), None, None)
self.add_marriage((generation + 1, index * 2), None, None)
if not self.can_recurse():
self.continue_recursion()
return
self.__fill(generation+1, (index*2)+1, mx_fill-1)
self.__fill(generation + 1, (index * 2) + 1, mx_fill - 1)
def __iterate(self, generation, index, person_handle, full_family_handle):
"""
@@ -478,15 +479,15 @@ class AscendPerson(_StopRecurse, _PersonSeen):
person = self.database.get_person_from_handle(person_handle)
# we have a valid person, add him/her
self._add_person((generation, index), person_handle, full_family_handle)
self._add_person((generation, index), person_handle,
full_family_handle)
# has the user canceled recursion?
if not self.can_recurse():
self.continue_recursion()
return
#Now recurse on the parents
# Now recurse on the parents
family_handle = person.get_main_parents_family_handle()
if family_handle is not None:
@@ -498,21 +499,26 @@ class AscendPerson(_StopRecurse, _PersonSeen):
mother_handle = None
# Recursively call the function. It is okay if the handle is None,
self.__iterate(generation+1, index*2, father_handle, family_handle) #recurse on dad
self.__iterate(generation + 1, index * 2, father_handle,
family_handle) # recurse on dad
if generation < self.max_generations:
if father_handle is not None: # Stil winin max_generations
self.add_marriage((generation+1, index*2), father_handle, family_handle)
self.add_marriage((generation + 1, index * 2), father_handle,
family_handle)
elif mother_handle is not None:
self.add_marriage((generation+1, index*2), mother_handle, family_handle)
self.add_marriage((generation + 1, index * 2), mother_handle,
family_handle)
elif family_handle is not None:
self.add_marriage((generation+1, index*2), None, family_handle)
self.add_marriage((generation + 1, index * 2), None,
family_handle)
elif self.fill_out > 0:
self.add_marriage((generation+1, index*2), None, None)
self.add_marriage((generation + 1, index * 2), None, None)
if not self.can_recurse():
self.continue_recursion()
return
self.__iterate(generation+1, (index*2)+1, mother_handle, family_handle) #recurse mom
self.__iterate(generation + 1, (index * 2) + 1, mother_handle,
family_handle) # recurse mom
def recurse(self, person_handle):
"""
+8 -12
View File
@@ -405,7 +405,6 @@ class GeoGraphyView(OsmGps, NavigationView):
self.changemap = Gtk.Menu()
changemap = self.changemap
changemap.set_title(title)
changemap.show()
add_item.set_submenu(changemap)
# show in the map menu all available providers
@@ -885,7 +884,6 @@ class GeoGraphyView(OsmGps, NavigationView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Place"))
@@ -990,11 +988,11 @@ class GeoGraphyView(OsmGps, NavigationView):
filtering = Gtk.FileFilter()
filtering.add_pattern("*.kml")
kml = Gtk.FileChooserDialog(
_("Select a kml file used to add places"),
title=_("Select a kml file used to add places"),
action=Gtk.FileChooserAction.OPEN,
parent=self.uistate.window,
buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK))
transient_for=self.uistate.window)
kml.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
mpath = HOME_DIR
kml.set_current_folder(os.path.dirname(mpath))
kml.set_filter(filtering)
@@ -1286,13 +1284,11 @@ class GeoGraphyView(OsmGps, NavigationView):
"""
dummy_obj = obj
selected_dir = Gtk.FileChooserDialog(
_("Select tile cache directory for offline mode"),
title=_("Select tile cache directory for offline mode"),
action=Gtk.FileChooserAction.SELECT_FOLDER,
parent=self.uistate.window,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
transient_for=self.uistate.window)
selected_dir.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
mpath = config.get('geography.path')
if not mpath:
mpath = HOME_DIR
+6 -6
View File
@@ -115,10 +115,10 @@ class PlaceSelection(ManagedWindow, OsmGps):
self.selection_layer = layer
self.layer = layer
self.warning = False
self.set_window(
Gtk.Dialog(_('Place Selection in a region'), uistate.window,
buttons=(_('_Close'), Gtk.ResponseType.CLOSE)),
None, _('Place Selection in a region'), None)
dlg = Gtk.Dialog(title=_('Place Selection in a region'),
transient_for=uistate.window)
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE)
self.set_window(dlg, None, _('Place Selection in a region'), None)
mylabel = _('Choose the radius of the selection.\n'
'On the map you should see a circle or an'
' oval depending on the latitude.')
@@ -139,11 +139,11 @@ class PlaceSelection(ManagedWindow, OsmGps):
slider.connect('value-changed', self.slider_change, self.lat, self.lon)
self.window.vbox.pack_start(slider, False, True, 0)
self.vadjust = Gtk.Adjustment(page_size=15)
self.scroll = Gtk.ScrolledWindow(self.vadjust)
self.scroll = Gtk.ScrolledWindow(vadjustment=self.vadjust)
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
self.scroll.set_shadow_type(Gtk.ShadowType.IN)
self.plist = Gtk.ListStore(str, str, str, str, str)
self.choices = Gtk.TreeView(self.plist)
self.choices = Gtk.TreeView(model=self.plist)
self.scroll.add(self.choices)
self.renderer = Gtk.CellRendererText()
self.tvcol1 = Gtk.TreeViewColumn(_('Country'), self.renderer, markup=0)
+4 -4
View File
@@ -775,10 +775,10 @@ class CheckIntegrity:
'kept')
fs_top = Gtk.FileChooserDialog(
"%s - Gramps" % _("Select file"),
parent=self.parent_window,
buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_OK'), Gtk.ResponseType.OK))
title="%s - Gramps" % _("Select file"),
transient_for=self.parent_window)
fs_top.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_OK'), Gtk.ResponseType.OK)
fs_top.set_current_folder(self.last_img_dir)
response = fs_top.run()
if response == Gtk.ResponseType.OK:
+4 -6
View File
@@ -393,12 +393,10 @@ class EventComparisonResults(ManagedWindow):
def on_write_table(self, obj):
f = Gtk.FileChooserDialog(_("Select filename"),
parent=self.window,
action=Gtk.FileChooserAction.SAVE,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Save'),
Gtk.ResponseType.OK))
transient_for=self.window,
action=Gtk.FileChooserAction.SAVE)
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Save'), Gtk.ResponseType.OK)
f.set_current_folder(get_curr_dir())
status = f.run()
+10 -9
View File
@@ -84,15 +84,16 @@ class PopulateSources(tool.Tool, ManagedWindow):
num_citations = self.options.handler.options_dict['citations']
# GUI setup:
dialog = Gtk.Dialog("Populate sources and citations tool",
self.uistate.window,
Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT,
(_('_Cancel'), Gtk.ResponseType.REJECT,
_('_OK'), Gtk.ResponseType.ACCEPT))
label = Gtk.Label("Enter a valid number of sources and citations."
" This will create the requested number of sources,"
" and for each source, will create the requested"
" number of citations.")
dialog = Gtk.Dialog(title="Populate sources and citations tool",
transient_for=self.uistate.window,
modal=True, destroy_with_parent=True)
dialog.add_buttons(_('_Cancel'), Gtk.ResponseType.REJECT,
_('_OK'), Gtk.ResponseType.ACCEPT)
label = Gtk.Label(
label="Enter a valid number of sources and citations."
" This will create the requested number of sources,"
" and for each source, will create the requested"
" number of citations.")
label.set_line_wrap(True)
hbox1 = Gtk.Box()
+1 -1
View File
@@ -272,7 +272,7 @@ class TestcaseGenerator(tool.BatchTool):
def init_gui(self, uistate):
title = "%s - Gramps" % _("Generate testcases")
self.top = Gtk.Dialog(title, parent=uistate.window)
self.top = Gtk.Dialog(title=title, transient_for=uistate.window)
self.window = uistate.window
self.top.set_default_size(400, 150)
self.top.vbox.set_spacing(5)
+8
View File
@@ -453,6 +453,14 @@ class CitationListView(ListView):
citation.add_tag(tag_handle)
self.dbstate.db.commit_citation(citation, transaction)
def remove_tag(self, transaction, citation_handle, tag_handle):
"""
Remove the given tag from the given citation.
"""
citation = self.dbstate.db.get_citation_from_handle(citation_handle)
citation.remove_tag(tag_handle)
self.dbstate.db.commit_citation(citation, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+12
View File
@@ -742,6 +742,18 @@ class CitationTreeView(ListView):
source.add_tag(tag_handle)
self.dbstate.db.commit_source(source, transaction)
def remove_tag(self, transaction, handle, tag_handle):
"""
Remove the given tag from the given source or citation.
"""
source, citation = self.get_source_or_citation(handle)
if citation:
citation.remove_tag(tag_handle)
self.dbstate.db.commit_citation(citation, transaction)
else:
source.remove_tag(tag_handle)
self.dbstate.db.commit_source(source, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+8
View File
@@ -468,6 +468,14 @@ class EventView(ListView):
event.add_tag(tag_handle)
self.dbstate.db.commit_event(event, transaction)
def remove_tag(self, transaction, event_handle, tag_handle):
"""
Remove the given tag from the given event.
"""
event = self.dbstate.db.get_event_from_handle(event_handle)
event.remove_tag(tag_handle)
self.dbstate.db.commit_event(event, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+8
View File
@@ -483,6 +483,14 @@ class FamilyView(ListView):
family.add_tag(tag_handle)
self.dbstate.db.commit_family(family, transaction)
def remove_tag(self, transaction, family_handle, tag_handle):
"""
Remove the given tag from the given family.
"""
family = self.dbstate.db.get_family_from_handle(family_handle)
family.remove_tag(tag_handle)
self.dbstate.db.commit_family(family, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+4 -4
View File
@@ -135,7 +135,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
self.scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.fan.show_all()
self.scrolledwindow.add_with_viewport(self.fan)
self.scrolledwindow.add(self.fan)
return self.scrolledwindow
@@ -573,9 +573,9 @@ class CairoPrintSave():
(typically evince not installed)!
"""
dummy_preview = preview
dlg = Gtk.MessageDialog(parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.WARNING,
dlg = Gtk.MessageDialog(transient_for=parent,
modal=True,
message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.CLOSE,
message_format=_('No preview available'))
self.preview = dlg
+3 -3
View File
@@ -561,9 +561,9 @@ class CairoPrintSave:
(typically evince not installed)!
"""
dummy_preview = preview
dlg = Gtk.MessageDialog(parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.WARNING,
dlg = Gtk.MessageDialog(transient_for=parent,
modal=True,
message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.CLOSE,
message_format=_('No preview available'))
self.preview = dlg
+3 -3
View File
@@ -659,9 +659,9 @@ class CairoPrintSave:
(typically evince not installed)!
"""
dummy_preview = preview
dlg = Gtk.MessageDialog(parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.WARNING,
dlg = Gtk.MessageDialog(transient_for=parent,
modal=True,
message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.CLOSE,
message_format=_('No preview available'))
self.preview = dlg
-2
View File
@@ -568,7 +568,6 @@ class GeoClose(GeoGraphyView):
"""
self.newmenu = Gtk.Menu()
menu = self.newmenu
menu.set_title("person")
events = []
message = ""
oldplace = ""
@@ -613,7 +612,6 @@ class GeoClose(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
-4
View File
@@ -379,7 +379,6 @@ class GeoEvents(GeoGraphyView):
def bubble_message(self, event, lat, lon, marks):
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("events")
message = ""
oldplace = ""
prevmark = None
@@ -390,7 +389,6 @@ class GeoEvents(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
@@ -424,7 +422,6 @@ class GeoEvents(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
@@ -461,7 +458,6 @@ class GeoEvents(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(_("Centering on Place"))
itemoption.show()
add_item.set_submenu(itemoption)
oldplace = ""
-2
View File
@@ -758,7 +758,6 @@ class GeoFamClose(GeoGraphyView):
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("family")
events = []
message = ""
oldplace = ""
@@ -802,7 +801,6 @@ class GeoFamClose(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
-1
View File
@@ -494,7 +494,6 @@ class GeoFamily(GeoGraphyView):
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("family")
message = ""
oldplace = ""
prevmark = None
-2
View File
@@ -637,7 +637,6 @@ class GeoMoves(GeoGraphyView):
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("descendance")
events = []
message = ""
oldplace = ""
@@ -680,7 +679,6 @@ class GeoMoves(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
-4
View File
@@ -485,7 +485,6 @@ class GeoPerson(GeoGraphyView):
def bubble_message(self, event, lat, lon, marks):
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("person")
message = ""
oldplace = ""
prevmark = None
@@ -496,7 +495,6 @@ class GeoPerson(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
message = ""
add_item.set_submenu(itemoption)
@@ -517,7 +515,6 @@ class GeoPerson(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
message = ""
add_item.set_submenu(itemoption)
@@ -559,7 +556,6 @@ class GeoPerson(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
-4
View File
@@ -480,7 +480,6 @@ class GeoPlaces(GeoGraphyView):
def bubble_message(self, event, lat, lon, marks):
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("places")
message = ""
prevmark = None
for mark in marks:
@@ -490,7 +489,6 @@ class GeoPlaces(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Place"))
@@ -516,7 +514,6 @@ class GeoPlaces(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Place"))
@@ -553,7 +550,6 @@ class GeoPlaces(GeoGraphyView):
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(_("Centering on Place"))
itemoption.show()
add_item.set_submenu(itemoption)
oldplace = ""
+8
View File
@@ -518,6 +518,14 @@ class MediaView(ListView):
media.add_tag(tag_handle)
self.dbstate.db.commit_media(media, transaction)
def remove_tag(self, transaction, media_handle, tag_handle):
"""
Remove the given tag from the given media object.
"""
media = self.dbstate.db.get_media_from_handle(media_handle)
media.remove_tag(tag_handle)
self.dbstate.db.commit_media(media, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+8
View File
@@ -382,6 +382,14 @@ class NoteView(ListView):
note.add_tag(tag_handle)
self.dbstate.db.commit_note(note, transaction)
def remove_tag(self, transaction, note_handle, tag_handle):
"""
Remove the given tag from the given note.
"""
note = self.dbstate.db.get_note_from_handle(note_handle)
note.remove_tag(tag_handle)
self.dbstate.db.commit_note(note, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+4 -3
View File
@@ -1196,7 +1196,7 @@ class RelationshipView(NavigationView):
label = widgets.MarkupLabel(format % escape(title),
halign=Gtk.Align.END)
if self._config.get('preferences.releditbtn'):
label.set_padding(0, 5)
label.set_margin_end(5)
eventbox = Gtk.EventBox()
if handle is not None:
@@ -1286,7 +1286,7 @@ class RelationshipView(NavigationView):
lbl = widgets.MarkupLabel(format % escape(title),
halign=Gtk.Align.END)
if self._config.get('preferences.releditbtn'):
lbl.set_padding(0, 5)
lbl.set_margin_end(5)
return lbl
def write_child(self, vbox, handle, index, child_should_be_linked):
@@ -1333,6 +1333,7 @@ class RelationshipView(NavigationView):
link_label = widgets.LinkLabel(name, link_func, handle, emph,
theme=self.theme)
link_label.set_padding(3, 0)
if child_should_be_linked and self._config.get(
'preferences.releditbtn'):
button = widgets.IconButton(self.edit_button_press, handle)
@@ -1354,7 +1355,7 @@ class RelationshipView(NavigationView):
value = self.info_string(handle)
if value:
l = widgets.MarkupLabel(value)
l.set_padding(48, 0)
l.set_margin_start(48)
vbox.add(l)
def write_data(self, box, title, start_col=_SDATA_START,
+8
View File
@@ -396,6 +396,14 @@ class RepositoryView(ListView):
repo.add_tag(tag_handle)
self.dbstate.db.commit_repository(repo, transaction)
def remove_tag(self, transaction, repo_handle, tag_handle):
"""
Remove the given tag from the given repository.
"""
repo = self.dbstate.db.get_repository_from_handle(repo_handle)
repo.remove_tag(tag_handle)
self.dbstate.db.commit_repository(repo, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+8
View File
@@ -380,6 +380,14 @@ class SourceView(ListView):
source.add_tag(tag_handle)
self.dbstate.db.commit_source(source, transaction)
def remove_tag(self, transaction, source_handle, tag_handle):
"""
Remove the given tag from the given source.
"""
source = self.dbstate.db.get_source_from_handle(source_handle)
source.remove_tag(tag_handle)
self.dbstate.db.commit_source(source, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
+18 -5
View File
@@ -742,7 +742,7 @@ class BasePage: # pylint: disable=C1001
event_date = event.get_date_object()
# 0 = latitude, 1 = longitude, 2 - placetitle,
# 3 = place handle, 4 = event date, 5 = event type
# 3 = place handle, 4 = event
found = any(data[3] == place_handle and data[4] == event_date
for data in place_lat_long)
if not found:
@@ -752,9 +752,8 @@ class BasePage: # pylint: disable=C1001
if latitude and longitude:
latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8")
if latitude is not None:
etype = event.get_type()
place_lat_long.append([latitude, longitude, placetitle,
place_handle, event_date, etype])
place_handle, event])
def _get_event_place(self, person, place_lat_long):
"""
@@ -1422,8 +1421,23 @@ class BasePage: # pylint: disable=C1001
Html("link", type="text/css", href=url3,
media='print', rel="stylesheet", indent=False),
Html("link", type="text/css", href=url2,
media="screen", rel="stylesheet", indent=False),
media="screen", title=self._("Default"),
rel="stylesheet", indent=False),
)
# create all alternate stylesheets
# Cannot use it on local files (file://)
for css_f in CSS:
already_done = False
for css_fn in ("UsEr_", "Basic", "Mainz", "Nebraska"):
if css_fn in css_f and not already_done:
css_f = css_f.replace("UsEr_", "")
fname = "/".join(["css", css_f + ".css"])
urlx = self.report.build_url_fname(fname, None,
self.uplink)
links += Html("link", rel="alternate stylesheet",
title=css_f, indent=False,
media="screen", type="text/css",
href=urlx)
# Link to Navigation Menus stylesheet
if CSS[self.report.css]["navigation"]:
@@ -3000,4 +3014,3 @@ class BasePage: # pylint: disable=C1001
# closes the file
self.report.close_file(output_file, sio, date)
+145 -36
View File
@@ -120,16 +120,27 @@ DROPMASTERS = """
function addMarker() {
var location = tracelife[iterator];
var myLatLng = new google.maps.LatLng(location[1], location[2]);
var infoWindow = new google.maps.InfoWindow;
markers.push(new google.maps.Marker({
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
draggable: true,
title: location[0],
animation: google.maps.Animation.DROP
}));
});
markers.push(marker);
iterator++;
}"""
var title = "<h2>" + location[0] + "</h2>"
bindInfoWindow(marker, map, infoWindow, title+location[4]);
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
"""
# javascript for Google's Markers...
MARKERS = """
@@ -153,6 +164,7 @@ MARKERS = """
function addMarkers() {
var bounds = new google.maps.LatLngBounds();
var infoWindow = new google.maps.InfoWindow;
for (var i = 0; i < tracelife.length; i++) {
var location = tracelife[i];
@@ -165,16 +177,30 @@ MARKERS = """
map: map,
zIndex: location[3]
});
var title = "<h2>" + location[0] + "</h2>"
bindInfoWindow(marker, map, infoWindow, title+location[4]);
bounds.extend(myLatLng);
if ( i > 1 ) { map.fitBounds(bounds); };
}
}"""
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
"""
# javascript for OpenStreetMap's markers...
"""
https://openlayers.org/en/latest/examples/
"""
OSM_MARKERS = """
function initialize(){
var map;
var tracelife = %s;
var tracelife = %s
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.2, 48],
@@ -192,6 +218,7 @@ OSM_MARKERS = """
geometry: new ol.geom.Point(ol.proj.transform([loc[0], loc[1]],
'EPSG:4326', 'EPSG:3857')),
name: loc[2],
data: loc[3],
});
iconFeature.setStyle(iconStyle);
markerSource.addFeature(iconFeature);
@@ -200,53 +227,135 @@ OSM_MARKERS = """
source: markerSource,
style: iconStyle
});
tooltip = new ol.layer.Vector({
source: markerSource,
style: iconStyle
});
var centerCoord = new ol.proj.transform([%s, %s], 'EPSG:4326', 'EPSG:3857');
map= new ol.Map({
map = new ol.Map({
target: 'map_canvas',
layers: [new ol.layer.Tile({ source: new ol.source.OSM() }),
markerLayer],
markerLayer, tooltip],
view: new ol.View({ center: centerCoord, zoom: %d })
});
"""
STAMEN_MARKERS = """
function initialize(){
var map;
var tracelife = %s
var layer = '%s';
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.2, 48],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 1.0,
src: marker_png
}))
});
var markerSource = new ol.source.Vector({
});
for (var i = 0; i < tracelife.length; i++) {
var loc = tracelife[i];
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([loc[0], loc[1]],
'EPSG:4326', 'EPSG:3857')),
name: loc[2],
data: loc[3],
});
iconFeature.setStyle(iconStyle);
markerSource.addFeature(iconFeature);
}
var centerCoord = new ol.proj.transform([%s, %s], 'EPSG:4326', 'EPSG:3857');
markerLayer = new ol.layer.Vector({
source: markerSource,
style: iconStyle
});
tooltip = new ol.layer.Vector({
source: markerSource,
style: iconStyle
});
map = new ol.Map({
target: 'map_canvas',
layers: [
new ol.layer.Tile({ source: new ol.source.Stamen({
layer: layer }) }),
markerLayer, tooltip],
view: new ol.View({ center: centerCoord, zoom: %d })
});
"""
OPENLAYER = """
var element = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
var tip = document.getElementById('tooltip');
var tipcontent = document.getElementById('tooltip-content');
var tooltip = new ol.Overlay({
element: element,
element: tip,
positioning: 'bottom-center',
stopEvent: false
offset: [10, 0],
});
map.addOverlay(tooltip);
var displayFeatureInfo = function(pixel) {
var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
var popup = new ol.Overlay({
element: element,
positioning: 'bottom-center',
autoPan: true,
autoPanAnimation: { duration: 500 },
stopEvent: false
});
map.addOverlay(popup);
/**
* Add a click handler to hide the popup.
* @return {boolean} Don't follow the href.
*/
closer.onclick = function() {
popup.setPosition(undefined);
closer.blur();
return false;
};
map.on('pointermove', function(evt) {
evt.preventDefault()
var feature = this.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
var info = document.getElementById('popup');
if (feature) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
tooltip.setPosition(coord);
$(element).siblings('.popover').css({ width: '250px' });
$(element).siblings('.popover').css({ background: '#aaa' });
$(info).popover({
'placement': 'auto',
'html': true,
'content': feature.get('name')
});
$(info).popover('show');
} else {
// TODO : some warning with firebug here
$(info).popover('destroy');
$('.popover').remove();
}
};
map.on('pointermove', function(evt) {
map.getTargetElement().style.cursor = feature ? 'pointer' : '';
if (evt.dragging) {
popup.setPosition(undefined);
tooltip.setPosition(undefined);
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
displayFeatureInfo(pixel);
});
map.on('click', function(evt) {
displayFeatureInfo(evt.pixel);
if (feature) {
var coordinate = evt.coordinate;
tipcontent.innerHTML = feature.get('name');
tooltip.setPosition(coordinate);
} else {
tooltip.setPosition(undefined);
}
});
map.on('singleclick', function(evt) {
evt.preventDefault()
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if (feature) {
var coordinate = evt.coordinate;
var title = '<h2>' + feature.get('name') + '</h2>';
content.innerHTML = title + feature.get('data');
popup.setPosition(coordinate);
} else {
popup.setPosition(undefined);
}
});
};
"""
+36 -2
View File
@@ -233,6 +233,7 @@ class NavWebReport(Report):
self.mapservice = self.options['mapservice']
self.googleopts = self.options['googleopts']
self.googlemapkey = self.options['googlemapkey']
self.stamenopts = self.options['stamenopts']
self.reference_sort = self.options['reference_sort']
if self.use_home:
@@ -1012,6 +1013,18 @@ class NavWebReport(Report):
"""
imgs = []
# copy all screen style sheet
for css_f in CSS:
already_done = False
for css_fn in ("UsEr_", "Basic", "Mainz", "Nebraska", "Vis"):
if css_fn in css_f and not already_done:
already_done = True
fname = CSS[css_f]["filename"]
# add images for this css
imgs += CSS[css_f]["images"]
css_f = css_f.replace("UsEr_", "")
self.copy_file(fname, css_f + ".css", "css")
# copy screen style sheet
if CSS[self.css]["filename"]:
fname = CSS[self.css]["filename"]
@@ -1687,13 +1700,15 @@ class NavWebOptions(MenuReportOptions):
cright.set_help(_("The copyright to be used for the web files"))
addopt("cright", cright)
self.__css = EnumeratedListOption(('StyleSheet'), CSS["default"]["id"])
self.__css = EnumeratedListOption(('StyleSheet'),
CSS["Basic-Ash"]["id"])
for (dummy_fname, gid) in sorted(
[(CSS[key]["translation"], CSS[key]["id"])
for key in list(CSS.keys())]):
if CSS[gid]["user"]:
self.__css.add_item(CSS[gid]["id"], CSS[gid]["translation"])
self.__css.set_help(_('The stylesheet to be used for the web pages'))
self.__css.set_help(_('The default stylesheet to be used for'
' the pages'))
addopt("css", self.__css)
self.__css.connect("value-changed", self.__stylesheet_changed)
@@ -2046,6 +2061,7 @@ class NavWebOptions(MenuReportOptions):
mapopts = [
[_("OpenStreetMap"), "OpenStreetMap"],
[_("StamenMap"), "StamenMap"],
[_("Google"), "Google"]]
self.__mapservice = EnumeratedListOption(_("Map Service"),
mapopts[0][1])
@@ -2092,6 +2108,19 @@ class NavWebOptions(MenuReportOptions):
self.__googlemapkey.set_help(_("The API key used for the Google maps"))
addopt("googlemapkey", self.__googlemapkey)
stamenopts = [
(_("Toner"), "toner"),
(_("Terrain"), "terrain"),
(_("WaterColor"), "watercolor")]
self.__stamenopts = EnumeratedListOption(_("Stamen Option"),
stamenopts[0][1])
for trans, opt in stamenopts:
self.__stamenopts.add_item(opt, trans)
self.__stamenopts.set_help(
_("Select which option that you would like "
"to have for the Stamenmap Map pages..."))
addopt("stamenopts", self.__stamenopts)
self.__placemap_options()
def __add_others_options(self, menu):
@@ -2276,6 +2305,11 @@ class NavWebOptions(MenuReportOptions):
else:
self.__mapservice.set_available(False)
if mapservice_opts == "StamenMap":
self.__stamenopts.set_available(True)
else:
self.__stamenopts.set_available(False)
if family_active and mapservice_opts == "Google":
self.__googleopts.set_available(True)
else:
+180 -62
View File
@@ -52,7 +52,7 @@ import logging
#------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.lib import (ChildRefType, Date, Name, Person, EventRoleType,
EventType)
Event, EventType)
from gramps.gen.lib.date import Today
from gramps.gen.plug.report import Bibliography
from gramps.gen.plug.report import utils
@@ -74,7 +74,8 @@ from gramps.plugins.webreport.common import (get_first_letters, _KEYPERSON,
get_index_letter, add_birthdate,
primary_difference, FULLCLEAR,
_find_birth_date, _find_death_date,
MARKER_PATH, OSM_MARKERS,
MARKER_PATH, OPENLAYER,
OSM_MARKERS, STAMEN_MARKERS,
GOOGLE_MAPS, MARKERS, html_escape,
DROPMASTERS, FAMILYLINKS)
from gramps.plugins.webreport.layout import LayoutTree
@@ -120,6 +121,7 @@ class PersonPages(BasePage):
self.sort_name = None
self.googleopts = None
self.googlemapkey = None
self.stamenopts = None
self.birthorder = None
self.person = None
self.familymappages = None
@@ -455,6 +457,7 @@ class PersonPages(BasePage):
self.mapservice = self.report.options['mapservice']
self.googleopts = self.report.options['googleopts']
self.googlemapkey = self.report.options['googlemapkey']
self.stamenopts = self.report.options['stamenopts']
# decide if we will sort the birth order of siblings...
self.birthorder = self.report.options['birthorder']
@@ -623,6 +626,35 @@ class PersonPages(BasePage):
# and close the file
self.xhtml_writer(indivdetpage, output_file, sio, date)
def _create_family_tracelife(self, tracelife, placetitle,
latitude, longitude, seq_, links):
"""
creates individual family tracelife map events
@param: person -- person from database
@param: links -- used to add links in the popup html page
"""
# are we using Google?
if self.mapservice == "Google":
# are we creating Family Links?
if self.googleopts == "FamilyLinks":
tracelife += """
new google.maps.LatLng(%s, %s),""" % (latitude, longitude)
# are we creating Drop Markers or Markers?
elif self.googleopts in ["Drop", "Markers"]:
tracelife += """
['%s', %s, %s, %d, %s],""" % (placetitle.replace("'", "\\'"), latitude,
longitude, seq_, links)
# are we using OpenStreetMap, Stamen...
else:
tracelife += """
[%f, %f, \'%s\', %s],""" % (float(longitude), float(latitude),
placetitle.replace("'", "\\'"), links)
return tracelife
def __create_family_map(self, person, place_lat_long):
"""
creates individual family map page
@@ -646,7 +678,7 @@ class PersonPages(BasePage):
number_markers = len(place_lat_long)
if number_markers > 1:
for (latitude, longitude, placetitle, handle,
date, etype) in place_lat_long:
event) in place_lat_long:
xwidth.append(latitude)
yheight.append(longitude)
xwidth.sort()
@@ -686,8 +718,8 @@ class PersonPages(BasePage):
# 0 = latitude, 1 = longitude, 2 = place title,
# 3 = handle, and 4 = date, 5 = event type...
# being sorted by date, latitude, and longitude...
place_lat_long = sorted(place_lat_long, key=itemgetter(4, 0, 1))
# being sorted by place_title
place_lat_long = sorted(place_lat_long, key=itemgetter(2))
# for all plugins
# if family_detail_page
@@ -710,7 +742,7 @@ class PersonPages(BasePage):
src_js += "&key=" + self.googlemapkey
head += Html("script", type="text/javascript",
src=src_js, inline=True)
else:
else: # OpenStreetMap, Stamen...
url = self.secure_mode
url += ("maxcdn.bootstrapcdn.com/bootstrap/3.3.7/"
"css/bootstrap.min.css")
@@ -734,61 +766,113 @@ class PersonPages(BasePage):
if number_markers > 0:
tracelife = "["
seq_ = 1
seq_ = 0
for index in range(0, (number_markers - 1)):
(latitude, longitude, placetitle, handle, date,
etype) = place_lat_long[index]
old_place_title = ""
oldevent = None
links = ""
ln_str = "<a href='%s' title='%s' target='_self'>%s</a>"
for index in range(0, number_markers):
(latitude, longitude, placetitle, handle,
event) = place_lat_long[index]
# Do we have several events for this place?
if placetitle == old_place_title:
evthdle = event.get_handle()
bkref_list = self.report.bkref_dict[Event][evthdle]
url_fct = self.report.build_url_fname_html
if bkref_list:
for ref in bkref_list:
(bkref_class, bkref_hdle, role) = ref
if role == "Primary":
url = url_fct(bkref_hdle,
"ppl", self.uplink)
ppl_fct = self.r_db.get_person_from_handle
person = ppl_fct(bkref_hdle)
ppl_lnk = ln_str % (url,
person.get_gramps_id(),
self.get_name(person))
url = self.report.build_url_fname_html(event.get_handle(),
"evt", self.uplink)
evt_type = self._(str(event.get_type()))
evt_date = self.rlocale.get_date(event.get_date_object())
evt_lnk = ln_str % (url, evt_date, evt_type)
# are we using Google?
if self.mapservice == "Google":
links += ' + "</br>%s"' % (ppl_lnk + self._(":") + evt_lnk)
if index == number_markers - 1:
tracelife = self._create_family_tracelife(tracelife,
placetitle,
latitude,
longitude,
seq_,
links)
break
continue
elif old_place_title != "" and index != 0:
(lat, lng, plcetitle, handle_,
event_) = place_lat_long[index-1]
tracelife = self._create_family_tracelife(tracelife,
plcetitle,
lat,
lng,
seq_,
links)
if old_place_title != placetitle:
old_place_title = placetitle
evthdle = event.get_handle()
bkref_list = self.report.bkref_dict[Event][evthdle]
url_fct = self.report.build_url_fname_html
if bkref_list:
for ref in bkref_list:
(bkref_class, bkref_hdle, role) = ref
if role == "Primary":
url = url_fct(bkref_hdle,
"ppl", self.uplink)
ppl_fct = self.r_db.get_person_from_handle
person = ppl_fct(bkref_hdle)
ppl_lnk = ln_str % (url,
person.get_gramps_id(),
self.get_name(person))
url = self.report.build_url_fname_html(event.handle,
"evt",
self.uplink)
evt_type = self._(str(event.get_type()))
evt_date = self.rlocale.get_date(event.get_date_object())
evt_lnk = ln_str % (url, evt_date, evt_type)
# are we creating Family Links?
if self.googleopts == "FamilyLinks":
tracelife += """
new google.maps.LatLng(%s, %s),""" % (latitude, longitude)
# are we creating Drop Markers or Markers?
elif self.googleopts in ["Drop", "Markers"]:
tracelife += """
['%s', %s, %s, %d],""" % (placetitle.replace("'", "\\'"), latitude,
longitude, seq_)
# are we using OpenStreetMap?
links = '"</br>%s"' % (ppl_lnk + self._(":") +
evt_lnk)
elif index == number_markers:
tracelife = self._create_family_tracelife(tracelife,
placetitle,
latitude,
longitude,
seq_,
links)
else:
tracelife += """
[%f, %f, \'%s\'],""" % (float(longitude), float(latitude),
placetitle.replace("'", "\\'"))
evthdle = event.get_handle()
bkref_list = self.report.bkref_dict[Event][evthdle]
url_fct = self.report.build_url_fname_html
if bkref_list:
for ref in bkref_list:
(bkref_class, bkref_hdle, role) = ref
if role == "Primary":
url = url_fct(bkref_hdle,
"ppl", self.uplink)
ppl_fct = self.r_db.get_person_from_handle
person = ppl_fct(bkref_hdle)
ppl_lnk = ln_str % (url,
person.get_gramps_id(),
self.get_name(person))
url = self.report.build_url_fname_html(event.handle,
"evt",
self.uplink)
evt_type = self._(str(event.get_type()))
evt_lnk = ln_str % (url, evt_type, evt_type)
links = '"<p>%s"' % (ppl_lnk + self._(":") + evt_lnk)
old_place_title = placetitle
seq_ += 1
# FIXME: The last element in the place_lat_long list is treated
# specially, and the code above is apparently repeated so as to
# avoid a comma at the end, and get the right closing. This is very
# ugly.
(latitude, longitude, placetitle, handle, date,
etype) = place_lat_long[-1]
# are we using Google?
if self.mapservice == "Google":
# are we creating Family Links?
if self.googleopts == "FamilyLinks":
tracelife += """
new google.maps.LatLng(%s, %s)
];""" % (latitude, longitude)
# are we creating Drop Markers or Markers?
elif self.googleopts in ["Drop", "Markers"]:
tracelife += """
['%s', %s, %s, %d]
];""" % (placetitle.replace("'", "\\'"), latitude, longitude, seq_)
# are we using OpenStreetMap?
elif self.mapservice == "OpenStreetMap":
tracelife += """
[%f, %f, \'%s\']
];""" % (float(longitude), float(latitude), placetitle.replace("'", "\\'"))
tracelife += "];"
# begin MapDetail division...
with Html("div", class_="content", id="FamilyMapDetail") as mapdetail:
outerwrapper += mapdetail
@@ -858,8 +942,8 @@ class PersonPages(BasePage):
jsc += MARKERS % (tracelife, midx_, midy_,
zoomlevel)
# we are using OpenStreetMap...
else:
# we are using OpenStreetMap
elif self.mapservice == "OpenStreetMap":
if midy_ is None:
jsc += OSM_MARKERS % (tracelife,
longitude,
@@ -867,6 +951,23 @@ class PersonPages(BasePage):
else:
jsc += OSM_MARKERS % (tracelife, midy_, midx_,
zoomlevel)
jsc += OPENLAYER
# we are using StamenMap
elif self.mapservice == "StamenMap":
if midy_ is None:
jsc += STAMEN_MARKERS % (tracelife,
self.stamenopts,
longitude,
latitude,
10,
)
else:
jsc += STAMEN_MARKERS % (tracelife,
self.stamenopts,
midy_, midx_,
zoomlevel,
)
jsc += OPENLAYER
# if Google and Drop Markers are selected,
# then add "Drop Markers" button?
@@ -875,8 +976,20 @@ class PersonPages(BasePage):
id="drop", onclick="drop()", inline=True)
# add div for popups.
with Html("div", id="popup", inline=True) as popup:
mapdetail += popup
if self.mapservice == "Google":
with Html("div", id="popup", inline=True) as popup:
mapdetail += popup
else:
with Html("div", id="popup", class_="ol-popup",
inline=True) as popup:
mapdetail += popup
popup += Html("a", href="#", id="popup-closer",
class_="ol-popup-closer")
popup += Html("div", id="popup-content")
with Html("div", id="tooltip", class_="ol-popup",
inline=True) as tooltip:
mapdetail += tooltip
tooltip += Html("div", id="tooltip-content")
# begin place reference section and its table...
with Html("div", class_="subsection", id="references") as section:
@@ -904,11 +1017,16 @@ class PersonPages(BasePage):
tbody = Html("tbody")
table += tbody
for (latitude, longitude, placetitle, handle, date,
etype) in place_lat_long:
# being sorted by date
place_lat_long = sorted(place_lat_long,
key=lambda evt:
evt[4].get_date_object())
for (latitude, longitude, placetitle, handle,
event) in place_lat_long:
trow = Html("tr")
tbody += trow
date = event.get_date_object()
trow.extend(
Html("td", data, class_=colclass, inline=True)
for data, colclass in [
@@ -916,7 +1034,7 @@ class PersonPages(BasePage):
(self.place_link(handle, placetitle,
uplink=True),
"ColumnPlace"),
(self._(str(etype)), "ColumnType")
(self._(str(event.get_type())), "ColumnType")
]
)
+20 -10
View File
@@ -63,8 +63,10 @@ from gramps.plugins.webreport.common import (get_first_letters, first_letter,
alphabet_navigation, GOOGLE_MAPS,
primary_difference, _KEYPLACE,
get_index_letter, FULLCLEAR,
MARKER_PATH, OSM_MARKERS, MARKERS,
html_escape, sort_places)
MARKER_PATH, OPENLAYER,
OSM_MARKERS, STAMEN_MARKERS,
MARKERS, html_escape,
sort_places)
_ = glocale.translation.sgettext
LOG = logging.getLogger(".NarrativeWeb")
@@ -304,6 +306,7 @@ class PlacePages(BasePage):
self.placemappages = self.report.options['placemappages']
self.mapservice = self.report.options['mapservice']
self.googlemapkey = self.report.options['googlemapkey']
self.stamenopts = self.report.options['stamenopts']
# begin PlaceDetail Division
with Html("div", class_="content", id="PlaceDetail") as placedetail:
@@ -373,7 +376,7 @@ class PlacePages(BasePage):
src_js += "&key=" + self.googlemapkey
head += Html("script", type="text/javascript",
src=src_js, inline=True)
else:
else: # OpenStreetMap, Stamen...
url = self.secure_mode
url += ("maxcdn.bootstrapcdn.com/bootstrap/3.3.7/"
"css/bootstrap.min.css")
@@ -416,22 +419,29 @@ class PlacePages(BasePage):
jsc += MARKERS % ([[plce,
latitude,
longitude,
1]],
1,""]],
latitude, longitude,
10)
else:
# OpenStreetMap (OSM) adds Longitude/ Latitude
# to its maps, and needs a country code in
# lowercase letters...
elif self.mapservice == "OpenStreetMap":
with Html("script", type="text/javascript") as jsc:
canvas += jsc
#param1 = xml_lang()[3:5].lower()
jsc += MARKER_PATH % marker_path
jsc += OSM_MARKERS % ([[float(longitude),
float(latitude),
placetitle]],
placetitle,""]],
longitude, latitude, 10)
jsc += OPENLAYER
else: # STAMEN
with Html("script", type="text/javascript") as jsc:
canvas += jsc
jsc += MARKER_PATH % marker_path
jsc += STAMEN_MARKERS % ([[float(longitude),
float(latitude),
placetitle,""]],
self.stamenopts,
longitude, latitude, 10)
jsc += OPENLAYER
# add javascript function call to body element
body.attr += ' onload = "initialize();" '
+59 -10
View File
@@ -348,6 +348,20 @@ class WebCalReport(Report):
"""
Copies all the necessary stylesheets and images for these calendars
"""
imgs = []
# copy all screen style sheet
for css_f in CSS:
already_done = False
for css_fn in ("UsEr_", "Basic", "Mainz", "Nebraska", "Vis"):
if css_fn in css_f and not already_done:
already_done = True
fname = CSS[css_f]["filename"]
# add images for this css
imgs += CSS[css_f]["images"]
css_f = css_f.replace("UsEr_", "")
self.copy_file(fname, css_f + ".css", "css")
# Copy the screen stylesheet
if self.css and self.css != 'No style sheet':
fname = CSS[self.css]["filename"]
@@ -364,8 +378,6 @@ class WebCalReport(Report):
fname = CSS["Print-Default"]["filename"]
self.copy_file(fname, _CALENDARPRINT, "css")
imgs = []
# Mainz stylesheet graphics
# will only be used if Mainz is slected as the stylesheet
imgs += CSS[self.css]["images"]
@@ -457,7 +469,20 @@ class WebCalReport(Report):
links = Html("link", rel='shortcut icon',
href=fname1, type="image/x-icon") + (
Html("link", href=fname2, type="text/css",
title=self._("Default"),
media="screen", rel="stylesheet", indent=False))
# create all alternate stylesheets
# Cannot use it on local files (file://)
for css_f in CSS:
already_done = False
for css_fn in ("UsEr_", "Basic", "Mainz", "Nebraska"):
if css_fn in css_f and not already_done:
css_f = css_f.replace("UsEr_", "")
fname = "/".join(subdirs + ["css", css_f + ".css"])
links += Html("link", rel="alternate stylesheet",
title=css_f, indent=False,
media="screen", type="text/css",
href=fname)
# add horizontal menu if css == Blue or Visually because
# there is no menus?
@@ -1391,9 +1416,6 @@ class WebCalReport(Report):
text = short_name
self.add_day_item(text, year, month, day, 'Death',
age_at_death, death_date)
#print('Death date for %s %s/%s/%s' % (short_name, day,
# month, year),
# age_at_death)
# add anniversary if requested
if self.anniv:
@@ -1449,6 +1471,18 @@ class WebCalReport(Report):
wedding_age = first_died - event_date
wedding_age = wedding_age.format(
dlocale=self.rlocale)
divorce_event = get_divorce_event(db, fam)
if divorce_event:
d_date = divorce_event.get_date_object()
if (d_date is not Date() and
d_date.is_valid()):
d_date = gregorian(d_date)
if d_date != Date():
w_age = d_date - event_date
w_age = w_age.format(
dlocale=self.rlocale)
wedding_age = w_age
first_died = d_date
if self.link_to_narweb:
prefx = self.narweb_prefix
@@ -1468,8 +1502,8 @@ class WebCalReport(Report):
prob_alive_date)
if first_died == Date():
first_died = Date(0, 0, 0)
if ((self.alive and alive1
and alive2) or not self.alive):
if ((self.alive and (alive1 or alive2))
or not self.alive):
spse = self._('%(spouse)s and'
' %(person)s')
@@ -1991,14 +2025,29 @@ def get_marriage_event(db, family):
for event_ref in family.get_event_ref_list():
event = db.get_event_from_handle(event_ref.ref)
if event.type.is_marriage:
if event.type.is_marriage():
marriage_event = event
elif event.type.is_divorce:
continue
break
# return the marriage event or False to it caller
return marriage_event
def get_divorce_event(db, family):
"""
divorce will either be the divorce event or False
"""
divorce_event = False
for event_ref in family.get_event_ref_list():
event = db.get_event_from_handle(event_ref.ref)
if event.type.is_divorce():
divorce_event = event
break
# return the divorce event or False to it caller
return divorce_event
def get_first_day_of_month(year, month):
"""
Compute the first day to display for this month.
+65 -41
View File
@@ -23,6 +23,7 @@
# python modules
#------------------------------------------------
import os
import re
from gramps.gen.const import VERSION_DIR, IMAGE_DIR, DATA_DIR, USER_CSS
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
@@ -57,125 +58,148 @@ def load_on_reg(dbstate, uistate, plugin):
# default style sheet in the options
# Basic Ash style sheet
["default", 1, _("Basic-Ash"),
path_css('Web_Basic-Ash.css'), None, [], [] ],
["Basic-Ash", 1, _("Basic-Ash"),
path_css('Web_Basic-Ash.css'), None, [], []],
# Basic Blue style sheet with navigation menus
["Basic-Blue", 1, _("Basic-Blue"),
path_css('Web_Basic-Blue.css'), None, [], [] ],
["Basic-Blue", 1, _("Basic-Blue"),
path_css('Web_Basic-Blue.css'), None, [], []],
# Basic Cypress style sheet
["Basic-Cypress", 1, _("Basic-Cypress"),
path_css('Web_Basic-Cypress.css'), None, [], [] ],
path_css('Web_Basic-Cypress.css'), None, [], []],
# basic Lilac style sheet
["Basic-Lilac", 1, _("Basic-Lilac"),
path_css('Web_Basic-Lilac.css'), None, [], [] ],
["Basic-Lilac", 1, _("Basic-Lilac"),
path_css('Web_Basic-Lilac.css'), None, [], []],
# basic Peach style sheet
["Basic-Peach", 1, _("Basic-Peach"),
path_css('Web_Basic-Peach.css'), None, [], [] ],
["Basic-Peach", 1, _("Basic-Peach"),
path_css('Web_Basic-Peach.css'), None, [], []],
# basic Spruce style sheet
["Basic-Spruce", 1, _("Basic-Spruce"),
path_css('Web_Basic-Spruce.css'), None, [], [] ],
["Basic-Spruce", 1, _("Basic-Spruce"),
path_css('Web_Basic-Spruce.css'), None, [], []],
# Mainz style sheet with its images
["Mainz", 1, _("Mainz"),
path_css('Web_Mainz.css'), None,
["Mainz", 1, _("Mainz"),
path_css('Web_Mainz.css'), None,
[path_img("Web_Mainz_Bkgd.png"),
path_img("Web_Mainz_Header.png"),
path_img("Web_Mainz_Mid.png"),
path_img("Web_Mainz_MidLight.png")], [] ],
path_img("Web_Mainz_MidLight.png")], []],
# Nebraska style sheet
["Nebraska", 1, _("Nebraska"),
path_css('Web_Nebraska.css'), None, [], [] ],
["Nebraska", 1, _("Nebraska"),
path_css('Web_Nebraska.css'), None, [], []],
# Visually Impaired style sheet with its navigation menus
["Visually Impaired", 1, _("Visually Impaired"),
path_css('Web_Visually.css'), "narrative-menus.css", [], [] ],
path_css('Web_Visually.css'), "narrative-menus.css", [], []],
# ancestor tree style sheet and its images
["ancestortree", 0, "ancestortree",
["ancestortree", 0, "ancestortree",
path_css("ancestortree.css"), None,
[path_img("Web_Gender_Female.png"),
path_img("Web_Gender_Male.png")], [] ],
path_img("Web_Gender_Male.png")], []],
# media reference regions style sheet
["behaviour", 0, "Behaviour",
path_css('behaviour.css'), None, [], [] ],
["behaviour", 0, "Behaviour",
path_css('behaviour.css'), None, [], []],
# NarrativeMap stylesheet/ image for NarrativeWeb place maps
["NarrativeMaps", 0, "",
path_css("narrative-maps.css"), None, [], [] ],
["NarrativeMaps", 0, "",
path_css("narrative-maps.css"), None, [], []],
# default printer style sheet
["Print-Default", 0, "Print-Default",
path_css('Web_Print-Default.css'), None, [], [] ],
path_css('Web_Print-Default.css'), None, [], []],
# Horizontal Navigation Menus Style Sheet
["Horizontal-Menus", 0, "Horizontal Menus",
path_css('Web_Horizontal-Menus.css'), None, [], [] ],
path_css('Web_Horizontal-Menus.css'), None, [], []],
# Vertical Navigation Menus Style Sheet
["Vertical-Menus", 0, "Vertical Menus",
path_css('Web_Vertical-Menus.css'), None, [], [] ],
path_css('Web_Vertical-Menus.css'), None, [], []],
# WebKit/ Html5/ CSS3 Fade Navigation Menus Style Sheet
["Fade-Menus", 0, "Fade In/ Out Menus",
path_css('Web_Fade-Menus.css'), None, [], [] ],
path_css('Web_Fade-Menus.css'), None, [], []],
# WebKit/ Html5/ CSS3 Animated Drop Down Style Sheet
["Animated DropDown", 0, "Animated DropDown",
path_css("Web_Citations-Animated.css"), None, [],
"https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" ],
"https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"],
# Source Page Citations Referents Outline Style sheet...
["Outline", 0, "Outline Citations",
path_css("Web_Citations-Outline.css"), None, [], [] ],
path_css("Web_Citations-Outline.css"), None, [], []],
# WebKit/ Html5/ CSS3 Drop Down Navigation Menus Style Sheet
["DropDown-Menus", 0, "Drop Down Menus",
path_css("Web_DropDown-Menus.css"), None, [], [] ],
path_css("Web_DropDown-Menus.css"), None, [], []],
# no style sheet option
["No style sheet",1, _("No style sheet"), [], None, [], [] ],
["No style sheet", 1, _("No style sheet"), [], None, [], []],
# Document image
["Document", 0, "Document",
os.path.join(IMAGE_DIR, "document.png"), None, [], [] ],
os.path.join(IMAGE_DIR, "document.png"), None, [], []],
# blank
["Blank", 0, "Blank",
path_img("blank.gif"), None, [], [] ],
path_img("blank.gif"), None, [], []],
# all other images for use in NarrativeWeb
['All Images', 0, 'All Images', None, None,
[path_img("blank.gif"),
os.path.join(IMAGE_DIR, "document.png")], [] ],
os.path.join(IMAGE_DIR, "document.png")], []],
# Gramps Fav icon #2
["favicon2", 0, "FavIcon2",
path_img("favicon2.ico"), None, [], [] ],
path_img("favicon2.ico"), None, [], []],
# copyright image
['Copyright', 0, 'Copyright',
path_img("somerights20.gif"), None, [], [] ],
path_img("somerights20.gif"), None, [], []],
# marker icon for openstreetmap
['marker', 0, 'marker',
path_img_48x48("gramps-geo-mainmap.png"), None, [], [] ],
path_img_48x48("gramps-geo-mainmap.png"), None, [], []],
]
# If we add css user files, we must restart gramps to use them.
if os.path.exists(USER_CSS):
list_files = os.listdir(USER_CSS)
for cssfile in list_files:
CSS_FILES.append([cssfile, 1, cssfile.replace('.css', ''),
os.path.join(USER_CSS,cssfile),
None, [], [] ])
if cssfile.endswith(".css"):
css_f = cssfile.replace('.css', '')
CSS_FILES.append(["UsEr_" + css_f, 1, css_f,
os.path.join(USER_CSS, cssfile), None,
looking_for_urls_in_user_css(cssfile),
[]])
return CSS_FILES
def looking_for_urls_in_user_css(css_file):
"""
At each time we find the tag url, we get the content and add it
to the images list. This content must be local.
"""
images = []
cssfile = os.path.join(USER_CSS, css_file)
with open(cssfile) as css:
data = css.readlines()
for line in data:
if "url" in line:
url = re.match(r".*url\((.*)\)", line)
if url.group(1)[0:3] != "http":
img = url.group(1).replace("../images/", "")
img = os.path.join(USER_CSS, img)
if img not in images:
images.append('%s' % img)
return images
def process_list(data):
"""
Gather all of the web resources together, and allow override files
@@ -185,7 +209,7 @@ def process_list(data):
for row in data:
file = row[3]
if file:
path, filename = os.path.split(file)
dummy_path, filename = os.path.split(file)
# is there a override file in the VERSION_DIR/webstuff?
# eg, ~/.gramps/gramps34/webstuff/Web_Nebraska.css
# if so, replace this one:
+4
View File
@@ -48,6 +48,7 @@ gramps/gen/filters/rules/_rule.py
gramps/gen/filters/rules/citation/_allcitations.py
gramps/gen/filters/rules/citation/_changedsince.py
gramps/gen/filters/rules/citation/_citationprivate.py
gramps/gen/filters/rules/citation/_hasattribute.py
gramps/gen/filters/rules/citation/_hascitation.py
gramps/gen/filters/rules/citation/_hasgallery.py
gramps/gen/filters/rules/citation/_hasidof.py
@@ -157,6 +158,7 @@ gramps/gen/filters/rules/person/_disconnected.py
gramps/gen/filters/rules/person/_everyone.py
gramps/gen/filters/rules/person/_familywithincompleteevent.py
gramps/gen/filters/rules/person/_hasaddress.py
gramps/gen/filters/rules/person/_hasaddresstext.py
gramps/gen/filters/rules/person/_hasalternatename.py
gramps/gen/filters/rules/person/_hasassociation.py
gramps/gen/filters/rules/person/_hasattribute.py
@@ -255,6 +257,7 @@ gramps/gen/filters/rules/place/_regexpidof.py
gramps/gen/filters/rules/place/_withinarea.py
gramps/gen/filters/rules/repository/_allrepos.py
gramps/gen/filters/rules/repository/_changedsince.py
gramps/gen/filters/rules/repository/_hasattribute.py
gramps/gen/filters/rules/repository/_hasidof.py
gramps/gen/filters/rules/repository/_hasnotematchingsubstringof.py
gramps/gen/filters/rules/repository/_hasnoteregexp.py
@@ -267,6 +270,7 @@ gramps/gen/filters/rules/repository/_regexpidof.py
gramps/gen/filters/rules/repository/_repoprivate.py
gramps/gen/filters/rules/source/_allsources.py
gramps/gen/filters/rules/source/_changedsince.py
gramps/gen/filters/rules/source/_hasattribute.py
gramps/gen/filters/rules/source/_hasgallery.py
gramps/gen/filters/rules/source/_hasidof.py
gramps/gen/filters/rules/source/_hasnote.py
+1954 -2173
View File
File diff suppressed because it is too large Load Diff