* src/data/gnome-mime-application-x-geneweb.png: Add to CVS.

* src/data/Makefile.am, src/plugins/Makefile.am: Ship new files.

* src/plugins/ImportGeneWeb.py, src/plugins/WriteGeneWeb.py,
src/plugins/genewebexport.glade: Add to CVS.
* src/data/gramps.applications, src/data/gramps.keys,
src/data/gramps.mime, src/data/gramps.xml: Add GeneWeb format.


svn: r3572
This commit is contained in:
Alex Roitman 2004-09-24 22:42:21 +00:00
parent f61ab522d9
commit f57fa24b10
11 changed files with 1699 additions and 3 deletions

View File

@ -1,3 +1,13 @@
2004-09-24 Alex Roitman <shura@alex.neuro.umn.edu>
* src/data/gnome-mime-application-x-geneweb.png: Add to CVS.
* src/data/Makefile.am, src/plugins/Makefile.am: Ship new files.
2004-09-24 Martin Hawlisch <Martin.Hawlisch@gmx.de>
* src/plugins/ImportGeneWeb.py, src/plugins/WriteGeneWeb.py,
src/plugins/genewebexport.glade: Add to CVS.
* src/data/gramps.applications, src/data/gramps.keys,
src/data/gramps.mime, src/data/gramps.xml: Add GeneWeb format.
2004-09-24 Don Allingham <dallingham@users.sourceforge.net>
* src/DateDisplay.py: use LC_TIME and D_FMT to determine
the locale date format

View File

@ -10,6 +10,7 @@ dist_pkgdata_DATA = \
gnome-mime-application-x-gedcom.png \
gnome-mime-application-x-gramps-package.png \
gnome-mime-application-x-gramps-xml.png \
gnome-mime-application-x-geneweb.png \
gramps.applications \
gramps.desktop \
gramps.svg \

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -4,4 +4,4 @@ gramps
can_open_multiple_files=false
expects_uris=false
requires_terminal=false
mime_types=application/x-gramps,application/x-gedcom,application/x-gramps-package,application/x-gramps-xml
mime_types=application/x-gramps,application/x-gedcom,application/x-gramps-package,application/x-gramps-xml,application/x-geneweb

View File

@ -41,3 +41,14 @@ application/x-gedcom:
category=Documents/Genealogy
icon-filename=/usr/share/gramps/gramps.png
open=gramps %f
application/x-geneweb:
description=GeneWeb
default_action_type=application
short_list_application_ids=gramps
short_list_application_ids_for_novice_user_level=gramps
short_list_application_ids_for_intermediate_user_level=gramps
short_list_application_ids_for_advanced_user_level=gramps
category=Documents/Genealogy
icon-filename=/usr/share/gramps/gramps.png
open=gramps %f

View File

@ -9,3 +9,6 @@ application/x-gramps-package
application/x-gedcom
ext: ged gedcom GED GEDCOM
application/x-geneweb
ext: gw GW

View File

@ -16,4 +16,8 @@
<comment xml:lang="en">GRAMPS XML database</comment>
<glob pattern="*.gramps"/>
</mime-type>
<mime-type type="application/x-geneweb">
<comment xml:lang="en">GeneWeb source file</comment>
<glob pattern="*.gw"/>
</mime-type>
</mime-info>

View File

