diff --git a/data/tests/imp_FTM_PHOTO.ged b/data/tests/imp_FTM_PHOTO.ged
new file mode 100644
index 000000000..acc4b274c
--- /dev/null
+++ b/data/tests/imp_FTM_PHOTO.ged
@@ -0,0 +1,43 @@
+0 HEAD
+1 SOUR FTM
+2 VERS Family Tree Maker (21.0.0.723)
+2 NAME Family Tree Maker for Windows
+2 CORP Ancestry.com
+3 ADDR 360 W 4800 N
+4 CONT Provo, UT 84604
+3 PHON (801) 705-7000
+1 DEST GED55
+1 DATE 11 DEC 2013
+1 CHAR UTF-8
+1 FILE D:\Family Tree Maker\imp_FTM_OCCU_bug.ged
+1 SUBM @SUBM@
+1 GEDC
+2 VERS 5.5
+2 FORM LINEAGE-LINKED
+0 @SUBM@ SUBM
+0 @I1@ INDI
+1 NAME The /Tester/
+1 NOTE The primary photo should be a male Sourpuss in a Hat 03.jpg or Gid:M3
+1 _PHOTO @M3@
+1 OBJE @M1@
+1 OBJE @M2@
+1 OBJE @M3@
+1 OBJE @M4@
+1 OBJE @M5@
+0 @M1@ OBJE
+1 FILE O1.jpg
+2 TITL Ferry Arriving 1910
+0 @M2@ OBJE
+1 FILE O2.jpg
+2 TITL B&W Kids
+0 @M3@ OBJE
+1 FILE O3.jpg
+2 TITL Sourpuss in Hat
+1 NOTE Should be the selected primary photo
+0 @M4@ OBJE
+1 FILE O4.jpg
+2 TITL Girl Eating
+0 @M5@ OBJE
+1 FILE O5.jpg
+2 TITL Edwin & Janice Smith
+0 TRLR
diff --git a/data/tests/imp_FTM_PHOTO.gramps b/data/tests/imp_FTM_PHOTO.gramps
new file mode 100644
index 000000000..5f6c53558
--- /dev/null
+++ b/data/tests/imp_FTM_PHOTO.gramps
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+ U
+
+ The
+ Tester
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The primary photo should be a male Sourpuss in a Hat 03.jpg or Gid:M3
+
+
+ Records not imported into OBJE (multi-media object) Gramps ID M1:
+
+Could not import O1.jpg Line 28: 1 FILE O1.jpg
+
+
+
+ Records not imported into OBJE (multi-media object) Gramps ID M2:
+
+Could not import O2.jpg Line 31: 1 FILE O2.jpg
+
+
+
+ Should be the selected primary photo
+
+
+ Records not imported into OBJE (multi-media object) Gramps ID M3:
+
+Could not import O3.jpg Line 34: 1 FILE O3.jpg
+
+
+
+ Records not imported into OBJE (multi-media object) Gramps ID M4:
+
+Could not import O4.jpg Line 38: 1 FILE O4.jpg
+
+
+
+ Records not imported into OBJE (multi-media object) Gramps ID M5:
+
+Could not import O5.jpg Line 41: 1 FILE O5.jpg
+
+
+
+
diff --git a/gramps/plugins/lib/libgedcom.py b/gramps/plugins/lib/libgedcom.py
index e4f436c2e..bc69271c9 100755
--- a/gramps/plugins/lib/libgedcom.py
+++ b/gramps/plugins/lib/libgedcom.py
@@ -267,6 +267,7 @@ TOKEN__MAR = 128
TOKEN__MARN = 129
TOKEN__ADPN = 130
TOKEN__FSFTID = 131
+TOKEN__PHOTO = 132
TOKENS = {
"HEAD" : TOKEN_HEAD, "MEDI" : TOKEN_MEDI,
@@ -373,6 +374,7 @@ TOKENS = {
"_URL" : TOKEN_URL, "URL" : TOKEN_URL,
"_MAR" : TOKEN__MAR, "_MARN" : TOKEN__MARN,
"_ADPN" : TOKEN__ADPN, "_FSFTID" : TOKEN__FSFTID,
+ "_PHOTO" : TOKEN__PHOTO,
}
ADOPT_NONE = 0
@@ -1622,6 +1624,7 @@ class CurrentState:
self.repo_ref = None
self.place = None
self.media = None
+ self.photo = "" # prc Person primary photo
def __getattr__(self, name):
"""
@@ -2087,6 +2090,7 @@ class GedcomParser(UpdateCallback):
TOKEN_URL : self.__person_url,
TOKEN__TODO : self.__skip_record,
TOKEN_TITL : self.__person_titl,
+ TOKEN__PHOTO: self.__person_photo,
}
self.func_list.append(self.indi_parse_tbl)
@@ -3596,6 +3600,9 @@ class GedcomParser(UpdateCallback):
# Add a default tag if provided
self.__add_default_tag(person)
+ # Set up primary photo if present
+ self.__do_photo(state)
+
self.__check_msgs(_("INDI (individual) Gramps ID %s") %
person.get_gramps_id(), state, person)
# commit the person to the database
@@ -3798,6 +3805,13 @@ class GedcomParser(UpdateCallback):
self.__add_msg(_("Form omitted"), line, state)
self.build_media(state.person, form, filename, title, note)
+ def __person_photo(self, line, state):
+ """
+ This handles the FTM _PHOTO feature, which identifies an OBJE to use
+ as the person's primary photo.
+ """
+ state.photo = line.data # Just save it for now.
+
def __person_name(self, line, state):
"""
Parsers the NAME token in a GEDCOM file. The text is in the format
@@ -7650,6 +7664,30 @@ class GedcomParser(UpdateCallback):
event_ref.set_reference_handle(event.handle)
return event_ref
+ def __do_photo(self, state):
+ """
+ Choose the primary photo from the list of media present for this
+ person. Supports FTM _PHOTO feature.
+ 0 INDI
+ +1 _PHOTO @@ {1:1}
+ Since Gramps currently uses the first media in the list as the
+ primary, find the primary photo if already in the list, if present,
+ move to beginning. If not present, add at the beginning.
+ This is run after all of the person processing is complete but before
+ committing the person.
+ """
+ if state.photo:
+ gramps_id = self.oid_map[state.photo]
+ handle = self.__find_media_handle(gramps_id)
+ for mref in state.person.media_list:
+ if handle == mref.ref:
+ state.person.media_list.remove(mref)
+ state.person.media_list.insert(0, mref)
+ return
+ mref = MediaRef()
+ mref.set_reference_handle(handle)
+ state.person.media_list.insert(0, mref)
+
def __extract_temple(self, line):
def get_code(code):
if TEMPLES.is_valid_code(code):