Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a94f3100df | |||
| 5d341a684e | |||
| 26723c1b60 | |||
| de7430eeb8 | |||
| 89ffc6b4cc | |||
| a18120f17d | |||
| 2846fc7dc5 | |||
| e6c5232ae8 | |||
| e7ab8b322b | |||
| fde34bb53b | |||
| 60c0843861 | |||
| 2ae2ca5c7d | |||
| 9747d1deea | |||
| e52d0a7a90 | |||
| eefd3e13e4 | |||
| 918317434f | |||
| 8dfc5381cd | |||
| 6511a80b47 | |||
| a5074e9478 | |||
| b90808525c | |||
| fedfabc87e | |||
| 891b9d2e34 | |||
| 3b0579afc3 | |||
| 5e763026a4 | |||
| de706de317 | |||
| b884dc0e4c | |||
| aaba2ec347 | |||
| bdd44b57fd | |||
| 8deb444a6c | |||
| ca3158a6ff | |||
| 53a9cfc83f | |||
| 92fc8f8dcb | |||
| 7a488c2fd4 | |||
| 98ff7693f3 | |||
| 6b7258dfe0 | |||
| aceee07544 | |||
| 9e670d51bd | |||
| 8e97b25f38 | |||
| 6aeeafe74d | |||
| 4189799d45 | |||
| 5bfe514f45 | |||
| aa35dbfb82 | |||
| 784ab0c3c7 | |||
| 5847bb0e17 | |||
| 08ac0b0996 | |||
| c38ccf22ed | |||
| 1866b7ace1 | |||
| 27b7676caa | |||
| c273926941 | |||
| ba8392923a |
+1
-1
@@ -8,7 +8,7 @@ language: c
|
||||
# - 3.4
|
||||
|
||||
install:
|
||||
- git clone --depth=50 --branch=master git://github.com/gramps-project/gramps.git gramps-project/gramps
|
||||
- git clone --depth=50 --branch=maintenance/gramps42 git://github.com/gramps-project/gramps.git gramps-project/gramps
|
||||
- cd gramps-project/gramps
|
||||
- time sudo apt-get update
|
||||
- travis_retry sudo apt-get install gir1.2-pango gir1.2-gtk xdg-utils librsvg2-common libglib2.0-dev intltool
|
||||
|
||||
@@ -91,12 +91,6 @@ alternative location on windows, supply the --root argument to setup.py
|
||||
|
||||
For example:
|
||||
python setup.py install --root ~/test
|
||||
or
|
||||
python setup.py install --root ~/test --enable-packager-mode
|
||||
|
||||
The last option, --enable-packager-mode, is needed if you want to disable
|
||||
execution of post-install mime processing. If you don't have root/admin
|
||||
access, this will be needed
|
||||
|
||||
Packager's issues
|
||||
------------------
|
||||
@@ -104,3 +98,9 @@ There is a MANIFEST.in file to indicate the work needed.
|
||||
To create a source distribution run:
|
||||
|
||||
python setup.py sdist
|
||||
|
||||
If Gramps is built outside of the source tree in a temporary location (e.g. when
|
||||
packaging for a distribution), the --resourcepath option can be used to specify
|
||||
the path to the installed location of the Gramps resources (e.g. /usr/share):
|
||||
|
||||
python setup.py install --resourcepath=/usr/share
|
||||
|
||||
@@ -1,3 +1,189 @@
|
||||
2015-05-01
|
||||
Version 4.1.3, "Thou shalt not count to five", a maintenance release.
|
||||
* Fix db upgrade failure
|
||||
* GtkDialog mapped without a transient parent
|
||||
* [Gedcom} SUBN and SUBM record handling
|
||||
* [Gedcom] Import/export round trip causes lost information
|
||||
* [Gedcom] Entering a witness to an event such as marriage might be ignored
|
||||
* [Gedcom] Gramps can't import estim. date period exported by itself
|
||||
* [Gedcom] 1/4 and 1/2 ANSEL characters not supported on importing ANSEL
|
||||
* [Gedcom] Importing file containing multibyte UTF-8 characters fails
|
||||
* [Gedcom] Import fails for ANSI file under python 3
|
||||
* [Gedcom] Failure importing ANSEL encoded gedcom file.
|
||||
* [Gedcom] Characters ignored on a Gedcom encoded ANSI (cp1252 West Europe, USA)
|
||||
* [Gedcom] NameError in importer
|
||||
* [Gedcom] Event address is lost on import, i.e. disconnected from event
|
||||
* Crash on geneweb export with python3
|
||||
* GuiColorOption missing avail-changed event handler
|
||||
* Bad generation of [timeline report] ODT files since 4.0.0
|
||||
* Fix bad handle in explanation note for unknown event
|
||||
* Fix spurious generation of empty 'Alternative Name' in place.merge()
|
||||
* Support creating directories in various scenarios
|
||||
* Attempting to add a bookmark causes an error
|
||||
* Long series of "unhandled exception" popup boxes while doing a check & repair
|
||||
* Crash when trying to link existing place as an enclosing place using P0001 number
|
||||
* HTML view fails to load
|
||||
* Relationship Graph crashes
|
||||
* Python3 needs new_subpixbuf not subpixbuf
|
||||
* Regression: running gramps from crontab fails
|
||||
* tag_map is not initialized
|
||||
* Some labels now fit better on citations sidebar filter
|
||||
* Event columns in web narrative are too narrow
|
||||
* Problem by start program (launcher)
|
||||
* Translation string missing in Not Related tool for help and close button
|
||||
* Date format month/year is not well reported at editing time [in Italian]
|
||||
* Fix unknown gender relationships handler for the french locale
|
||||
* Fix a handle type bug on sidebar filter
|
||||
* Tidy up About dialog
|
||||
* Cleanup on some man files
|
||||
* Convert some remaining unicode literals
|
||||
* Fix mac menubar setting
|
||||
* Enable python3 to run po/update_po.py
|
||||
* Updated translations: cs, de, fr, is, nl
|
||||
|
||||
2015-02-28
|
||||
Version 4.1.2, "That's no ordinary rabbit", a maintenance release.
|
||||
* Error converting python2 utf-8 strings to python3 str when loading data from database
|
||||
* Removing a parent place from a place leaves a dangling reference
|
||||
* Error during checking the database
|
||||
* Stubborn blank space in database won't be removed, fix removing rows in flat list views
|
||||
* Database upgrade fails if default media path is not set
|
||||
* Error converting database after upgrade to Gramps 4.1.1
|
||||
* Error in a single place within the places section
|
||||
* Entries from the add-or-choose selector of Place/Source/Media/Note cannot be dragged
|
||||
* Enclosing places tab should work like other similar tabs, new place reference editor
|
||||
* Association editor refuses dropped persons
|
||||
* Error on opening twice an object from clipboard
|
||||
* Incorrect spacing in export assistant file chooser
|
||||
* New Event types are saved as a disordered list
|
||||
* Always display main participants
|
||||
* Place titles can now be generated on-the-fly by a place displayer, default is still to use the place title field
|
||||
* GEDCOM import of embedded notes attached to media does not work
|
||||
* Crash on Ancestry.com .ged import; consistent.
|
||||
* Errors handling owner/submitter information in GEDCOM files.
|
||||
Only import researcher from GEDCOM or XML if the family tree was originally empty.
|
||||
* GEDCOM export does not export media attached to citations.
|
||||
* The fanchart view crashes if max generation is set to 1 away.
|
||||
* Sidebar Filters do not match placetypes in new placeview, two new filter rules (HasTitle, HasData)
|
||||
* Fix bug when family has no parents
|
||||
* Fix bad handle in explanation note for unknown event
|
||||
* Some labels now fit better on citations sidebar filter
|
||||
* Views in Geography should not always use the last option set by the user
|
||||
* Request for keyboard-controlled zoom on Geography view
|
||||
* Error geography view - Displaying main menu
|
||||
* Configure screen needs a file selector to select directory for "offline mode" files
|
||||
* Filter panel on geography view displays improperly
|
||||
* Detailed descendant report crashes, bibliography (citations)
|
||||
* Can't disable box shadow in SVG descendant tree
|
||||
* Descendant tree graphical report, syntax error in svg output
|
||||
* Regression: Complete Individual report has partially-untranslated output
|
||||
* Events Page in Narrative Report not working
|
||||
* Gramps freeze after defining a report style with German cm values
|
||||
* Various problems with docgen.TextDoc.add_media_object
|
||||
* Report event attribute name is not translated
|
||||
* Records Gramplet uses wrong text
|
||||
* Closing detached gramplet causes python to crash
|
||||
* Cannot reduce size of gramplets detached from a gramplet bar
|
||||
* Gramplets don't fill window when detached from dashboard
|
||||
* ImageMetadata doesn't show metadata
|
||||
* typo on GLib call, used by an addon only
|
||||
* Fix error setting gramplet tab label
|
||||
* Check for active person in session log gramplet
|
||||
* Spurious spaces in CLI List Family Trees, tab delimited output.
|
||||
Print statements changed to assemble the whole line before output.
|
||||
* Gtk3 warning and custom undoableentry widget, see bugzilla_id 644927
|
||||
* Warnings: deprecated Gtk properties and errors loading theme icon.
|
||||
Fix: database manager dialog is inconsistent for older gtk+3 versions.
|
||||
Warnings: deprecated Gtk properties and errors loading theme icon.
|
||||
Fix: Error loading theme icon 'gtk-apply'
|
||||
* gramps fails to start with gtk+-3.13.3
|
||||
* Places in data.gramps are not in the new Place hierarchy
|
||||
* Upgrade the version of some dependencies for Mac OS and Windows OS.
|
||||
* Keywords entry in gramps.desktop does not work
|
||||
* 'Available Gramps Updates for Addons' window not on top
|
||||
* Some text not translatable in context menu fancharts
|
||||
* Fix for Unit test
|
||||
* date inflections in _datehandler.py, update for Ukrainian, Russian, Croatian
|
||||
* Better support for Serbian and Turkish locales
|
||||
* New translation: Icelandic
|
||||
* Re-enable Turkish support after a major review. Thank you Uğur.
|
||||
* Updated translations: cs, de, eo, fi, fr, hr, hu, it, nb, nn, ru, sk, sr, sv, uk, zh_CN
|
||||
|
||||
2014-10-24
|
||||
Version 4.1.1, "MachineThatGoes...Ping!", a maintenance release.
|
||||
* Fix custom place types in the place editor
|
||||
* Allow place type combobox to receive focus.
|
||||
* Store custom place types in the metadata table
|
||||
* Fix place type for places without a main location
|
||||
* Fix bug adding parent places to a new place
|
||||
* Prevent user creating a cycle in the place hierarchy
|
||||
* Avoid infinite loop when place cycle encountered
|
||||
* Prevent creation of a place cycle when merging
|
||||
* Fix error when no place is selected
|
||||
* Check that a place has been selected when saving.
|
||||
* Use the standard place selection widget to be consistent.
|
||||
* Add a new Top Level place through the Place Reference Editor
|
||||
* Fix backlinks code in place report
|
||||
* Backlinks for places can now also be places as well as events.
|
||||
* Fix check and repair tool for empty placerefs
|
||||
* Update location utilities to work with proxies
|
||||
* Place report does not run
|
||||
* Update place details gramplet
|
||||
* Locations are now displayed in a new separate gramplet.
|
||||
* Add check for empty handle in gramplets
|
||||
* Check DB lock on the recent opened trees list
|
||||
* Sidebarfilter gramplet does not fit well into People, Events or Media views
|
||||
* Fix new event default type considering existing events with *default* role
|
||||
* Rebuild secondary indexes after database upgrade
|
||||
* Importing gedcom files containing multibyte UTF-8 characters fails
|
||||
* Ahnentafel Report did not use Christening Date if no Birth Date
|
||||
* [Narweb:] Missing webpage for media under some circumstances
|
||||
* Fix narrated web report with gendex option enabled
|
||||
* Tweak to "default" CSS choice for the narrated web report
|
||||
* Invalid link for Merge citation Help button
|
||||
* Fix 'todo' gramplet
|
||||
* Fix path when using drag & drop to add media
|
||||
* Limit the number of generations displayed in the ancestor gramplet
|
||||
* Export of a subset of the tree failed
|
||||
* Fix issues in python3, and bytes-string mismatch with ICU
|
||||
* Fix url/uri handling with non-ascii characters under linux and mac
|
||||
* Fix name format on graphical reports
|
||||
* Fix name format on textual reports
|
||||
* Better GUI support for embeded custom attributes list on media object
|
||||
* Better keys for search under linux shells (.desktop file)
|
||||
* 'Unknown' person in detailed ancestor report can not be translated
|
||||
* Translations don't show in many labels
|
||||
* Ensure python text domain gets the right encoding.
|
||||
* Translate some punctuation marks
|
||||
* Various fixes around Geography and osmgpsmap
|
||||
* Allow gramplets to be displayed in the dashboard only
|
||||
* Update FSF address
|
||||
* Add Arabic-script, Islamic-date, Thai script, Married Name and more dates examples
|
||||
* Fix on czech date handler for calculated and estimated dates
|
||||
* Enhance Serbian date handler to handle Cyrillic dates
|
||||
* Simplify Canadian Ash Wednesday holiday
|
||||
* Re-enable Esperanto support (for non-Windows OS only) after a large review
|
||||
* New translation: Serbian
|
||||
* Various fixes in German and Czech
|
||||
* Updated translations: ar, cs, de, fi, fr, it, sv
|
||||
|
||||
2014-06-15
|
||||
Version 4.1.0, the "Name go in book", new major release.
|
||||
* GEP 006: Better Place handling
|
||||
* New Tags support on Event, Place, Repository, Source, and Citation
|
||||
* Source/Citation Data becomes Attributes
|
||||
* Add optional support for checksum on Media object
|
||||
* New place hierarchies model
|
||||
* By default, you can choose navigator modes with a drop down.
|
||||
* New Place editor
|
||||
* Enhanced MediaReference Editor
|
||||
* Some debug tools move to new gramplets
|
||||
* Full Python 3 support
|
||||
* New functions and widgets related to Place and Media selections
|
||||
* Enhancements on to_struct()
|
||||
* New methods on Date handlers
|
||||
* Better support on translation for inflection rules
|
||||
|
||||
2014-05-22
|
||||
Version 4.0.4, "Not the comfy chair", a maintenance release.
|
||||
* Upgrade to db version 17 fails in Python 3 due to use of iteritems
|
||||
|
||||
Vendored
+2
-1
@@ -17,13 +17,14 @@ Vcs-browser: http://anonscm.debian.org/gitweb/?p=collab-maint/gramps.git
|
||||
Homepage: http://www.gramps-project.org/
|
||||
X-Python-Version: >= 3.0
|
||||
|
||||
Package: python-gramps
|
||||
Package: python3-gramps
|
||||
Architecture: all
|
||||
Depends:
|
||||
gir1.2-gtk-3.0,
|
||||
librsvg2-2,
|
||||
python3-gi,
|
||||
python3-gi-cairo,
|
||||
python3-bsddb3,
|
||||
xdg-utils,
|
||||
${misc:Depends},
|
||||
${python:Depends}
|
||||
|
||||
Vendored
+3
-3
@@ -12,7 +12,7 @@ override_dh_auto_test:
|
||||
|
||||
# Override of auto_build
|
||||
override_dh_auto_build:
|
||||
python3 setup.py build
|
||||
python3 setup.py build --resourcepath=/usr/share
|
||||
|
||||
# Override of auto_install to remove information from package
|
||||
override_dh_auto_install:
|
||||
@@ -29,8 +29,8 @@ override_dh_auto_install:
|
||||
override_dh_fixperms:
|
||||
dh_fixperms
|
||||
chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/css/Web_*.css
|
||||
chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/images/22x22/gramps*.png
|
||||
chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/images/16x16/gramps*.png
|
||||
#chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/images/hicolor/22x22/actions/gramps*.png
|
||||
#chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/images/hicolor/16x16/actions/gramps*.png
|
||||
|
||||
# Avoid compressing COPYING file so that it can appear in the "About" dialog
|
||||
override_dh_compress:
|
||||
|
||||
@@ -164,7 +164,7 @@ class DateParserCZ(DateParser):
|
||||
|
||||
quality_to_int = {
|
||||
'přibližně' : Date.QUAL_ESTIMATED,
|
||||
'odhadované' : Date.QUAL_ESTIMATED,
|
||||
'odhadem' : Date.QUAL_ESTIMATED,
|
||||
'odh.' : Date.QUAL_ESTIMATED,
|
||||
'vypočteno' : Date.QUAL_CALCULATED,
|
||||
'vypočtené' : Date.QUAL_CALCULATED,
|
||||
@@ -173,6 +173,8 @@ class DateParserCZ(DateParser):
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
self._text2 = re.compile('(\d+)?\.?\s+?%s\.?\s*((\d+)(/\d+)?)?\s*$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
self._span = re.compile(
|
||||
"(od)\s+(?P<start>.+)\s+(do)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
@@ -221,7 +223,9 @@ class DateDisplayCZ(DateDisplay):
|
||||
# this must agree with DateDisplayEn's "formats" definition
|
||||
# (since no locale-specific _display_gregorian exists, here)
|
||||
|
||||
def display(self, date):
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
def orig_display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
|
||||
@@ -70,25 +70,43 @@ class DateParserHR(DateParser):
|
||||
bce = ["prije nove ere", "prije Krista",
|
||||
"p.n.e."] + DateParser.bce
|
||||
|
||||
# def init_strings(self):
|
||||
# """
|
||||
# compiles regular expression strings for matching dates
|
||||
# """
|
||||
# DateParser.init_strings(self)
|
||||
# #~ DateParser.calendar_to_int.update({
|
||||
# #~ 'персидский' : Date.CAL_PERSIAN,
|
||||
# #~ 'п' : Date.CAL_PERSIAN,
|
||||
# #~ })
|
||||
# _span_1 = ['od']
|
||||
# _span_2 = ['do']
|
||||
# _range_1 = ['između']
|
||||
# _range_2 = ['i']
|
||||
# self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
# ('|'.join(_span_1), '|'.join(_span_2)),
|
||||
# re.IGNORECASE)
|
||||
# self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
# ('|'.join(_range_1), '|'.join(_range_2)),
|
||||
# re.IGNORECASE)
|
||||
|
||||
def init_strings(self):
|
||||
"""
|
||||
compiles regular expression strings for matching dates
|
||||
"""
|
||||
DateParser.init_strings(self)
|
||||
#~ DateParser.calendar_to_int.update({
|
||||
#~ 'персидский' : Date.CAL_PERSIAN,
|
||||
#~ 'п' : Date.CAL_PERSIAN,
|
||||
#~ })
|
||||
_span_1 = ['od']
|
||||
_span_2 = ['do']
|
||||
_range_1 = ['između']
|
||||
_range_2 = ['i']
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1), '|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1), '|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
# match 'Day. MONTH year.' format with or without dots
|
||||
self._text2 = re.compile('(\d+)?\.?\s*?%s\.?\s*((\d+)(/\d+)?)?\s*\.?$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
# match Day.Month.Year.
|
||||
self._numeric = re.compile(
|
||||
"((\d+)[/\. ])?\s*((\d+)[/\.])?\s*(\d+)\.?$")
|
||||
#"((\d+)[/\.]\s*)?((\d+)[/\.]\s*)?(\d+)\s*$")
|
||||
self._span = re.compile(
|
||||
"(od)\s+(?P<start>.+)\s+(do)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._jtext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?'\
|
||||
% self._jmon_str, re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -105,6 +123,38 @@ class DateDisplayHR(DateDisplay):
|
||||
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
def dd_dformat01(self, date_val):
|
||||
"""
|
||||
numerical
|
||||
"""
|
||||
if date_val[3]:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0] == date_val[1] == 0:
|
||||
return str(date_val[2]) + '.'
|
||||
else:
|
||||
value = self._tformat.replace('%m', str(date_val[1]))
|
||||
value = value.replace('%d', str(date_val[0]))
|
||||
value = value.replace('%Y', str(abs(date_val[2])))
|
||||
return value
|
||||
|
||||
def dd_dformat04(self, date_val, inflect, long_months):
|
||||
"""
|
||||
day month_name year
|
||||
"""
|
||||
year = self._slash_year(date_val[2], date_val[3])
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
return year + '.'
|
||||
else:
|
||||
return self.format_long_month_year(date_val[1], year,
|
||||
inflect, long_months)
|
||||
else:
|
||||
return "{day:d}. {long_month.f[G]} {year}.".format(
|
||||
day = date_val[0],
|
||||
long_month = long_months[date_val[1]],
|
||||
year = year)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
|
||||
@@ -186,6 +186,8 @@ except:
|
||||
'10/25/2005' : '%m/%d/%Y',
|
||||
'2005/10/25' : '%Y/%m/%d',
|
||||
'25.10.2005' : '%d.%m.%Y',
|
||||
'25.10.2005.' : '%d.%m.%Y.',
|
||||
'25. 10. 2005.' : '%d. %m. %Y.',
|
||||
'10.25.2005' : '%m.%d.%Y',
|
||||
'2005.10.25' : '%Y.%m.%d',
|
||||
}
|
||||
|
||||
@@ -722,8 +722,11 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
|
||||
# Check for pickle upgrade
|
||||
versionpath = os.path.join(self.path, str(PCKVERSFN))
|
||||
if not os.path.isfile(versionpath) and \
|
||||
not self.readonly and not self.update_pickle_version:
|
||||
# Up to gramps 3.4.x PCKVERSFN was not written
|
||||
# Gramps 4.2 incorrectly wrote PCKVERSFN = 'Yes' for Python2, so check
|
||||
# whether python is upgraded
|
||||
if ((not self.readonly and not self.update_pickle_version) and
|
||||
(not os.path.isfile(versionpath) or self.update_python_version)):
|
||||
_LOG.debug("Make backup in case there is a pickle upgrade")
|
||||
self.__make_zip_backup(name)
|
||||
self.update_pickle_version = True
|
||||
|
||||
@@ -78,22 +78,26 @@ class IsDescendantFamilyOf(Rule):
|
||||
return
|
||||
|
||||
# Add self
|
||||
self.matches.add(person.handle)
|
||||
expand = [person]
|
||||
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
if family:
|
||||
# Add every child recursively
|
||||
for child_ref in family.get_child_ref_list():
|
||||
if child_ref:
|
||||
self.add_matches(self.db.get_person_from_handle(child_ref.ref))
|
||||
|
||||
# Add spouse
|
||||
if person.handle == family.get_father_handle():
|
||||
spouse_handle = family.get_mother_handle()
|
||||
else:
|
||||
spouse_handle = family.get_father_handle()
|
||||
self.matches.add(spouse_handle)
|
||||
while expand:
|
||||
person = expand.pop(0)
|
||||
if person is None:
|
||||
continue
|
||||
self.matches.add(person.handle)
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
if family:
|
||||
# Add every child recursively
|
||||
for child_ref in family.get_child_ref_list():
|
||||
if child_ref:
|
||||
expand.append(self.db.get_person_from_handle(child_ref.ref))
|
||||
# Add spouse
|
||||
if person.handle == family.get_father_handle():
|
||||
spouse_handle = family.get_mother_handle()
|
||||
else:
|
||||
spouse_handle = family.get_father_handle()
|
||||
self.matches.add(spouse_handle)
|
||||
|
||||
def exclude(self):
|
||||
# This removes root person and his/her spouses from the matches set
|
||||
|
||||
@@ -87,7 +87,7 @@ class Location(SecondaryObject, LocationBase):
|
||||
"street": self.street,
|
||||
"locality": self.locality,
|
||||
"city": self.city,
|
||||
"country": self.county,
|
||||
"county": self.county,
|
||||
"state": self.state,
|
||||
"country": self.country,
|
||||
"postal": self.postal,
|
||||
|
||||
@@ -84,7 +84,7 @@ class Researcher(LocationBase):
|
||||
"street": self.street,
|
||||
"locality": self.locality,
|
||||
"city": self.city,
|
||||
"country": self.county,
|
||||
"county": self.county,
|
||||
"state": self.state,
|
||||
"country": self.country,
|
||||
"postal": self.postal,
|
||||
|
||||
@@ -785,7 +785,8 @@ class SimpleAccess(object):
|
||||
"""
|
||||
|
||||
with self.dbase.get_person_cursor() as cursor:
|
||||
slist = sorted((data[3][3], key) for key, data in cursor)
|
||||
# data[3] is primary_name; data[3][5][0][0] is surname
|
||||
slist = sorted((data[3][5][0][0], key) for key, data in cursor)
|
||||
|
||||
for info in slist:
|
||||
obj = self.dbase.get_person_from_handle(info[1])
|
||||
|
||||
+11
-1
@@ -1579,7 +1579,8 @@ class MultiTreeView(Gtk.TreeView):
|
||||
|
||||
def edit_obj(self, objclass, handle):
|
||||
from .editors import (EditPerson, EditEvent, EditFamily, EditSource,
|
||||
EditPlace, EditRepository, EditNote, EditMedia)
|
||||
EditPlace, EditRepository, EditNote, EditMedia,
|
||||
EditCitation)
|
||||
if objclass == 'Person':
|
||||
person = self.dbstate.db.get_person_from_handle(handle)
|
||||
if person:
|
||||
@@ -1644,6 +1645,15 @@ class MultiTreeView(Gtk.TreeView):
|
||||
self.uistate, [], ref)
|
||||
except WindowActiveError:
|
||||
pass
|
||||
elif objclass == 'Citation':
|
||||
ref = self.dbstate.db.get_citation_from_handle(handle)
|
||||
if ref:
|
||||
try:
|
||||
EditCitation(self.dbstate,
|
||||
self.uistate, [], ref)
|
||||
except WindowActiveError:
|
||||
pass
|
||||
|
||||
|
||||
def short(val,size=60):
|
||||
if len(val) > size:
|
||||
|
||||
@@ -1086,7 +1086,7 @@ class GrampsPreferences(ConfigureDialog):
|
||||
|
||||
# Text in sidebar:
|
||||
self.add_checkbox(grid,
|
||||
_("Show text in sidebar buttons (requires restart)"),
|
||||
_("Show text label beside Navigator buttons (requires restart)"),
|
||||
row, 'interface.sidebar-text', stop=3)
|
||||
row += 1
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ class AddMediaObject(ManagedWindow):
|
||||
if self.file_text.get_filename() is None:
|
||||
msgstr = _("Import failed")
|
||||
msgstr2 = _("The filename supplied could not be found.")
|
||||
ErrorDialog(msgstr, msgstr2)
|
||||
ErrorDialog(msgstr, msgstr2, parent=self.window)
|
||||
return
|
||||
|
||||
filename = conv_to_unicode(self.file_text.get_filename())
|
||||
@@ -158,7 +158,7 @@ class AddMediaObject(ManagedWindow):
|
||||
if not os.path.exists(pname):
|
||||
msgstr = _("Cannot import %s")
|
||||
msgstr2 = _("Directory specified in preferences: Base path for relative media paths: %s does not exist. Change preferences or do not use relative path when importing")
|
||||
ErrorDialog(msgstr % filename, msgstr2 % pname)
|
||||
ErrorDialog(msgstr % filename, msgstr2 % pname, parent=self.window)
|
||||
return
|
||||
filename = relative_path(filename, pname)
|
||||
|
||||
|
||||
@@ -137,7 +137,8 @@ class EditAttributeRoot(EditSecondary):
|
||||
from ..dialog import ErrorDialog
|
||||
ErrorDialog(
|
||||
_("Cannot save attribute"),
|
||||
_("The attribute type cannot be empty"))
|
||||
_("The attribute type cannot be empty"),
|
||||
parent=self.window)
|
||||
return
|
||||
if self.callback:
|
||||
self.callback(self.obj)
|
||||
|
||||
@@ -280,7 +280,8 @@ class EditCitation(EditPrimary):
|
||||
"derived. To create a citation, first select the "
|
||||
"required source, and then record the location of "
|
||||
"the information referenced within the source in the "
|
||||
"'Volume/Page' field."))
|
||||
"'Volume/Page' field."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -294,7 +295,7 @@ class EditCitation(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : gramps_id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -236,7 +236,8 @@ class EditEvent(EditPrimary):
|
||||
if self.object_is_empty():
|
||||
ErrorDialog(_("Cannot save event"),
|
||||
_("No data exists for this event. Please "
|
||||
"enter data or cancel the edit."))
|
||||
"enter data or cancel the edit."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -250,7 +251,7 @@ class EditEvent(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -258,7 +259,7 @@ class EditEvent(EditPrimary):
|
||||
if t.is_custom() and str(t) == '':
|
||||
ErrorDialog(
|
||||
_("Cannot save event"),
|
||||
_("The event type cannot be empty"))
|
||||
_("The event type cannot be empty"), parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -362,7 +362,8 @@ class EditFamily(EditPrimary):
|
||||
"are available when you create a new family. The "
|
||||
"remaining fields will become available after you "
|
||||
"attempt to select a parent."),
|
||||
'preferences.family-warn')
|
||||
'preferences.family-warn',
|
||||
parent=self.window)
|
||||
else:
|
||||
self.add_parent = False
|
||||
|
||||
@@ -1049,8 +1050,9 @@ class EditFamily(EditPrimary):
|
||||
name = "%s [%s]" % (name_displayer.display(father),
|
||||
father.gramps_id)
|
||||
ErrorDialog(_("A father cannot be his own child"),
|
||||
_("%s is listed as both the father and child "
|
||||
"of the family.") % name)
|
||||
_("%s is listed as both the father and child "
|
||||
"of the family.") % name,
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
elif self.obj.get_mother_handle() in child_list:
|
||||
@@ -1059,8 +1061,9 @@ class EditFamily(EditPrimary):
|
||||
name = "%s [%s]" % (name_displayer.display(mother),
|
||||
mother.gramps_id)
|
||||
ErrorDialog(_("A mother cannot be her own child"),
|
||||
_("%s is listed as both the mother and child "
|
||||
"of the family.") % name)
|
||||
_("%s is listed as both the mother and child "
|
||||
"of the family.") % name,
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -1068,7 +1071,8 @@ class EditFamily(EditPrimary):
|
||||
ErrorDialog(
|
||||
_("Cannot save family"),
|
||||
_("No data exists for this family. "
|
||||
"Please enter data or cancel the edit."))
|
||||
"Please enter data or cancel the edit."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -1080,7 +1084,7 @@ class EditFamily(EditPrimary):
|
||||
"enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id}
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ class EditMedia(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -304,7 +304,7 @@ class EditMedia(EditPrimary):
|
||||
"value '%(path)s'. This path does not exist!"
|
||||
" Please enter a different path") % {
|
||||
'path' : path }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -382,7 +382,8 @@ class EditName(EditSecondary):
|
||||
) % { 'surname' : surname,
|
||||
'group_name':group_as},
|
||||
_("Continue"),
|
||||
_("Return to Name Editor"))
|
||||
_("Return to Name Editor"),
|
||||
parent=self.window)
|
||||
val = q.run()
|
||||
if val:
|
||||
#delete the grouping link on database
|
||||
@@ -414,7 +415,8 @@ class EditName(EditSecondary):
|
||||
) % { 'surname' : surname,
|
||||
'group_name':group_as},
|
||||
_("Group all"),
|
||||
_("Group this name only"))
|
||||
_("Group this name only"),
|
||||
parent=self.window)
|
||||
val = q.run()
|
||||
if val:
|
||||
if group_as == surname :
|
||||
|
||||
@@ -301,7 +301,8 @@ class EditNote(EditPrimary):
|
||||
if self.object_is_empty():
|
||||
ErrorDialog(_("Cannot save note"),
|
||||
_("No data exists for this note. Please "
|
||||
"enter data or cancel the edit."))
|
||||
"enter data or cancel the edit."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -313,7 +314,7 @@ class EditNote(EditPrimary):
|
||||
"enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -811,7 +811,7 @@ class EditPerson(EditPrimary):
|
||||
msg = _("Changing the gender caused problems "
|
||||
"with marriage information.\nPlease check "
|
||||
"the person's marriages.")
|
||||
ErrorDialog(msg2, msg)
|
||||
ErrorDialog(msg2, msg, parent=self.window)
|
||||
|
||||
def save(self, *obj):
|
||||
"""
|
||||
@@ -821,7 +821,8 @@ class EditPerson(EditPrimary):
|
||||
if self.object_is_empty():
|
||||
ErrorDialog(_("Cannot save person"),
|
||||
_("No data exists for this person. Please "
|
||||
"enter data or cancel the edit."))
|
||||
"enter data or cancel the edit."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
# fix surname problems
|
||||
@@ -849,7 +850,7 @@ class EditPerson(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -229,4 +229,5 @@ class EditPersonRef(EditSecondary):
|
||||
ErrorDialog(
|
||||
_('No person selected'),
|
||||
_('You must either select a person or Cancel '
|
||||
'the edit'))
|
||||
'the edit'),
|
||||
parent=self.window)
|
||||
|
||||
@@ -272,7 +272,7 @@ class EditPlace(EditPrimary):
|
||||
if self.obj.get_name().get_value().strip() == '':
|
||||
msg1 = _("Cannot save place. Name not entered.")
|
||||
msg2 = _("You must enter a name before saving.")
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -286,7 +286,7 @@ class EditPlace(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -35,9 +35,46 @@ from .editsecondary import EditSecondary
|
||||
from ..glade import Glade
|
||||
from ..widgets import MonitoredDate, MonitoredEntry
|
||||
from ..dialog import ErrorDialog
|
||||
from gramps.gen.errors import ValidationError
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
ISO_CODES = (
|
||||
'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az',
|
||||
'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs',
|
||||
'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy',
|
||||
'da', 'de', 'dv', 'dz',
|
||||
'ee', 'el', 'en', 'eo', 'es', 'et', 'eu',
|
||||
'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy',
|
||||
'ga', 'gd', 'gl', 'gn', 'gu', 'gv',
|
||||
'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz',
|
||||
'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'io', 'is', 'it', 'iu',
|
||||
'ja', 'jv',
|
||||
'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv',
|
||||
'kw', 'ky',
|
||||
'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv',
|
||||
'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mr', 'ms', 'mt', 'my',
|
||||
'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny',
|
||||
'oc', 'oj', 'om', 'or', 'os',
|
||||
'pa', 'pi', 'pl', 'ps', 'pt',
|
||||
'qu',
|
||||
'rm', 'rn', 'ro', 'ru', 'rw',
|
||||
'sa', 'sc', 'sd', 'se', 'sg', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr',
|
||||
'ss', 'st', 'su', 'sv', 'sw',
|
||||
'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw',
|
||||
'ty',
|
||||
'ug', 'uk', 'ur', 'uz',
|
||||
've', 'vi', 'vo',
|
||||
'wa', 'wo',
|
||||
'xh',
|
||||
'yi', 'yo',
|
||||
'za', 'zh', 'zu')
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# EditPlaceName class
|
||||
@@ -75,6 +112,13 @@ class EditPlaceName(EditSecondary):
|
||||
self.language = MonitoredEntry(
|
||||
self.top.get_object("language"), self.obj.set_language,
|
||||
self.obj.get_language, self.db.readonly)
|
||||
self.language.connect("validate", self._validate_iso_code)
|
||||
#force validation now with initial entry
|
||||
self.top.get_object("language").validate(force=True)
|
||||
|
||||
def _validate_iso_code(self, widget, text):
|
||||
if text not in ISO_CODES:
|
||||
return ValidationError(_("Invalid ISO code"))
|
||||
|
||||
def _connect_signals(self):
|
||||
self.define_help_button(self.top.get_object('help'))
|
||||
@@ -87,7 +131,8 @@ class EditPlaceName(EditSecondary):
|
||||
def save(self, *obj):
|
||||
if not self.obj.get_value():
|
||||
ErrorDialog(_("Cannot save place name"),
|
||||
_("The place name cannot be empty"))
|
||||
_("The place name cannot be empty"),
|
||||
parent=self.window)
|
||||
return
|
||||
|
||||
if self.callback:
|
||||
|
||||
@@ -274,7 +274,7 @@ class EditPlaceRef(EditReference):
|
||||
if self.source.get_name().get_value().strip() == '':
|
||||
msg1 = _("Cannot save place. Name not entered.")
|
||||
msg2 = _("You must enter a name before saving.")
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -297,6 +297,6 @@ class EditReference(ManagedWindow, DbGUIElement):
|
||||
"different ID or leave blank to get the next "
|
||||
"available ID value.") % {
|
||||
'id' : new_id}
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -167,7 +167,8 @@ class EditRepository(EditPrimary):
|
||||
if self.object_is_empty():
|
||||
ErrorDialog(_("Cannot save repository"),
|
||||
_("No data exists for this repository. Please "
|
||||
"enter data or cancel the edit."))
|
||||
"enter data or cancel the edit."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -181,7 +182,7 @@ class EditRepository(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -187,7 +187,8 @@ class EditSource(EditPrimary):
|
||||
if self.object_is_empty():
|
||||
ErrorDialog(_("Cannot save source"),
|
||||
_("No data exists for this source. Please "
|
||||
"enter data or cancel the edit."))
|
||||
"enter data or cancel the edit."),
|
||||
parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
@@ -201,7 +202,7 @@ class EditSource(EditPrimary):
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
ErrorDialog(msg1, msg2, parent=self.window)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
|
||||
@@ -108,26 +108,12 @@
|
||||
<property name="label" translatable="yes">Language:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">language</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="UndoableEntry" id="language">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Language in which the name is written.</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="date_stat">
|
||||
<property name="visible">True</property>
|
||||
@@ -180,7 +166,7 @@
|
||||
<object class="UndoableEntry" id="value">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes" context="place">The name of the place.</property>
|
||||
<property name="tooltip_text" translatable="yes">The name of the place.</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
@@ -197,13 +183,25 @@
|
||||
<property name="label" translatable="yes">Name:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">language</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ValidatableMaskedEntry" id="language">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Language in which the name is written. Valid values are two character ISO codes. For example: en, fr, de, nl ...</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
||||
@@ -423,7 +423,7 @@ primary data for the merged place.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="name_btn1">
|
||||
<property name="label" translatable="yes" context="place">Name:</property>
|
||||
<property name="label" translatable="yes">Name:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
@@ -440,7 +440,7 @@ primary data for the merged place.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="name_btn2">
|
||||
<property name="label" translatable="yes" context="place">Name:</property>
|
||||
<property name="label" translatable="yes">Name:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
|
||||
@@ -160,7 +160,7 @@ class Gramps(object):
|
||||
from .dialog import WarningDialog
|
||||
import gettext
|
||||
|
||||
_display_welcome_message()
|
||||
#_display_welcome_message()
|
||||
|
||||
# Append image directory to the theme search path
|
||||
theme = Gtk.IconTheme.get_default()
|
||||
|
||||
@@ -279,10 +279,17 @@ class PaperFrame(Gtk.Box):
|
||||
return paper_margins
|
||||
|
||||
def get_custom_paper_size(self):
|
||||
width = float(self.pwidth.get_text().replace(",", ".")) * \
|
||||
"""Get and validate custom paper size values from dialog entries.
|
||||
Float values returned.
|
||||
"""
|
||||
try:
|
||||
width = float(self.pwidth.get_text().replace(",", ".")) * \
|
||||
self.paper_unit_multiplier
|
||||
height = float(self.pheight.get_text().replace(",", ".")) * \
|
||||
height = float(self.pheight.get_text().replace(",", ".")) * \
|
||||
self.paper_unit_multiplier
|
||||
except ValueError:
|
||||
width = float(21.0)
|
||||
height = float(29.7)
|
||||
|
||||
paper_size = [max(width, 1.0), max(height, 1.0)]
|
||||
|
||||
|
||||
@@ -136,7 +136,8 @@ class StyleListDisplay(object):
|
||||
self.sheetlist.save()
|
||||
except IOError as msg:
|
||||
from ...dialog import ErrorDialog
|
||||
ErrorDialog(_("Error saving stylesheet"), str(msg))
|
||||
ErrorDialog(_("Error saving stylesheet"),
|
||||
str(msg), parent=self.window)
|
||||
except:
|
||||
log.error("Failed to save stylesheet", exc_info=True)
|
||||
|
||||
|
||||
@@ -663,7 +663,7 @@ class ViewManager(CLIManager):
|
||||
"""
|
||||
Initialize the interface.
|
||||
"""
|
||||
self.views = get_available_views()
|
||||
self.views = get_available_views(self.uistate)
|
||||
defaults = views_to_show(self.views,
|
||||
config.get('preferences.use-last-view'))
|
||||
self.current_views = defaults[2]
|
||||
@@ -764,7 +764,7 @@ class ViewManager(CLIManager):
|
||||
try:
|
||||
backup(self.dbstate.db)
|
||||
except DbException as msg:
|
||||
ErrorDialog(_("Error saving backup data"), msg)
|
||||
ErrorDialog(_("Error saving backup data"), msg, parent=self.uistate.window)
|
||||
self.uistate.set_busy_cursor(False)
|
||||
self.uistate.progress.hide()
|
||||
|
||||
@@ -779,7 +779,8 @@ class ViewManager(CLIManager):
|
||||
_("Aborting changes will return the database to the state "
|
||||
"it was before you started this editing session."),
|
||||
_("Abort changes"),
|
||||
_("Cancel"))
|
||||
_("Cancel"),
|
||||
parent=self.uistate.window)
|
||||
|
||||
if dialog.run():
|
||||
self.dbstate.db.disable_signals()
|
||||
@@ -791,7 +792,8 @@ class ViewManager(CLIManager):
|
||||
_("Cannot abandon session's changes"),
|
||||
_('Changes cannot be completely abandoned because the '
|
||||
'number of changes made in the session exceeded the '
|
||||
'limit.'))
|
||||
'limit.'),
|
||||
parent=self.uistate.window)
|
||||
|
||||
def __init_action_group(self, name, actions, sensitive=True, toggles=None):
|
||||
"""
|
||||
@@ -1608,7 +1610,8 @@ def run_plugin(pdata, dbstate, uistate):
|
||||
'gramps_bugtracker_url' : URL_BUGHOME,
|
||||
'firstauthoremail': pdata.authors_email[0] if
|
||||
pdata.authors_email else '...',
|
||||
'error_msg': pmgr.get_fail_list()[-1][1][1]})
|
||||
'error_msg': pmgr.get_fail_list()[-1][1][1]},
|
||||
parent=uistate.window)
|
||||
return
|
||||
|
||||
if pdata.ptype == REPORT:
|
||||
@@ -1633,7 +1636,7 @@ def make_plugin_callback(pdata, dbstate, uistate):
|
||||
"""
|
||||
return lambda x: run_plugin(pdata, dbstate, uistate)
|
||||
|
||||
def get_available_views():
|
||||
def get_available_views(uistate):
|
||||
"""
|
||||
Query the views and determine what views to show and in which order
|
||||
|
||||
@@ -1664,7 +1667,8 @@ def get_available_views():
|
||||
'gramps_bugtracker_url' : URL_BUGHOME,
|
||||
'firstauthoremail': pdata.authors_email[0] if
|
||||
pdata.authors_email else '...',
|
||||
'error_msg': lasterror})
|
||||
'error_msg': lasterror},
|
||||
parent=uistate.window)
|
||||
continue
|
||||
viewclass = getattr(mod, pdata.viewclass)
|
||||
|
||||
|
||||
@@ -409,7 +409,8 @@ class CitationBookmarks(ListBookmarks) :
|
||||
"You are probably trying to bookmark a Source in the "
|
||||
"Citation Tree View. In this view, only Citations "
|
||||
"can be bookmarked. To bookmark a Source, switch to "
|
||||
"the Source View")
|
||||
"the Source View",
|
||||
parent=self.uistate.window)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('citation-delete', self.remove_handles)
|
||||
|
||||
@@ -447,7 +447,8 @@ class ListView(NavigationView):
|
||||
WarningDialog(
|
||||
_("Could Not Set a Bookmark"),
|
||||
_("A bookmark could not be set because "
|
||||
"nothing was selected."))
|
||||
"nothing was selected."),
|
||||
parent=self.uistate.window)
|
||||
|
||||
####################################################################
|
||||
#
|
||||
@@ -541,7 +542,8 @@ class ListView(NavigationView):
|
||||
_("More than one item has been selected for deletion. "
|
||||
"Select the option indicating how to delete the items:"),
|
||||
_("Delete All"),
|
||||
_("Confirm Each Delete"))
|
||||
_("Confirm Each Delete"),
|
||||
parent=self.uistate.window)
|
||||
prompt = not q.run()
|
||||
|
||||
if not prompt:
|
||||
@@ -563,7 +565,8 @@ class ListView(NavigationView):
|
||||
descr = object.get_gramps_id()
|
||||
self.uistate.set_busy_cursor(True)
|
||||
QuestionDialog(_('Delete %s?') % descr, msg,
|
||||
_('_Delete Item'), query.query_response)
|
||||
_('_Delete Item'), query.query_response,
|
||||
parent=self.uistate.window)
|
||||
self.uistate.set_busy_cursor(False)
|
||||
else:
|
||||
query.query_response()
|
||||
|
||||
@@ -254,7 +254,8 @@ class NavigationView(PageView):
|
||||
WarningDialog(
|
||||
_("Could Not Set a Bookmark"),
|
||||
_("A bookmark could not be set because "
|
||||
"no one was selected."))
|
||||
"no one was selected."),
|
||||
parent=self.uistate.window)
|
||||
|
||||
def edit_bookmarks(self, obj):
|
||||
"""
|
||||
@@ -343,7 +344,7 @@ class NavigationView(PageView):
|
||||
"""
|
||||
A dialog to move to a Gramps ID entered by the user.
|
||||
"""
|
||||
dialog = Gtk.Dialog(_('Jump to by Gramps ID'))
|
||||
dialog = Gtk.Dialog(_('Jump to by Gramps ID'), parent=self.uistate.window)
|
||||
dialog.set_border_width(12)
|
||||
label = Gtk.Label(label='<span weight="bold" size="larger">%s</span>' %
|
||||
_('Jump to by Gramps ID'))
|
||||
|
||||
@@ -81,9 +81,9 @@ TAG_3 = '''
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
WIKI_HELP_PAGE = '%s_-_Entering_and_Editing_Data:_Detailed_-_part_3' % \
|
||||
URL_MANUAL_PAGE
|
||||
WIKI_HELP_SEC = _('manual|Tags')
|
||||
WIKI_HELP_PAGE = '%s_-_Filters' % \
|
||||
URL_MANUAL_PAGE
|
||||
WIKI_HELP_SEC = _('manual|Tagging')
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -485,7 +485,9 @@ class OrganizeTagsDialog(object):
|
||||
_("The tag definition will be removed. "
|
||||
"The tag will be also removed from all objects in the database."),
|
||||
_("Yes"),
|
||||
_("No"))
|
||||
_("No"),
|
||||
parent=top)
|
||||
|
||||
prompt = yes_no.run()
|
||||
if prompt:
|
||||
|
||||
@@ -571,7 +573,8 @@ class EditTag(object):
|
||||
if not self.tag.get_name():
|
||||
ErrorDialog(
|
||||
_("Cannot save tag"),
|
||||
_("The tag name cannot be empty"))
|
||||
_("The tag name cannot be empty"),
|
||||
parent=self.top)
|
||||
return
|
||||
|
||||
if not self.tag.get_handle():
|
||||
|
||||
+107
-109
@@ -1917,6 +1917,7 @@ class GedcomParser(UpdateCallback):
|
||||
self.default_tag = None
|
||||
self.dir_path = os.path.dirname(filename)
|
||||
self.is_ftw = False
|
||||
self.addr_is_detail = False
|
||||
self.groups = None
|
||||
self.want_parse_warnings = True
|
||||
|
||||
@@ -2931,23 +2932,32 @@ class GedcomParser(UpdateCallback):
|
||||
return place
|
||||
return None
|
||||
|
||||
def __create_place(self, title, location):
|
||||
def __add_place(self, event, sub_state):
|
||||
"""
|
||||
Create a new place based on the title and primary location.
|
||||
Add a new place to an event if not already present, or update a
|
||||
place.
|
||||
|
||||
@param title: The place title
|
||||
@type title: string
|
||||
@param location: The current location
|
||||
@type location: gen.lib.Location
|
||||
@return gen.lib.Place
|
||||
@param event: The event
|
||||
@type event: gen.lib.Event
|
||||
@param substate: The sub-state for PLAC or ADDR elements (i.e. parsed by
|
||||
event_parse_tbl)
|
||||
@type sub_state: CurrentState
|
||||
"""
|
||||
place = Place()
|
||||
place.set_title(title)
|
||||
if location:
|
||||
place.add_alternate_locations(location)
|
||||
self.dbase.add_place(place, self.trans)
|
||||
self.place_names[title].append(place.get_handle())
|
||||
return place
|
||||
if sub_state.place:
|
||||
# see whether this place already exists
|
||||
place = self.__find_place(sub_state.place.get_title(),
|
||||
self.__get_first_loc(sub_state.place))
|
||||
if place is None:
|
||||
place = sub_state.place
|
||||
self.dbase.add_place(place, self.trans)
|
||||
self.place_names[place.get_title()].append(place.get_handle())
|
||||
event.set_place_handle(place.get_handle())
|
||||
else:
|
||||
place.merge(sub_state.place)
|
||||
self.dbase.commit_place(place, self.trans)
|
||||
event.set_place_handle(place.get_handle())
|
||||
place_title = place_displayer.display(self.dbase, place)
|
||||
sub_state.pf.load_place(self.place_import, place, place_title)
|
||||
|
||||
def __find_file(self, fullname, altpath):
|
||||
tries = []
|
||||
@@ -3862,10 +3872,13 @@ class GedcomParser(UpdateCallback):
|
||||
sub_state.level = state.level+1
|
||||
sub_state.event = event
|
||||
sub_state.event_ref = event_ref
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
self.__add_place(event, sub_state)
|
||||
|
||||
self.dbase.commit_event(event, self.trans)
|
||||
event_ref.ref = event.handle
|
||||
state.person.add_event_ref(event_ref)
|
||||
@@ -4067,10 +4080,13 @@ class GedcomParser(UpdateCallback):
|
||||
sub_state.level = state.level+1
|
||||
sub_state.event = event
|
||||
sub_state.event_ref = event_ref
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
self.__add_place(event, sub_state)
|
||||
|
||||
self.dbase.add_event(event, self.trans)
|
||||
event_ref.ref = event.handle
|
||||
state.person.add_event_ref(event_ref)
|
||||
@@ -4519,11 +4535,14 @@ class GedcomParser(UpdateCallback):
|
||||
try:
|
||||
title = line.data
|
||||
place = self.__find_place(title, None)
|
||||
if place:
|
||||
state.place = place
|
||||
if place is None:
|
||||
place = Place()
|
||||
place.set_title(title)
|
||||
self.dbase.add_place(place, self.trans)
|
||||
self.place_names[place.get_title()].append(place.get_handle())
|
||||
else:
|
||||
state.place = self.__create_place(title, None)
|
||||
state.lds_ord.set_place_handle(state.place.handle)
|
||||
pass
|
||||
state.lds_ord.set_place_handle(place.handle)
|
||||
except NameError:
|
||||
return
|
||||
|
||||
@@ -4887,10 +4906,13 @@ class GedcomParser(UpdateCallback):
|
||||
sub_state.level = state.level+1
|
||||
sub_state.event = event
|
||||
sub_state.event_ref = event_ref
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
self.__add_place(event, sub_state)
|
||||
|
||||
if event.type == EventType.MARRIAGE:
|
||||
descr = event.get_description()
|
||||
if descr == "Civil Union":
|
||||
@@ -4930,9 +4952,12 @@ class GedcomParser(UpdateCallback):
|
||||
sub_state.level = state.level+1
|
||||
sub_state.event = event
|
||||
sub_state.event_ref = event_ref
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
self.__add_place(event, sub_state)
|
||||
|
||||
self.dbase.commit_event(event, self.trans)
|
||||
event_ref.ref = event.handle
|
||||
@@ -5361,65 +5386,30 @@ class GedcomParser(UpdateCallback):
|
||||
state.event.set_description(line.data)
|
||||
else:
|
||||
title = line.data
|
||||
place_handle = state.event.get_place_handle()
|
||||
if place_handle:
|
||||
place = state.place
|
||||
if place:
|
||||
# We encounter a PLAC, having previously encountered an ADDR
|
||||
old_place = self.dbase.get_place_from_handle(place_handle)
|
||||
old_title = old_place.get_title()
|
||||
location = self.__get_first_loc(old_place)
|
||||
if old_title != "":
|
||||
if place.get_title() and place.get_title() != "":
|
||||
# We have previously found a PLAC
|
||||
self.__add_msg(_("A second PLAC ignored"), line, state)
|
||||
# ignore this second PLAC, and use the old one
|
||||
title = old_title
|
||||
place = old_place
|
||||
else:
|
||||
# This is the first PLAC
|
||||
refs = list(self.dbase.find_backlink_handles(place_handle))
|
||||
# We haven't commited the event yet, so the place will not
|
||||
# be linked to it. If there are any refs they will be from
|
||||
# other events (etc)
|
||||
if len(refs) == 0:
|
||||
place = self.__find_place(title, location)
|
||||
if place is None:
|
||||
place = old_place
|
||||
place.set_title(title)
|
||||
self.place_names[old_title].remove(place_handle)
|
||||
self.place_names[title].append(place_handle)
|
||||
else:
|
||||
place.merge(old_place)
|
||||
self.place_import.remove_location(old_place.handle)
|
||||
self.dbase.remove_place(place_handle, self.trans)
|
||||
self.place_names[old_title].remove(place_handle)
|
||||
else:
|
||||
place = self.__find_place(title, location)
|
||||
if place is None:
|
||||
place = self.__create_place(title, location)
|
||||
else:
|
||||
pass
|
||||
place.set_title(line.data)
|
||||
else:
|
||||
# The first thing we encounter is PLAC
|
||||
location = None
|
||||
place = self.__find_place(title, location)
|
||||
if place is None:
|
||||
place = self.__create_place(title, location)
|
||||
|
||||
state.event.set_place_handle(place.handle)
|
||||
|
||||
state.place = Place()
|
||||
place = state.place
|
||||
place.set_title(line.data)
|
||||
|
||||
sub_state = CurrentState()
|
||||
sub_state.place = place
|
||||
sub_state.level = state.level+1
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, self.event_place_map,
|
||||
self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
place_title = place_displayer.display(self.dbase, place)
|
||||
sub_state.pf.load_place(self.place_import, place, place_title)
|
||||
|
||||
self.dbase.commit_place(place, self.trans)
|
||||
|
||||
def __event_place_note(self, line, state):
|
||||
"""
|
||||
@param line: The current line in GedLine format
|
||||
@@ -5528,55 +5518,53 @@ class GedcomParser(UpdateCallback):
|
||||
self.__merge_address(free_form, sub_state.location, line, state)
|
||||
|
||||
location = sub_state.location
|
||||
place_handle = state.event.get_place_handle()
|
||||
if place_handle:
|
||||
# We encounter an ADDR having previously encountered a PLAC
|
||||
old_place = self.dbase.get_place_from_handle(place_handle)
|
||||
title = old_place.get_title()
|
||||
if len(old_place.get_alternate_locations()) != 0 and \
|
||||
not self.__get_first_loc(old_place).is_empty():
|
||||
# We have perviously found an ADDR, or have populated location
|
||||
# from PLAC title
|
||||
self.__add_msg(_("Location already populated; ADDR ignored"),
|
||||
line, state)
|
||||
# ignore this second ADDR, and use the old one
|
||||
location = self.__get_first_loc(old_place)
|
||||
place = old_place
|
||||
else:
|
||||
# This is the first ADDR
|
||||
refs = list(self.dbase.find_backlink_handles(place_handle))
|
||||
# We haven't commited the event yet, so the place will not be
|
||||
# linked to it. If there are any refs they will be from other
|
||||
# events (etc)
|
||||
if len(refs) == 0:
|
||||
place = self.__find_place(title, location)
|
||||
if place is None:
|
||||
place = old_place
|
||||
self.__add_location(place, location)
|
||||
else:
|
||||
place.merge(old_place)
|
||||
self.place_import.remove_location(old_place.handle)
|
||||
self.dbase.remove_place(place_handle, self.trans)
|
||||
self.place_names[title].remove(place_handle)
|
||||
else:
|
||||
place = self.__find_place(title, location)
|
||||
if place is None:
|
||||
place = self.__create_place(title, location)
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
# The first thing we encounter is ADDR
|
||||
title = ""
|
||||
place = self.__find_place(title, location)
|
||||
|
||||
if self.addr_is_detail and state.place:
|
||||
# Commit the enclosing place
|
||||
place = self.__find_place(state.place.get_title(), None)
|
||||
if place is None:
|
||||
place = self.__create_place(title, location)
|
||||
place = state.place
|
||||
self.dbase.add_place(place, self.trans)
|
||||
self.place_names[place.get_title()].append(place.get_handle())
|
||||
else:
|
||||
place.merge(state.place)
|
||||
self.dbase.commit_place(place, self.trans)
|
||||
place_title = place_displayer.display(self.dbase, place)
|
||||
state.pf.load_place(self.place_import, place, place_title)
|
||||
|
||||
# Create the Place Details (it is committed with the event)
|
||||
place_detail = Place()
|
||||
place_detail.set_name(location.get_street())
|
||||
place_detail.set_title(location.get_street())
|
||||
# For RootsMagic etc. Place Details e.g. address, hospital, cemetary
|
||||
place_detail.set_type((PlaceType.CUSTOM, _("Detail")))
|
||||
placeref = PlaceRef()
|
||||
placeref.ref = place.get_handle()
|
||||
place_detail.set_placeref_list([placeref])
|
||||
state.place = place_detail
|
||||
else:
|
||||
place = state.place
|
||||
if place:
|
||||
# We encounter an ADDR having previously encountered a PLAC
|
||||
if len(place.get_alternate_locations()) != 0 and \
|
||||
not self.__get_first_loc(place).is_empty():
|
||||
# We have perviously found an ADDR, or have populated location
|
||||
# from PLAC title
|
||||
self.__add_msg(_("Location already populated; ADDR ignored"),
|
||||
line, state)
|
||||
# ignore this second ADDR, and use the old one
|
||||
else:
|
||||
# This is the first ADDR
|
||||
place.add_alternate_locations(location)
|
||||
else:
|
||||
# The first thing we encounter is ADDR
|
||||
state.place = Place()
|
||||
place = state.place
|
||||
place.add_alternate_locations(location)
|
||||
|
||||
# merge notes etc into place
|
||||
place.merge(sub_state.place)
|
||||
|
||||
state.event.set_place_handle(place.get_handle())
|
||||
self.dbase.commit_place(place, self.trans)
|
||||
|
||||
def __add_location(self, place, location):
|
||||
"""
|
||||
@param place: A place object we have found or created
|
||||
@@ -5608,12 +5596,10 @@ class GedcomParser(UpdateCallback):
|
||||
@param state: The current state
|
||||
@type state: CurrentState
|
||||
"""
|
||||
place_handle = state.event.get_place_handle()
|
||||
if place_handle:
|
||||
place = self.dbase.get_place_from_handle(place_handle)
|
||||
place = state.place
|
||||
if place:
|
||||
codes = [place.get_code(), line.data]
|
||||
place.set_code(' '.join(code for code in codes if code))
|
||||
self.dbase.commit_place(place, self.trans)
|
||||
|
||||
def __event_privacy(self, line, state):
|
||||
"""
|
||||
@@ -6925,6 +6911,11 @@ class GedcomParser(UpdateCallback):
|
||||
self.gedsource = self.gedmap.get_from_source_tag(line.data)
|
||||
if line.data.strip() in ["FTW", "FTM"]:
|
||||
self.is_ftw = True
|
||||
# Some software (e.g. RootsMagic (http://files.rootsmagic.com/PAF-
|
||||
# Book/RootsMagic-for-PAF-Users-Printable.pdf) use the Addr fields for
|
||||
# 'Place Details (address, hospital, cemetary)'
|
||||
if line.data.strip().lower() in ['rootsmagic']:
|
||||
self.addr_is_detail = True
|
||||
# We will use the approved system ID as the name of the generating
|
||||
# software, in case we do not get the name in the proper place
|
||||
self.genby = line.data
|
||||
@@ -7576,9 +7567,13 @@ class GedcomParser(UpdateCallback):
|
||||
sub_state.event_ref = event_ref
|
||||
sub_state.event = event
|
||||
sub_state.person = state.person
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, event_map, self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
self.__add_place(event, sub_state)
|
||||
|
||||
self.dbase.commit_event(event, self.trans)
|
||||
|
||||
event_ref.set_reference_handle(event.handle)
|
||||
@@ -7600,10 +7595,13 @@ class GedcomParser(UpdateCallback):
|
||||
sub_state.level = state.level+1
|
||||
sub_state.event = event
|
||||
sub_state.event_ref = event_ref
|
||||
sub_state.pf = self.place_parser
|
||||
|
||||
self.__parse_level(sub_state, event_map, self.__undefined)
|
||||
state.msg += sub_state.msg
|
||||
|
||||
self.__add_place(event, sub_state)
|
||||
|
||||
self.dbase.commit_event(event, self.trans)
|
||||
event_ref.set_reference_handle(event.handle)
|
||||
return event_ref
|
||||
|
||||
@@ -296,7 +296,8 @@ class BasePersonView(ListView):
|
||||
QuestionDialog(msg1,
|
||||
msg2,
|
||||
_('_Delete Person'),
|
||||
self.delete_person_response)
|
||||
self.delete_person_response,
|
||||
parent=self.uistate.window)
|
||||
else:
|
||||
# Ask to delete; option to cancel, delete rest
|
||||
# This gets person to delete from parameter
|
||||
@@ -304,7 +305,8 @@ class BasePersonView(ListView):
|
||||
self._message2_format,
|
||||
handles,
|
||||
self._lookup_person,
|
||||
yes_func=self.delete_person_response) # Yes
|
||||
yes_func=self.delete_person_response,
|
||||
parent=self.uistate.window) # Yes
|
||||
|
||||
def _message1_format(self, person):
|
||||
return _('Delete %s?') % (name_displayer.display(person) +
|
||||
@@ -417,7 +419,8 @@ class BasePersonView(ListView):
|
||||
_("Cannot merge people"),
|
||||
_("Exactly two people must be selected to perform a merge. "
|
||||
"A second person can be selected by holding down the "
|
||||
"control key while clicking on the desired person."))
|
||||
"control key while clicking on the desired person."),
|
||||
parent=self.uistate.window)
|
||||
else:
|
||||
MergePerson(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ class PlaceBaseView(ListView):
|
||||
if not len(self.mapservicedata):
|
||||
msg = _("No map service is available.")
|
||||
msg2 = _("Check your installation.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
return
|
||||
|
||||
place_handles = self.selected_handles()
|
||||
@@ -269,7 +269,7 @@ class PlaceBaseView(ListView):
|
||||
msg2 = _("You need to select a place to be able to view it"
|
||||
" on a map. Some Map Services might support multiple"
|
||||
" selections.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
return
|
||||
|
||||
#TODO: support for descriptions in some cases. For now, pass None
|
||||
@@ -363,7 +363,7 @@ class PlaceBaseView(ListView):
|
||||
msg = _("Cannot delete place.")
|
||||
msg2 = _("This place is currently referenced by another place. "
|
||||
"First remove the places it contains.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
return
|
||||
self.remove_selected_objects()
|
||||
|
||||
@@ -406,14 +406,14 @@ class PlaceBaseView(ListView):
|
||||
msg2 = _("Exactly two places must be selected to perform a merge. "
|
||||
"A second place can be selected by holding down the "
|
||||
"control key while clicking on the desired place.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
if (located_in(self.dbstate.db, mlist[0], mlist[1]) or
|
||||
located_in(self.dbstate.db, mlist[1], mlist[0])):
|
||||
msg = _("Cannot merge places.")
|
||||
msg2 = _("Merging these places would create a cycle in the "
|
||||
"place hierarchy.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergePlace(self.dbstate, self.uistate, mlist[0], mlist[1],
|
||||
self.merged)
|
||||
|
||||
@@ -734,7 +734,7 @@ class VarString(object):
|
||||
|
||||
#return what we have
|
||||
return (self.state, curr_string)
|
||||
print("===" + str(self.state) + " '" + str(curr_string) + "'")
|
||||
#print("===" + str(self.state) + " '" + str(curr_string) + "'")
|
||||
|
||||
def extend(self, acquisition):
|
||||
"""
|
||||
|
||||
@@ -390,9 +390,7 @@ class GeoGraphyView(OsmGps, NavigationView):
|
||||
clearmap.show()
|
||||
menu.append(clearmap)
|
||||
menu.show()
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -193,7 +193,8 @@ class PlaceSelection(ManagedWindow, OsmGps):
|
||||
self.oldvalue)
|
||||
)
|
||||
for place in self.places:
|
||||
self.plist.append(place)
|
||||
p = (place[0].value, place[1].value, place[2].value, place[3])
|
||||
self.plist.append(p)
|
||||
# here, we could add value from geography names services ...
|
||||
|
||||
# if we found no place, we must create a default place.
|
||||
|
||||
@@ -64,7 +64,6 @@ fname_map = {'all': _('Filtering_on|all'),
|
||||
'people with missing birth dates':
|
||||
_('Filtering_on|people with missing birth dates'),
|
||||
'disconnected people': _('Filtering_on|disconnected people'),
|
||||
'all families': _('Filtering_on|all families'),
|
||||
'unique surnames': _('Filtering_on|unique surnames'),
|
||||
'people with media': _('Filtering_on|people with media'),
|
||||
'media references': _('Filtering_on|media references'),
|
||||
|
||||
@@ -357,7 +357,7 @@ class RelationshipCalculator(gramps.gen.relationship.RelationshipCalculator):
|
||||
else:
|
||||
return "%d-ésima tía abuela%s" % (level-2, inlaw)
|
||||
|
||||
def _get_distant_aunt(self, level, step, inlae):
|
||||
def _get_distant_aunt(self, level, step, inlaw):
|
||||
if step:
|
||||
base = 'tiastra'
|
||||
else:
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.10"/>
|
||||
<object class="GtkDialog" id="relcalc">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">400</property>
|
||||
@@ -93,6 +92,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="min_content_height">75</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text1">
|
||||
<property name="height_request">75</property>
|
||||
|
||||
@@ -301,7 +301,7 @@ class Verify(tool.Tool, ManagedWindow, UpdateCallback):
|
||||
self.top.get_object(option).set_value(
|
||||
self.options.handler.options_dict[option]
|
||||
)
|
||||
self.window.show()
|
||||
self.show()
|
||||
|
||||
def build_menu_names(self, obj):
|
||||
return (_("Tool settings"),self.label)
|
||||
@@ -530,7 +530,7 @@ class VerifyResults(ManagedWindow):
|
||||
name_column.set_sort_column_id(VerifyResults.OBJ_NAME_COL)
|
||||
self.warn_tree.append_column(name_column)
|
||||
|
||||
self.window.show()
|
||||
self.show()
|
||||
self.window_shown = False
|
||||
|
||||
def __dummy(self, obj):
|
||||
|
||||
@@ -313,7 +313,7 @@ class CitationListView(ListView):
|
||||
"merge. A second citation can be selected by holding "
|
||||
"down the control key while clicking on the desired "
|
||||
"citation.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
citation1 = self.dbstate.db.get_citation_from_handle(mlist[0])
|
||||
citation2 = self.dbstate.db.get_citation_from_handle(mlist[1])
|
||||
@@ -324,7 +324,7 @@ class CitationListView(ListView):
|
||||
"source to perform a merge. If you want to merge "
|
||||
"these two citations, then you must merge the "
|
||||
"sources first.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeCitation(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -427,12 +427,13 @@ class CitationTreeView(ListView):
|
||||
except WindowActiveError:
|
||||
from gramps.gui.dialog import WarningDialog
|
||||
WarningDialog(_("Cannot share this reference"),
|
||||
self.__blocked_text())
|
||||
self.__blocked_text(),
|
||||
parent=self.uistate.window)
|
||||
else:
|
||||
msg = _("Cannot add citation.")
|
||||
msg2 = _("In order to add a citation to an existing source, "
|
||||
" you must select a source.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
#
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
@@ -482,7 +483,8 @@ class CitationTreeView(ListView):
|
||||
except WindowActiveError:
|
||||
from gramps.gui.dialog import WarningDialog
|
||||
WarningDialog(_("Cannot share this reference"),
|
||||
self.__blocked_text2())
|
||||
self.__blocked_text2(),
|
||||
parent=self.uistate.window)
|
||||
|
||||
def __blocked_text(self):
|
||||
"""
|
||||
@@ -516,7 +518,7 @@ class CitationTreeView(ListView):
|
||||
"merge. A second citation can be selected by holding "
|
||||
"down the control key while clicking on the desired "
|
||||
"citation.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
source1 = self.dbstate.db.get_source_from_handle(mlist[0])
|
||||
citation1 = self.dbstate.db.get_citation_from_handle(mlist[0])
|
||||
@@ -536,7 +538,7 @@ class CitationTreeView(ListView):
|
||||
"source to perform a merge. If you want to merge "
|
||||
"these two citations, then you must merge the "
|
||||
"sources first.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeCitation(self.dbstate, self.uistate, mlist[0],
|
||||
mlist[1])
|
||||
@@ -547,7 +549,7 @@ class CitationTreeView(ListView):
|
||||
msg2 = _("Both objects must be of the same type, either "
|
||||
"both must be sources, or both must be "
|
||||
"citations.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_citation_from_gramps_id(gid)
|
||||
|
||||
@@ -264,7 +264,7 @@ class EventView(ListView):
|
||||
msg2 = _("Exactly two events must be selected to perform a merge. "
|
||||
"A second object can be selected by holding down the "
|
||||
"control key while clicking on the desired event.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeEvent(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -219,7 +219,8 @@ class FamilyView(ListView):
|
||||
WarningDialog(
|
||||
_("Could Not Set a Bookmark"),
|
||||
_("A bookmark could not be set because "
|
||||
"no one was selected."))
|
||||
"no one was selected."),
|
||||
parent=self.uistate.window)
|
||||
|
||||
def add(self, obj):
|
||||
family = Family()
|
||||
@@ -243,13 +244,15 @@ class FamilyView(ListView):
|
||||
QuestionDialog(msg1,
|
||||
msg2,
|
||||
_('_Delete Family'),
|
||||
lambda: self.delete_family_response(family))
|
||||
lambda: self.delete_family_response(family),
|
||||
parent=self.uistate.window)
|
||||
else:
|
||||
MultiSelectDialog(self._message1_format,
|
||||
self._message2_format,
|
||||
handles,
|
||||
self.dbstate.db.get_family_from_handle,
|
||||
yes_func=self.delete_family_response)
|
||||
yes_func=self.delete_family_response,
|
||||
parent=self.uistate.window)
|
||||
|
||||
def _message1_format(self, family):
|
||||
"""
|
||||
@@ -298,7 +301,7 @@ class FamilyView(ListView):
|
||||
msg2 = _("Exactly two families must be selected to perform a merge."
|
||||
" A second family can be selected by holding down the "
|
||||
"control key while clicking on the desired family.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeFamily(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -535,9 +535,7 @@ class GeoClose(GeoGraphyView):
|
||||
event, lat, lon, prevmark)
|
||||
itemoption.append(center)
|
||||
menu.show()
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -369,9 +369,7 @@ class GeoEvents(GeoGraphyView):
|
||||
bookm.show()
|
||||
bookm.connect("activate", self.add_bookmark_from_popup, hdle)
|
||||
itemoption.append(bookm)
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -678,9 +678,7 @@ class GeoFamClose(GeoGraphyView):
|
||||
event, lat, lon, prevmark)
|
||||
itemoption.append(center)
|
||||
menu.show()
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -446,9 +446,7 @@ class GeoFamily(GeoGraphyView):
|
||||
add_item.show()
|
||||
menu.append(add_item)
|
||||
self.add_event_bubble_message(event, lat, lon, prevmark, add_item)
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -610,9 +610,7 @@ class GeoMoves(GeoGraphyView):
|
||||
bookm.connect("activate", self.add_bookmark_from_popup, hdle)
|
||||
itemoption.append(bookm)
|
||||
menu.show()
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -490,9 +490,7 @@ class GeoPerson(GeoGraphyView):
|
||||
center.connect("activate", self.center_here, event, lat, lon, prevmark)
|
||||
itemoption.append(center)
|
||||
menu.show()
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -359,9 +359,7 @@ class GeoPlaces(GeoGraphyView):
|
||||
bookm.show()
|
||||
bookm.connect("activate", self.add_bookmark_from_popup, hdle)
|
||||
itemoption.append(bookm)
|
||||
menu.popup(None, None,
|
||||
lambda menu, data: (event.get_root_coords()[0],
|
||||
event.get_root_coords()[1], True),
|
||||
menu.popup(None, None, None,
|
||||
None, event.button, event.time)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ class MediaView(ListView):
|
||||
msg2 = _("Exactly two media objects must be selected to perform a "
|
||||
"merge. A second object can be selected by holding down the "
|
||||
"control key while clicking on the desired object.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeMedia(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ class NoteView(ListView):
|
||||
msg2 = _("Exactly two notes must be selected to perform a merge. "
|
||||
"A second note can be selected by holding down the "
|
||||
"control key while clicking on the desired note.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeNote(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -981,7 +981,7 @@ class PedigreeView(NavigationView):
|
||||
rela = lst[2*i+1][1]
|
||||
line = LineWidget2(1, rela, self.tree_direction)
|
||||
|
||||
if lst[i] and lst[i][2]:
|
||||
if lst[((i+1) // 2) - 1] and lst[((i+1) // 2) - 1][2]:
|
||||
# Required for popup menu
|
||||
line.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
line.connect("button-press-event",
|
||||
@@ -1494,7 +1494,8 @@ class PedigreeView(NavigationView):
|
||||
alive = probably_alive(person, self.dbstate.db)
|
||||
except RuntimeError:
|
||||
ErrorDialog(_('Relationship loop detected'),
|
||||
_('A person was found to be his/her own ancestor.'))
|
||||
_('A person was found to be his/her own ancestor.'),
|
||||
parent=self.uistate.window)
|
||||
alive = False
|
||||
lst[index] = [person, val, None, alive, None]
|
||||
|
||||
|
||||
@@ -1350,7 +1350,8 @@ class RelationshipView(NavigationView):
|
||||
from gramps.gui.dialog import WarningDialog
|
||||
WarningDialog(
|
||||
_('Broken family detected'),
|
||||
_('Please run the Check and Repair Database tool'))
|
||||
_('Please run the Check and Repair Database tool'),
|
||||
parent=self.uistate.window)
|
||||
return
|
||||
|
||||
father_handle = family.get_father_handle()
|
||||
|
||||
@@ -247,7 +247,7 @@ class RepositoryView(ListView):
|
||||
"merge. A second repository can be selected by holding "
|
||||
"down the control key while clicking on the desired "
|
||||
"repository.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeRepository(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ class SourceView(ListView):
|
||||
msg2 = _("Exactly two sources must be selected to perform a merge. "
|
||||
"A second source can be selected by holding down the "
|
||||
"control key while clicking on the desired source.")
|
||||
ErrorDialog(msg, msg2)
|
||||
ErrorDialog(msg, msg2, parent=self.uistate.window)
|
||||
else:
|
||||
MergeSource(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
|
||||
+4
-4
@@ -216,17 +216,17 @@ class Check_last_char( Check ):
|
||||
|
||||
def __process( self, msg, msgid, msgstr ):
|
||||
msgid_last = msgid[-1:]
|
||||
msgstr_last = unicode(msgstr, encoding='utf-8')[-1:]
|
||||
msgstr_last = msgstr[-1:]
|
||||
if msgid_last.isspace() != msgstr_last.isspace():
|
||||
self.msgs.append( msg )
|
||||
elif (msgid_last == '.') != (msgstr_last == '.' or
|
||||
msgstr_last == u'\u3002' ): # Chinese
|
||||
msgstr_last == '\u3002' ): # Chinese
|
||||
self.msgs.append( msg )
|
||||
elif (msgid_last == ':') != (msgstr_last == ':' or
|
||||
msgstr_last == u'\uff1a' ): # Chinese
|
||||
msgstr_last == '\uff1a' ): # Chinese
|
||||
self.msgs.append( msg )
|
||||
elif (msgid_last == ')') != (msgstr_last == ')' or
|
||||
msgstr_last == u'\uff09' ): # Chinese
|
||||
msgstr_last == '\uff09' ): # Chinese
|
||||
self.msgs.append( msg )
|
||||
|
||||
|
||||
|
||||
+398
-389
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,7 @@ from stat import ST_MODE
|
||||
import io
|
||||
from gramps.version import VERSION
|
||||
import unittest
|
||||
import argparse
|
||||
|
||||
# this list MUST be a subset of _LOCALE_NAMES in gen/utils/grampslocale.py
|
||||
# (that is, if you add a new language here, be sure it's in _LOCALE_NAMES too)
|
||||
@@ -60,6 +61,19 @@ if '--server' in sys.argv:
|
||||
sys.argv.remove('--server')
|
||||
server = True
|
||||
|
||||
# check if the resourcepath option is used and store the path
|
||||
# this is for packagers that build out of the source tree
|
||||
# other options to setup.py are passed through
|
||||
resource_path = ''
|
||||
packaging = False
|
||||
argparser = argparse.ArgumentParser(add_help=False)
|
||||
argparser.add_argument("--resourcepath", dest="resource_path")
|
||||
args, passthrough = argparser.parse_known_args()
|
||||
if args.resource_path:
|
||||
resource_path = args.resource_path
|
||||
packaging = True
|
||||
sys.argv = [sys.argv[0]] + passthrough
|
||||
|
||||
def intltool_version():
|
||||
'''
|
||||
Return the version of intltool as a tuple.
|
||||
@@ -241,7 +255,10 @@ class install(_install):
|
||||
'utils', 'resource-path')
|
||||
with io.open(resource_file, 'w', encoding='utf-8',
|
||||
errors='strict') as fp:
|
||||
path = os.path.abspath(os.path.join(self.install_data, 'share'))
|
||||
if packaging:
|
||||
path = resource_path
|
||||
else:
|
||||
path = os.path.abspath(os.path.join(self.install_data, 'share'))
|
||||
fp.write(path)
|
||||
|
||||
_install.run(self)
|
||||
|
||||
Reference in New Issue
Block a user