@ -0,0 +1,689 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2004 Martin Hawlisch, Donald N. Allingham
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"Import from GeneWeb"
#-------------------------------------------------------------------------
#
# standard python modules
#
#-------------------------------------------------------------------------
import os
import re
import string
import const
import time
#-------------------------------------------------------------------------
#
# GTK/GNOME Modules
#
#-------------------------------------------------------------------------
import gtk
import gtk.glade
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import Errors
import RelLib
import Date
import DateHandler
import latin_utf8
import Utils
from QuestionDialog import ErrorDialog
from gettext import gettext as _
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def importData(database, filename, cb=None):
global callback
try:
g = GeneWebParser(database,filename)
except IOError,msg:
ErrorDialog(_("%s could not be opened\n") % filename,str(msg))
return
except:
ErrorDialog(_("%s could not be opened\n") % filename)
import DisplayTrace
DisplayTrace.DisplayTrace()
return
try:
status = g.parse_geneweb_file()
except IOError,msg:
errmsg = _("%s could not be opened\n") % filename
ErrorDialog(errmsg,str(msg))
return
except:
import DisplayTrace
DisplayTrace.DisplayTrace()
return
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
class GeneWebParser:
def __init__(self, dbase, file):
self.db = dbase
self.f = open(file,"rU")
self.filename = file
self.dp = DateHandler.create_parser()
def get_next_line(self):
line = self.f.readline()
if line:
line = line.strip()
else:
line = None
return line
def parse_geneweb_file(self):
self.trans = self.db.transaction_begin()
t = time.time()
self.index = 0
self.fam_count = 0
self.indi_count = 0
self.fkeys = []
self.ikeys = {}
self.pkeys = {}
self.skeys = {}
self.current_mode = None
self.current_family = None
self.current_husband_handle = None
try:
while 1:
line = self.get_next_line()
if line == None:
break
if line == "":
continue
fields = line.split(" ")
print "LINE: %s" %line
if fields[0] == "fam":
self.read_family_line(line,fields)
elif fields[0] == "src":
self.read_source_line(line,fields)
elif fields[0] == "wit":
self.read_witness_line(line,fields)
elif fields[0] == "cbp":
self.read_children_birthplace_line(line,fields)
elif fields[0] == "beg":
self.read_children_lines()
elif fields[0] == "comm":
self.read_family_comment(line,fields)
elif fields[0] == "notes":
self.read_notes_lines(line,fields)
elif fields[0] == "end":
self.current_mode = None
else:
print "Token >%s< unknown. line skipped: %s" % (fields[0],line)
except Errors.GedcomError, err:
self.errmsg(str(err))
t = time.time() - t
msg = _('Import Complete: %d seconds') % t
self.db.transaction_commit(self.trans,_("GeneWeb import"))
print msg
print "Families: %d" % len(self.fkeys)
print "Individuals: %d" % len(self.ikeys)
return None
def read_family_line(self,line,fields):
self.current_husband_handle = None
self.current_family = RelLib.Family()
self.db.add_family(self.current_family,self.trans)
self.db.commit_family(self.current_family,self.trans)
self.fkeys.append(self.current_family.get_handle())
idx = 1;
print "\nHusband:"
(idx,husband) = self.parse_person(fields,idx,RelLib.Person.male,None)
if husband:
self.current_husband_handle = husband.get_handle()
self.current_family.set_father_handle(husband.get_handle())
self.db.commit_family(self.current_family,self.trans)
husband.add_family_handle(self.current_family.get_handle())
self.db.commit_person(husband,self.trans)
print "Marriage:"
idx = self.parse_marriage(fields,idx)
print "Wife:"
(idx,wife) = self.parse_person(fields,idx,RelLib.Person.female,None)
if wife:
self.current_family.set_mother_handle(wife.get_handle())
self.db.commit_family(self.current_family,self.trans)
wife.add_family_handle(self.current_family.get_handle())
self.db.commit_person(wife,self.trans)
return None
def read_source_line(self,line,fields):
if not self.current_family:
print "Unknown family of child!"
return None
source = self.get_or_create_source(self.decode(fields[1]))
self.current_family.add_source_reference(source)
self.db.commit_family(self.current_family,self.trans)
return None
def read_witness_line(self,line,fields):
print "Witness:"
if fields[1] == "m:":
self.parse_person(fields,2,RelLib.Person.male,None)
elif fields[1] == "f:":
self.parse_person(fields,2,RelLib.Person.female,None)
else:
self.parse_person(fields,1,None,None)
return None
def read_children_lines(self):
father_surname = "Dummy"
if not self.current_husband_handle:
print "Unknown father for child!"
return None
husb = self.db.get_person_from_handle(self.current_husband_handle)
father_surname = husb.get_primary_name().get_surname()
if not self.current_family:
print "Unknown family of child!"
return None
while 1:
line = self.get_next_line()
if line == None:
break
if line == "":
continue
fields = line.split(" ")
if fields[0] == "-":
print "Child:"
child = None
if fields[1] == "h":
(idx,child) = self.parse_person(fields,2,RelLib.Person.male,father_surname)
elif fields[1] == "f":
(idx,child) = self.parse_person(fields,2,RelLib.Person.female,father_surname)
else:
(idx,child) = self.parse_person(fields,1,None,father_surname)
if child:
self.current_family.add_child_handle(child.get_handle())
self.db.commit_family(self.current_family,self.trans)
child.add_parent_family_handle(self.current_family.get_handle(),"Birth","Birth")
self.db.commit_person(child,self.trans)
else:
break
return None
def read_children_birthplace_line(self,line,fields):
return None
def read_family_comment(self,line,fields):
if not self.current_family:
print "Unknown family of child!"
return None
self.current_family.set_note(self.cnv(line))
self.db.commit_family(self.current_family,self.trans)
return None
def read_notes_lines(self,line,fields):
(idx,person) = self.parse_person(fields,1,None,None)
note_txt = ""
while 1:
line = self.get_next_line()
if line == None:
break
fields = line.split(" ")
if fields[0] == "end" and fields[1] == "notes":
break
elif fields[0] == "beg":
continue
else:
if note_txt:
note_txt = note_txt + "\n" + self.cnv(line)
else:
note_txt = note_txt + self.cnv(line)
if note_txt:
person.set_note(note_txt)
self.db.commit_person(person,self.trans)
return None
def parse_marriage(self,fields,idx):
mdate = self.parse_date(fields[idx])
mariageDataRe = re.compile("^[+#-0-9].*$")
mar_date = None
mar_place = None
mar_source = None
sep_date = None
div_date = None
married = 1
engaged = 0
# skip to marriage date in case person contained unmatches tokens
#Alex: this failed when fields[idx] was an empty line. Fixed.
#while idx < len(fields) and not fields[idx][0] == "+":
while idx < len(fields) and not (fields[idx] and fields[idx][0] == "+"):
print "Unknown field: "+fields[idx]
idx = idx + 1
while idx < len(fields) and mariageDataRe.match(fields[idx]):
if fields[idx][0] == "+":
mar_date = self.parse_date(self.decode(fields[idx]))
print " Married at: %s" % fields[idx]
idx = idx + 1
elif fields[idx][0] == "-":
div_date = self.parse_date(self.decode(fields[idx]))
print " Div at: %s" % fields[idx]
idx = idx + 1
elif fields[idx] == "#mp":
idx = idx + 1
mar_place = self.get_or_create_place(self.decode(fields[idx]))
print " Marriage place: %s" % fields[idx]
idx = idx + 1
elif fields[idx] == "#ms":
idx = idx + 1
mar_source = self.get_or_create_source(self.decode(fields[idx]))
print " Marriage source: %s" % fields[idx]
idx = idx + 1
elif fields[idx] == "#sep":
idx = idx + 1
sep_date = self.parse_date(self.decode(fields[idx]))
print " Seperated since: %s" % fields[idx]
idx = idx + 1
elif fields[idx] == "#np":
print " Are not married."
married = 0
idx = idx + 1
elif fields[idx] == "#eng":
print " Are engaged."
engaged = 1
idx = idx + 1
else:
print "Unknown field for mariage: %s" % fields[idx]
idx = idx + 1
if mar_date or mar_place or mar_source:
mar = self.create_event("Marriage", None, mar_date, mar_place, mar_source)
self.current_family.add_event_handle(mar.get_handle())
if div_date:
div = self.create_event("Divorce", None, div_date, None, None)
self.current_family.add_event_handle(div.get_handle())
if sep_date or engaged:
sep = self.create_event("Engagement", None, sep_date, None, None)
self.current_family.add_event_handle(sep.get_handle())
if not married:
self.current_family.set_relationship(const.FAMILY_UNMARRIED)
self.db.commit_family(self.current_family,self.trans)
return idx
def parse_person(self,fields,idx,gender,father_surname):
firstname = ""
surname = ""
occupation = ""
birthplace = ""
alias = ""
if not father_surname:
if not idx < len(fields):
print "Missing surname of person"
return (idx,None)
surname = self.decode(fields[idx])
idx = idx + 1
else:
surname = father_surname
if not idx < len(fields):
print "Missing firstname of person"
return (idx,None)
firstname = self.decode(self.cnv(fields[idx]))
idx = idx + 1
if idx < len(fields) and father_surname:
noSurnameRe = re.compile("^[({\[~><?0-9#].*$")
if not noSurnameRe.match(self.cnv(fields[idx])):
surname = self.decode(fields[idx])
idx = idx + 1
print "Person: %s %s" % (firstname, surname)
person = self.get_or_create_person(firstname,surname)
name = RelLib.Name()
name.set_type("Birth Name")
name.set_first_name(firstname)
name.set_surname(surname)
person.set_primary_name(name)
if gender != None:
person.set_gender(gender)
self.db.commit_person(person,self.trans)
personDataRe = re.compile("^[0-9<>~#\[({!].*$")
dateRe = re.compile("^[0-9~<>?]+.*$")
source = None
birth_date = None
birth_place = None
birth_source = None
bapt_date = None
bapt_place = None
bapt_source = None
death_date = None
death_place = None
death_source = None
crem_date = None
bur_date = None
bur_place = None
bur_source = None
public_name = None
firstname_aliases = []
nick_names = []
name_aliases = []
surname_aliases = []
while idx < len(fields) and personDataRe.match(fields[idx]):
if fields[idx][0] == '(':
print "Public Name: %s" % fields[idx]
public_name = self.decode(fields[idx])
idx = idx + 1
elif fields[idx][0] == '{':
print "Firstsname Alias: %s" % fields[idx]
firstname_aliases.append(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx][0] == '[':
print "Titles: %s" % fields[idx]
idx = idx + 1
elif fields[idx] == '#nick':
idx = idx + 1
print "Nick Name: %s" % fields[idx]
nick_names.append(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#occu':
idx = idx + 1
print "Occupation: %s" % fields[idx]
occu = self.create_event("Occupation",self.decode(fields[idx]))
person.add_event_handle(occu.get_handle())
self.db.commit_person(person,self.trans)
idx = idx + 1
elif fields[idx] == '#alias':
idx = idx + 1
print "Name Alias: %s" % fields[idx]
name_aliases.append(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#salias':
idx = idx + 1
print "Surname Alias: %s" % fields[idx]
surname_aliases.append(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#image':
idx = idx + 1
print "Image: %s" % fields[idx]
idx = idx + 1
elif fields[idx] == '#src':
idx = idx + 1
print "Source: %s" % fields[idx]
source = self.get_or_create_source(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#bs':
idx = idx + 1
print "Birth Source: %s" % fields[idx]
birth_source = self.get_or_create_source(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx][0] == '!':
print "Baptize at: %s" % fields[idx]
bapt_date = self.parse_date(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#bp':
idx = idx + 1
print "Birth Place: %s" % fields[idx]
birth_place = self.get_or_create_place(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#pp':
idx = idx + 1
print "Baptize Place: %s" % fields[idx]
bapt_place = self.get_or_create_place(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#ps':
idx = idx + 1
print "Baptize Source: %s" % fields[idx]
bapt_source = self.get_or_create_source(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#dp':
idx = idx + 1
print "Death Place: %s" % fields[idx]
death_place = self.get_or_create_place(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#ds':
idx = idx + 1
print "Death Source: %s" % fields[idx]
death_source = self.get_or_create_source(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#buri':
idx = idx + 1
print "Burial Date: %s" % fields[idx]
bur_date = self.parse_date(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#crem':
idx = idx + 1
print "Cremention Date: %s" % fields[idx]
crem_date = self.parse_date(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#bp':
idx = idx + 1
print "Burial Place: %s" % fields[idx]
bur_place = self.get_or_create_place(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#rs':
idx = idx + 1
print "Burial Source: %s" % fields[idx]
bur_source = self.get_or_create_source(self.decode(fields[idx]))
idx = idx + 1
elif fields[idx] == '#apubl':
print "This is a public record"
idx = idx + 1
elif fields[idx] == '#apriv':
print "This is a private record"
idx = idx + 1
elif dateRe.match( fields[idx]):
if not birth_date:
print "Birth Date: %s" % fields[idx]
birth_date = self.parse_date(self.decode(fields[idx]))
else:
print "Death Date: %s" % fields[idx]
death_date = self.parse_date(self.decode(fields[idx]))
idx = idx + 1
else:
print "Unknown field for person: %s" % fields[idx]
idx = idx + 1
if public_name:
name = person.get_primary_name()
name.set_type("Birth Name")
person.add_alternate_name(name)
name = RelLib.Name()
name.set_type("Also Known As")
name.set_first_name(public_name)
name.set_surname(surname)
person.set_primary_name(name)
i = 0
for aka in nick_names:
if i == 0:
person.set_nick_name(aka)
else:
name = RelLib.Name()
name.set_type("Also Known As")
name.set_first_name(aka)
name.set_surname(surname)
person.add_alternate_name(name)
i = i + 1
for aka in firstname_aliases:
name = RelLib.Name()
name.set_type("Also Known As")
name.set_first_name(aka)
name.set_surname(surname)
person.add_alternate_name(name)
for aka in name_aliases:
name = RelLib.Name()
name.set_type("Also Known As")
name.set_first_name(aka)
name.set_surname(surname)
person.add_alternate_name(name)
for aka in surname_aliases:
name = RelLib.Name()
name.set_type("Also Known As")
if public_name:
name.set_first_name(public_name)
else:
name.set_first_name(firstname)
name.set_surname(aka)
person.add_alternate_name(name)
if source:
person.add_source_reference(source)
if birth_date or birth_place or birth_source:
birth = self.create_event("Birth", None, birth_date, birth_place, birth_source)
person.set_birth_handle(birth.get_handle())
if bapt_date or bapt_place or bapt_source:
babt = self.create_event("Baptism", None, bapt_date, bapt_place, bapt_source)
person.add_event_handle(babt.get_handle())
if death_date or death_place or death_source:
babt = self.create_event("Death", None, death_date, death_place, death_source)
person.set_death_handle(babt.get_handle())
if bur_date:
babt = self.create_event("Burial", None, bur_date, bur_place, bur_source)
person.add_event_handle(babt.get_handle())
if crem_date:
babt = self.create_event("Cremation", None, crem_date, bur_place, bur_source)
person.add_event_handle(babt.get_handle())
self.db.commit_person(person,self.trans)
return (idx,person)
def parse_date(self,field):
#Alex: this should do the trick
date = self.dp.parse(field)
return date
def create_event(self,type,desc=None,date=None,place=None,source=None):
event = RelLib.Event()
if type:
event.set_name(type)
if desc:
event.set_description(desc)
if date:
event.set_date_object(date)
if place:
event.set_place_handle(place.get_handle())
if source:
event.add_source_reference(source)
self.db.add_event(event,self.trans)
self.db.commit_event(event,self.trans)
return event
def get_or_create_person(self,firstname,lastname):
person = None
mykey = firstname+lastname
if mykey in self.ikeys:
person = self.db.get_person_from_handle(self.ikeys[mykey])
else:
person = RelLib.Person()
self.db.add_person(person,self.trans)
self.db.commit_person(person,self.trans)
self.ikeys[mykey] = person.get_handle()
return person
def get_or_create_place(self,place_name):
place = None
if place_name in self.pkeys:
person = self.db.get_place_from_handle(self.pkeys[place_name])
else:
place = RelLib.Place()
place.set_title(place_name)
self.db.add_place(place,self.trans)
self.db.commit_place(place,self.trans)
self.pkeys[place_name] = place.get_handle()
return place
def get_or_create_source(self,source_name):
source = None
if source_name in self.skeys:
source = self.db.get_source_from_handle(self.skeys[source_name])
else:
source = RelLib.Source()
source.set_title(source_name)
self.db.add_source(source,self.trans)
self.db.commit_source(source,self.trans)
self.skeys[source_name] = source.get_handle()
sref = RelLib.SourceRef()
sref.set_base_handle(source.get_handle())
return sref
def decode(self,s):
return( latin_utf8.latin_to_utf8( s.replace('_',' ')))
def cnv(seld,s):
return( latin_utf8.latin_to_utf8(s))
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
_mime_type = 'application/x-geneweb'
_filter = gtk.FileFilter()
_filter.set_name(_('GeneWeb files'))
_filter.add_mime_type(_mime_type)
from Plugins import register_import
register_import(importData,_filter,_mime_type,1)

View File

@ -55,7 +55,10 @@ pkgdata_PYTHON = \
rel_fi.py\
rel_fr.py\
rel_no.py\
rel_sv.py
rel_sv.py\
ImportGeneWeb.py\
WriteGeneWeb.py
pkgpyexecdir = @pkgpyexecdir@/plugins
pkgpythondir = @pkgpythondir@/plugins
@ -74,7 +77,8 @@ GLADEFILES = \
eval.glade\
leak.glade\
book.glade\
writeftree.glade
writeftree.glade\
genewebexport.glade
dist_pkgdata_DATA = $(GLADEFILES)

View File

@ -0,0 +1,587 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004 Martin Hawlisch
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"Export to GeneWeb"
#-------------------------------------------------------------------------
#
# Standard Python Modules
#
#-------------------------------------------------------------------------
import os
import string
import time
import re
#-------------------------------------------------------------------------
#
# GNOME/GTK modules
#
#-------------------------------------------------------------------------
import gtk
import gtk.glade
import gnome
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import RelLib
import GenericFilter
import const
import Utils
import Date
import Errors
from gettext import gettext as _
from QuestionDialog import ErrorDialog
_title_string = _("Export to GeneWeb")
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
class GeneWebWriterOptionBox:
"""
Create a VBox with the option widgets and define methods to retrieve
the options.
"""
def __init__(self,person):
self.person = person
def get_option_box(self):
self.restrict = 1
self.private = 1
glade_file = "%s/genewebexport.glade" % os.path.dirname(__file__)
if not os.path.isfile(glade_file):
glade_file = "plugins/genewebexport.glade"
self.topDialog = gtk.glade.XML(glade_file,"genewebExport","gramps")
self.topDialog.signal_autoconnect({
"on_restrict_toggled": self.on_restrict_toggled
})
filter_obj = self.topDialog.get_widget("filter")
self.copy = 0
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name())
des.add_rule(GenericFilter.IsDescendantOf([self.person.get_handle(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf([self.person.get_handle(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith([self.person.get_handle()]))
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
filter_obj.set_menu(self.filter_menu)
the_box = self.topDialog.get_widget('vbox1')
the_parent = self.topDialog.get_widget('dialog-vbox1')
the_parent.remove(the_box)
self.topDialog.get_widget("genewebExport").destroy()
return the_box
def on_restrict_toggled(self,restrict):
active = restrict.get_active ()
map (lambda x: x.set_sensitive (active),
[self.topDialog.get_widget("living"),
self.topDialog.get_widget("notes"),
self.topDialog.get_widget("sources")])
def parse_options(self):
self.restrict = self.topDialog.get_widget("restrict").get_active()
self.living = (self.restrict and
self.topDialog.get_widget("living").get_active())
self.exclnotes = (self.restrict and
self.topDialog.get_widget("notes").get_active())
self.exclsrcs = (self.restrict and
self.topDialog.get_widget("sources").get_active())
self.private = self.topDialog.get_widget("private").get_active()
self.cfilter = self.filter_menu.get_active().get_data("filter")
self.images = self.topDialog.get_widget ("images").get_active ()
if self.images:
images_path = self.topDialog.get_widget ("images_path")
self.images_path = unicode(images_path.get_text ())
else:
self.images_path = ""
class GeneWebWriter:
def __init__(self,database,person,cl=0,filename="",option_box=None):
self.db = database
self.person = person
self.option_box = option_box
self.cl = cl
self.filename = filename
self.plist = {}
self.flist = {}
self.persons_details_done = []
self.persons_notes_done = []
self.person_ids = {}
if not option_box:
self.cl_setup()
else:
self.option_box.parse_options()
self.restrict = self.option_box.restrict
self.living = self.option_box.living
self.exclnotes = self.option_box.exclnotes
self.exclsrcs = self.option_box.exclsrcs
self.private = self.option_box.private
self.copy = self.option_box.copy
self.images = self.option_box.images
self.images_path = self.option_box.images_path
if self.option_box.cfilter == None:
for p in self.db.get_person_handles(sort_handles=False):
self.plist[p] = 1
else:
try:
for p in self.option_box.cfilter.apply(self.db, self.db.get_person_handles(sort_handles=False)):
self.plist[p] = 1
except Errors.FilterError, msg:
(m1,m2) = msg.messages()
ErrorDialog(m1,m2)
return
self.flist = {}
for key in self.plist:
p = self.db.get_person_from_handle(key)
for family_handle in p.get_family_handle_list():
self.flist[family_handle] = 1
def cl_setup(self):
self.restrict = 0
self.private = 0
self.copy = 0
self.images = 0
for p in self.db.get_person_handles(sort_handles=False):
self.plist[p] = 1
self.flist = {}
for key in self.plist:
p = self.db.get_person_from_handle(key)
for family_handle in p.get_family_handle_list():
self.flist[family_handle] = 1
def writeln(self,text):
self.g.write(self.iso8859('%s\n' % (text)))
def export_data(self,filename):
self.dirname = os.path.dirname (filename)
try:
self.g = open(filename,"w")
except IOError,msg:
msg2 = _("Could not create %s") % filename
ErrorDialog(msg2,str(msg))
return 0
except:
ErrorDialog(_("Could not create %s") % filename)
return 0
if len(self.flist) < 1:
ErrorDialog(_("No families matched by selected filter"))
return 0
for key in self.flist:
self.write_family(key)
self.writeln("")
self.g.close()
return 1
def write_family(self,family_handle):
family = self.db.get_family_from_handle(family_handle)
if family:
father_handle = family.get_father_handle()
if father_handle:
father = self.db.get_person_from_handle(father_handle)
mother_handle = family.get_mother_handle()
if mother_handle:
mother = self.db.get_person_from_handle(mother_handle)
self.writeln("fam %s %s +%s %s %s" % (self.get_ref_name(father), self.get_full_person_info_fam(father), self.get_wedding_data(family), self.get_ref_name(mother), self.get_full_person_info_fam(mother)))
self.write_witness( family)
self.write_sources( family.get_source_references())
self.write_children( family, father)
self.write_notes( family, father, mother)
if not (self.restrict and self.exclnotes):
note = family.get_note()
if note and note != "":
note = note.replace('\n\r',' ')
note = note.replace('\r\n',' ')
note = note.replace('\n',' ')
note = note.replace('\r',' ')
self.writeln("comm %s" % note)
def write_witness(self,family):
if self.restrict:
return
event_list = family.get_event_list()
for event_handle in event_list:
event = self.db.get_event_from_handle(event_handle)
if event.get_name() == "Marriage":
w_list = event.get_witness_list()
if w_list:
for witness in w_list:
if witness and witness.type == RelLib.Event.ID:
person = self.db.get_person_from_handle(witness.get_value())
if person:
gender = ""
if person.get_gender() == RelLib.Person.male:
gender = "h"
elif person.get_gender() == RelLib.Person.female:
gender = "f"
self.writeln("wit %s %s %s" % (gender, self.get_ref_name(person), self.get_full_person_info_fam(person)))
def write_sources(self,reflist):
if self.restrict and self.exclnotes:
return
if reflist:
for sr in reflist:
sbase = sr.get_base_handle()
if sbase:
source = self.db.get_source_from_handle(sbase)
if source:
self.writeln( "src %s" % (self.rem_spaces(source.get_title())))
def write_children(self,family, father):
father_lastname = father.get_primary_name().get_surname()
child_list = family.get_child_handle_list()
if child_list:
self.writeln("beg")
for child_handle in child_list:
child = self.db.get_person_from_handle(child_handle)
if child:
gender = ""
if child.get_gender() == RelLib.Person.male:
gender = "h"
elif child.get_gender() == RelLib.Person.female:
gender = "f"
self.writeln("- %s %s %s" % (gender, self.get_child_ref_name(child, father_lastname), self.get_full_person_info_child(child)))
self.writeln("end")
def write_notes(self,family, father, mother):
if self.restrict and self.exclnotes:
return
self.write_note_of_person(father)
self.write_note_of_person(mother)
child_list = family.get_child_handle_list()
if child_list:
for child_handle in child_list:
child = self.db.get_person_from_handle(child_handle)
if child:
self.write_note_of_person(child)
event_list = family.get_event_list()
for event_handle in event_list:
event = self.db.get_event_from_handle(event_handle)
if event.get_name() == "Marriage":
w_list = event.get_witness_list()
if w_list:
for witness in w_list:
if witness and witness.type == RelLib.Event.ID:
person = self.db.get_person_from_handle(witness.get_value())
if person:
self.write_note_of_person(person)
def write_note_of_person(self,person):
if self.persons_notes_done.count(person.get_handle()) == 0:
self.persons_notes_done.append(person.get_handle())
note = person.get_note()
if note and note != "":
self.writeln("")
self.writeln("notes %s" % self.get_ref_name(person))
self.writeln("beg")
self.writeln(note)
self.writeln("end notes")
def get_full_person_info(self, person):
if self.restrict:
return "0 "
retval = ""
b_date = "0"
b_place = ""
birth_handle = person.get_birth_handle()
if birth_handle:
birth = self.db.get_event_from_handle(birth_handle)
if birth:
b_date = self.format_date( birth.get_date_object())
place_handle = birth.get_place_handle()
if place_handle:
place = self.db.get_place_from_handle(place_handle)
b_place = place.get_title()
if person.probably_alive(self.db):
d_date = ""
else:
d_date = "0"
d_place = ""
death_handle = person.get_death_handle()
if death_handle:
death = self.db.get_event_from_handle(death_handle)
if death:
d_date = self.format_date( death.get_date_object())
place_handle = death.get_place_handle()
if place_handle:
place = self.db.get_place_from_handle(place_handle)
d_place = place.get_title()
retval = retval + "%s " % b_date
if b_place != "":
retval = retval + "#bp %s " % self.rem_spaces(b_place)
retval = retval + "%s " % d_date
if d_place != "":
retval = retval + "#dp %s " % self.rem_spaces(d_place)
return retval
def get_full_person_info_fam(self, person):
"""Output full person data of a family member only if the person is not listed as a child"""
retval = ""
if self.persons_details_done.count(person.get_handle()) == 0:
is_child = 0
pf_list = person.get_parent_family_handle_list()
if pf_list:
for (family_handle,mrel,frel) in pf_list:
if self.flist.has_key(family_handle):
is_child = 1
if is_child == 0:
self.persons_details_done.append(person.get_handle())
retval = self.get_full_person_info(person)
return retval
def get_full_person_info_child(self, person):
"""Output full person data for a child, if not printed somewhere else"""
retval = ""
if self.persons_details_done.count(person.get_handle()) == 0:
self.persons_details_done.append(person.get_handle())
retval = self.get_full_person_info(person)
return retval
def rem_spaces(self,string):
string = string.replace(' ','_')
return string
def get_ref_name(self,person):
surname = self.rem_spaces( person.get_primary_name().get_surname())
firstname = "Living"
if not (person.probably_alive(self.db) and self.restrict and self.living):
firstname = self.rem_spaces( person.get_primary_name().get_first_name())
if not self.person_ids.has_key(person.get_handle()):
self.person_ids[person.get_handle()] = len(self.person_ids)
ret = "%s %s.%d" % (surname, firstname, self.person_ids[person.get_handle()])
return ret
def get_child_ref_name(self,person,father_lastname):
surname = self.rem_spaces( person.get_primary_name().get_surname())
firstname = "Living"
if not (person.probably_alive(self.db) and self.restrict and self.living):
firstname = self.rem_spaces( person.get_primary_name().get_first_name())
if not self.person_ids.has_key(person.get_handle()):
self.person_ids[person.get_handle()] = len(self.person_ids)
if surname != father_lastname:
ret = "%s.%d %s" % (firstname, self.person_ids[person.get_handle()], surname)
else:
ret = "%s.%d" % (firstname, self.person_ids[person.get_handle()])
return ret
def get_wedding_data(self,family):
ret = "";
event_list = family.get_event_list()
m_date = ""
m_place = ""
m_source = ""
married = 0
eng_date = ""
eng_place = ""
eng_source = ""
engagend = 0
div_date = ""
divorced = 0
for event_handle in event_list:
event = self.db.get_event_from_handle(event_handle)
if event.get_name() == "Marriage":
married = 1
m_date = self.format_date( event.get_date_object())
place_handle = event.get_place_handle()
if place_handle:
place = self.db.get_place_from_handle(place_handle)
m_place = place.get_title()
m_source = self.get_primary_source( event.get_source_references())
if event.get_name() == "Engagement":
engagend = 1
eng_date = self.format_date( event.get_date_object())
place_handle = event.get_place_handle()
if place_handle:
place = self.db.get_place_from_handle(place_handle)
eng_place = place.get_title()
eng_source = self.get_primary_source( event.get_source_references())
if event.get_name() == "Divorce":
divorced = 1
div_date = self.format_date( event.get_date_object())
if married == 1:
if m_date != "":
ret = ret + m_date
ret = ret + " "
if m_place != "":
ret = ret + "#mp %s " % self.rem_spaces( m_place)
if m_source != "":
ret = ret + "#ms %s " % self.rem_spaces( m_source)
elif engagend == 1:
"""Geneweb only supports either Marriage or engagement"""
if eng_date != "":
ret = ret + eng_date
ret = ret + " "
if eng_place != "":
ret = ret + "#mp %s " % self.rem_spaces( m_place)
if eng_source != "":
ret = ret + "#ms %s " % self.rem_spaces( m_source)
else:
if family.get_relationship() != const.FAMILY_MARRIED:
"""Not married or engaged"""
ret = ret + " #nm "
if divorced == 1:
if div_date != "":
ret = ret + "-%s " %div_date
else:
ret = ret + "-0 "
return ret
def get_primary_source(self,reflist):
ret = ""
if reflist:
for sr in reflist:
sbase = sr.get_base_handle()
if sbase:
source = self.db.get_source_from_handle(sbase)
if source:
if ret != "":
ret = ret + ", "
ret = ret + source.get_title()
return ret
def format_single_date(self,subdate,cal,mode):
retval = ""
(day,month,year,sl) = subdate
cal_type = ""
if cal == Date.CAL_HEBREW:
type = "H"
elif cal == Date.CAL_FRENCH:
type = "F"
elif cal == Date.CAL_JULIAN:
type = "J"
mode_prefix = ""
if mode == Date.MOD_ABOUT:
mode_prefix = "~"
elif mode == Date.MOD_BEFORE:
mode_prefix = "<"
elif mode == Date.MOD_AFTER:
mode_prefix = ">"
if year > 0:
if month > 0:
if day > 0:
retval = "%s%s/%s/%s%s" % (mode_prefix,day,month,year,cal_type)
else:
retval = "%s%s/%s%s" % (mode_prefix,month,year,cal_type)
else:
retval = "%s%s%s" % (mode_prefix,year,cal_type)
return retval
def format_date(self,date):
retval = ""
strval = date.get_text()
if strval:
retval = "0(%s)" % self.rem_spaces(strval)
elif not date.is_empty():
mod = date.get_modifier()
cal = cal = date.get_calendar()
if mod == Date.MOD_SPAN or mod == Date.MOD_RANGE:
retval = "%s..%s" % (self.format_single_date(date.get_start_date(), cal,mod),
self.format_single_date(date.get_stop_date(),cal,mod))
else:
retval = self.format_single_date(date.get_start_date(),cal,mod)
return retval
def iso8859(self,s):
return s.encode('iso-8859-1')
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def exportData(database,filename,person,option_box):
ret = 0
try:
gw = GeneWebWriter(database,person,0,filename,option_box)
ret = gw.export_data(filename)
except:
import DisplayTrace
DisplayTrace.DisplayTrace()
return ret
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
_title = _('GeneWeb')
_description = _('GeneWeb is a web based genealogy program.')
_config = (_('GeneWeb export options'),GeneWebWriterOptionBox)
_filename = 'gw'
from Plugins import register_export
register_export(exportData,_title,_description,_config,_filename)

View File

@ -0,0 +1,387 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<requires lib="gnome"/>
<widget class="GtkDialog" id="genewebExport">
<property name="visible">True</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">True</property>
<property name="default_width">400</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">8</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="destroy_passed_object" object="gedcomExport"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_ok_clicked" object="gedcomExport"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-help</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-11</property>
<signal name="clicked" handler="on_help_clicked" last_modification_time="Tue, 02 Dec 2003 01:53:26 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkTable" id="table3">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Options&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Filter:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">filter</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkOptionMenu" id="filter">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="history">-1</property>
<child internal-child="menu">
<widget class="GtkMenu" id="convertwidget1">
<property name="visible">True</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="private">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Do not include records marked private</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">True</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="restrict">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Restrict data on living people</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">True</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_restrict_toggled" last_modification_time="Tue, 22 Jul 2003 09:50:16 GMT"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table4">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<widget class="GtkCheckButton" id="notes">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Exclude _notes</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">True</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="sources">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Exclude sour_ces</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">True</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="living">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use _Living as first name</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">True</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkDrawingArea" id="drawingarea1">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">shrink|fill</property>
<property name="y_options">fill</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkCheckButton" id="images">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">R_eference images from path: </property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="images_path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">media</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">3</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">fill</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>